Files
pk10/Docs/MULTI_GAME_PERIOD_UPDATE.md

397 lines
9.2 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 多游戏独立期号系统更新说明
## 更新日期
2026-01-08
## 问题描述
原系统存在以下问题:
1. **所有游戏共用一个期号队列** - 骰子游戏和 Xóc Đĩa 无法同时运行
2. **开始下注时没有游戏选择** - 系统自动使用上一期的游戏ID
3. **前台获取期号不区分游戏** - 导致不同游戏显示相同期号
## 解决方案
实现**每个游戏独立维护自己的期号队列**,允许多个游戏同时运行。
---
## 修改的文件
### 1. 后端控制器
#### `App/Controllers/Admin/PeriodController.php`
**修改 `start()` 方法**
- 添加 `game_id` 参数验证
- 检查该游戏是否有未结束的期号(而不是全局检查)
- 生成期号时传递 `game_id`
```php
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过滤期号
```php
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`
**添加游戏选择下拉框**
```html
<!-- 当前期号卡片 -->
<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 硬币输入界面
- 根据游戏类型动态显示输入界面
```html
<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**
```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`
**修改期号轮询**
```javascript
function checkPeriodStatus() {
fetch('/api/period/current?game_id=' + currentGameId)
.then(res => res.json())
.then(data => {
// 更新期号状态
});
}
```
---
## 使用流程
### 后台管理员操作
1. **开始新一期**
- 进入后台 → 期号管理
- 从下拉框选择游戏(骰子游戏 或 Xóc Đĩa)
- 点击"开始下注"按钮
- 系统创建该游戏的新期号
2. **录入开奖结果**
- 点击期号列表中的"录入开奖"按钮
- 系统自动识别游戏类型:
- **骰子游戏**:显示3个骰子输入框
- **Xóc Đĩa**:显示4个硬币颜色选择框
- 输入开奖结果并确认
3. **结算**
- 点击"确认结算"按钮
- 系统自动结算所有投注
- 可以继续为该游戏或其他游戏开始新一期
### 前台用户体验
1. **进入游戏**
- 访问首页,点击游戏卡片
- 系统自动获取该游戏的当前期号
2. **投注**
- 页面显示该游戏的倒计时和期号
- 只能对当前游戏的期号进行投注
3. **多游戏并行**
- 骰子游戏和 Xóc Đĩa 可以同时运行
- 每个游戏独立维护期号队列
- 互不干扰
---
## 数据库变更
**无需修改数据库结构**,现有的 `periods` 表已经包含 `game_id` 字段。
---
## 验证步骤
### 1. 后台验证
```bash
# 1. 访问后台期号管理
http://yourdomain.com/admin/periods
# 2. 选择"骰子游戏",点击"开始下注"
# 应该看到:新期号创建成功,期号格式为 G1YYYYMMDDNNNN
# 3. 选择"Xóc Đĩa",点击"开始下注"
# 应该看到:新期号创建成功,期号格式为 G2YYYYMMDDNNNN
# 4. 期号列表应该显示两个游戏的期号
```
### 2. 前台验证
```bash
# 1. 访问骰子游戏
http://yourdomain.com/live?game_id=1
# 应该看到:骰子游戏的期号和倒计时
# 2. 访问 Xóc Đĩa 游戏
http://yourdomain.com/live?game_id=2
# 应该看到:Xóc Đĩa 游戏的期号和倒计时
# 3. 两个游戏的期号应该不同
```
### 3. 开奖验证
```bash
# 1. 后台点击骰子游戏的"录入开奖"
# 应该看到:3个骰子输入框
# 2. 后台点击 Xóc Đĩa 的"录入开奖"
# 应该看到:4个硬币颜色选择框
```
---
## 故障排查
### 问题1:点击"开始下注"提示"请先选择游戏"
**原因**:未选择游戏
**解决**:从下拉框选择游戏后再点击按钮
---
### 问题2:前台显示"缺少游戏ID参数"
**原因**URL 中没有 `game_id` 参数
**解决**
```bash
# 错误的URL
http://yourdomain.com/live
# 正确的URL
http://yourdomain.com/live?game_id=1 # 骰子游戏
http://yourdomain.com/live?game_id=2 # Xóc Đĩa
```
---
### 问题3:开奖模态框显示错误的输入界面
**原因**:游戏类型获取失败
**解决**
1. 检查游戏记录的 `type` 字段是否正确
```sql
SELECT id, name, type FROM games;
-- 应该看到:
-- 1 | Tài Xỉu | dice
-- 2 | Xóc Đĩa | xocdia
```
2. 如果类型不正确,执行修复SQL
```sql
UPDATE games SET type='xocdia' WHERE name LIKE '%Xóc%';
```
---
## 技术细节
### 期号格式
```
G{GameID}{YYYYMMDD}{NNNN}
示例:
G120260108001 # 骰子游戏(game_id=12026年1月8日第1期
G220260108001 # Xóc Đĩagame_id=22026年1月8日第1期
```
### 期号状态流转
```
pending (待开奖)
locked (已封盘)
drawn (已开奖)
settled (已结算)
```
### 并发控制
- 每个游戏独立检查是否有未结束的期号
- 允许多个游戏同时处于 `pending` 状态
- 不允许同一游戏有多个未结束的期号
---
## 兼容性说明
### 向后兼容
- 现有的骰子游戏功能完全保留
- 数据库结构无变更
- 前台URL需要添加 `game_id` 参数
### 升级建议
1. **更新前台链接**
- 将所有 `/live` 链接改为 `/live?game_id=X`
- 首页游戏卡片已经正确传递 `game_id`
2. **清理旧期号**(可选)
- 如果有未关联游戏的期号,建议手动关联
```sql
UPDATE periods SET game_id=1 WHERE game_id IS NULL OR game_id=0;
```
---
## 最后更新
2026-01-08
## 相关文档
- [Xóc Đĩa 集成指南](./XOCDIA_INTEGRATION_GUIDE.md)
- [宝塔快速部署修复指南](./BAOTA_DEPLOYMENT_QUICK_FIX.md)