220 lines
6.6 KiB
PHP
220 lines
6.6 KiB
PHP
<?php
|
|
/**
|
|
* This crontab file is part of item.
|
|
*
|
|
* @author ctexthuang
|
|
* @contact ctexthuang@qq.com
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Cron\Chef;
|
|
|
|
use App\Constants\Admin\UserCode;
|
|
use App\Constants\Common\LeaderboardHistoryCode;
|
|
use App\Extend\DateUtil;
|
|
use App\Lib\Log;
|
|
use App\Model\Chef;
|
|
use App\Model\ChefStatement;
|
|
use App\Model\Evaluation;
|
|
use App\Model\Kitchen;
|
|
use App\Model\LeaderboardHistory;
|
|
use Exception;
|
|
use Hyperf\Crontab\Annotation\Crontab;
|
|
use Hyperf\DbConnection\Db;
|
|
use Hyperf\Di\Annotation\Inject;
|
|
use Psr\Container\ContainerExceptionInterface;
|
|
use Psr\Container\NotFoundExceptionInterface;
|
|
|
|
#[Crontab(rule: "0 12 * * 6", name: "RankTask", singleton: true , callback: "execute", memo: "厨师排行榜数据生成")]
|
|
class RankTask
|
|
{
|
|
/**
|
|
* @var ChefStatement
|
|
*/
|
|
#[Inject]
|
|
protected ChefStatement $chefStatementModel;
|
|
|
|
/**
|
|
* @var Evaluation
|
|
*/
|
|
#[Inject]
|
|
protected Evaluation $evaluationModel;
|
|
|
|
/**
|
|
* @var LeaderboardHistory
|
|
*/
|
|
#[Inject]
|
|
protected LeaderboardHistory $leaderboardHistoryModel;
|
|
|
|
/**
|
|
* @var Log
|
|
*/
|
|
#[Inject]
|
|
protected Log $log;
|
|
|
|
/**
|
|
* @var Chef
|
|
*/
|
|
#[Inject]
|
|
protected Chef $chefModel;
|
|
|
|
/**
|
|
* @var Kitchen
|
|
*/
|
|
#[Inject]
|
|
protected Kitchen $kitchenModel;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected array $thisWeekInfo;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected array $chefInfo;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected array $kitchenSiteList;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected array $insertData;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected string $nowDate;
|
|
|
|
/**
|
|
* @return void
|
|
* @throws ContainerExceptionInterface
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
public function execute(): void
|
|
{
|
|
try {
|
|
$this->thisWeekInfo = DateUtil::getThisWeekInfo();
|
|
|
|
if (
|
|
empty($this->thisWeekInfo) ||
|
|
empty($this->thisWeekInfo['start_date']) ||
|
|
empty($this->thisWeekInfo['end_date']) ||
|
|
empty($this->thisWeekInfo['week_number']) ||
|
|
empty($this->thisWeekInfo['year'])
|
|
) throw new Exception(__CLASS__.'数据生成失败,获取上周信息失败');
|
|
|
|
$this->nowDate = date("Y-m-d H:i:s");
|
|
|
|
$flag = $this->leaderboardHistoryModel->where('time_key',$this->thisWeekInfo['year'].$this->thisWeekInfo['week_number'])->first();
|
|
if (!empty($flag)) throw new Exception(__CLASS__.'数据生成失败,上周数据已生成');
|
|
|
|
$chefInfo = $this->chefModel
|
|
->join('admin_user', function ($join) {
|
|
$join->on('admin_user.id', '=', 'chef.user_id')
|
|
->where('admin_user.is_del', '=', UserCode::IS_NO_DEL)
|
|
->select([
|
|
'admin_user.id',
|
|
'chef.kitchen_id',
|
|
'admin_user.city_id'
|
|
]);
|
|
})
|
|
->get();
|
|
if ($chefInfo->isEmpty()) throw new Exception(__CLASS__.'数据生成失败,获取厨师信息失败');
|
|
$this->chefInfo = $chefInfo->toArray();
|
|
|
|
// $kitchenIds = array_column($this->chefInfo, 'kitchen_id');
|
|
// $this->kitchenSiteList = $this->kitchenModel->whereIn('id',$kitchenIds)->pluck('city_id','id')->toArray();
|
|
// if (empty($this->kitchenSiteList)) throw new Exception(__CLASS__.'数据生成失败,获取厨房城市信息失败');
|
|
|
|
$this->buildChefEvaluationRankData();
|
|
|
|
$this->buildChefStatementRankData();
|
|
|
|
if (empty($this->insertData)) throw new Exception(__CLASS__.'数据生成失败,获取厨师排行榜数据失败');
|
|
Db::transaction(function () {
|
|
$res = (new LeaderboardHistory)->insert($this->insertData);
|
|
|
|
if (!$res) throw new Exception(__CLASS__.'数据生成失败,插入数据失败');
|
|
});
|
|
|
|
|
|
}catch (Exception $e){
|
|
$this->log->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
*/
|
|
private function buildChefEvaluationRankData(): void
|
|
{
|
|
$data = $this->chefStatementModel
|
|
->whereBetween('date',[$this->thisWeekInfo['start_date'],$this->thisWeekInfo['end_date']])
|
|
->select('chef_id', Db::raw('SUM(`sale`) as total_sale'))
|
|
->groupBy('chef_id')
|
|
->get();
|
|
|
|
if ($data->isEmpty()) $this->buildChefStatementNullData(LeaderboardHistoryCode::TYPE_CHEF_SALE);
|
|
$data = array_column($data->toArray(),'total_sale','chef_id');
|
|
|
|
foreach ($this->chefInfo as $v){
|
|
$this->insertData[] = [
|
|
'chef_id' => $v->id,
|
|
'kitchen_id' => $v->kitchen_id,
|
|
'city_id' => $v->city_id,
|
|
'time_key' => $this->thisWeekInfo['year'].$this->thisWeekInfo['week_number'],
|
|
'board_type' => LeaderboardHistoryCode::TYPE_CHEF_SALE,
|
|
'score' => $data[$v->id] ?? 0,
|
|
'create_time' => $this->nowDate,
|
|
];
|
|
}
|
|
|
|
}
|
|
|
|
private function buildChefStatementNullData(int $type): void
|
|
{
|
|
foreach ($this->chefInfo as $v) {
|
|
$this->insertData[] = [
|
|
'chef_id' => $v->id,
|
|
'kitchen_id' => $v->kitchen_id,
|
|
'city_id' => $v->city_id,
|
|
'time_key' => $this->thisWeekInfo['year'].$this->thisWeekInfo['week_number'],
|
|
'board_type' => $type,
|
|
'score' => 0,
|
|
'create_time' => $this->nowDate,
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
*/
|
|
private function buildChefStatementRankData(): void
|
|
{
|
|
$data = $this->evaluationModel
|
|
->whereBetween('date',[$this->thisWeekInfo['start_date'],$this->thisWeekInfo['end_date']])
|
|
->select('chef_id',Db::raw('AVG(`score`) as total_score'))
|
|
->groupBy('chef_id')
|
|
->get();
|
|
|
|
if ($data->isEmpty()) $this->buildChefStatementNullData(LeaderboardHistoryCode::TYPE_CHEF_SCORE);
|
|
$data = array_column($data->toArray(),'total_score','chef_id');
|
|
|
|
foreach ($this->chefInfo as $v){
|
|
$this->insertData[] = [
|
|
'chef_id' => $v->id,
|
|
'kitchen_id' => $v->kitchen_id,
|
|
'city_id' => $v->city_id,
|
|
'time_key' => $this->thisWeekInfo['year'].$this->thisWeekInfo['week_number'],
|
|
'board_type' => LeaderboardHistoryCode::TYPE_CHEF_SCORE,
|
|
'score' => $data[$v->id] ?? 0,
|
|
'create_time' => $this->nowDate,
|
|
];
|
|
}
|
|
}
|
|
} |