Files
cursor/plans/渠道编号自动生成_ef6f98ea.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

5.8 KiB
Raw Permalink Blame History

name, overview, todos, isProject
name overview todos isProject
渠道编号自动生成 在 slot-admin 后端创建渠道时自动生成唯一 6 位字母数字编号编辑时禁止修改slot-admin-vue 前端对应隐藏创建输入、编辑只读展示,并移除前端校验。
id content status
backend-add-generate GameServerLogic实现 add() + generateUniqueSource(),合并原 save() 逻辑edit() unset source completed
id content status
backend-validate GameServerValidatesave/update 场景移除 source 校验 completed
id content status
frontend-edit-form edit.vue新增隐藏编号、编辑只读、移除校验、提交时不传 source completed
id content status
verify Docker 内手工验证创建/编辑,跑 verify-slot-backend.sh completed
false

渠道编号系统自动生成方案

背景与范围

渠道管理对应模块:

层级 路径
前端列表/表单 slot-admin-vue/src/views/game/source/index.vueedit.vue
API POST /game/game-server/savePUT /game/game-server/update
后端 GameServerControllerGameServerLogicGameServerModel
校验 GameServerValidate

当前行为:创建/编辑时前端手动填写 source(编号),后端 save/update 场景均校验 source 必填。

额外发现(需一并修复)GameServerLogic::save()secret_key 生成、extend_data 格式化、Redis 同步等逻辑,但 BaseController::save() 实际调用的是 logic->add(),导致创建时这些逻辑未执行。本次应改为在 add() 中统一处理(参照 GGameLogic::add() 模式)。

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(),冲突则重试(最多 20 次),失败抛 ApiException
  • 存量数据:已有渠道编号不变,仅新建渠道走自动生成

后端改动slot-admin

1. GameServerLogic.php

新增 add()(替代当前未接入的 save()

  • 调用 generateUniqueSource() 写入 $data['source'],忽略前端传入值
  • 复用现有 save() 内创建前处理:secret_keyformat(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

  • save 场景:移除 source(后端生成,不要求前端传)
  • update 场景:移除 source(不可编辑)
  • 可保留 source 规则定义供其他场景复用,但不再出现在 save/update scene

3. GameServerModel.php(可选小改)

  • 新增 existsBySource(string $source): bool,供 Logic 查重,语义更清晰(非必须,可直接用 getBySource

前端改动slot-admin-vue

edit.vue

模板(约 L19-23

  • 新增模式:不展示编号输入框;可加一行提示文案「渠道编号将在创建后自动生成」
  • 编辑模式:展示 sourcedisabled 只读输入框

校验规则(约 L306-311

  • 移除 sourcerequired 规则

提交(约 L344-357

  • 新增/编辑提交前均 delete data.source,避免误传

列表页 index.vue 已有「编号」列,创建成功后刷新即可看到生成结果,无需改动。


安全与兼容

  • 后端 edit() 强制 unset source 为最终防线,不依赖前端
  • 新建渠道若前端仍传 source,后端忽略并覆盖为系统生成值
  • 不影响 refreshFb 等按 source 查询的现有功能

验证步骤

  1. Docker 内创建渠道:不传编号,保存成功,列表出现 6 位字母数字编号
  2. 编辑渠道:编号字段只读,修改名称等其他字段保存成功,编号不变
  3. 尝试通过 API 直接 PUT 修改 source,确认后端不更新该字段
  4. 执行 SLOT_ROOT=/Users/ray/Documents/project/www/ray ~/.cursor/hooks/verify-slot-backend.sh