request ? $this->request->get('record_id') : null; $recordId = is_numeric((string) $recordIdRaw) ? (int) $recordIdRaw : null; return $this->success('', GameLiveService::buildSnapshot($recordId)); } public function snapshot(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } $recordIdRaw = $request->get('record_id'); $recordId = is_numeric((string) $recordIdRaw) ? (int) $recordIdRaw : null; return $this->success('', GameLiveService::buildSnapshot($recordId)); } /** * 后台实时对局 WebSocket 配置(管理员联调专用)。 */ public function wsConfig(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } $topics = [ 'admin.live.snapshot', 'admin.live.opened', 'period.tick', 'period.locked', 'period.opened', 'period.payout', 'bet.accepted', 'wallet.changed', 'auto.spin.progress', ]; return $this->success('', [ 'name' => 'ws.admin.live', 'ws_url' => WebSocketConfigHelper::wsUrl(), 'connect_tip' => '后台实时对局页将自动订阅管理员全量主题(含本局下注、候选号、开奖与派彩信息)。', 'subscribe_topics' => $topics, 'sample_messages' => [ '{"action":"ping"}', '{"action":"subscribe","topics":["admin.live.snapshot","admin.live.opened"]}', '{"action":"subscribe","topics":["period.tick","period.opened","wallet.changed"]}', ], ]); } public function calculate(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $recordIdRaw = $request->post('record_id'); $recordId = is_numeric((string) $recordIdRaw) ? (int) $recordIdRaw : null; $manualRaw = $request->post('manual_number'); $manualNumber = is_numeric((string) $manualRaw) ? (int) $manualRaw : null; $res = GameLiveService::calculateResult($recordId, $manualNumber); if (!($res['ok'] ?? false)) { $errMsg = $res['msg'] ?? null; return $this->error(is_string($errMsg) ? $errMsg : __('Calculation failed')); } $okMsg = $res['msg'] ?? ''; return $this->success(is_string($okMsg) ? $okMsg : '', $res); } /** * 预约本期开奖号码(倒计时结束后自动开奖,不立即开奖)。 */ public function draw(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $recordIdRaw = $request->post('record_id'); $recordId = is_numeric((string) $recordIdRaw) ? (int) $recordIdRaw : null; $manualRaw = $request->post('manual_number'); if (!is_numeric((string) $manualRaw)) { return $this->error(__('Please enter the draw number')); } $manualNumber = (int) $manualRaw; $res = GameLiveService::scheduleDraw($recordId, $manualNumber); if (!($res['ok'] ?? false)) { $errMsg = $res['msg'] ?? null; return $this->error(is_string($errMsg) ? $errMsg : __('Schedule failed')); } $okMsg = $res['msg'] ?? ''; return $this->success(is_string($okMsg) ? $okMsg : '', $res); } /** * 游戏运行开关:关闭时禁止下注、派彩结束后不自动开新期,但当局仍自动开奖并结算;重新开启且无进行中局时立即创建新一期。 */ public function runtime(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $raw = $request->post('enabled'); $enabled = $raw === true || $raw === '1' || $raw === 1; GameRecordService::setLiveRuntimeEnabled($enabled); if ($enabled) { GameRecordService::bootstrapPeriodWhenRuntimeEnabled(); } return $this->success('', GameLiveService::buildSnapshot(null)); } /** * 作废当前对局(下注/封盘阶段),填写原因后退款待开奖注单并关闭运行开关。 */ public function voidPeriod(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $recordIdRaw = $request->post('record_id'); $recordId = is_numeric((string) $recordIdRaw) ? (int) $recordIdRaw : null; $voidReason = $request->post('void_reason'); $reasonStr = is_string($voidReason) ? $voidReason : ''; $res = GameLiveService::voidCurrentPeriod($recordId, $reasonStr); if (!($res['ok'] ?? false)) { $errMsg = $res['msg'] ?? null; return $this->error(is_string($errMsg) ? $errMsg : __('Void failed')); } $okMsg = $res['msg'] ?? ''; return $this->success(is_string($okMsg) ? $okMsg : '', GameLiveService::buildSnapshot(null)); } }