Files
hyperf_service/app/Service/Api/System/GetLeaderboardService.php
2025-04-09 09:40:05 +08:00

115 lines
3.3 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 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,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]);
}
}