Initial commit: 投注游戏平台初始化

This commit is contained in:
li
2026-02-25 01:26:58 +08:00
commit 77ca2cc8b3
275 changed files with 237479 additions and 0 deletions
+273
View File
@@ -0,0 +1,273 @@
# 🚀 宝塔快速部署修复指南
## 问题现状
1. ❌ 后台游戏类型下拉菜单没有"Xóc Đĩa"选项
2. ❌ 玩法标签缺少适合 Xóc Đĩa 的选项
3. ❌ 前台显示的是骰子游戏的投注面板(不是 Xóc Đĩa 面板)
4. ❌ 没有直播画面
---
## ✅ 解决方案
### 第一步:上传修改的文件
#### 📁 需要替换的文件(共5个)
```
1. App/Views/Admin/games.php ← 已修复游戏类型和标签选项
2. App/Controllers/Web/HomeController.php
3. App/Controllers/Web/BetController.php
4. App/Controllers/Admin/PeriodController.php
5. App/Views/Web/live.php
```
#### 📦 需要新增的文件(共2个)
```
1. App/Views/Web/components/xocdia-bet-panel.php ← Xóc Đĩa 投注面板
2. Db/fix_xocdia_game.sql ← 快速修复SQL
```
---
### 第二步:宝塔文件上传操作
#### 🔧 方式1:通过宝塔文件管理器(推荐)
1. **备份原文件**
```
登录宝塔 → 文件管理
→ 导航到网站根目录
→ 找到以下文件并重命名(加 .bak 后缀):
- App/Views/Admin/games.php → games.php.bak
- App/Controllers/Web/HomeController.php → HomeController.php.bak
- App/Controllers/Web/BetController.php → BetController.php.bak
- App/Controllers/Admin/PeriodController.php → PeriodController.php.bak
- App/Views/Web/live.php → live.php.bak
```
2. **上传新文件**
```
→ 创建目录:App/Views/Web/components/
→ 上传 xocdia-bet-panel.php 到该目录
→ 上传其他5个修改的文件到对应位置
→ 上传 fix_xocdia_game.sql 到 Db/ 目录
```
3. **设置权限**
```
→ 选中所有上传的 .php 文件
→ 右键 → 权限 → 设置为 644
```
---
### 第三步:执行修复SQL脚本
#### 🗄️ 通过 phpMyAdmin(最简单)
```
宝塔面板
→ 数据库
→ 点击您的数据库名 → phpMyAdmin
→ SQL 标签页
→ 复制粘贴 fix_xocdia_game.sql 的全部内容
→ 点击"执行"
```
**预期结果**
```
应该看到查询结果:
game_id | name | code | type | status | featured | odds_count
--------|----------|---------|---------|--------|----------|------------
2 | Xóc Đĩa | xocdia | xocdia | 1 | 1 | 6
如果 odds_count = 6,说明修复成功!
```
#### 🔍 如果遇到错误
**错误1Duplicate entry for key 'PRIMARY'**
```sql
-- 说明游戏已存在,只需要更新类型
UPDATE games
SET type = 'xocdia', code = 'xocdia', tags = 'hot,traditional'
WHERE name LIKE '%Xóc%' OR name LIKE '%色碟%';
```
**错误2Table 'game_odds' doesn't exist**
```sql
-- 需要先创建 game_odds 表(执行完整的 xocdia_setup.sql
```
---
### 第四步:验证修复
#### ✅ 检查清单
1. **后台验证**
```
访问:http://您的域名/admin/games
→ 点击"新增游戏"
→ 检查"游戏类型"下拉菜单:
☐ 骰子游戏
☐ Xóc Đĩa(色碟) ← 应该有这个选项
☐ 其他
```
2. **数据库验证**
```sql
-- 在 phpMyAdmin 执行
SELECT id, name, code, type, status FROM games WHERE code='xocdia';
-- 应该返回:
-- id | name | code | type | status
-- ---|---------|--------|--------|--------
-- 2 | Xóc Đĩa | xocdia | xocdia | 1
```
3. **前台验证**
```
访问:http://您的域名/
→ 应该看到 Xóc Đĩa 游戏卡片
→ 点击进入游戏
→ 应该看到 Xóc Đĩa 投注面板(双/单 + 精确组合)
→ 不应该看到骰子游戏的界面
```
---
### 第五步:配置直播流(可选)
如果您有直播流地址:
```
后台 → 游戏管理 → 编辑 Xóc Đĩa
→ 直播流地址:填写您的 HLS/FLV 地址
例如:https://your-cdn.com/live/xocdia.m3u8
→ 保存
```
如果暂时没有直播:
```
可以先不填,系统会正常运行,只是没有视频画面
```
---
## 🔍 故障排查
### 问题1:前台仍然显示骰子游戏界面
**原因**:游戏的 `type` 字段不是 'xocdia'
**解决**
```sql
-- 在 phpMyAdmin 执行
SELECT id, name, type FROM games WHERE name LIKE '%Xóc%';
-- 如果 type 不是 'xocdia',执行:
UPDATE games SET type='xocdia' WHERE name LIKE '%Xóc%';
```
---
### 问题2:后台看不到游戏类型选项
**原因**games.php 文件没有替换成功
**解决**
```
1. 检查文件是否上传:
App/Views/Admin/games.php
2. 检查文件大小是否与本地一致
3. 清除浏览器缓存(Ctrl+F5
```
---
### 问题3:点击游戏后页面空白或500错误
**原因**:组件文件缺失或权限错误
**解决**
```
1. 检查文件是否存在:
App/Views/Web/components/xocdia-bet-panel.php
2. 检查文件权限:
chmod 644 App/Views/Web/components/xocdia-bet-panel.php
3. 查看错误日志:
宝塔 → 网站 → 日志 → PHP错误日志
```
---
### 问题4:投注后提示"赔率无效"
**原因**game_odds 表中缺少赔率配置
**解决**
```sql
-- 重新执行赔率配置(在 phpMyAdmin
SET @xocdia_game_id = (SELECT id FROM games WHERE code='xocdia');
DELETE FROM game_odds WHERE game_id = @xocdia_game_id;
INSERT INTO game_odds (game_id, type, target, odds, created_at) VALUES
(@xocdia_game_id, 'chan', 'all', 0.96, NOW()),
(@xocdia_game_id, 'le', 'all', 0.96, NOW()),
(@xocdia_game_id, 'exact', '4red', 10.0, NOW()),
(@xocdia_game_id, 'exact', '4white', 10.0, NOW()),
(@xocdia_game_id, 'exact', '3red1white', 3.5, NOW()),
(@xocdia_game_id, 'exact', '3white1red', 3.5, NOW());
```
---
## 📝 完整操作总结
### 宝塔操作步骤(按顺序)
```
1. 【文件管理】备份原文件(重命名加.bak)
2. 【文件管理】创建 components 目录
3. 【文件管理】上传7个文件(5个替换 + 2个新增)
4. 【文件管理】设置权限为 644
5. 【数据库】→ phpMyAdmin → 执行 fix_xocdia_game.sql
6. 【浏览器】清除缓存
7. 【后台】验证游戏类型选项
8. 【前台】验证 Xóc Đĩa 界面
```
---
## ⏱️ 预计耗时
- 文件上传:5-10分钟
- 执行SQL1分钟
- 验证测试:5分钟
- **总计:15分钟左右**
---
## 📞 需要帮助?
如果遇到问题,请提供:
1. 错误截图
2. PHP错误日志(宝塔 → 网站 → 日志)
3. 数据库查询结果:
```sql
SELECT id, name, code, type FROM games;
```
---
**最后更新**: 2026-01-08
**适用版本**: TM68 投注平台
+396
View File
@@ -0,0 +1,396 @@
# 多游戏独立期号系统更新说明
## 更新日期
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)
+319
View File
@@ -0,0 +1,319 @@
# 期号问题快速修复指南
## 问题描述
用户报告:
1. **新游戏显示老游戏的开奖信息** - Xóc Đĩa 显示骰子游戏的历史记录
2. **无法正常下注** - 投注时提示错误
## 根本原因
1. **历史开奖记录是硬编码的** - 前台页面使用固定的示例数据
2. **期号状态可能不正确** - 需要确认期号是否处于 `pending` 状态
---
## 解决方案
### 1. 修改的文件
已修改以下文件以支持动态历史记录:
#### `App/Controllers/Web/HomeController.php`
- 添加获取历史开奖记录的代码
- 传递 `recentPeriods` 变量到视图
#### `App/Views/Web/live.php`
- 将硬编码的历史记录改为动态生成
- 根据游戏类型显示不同的历史记录格式
---
### 2. 验证步骤
#### 步骤1:检查数据库中的期号
```sql
-- 查看所有期号
SELECT id, period_number, game_id, status, created_at
FROM periods
ORDER BY id DESC
LIMIT 10;
-- 应该看到:
-- 骰子游戏(game_id=1)和 Xóc Đĩagame_id=2)的期号分开
```
#### 步骤2:检查当前期号状态
```sql
-- 查看 Xóc Đĩa 的当前期号
SELECT id, period_number, game_id, status, start_time
FROM periods
WHERE game_id = 2
ORDER BY id DESC
LIMIT 1;
-- 状态应该是 'pending'
-- start_time 应该是最近的时间
```
#### 步骤3:如果期号状态不对
```sql
-- 如果状态是 'locked' 或其他,重置为 'pending'
UPDATE periods
SET status = 'pending', start_time = NOW()
WHERE id = [ID];
```
#### 步骤4:检查游戏配置
```sql
-- 确认游戏类型正确
SELECT id, name, code, type, status
FROM games;
-- 应该看到:
-- 1 | Tài Xỉu | dice | dice | 1
-- 2 | Xóc Đĩa | xocdia | xocdia | 1
```
---
### 3. 投注失败的常见原因
#### 原因1:期号状态不是 pending
**检查**
```sql
SELECT id, period_number, status FROM periods WHERE game_id = 2 ORDER BY id DESC LIMIT 1;
```
**修复**
```sql
UPDATE periods SET status = 'pending' WHERE id = [ID];
```
#### 原因2:投注时间超过60秒
**检查**
```sql
SELECT id, period_number, start_time,
TIMESTAMPDIFF(SECOND, start_time, NOW()) as elapsed_seconds
FROM periods
WHERE game_id = 2
ORDER BY id DESC
LIMIT 1;
-- 如果 elapsed_seconds > 60,说明已经超时
```
**修复**
```sql
-- 重置开始时间
UPDATE periods SET start_time = NOW() WHERE id = [ID];
```
#### 原因3:期号不存在
**检查**
```sql
-- 查看是否有 Xóc Đĩa 的期号
SELECT COUNT(*) FROM periods WHERE game_id = 2;
```
**修复**
- 进入后台 → 期号管理
- 选择"Xóc Đĩa"游戏
- 点击"开始下注"
---
### 4. 完整的重置流程
如果问题仍然存在,执行以下完整重置:
```sql
-- 1. 删除 Xóc Đĩa 的所有旧期号(可选,谨慎操作)
-- DELETE FROM periods WHERE game_id = 2;
-- 2. 确认游戏配置正确
UPDATE games SET type = 'xocdia', code = 'xocdia' WHERE name LIKE '%Xóc%';
-- 3. 通过后台创建新期号
-- 进入后台 → 期号管理 → 选择 Xóc Đĩa → 开始下注
```
---
### 5. 前台测试
#### 测试1:访问游戏页面
```bash
# 访问 Xóc Đĩa 游戏
http://yourdomain.com/live?game_id=2
# 应该看到:
# - 期号显示(例如:G220260108001
# - 倒计时(60秒)
# - 历史记录为空或显示 Xóc Đĩa 的历史
```
#### 测试2:投注
1. 选择筹码金额
2. 点击投注区域(双/单 或 精确组合)
3. 点击"ĐẶT CƯỢC"确认
4. 应该看到"Đặt cược thành công!"提示
#### 测试3:查看投注记录
```sql
-- 查看最新的投注记录
SELECT id, user_id, period_id, bet_type, bet_value, amount, status
FROM bets
ORDER BY id DESC
LIMIT 5;
-- 应该看到刚才的投注记录
```
---
### 6. 浏览器控制台调试
打开浏览器开发者工具(F12),查看 Console 和 Network 标签:
#### Console 错误
如果看到错误信息,记录下来:
```
Poll error: ...
Bet error: ...
```
#### Network 请求
查看以下请求是否成功:
1. **期号轮询**`/api/period/current?game_id=2`
- 应该返回:`{"success":true,"data":{...}}`
- 如果返回 `success: false`,说明期号不存在
2. **投注请求**`/api/bet`
- 应该返回:`{"success":true,"new_balance":...}`
- 如果返回 `success: false`,查看 `message` 字段
---
### 7. 后台日志
如果问题仍然存在,检查后台日志:
```bash
# 查看 PHP 错误日志
tail -f /path/to/touzi/Storage/log/error.log
# 或者查看宝塔面板的日志
# 宝塔 → 网站 → 日志 → PHP错误日志
```
---
## 常见错误信息
### "Kỳ quay không tồn tại"(期号不存在)
**原因**:数据库中没有该游戏的 pending 期号
**解决**
1. 进入后台期号管理
2. 选择游戏
3. 点击"开始下注"
---
### "Kỳ quay đã đóng hoặc đang xử lý"(期号已关闭)
**原因**:期号状态不是 `pending`
**解决**
```sql
UPDATE periods SET status = 'pending' WHERE id = [ID];
```
---
### "Đã hết thời gian đặt cược"(投注时间已过)
**原因**:距离开始时间超过60秒
**解决**
```sql
UPDATE periods SET start_time = NOW() WHERE id = [ID];
```
---
### "Dữ liệu không hợp lệ"(数据无效)
**原因**:前端发送的数据格式不正确
**解决**
1. 检查浏览器 Console 是否有 JavaScript 错误
2. 确认 `currentGameId` 变量是否正确
3. 刷新页面重试
---
## 预防措施
### 1. 定期检查期号状态
```sql
-- 查看所有未结算的期号
SELECT id, period_number, game_id, status, start_time
FROM periods
WHERE status IN ('pending', 'locked', 'drawn')
ORDER BY id DESC;
```
### 2. 自动封盘机制
前台已经实现自动封盘:
- 60秒后自动将 `pending` 改为 `locked`
- 但需要有用户访问页面触发
### 3. 后台操作流程
标准流程:
1. 开始下注(创建 pending 期号)
2. 等待60秒或手动封盘
3. 录入开奖结果(状态变为 drawn)
4. 确认结算(状态变为 settled)
5. 重复步骤1
---
## 联系支持
如果以上步骤都无法解决问题,请提供:
1. **数据库查询结果**
```sql
SELECT * FROM periods WHERE game_id = 2 ORDER BY id DESC LIMIT 3;
SELECT * FROM games WHERE id = 2;
```
2. **浏览器 Console 错误**:截图或复制错误信息
3. **Network 请求详情**
- `/api/period/current?game_id=2` 的响应
- `/api/bet` 的请求和响应
---
**最后更新**: 2026-01-08
**适用版本**: TM68 投注平台
+480
View File
@@ -0,0 +1,480 @@
# Xóc Đĩa 游戏后台管理使用指南
## 目录
1. [快速开始](#快速开始)
2. [数据库初始化](#数据库初始化)
3. [房间配置管理](#房间配置管理)
4. [期号管理流程](#期号管理流程)
5. [实时监控](#实时监控)
6. [常见问题](#常见问题)
---
## 快速开始
### 访问地址
- **房间配置管理**: `http://yourdomain.com/admin/xocdia/rooms`
- **期号管理**: `http://yourdomain.com/admin/xocdia/periods`
- **实时监控**: `http://yourdomain.com/admin/xocdia/monitor?room_id=1`
### 前置条件
1. 已完成系统安装(`/install`
2. 已创建管理员账号并登录后台
3. 已执行数据库初始化脚本
---
## 数据库初始化
### 步骤1:导入数据库表结构
连接到 MySQL 数据库,执行以下命令:
```bash
mysql -u your_username -p your_database < Db/xocdia_schema.sql
```
或者通过 phpMyAdmin 导入 `Db/xocdia_schema.sql` 文件。
### 步骤2:验证表是否创建成功
```sql
SHOW TABLES LIKE 'xd_%';
```
应该看到以下表:
- `xd_room_config` - 房间配置表
- `xd_periods` - 期号表
- `xd_bets` - 投注记录表
- `xd_settlements` - 结算汇总表
- `xd_bet_stats` - 实时投注统计表
### 步骤3:查看默认房间
数据库初始化时已自动创建两个默认房间:
```sql
SELECT room_id, room_name, room_type FROM xd_room_config;
```
- **Room 1**: Bàn Thu Phế (抽水台) - 标准抽水 5%
- **Room 2**: Bàn Xâu 3 Đen (免水台) - 特殊规则,3红1白时退款
---
## 房间配置管理
### 访问房间列表
1. 登录后台后,访问 `/admin/xocdia/rooms`
2. 可以看到所有房间的列表
### 创建新房间
**注意**:当前版本暂不支持通过界面创建房间,请直接修改数据库或复制以下 SQL:
```sql
INSERT INTO xd_room_config (room_id, room_name, room_type, odds, limits, timing)
VALUES (
3, -- 新房间ID
'高级房', -- 房间名称
'commission', -- 房间类型
JSON_OBJECT(
'even', 1.0,
'odd', 1.0,
'four_red', 12.0, -- 可自定义赔率
'four_white', 12.0,
'three_red', 4.0,
'three_white', 4.0
),
JSON_OBJECT(
'min_bet', 100, -- 最小投注
'max_bet', 100000, -- 最大投注
'max_payout', 1000000
),
JSON_OBJECT(
'betting_duration', 60, -- 下注时长60秒
'result_display_duration', 10,
'auto_start_next', true
)
);
```
### 编辑房间配置
#### 方式1:通过后台界面
1. 在房间列表点击"编辑"按钮
2. 修改以下配置项:
**基本设置**
- 房间名称
- 房间类型(抽水台/免水台)
- 抽水比例(仅抽水台)
**赔率配置**
- 双 (Chẵn) - 默认 1.0
- 单 (Lẻ) - 默认 1.0
- 4红 - 默认 10.0
- 4白 - 默认 10.0
- 3红1白 - 默认 3.5
- 3白1红 - 默认 3.5
**限红配置**
- 最小投注:建议 10-100
- 最大投注:建议 50000-100000
- 最大赔付:建议 500000-1000000
**时间配置**
- 下注时长:建议 30-60 秒
3. 点击"保存配置"
#### 方式2:直接修改数据库
```sql
-- 修改赔率
UPDATE xd_room_config
SET odds = JSON_OBJECT(
'even', 1.0,
'odd', 1.0,
'four_red', 15.0, -- 修改赔率
'four_white', 15.0,
'three_red', 5.0,
'three_white', 5.0
),
version = version + 1 -- 版本号加1
WHERE room_id = 1;
```
### 配置生效时机
⚠️ **重要**:配置修改后,**下一期号开始时**才会生效。
- 当前正在进行的期号使用"配置快照",不受影响
- 新开始的期号会读取最新配置
### 开放/关闭房间
1. 在房间列表点击"开放"或"关闭"按钮
2. 关闭的房间无法开始新期号
---
## 期号管理流程
### 完整流程图
```
开始新期号 → 下注阶段 (30-60s) → 封盘 → 开奖 → 自动结算 → 展示结果 → 完成
```
### 步骤1:开始新期号
1. 访问 `/admin/xocdia/periods`
2. 选择房间
3. 点击"开始新期号"按钮
**自动执行的操作**
- 生成期号(格式:`YYYYMMDD-001`
- 快照当前房间配置
- 初始化投注统计表
- 设置状态为 `betting`
### 步骤2:下注阶段
此时前台用户可以下注。
**管理员可以**
- 实时查看投注统计(访问监控页面)
- 手动封盘(提前结束下注)
**自动封盘**
- 如果配置了倒计时,到时间后自动封盘(需 WebSocket 支持)
### 步骤3:封盘
1. 在期号列表找到状态为"下注中"的期号
2. 点击"封盘"按钮
**自动执行的操作**
- 设置状态为 `shaking`
- 记录封盘时间
- 拒绝新的投注请求
### 步骤4:开奖
1. 在期号列表找到状态为"摇碟中"的期号
2. 点击"开奖"按钮
3. 在弹窗中选择 4 枚硬币的结果:
- **1 = 红色 (Đen)**
- **0 = 白色 (Trắng)**
**示例结果**
- `[1, 1, 1, 0]` = 3红1白 = `3_red_1_white`
- `[1, 1, 1, 1]` = 4红 = `4_red`
- `[0, 0, 0, 0]` = 4白 = `4_white`
4. 点击"确认开奖并结算"
### 步骤5:自动结算
开奖后,系统自动执行以下操作:
1. **判断输赢**
- 遍历所有投注记录
- 根据开奖结果判断是否赢
2. **计算赔付**
- 赢的投注:`赢得金额 = 投注金额 × 赔率`
- 输的投注:`净盈亏 = -投注金额`
3. **应用佣金**(仅抽水台)
- `佣金 = 赢得金额 × 佣金率`
- `净盈亏 = 赢得金额 - 佣金`
4. **应用特殊规则**(仅免水台)
- 检查是否触发特殊规则(如 3红1白)
- 如果触发:
- `action=refund`: 退款,净盈亏 = 0
- `action=half_win`: 只赢一半
- `action=lose`: 强制输
5. **更新余额**
- 更新所有玩家的余额
- 记录交易流水
6. **生成结算汇总**
- 总投注笔数
- 总投注金额
- 总赢得金额
- 总佣金
- **庄家盈利** = 总投注额 - (总赢得金额 - 总佣金)
7. **完成**
- 设置状态为 `showing`
### 步骤6:查看结算详情
1. 点击期号的"详情"按钮
2. 查看:
- 开奖结果
- 投注统计
- 结算数据
- 庄家盈亏
---
## 实时监控
### 访问监控页面
```
/admin/xocdia/monitor?room_id=1
```
### 监控内容
1. **当前期号信息**
- 期号
- 状态
- 倒计时(如果在下注阶段)
2. **实时投注统计**(需要数据库触发器或定时刷新)
- 各投注项的金额
- 各投注项的笔数
- 单边倾斜预警
3. **赔付预测**
- 如果结果是 X,庄家盈亏多少
- 最差情况/最佳情况分析
---
## 常见问题
### Q1: 配置修改后为什么还是旧的赔率?
**答**:当前期号使用的是"配置快照",修改不会影响正在进行的期号。新期号开始后才会使用新配置。
---
### Q2: 如何验证结算是否正确?
**答**:可以手动计算验证:
```sql
-- 查看某期号的结算汇总
SELECT * FROM xd_settlements WHERE period_id = 123;
-- 查看详细投注记录
SELECT
bet_type,
COUNT(*) as count,
SUM(bet_amount) as total_bet,
SUM(win_amount) as total_win,
SUM(commission) as total_commission,
SUM(net_profit) as total_profit
FROM xd_bets
WHERE period_id = 123
GROUP BY bet_type;
```
验证公式:
```
庄家盈利 = 总投注额 - (总赢得金额 - 总佣金)
= 总投注额 - 玩家净盈亏总和
```
---
### Q3: 如何处理误操作开奖?
**答**:当前版本不支持撤销开奖。如果误操作:
1. **紧急方案**:直接修改数据库
```sql
-- 回滚期号状态(谨慎操作!)
UPDATE xd_periods SET state = 'shaking', result = NULL WHERE id = 123;
-- 删除结算记录
DELETE FROM xd_settlements WHERE period_id = 123;
-- 回滚投注记录
UPDATE xd_bets SET status = 'pending', is_win = 0, win_amount = 0, commission = 0, net_profit = 0 WHERE period_id = 123;
-- 手动调整受影响用户的余额(需逐个计算)
```
2. **推荐方案**:联系技术团队处理
---
### Q4: 特殊规则如何配置?
**答**:修改 `special_rule` 字段(JSON 格式):
```sql
UPDATE xd_room_config
SET special_rule = JSON_OBJECT(
'enabled', true,
'trigger_result', '3_red_1_white', -- 触发条件:3红1白
'affected_bet_types', JSON_ARRAY('odd'), -- 影响的投注类型
'action', 'refund', -- 动作:refund/half_win/lose
'refund_percentage', 1.0 -- 退款比例(1.0=100%
),
version = version + 1
WHERE room_id = 2;
```
**常见配置示例**
| 规则名称 | trigger_result | affected_bet_types | action | refund_percentage |
|---------|----------------|-------------------|--------|------------------|
| Xâu 3 Đen 全退款 | 3_red_1_white | ['odd'] | refund | 1.0 |
| Xâu 3 Đen 半退款 | 3_red_1_white | ['odd'] | refund | 0.5 |
| Xâu 3 Đen 只赢一半 | 3_red_1_white | ['odd'] | half_win | - |
| Xâu 3 Đen 强制输 | 3_red_1_white | ['odd'] | lose | - |
---
### Q5: 如何查看房间盈亏统计?
**答**:执行以下 SQL
```sql
-- 查看某房间今日盈亏
SELECT
SUM(house_profit) as total_profit,
SUM(total_bets_amount) as total_bets,
SUM(total_commission) as total_commission,
COUNT(*) as period_count
FROM xd_settlements
WHERE room_id = 1
AND settled_at >= CURDATE();
-- 查看某房间历史盈亏(按日统计)
SELECT
DATE(settled_at) as date,
COUNT(*) as period_count,
SUM(total_bets_amount) as total_bets,
SUM(house_profit) as total_profit
FROM xd_settlements
WHERE room_id = 1
GROUP BY DATE(settled_at)
ORDER BY date DESC
LIMIT 30;
```
---
### Q6: 如何备份游戏数据?
**答**:定期备份以下表:
```bash
# 备份所有 Xóc Đĩa 相关表
mysqldump -u username -p database_name \
xd_room_config \
xd_periods \
xd_bets \
xd_settlements \
xd_bet_stats \
> xocdia_backup_$(date +%Y%m%d).sql
```
---
## 后续开发建议
### 高优先级
1. **WebSocket 集成**
- 实时推送游戏状态变化
- 自动倒计时
- 实时投注更新
2. **自动化流程**
- 定时自动开始新期号
- 定时自动封盘
- 定时自动开奖(如接入硬件设备)
3. **风险控制**
- 单边预警(投注严重倾斜时提醒)
- 异常投注检测
- 最大赔付限制
### 中优先级
4. **数据分析**
- 房间盈亏报表
- 用户投注习惯分析
- 热门玩法统计
5. **用户体验优化**
- 投注历史查询
- 开奖历史走势图
- 房间排行榜
### 低优先级
6. **高级功能**
- 多语言支持(越南语/中文/英文)
- 移动端适配
- API 接口文档
---
## 技术支持
如有问题,请参考:
- 后端逻辑设计:`/path/to/architecture_design.md`
- 数据库表结构:`Db/xocdia_schema.sql`
- 控制器代码:`App/Controllers/Admin/Xocdia*.php`
---
**最后更新**: 2026-01-08
**文档版本**: 1.0.0
+1480
View File
File diff suppressed because it is too large Load Diff
+294
View File
@@ -0,0 +1,294 @@
# Xóc Đĩa API 快速参考表
> 这是简化版的 API 参考表,详细文档请查看 `XOCDIA_API_DOCUMENTATION.md`
---
## WebSocket 连接
```javascript
const ws = new WebSocket('ws://yourdomain.com/ws/xocdia');
// 连接成功后订阅房间
ws.send(JSON.stringify({
action: 'SUBSCRIBE_ROOM',
data: { room_id: 1 }
}));
```
---
## 服务器推送事件(监听)
| 事件名 | 说明 | 数据示例 |
|--------|------|---------|
| `GAME_START` | 新期号开始 | `{ period_id, period_number, countdown, config }` |
| `COUNTDOWN_UPDATE` | 倒计时更新(每秒) | `{ remaining: 25 }` |
| `BET_SUCCESS` | 投注成功 | `{ bet_id, remaining_balance, potential_win }` |
| `BETTING_CLOSED` | 封盘 | `{ state: "shaking" }` |
| `GAME_RESULT` | 开奖结果 | `{ result: { coins, pattern }, settlement }` |
| `ERROR` | 错误 | `{ code, message }` |
---
## 客户端发送动作
### 1. 下注(WebSocket
```javascript
ws.send(JSON.stringify({
action: 'PLACE_BET',
data: {
room_id: 1,
period_id: 12345,
bet_type: 'odd', // even/odd/four_red/four_white/three_red/three_white
bet_amount: 100
}
}));
```
### 2. 获取当前状态
```javascript
ws.send(JSON.stringify({
action: 'GET_GAME_STATE',
data: { room_id: 1 }
}));
```
---
## HTTP API 端点
### 获取房间列表
```http
GET /api/xocdia/rooms
```
### 获取房间详情
```http
GET /api/xocdia/rooms/{room_id}
```
### 获取当前期号
```http
GET /api/xocdia/periods/current?room_id=1
```
### 下注(HTTP 备用)
```http
POST /api/xocdia/bet
Content-Type: application/json
{
"room_id": 1,
"period_id": 12345,
"bet_type": "odd",
"bet_amount": 100
}
```
### 获取开奖历史
```http
GET /api/xocdia/periods/history?room_id=1&limit=20
```
### 获取我的投注记录
```http
GET /api/xocdia/my-bets?room_id=1&limit=20
```
### 获取用户余额
```http
GET /api/user/balance
```
---
## 投注类型(bet_type
| 类型值 | 中文 | 越南语 | 赔率 |
|--------|------|--------|------|
| `even` | 双 | Chẵn | 1:1 |
| `odd` | 单 | Lẻ | 1:1 |
| `four_red` | 4红 | 4 Đen | 10:1 |
| `four_white` | 4白 | 4 Trắng | 10:1 |
| `three_red` | 3红1白 | 3 Đen 1 Trắng | 3.5:1 |
| `three_white` | 1红3白 | 1 Đen 3 Trắng | 3.5:1 |
---
## 开奖结果映射
```
硬币数组 → 结果模式
[1,1,1,1] → 4_red (4红)
[1,1,1,0] → 3_red_1_white (3红1白) ← 押"单"赢
[1,1,0,0] → 2_red_2_white (2红2白) ← 押"双"赢
[1,0,0,0] → 1_red_3_white (1红3白) ← 押"单"赢
[0,0,0,0] → 4_white (4白) ← 押"双"赢
注:1=红, 0=白
```
---
## 游戏状态(state
| 状态值 | 说明 | 前端行为 |
|--------|------|---------|
| `waiting` | 等待中 | 显示上期结果 |
| `betting` | 下注中 | 显示倒计时,开放投注 |
| `shaking` | 摇碟中 | 禁用投注,显示动画 |
| `settling` | 结算中 | 等待结算完成 |
| `showing` | 展示结果 | 显示开奖结果和赔付 |
---
## 常见错误码
| 错误码 | 说明 | 处理方式 |
|--------|------|---------|
| `NOT_LOGGED_IN` | 未登录 | 跳转登录页 |
| `INSUFFICIENT_BALANCE` | 余额不足 | 提示充值 |
| `BET_AMOUNT_INVALID` | 投注金额无效 | 检查限红 |
| `BETTING_CLOSED` | 已封盘 | 等待下期 |
| `PERIOD_NOT_FOUND` | 期号不存在 | 刷新页面 |
---
## 前端完整示例
```javascript
// 1. 连接 WebSocket
const ws = new WebSocket('ws://yourdomain.com/ws/xocdia');
ws.onopen = () => {
// 2. 订阅房间
ws.send(JSON.stringify({
action: 'SUBSCRIBE_ROOM',
data: { room_id: 1 }
}));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
// 3. 处理服务器事件
switch (msg.event) {
case 'GAME_START':
// 显示期号,启动倒计时,开放投注
document.getElementById('period').textContent = msg.data.period_number;
startCountdown(msg.data.countdown);
break;
case 'COUNTDOWN_UPDATE':
// 更新倒计时
document.getElementById('countdown').textContent = msg.data.remaining;
break;
case 'BET_SUCCESS':
// 更新余额,显示投注成功
document.getElementById('balance').textContent = msg.data.remaining_balance;
alert('投注成功!');
break;
case 'BETTING_CLOSED':
// 禁用投注按钮
disableBettingButtons();
break;
case 'GAME_RESULT':
// 显示开奖结果
showResult(msg.data.result.coins);
updateBalance(msg.data.settlement.new_balance);
showProfit(msg.data.settlement.net_profit);
break;
case 'ERROR':
alert(msg.data.message);
break;
}
};
// 4. 投注
function placeBet(betType, amount) {
ws.send(JSON.stringify({
action: 'PLACE_BET',
data: {
room_id: 1,
period_id: currentPeriodId,
bet_type: betType,
bet_amount: amount
}
}));
}
// 5. 按钮事件
document.getElementById('btn-bet-even').onclick = () => {
placeBet('even', 100);
};
document.getElementById('btn-bet-odd').onclick = () => {
placeBet('odd', 100);
};
```
---
## 注意事项
1. **所有请求需携带 Cookie**`credentials: 'include'`
2. **WebSocket 断线重连**:监听 `onclose` 事件,延迟重连
3. **金额精度**:使用浮点数,保留 2 位小数
4. **时区处理**:服务器返回 UTC 时间,前端转换为本地时间
5. **防抖处理**:投注按钮需防抖,避免重复提交
6. **余额实时更新**:监听 `BET_SUCCESS``GAME_RESULT` 更新余额
---
## 测试数据
### 模拟开奖结果
```javascript
// 测试用:手动触发开奖结果
const mockResult = {
event: 'GAME_RESULT',
data: {
result: {
coins: [1, 1, 1, 0],
pattern: '3_red_1_white',
display_text: '3 Đen 1 Trắng'
},
settlement: {
your_bets: [
{
bet_type: 'odd',
bet_amount: 100,
is_win: true,
win_amount: 100,
commission: 5,
net_profit: 95
}
],
new_balance: 10095
}
}
};
ws.onmessage({ data: JSON.stringify(mockResult) });
```
---
## 完整文档
详细说明、TypeScript 类型定义、高级功能请查看:
**`XOCDIA_API_DOCUMENTATION.md`**
---
**快速参考版本**: v1.0.0
**最后更新**: 2026-01-08
+360
View File
@@ -0,0 +1,360 @@
# Xóc Đĩa 游戏集成指南
## 📋 概述
本文档描述如何在 TM68 平台上使用新集成的 Xóc Đĩa(色碟)游戏功能。
## 🎯 游戏规则
### 基本机制
- 使用 4 枚双色硬币(红色/白色)
- 荷官摇动后开盖展示结果
- 玩家根据硬币颜色组合进行投注
### 投注类型
| 投注类型 | 说明 | 中奖条件 | 默认赔率 |
|---------|------|---------|---------|
| **CHẴN (双/偶)** | 双数组合 | 4红 或 4白 或 2红2白 | 1:0.96 |
| **LẺ (单/奇)** | 单数组合 | 3红1白 或 3白1红 | 1:0.96 |
| **4 ĐỎ** | 4个红色 | 全部红色 | 1:10 |
| **4 TRẮNG** | 4个白色 | 全部白色 | 1:10 |
| **3 ĐỎ 1 TRẮNG** | 3红1白 | 3个红色1个白色 | 1:3.5 |
| **3 TRẮNG 1 ĐỎ** | 3白1红 | 3个白色1个红色 | 1:3.5 |
---
## 🚀 部署步骤
### 1. 初始化数据库
执行 SQL 脚本初始化游戏和赔率配置:
```bash
# 方式1:通过 phpMyAdmin 导入
# 导入文件:Db/xocdia_setup.sql
# 方式2:通过命令行执行
mysql -u用户名 -p数据库名 < Db/xocdia_setup.sql
```
**脚本内容**
-`games` 表添加 Xóc Đĩa 游戏记录(code='xocdia', type='xocdia'
-`game_odds` 表配置6种投注类型的赔率
### 2. 配置游戏信息
登录后台管理 → **游戏管理** → 编辑 Xóc Đĩa 游戏:
1. **基本信息**
- 游戏名称:Xóc Đĩa
- 游戏标识:xocdia(自动生成)
- 游戏类型:xocdia(重要!)
- 状态:启用
2. **直播配置**
- 直播流地址:填写 HLS/FLV 流地址
- 示例:`https://your-cdn.com/live/xocdia.m3u8`
3. **展示设置**
- 游戏图片:上传缩略图(推荐尺寸 400x300)
- 在游戏大厅显示:是
- 排序权重:100(数字越大越靠前)
### 3. 配置赔率(可选)
如需调整赔率,登录后台管理 → **游戏管理****赔率配置**
| 类型 (type) | 目标 (target) | 赔率 (odds) | 说明 |
|------------|--------------|------------|------|
| chan | all | 0.96 | 双(偶)的赔率 |
| le | all | 0.96 | 单(奇)的赔率 |
| exact | 4red | 10.0 | 4红的赔率 |
| exact | 4white | 10.0 | 4白的赔率 |
| exact | 3red1white | 3.5 | 3红1白的赔率 |
| exact | 3white1red | 3.5 | 3白1红的赔率 |
---
## 🎮 游戏流程
### 前台用户流程
1. **进入游戏**
- 访问首页 → 点击 Xóc Đĩa 游戏卡片
- 或直接访问:`http://yourdomain.com/live?game_id=X`X为游戏ID
2. **观看直播**
- 页面左侧自动播放直播视频
- 显示当前期号和倒计时
3. **下注**
- 选择筹码金额(100K ~ 5M
- 点击投注区域(双/单 或 精确组合)
- 可多次点击累加投注额
- 点击"ĐẶT CƯỢC"确认,或"HỦY"取消
4. **等待开奖**
- 倒计时结束后封盘
- 荷官开奖
- 自动结算并更新余额
### 后台管理流程
#### 开始新一轮
1. 登录后台管理 → **期号管理**
2. 点击"开始下注"按钮
3. 系统自动创建新期号(格式:`G{GameID}{YYYYMMDD}{NNNN}`
4. 前台用户可以开始投注(60秒倒计时)
#### 开奖
1. 倒计时结束或手动封盘
2. 点击"开奖"按钮
3. 选择开奖方式:
- **手动输入**:逐个选择4个硬币的颜色(red/white)
- **自动随机**:系统随机生成结果
4. 确认开奖
**开奖结果存储格式**JSON):
```json
["red", "white", "red", "red"] // 3红1白
```
#### 结算
1. 点击"结算"按钮
2. 系统自动:
- 遍历所有待结算投注
- 根据开奖结果判断输赢
- 中奖用户:返还本金 + 盈利
- 未中奖:不退还本金
- 记录资金流水
3. 期号状态变更为"已结算"
4. 点击"开始下注"启动下一轮
---
## 🔧 技术实现细节
### 数据库字段复用
为避免修改数据库结构,Xóc Đĩa 游戏复用了 `periods` 表的骰子游戏字段:
| 字段名 | 骰子游戏 | Xóc Đĩa 游戏 |
|-------|---------|------------|
| `result` | "Xỉu/Tài" | JSON数组:`["red","white",...]` |
| `dice1` | 骰子1点数 | 红色硬币数量 |
| `dice2` | 骰子2点数 | 白色硬币数量 |
| `dice3` | 骰子3点数 | `null` |
| `total` | 三骰总和 | `null` |
### 投注数据结构
```json
{
"bets": [
{
"type": "chan", // 投注类型
"value": "all", // 投注目标
"amount": 100000, // 投注金额
"odds": 0.96 // 赔率(从服务器获取)
},
{
"type": "exact",
"value": "4red",
"amount": 500000,
"odds": 10.0
}
],
"period_number": "G2202601080001",
"game_id": 2
}
```
### 开奖API调用示例
```javascript
// 手动开奖
fetch('/admin/periods/draw', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: 123, // 期号ID
auto: false, // 手动模式
coins: ['red', 'red', 'white', 'red'] // 4个硬币颜色
})
});
// 自动开奖
fetch('/admin/periods/draw', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: 123,
auto: true // 自动随机
})
});
```
### 结算逻辑
```php
// 中奖判断示例(checkWin 方法)
$coins = json_decode($period['result'], true); // ["red", "red", "white", "red"]
$redCount = count(array_filter($coins, fn($c) => $c === 'red')); // 3
// 判断 chan(双)
if (in_array($redCount, [0, 2, 4])) {
// 中奖:0红4白, 2红2白, 4红0白
$winAmount = $betAmount * $odds;
}
// 判断 exact(精确组合)
if ($betValue === '3red1white' && $redCount === 3) {
// 中奖:3红1白
$winAmount = $betAmount * $odds;
}
```
---
## 🐛 故障排查
### 问题1:前台看不到 Xóc Đĩa 游戏
**原因**
- 游戏未启用(status=0
- featured=0(不在大厅显示)
**解决**
```sql
UPDATE games SET status=1, featured=1 WHERE code='xocdia';
```
### 问题2:投注时提示"赔率无效"
**原因**
- `game_odds` 表缺少赔率配置
**解决**
```bash
# 重新执行初始化脚本
mysql -u用户名 -p数据库名 < Db/xocdia_setup.sql
```
### 问题3:开奖后前台显示错误
**原因**
- `result` 字段不是有效的 JSON 数组
**解决**
```sql
-- 检查 result 字段格式
SELECT id, result FROM periods WHERE game_id=2 LIMIT 5;
-- 应该是:["red","white","red","red"] 格式
-- 如果不是,手动修正
UPDATE periods SET result='["red","red","white","white"]' WHERE id=XXX;
```
### 问题4:结算失败
**原因**
- 期号状态不是 'drawn'
- 事务回滚
**解决**
1. 检查日志:`Storage/log/error.log`
2. 检查期号状态:
```sql
SELECT id, period_number, status FROM periods WHERE id=XXX;
```
3. 手动修复状态:
```sql
UPDATE periods SET status='drawn' WHERE id=XXX;
```
---
## 📊 性能优化建议
### 1. 赔率缓存
当前实现已使用静态缓存,避免重复查询:
```php
static $oddsCache = [];
```
### 2. 期号索引
确保数据库有以下索引:
```sql
CREATE INDEX idx_period_status ON periods(status);
CREATE INDEX idx_period_game ON periods(game_id, status);
CREATE INDEX idx_bet_period ON bets(period_id, status);
```
### 3. 定时清理
建议每月清理已结算的旧期号和投注记录:
```sql
-- 保留最近30天的记录
DELETE FROM periods WHERE status='settled' AND created_at < DATE_SUB(NOW(), INTERVAL 30 DAY);
DELETE FROM bets WHERE status IN ('win','lose') AND created_at < DATE_SUB(NOW(), INTERVAL 30 DAY);
```
---
## 📝 未来扩展
### 可能的功能增强
1. **统计数据**
- 历史开奖记录(路单)
- 热门投注统计
- 玩家胜率分析
2. **游戏变体**
- 支持自定义硬币图案
- 支持更多投注类型(如:颜色顺序)
3. **自动化**
- 自动开奖(对接硬件或视频识别)
- 自动封盘(基于倒计时)
---
## ✅ 集成检查清单
部署前请确认:
- [ ] SQL 脚本已执行,游戏和赔率已创建
- [ ] 后台游戏管理中 Xóc Đĩa 状态为"启用"
- [ ] 已配置直播流地址(或留空测试)
- [ ] 前台可以正常访问游戏页面
- [ ] 测试完整流程:创建期号 → 投注 → 开奖 → 结算
- [ ] 数据库备份已创建
---
## 📞 技术支持
如遇到问题,请检查:
1. `Storage/log/error.log` - PHP 错误日志
2. 浏览器开发者工具 Console - 前端错误
3. 数据库查询日志 - SQL 错误
**相关文件**
- 数据库脚本:`Db/xocdia_setup.sql`
- 前端组件:`App/Views/Web/components/xocdia-bet-panel.php`
- 后端控制器:
- `App/Controllers/Web/HomeController.php` (live方法)
- `App/Controllers/Web/BetController.php` (placeBet方法)
- `App/Controllers/Admin/PeriodController.php` (draw/settle方法)
---
**最后更新**: 2026-01-08
**版本**: 1.0.0