Initial commit: 投注游戏平台初始化
This commit is contained in:
Executable
+273
@@ -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,说明修复成功!
|
||||
```
|
||||
|
||||
#### 🔍 如果遇到错误
|
||||
|
||||
**错误1:Duplicate entry for key 'PRIMARY'**
|
||||
```sql
|
||||
-- 说明游戏已存在,只需要更新类型
|
||||
UPDATE games
|
||||
SET type = 'xocdia', code = 'xocdia', tags = 'hot,traditional'
|
||||
WHERE name LIKE '%Xóc%' OR name LIKE '%色碟%';
|
||||
```
|
||||
|
||||
**错误2:Table '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分钟
|
||||
- 执行SQL:1分钟
|
||||
- 验证测试:5分钟
|
||||
- **总计:15分钟左右**
|
||||
|
||||
---
|
||||
|
||||
## 📞 需要帮助?
|
||||
|
||||
如果遇到问题,请提供:
|
||||
1. 错误截图
|
||||
2. PHP错误日志(宝塔 → 网站 → 日志)
|
||||
3. 数据库查询结果:
|
||||
```sql
|
||||
SELECT id, name, code, type FROM games;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2026-01-08
|
||||
**适用版本**: TM68 投注平台
|
||||
Executable
+396
@@ -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=1)2026年1月8日第1期
|
||||
G220260108001 # Xóc Đĩa(game_id=2)2026年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)
|
||||
Executable
+319
@@ -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 Đĩa(game_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 投注平台
|
||||
Executable
+480
@@ -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
|
||||
Executable
+1480
File diff suppressed because it is too large
Load Diff
Executable
+294
@@ -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
|
||||
Executable
+360
@@ -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
|
||||
Reference in New Issue
Block a user