Files
lotteryLaravel/app/Support/PlayerApiPresenter.php

102 lines
4.1 KiB
PHP

<?php
namespace App\Support;
use App\Models\Player;
use App\Models\AgentNode;
use App\Models\AgentProfile;
use App\Models\PlayerWallet;
use Illuminate\Support\Facades\DB;
/** 玩家 API 统一 JSON 形状(列表行 / 详情)。 */
final class PlayerApiPresenter
{
/** @return array<string, mixed> */
public static function listItem(Player $player): array
{
$wallets = $player->relationLoaded('wallets')
? $player->wallets
: $player->wallets()->get();
$walletRows = $wallets->map(static fn (PlayerWallet $w): array => [
'wallet_type' => $w->wallet_type,
'currency_code' => $w->currency_code,
'balance' => (int) $w->balance,
'frozen_balance' => (int) $w->frozen_balance,
'available_balance' => max(0, (int) $w->balance - (int) $w->frozen_balance),
'status' => (int) $w->status,
])->values()->all();
$agent = $player->relationLoaded('agentNode')
? $player->agentNode
: ($player->agent_node_id ? $player->agentNode()->first() : null);
$usesCredit = PlayerFundingMode::usesCredit($player);
$credit = DB::table('player_credit_accounts')->where('player_id', $player->id)->first();
$creditLimit = $credit !== null ? (int) $credit->credit_limit : ($usesCredit ? 0 : null);
$usedCredit = $credit !== null ? (int) $credit->used_credit : ($usesCredit ? 0 : null);
$availableCredit = $credit !== null
? max(0, (int) $credit->credit_limit - (int) $credit->used_credit - (int) $credit->frozen_credit)
: ($usesCredit ? 0 : null);
[$rebateRate, $rebateInherited] = self::resolveListRebate($player, $agent);
return [
'id' => (int) $player->id,
...AgentNodeApiPresenter::embed($agent),
'site_code' => $player->site_code,
'site_player_id' => $player->site_player_id,
'auth_source' => $player->auth_source,
'funding_mode' => $player->funding_mode,
'username' => $player->username,
'nickname' => $player->nickname,
'default_currency' => $player->default_currency,
'status' => (int) $player->status,
'last_login_at' => $player->last_login_at?->toIso8601String(),
'created_at' => $player->created_at?->toIso8601String(),
'wallets' => $walletRows,
'uses_credit' => $usesCredit,
'credit_limit' => $creditLimit,
'used_credit' => $usedCredit,
'available_credit' => $availableCredit,
'rebate_rate' => $rebateRate,
'rebate_inherited' => $rebateInherited,
'risk_tags' => $player->risk_tags ?? [],
'rebate_profiles' => DB::table('player_rebate_profiles')
->where('player_id', $player->id)
->orderBy('game_type')
->get()
->map(static fn (object $row): array => [
'game_type' => (string) $row->game_type,
'rebate_rate' => round((float) $row->rebate_rate * 100, 4),
'extra_rebate_rate' => round((float) $row->extra_rebate_rate * 100, 4),
'inherit_from_agent' => (bool) $row->inherit_from_agent,
])
->all(),
];
}
/**
* @return array{0: ?float, 1: bool} rebate rate (ratio) and whether inherited from agent
*/
private static function resolveListRebate(Player $player, ?AgentNode $agent): array
{
$row = DB::table('player_rebate_profiles')
->where('player_id', $player->id)
->where('game_type', '*')
->first();
if ($row !== null && ! (bool) $row->inherit_from_agent) {
return [round((float) $row->rebate_rate * 100, 4), false];
}
if ($agent !== null) {
$profile = AgentProfile::query()->where('agent_node_id', $agent->id)->first();
return [round((float) ($profile?->default_player_rebate ?? 0) * 100, 4), true];
}
return [null, false];
}
}