diff --git a/app/admin/controller/test/GameCurrentStatus.php b/app/admin/controller/test/GameCurrentStatus.php index 4c5bc89..6af370f 100644 --- a/app/admin/controller/test/GameCurrentStatus.php +++ b/app/admin/controller/test/GameCurrentStatus.php @@ -6,6 +6,7 @@ namespace app\admin\controller\test; use app\common\controller\Backend; use app\common\library\admin\WebSocketConfigHelper; +use app\common\service\GameWebSocketPayloadHelper; use support\Response; use Webman\Http\Request as WebmanRequest; @@ -25,6 +26,7 @@ class GameCurrentStatus extends Backend $subscribeTopics = [ 'period.tick', + 'user.streak', 'period.opened', 'period.locked', 'period.payout', @@ -33,15 +35,22 @@ class GameCurrentStatus extends Backend 'auto.spin.progress', ]; + $oddsPushTopics = GameWebSocketPayloadHelper::ODDS_PUSH_TOPICS; + $testPlayerOdds = GameWebSocketPayloadHelper::adminTestPlayerOddsSnapshot(); + return $this->success('', [ 'name' => 'ws.period', 'ws_url' => WebSocketConfigHelper::wsUrl($request), - 'connect_tip' => 'After connected, topics are auto-subscribed. You can also send subscribe manually.', + 'connect_tip' => '连接成功后将自动订阅下列主题。真实业务仅在有玩家下注/结算时推送赔率;本页联调会在订阅后额外推送带 is_test/preview 的演示帧(见下方测试玩家赔率)。', 'subscribe_topics' => $subscribeTopics, + 'odds_push_topics' => $oddsPushTopics, + 'player_odds_fields' => ['current_streak', 'streak_level', 'odds_factor', 'is_jackpot'], + 'test_player_odds' => $testPlayerOdds, + 'test_push_topics' => $oddsPushTopics, 'sample_messages' => [ '{"action":"ping"}', - '{"action":"subscribe","topics":["period.tick","period.opened"]}', - '{"action":"subscribe","topics":["bet.accepted","wallet.changed","auto.spin.progress"]}', + '{"action":"subscribe","topics":["period.tick","user.streak","period.opened","period.locked","period.payout"]}', + '{"action":"subscribe","topics":["user.streak","wallet.changed","bet.accepted","auto.spin.progress"]}', ], ]); } diff --git a/app/api/controller/Game.php b/app/api/controller/Game.php index f1688b1..2c400be 100644 --- a/app/api/controller/Game.php +++ b/app/api/controller/Game.php @@ -14,6 +14,7 @@ use app\common\service\GameHotDataCoordinator; use app\common\service\GameHotDataRedis; use app\common\service\GameRecordService; use app\common\service\GameWebSocketEventBus; +use app\common\service\GameWebSocketPayloadHelper; use support\think\Db; use Webman\Http\Request; use support\Response; @@ -49,6 +50,9 @@ class Game extends MobileBase } $user = $this->auth->getUser(); + $currentStreakRaw = $user->current_streak ?? 0; + $currentStreakParsed = filter_var($currentStreakRaw, FILTER_VALIDATE_INT); + $currentStreak = $currentStreakParsed === false ? 0 : $currentStreakParsed; return $this->mobileSuccess([ 'server_time' => $now, 'runtime_enabled' => GameRecordService::getConfigBool(GameRecordService::KEY_AUTO_CREATE), @@ -68,11 +72,12 @@ class Game extends MobileBase BetChips::lobbyChipsPayload() ), 'dictionary' => $items, - 'streak_win_reward' => StreakWinReward::lobbyPayload(), - 'user_snapshot' => [ - 'coin' => $user->coin, - 'current_streak' => $user->current_streak ?? 0, - ], + 'user_snapshot' => array_merge( + [ + 'coin' => $user->coin, + ], + StreakWinReward::playerBetOddsForCurrentStreak($currentStreak) + ), ]); } @@ -280,7 +285,7 @@ class Game extends MobileBase } GameHotDataCoordinator::afterUserCommitted($userId); - GameWebSocketEventBus::publish('bet.accepted', [ + GameWebSocketEventBus::publish('bet.accepted', GameWebSocketPayloadHelper::mergeUserStreakInto([ 'user_id' => $userId, 'period_no' => $period->period_no, 'numbers' => $numbers, @@ -290,13 +295,13 @@ class Game extends MobileBase 'total_amount' => $totalAmount, 'balance_after' => $after, 'accepted_at' => time(), - ]); - GameWebSocketEventBus::publish('wallet.changed', [ + ], $userId, $streakAtBet)); + GameWebSocketEventBus::publish('wallet.changed', GameWebSocketPayloadHelper::mergeUserStreakInto([ 'user_id' => $userId, 'balance_after' => $after, 'biz_type' => 'bet', 'changed_at' => time(), - ]); + ], $userId, $streakAtBet)); return $this->mobileSuccess([ 'order_no' => $orderNo, 'period_no' => $period->period_no, diff --git a/app/common/library/finance/DepositSettlement.php b/app/common/library/finance/DepositSettlement.php index 707ab62..10f73dd 100644 --- a/app/common/library/finance/DepositSettlement.php +++ b/app/common/library/finance/DepositSettlement.php @@ -184,13 +184,13 @@ final class DepositSettlement throw new RuntimeException($e->getMessage()); } - GameWebSocketEventBus::publish('wallet.changed', [ + GameWebSocketEventBus::publish('wallet.changed', \app\common\service\GameWebSocketPayloadHelper::mergeUserStreakInto([ 'user_id' => $userId, 'balance_after' => $balanceAfter, 'biz_type' => 'deposit', 'order_no' => $orderNo, 'changed_at' => $now, - ]); + ], $userId)); return [ 'order_id' => $orderId, diff --git a/app/common/library/game/StreakWinReward.php b/app/common/library/game/StreakWinReward.php index 862625f..b919bd0 100644 --- a/app/common/library/game/StreakWinReward.php +++ b/app/common/library/game/StreakWinReward.php @@ -107,22 +107,23 @@ final class StreakWinReward } /** - * lobbyInit 用:连胜赔率档位(与后台「连胜奖励」、派彩公式一致)。 + * 当前玩家本局适用赔率(非全表):按 current_streak 解析下一注中奖将使用的档位。 * - * @return array{rows: list} + * @return array{current_streak: int, streak_level: int, odds_factor: int, is_jackpot: bool} */ - public static function lobbyPayload(): array + public static function playerBetOddsForCurrentStreak(int $currentStreak): array { - $rows = []; - foreach (self::loadRows() as $row) { - $rows[] = [ - 'streak' => (int) ($row['streak'] ?? 0), - 'odds_factor' => (int) ($row['odds_factor'] ?? 0), - 'is_jackpot' => ($row['is_jackpot'] ?? false) === true, - ]; + if ($currentStreak < 0) { + $currentStreak = 0; } + $row = self::rowForStreakAtBet($currentStreak); - return ['rows' => $rows]; + return [ + 'current_streak' => $currentStreak, + 'streak_level' => self::levelFromStreakAtBet($currentStreak), + 'odds_factor' => (int) ($row['odds_factor'] ?? 1), + 'is_jackpot' => ($row['is_jackpot'] ?? false) === true, + ]; } /** diff --git a/app/common/service/GameBetSettleService.php b/app/common/service/GameBetSettleService.php index 0ed2a49..eb1a049 100644 --- a/app/common/service/GameBetSettleService.php +++ b/app/common/service/GameBetSettleService.php @@ -143,6 +143,7 @@ final class GameBetSettleService 'update_time' => $now, ]); GameHotDataCoordinator::afterUserCommitted($userId); + GameWebSocketPayloadHelper::publishUserStreak($userId, $next); } $jackpotHits = []; @@ -408,13 +409,13 @@ final class GameBetSettleService 'update_time' => $now, ]); GameHotDataCoordinator::afterUserCommitted($userId); - GameWebSocketEventBus::publish('wallet.changed', [ + GameWebSocketEventBus::publish('wallet.changed', GameWebSocketPayloadHelper::mergeUserStreakInto([ 'user_id' => $userId, 'balance_after' => $after, 'biz_type' => 'payout', 'ref_id' => $betId, 'changed_at' => $now, - ]); + ], $userId)); return $after; } diff --git a/app/common/service/GameWebSocketPayloadHelper.php b/app/common/service/GameWebSocketPayloadHelper.php new file mode 100644 index 0000000..3baa775 --- /dev/null +++ b/app/common/service/GameWebSocketPayloadHelper.php @@ -0,0 +1,232 @@ + */ + public const ODDS_PUSH_TOPICS = [ + 'user.streak', + 'wallet.changed', + 'bet.accepted', + ]; + + /** + * @return array{user_id: int, current_streak: int, streak_level: int, odds_factor: int, is_jackpot: bool} + */ + public static function userStreakData(int $userId, ?int $currentStreak = null): array + { + if ($userId <= 0) { + return [ + 'user_id' => 0, + 'current_streak' => 0, + 'streak_level' => 1, + 'odds_factor' => 1, + 'is_jackpot' => false, + ]; + } + if ($currentStreak === null) { + $row = GameHotDataRedis::userRow($userId); + $raw = $row['current_streak'] ?? 0; + $parsed = filter_var($raw, FILTER_VALIDATE_INT); + $currentStreak = $parsed === false ? 0 : $parsed; + } + + $odds = StreakWinReward::playerBetOddsForCurrentStreak($currentStreak); + + return [ + 'user_id' => $userId, + 'current_streak' => $odds['current_streak'], + 'streak_level' => $odds['streak_level'], + 'odds_factor' => $odds['odds_factor'], + 'is_jackpot' => $odds['is_jackpot'], + ]; + } + + /** + * @param array $payload + * @return array + */ + public static function mergeUserStreakInto(array $payload, int $userId, ?int $currentStreak = null): array + { + if ($userId <= 0) { + return $payload; + } + + return array_merge($payload, self::userStreakData($userId, $currentStreak)); + } + + public static function publishUserStreak(int $userId, ?int $currentStreak = null): void + { + if ($userId <= 0) { + return; + } + GameWebSocketEventBus::publish(self::TOPIC_USER_STREAK, self::userStreakData($userId, $currentStreak)); + } + + /** + * 后台 WebSocket 联调:从库内选取样例玩家(优先 current_streak 最高)。 + * + * @return array|null + */ + public static function pickAdminTestUserRow(): ?array + { + $fields = ['id', 'username', 'uuid', 'phone', 'current_streak', 'coin']; + $row = Db::name('user') + ->where('status', 1) + ->order('current_streak', 'desc') + ->order('id', 'asc') + ->field($fields) + ->find(); + if (is_array($row) && !empty($row['id'])) { + return $row; + } + $fallback = Db::name('user') + ->order('id', 'asc') + ->field($fields) + ->find(); + + return is_array($fallback) && !empty($fallback['id']) ? $fallback : null; + } + + /** + * wsConfig 与订阅后演示推送共用的玩家赔率快照。 + * + * @return array + */ + public static function adminTestPlayerOddsSnapshot(): array + { + $row = self::pickAdminTestUserRow(); + if ($row === null) { + $demoStreak = 3; + $odds = StreakWinReward::playerBetOddsForCurrentStreak($demoStreak); + + return array_merge([ + 'is_test' => true, + 'preview' => true, + 'user_id' => 0, + 'username' => '演示玩家(库内无用户)', + 'uuid' => '', + 'phone' => '', + 'coin' => '0.00', + 'source' => 'synthetic', + ], $odds); + } + + $userIdRaw = $row['id'] ?? 0; + $userIdParsed = filter_var($userIdRaw, FILTER_VALIDATE_INT); + $userId = $userIdParsed === false ? 0 : $userIdParsed; + $streakRaw = $row['current_streak'] ?? 0; + $streakParsed = filter_var($streakRaw, FILTER_VALIDATE_INT); + $currentStreak = $streakParsed === false ? 0 : $streakParsed; + $odds = StreakWinReward::playerBetOddsForCurrentStreak($currentStreak); + + return array_merge([ + 'is_test' => true, + 'preview' => true, + 'user_id' => $userId, + 'username' => (string) ($row['username'] ?? ''), + 'uuid' => (string) ($row['uuid'] ?? ''), + 'phone' => (string) ($row['phone'] ?? ''), + 'coin' => (string) ($row['coin'] ?? '0.00'), + 'source' => 'db_user', + ], $odds); + } + + /** + * 后台测试连接订阅赔率主题后,推送演示帧(非真实业务事件)。 + * + * @param list $subscribedTopics + * @return list}> + */ + public static function adminTestPushFrames(array $subscribedTopics): array + { + $snapshot = self::adminTestPlayerOddsSnapshot(); + $userIdRaw = $snapshot['user_id'] ?? 0; + $userIdParsed = filter_var($userIdRaw, FILTER_VALIDATE_INT); + $userId = $userIdParsed === false ? 0 : $userIdParsed; + $streakRaw = $snapshot['current_streak'] ?? 0; + $streakParsed = filter_var($streakRaw, FILTER_VALIDATE_INT); + $currentStreak = $streakParsed === false ? 0 : $streakParsed; + + $topicSet = []; + foreach ($subscribedTopics as $topic) { + if (!is_string($topic)) { + continue; + } + $value = trim($topic); + if ($value !== '') { + $topicSet[$value] = true; + } + } + + $frames = []; + if (isset($topicSet[self::TOPIC_USER_STREAK])) { + $frames[] = [ + 'topic' => self::TOPIC_USER_STREAK, + 'event' => self::TOPIC_USER_STREAK, + 'data' => $snapshot, + ]; + } + if (isset($topicSet['wallet.changed'])) { + $frames[] = [ + 'topic' => 'wallet.changed', + 'event' => 'wallet.changed', + 'data' => self::mergeOddsFieldsFromSnapshot([ + 'is_test' => true, + 'preview' => true, + 'user_id' => $userId, + 'balance_after' => (string) ($snapshot['coin'] ?? '0.00'), + 'biz_type' => 'admin_test_preview', + 'changed_at' => time(), + ], $snapshot), + ]; + } + if (isset($topicSet['bet.accepted'])) { + $frames[] = [ + 'topic' => 'bet.accepted', + 'event' => 'bet.accepted', + 'data' => self::mergeOddsFieldsFromSnapshot([ + 'is_test' => true, + 'preview' => true, + 'user_id' => $userId, + 'period_no' => 'ADMIN-TEST-PREVIEW', + 'numbers' => [1, 2, 3], + 'bet_id' => 1, + 'single_bet_amount' => '1.00', + 'numbers_count' => 3, + 'total_amount' => '3.00', + 'balance_after' => (string) ($snapshot['coin'] ?? '0.00'), + 'accepted_at' => time(), + ], $snapshot), + ]; + } + + return $frames; + } + + /** + * @param array $payload + * @param array $snapshot + * @return array + */ + private static function mergeOddsFieldsFromSnapshot(array $payload, array $snapshot): array + { + return array_merge($payload, [ + 'current_streak' => $snapshot['current_streak'] ?? 0, + 'streak_level' => $snapshot['streak_level'] ?? 1, + 'odds_factor' => $snapshot['odds_factor'] ?? 1, + 'is_jackpot' => ($snapshot['is_jackpot'] ?? false) === true, + ]); + } +} diff --git a/app/process/GameWebSocketServer.php b/app/process/GameWebSocketServer.php index 717fa22..d73be55 100644 --- a/app/process/GameWebSocketServer.php +++ b/app/process/GameWebSocketServer.php @@ -6,6 +6,7 @@ namespace app\process; use app\common\service\GameWebSocketEventBus; use app\common\service\GameLiveService; +use app\common\service\GameWebSocketPayloadHelper; use Workerman\Connection\TcpConnection; use Workerman\Timer; @@ -169,6 +170,7 @@ class GameWebSocketServer 'event' => 'ws.subscribed', 'topics' => $connection->topics, ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + self::pushAdminTestOddsPreview($connection, $connection->topics); return; } @@ -194,4 +196,26 @@ class GameWebSocketServer $connection->topics = []; unset(self::$connections[$connection->id]); } + + /** + * 后台联调:订阅赔率相关主题后立即推送演示帧(库内样例玩家,带 is_test / preview)。 + * + * @param list $topics + */ + private static function pushAdminTestOddsPreview(TcpConnection $connection, array $topics): void + { + $frames = GameWebSocketPayloadHelper::adminTestPushFrames($topics); + if ($frames === []) { + return; + } + $serverTime = time(); + foreach ($frames as $frame) { + $connection->send(json_encode([ + 'event' => $frame['event'], + 'topic' => $frame['topic'], + 'data' => $frame['data'], + 'server_time' => $serverTime, + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + } + } } diff --git a/docs/36字花-移动端接口设计草案.md b/docs/36字花-移动端接口设计草案.md index 2fae430..e23c2ce 100644 --- a/docs/36字花-移动端接口设计草案.md +++ b/docs/36字花-移动端接口设计草案.md @@ -235,17 +235,17 @@ - `default_bet_chip_id`:int(含义:默认选中的筹码标识,来自 `game_config.default_bet_chip_id`,非法或指向无效档位时服务端回退为首个有效档) - `min_bet_per_number`:string(含义:单号码最小下注额,须 ≤ 所选筹码面额且受后台配置约束) - `max_bet_per_number`:string(含义:单号码最大下注额) -- `streak_win_reward`:object(含义:连胜赔率配置,来自 `game_config.streak_win_reward`,与后台「连胜奖励」一致) - - `rows`:array(固定 1~10 档,按 `streak` 升序) - - `streak`:int(连胜档位 1~10;下注时 `streak_at_bet=0` 适用档位 1,`streak_at_bet=n` 适用档位 `min(n+1, 10)`) - - `odds_factor`:int(赔率乘数;中奖派彩 = 本笔 `total_amount` × `odds_factor`) - - `is_jackpot`:bool(是否大奖档,触发 `jackpot.hit` 等流程) - `dictionary`:array - `number`:int(1-36,含义:字花编号) - `name`:string(含义:字花名称) - `category`:string(含义:字花分类) - `icon`:string(含义:图标资源地址) -- `user_snapshot`:object(`coin`、`current_streak`,含义:用户状态快照) +- `user_snapshot`:object(含义:用户状态快照 + **当前玩家本局适用赔率**,不下发 1~10 全表) + - `coin`:string(余额) + - `current_streak`:int(当前连胜场数) + - `streak_level`:int(若本局中奖将使用的连胜档位 1~10,由 `min(current_streak+1, 10)` 推导) + - `odds_factor`:int(赔率乘数;中奖派彩 = 本笔 `total_amount` × `odds_factor`) + - `is_jackpot`:bool(是否大奖档) ### 3.2 获取36字花字典(可缓存) - **POST** `/api/game/dictionaryList` @@ -750,9 +750,11 @@ - **建议消息**: - 心跳:`{"action":"ping"}` - 服务端对心跳的当前实现回包:`{"event":"pong","server_time":"YYYY-mm-dd HH:ii:ss"}`(**注意**:此处 `server_time` 为**本地时间字符串**,与业务推送帧里 `server_time` 常用**秒级 int** 不一致,客户端解析时请分支处理) - - 订阅状态流:`{"action":"subscribe","topics":["period.tick","period.opened"]}` + - 订阅状态流:`{"action":"subscribe","topics":["period.tick"]}` + - 订阅连胜/赔率(仅当前玩家):`{"action":"subscribe","topics":["user.streak","wallet.changed","bet.accepted"]}` - 订阅资金流:`{"action":"subscribe","topics":["bet.accepted","wallet.changed"]}` - 订阅托管流:`{"action":"subscribe","topics":["auto.spin.progress","wallet.changed"]}` + - 移动端推荐合并订阅:`period.tick`、`user.streak`、`wallet.changed`、`bet.accepted`、`period.opened` #### 7.1.1 消息协议字段定义(联调口径) @@ -770,10 +772,22 @@ - **仅建立连接不会自动下发全部业务消息**;客户端需要发送 `subscribe` 明确订阅主题。 - 成功订阅后服务端返回:`{"event":"ws.subscribed","topics":[...]}`。 - 若未订阅主题,通常只能收到握手首帧(`ws.connected`)和心跳回包(`pong`)。 +- **不下发** `streak_win_reward` 全表(1~10 档);赔率仅通过 `user.streak` / `wallet.changed` / `bet.accepted` 及 `lobbyInit.user_snapshot` 推送**当前登录玩家**本局适用字段。 + +#### 7.1.2A 连胜赔率与连胜场次(WebSocket) + +- **`user.streak`**(开奖结算后推送;载荷为当前玩家本局适用赔率) + - `data.user_id`:int + - `data.current_streak`:int + - `data.streak_level`:int + - `data.odds_factor`:int + - `data.is_jackpot`:bool +- **`wallet.changed` / `bet.accepted`**:在原有字段上合并同上 **`current_streak`**、**`streak_level`**、**`odds_factor`**、**`is_jackpot`**;客户端按 `user_id` 过滤,仅处理本用户 #### 7.1.3 推送频率与触发规则(当前实现) -- `period.tick`:**每秒一次**(用于倒计时、状态同步)。 +- `period.tick`:**每秒一次**(用于倒计时、状态同步;**不含**赔率全表)。 +- `user.streak`:每期结算更新用户连胜后按用户推送(未中奖也会推送,`current_streak` 可能归零)。 - `admin.live.snapshot`:**每秒一次**(后台实时对局页全量快照)。 - `period.opened` / `period.payout` / `admin.live.opened`:按开奖流程阶段触发(事件触发型,非固定频率)。 - `wallet.changed`:仅在余额发生变更时推送(如下注扣款、充值入账、派彩入账)。 diff --git a/web/src/lang/backend/en/test/gameCurrentStatus.ts b/web/src/lang/backend/en/test/gameCurrentStatus.ts index 1443c08..5c25ae2 100644 --- a/web/src/lang/backend/en/test/gameCurrentStatus.ts +++ b/web/src/lang/backend/en/test/gameCurrentStatus.ts @@ -1,3 +1,3 @@ export default { - tip: 'WebSocket connection test for status stream: listen to period.tick / period.opened events.', + tip: 'WebSocket test: load config then connect to auto-subscribe. Period state via period.tick; player odds via user.streak / wallet.changed / bet.accepted (no game.config full table).', } diff --git a/web/src/lang/backend/en/test/ws.ts b/web/src/lang/backend/en/test/ws.ts index d150849..71c5272 100644 --- a/web/src/lang/backend/en/test/ws.ts +++ b/web/src/lang/backend/en/test/ws.ts @@ -12,5 +12,12 @@ export default { btn_clear: 'Clear log', log_title: 'WebSocket log', log_empty: 'No logs yet. Connect first and then send a message.', + subscribe_topics: 'Auto-subscribe topics', + odds_push_topics: 'Odds push topics', + player_odds_fields: 'Player odds fields', + test_player_odds: 'Test player odds (config preview)', + test_player_odds_hint: 'After connect and subscribe, the server pushes demo frames with is_test / preview (from highest-streak sample user in DB).', + test_source_db: 'Sample user from DB', + test_source_synthetic: 'Synthetic demo', } diff --git a/web/src/lang/backend/zh-cn/test/gameCurrentStatus.ts b/web/src/lang/backend/zh-cn/test/gameCurrentStatus.ts index c641a23..99de5f6 100644 --- a/web/src/lang/backend/zh-cn/test/gameCurrentStatus.ts +++ b/web/src/lang/backend/zh-cn/test/gameCurrentStatus.ts @@ -1,3 +1,3 @@ export default { - tip: 'WebSocket 连接测试(状态流):按文档监听 period.tick / period.opened 等事件。', + tip: 'WebSocket 联调:加载配置后连接即自动订阅;对局状态见 period.tick,当前玩家赔率见 user.streak / wallet.changed / bet.accepted(不含 game.config 全表)。', } diff --git a/web/src/lang/backend/zh-cn/test/ws.ts b/web/src/lang/backend/zh-cn/test/ws.ts index 6304ff8..b8c0917 100644 --- a/web/src/lang/backend/zh-cn/test/ws.ts +++ b/web/src/lang/backend/zh-cn/test/ws.ts @@ -12,5 +12,12 @@ export default { btn_clear: '清空日志', log_title: 'WebSocket 日志', log_empty: '暂无日志,请先连接后发送消息。', + subscribe_topics: '自动订阅主题', + odds_push_topics: '赔率推送主题', + player_odds_fields: '玩家赔率字段', + test_player_odds: '测试玩家赔率(配置预览)', + test_player_odds_hint: '连接并订阅赔率主题后,服务端将推送带 is_test / preview 的演示帧(数据来自库内连胜最高的样例玩家)。', + test_source_db: '库内样例玩家', + test_source_synthetic: '合成演示', } diff --git a/web/src/views/backend/test/components/WebSocketTestPage.vue b/web/src/views/backend/test/components/WebSocketTestPage.vue index f022772..0ac6f5f 100644 --- a/web/src/views/backend/test/components/WebSocketTestPage.vue +++ b/web/src/views/backend/test/components/WebSocketTestPage.vue @@ -23,6 +23,38 @@
{{ connectTip || '-' }}
+ + + +

{{ t('test.ws.test_player_odds_hint') }}

+ + {{ testPlayerOdds.user_id }} + {{ testPlayerOdds.username || '-' }} + {{ testPlayerOdds.uuid || '-' }} + {{ testPlayerOdds.phone || '-' }} + {{ testPlayerOdds.coin }} + {{ testPlayerOdds.current_streak }} + {{ testPlayerOdds.streak_level }} + {{ testPlayerOdds.odds_factor }} + {{ testPlayerOdds.is_jackpot ? 'true' : 'false' }} + +
@@ -35,7 +67,7 @@