Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
refactor(service): 修改banner和guild删除逻辑为软删除 fix(service): 修复删除操作使用软删除而非物理删除 build: 添加SQLite测试仓库实现 docs: 新增奖励管理字段拆分和批量抽奖UI改造文档 ci: 更新CI忽略文件 style: 清理无用资源文件
88 lines
6.3 KiB
Markdown
88 lines
6.3 KiB
Markdown
## 目标
|
||
- 将活动创建流程改造成“清晰、可操作、可回退”的向导式体验,显著降低填写负担、减少出错率,并确保与现有后端接口完全对齐。
|
||
- 统一字段与交互:活动、期、奖励配置的字段、校验与排序一致;消除重复输入与歧义(如奖励名称以选品自动回填)。
|
||
- 杜绝常见错误:时间格式、权限校验、表单必填项、动态模块加载等问题在交互层面被提前防护。
|
||
|
||
## 现状与痛点
|
||
- 后端接口已齐备(管理端):
|
||
- 创建活动:`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 仅一个 `<template>` 和一个 `<script setup>`,无重复导入、重复变量与重复函数
|
||
- 编译错误先清理其他页面的类型错误(如 `shipping-stats/index.vue` 的 `remoteLoading.orders` 与 `reconcile/diff/index.vue` 的 `formatDetail`),避免影响整体构建可用性
|
||
|
||
## 后端约束与对齐
|
||
- 保持接口不变:`CreateActivity`/`CreateIssue`/`CreateIssueRewards`
|
||
- 修改建议(可选):
|
||
- 数据库列允许 `NULL`(避免零日期);
|
||
- 在 `CreateActivity` 中对 `StartTime/EndTime` 为空时不写入(现有已 Omit)
|
||
|
||
## 验收标准
|
||
- 用户可通过统一向导完成活动创建:每步“下一步”均会发起对应请求并进入下一步;错误有明确提示
|
||
- 奖励配置以选择商品为主,不再手填名称;行字段与顺序一致
|
||
- 复杂表单两列布局,填写效率明显提升;可编辑/删除奖励卡片
|
||
- 构建通过(无 SFC 结构错误与类型错误);页面加载不再出现“动态模块导入失败”
|
||
|
||
## 实施步骤
|
||
1. 重构向导组件结构与路由入口;统一使用弹窗向导(保留独立页入口但复用组件)
|
||
2. 基本信息与期信息改为两列布局;“下一步”触发提交与推进
|
||
3. 奖励配置改为卡片 + 弹窗表单;远程选品与字段统一;提交前自动补齐名称
|
||
4. 表单校验与错误提示完善;未填时间的兜底(前端默认或后端允许 NULL)
|
||
5. 清理页面内无关类型错误(`shipping-stats/index.vue`、`reconcile/diff/index.vue`)保证构建与动态导入稳定
|
||
6. 编写端到端测试用例:
|
||
- 正常流程:活动→期→奖励→提交 成功
|
||
- 边界:缺少必填项、非超级管理员、时间为空等
|
||
- 性能:奖励 50+ 条下的编辑与提交
|
||
|
||
## 交付物
|
||
- 统一的向导组件及子组件
|
||
- API 映射与表单校验实现
|
||
- 样式与布局更新,卡片/弹窗交互
|
||
- 测试用例与构建通过证明
|