group(function (): void { // 名称:服务健康检查 Route::get('health', HealthController::class)->name('api.v1.health'); // 名称:当前期号(下注大厅倒计时;无需登录) Route::get('draw/current', DrawCurrentController::class)->name('api.v1.draw.current'); // 名称:已发布开奖往期 / 单期(公开) Route::get('draw/results', DrawResultsIndexController::class)->name('api.v1.draw.results'); Route::get('draw/results/{draw_no}', DrawResultShowController::class) ->where('draw_no', '[0-9]{8}-[0-9]{3}') ->name('api.v1.draw.results.show'); Route::get('jackpot/summary', JackpotSummaryController::class)->name('api.v1.jackpot.summary'); // 名称:生效玩法 / 赔率 / 封顶目录(阶段 4;公开) Route::get('play/effective', PlayEffectiveCatalogController::class)->name('api.v1.play.effective'); Route::prefix('player') ->name('api.v1.player.') ->group(function (): void { // 名称:玩家端连通性探测 Route::get('ping', PlayerPingController::class)->name('ping'); }); Route::middleware('lottery.player')->group(function (): void { Route::prefix('player') ->name('api.v1.player.') ->group(function (): void { // 名称:当前登录玩家信息 Route::get('me', MeController::class)->name('me'); }); Route::prefix('wallet') ->name('api.v1.wallet.') ->group(function (): void { // 名称:彩票钱包余额查询 Route::get('balance', WalletBalanceController::class)->name('balance'); // 名称:钱包流水(PRD §10.1.1) Route::get('logs', WalletLogsController::class)->name('logs'); // 名称:主站 → 彩票 转入 Route::post('transfer-in', WalletTransferInController::class)->name('transfer-in'); // 名称:彩票 → 主站 转出 Route::post('transfer-out', WalletTransferOutController::class)->name('transfer-out'); }); Route::prefix('ticket') ->name('api.v1.ticket.') ->group(function (): void { Route::post('preview', TicketPreviewController::class)->name('preview'); Route::post('place', TicketPlaceController::class)->name('place'); Route::get('items', TicketItemsIndexController::class)->name('items.index'); Route::get('items/{ticket_no}', TicketItemShowController::class) ->where('ticket_no', 'TK[0-9]+') ->name('items.show'); Route::get('draws/{draw_no}/my-match', TicketDrawMyMatchController::class) ->where('draw_no', '[0-9]{8}-[0-9]{3}') ->name('draws.my-match'); }); }); Route::prefix('admin') ->name('api.v1.admin.') ->group(function (): void { Route::middleware('throttle:admin-auth-captcha') ->get('auth/captcha', CaptchaController::class) ->name('auth.captcha'); Route::middleware('throttle:admin-auth-login') ->post('auth/login', LoginController::class) ->name('auth.login'); Route::middleware(['auth:sanctum', 'lottery.admin'])->group(function (): void { // 名称:后台接口连通性探测(需 Bearer Token;不校验细粒度 RBAC) Route::get('ping', AdminPingController::class)->name('ping'); /** 首页仪表盘:聚合大厅 + 当期财务/风控/待办计数(细粒度权限在控制器内按块判断) */ Route::get('dashboard', AdminDashboardController::class)->name('dashboard'); /** §8 钱包对账:超管可管、风控查看、财务可管、客服单用户 */ Route::middleware('admin.permission:prd.wallet_reconcile.manage|prd.wallet_reconcile.view|prd.wallet_reconcile.view_cs')->group(function (): void { Route::get('wallet/transfer-orders', TransferOrderListController::class) ->name('wallet.transfer-orders'); Route::get('wallet/transactions', WalletTransactionListController::class) ->name('wallet.transactions'); }); /** §8 用户管理:财务查看 / 客服单用户 / 超管可管 */ Route::middleware('admin.permission:prd.users.manage|prd.users.view_finance|prd.users.view_cs')->group(function (): void { Route::get('players/{player}/wallets', PlayerWalletShowController::class) ->name('players.wallets'); /** §15.4 客服/财务:按玩家查注单 */ Route::get('players/{player}/ticket-items', AdminPlayerTicketItemsIndexController::class) ->name('players.ticket-items.index'); }); /** §8 开奖结果·查看 + 风控占用监控(与开奖/风险域一致) */ Route::middleware('admin.permission:prd.draw_result.manage|prd.draw_result.view')->group(function (): void { Route::get('draws', AdminDrawIndexController::class)->name('draws.index'); Route::get('draws/{draw}', AdminDrawShowController::class)->name('draws.show'); /** §15.4 单期投注/派彩汇总(与结算批次对照) */ Route::get('draws/{draw}/finance-summary', AdminDrawFinanceSummaryController::class) ->name('draws.finance-summary'); Route::get('draws/{draw}/result-batches', AdminDrawResultBatchesIndexController::class) ->name('draws.result-batches.index'); Route::get('draws/{draw}/risk-pools/{number_4d}', AdminRiskPoolShowController::class) ->where('number_4d', '[0-9]{4}') ->name('draws.risk-pools.show'); Route::get('draws/{draw}/risk-pool-lock-logs', AdminRiskPoolLockLogIndexController::class) ->name('draws.risk-pool-lock-logs.index'); Route::get('draws/{draw}/risk-pools', AdminRiskPoolIndexController::class) ->name('draws.risk-pools.index'); }); /** §8 开奖结果录入(发布批次) */ Route::middleware('admin.permission:prd.draw_result.manage')->group(function (): void { Route::post( 'draws/{draw}/result-batches/{batch}/publish', DrawResultBatchPublishController::class, )->name('draws.result-batches.publish'); }); /** §8 派彩确认:超管执行 + 风控审核 */ Route::middleware('admin.permission:prd.payout.manage|prd.payout.review')->group(function (): void { Route::post('draws/{draw}/settlement/run', DrawSettlementRunController::class) ->name('draws.settlement.run'); }); Route::middleware('admin.permission:prd.payout.manage|prd.payout.review|prd.payout.view')->group(function (): void { Route::get('settlement-batches', AdminSettlementBatchIndexController::class) ->name('settlement-batches.index'); Route::get('settlement-batches/{batch}', AdminSettlementBatchShowController::class) ->name('settlement-batches.show'); Route::get('settlement-batches/{batch}/details', AdminSettlementBatchDetailsController::class) ->name('settlement-batches.details'); }); Route::middleware('admin.permission:prd.jackpot.manage|prd.jackpot.view')->group(function (): void { Route::get('jackpot/pools', AdminJackpotPoolIndexController::class)->name('jackpot.pools.index'); Route::get('jackpot/payout-logs', AdminJackpotPayoutLogIndexController::class) ->name('jackpot.payout-logs.index'); Route::get('jackpot/contributions', AdminJackpotContributionIndexController::class) ->name('jackpot.contributions.index'); }); Route::middleware('admin.permission:prd.jackpot.manage')->group(function (): void { Route::put('jackpot/pools/{pool}', AdminJackpotPoolUpdateController::class)->name('jackpot.pools.update'); }); /** §8 玩法/玩法版本只读:财务不可(不含 rebate.view) */ Route::middleware('admin.permission:prd.play_switch.manage|prd.odds.manage')->group(function (): void { Route::get('play-types', PlayTypeIndexController::class)->name('play-types.index'); Route::prefix('config')->name('config.')->group(function (): void { Route::get('play-versions', PlayConfigVersionIndexController::class)->name('play-versions.index'); Route::get('play-versions/{id}', PlayConfigVersionShowController::class) ->whereNumber('id') ->name('play-versions.show'); }); }); /** §8 赔率/回水只读:财务仅 rebate.view,不可单独看玩法版本 */ Route::middleware('admin.permission:prd.odds.manage|prd.rebate.manage|prd.rebate.view')->group(function (): void { Route::prefix('config')->name('config.')->group(function (): void { Route::get('odds-versions', OddsVersionIndexController::class)->name('odds-versions.index'); Route::get('odds-versions/{id}', OddsVersionShowController::class) ->whereNumber('id') ->name('odds-versions.show'); }); }); /** §8 封顶只读 */ Route::middleware('admin.permission:prd.risk_cap.manage|prd.risk_cap.view')->group(function (): void { Route::prefix('config')->name('config.')->group(function (): void { Route::get('risk-cap-versions', RiskCapVersionIndexController::class)->name('risk-cap-versions.index'); Route::get('risk-cap-versions/{id}', RiskCapVersionShowController::class) ->whereNumber('id') ->name('risk-cap-versions.show'); }); }); /** §8 玩法/赔率/封顶/回水/Jackpot 配置写 */ Route::middleware('admin.permission:prd.play_switch.manage|prd.odds.manage|prd.risk_cap.manage|prd.rebate.manage|prd.jackpot.manage')->group(function (): void { Route::patch('play-types/{play_code}', PlayTypePatchController::class) ->where('play_code', '[a-z0-9_]+') ->name('play-types.patch'); Route::prefix('config')->name('config.')->group(function (): void { Route::post('play-versions', PlayConfigVersionStoreController::class)->name('play-versions.store'); Route::put('play-versions/{id}/items', PlayConfigItemsReplaceController::class) ->whereNumber('id') ->name('play-versions.items.replace'); Route::post('play-versions/{id}/publish', PlayConfigVersionPublishController::class) ->whereNumber('id') ->name('play-versions.publish'); Route::post('odds-versions', OddsVersionStoreController::class)->name('odds-versions.store'); Route::put('odds-versions/{id}/items', OddsItemsReplaceController::class) ->whereNumber('id') ->name('odds-versions.items.replace'); Route::post('odds-versions/{id}/publish', OddsVersionPublishController::class) ->whereNumber('id') ->name('odds-versions.publish'); Route::post('risk-cap-versions', RiskCapVersionStoreController::class)->name('risk-cap-versions.store'); Route::put('risk-cap-versions/{id}/items', RiskCapItemsReplaceController::class) ->whereNumber('id') ->name('risk-cap-versions.items.replace'); Route::post('risk-cap-versions/{id}/publish', RiskCapVersionPublishController::class) ->whereNumber('id') ->name('risk-cap-versions.publish'); }); }); /** §8 审计日志:超管全部 / 风控自身 / 财务资金;客服无 */ Route::middleware('admin.permission:prd.audit.all|prd.audit.self|prd.audit.finance')->group(function (): void { Route::get('audit-logs', AuditLogIndexController::class)->name('audit-logs.index'); }); /** §8 报表 */ Route::middleware('admin.permission:prd.report.all|prd.report.risk|prd.report.finance|prd.report.player')->group(function (): void { Route::get('report-jobs', ReportJobIndexController::class)->name('report-jobs.index'); Route::post('report-jobs', ReportJobStoreController::class)->name('report-jobs.store'); Route::get('report-jobs/{report_job}', ReportJobShowController::class) ->name('report-jobs.show'); }); /** §8 钱包对账任务:查看含客服单用户;创建任务仅可管理(超管/财务) */ Route::middleware('admin.permission:prd.wallet_reconcile.manage|prd.wallet_reconcile.view|prd.wallet_reconcile.view_cs')->group(function (): void { Route::get('reconcile-jobs', ReconcileJobIndexController::class)->name('reconcile-jobs.index'); Route::get('reconcile-jobs/{reconcile_job}', ReconcileJobShowController::class) ->name('reconcile-jobs.show'); Route::get('reconcile-jobs/{reconcile_job}/items', ReconcileItemIndexController::class) ->name('reconcile-jobs.items.index'); }); Route::middleware('admin.permission:prd.wallet_reconcile.manage')->group(function (): void { Route::post('reconcile-jobs', ReconcileJobStoreController::class)->name('reconcile-jobs.store'); }); /** 后台账号与权限分配:仅可管理账户执行。 */ Route::middleware('admin.permission:prd.admin_user.manage')->group(function (): void { Route::get('admin-users', AdminUserIndexController::class)->name('admin-users.index'); Route::post('admin-users', AdminUserStoreController::class)->name('admin-users.store'); Route::get('admin-users/{admin_user}', AdminUserShowController::class)->name('admin-users.show'); Route::put('admin-users/{admin_user}', AdminUserUpdateController::class)->name('admin-users.update'); Route::delete('admin-users/{admin_user}', AdminUserDestroyController::class)->name('admin-users.destroy'); Route::get('admin-user-permission-catalog', AdminPermissionCatalogController::class) ->name('admin-users.permission-catalog'); Route::put('admin-users/{admin_user}/permissions', AdminUserPermissionSyncController::class) ->name('admin-users.permissions.sync'); Route::put('admin-users/{admin_user}/roles', AdminUserRoleSyncController::class) ->name('admin-users.roles.sync'); }); }); }); });