- 在多个控制器中更新权限检查逻辑,确保管理员能够更灵活地管理代理和玩家。 - 在 AdminPlayerStoreController 中引入对玩家创建能力的验证,确保只有具备相应权限的管理员能够创建玩家。 - 更新请求验证逻辑,新增 credit_limit、rebate_rate 和 extra_rebate_rate 字段,以支持更细粒度的玩家管理。 - 在 AgentNodeProfileController 中添加对父代理能力授予的验证,确保子代理的权限在父代理范围内。 - 引入 AgentProfileFieldRules 以简化代理资料更新请求的规则定义,提升代码复用性。
90 lines
3.1 KiB
PHP
90 lines
3.1 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Api\V1\Wallet;
|
||
|
||
use App\Models\TransferOrder;
|
||
use App\Support\ApiResponse;
|
||
use Illuminate\Http\Request;
|
||
use App\Support\PaginationTrait;
|
||
use Illuminate\Http\JsonResponse;
|
||
use App\Support\CurrencyFormatter;
|
||
use App\Http\Controllers\Controller;
|
||
use App\Services\Wallet\PlayerLedgerLogsService;
|
||
|
||
/**
|
||
* PRD §10.1.1:`GET /api/v1/wallet/logs` — 钱包/信用流水(按玩家资金模式分表)。
|
||
*
|
||
* Query:`page`、`size`(每页条数,默认 20)、`type`(逗号分隔:transfer_in,transfer_out,bet,prize,refund,reversal)
|
||
*/
|
||
final class WalletLogsController extends Controller
|
||
{
|
||
use PaginationTrait;
|
||
|
||
public function __construct(
|
||
private readonly PlayerLedgerLogsService $ledgerLogs,
|
||
) {}
|
||
|
||
public function __invoke(Request $request): JsonResponse
|
||
{
|
||
$player = $request->lotteryPlayer();
|
||
abort_if($player === null, 500, 'lottery_player missing');
|
||
|
||
$perPage = $this->perPage($request, 'size', 20, 100);
|
||
$page = $this->page($request);
|
||
$currencyCode = strtoupper(trim((string) $request->query('currency', '')));
|
||
$typeFilter = (string) $request->query('type', '');
|
||
|
||
$pendingPayload = $this->pendingReconcilePayload((int) $player->id, $currencyCode);
|
||
|
||
$result = $this->ledgerLogs->listForPlayerApi($player, $page, $perPage, $currencyCode, $typeFilter);
|
||
|
||
return ApiResponse::success([
|
||
'items' => $result['items'],
|
||
'total' => $result['total'],
|
||
'page' => $result['page'],
|
||
'per_page' => $result['per_page'],
|
||
'ledger_source' => $result['ledger_source'],
|
||
'funding_mode' => $result['funding_mode'],
|
||
'auth_source' => $result['auth_source'],
|
||
'pending_reconcile' => $pendingPayload,
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* @return list<array<string, mixed>>
|
||
*/
|
||
private function pendingReconcilePayload(int $playerId, string $currencyCode = ''): array
|
||
{
|
||
return TransferOrder::query()
|
||
->where('player_id', $playerId)
|
||
->when($currencyCode !== '', fn ($q) => $q->where('currency_code', $currencyCode))
|
||
->where('status', 'pending_reconcile')
|
||
->orderByDesc('id')
|
||
->limit(50)
|
||
->get()
|
||
->map(fn (TransferOrder $o) => $this->formatPendingOrder($o))
|
||
->all();
|
||
}
|
||
|
||
/**
|
||
* @return array<string, mixed>
|
||
*/
|
||
private function formatPendingOrder(TransferOrder $order): array
|
||
{
|
||
$amount = (int) $order->amount;
|
||
|
||
return [
|
||
'transfer_no' => $order->transfer_no,
|
||
'direction' => $order->direction,
|
||
'type' => $order->direction === 'in' ? 'transfer_in' : 'transfer_out',
|
||
'currency_code' => $order->currency_code,
|
||
'amount' => $amount,
|
||
'amount_formatted' => CurrencyFormatter::fromMinor($amount),
|
||
'status' => $order->status,
|
||
'fail_reason' => $order->fail_reason,
|
||
'idempotent_key' => $order->idempotent_key,
|
||
'created_at' => $order->created_at?->toIso8601String(),
|
||
];
|
||
}
|
||
}
|