104 lines
3.5 KiB
PHP
104 lines
3.5 KiB
PHP
<?php
|
|
|
|
/**
|
|
* 文件功能:每日游戏净盈利前三榜读服务
|
|
*
|
|
* 聚合百家乐与赛马当天金币流水,给聊天室顶部悬浮榜提供轻量数据。
|
|
*
|
|
* @author ChatRoom Laravel
|
|
*
|
|
* @version 1.0.0
|
|
*/
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Enums\CurrencySource;
|
|
use App\Models\UserCurrencyLog;
|
|
use Carbon\CarbonImmutable;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
/**
|
|
* 类功能:查询百家乐与赛马每日净盈利前三用户。
|
|
*/
|
|
class DailyGameProfitLeaderboardService
|
|
{
|
|
/**
|
|
* 每日榜单固定称号。
|
|
*/
|
|
private const TITLES = [
|
|
1 => '金库爆破王',
|
|
2 => '马桌双修财神',
|
|
3 => '金币收割机',
|
|
];
|
|
|
|
/**
|
|
* 参与净盈利统计的游戏流水来源。
|
|
*/
|
|
private const GAME_PROFIT_SOURCES = [
|
|
CurrencySource::BACCARAT_BET,
|
|
CurrencySource::BACCARAT_WIN,
|
|
CurrencySource::HORSE_BET,
|
|
CurrencySource::HORSE_WIN,
|
|
];
|
|
|
|
/**
|
|
* 获取指定日期的游戏净盈利前三榜。
|
|
*
|
|
* @return Collection<int, object{rank:int,title:string,user_id:int,username:string,headface_url:string,net_profit:int}>
|
|
*/
|
|
public function topThree(?string $date = null): Collection
|
|
{
|
|
$statsDate = CarbonImmutable::parse($date ?? today()->toDateString())->startOfDay();
|
|
$cacheKey = 'daily_game_profit_leaderboard:v2:'.$statsDate->toDateString();
|
|
|
|
return Cache::remember($cacheKey, 300, function () use ($statsDate) {
|
|
$rangeStart = $statsDate;
|
|
$rangeEnd = $statsDate->addDay();
|
|
|
|
return UserCurrencyLog::query()
|
|
->join('users', 'users.id', '=', 'user_currency_logs.user_id')
|
|
->where('user_currency_logs.currency', 'gold')
|
|
->whereIn('user_currency_logs.source', array_map(
|
|
fn (CurrencySource $source): string => $source->value,
|
|
self::GAME_PROFIT_SOURCES
|
|
))
|
|
->where('user_currency_logs.created_at', '>=', $rangeStart)
|
|
->where('user_currency_logs.created_at', '<', $rangeEnd)
|
|
->where('users.username', '!=', 'AI小班长')
|
|
->groupBy('user_currency_logs.user_id', 'users.username', 'users.usersf')
|
|
->havingRaw('SUM(user_currency_logs.amount) > 0')
|
|
->orderByRaw('SUM(user_currency_logs.amount) DESC')
|
|
->orderBy('user_currency_logs.user_id')
|
|
->limit(3)
|
|
->selectRaw('user_currency_logs.user_id, users.username, users.usersf, SUM(user_currency_logs.amount) as net_profit')
|
|
->get()
|
|
->values()
|
|
->map(function (object $row, int $index): object {
|
|
$rank = $index + 1;
|
|
|
|
return (object) [
|
|
'rank' => $rank,
|
|
'title' => self::TITLES[$rank],
|
|
'user_id' => (int) $row->user_id,
|
|
'username' => (string) $row->username,
|
|
'headface_url' => $this->resolveHeadfaceUrl((string) ($row->usersf ?: '1.gif')),
|
|
'net_profit' => (int) $row->net_profit,
|
|
];
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 解析榜单头像地址。
|
|
*/
|
|
private function resolveHeadfaceUrl(string $headface): string
|
|
{
|
|
if (str_starts_with($headface, 'storage/')) {
|
|
return '/'.$headface;
|
|
}
|
|
|
|
return '/images/headface/'.strtolower($headface);
|
|
}
|
|
}
|