1.修复自动创建下一期bug
This commit is contained in:
@@ -616,6 +616,9 @@ final class GameLiveService
|
|||||||
if ($existingResult !== false && $existingResult >= 1 && $existingResult <= self::DRAW_NUMBER_MAX && $st >= 2) {
|
if ($existingResult !== false && $existingResult >= 1 && $existingResult <= self::DRAW_NUMBER_MAX && $st >= 2) {
|
||||||
Db::commit();
|
Db::commit();
|
||||||
$periodNo = is_string($record['period_no'] ?? null) ? (string) $record['period_no'] : '';
|
$periodNo = is_string($record['period_no'] ?? null) ? (string) $record['period_no'] : '';
|
||||||
|
GameHotDataCoordinator::afterGameRecordCommitted($rid);
|
||||||
|
self::publishSnapshot($rid);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'ok' => true,
|
'ok' => true,
|
||||||
'msg' => __('Draw completed; paying out'),
|
'msg' => __('Draw completed; paying out'),
|
||||||
@@ -755,15 +758,7 @@ final class GameLiveService
|
|||||||
|
|
||||||
public static function tickAutoDraw(): void
|
public static function tickAutoDraw(): void
|
||||||
{
|
{
|
||||||
if (!GameRecordService::isAutoCreateEnabled()) {
|
$record = self::resolveRecordForAutoDraw();
|
||||||
$record = Db::name('game_record')
|
|
||||||
->whereIn('status', [0, 1])
|
|
||||||
->order('id', 'asc')
|
|
||||||
->find();
|
|
||||||
$record = is_array($record) ? $record : null;
|
|
||||||
} else {
|
|
||||||
$record = self::resolveRecordForAutoDraw();
|
|
||||||
}
|
|
||||||
if (!$record || !in_array((int) $record['status'], [0, 1], true)) {
|
if (!$record || !in_array((int) $record['status'], [0, 1], true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -772,7 +767,15 @@ final class GameLiveService
|
|||||||
if ($elapsed < $periodSeconds) {
|
if ($elapsed < $periodSeconds) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self::drawResult((int) $record['id'], null);
|
$rid = (int) $record['id'];
|
||||||
|
$out = self::drawResult($rid, null);
|
||||||
|
if (!($out['ok'] ?? false)) {
|
||||||
|
Log::warning('tickAutoDraw: drawResult failed', [
|
||||||
|
'record_id' => $rid,
|
||||||
|
'period_no' => $record['period_no'] ?? '',
|
||||||
|
'msg' => $out['msg'] ?? '',
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -85,6 +85,9 @@ class GameWebSocketServer
|
|||||||
if (!$hasAdminSubscriber) {
|
if (!$hasAdminSubscriber) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 与 GameLiveTicker 对齐:仅推快照时若 live ticker 未运行会导致倒计时归零但永不开奖
|
||||||
|
GameLiveService::finalizePayoutGrace();
|
||||||
|
GameLiveService::tickAutoDraw();
|
||||||
$snapshot = GameLiveService::buildSnapshot(null);
|
$snapshot = GameLiveService::buildSnapshot(null);
|
||||||
$payload = json_encode([
|
$payload = json_encode([
|
||||||
'event' => 'admin.live.snapshot',
|
'event' => 'admin.live.snapshot',
|
||||||
|
|||||||
@@ -278,6 +278,8 @@ const serverSkewSeconds = ref(0)
|
|||||||
const clockTick = ref(0)
|
const clockTick = ref(0)
|
||||||
let clockTimer: number | null = null
|
let clockTimer: number | null = null
|
||||||
let payoutStuckRefreshTimer: number | null = null
|
let payoutStuckRefreshTimer: number | null = null
|
||||||
|
let drawStuckRefreshTimer: number | null = null
|
||||||
|
let drawStuckSeconds = 0
|
||||||
let fallbackPollTimer: number | null = null
|
let fallbackPollTimer: number | null = null
|
||||||
let betStreamRefreshTimer: number | null = null
|
let betStreamRefreshTimer: number | null = null
|
||||||
/** 合并并发 snapshot 请求,避免 axios 重复请求取消导致控制台报错 */
|
/** 合并并发 snapshot 请求,避免 axios 重复请求取消导致控制台报错 */
|
||||||
@@ -1003,10 +1005,44 @@ function schedulePayoutEndRefresh(delayMs: number): void {
|
|||||||
if (!snapshot.is_payout_phase) {
|
if (!snapshot.is_payout_phase) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!wsConnected.value) {
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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 })
|
void loadSnapshot({ force: true })
|
||||||
}
|
}
|
||||||
}, delayMs)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@@ -1014,6 +1050,7 @@ onMounted(async () => {
|
|||||||
window.addEventListener('resize', updateIsMobile)
|
window.addEventListener('resize', updateIsMobile)
|
||||||
clockTimer = window.setInterval(() => {
|
clockTimer = window.setInterval(() => {
|
||||||
clockTick.value++
|
clockTick.value++
|
||||||
|
tickPrePayoutDrawStuckRecovery()
|
||||||
}, 1000)
|
}, 1000)
|
||||||
fallbackPollTimer = window.setInterval(() => {
|
fallbackPollTimer = window.setInterval(() => {
|
||||||
if (!wsConnected.value) {
|
if (!wsConnected.value) {
|
||||||
@@ -1040,6 +1077,10 @@ onUnmounted(() => {
|
|||||||
window.clearTimeout(payoutStuckRefreshTimer)
|
window.clearTimeout(payoutStuckRefreshTimer)
|
||||||
payoutStuckRefreshTimer = null
|
payoutStuckRefreshTimer = null
|
||||||
}
|
}
|
||||||
|
if (drawStuckRefreshTimer !== null) {
|
||||||
|
window.clearTimeout(drawStuckRefreshTimer)
|
||||||
|
drawStuckRefreshTimer = null
|
||||||
|
}
|
||||||
if (betStreamRefreshTimer !== null) {
|
if (betStreamRefreshTimer !== null) {
|
||||||
window.clearTimeout(betStreamRefreshTimer)
|
window.clearTimeout(betStreamRefreshTimer)
|
||||||
betStreamRefreshTimer = null
|
betStreamRefreshTimer = null
|
||||||
|
|||||||
Reference in New Issue
Block a user