1.修复自动创建下一期bug
This commit is contained in:
@@ -37,7 +37,6 @@
|
||||
>
|
||||
{{ t('game.live.void_btn') }}
|
||||
</el-button>
|
||||
<el-button :loading="loading" :disabled="asideOperationLocked" @click="loadSnapshot({ force: true })">{{ t('Refresh') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -277,12 +276,7 @@ const serverSkewSeconds = ref(0)
|
||||
/** 每秒递增,驱动派彩剩余秒本地刷新 */
|
||||
const clockTick = ref(0)
|
||||
let clockTimer: number | null = null
|
||||
let payoutStuckRefreshTimer: number | null = null
|
||||
let drawStuckRefreshTimer: number | null = null
|
||||
let drawStuckSeconds = 0
|
||||
let payoutPhaseStuckSeconds = 0
|
||||
let fallbackPollTimer: number | null = null
|
||||
let betStreamRefreshTimer: number | null = null
|
||||
/** 合并并发 snapshot 请求,避免 axios 重复请求取消导致控制台报错 */
|
||||
let snapshotLoadPromise: Promise<void> | null = null
|
||||
|
||||
@@ -350,16 +344,23 @@ function handleWsPayload(raw: unknown): void {
|
||||
snapshot.result_number = opened.result_number
|
||||
calcResultNumber.value = opened.result_number
|
||||
}
|
||||
void loadSnapshot({ force: true })
|
||||
if (typeof opened.payout_until === 'number' && opened.payout_until > 0 && snapshot.record) {
|
||||
snapshot.record.payout_until = opened.payout_until
|
||||
snapshot.is_payout_phase = true
|
||||
}
|
||||
return
|
||||
}
|
||||
if (event === 'admin.live.finalized' && parsed.data && typeof parsed.data === 'object') {
|
||||
const fin = parsed.data as anyObj
|
||||
snapshot.is_payout_phase = false
|
||||
snapshot.payout_remaining_seconds = 0
|
||||
if (toBool(fin.maintenance_ui) === true) {
|
||||
snapshot.is_payout_phase = false
|
||||
snapshot.payout_remaining_seconds = 0
|
||||
snapshot.maintenance_ui = true
|
||||
snapshot.record = null
|
||||
}
|
||||
if (toBool(fin.runtime_enabled) !== null) {
|
||||
snapshot.runtime_enabled = toBool(fin.runtime_enabled) === true
|
||||
}
|
||||
void loadSnapshot({ force: true })
|
||||
return
|
||||
}
|
||||
if (event === 'period.payout' && parsed.data && typeof parsed.data === 'object') {
|
||||
@@ -393,30 +394,7 @@ function handleWsPayload(raw: unknown): void {
|
||||
}
|
||||
if (event === 'period.tick' && parsed.data && typeof parsed.data === 'object') {
|
||||
handlePeriodTickEvent(parsed.data as anyObj)
|
||||
return
|
||||
}
|
||||
if (event === 'bet.accepted' && parsed.data && typeof parsed.data === 'object') {
|
||||
const betData = parsed.data as anyObj
|
||||
const periodNo = typeof betData.period_no === 'string' ? betData.period_no : ''
|
||||
const currentNo = typeof snapshot.record?.period_no === 'string' ? snapshot.record.period_no : ''
|
||||
if (periodNo !== '' && periodNo === currentNo) {
|
||||
scheduleBetStreamRefresh()
|
||||
} else if (!wsConnected.value) {
|
||||
void loadSnapshot({ force: true })
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
/** 有新下注时防抖拉取快照,补全 WS 每秒快照之间的下注列表 */
|
||||
function scheduleBetStreamRefresh(): void {
|
||||
if (betStreamRefreshTimer !== null) {
|
||||
window.clearTimeout(betStreamRefreshTimer)
|
||||
}
|
||||
betStreamRefreshTimer = window.setTimeout(() => {
|
||||
betStreamRefreshTimer = null
|
||||
void loadSnapshot({ force: true })
|
||||
}, 600)
|
||||
}
|
||||
|
||||
/** 用 period.tick 轻量字段刷新倒计时(不触发 HTTP,避免与 WS 每秒 snapshot 冲突) */
|
||||
@@ -457,18 +435,9 @@ function handlePeriodTickEvent(periodData: anyObj): void {
|
||||
if (runtimeOff && (status === 'betting' || status === 'locked')) {
|
||||
return
|
||||
}
|
||||
if (status === 'betting' && periodNo !== '' && periodNo !== currentNo) {
|
||||
void loadSnapshot({ force: true })
|
||||
return
|
||||
}
|
||||
if (status === 'finished') {
|
||||
snapshot.is_payout_phase = false
|
||||
snapshot.payout_remaining_seconds = 0
|
||||
void loadSnapshot({ force: true })
|
||||
return
|
||||
}
|
||||
if (currentNo === '' && periodNo !== '' && !runtimeOff) {
|
||||
void loadSnapshot({ force: true })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1015,96 +984,17 @@ const countdownParts = computed(() => {
|
||||
return { bet, draw, payout }
|
||||
})
|
||||
|
||||
/** 派彩倒计时从 >0 变为 0 时主动拉 HTTP 快照 */
|
||||
watch(payoutRemainingLive, (remain, prev) => {
|
||||
if (!snapshot.is_payout_phase || remain !== 0) {
|
||||
return
|
||||
}
|
||||
if (prev !== null && prev !== undefined && prev > 0) {
|
||||
schedulePayoutEndRefresh(400)
|
||||
}
|
||||
})
|
||||
|
||||
function schedulePayoutEndRefresh(delayMs: number): void {
|
||||
if (payoutStuckRefreshTimer !== null) {
|
||||
window.clearTimeout(payoutStuckRefreshTimer)
|
||||
}
|
||||
payoutStuckRefreshTimer = window.setTimeout(() => {
|
||||
payoutStuckRefreshTimer = null
|
||||
if (!snapshot.is_payout_phase) {
|
||||
return
|
||||
}
|
||||
void loadSnapshot({ force: true })
|
||||
}, delayMs)
|
||||
}
|
||||
|
||||
/** 下注/开奖倒计时均已归零但仍未进入派彩(常见于 live ticker 未跑或开奖锁竞争失败) */
|
||||
function isPrePayoutDrawStuck(): boolean {
|
||||
if (snapshot.is_payout_phase || !snapshot.can_calculate) {
|
||||
return false
|
||||
}
|
||||
const bet = snapshot.bet_remaining_seconds ?? 0
|
||||
const draw = snapshot.remaining_seconds ?? 0
|
||||
if (bet > 0 || draw > 0) {
|
||||
return false
|
||||
}
|
||||
const st = numberValue(snapshot.record?.status)
|
||||
return st === 0 || st === 1
|
||||
}
|
||||
|
||||
/** 派彩倒计时已为 0 但 is_payout_phase 仍为 true(关服排水时常见) */
|
||||
function tickPayoutPhaseStuckRecovery(): void {
|
||||
if (!snapshot.is_payout_phase) {
|
||||
payoutPhaseStuckSeconds = 0
|
||||
return
|
||||
}
|
||||
const remain = payoutRemainingLive.value
|
||||
if (remain === null || remain > 0) {
|
||||
payoutPhaseStuckSeconds = 0
|
||||
return
|
||||
}
|
||||
payoutPhaseStuckSeconds++
|
||||
if (payoutPhaseStuckSeconds >= 4) {
|
||||
payoutPhaseStuckSeconds = 0
|
||||
void loadSnapshot({ force: true })
|
||||
}
|
||||
}
|
||||
|
||||
function tickPrePayoutDrawStuckRecovery(): void {
|
||||
if (!isPrePayoutDrawStuck()) {
|
||||
drawStuckSeconds = 0
|
||||
if (drawStuckRefreshTimer !== null) {
|
||||
window.clearTimeout(drawStuckRefreshTimer)
|
||||
drawStuckRefreshTimer = null
|
||||
}
|
||||
return
|
||||
}
|
||||
drawStuckSeconds++
|
||||
if (drawStuckSeconds < 8 || drawStuckRefreshTimer !== null) {
|
||||
return
|
||||
}
|
||||
drawStuckRefreshTimer = window.setTimeout(() => {
|
||||
drawStuckRefreshTimer = null
|
||||
drawStuckSeconds = 0
|
||||
if (isPrePayoutDrawStuck()) {
|
||||
void loadSnapshot({ force: true })
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
updateIsMobile()
|
||||
window.addEventListener('resize', updateIsMobile)
|
||||
clockTimer = window.setInterval(() => {
|
||||
clockTick.value++
|
||||
tickPrePayoutDrawStuckRecovery()
|
||||
tickPayoutPhaseStuckRecovery()
|
||||
}, 1000)
|
||||
fallbackPollTimer = window.setInterval(() => {
|
||||
if (!wsConnected.value) {
|
||||
void loadSnapshot({ force: true })
|
||||
}
|
||||
}, 3000)
|
||||
}, 15000)
|
||||
await loadSnapshot({ force: true })
|
||||
await reloadWsConfig()
|
||||
connectWs()
|
||||
@@ -1121,18 +1011,6 @@ onUnmounted(() => {
|
||||
window.clearInterval(fallbackPollTimer)
|
||||
fallbackPollTimer = null
|
||||
}
|
||||
if (payoutStuckRefreshTimer !== null) {
|
||||
window.clearTimeout(payoutStuckRefreshTimer)
|
||||
payoutStuckRefreshTimer = null
|
||||
}
|
||||
if (drawStuckRefreshTimer !== null) {
|
||||
window.clearTimeout(drawStuckRefreshTimer)
|
||||
drawStuckRefreshTimer = null
|
||||
}
|
||||
if (betStreamRefreshTimer !== null) {
|
||||
window.clearTimeout(betStreamRefreshTimer)
|
||||
betStreamRefreshTimer = null
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user