9.2 KiB
Executable File
9.2 KiB
Executable File
多游戏独立期号系统更新说明
更新日期
2026-01-08
问题描述
原系统存在以下问题:
- 所有游戏共用一个期号队列 - 骰子游戏和 Xóc Đĩa 无法同时运行
- 开始下注时没有游戏选择 - 系统自动使用上一期的游戏ID
- 前台获取期号不区分游戏 - 导致不同游戏显示相同期号
解决方案
实现每个游戏独立维护自己的期号队列,允许多个游戏同时运行。
修改的文件
1. 后端控制器
App/Controllers/Admin/PeriodController.php
修改 start() 方法:
- 添加
game_id参数验证 - 检查该游戏是否有未结束的期号(而不是全局检查)
- 生成期号时传递
game_id
public function start() {
// 接收 game_id 参数
$gameId = isset($data['game_id']) ? (int)$data['game_id'] : 0;
// 检查该游戏是否有未结束的期号
$activePeriod = $db->get('periods', '*', [
'game_id' => $gameId,
'status' => ['pending', 'locked', 'drawn']
]);
// 生成期号时传递 game_id
$periodNumber = $this->generatePeriodNumber($db, $gameId);
}
App/Controllers/Web/PeriodController.php
修改 getCurrent() 方法:
- 添加
game_id参数验证 - 按游戏ID过滤期号
public function getCurrent() {
$gameId = isset($_GET['game_id']) ? (int)$_GET['game_id'] : 0;
// 获取该游戏最新的期号
$currentPeriod = $db->get('periods', '*', [
'game_id' => $gameId,
'ORDER' => ['id' => 'DESC']
]);
}
App/Controllers/Web/HomeController.php
已经正确实现:
live()方法已经按game_id过滤期号
2. 后台视图
App/Views/Admin/periods.php
添加游戏选择下拉框:
<!-- 当前期号卡片 -->
<select id="startGameSelect" class="px-3 py-2 border border-gray-300 rounded-lg text-sm bg-white">
<option value="">选择游戏</option>
<?php foreach ($games as $gid => $gname): ?>
<option value="<?= $gid ?>"><?= htmlspecialchars($gname) ?></option>
<?php endforeach; ?>
</select>
<button class="period-start-btn">开始下注</button>
修改开奖模态框:
- 添加游戏类型隐藏字段
- 添加 Xóc Đĩa 硬币输入界面
- 根据游戏类型动态显示输入界面
<input type="hidden" id="drawGameType" name="game_type">
<!-- 骰子游戏输入 -->
<div id="diceInputSection" class="grid grid-cols-3 gap-4">
<!-- 骰子1, 2, 3 -->
</div>
<!-- Xóc Đĩa 硬币输入 -->
<div id="xocdiaInputSection" class="hidden space-y-3">
<select id="coin1">
<option value="red">红色</option>
<option value="white">白色</option>
</select>
<!-- coin2, coin3, coin4 -->
</div>
修改JavaScript:
// 开始下注
async function startPeriod() {
const gameId = document.getElementById('startGameSelect').value;
if (!gameId) {
layer.msg('请先选择游戏', {icon: 2});
return;
}
fetch('/admin/periods/start', {
method: 'POST',
body: JSON.stringify({game_id: parseInt(gameId)})
});
}
// 打开开奖模态框
function openDrawPeriodModal(periodId) {
// 获取期号信息
fetch(`/admin/periods/${periodId}`)
.then(res => res.json())
.then(data => {
const gameId = data.data.game_id;
// 获取游戏类型
fetch(`/admin/games/${gameId}`)
.then(res => res.json())
.then(gameData => {
const gameType = gameData.data.type;
// 根据游戏类型显示不同界面
if (gameType === 'xocdia') {
document.getElementById('diceInputSection').classList.add('hidden');
document.getElementById('xocdiaInputSection').classList.remove('hidden');
} else {
document.getElementById('diceInputSection').classList.remove('hidden');
document.getElementById('xocdiaInputSection').classList.add('hidden');
}
});
});
}
// 提交开奖
async function submitDrawPeriod() {
const gameType = document.getElementById('drawGameType').value;
const data = {id: periodId, auto: false};
if (gameType === 'xocdia') {
// 收集硬币颜色
data.coins = [
document.getElementById('coin1').value,
document.getElementById('coin2').value,
document.getElementById('coin3').value,
document.getElementById('coin4').value
];
} else {
// 收集骰子点数
data.dice1 = parseInt(drawDice1.value);
data.dice2 = parseInt(drawDice2.value);
data.dice3 = parseInt(drawDice3.value);
}
fetch('/admin/periods/draw', {
method: 'POST',
body: JSON.stringify(data)
});
}
3. 前台视图
App/Views/Web/live.php
修改期号轮询:
function checkPeriodStatus() {
fetch('/api/period/current?game_id=' + currentGameId)
.then(res => res.json())
.then(data => {
// 更新期号状态
});
}
使用流程
后台管理员操作
-
开始新一期
- 进入后台 → 期号管理
- 从下拉框选择游戏(骰子游戏 或 Xóc Đĩa)
- 点击"开始下注"按钮
- 系统创建该游戏的新期号
-
录入开奖结果
- 点击期号列表中的"录入开奖"按钮
- 系统自动识别游戏类型:
- 骰子游戏:显示3个骰子输入框
- Xóc Đĩa:显示4个硬币颜色选择框
- 输入开奖结果并确认
-
结算
- 点击"确认结算"按钮
- 系统自动结算所有投注
- 可以继续为该游戏或其他游戏开始新一期
前台用户体验
-
进入游戏
- 访问首页,点击游戏卡片
- 系统自动获取该游戏的当前期号
-
投注
- 页面显示该游戏的倒计时和期号
- 只能对当前游戏的期号进行投注
-
多游戏并行
- 骰子游戏和 Xóc Đĩa 可以同时运行
- 每个游戏独立维护期号队列
- 互不干扰
数据库变更
无需修改数据库结构,现有的 periods 表已经包含 game_id 字段。
验证步骤
1. 后台验证
# 1. 访问后台期号管理
http://yourdomain.com/admin/periods
# 2. 选择"骰子游戏",点击"开始下注"
# 应该看到:新期号创建成功,期号格式为 G1YYYYMMDDNNNN
# 3. 选择"Xóc Đĩa",点击"开始下注"
# 应该看到:新期号创建成功,期号格式为 G2YYYYMMDDNNNN
# 4. 期号列表应该显示两个游戏的期号
2. 前台验证
# 1. 访问骰子游戏
http://yourdomain.com/live?game_id=1
# 应该看到:骰子游戏的期号和倒计时
# 2. 访问 Xóc Đĩa 游戏
http://yourdomain.com/live?game_id=2
# 应该看到:Xóc Đĩa 游戏的期号和倒计时
# 3. 两个游戏的期号应该不同
3. 开奖验证
# 1. 后台点击骰子游戏的"录入开奖"
# 应该看到:3个骰子输入框
# 2. 后台点击 Xóc Đĩa 的"录入开奖"
# 应该看到:4个硬币颜色选择框
故障排查
问题1:点击"开始下注"提示"请先选择游戏"
原因:未选择游戏
解决:从下拉框选择游戏后再点击按钮
问题2:前台显示"缺少游戏ID参数"
原因:URL 中没有 game_id 参数
解决:
# 错误的URL
http://yourdomain.com/live
# 正确的URL
http://yourdomain.com/live?game_id=1 # 骰子游戏
http://yourdomain.com/live?game_id=2 # Xóc Đĩa
问题3:开奖模态框显示错误的输入界面
原因:游戏类型获取失败
解决:
- 检查游戏记录的
type字段是否正确
SELECT id, name, type FROM games;
-- 应该看到:
-- 1 | Tài Xỉu | dice
-- 2 | Xóc Đĩa | xocdia
- 如果类型不正确,执行修复SQL
UPDATE games SET type='xocdia' WHERE name LIKE '%Xóc%';
技术细节
期号格式
G{GameID}{YYYYMMDD}{NNNN}
示例:
G120260108001 # 骰子游戏(game_id=1)2026年1月8日第1期
G220260108001 # Xóc Đĩa(game_id=2)2026年1月8日第1期
期号状态流转
pending (待开奖)
↓
locked (已封盘)
↓
drawn (已开奖)
↓
settled (已结算)
并发控制
- 每个游戏独立检查是否有未结束的期号
- 允许多个游戏同时处于
pending状态 - 不允许同一游戏有多个未结束的期号
兼容性说明
向后兼容
- 现有的骰子游戏功能完全保留
- 数据库结构无变更
- 前台URL需要添加
game_id参数
升级建议
-
更新前台链接
- 将所有
/live链接改为/live?game_id=X - 首页游戏卡片已经正确传递
game_id
- 将所有
-
清理旧期号(可选)
- 如果有未关联游戏的期号,建议手动关联
UPDATE periods SET game_id=1 WHERE game_id IS NULL OR game_id=0;
最后更新
2026-01-08