102 lines
4.1 KiB
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];
|
|
}
|
|
}
|