## 目标 - 将活动创建流程改造成“清晰、可操作、可回退”的向导式体验,显著降低填写负担、减少出错率,并确保与现有后端接口完全对齐。 - 统一字段与交互:活动、期、奖励配置的字段、校验与排序一致;消除重复输入与歧义(如奖励名称以选品自动回填)。 - 杜绝常见错误:时间格式、权限校验、表单必填项、动态模块加载等问题在交互层面被提前防护。 ## 现状与痛点 - 后端接口已齐备(管理端): - 创建活动:`POST /api/admin/activities`(`internal/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/issues`(`internal/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/products`(`web/admin/src/api/product.ts`),选择后自动回填奖励名称(传递给后端以兼容) - 支持复制卡片、删除卡片、批量导入(CSV/JSON)作为扩展项(初版可不做批量) - 字段统一:奖励行统一字段为 `product_id、weight、quantity、original_qty、level、sort、is_boss`;`name`由选品自动补齐,不再手填 - 权限与提示:检测 `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.vue`、`ActivityStepIssue.vue`、`ActivityStepRewards.vue`)+ 容器(`ActivityWizard.vue`) - 状态管理:使用本地状态(`ref/reactive`)即可;如需跨页保持,用 `pinia` 记录向导草稿 - API层:沿用 `web/admin/src/api/adminActivities.ts`,奖励提交前统一映射自动补齐 `name` - 动态导入稳定性: - 确保每个 SFC 仅一个 `