bindbox-game/.trae/documents/活动创建流程重构方案.md
邹方成 2a89a1ab9d
Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
feat(admin): 更新前端资源文件及修复相关功能
refactor(service): 修改banner和guild删除逻辑为软删除
fix(service): 修复删除操作使用软删除而非物理删除

build: 添加SQLite测试仓库实现
docs: 新增奖励管理字段拆分和批量抽奖UI改造文档

ci: 更新CI忽略文件
style: 清理无用资源文件
2025-11-19 01:35:55 +08:00

6.3 KiB
Raw Blame History

目标

  • 将活动创建流程改造成“清晰、可操作、可回退”的向导式体验,显著降低填写负担、减少出错率,并确保与现有后端接口完全对齐。
  • 统一字段与交互:活动、期、奖励配置的字段、校验与排序一致;消除重复输入与歧义(如奖励名称以选品自动回填)。
  • 杜绝常见错误:时间格式、权限校验、表单必填项、动态模块加载等问题在交互层面被提前防护。

现状与痛点

  • 后端接口已齐备(管理端):
    • 创建活动:POST /api/admin/activitiesinternal/router/router.go:78;控制器 internal/api/admin/activities_admin.go:41;服务层 internal/service/activity/activity_create.go:12-41
    • 创建期:POST /api/admin/activities/:activity_id/issuesinternal/router/router.go:83;控制器 internal/api/admin/issues_admin.go;服务层 internal/service/activity/issue_create.go:13-32
    • 创建奖励:POST /api/admin/activities/:activity_id/issues/:issue_id/rewards
  • 前端存在两套创建入口:
    • 独立向导页:web/admin/src/views/activity/wizard/index.vue(“下一步”仅切换步骤,提交由各步的“提交”触发)
    • 管理页弹窗向导:web/admin/src/views/activity/manage/index.vue(“下一步”实际调用创建并推进)
  • 痛点汇总:
    • 两处入口的字段命名、排序不一致;奖励有的手填名称,有的选商品
    • 时间未填时易触发数据库零日期错误(TRADITIONAL SQL 模式下)
    • “下一步”与“提交”含义不统一,用户易误操作
    • 表格行式编辑密度过高,填写多项参数不友好
    • 动态导入失败来源于 SFC 结构不合法、重复脚本块或未声明变量导致编译失败

重构设计(交互与结构)

向导统一(单入口)

  • 入口:统一从“管理页弹窗向导”打开;支持跳转到独立页,但独立页沿用同一套逻辑(避免两套逻辑分歧)
  • 步骤:
    1. 基本信息活动名称、分类、状态、门票价格、Boss、开始/结束时间
    2. 期信息(活动期):期号、状态、排序
    3. 奖励配置按商品选择与参数设置权重、数量、原始数量、等级、排序、Boss
    4. 确认提交:汇总校验与最终提交
  • 导航:
    • “下一步”即执行当前步的提交(成功后推进),失败则停留并有明确错误提示
    • “上一步”回退不丢数据;每步保存草稿状态在组件内存

表单布局与输入体验

  • 两列栅格布局(ElRow/ElCol):提升可读性与并行填写效率
  • 奖励配置交互:
    • 改为“卡片列表 + 弹窗表单”,卡片上显示商品名称及关键参数;“新增奖励/编辑奖励”在弹窗中填写,分两列布局
    • 商品选择:远程搜索 admin/productsweb/admin/src/api/product.ts),选择后自动回填奖励名称(传递给后端以兼容)
    • 支持复制卡片、删除卡片、批量导入CSV/JSON作为扩展项初版可不做批量
  • 字段统一:奖励行统一字段为 product_id、weight、quantity、original_qty、level、sort、is_bossname由选品自动补齐,不再手填
  • 权限与提示:检测 SessionUserInfo.IsSuper(控制器内已做),前端在 403/400 的返回文案时专门弹出“权限不足”提示

校验与防错

  • 实时校验规则:
    • 活动:名称与分类必填;开始/结束时间支持空,但若为空则前端默认以 ISO8601 当前时间传入或后端统一允许 NULL
    • 期:期号必填;排序与状态为数值校验
    • 奖励:product_id 必填;数值项均为非负或正数;level 合法枚举
  • 时间防错:
    • 方案优先级A数据库将 start_time/end_time 改为可 NULL 且默认 NULL(推荐);
    • 方案优先级B前端在未选择时默认传当前时间的 toISOString()
    • 后端保留 Omit 逻辑(internal/service/activity/activity_create.go:29-35),避免强行写零日期

代码结构与可维护性

  • 组件结构:每个步骤独立子组件(ActivityStepBasic.vueActivityStepIssue.vueActivityStepRewards.vue+ 容器(ActivityWizard.vue
  • 状态管理:使用本地状态(ref/reactive)即可;如需跨页保持,用 pinia 记录向导草稿
  • API层沿用 web/admin/src/api/adminActivities.ts,奖励提交前统一映射自动补齐 name
  • 动态导入稳定性:
    • 确保每个 SFC 仅一个 <template> 和一个 <script setup>,无重复导入、重复变量与重复函数
    • 编译错误先清理其他页面的类型错误(如 shipping-stats/index.vueremoteLoading.ordersreconcile/diff/index.vueformatDetail),避免影响整体构建可用性

后端约束与对齐

  • 保持接口不变:CreateActivity/CreateIssue/CreateIssueRewards
  • 修改建议(可选):
    • 数据库列允许 NULL(避免零日期);
    • CreateActivity 中对 StartTime/EndTime 为空时不写入(现有已 Omit

验收标准

  • 用户可通过统一向导完成活动创建:每步“下一步”均会发起对应请求并进入下一步;错误有明确提示
  • 奖励配置以选择商品为主,不再手填名称;行字段与顺序一致
  • 复杂表单两列布局,填写效率明显提升;可编辑/删除奖励卡片
  • 构建通过(无 SFC 结构错误与类型错误);页面加载不再出现“动态模块导入失败”

实施步骤

  1. 重构向导组件结构与路由入口;统一使用弹窗向导(保留独立页入口但复用组件)
  2. 基本信息与期信息改为两列布局;“下一步”触发提交与推进
  3. 奖励配置改为卡片 + 弹窗表单;远程选品与字段统一;提交前自动补齐名称
  4. 表单校验与错误提示完善;未填时间的兜底(前端默认或后端允许 NULL
  5. 清理页面内无关类型错误(shipping-stats/index.vuereconcile/diff/index.vue)保证构建与动态导入稳定
  6. 编写端到端测试用例:
    • 正常流程:活动→期→奖励→提交 成功
    • 边界:缺少必填项、非超级管理员、时间为空等
    • 性能:奖励 50+ 条下的编辑与提交

交付物

  • 统一的向导组件及子组件
  • API 映射与表单校验实现
  • 样式与布局更新,卡片/弹窗交互
  • 测试用例与构建通过证明