This commit is contained in:
ray zhou
2026-06-29 14:51:55 +08:00
parent 225fb2bd28
commit 2dd9f17da9
319 changed files with 29461 additions and 9412 deletions

View File

@@ -0,0 +1,137 @@
---
name: 渠道编号自动生成
overview: 在 slot-admin 后端创建渠道时自动生成唯一 6 位字母数字编号编辑时禁止修改slot-admin-vue 前端对应隐藏创建输入、编辑只读展示,并移除前端校验。
todos:
- id: backend-add-generate
content: GameServerLogic实现 add() + generateUniqueSource(),合并原 save() 逻辑edit() unset source
status: completed
- id: backend-validate
content: GameServerValidatesave/update 场景移除 source 校验
status: completed
- id: frontend-edit-form
content: edit.vue新增隐藏编号、编辑只读、移除校验、提交时不传 source
status: completed
- id: verify
content: Docker 内手工验证创建/编辑,跑 verify-slot-backend.sh
status: completed
isProject: false
---
# 渠道编号系统自动生成方案
## 背景与范围
渠道管理对应模块:
| 层级 | 路径 |
|------|------|
| 前端列表/表单 | [`slot-admin-vue/src/views/game/source/index.vue`](slot-admin-vue/src/views/game/source/index.vue)、[`edit.vue`](slot-admin-vue/src/views/game/source/edit.vue) |
| API | `POST /game/game-server/save``PUT /game/game-server/update` |
| 后端 | [`GameServerController`](slot-admin/app/game/controller/GameServerController.php) → [`GameServerLogic`](slot-admin/app/game/logic/GameServerLogic.php) → [`GameServerModel`](slot-admin/app/model/GameServerModel.php) |
| 校验 | [`GameServerValidate`](slot-admin/app/game/validate/GameServerValidate.php) |
当前行为:创建/编辑时前端手动填写 `source`(编号),后端 `save`/`update` 场景均校验 `source` 必填。
**额外发现(需一并修复)**[`GameServerLogic::save()`](slot-admin/app/game/logic/GameServerLogic.php) 含 `secret_key` 生成、`extend_data` 格式化、Redis 同步等逻辑,但 [`BaseController::save()`](slot-admin/plugin/saimulti/basic/BaseController.php) 实际调用的是 `logic->add()`,导致创建时这些逻辑**未执行**。本次应改为在 `add()` 中统一处理(参照 [`GGameLogic::add()`](slot-admin/app/game/logic/GGameLogic.php) 模式)。
```mermaid
sequenceDiagram
participant Vue as slot-admin-vue
participant Ctrl as GameServerController
participant Logic as GameServerLogic
participant DB as game_server
Vue->>Ctrl: POST save不含 source
Ctrl->>Logic: add(data)
Logic->>Logic: generateUniqueSource()
Logic->>Logic: prepareCreateData()
Logic->>DB: insert
Logic->>Logic: sync(redis)
Ctrl-->>Vue: success
Vue->>Ctrl: PUT updatesource 只读或不传)
Ctrl->>Logic: edit(id, data)
Logic->>Logic: unset source
Logic->>DB: update
Logic->>Logic: sync(redis)
```
---
## 编号规则(已确认)
- **格式**6 位 **大写字母 + 数字** 混合(如 `A3K9X2`
- **字符集**`A-Z` + `0-9`(统一大写,与现有 `sync()``strtoupper($source)` 行为一致)
- **唯一性**:生成后查库 [`GameServerModel::getBySource()`](slot-admin/app/model/GameServerModel.php),冲突则重试(最多 20 次),失败抛 `ApiException`
- **存量数据**:已有渠道编号不变,仅新建渠道走自动生成
---
## 后端改动slot-admin
### 1. [`GameServerLogic.php`](slot-admin/app/game/logic/GameServerLogic.php)
**新增 `add()`**(替代当前未接入的 `save()`
- 调用 `generateUniqueSource()` 写入 `$data['source']`,忽略前端传入值
- 复用现有 `save()` 内创建前处理:`secret_key``format(extend_data)``dot_type`/`fb_status`/`fb_pix`
- `parent::add($data)``sync($data['source'])`
- 删除或内联原 `save()` 方法,避免双入口
**新增私有方法**(均需中文 PHPDoc
- `generateUniqueSource(): string` — 生成唯一 6 位编号
- `prepareCreateData(array $data): array` — 从原 `save()` 提取的创建前数据整理(可选,保持方法 ≤50 行)
**修改 `edit()`**
- 在更新前 `unset($data['source'])`,防止通过 API 篡改编号
- 其余逻辑保持不变
### 2. [`GameServerValidate.php`](slot-admin/app/game/validate/GameServerValidate.php)
- `save` 场景:**移除** `source`(后端生成,不要求前端传)
- `update` 场景:**移除** `source`(不可编辑)
- 可保留 `source` 规则定义供其他场景复用,但不再出现在 save/update scene
### 3. [`GameServerModel.php`](slot-admin/app/model/GameServerModel.php)(可选小改)
- 新增 `existsBySource(string $source): bool`,供 Logic 查重,语义更清晰(非必须,可直接用 `getBySource`
---
## 前端改动slot-admin-vue
### [`edit.vue`](slot-admin-vue/src/views/game/source/edit.vue)
**模板**(约 L19-23
- **新增模式**:不展示编号输入框;可加一行提示文案「渠道编号将在创建后自动生成」
- **编辑模式**:展示 `source``disabled` 只读输入框
**校验规则**(约 L306-311
- 移除 `source``required` 规则
**提交**(约 L344-357
- 新增/编辑提交前均 `delete data.source`,避免误传
列表页 [`index.vue`](slot-admin-vue/src/views/game/source/index.vue) 已有「编号」列,创建成功后刷新即可看到生成结果,无需改动。
---
## 安全与兼容
- 后端 `edit()` 强制 `unset source` 为最终防线,不依赖前端
- 新建渠道若前端仍传 `source`,后端忽略并覆盖为系统生成值
- 不影响 [`refreshFb`](slot-admin/app/game/controller/GameServerController.php) 等按 `source` 查询的现有功能
---
## 验证步骤
1. Docker 内创建渠道:不传编号,保存成功,列表出现 6 位字母数字编号
2. 编辑渠道:编号字段只读,修改名称等其他字段保存成功,编号不变
3. 尝试通过 API 直接 PUT 修改 `source`,确认后端不更新该字段
4. 执行 `SLOT_ROOT=/Users/ray/Documents/project/www/ray ~/.cursor/hooks/verify-slot-backend.sh`