124 lines
3.6 KiB
PHP
124 lines
3.6 KiB
PHP
<?php
|
|
/**
|
|
* This service file is part of item.
|
|
*
|
|
* @author ctexthuang
|
|
* @contact ctexthuang@qq.com
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Service\Api\System;
|
|
|
|
use App\Cache\Redis\Api\ApiRedisKey;
|
|
use App\Cache\Redis\RedisCache;
|
|
use App\Constants\Common\LeaderboardHistoryCode;
|
|
use App\Extend\DateUtil;
|
|
use App\Model\AdminUser;
|
|
use App\Model\LeaderboardHistory;
|
|
use App\Model\SystemCity;
|
|
use App\Service\Api\BaseService;
|
|
use App\Service\ServiceTrait\Common\OssTrait;
|
|
use DateMalformedStringException;
|
|
use Hyperf\Di\Annotation\Inject;
|
|
use Psr\Container\ContainerExceptionInterface;
|
|
use Psr\Container\NotFoundExceptionInterface;
|
|
|
|
class GetLeaderboardService extends BaseService
|
|
{
|
|
use OssTrait;
|
|
|
|
/**
|
|
* @var SystemCity
|
|
*/
|
|
#[Inject]
|
|
protected SystemCity $systemCityModel;
|
|
|
|
/**
|
|
* @var RedisCache
|
|
*/
|
|
#[Inject]
|
|
protected RedisCache $redis;
|
|
|
|
/**
|
|
* @var LeaderboardHistory
|
|
*/
|
|
#[Inject]
|
|
protected LeaderboardHistory $leaderboardHistoryModel;
|
|
|
|
/**
|
|
* @var AdminUser
|
|
*/
|
|
#[Inject]
|
|
protected AdminUser $adminUserModel;
|
|
|
|
/**
|
|
* @return array
|
|
* @throws DateMalformedStringException
|
|
* @throws ContainerExceptionInterface
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
public function handle(): array
|
|
{
|
|
$cityId = (int)$this->request->input('city_id');
|
|
$type = (int)$this->request->input('type');
|
|
$cityInfo = $this->systemCityModel->find($cityId);
|
|
|
|
if (empty($cityInfo)) return $this->return->success('success',['list' => []]);
|
|
|
|
$lastInfo = DateUtil::getLastWeekInfo();
|
|
|
|
if (
|
|
empty($lastInfo) ||
|
|
empty($lastInfo['start_date']) ||
|
|
empty($lastInfo['end_date']) ||
|
|
empty($lastInfo['week_number']) ||
|
|
empty($lastInfo['year'])
|
|
) return $this->return->success('success',['list' => []]);
|
|
|
|
$timeKey = (int)($lastInfo['year'].$lastInfo['week_number']);
|
|
|
|
$redisKey = ApiRedisKey::getLeaderboardByCityIdAndType($cityId,$type,$timeKey);
|
|
|
|
if (!$this->redis->exists($redisKey)) {
|
|
$info = $this->leaderboardHistoryModel->where('board_type',$type)->where('city_id',$cityId)->where('time_key',$timeKey)->pluck('score','chef_id')->toArray();
|
|
foreach ($info as $k=>$v) {
|
|
if ($type == LeaderboardHistoryCode::TYPE_CHEF_SCORE) {
|
|
if ($v == 0) $v = 0;
|
|
|
|
if ($v < 4) {
|
|
$normalized = $v / 4;
|
|
$v = 4 + 1 - exp(-2 * $normalized);
|
|
}
|
|
|
|
$v = round($v,1);
|
|
}
|
|
|
|
$this->redis->zAdd($redisKey,$v,$k);
|
|
$this->redis->expire($redisKey,86400);
|
|
}
|
|
}
|
|
|
|
$leaderboardList = $this->redis->zRevRange($redisKey,0,-1,true);
|
|
|
|
$chefIds = array_keys($leaderboardList);
|
|
$chefList = $this->adminUserModel->whereIn('id',$chefIds)->select('id','chinese_name','avatar')->get();
|
|
if ($chefList->isEmpty()) return $this->return->success('success',['list' => []]);
|
|
$chefList = $chefList->toArray();
|
|
|
|
$avatarIds = array_column($chefList,'avatar');
|
|
$avatarList = $this->getOssObjects($avatarIds);
|
|
|
|
$res = [];
|
|
foreach ($leaderboardList as $k=>$v) {
|
|
$res[] = [
|
|
'id' => $k,
|
|
'name' => $chefList[$k]['chinese_name'],
|
|
'avatar' => $avatarList[$chefList[$k]['avatar']]['url'] ?? '',
|
|
'score' => $v,
|
|
];
|
|
}
|
|
|
|
return $this->return->success('success',['list' => $res]);
|
|
}
|
|
} |