feat: enhance risk pool management and role validation

- Updated AGENTS.md to streamline information on risk pool operations and agent account restrictions.
- Introduced filtering options in AdminRiskPoolIndexController for active risk pools.
- Refactored AdminRiskPoolLockLogIndexController to support grouping by ticket or entry.
- Enhanced AdminRoleStoreController and AdminRoleUpdateController to prevent the use of reserved slugs for new roles.
- Improved error messaging for role creation and updates to clarify reserved role restrictions.
- Added new API routes for ticket item retrieval to improve admin functionalities.
This commit is contained in:
2026-06-15 17:21:53 +08:00
parent 5b6d4cb74d
commit 606ed6817e
14 changed files with 440 additions and 49 deletions

View File

@@ -10,48 +10,51 @@ use App\Models\RiskPoolLockLog;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use App\Services\Admin\AdminRiskPoolLockLogQueryService;
/**
* GET /api/v1/admin/draws/{draw}/risk-pool-lock-logs 风险池占用/释放流水(审计与监控)。
*
* Query`group_by=ticket`(默认,按注单聚合)| `entry`(按号码明细);
* `ticket_item_id` 可筛单注;`action_type``normalized_number` 同前。
*/
final class AdminRiskPoolLockLogIndexController extends Controller
{
public function __construct(
private readonly AdminRiskPoolLockLogQueryService $queryService,
) {}
public function __invoke(Request $request, Draw $draw): JsonResponse
{
$p = AdminApiList::readPaging($request);
$action = trim((string) $request->query('action_type', ''));
$number = trim((string) $request->query('normalized_number', ''));
$q = RiskPoolLockLog::query()
->where('draw_id', $draw->id)
->with(['ticketItem:id,ticket_no,play_code,player_id'])
->orderByDesc('created_at')
->orderByDesc('id');
if ($action !== '' && in_array($action, ['lock', 'release'], true)) {
$q->where('action_type', $action);
}
if ($number !== '' && preg_match('/^[0-9]{4}$/', $number) === 1) {
$q->where('normalized_number', $number);
$groupBy = trim((string) $request->query('group_by', 'ticket'));
if (! in_array($groupBy, ['ticket', 'entry'], true)) {
$groupBy = 'ticket';
}
/** @var LengthAwarePaginator $paginator */
$paginator = $q->paginate($p['perPage'], ['*'], 'page', $p['page']);
$paginator = $groupBy === 'entry'
? $this->queryService->paginateEntries($draw, $request, $p['page'], $p['perPage'])
: $this->queryService->paginateByTicket($draw, $request, $p['page'], $p['perPage']);
$currencyCode = (string) (TicketOrder::query()
->where('draw_id', $draw->id)
->value('currency_code') ?? '');
return AdminApiList::jsonWith($paginator, fn (RiskPoolLockLog $log) => $this->row($log), [
$rowMapper = $groupBy === 'entry'
? fn (RiskPoolLockLog $log): array => $this->entryRow($log)
: fn (object $row): array => $this->ticketRow($row);
return AdminApiList::jsonWith($paginator, $rowMapper, [
'draw_id' => (int) $draw->id,
'draw_no' => $draw->draw_no,
'currency_code' => $currencyCode !== '' ? $currencyCode : null,
'group_by' => $groupBy,
]);
}
/** @return array<string, mixed> */
private function row(RiskPoolLockLog $log): array
private function entryRow(RiskPoolLockLog $log): array
{
return [
'id' => (int) $log->id,
@@ -66,4 +69,25 @@ final class AdminRiskPoolLockLogIndexController extends Controller
'created_at' => $log->created_at?->toIso8601String(),
];
}
/** @return array<string, mixed> */
private function ticketRow(object $row): array
{
$lastAt = $row->last_at ?? null;
return [
'ticket_item_id' => (int) $row->ticket_item_id,
'ticket_no' => (string) $row->ticket_no,
'play_code' => (string) $row->play_code,
'original_number' => (string) $row->original_number,
'combination_count' => (int) $row->combination_count,
'player_id' => (int) $row->player_id,
'number_count' => (int) $row->number_count,
'lock_entry_count' => (int) $row->lock_entry_count,
'release_entry_count' => (int) $row->release_entry_count,
'total_lock_amount' => (int) $row->total_lock_amount,
'total_release_amount' => (int) $row->total_release_amount,
'last_at' => is_string($lastAt) ? $lastAt : null,
];
}
}