@@ -23,6 +23,38 @@
< / el-form-item >
< / el-form >
< div class = "text-muted mb-8" > { { connectTip || '-' } } < / div >
< template v-if = "ready && subscribeTopics.length" >
< div class = "mb-4" >
< span class = "config-label" > { { t ( 'test.ws.subscribe_topics' ) } } : < / span >
< el-tag v-for = "topic in subscribeTopics" :key="topic" size="small" class="mr-4 mb-4" > {{ topic }} < / el -tag >
< / div >
< div v-if = "oddsPushTopics.length" class="mb-4" >
< span class = "config-label" > { { t ( 'test.ws.odds_push_topics' ) } } : < / span >
< el-tag v-for = "topic in oddsPushTopics" :key="'odds-' + topic" type="warning" size="small" class="mr-4 mb-4" > {{ topic }} < / el -tag >
< / div >
< div v-if = "playerOddsFields.length" class="mb-4" >
< span class = "config-label" > { { t ( 'test.ws.player_odds_fields' ) } } : < / span >
< el-tag v-for = "field in playerOddsFields" :key="field" type="success" size="small" class="mr-4 mb-4" > {{ field }} < / el -tag >
< / div >
< / template >
< el-card v-if = "testPlayerOdds" shadow="never" class="test-odds-card" >
< template # header >
< span > { { t ( 'test.ws.test_player_odds' ) } } < / span >
< el-tag type = "info" size = "small" class = "ml-8" > { { testPlayerOddsSourceLabel } } < / el-tag >
< / template >
< p class = "text-muted mb-8" > { { t ( 'test.ws.test_player_odds_hint' ) } } < / p >
< el-descriptions :column = "2" border size = "small" >
< el-descriptions-item label = "user_id" > { { testPlayerOdds . user _id } } < / el-descriptions-item >
< el-descriptions-item label = "username" > { { testPlayerOdds . username || '-' } } < / el-descriptions-item >
< el-descriptions-item label = "uuid" > { { testPlayerOdds . uuid || '-' } } < / el-descriptions-item >
< el-descriptions-item label = "phone" > { { testPlayerOdds . phone || '-' } } < / el-descriptions-item >
< el-descriptions-item label = "coin" > { { testPlayerOdds . coin } } < / el-descriptions-item >
< el-descriptions-item label = "current_streak" > { { testPlayerOdds . current _streak } } < / el-descriptions-item >
< el-descriptions-item label = "streak_level" > { { testPlayerOdds . streak _level } } < / el-descriptions-item >
< el-descriptions-item label = "odds_factor" > { { testPlayerOdds . odds _factor } } < / el-descriptions-item >
< el-descriptions-item label = "is_jackpot" > { { testPlayerOdds . is _jackpot ? 'true' : 'false' } } < / el-descriptions-item >
< / el-descriptions >
< / el-card >
< / el-card >
< el-card shadow = "never" >
@@ -35,7 +67,7 @@
< / template >
< script setup lang = "ts" >
import { computed , onUnmounted , ref } from 'vue'
import { computed , onMounted , onUnmounted , ref } from 'vue'
import { useI18n } from 'vue-i18n'
import createAxios from '/@/utils/axios'
@@ -58,11 +90,15 @@ const connectTip = ref('')
const sendMessage = ref ( '' )
/** 连接成功后自动订阅(由 wsConfig.subscribe_topics 下发) */
const subscribeTopics = ref < string [ ] > ( [ ] )
const oddsPushTopics = ref < string [ ] > ( [ ] )
const playerOddsFields = ref < string [ ] > ( [ ] )
const testPlayerOdds = ref < Record < string , unknown > | null > ( null )
const ws = ref < WebSocket | null > ( null )
const logs = ref < Array < { t : number ; event : string ; payload : string } > > ( [ ] )
const defaultSubscribeTopics = [
'period.tick' ,
'user.streak' ,
'period.opened' ,
'period.locked' ,
'period.payout' ,
@@ -71,6 +107,17 @@ const defaultSubscribeTopics = [
'auto.spin.progress' ,
] as const
const testPlayerOddsSourceLabel = computed ( ( ) => {
const source = testPlayerOdds . value ? . source
if ( source === 'db_user' ) {
return t ( 'test.ws.test_source_db' )
}
if ( source === 'synthetic' ) {
return t ( 'test.ws.test_source_synthetic' )
}
return ''
} )
const logText = computed ( ( ) => {
if ( ! logs . value . length ) return t ( 'test.ws.log_empty' )
return logs . value
@@ -109,6 +156,20 @@ async function loadConfig() {
} else {
subscribeTopics . value = [ ... defaultSubscribeTopics ]
}
const rawOddsTopics = res . data . odds _push _topics
if ( Array . isArray ( rawOddsTopics ) ) {
oddsPushTopics . value = rawOddsTopics . filter ( ( x : unknown ) : x is string => typeof x === 'string' && x . trim ( ) !== '' )
} else {
oddsPushTopics . value = [ 'user.streak' , 'wallet.changed' , 'bet.accepted' ]
}
const rawOddsFields = res . data . player _odds _fields
if ( Array . isArray ( rawOddsFields ) ) {
playerOddsFields . value = rawOddsFields . filter ( ( x : unknown ) : x is string => typeof x === 'string' && x . trim ( ) !== '' )
} else {
playerOddsFields . value = [ 'current_streak' , 'streak_level' , 'odds_factor' , 'is_jackpot' ]
}
const rawTestOdds = res . data . test _player _odds
testPlayerOdds . value = rawTestOdds && typeof rawTestOdds === 'object' ? ( rawTestOdds as Record < string , unknown > ) : null
const firstSample = Array . isArray ( res . data . sample _messages ) && res . data . sample _messages . length ? String ( res . data . sample _messages [ 0 ] ) : ''
sendMessage . value = firstSample
ready . value = wsUrl . value !== ''
@@ -146,10 +207,22 @@ function connectWs() {
} )
}
socket . onmessage = ( event ) => {
const raw = typeof event . data === 'string' ? event . data : JSON . stringify ( event . data )
let eventName = 'ws.message'
try {
const parsed = JSON . parse ( raw ) as { event ? : string ; topic ? : string }
if ( typeof parsed . event === 'string' && parsed . event !== '' ) {
eventName = parsed . event
} else if ( typeof parsed . topic === 'string' && parsed . topic !== '' ) {
eventName = parsed . topic
}
} catch {
// keep default event name
}
appendLog ( {
t : Date . now ( ) ,
event : 'ws.message' ,
payload : typeof event . data === 'string' ? event . data : JSON . stringify ( event . data ) ,
event : eventName ,
payload : raw ,
} )
}
socket . onerror = ( ) => {
@@ -199,6 +272,10 @@ function sendWs() {
}
}
onMounted ( ( ) => {
void loadConfig ( )
} )
onUnmounted ( ( ) => {
disconnectWs ( )
clearLogs ( )
@@ -217,4 +294,21 @@ onUnmounted(() => {
color : var ( -- el - text - color - secondary ) ;
font - size : 13 px ;
}
. config - label {
color : var ( -- el - text - color - regular ) ;
font - size : 13 px ;
margin - right : 8 px ;
}
. mr - 4 {
margin - right : 4 px ;
}
. mb - 4 {
margin - bottom : 4 px ;
}
. test - odds - card {
margin - top : 12 px ;
}
. ml - 8 {
margin - left : 8 px ;
}
< / style >