feat : rank
This commit is contained in:
115
app/Service/Api/System/GetLeaderboardService.php
Normal file
115
app/Service/Api/System/GetLeaderboardService.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?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 Hyperf\Di\Annotation\Inject;
|
||||
|
||||
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;
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$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,2);
|
||||
}
|
||||
|
||||
$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]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user