From a85605563711a52b1d60b54d9611ab0c1d7fb730 Mon Sep 17 00:00:00 2001 From: gpu Date: Sat, 17 Jan 2026 18:04:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E5=8F=B0=E4=BB=BB=E5=8A=A12?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../specs/goods-management-frontend/design.md | 433 ++++++++++++++++++ .../goods-management-frontend/requirements.md | 134 ++++++ .../specs/goods-management-frontend/tasks.md | 233 ++++++++++ docs/后台管理系统-功能分析清单.md | 4 +- docs/后台管理系统迁移批次规划.md | 7 +- 5 files changed, 806 insertions(+), 5 deletions(-) create mode 100644 .kiro/specs/goods-management-frontend/design.md create mode 100644 .kiro/specs/goods-management-frontend/requirements.md create mode 100644 .kiro/specs/goods-management-frontend/tasks.md diff --git a/.kiro/specs/goods-management-frontend/design.md b/.kiro/specs/goods-management-frontend/design.md new file mode 100644 index 00000000..f6885a66 --- /dev/null +++ b/.kiro/specs/goods-management-frontend/design.md @@ -0,0 +1,433 @@ +# 商品管理模块前端设计文档 + +## 架构设计 + +### 目录结构 + +``` +src/views/business/goods/ +├── index.vue # 盒子列表页面 +├── type.vue # 盒子类型管理页面 +├── components/ +│ ├── GoodsSearchForm.vue # 盒子搜索表单 +│ ├── GoodsTable.vue # 盒子列表表格 +│ ├── GoodsAddDialog.vue # 盒子新增弹窗 +│ ├── GoodsEditDialog.vue # 盒子编辑弹窗 +│ ├── GoodsExtendDialog.vue # 盒子扩展设置弹窗 +│ ├── PrizeListDialog.vue # 奖品列表弹窗 +│ ├── PrizeAddDialog.vue # 奖品新增弹窗 +│ ├── PrizeEditDialog.vue # 奖品编辑弹窗 +│ ├── TypeAddDialog.vue # 类型新增弹窗 +│ └── TypeEditDialog.vue # 类型编辑弹窗 + +src/api/business/ +├── goods.ts # 商品API接口 +``` + +### 组件关系图 + +``` +index.vue (盒子列表) +├── GoodsSearchForm.vue (搜索表单) +├── GoodsTable.vue (列表表格) +│ ├── GoodsAddDialog.vue (新增弹窗) +│ ├── GoodsEditDialog.vue (编辑弹窗) +│ ├── GoodsExtendDialog.vue (扩展设置弹窗) +│ └── PrizeListDialog.vue (奖品列表弹窗) +│ ├── PrizeAddDialog.vue (奖品新增弹窗) +│ └── PrizeEditDialog.vue (奖品编辑弹窗) + +type.vue (类型管理) +├── TypeAddDialog.vue (类型新增弹窗) +└── TypeEditDialog.vue (类型编辑弹窗) +``` + +## 数据模型 + +### 盒子类型枚举 + +```typescript +export enum GoodsType { + YiFanShang = 1, // 一番赏 + WuXianShang = 2, // 无限赏 + LeiTaiShang = 3, // 擂台赏 + FuDai = 5, // 福袋 + XingYunShang = 6, // 幸运赏 + LingZhuShang = 8, // 领主赏 + LianJiShang = 9, // 连击赏 + MangHe = 10, // 盲盒 + XingYunShangNew = 11,// 幸运赏(新) + FuLiWu = 15, // 福利屋 + FanBeiShang = 16, // 翻倍赏 + TeShuHeZi = 17, // 特殊盒子 +} + +export const GoodsTypeLabels: Record = { + [GoodsType.YiFanShang]: '一番赏', + [GoodsType.WuXianShang]: '无限赏', + [GoodsType.LeiTaiShang]: '擂台赏', + [GoodsType.FuDai]: '福袋', + [GoodsType.XingYunShang]: '幸运赏', + [GoodsType.LingZhuShang]: '领主赏', + [GoodsType.LianJiShang]: '连击赏', + [GoodsType.MangHe]: '盲盒', + [GoodsType.XingYunShangNew]: '幸运赏(新)', + [GoodsType.FuLiWu]: '福利屋', + [GoodsType.FanBeiShang]: '翻倍赏', + [GoodsType.TeShuHeZi]: '特殊盒子', +}; +``` + +### 盒子类型字段配置 + +```typescript +export interface GoodsTypeFieldConfig { + showStock: boolean; // 显示套数 + showLock: boolean; // 显示锁箱配置 + showDailyLimit: boolean; // 显示每日限购 + showRage: boolean; // 显示怒气值 + showItemCard: boolean; // 显示道具卡 + showLingzhu: boolean; // 显示领主配置 + showLianji: boolean; // 显示连击配置 + showTimeConfig: boolean; // 显示时间配置(福利屋) + showAutoXiajia: boolean; // 显示自动下架 + showCoupon: boolean; // 显示发券开关 + showIntegral: boolean; // 显示发积分开关 + showDescription: boolean; // 显示盒子描述 + showQuanjuXiangou: boolean; // 显示限购次数 +} + +export const GoodsTypeFieldConfigs: Record = { + [GoodsType.YiFanShang]: { + showStock: true, showLock: true, showDailyLimit: true, + showRage: false, showItemCard: false, showLingzhu: false, + showLianji: false, showTimeConfig: false, showAutoXiajia: true, + showCoupon: true, showIntegral: true, showDescription: false, + showQuanjuXiangou: false, + }, + [GoodsType.WuXianShang]: { + showStock: false, showLock: false, showDailyLimit: false, + showRage: true, showItemCard: true, showLingzhu: false, + showLianji: false, showTimeConfig: false, showAutoXiajia: true, + showCoupon: true, showIntegral: true, showDescription: false, + showQuanjuXiangou: false, + }, + // ... 其他类型配置 +}; +``` + +### 盒子数据模型 + +```typescript +export interface GoodsItem { + id: number; + type: GoodsType; + title: string; + price: number; + stock: number; + imgUrl: string; + imgUrlDetail: string; + status: number; // 0-下架 1-上架 2-售罄 + sort: number; + isNew: boolean; + isShouZhe: boolean; // 首抽五折 + lockIs: boolean; // 锁箱开关 + lockTime: number; // 锁箱时间(秒) + dailyXiangou: number; // 每日限购 + quanjuXiangou: number; // 限购次数 + rageIs: boolean; // 怒气值开关 + rage: number; // 怒气值 + itemCardId: number; // 道具卡ID + couponIs: boolean; // 发券开关 + integralIs: boolean; // 发积分开关 + isAutoXiajia: boolean; // 自动下架开关 + xiajiaLirun: number; // 下架利润值(%) + xiajiaAutoCoushu: number; // 下架抽数阈值 + xiajiaJine: number; // 下架金额 + unlockAmount: number; // 解锁金额 + choujiangXianzhi: number; // 抽奖门槛 + goodsDescribe: string; // 盒子描述 + // 福利屋专用 + flwStartTime: string; // 开始时间 + flwEndTime: string; // 结束时间 + openTime: string; // 开奖时间 + // 领主赏专用 + lingzhuIs: boolean; + lingzhuFan: number; + lingzhuShangId: number; + // 连击赏专用 + lianJiNum: number; + lianJiShangId: number; + // 时间戳 + createTime: string; + updateTime: string; +} +``` + +### 奖品数据模型 + +```typescript +export enum PrizeCategory { + XianHuo = 1, // 现货 + YuShou = 2, // 预售 + HuoBi = 3, // 货币 + BaoXiang = 4, // 宝箱 +} + +export interface PrizeItem { + id: number; + goodsId: number; + title: string; + category: PrizeCategory; + level: string; // A/B/C/D/E等 + price: number; // 售价 + costPrice: number; // 采购价 + referencePrice: number; // 参考价 + quantity: number; // 数量(一番赏等) + probability: number; // 概率%(无限赏等) + giftMultiple: number; // 赠送倍率(翻倍赏) + isLingzhu: boolean; // 是否领主(领主赏) + preSaleTime: string; // 预售时间 + sort: number; + imgUrl: string; + detailImgUrl: string; + giftCurrency: GiftCurrency[]; // 赠送货币配置 + children?: PrizeItem[]; // 宝箱子奖品 + createTime: string; + updateTime: string; +} + +export interface GiftCurrency { + type: string; // 货币类型 + amount: number; // 数量 +} +``` + +## API接口设计 + +```typescript +// src/api/business/goods.ts + +import request from '@/utils/request'; + +const BASE_URL = '/api/admin/business/goods'; + +// 盒子管理 +export const goodsApi = { + // 获取盒子列表 + getList: (params: GoodsListParams) => + request.get>(`${BASE_URL}`, { params }), + + // 获取盒子详情 + getDetail: (id: number) => + request.get(`${BASE_URL}/${id}`), + + // 创建盒子 + create: (data: GoodsCreateRequest) => + request.post<{ id: number }>(`${BASE_URL}`, data), + + // 更新盒子 + update: (id: number, data: GoodsUpdateRequest) => + request.put(`${BASE_URL}/${id}`, data), + + // 删除盒子 + delete: (id: number) => + request.delete(`${BASE_URL}/${id}`), + + // 设置盒子状态 + setStatus: (id: number, status: number) => + request.put(`${BASE_URL}/${id}/status`, { status }), + + // 获取盒子奖品列表 + getPrizes: (goodsId: number) => + request.get(`${BASE_URL}/${goodsId}/prizes`), + + // 添加奖品 + addPrize: (goodsId: number, data: PrizeCreateRequest) => + request.post<{ id: number }>(`${BASE_URL}/${goodsId}/prizes`, data), +}; + +// 奖品管理 +export const prizesApi = { + // 获取奖品详情 + getDetail: (id: number) => + request.get(`/api/admin/business/prizes/${id}`), + + // 更新奖品 + update: (id: number, data: PrizeUpdateRequest) => + request.put(`/api/admin/business/prizes/${id}`, data), + + // 删除奖品 + delete: (id: number) => + request.delete(`/api/admin/business/prizes/${id}`), +}; + +// 盒子类型管理 +export const goodsTypeApi = { + // 获取类型列表 + getList: () => + request.get(`${BASE_URL}/types`), + + // 创建类型 + create: (data: GoodsTypeCreateRequest) => + request.post(`${BASE_URL}/types`, data), + + // 更新类型 + update: (id: number, data: GoodsTypeUpdateRequest) => + request.put(`${BASE_URL}/types/${id}`, data), + + // 删除类型 + delete: (id: number) => + request.delete(`${BASE_URL}/types/${id}`), +}; +``` + +## 组件设计 + +### GoodsAddDialog 盒子新增弹窗 + +核心逻辑:根据盒子类型动态显示/隐藏字段 + +```typescript +// 计算属性:根据类型获取字段配置 +const fieldConfig = computed(() => { + return GoodsTypeFieldConfigs[formData.type] || defaultFieldConfig; +}); + +// 监听类型变化,重置相关字段 +watch(() => formData.type, (newType) => { + resetTypeSpecificFields(); +}); +``` + +### PrizeListDialog 奖品列表弹窗 + +核心逻辑:根据盒子类型动态显示不同列 + +```typescript +// 计算属性:动态列配置 +const dynamicColumns = computed(() => { + const type = props.goodsType; + const columns = [...baseColumns]; + + // 一番赏/擂台赏/福袋等显示数量列 + if ([1, 3, 5, 6, 10, 11, 15, 17].includes(type)) { + columns.push({ prop: 'quantity', label: '奖品数量' }); + } + + // 无限赏/翻倍赏等显示概率列 + if ([2, 8, 9, 16, 17].includes(type)) { + columns.push({ prop: 'probability', label: '真实概率(%)' }); + } + + // 翻倍赏显示赠送倍率 + if ([16, 17].includes(type)) { + columns.push({ prop: 'giftMultiple', label: '赠送倍率' }); + } + + return columns; +}); +``` + +## 路由配置 + +```typescript +// src/router/modules/business.ts + +{ + path: 'goods', + name: 'BusinessGoods', + component: () => import('@/views/business/goods/index.vue'), + meta: { title: '盒子管理', icon: 'goods', permission: 'goods:list' } +}, +{ + path: 'goods/type', + name: 'BusinessGoodsType', + component: () => import('@/views/business/goods/type.vue'), + meta: { title: '盒子类型', icon: 'type', permission: 'goods:type' } +}, +``` + +## 属性测试设计 + +### 测试用例 + +```csharp +// GoodsManagementFrontendPropertyTests.cs + +[Property] +public Property GoodsTypeFieldConfig_ShouldBeConsistent() +{ + // 验证每种盒子类型都有对应的字段配置 +} + +[Property] +public Property GoodsCreate_WithValidData_ShouldSucceed() +{ + // 验证有效数据创建盒子成功 +} + +[Property] +public Property GoodsCreate_WithInvalidType_ShouldFail() +{ + // 验证无效类型创建盒子失败 +} + +[Property] +public Property PrizeCreate_WithValidData_ShouldSucceed() +{ + // 验证有效数据创建奖品成功 +} + +[Property] +public Property PrizeProbability_ShouldNotExceed100() +{ + // 验证奖品概率总和不超过100% +} +``` + +## 状态管理 + +使用组合式API管理状态,不需要Pinia store: + +```typescript +// 盒子列表状态 +const goodsListState = reactive({ + loading: false, + list: [] as GoodsItem[], + total: 0, + searchParams: { + title: '', + status: null, + type: null, + page: 1, + pageSize: 20, + }, +}); + +// 奖品列表状态 +const prizeListState = reactive({ + loading: false, + list: [] as PrizeItem[], + goodsId: 0, + goodsType: 0, +}); +``` + +## 错误处理 + +```typescript +// 统一错误处理 +const handleApiError = (error: any, defaultMessage: string) => { + const message = error.response?.data?.message || defaultMessage; + ElMessage.error(message); +}; + +// 使用示例 +try { + await goodsApi.create(formData); + ElMessage.success('创建成功'); +} catch (error) { + handleApiError(error, '创建失败'); +} +``` diff --git a/.kiro/specs/goods-management-frontend/requirements.md b/.kiro/specs/goods-management-frontend/requirements.md new file mode 100644 index 00000000..8871a74d --- /dev/null +++ b/.kiro/specs/goods-management-frontend/requirements.md @@ -0,0 +1,134 @@ +# 商品管理模块前端迁移需求文档 + +## 概述 + +将 PHP 老项目 (`server/php/app/admin/view/Goods/`) 中的商品管理功能迁移到新的 Vue 3 + Element Plus 前端框架。 + +## 参考文档 + +- #[[file:docs/后台管理系统-功能分析清单.md]] - 模块功能分析 +- #[[file:server/HoneyBox/src/HoneyBox.Admin.Business/Controllers/GoodsController.cs]] - 后端API +- #[[file:server/HoneyBox/src/HoneyBox.Admin.Business/Services/GoodsService.cs]] - 后端服务 + +## 盒子类型定义 + +系统支持10种盒子类型,每种类型有不同的字段配置: + +| 类型值 | 类型名称 | 特有字段 | +|--------|----------|----------| +| 1 | 一番赏 | 套数、锁箱、每日限购 | +| 2 | 无限赏 | 怒气值、道具卡 | +| 3 | 擂台赏 | 全局赏数量 | +| 5 | 福袋 | 套数 | +| 6 | 幸运赏 | 套数、锁箱、限购 | +| 8 | 领主赏 | 领主开关、领主返还、领主奖品 | +| 9 | 连击赏 | 连击次数、连击奖品 | +| 10 | 盲盒 | 套数、盒子描述 | +| 11 | 幸运赏(新) | 套数、锁箱、每日限购 | +| 15 | 福利屋 | 开始/结束/开奖时间、限购次数 | +| 16 | 翻倍赏 | 怒气值、道具卡 | +| 17 | 特殊盒子 | 每日限购 | + +## 用户故事 + +### US-001: 盒子列表管理 +作为后台管理员,我需要查看和管理所有盒子,以便进行日常运营。 + +**验收标准:** +- AC-001.1: 支持按盒子标题、状态、类型搜索 +- AC-001.2: 列表显示盒子ID、类型、名称、价格、套数、图片、状态等信息 +- AC-001.3: 支持上架/下架状态切换 +- AC-001.4: 支持编辑、删除、复制盒子操作 +- AC-001.5: 支持查看和管理盒子奖品 +- AC-001.6: 支持盒子扩展设置(支付方式配置) +- AC-001.7: 福利屋类型显示开始/结束/开奖时间 + +### US-002: 盒子新增 +作为后台管理员,我需要新增盒子,以便上架新的抽奖活动。 + +**验收标准:** +- AC-002.1: 支持选择盒子类型(10种类型) +- AC-002.2: 根据盒子类型动态显示/隐藏相关字段 +- AC-002.3: 支持配置基础信息(名称、价格、排序、描述) +- AC-002.4: 支持配置首抽五折、是否最新 +- AC-002.5: 支持配置自动下架(利润值、抽数阈值、下架金额) +- AC-002.6: 支持配置解锁金额 +- AC-002.7: 支持上传盒子封面图和详情图 +- AC-002.8: 一番赏/幸运赏类型支持配置套数、锁箱、每日限购 +- AC-002.9: 无限赏/翻倍赏类型支持配置怒气值、道具卡 +- AC-002.10: 福利屋类型支持配置时间(开始/结束/开奖) + +### US-003: 盒子编辑 +作为后台管理员,我需要编辑已有盒子,以便调整活动配置。 + +**验收标准:** +- AC-003.1: 盒子类型不可修改(编辑时禁用) +- AC-003.2: 其他字段可正常编辑 +- AC-003.3: 保存后刷新列表 + +### US-004: 奖品列表管理 +作为后台管理员,我需要管理盒子的奖品,以便配置抽奖内容。 + +**验收标准:** +- AC-004.1: 支持按奖品标题搜索 +- AC-004.2: 根据盒子类型动态显示不同列(数量/概率) +- AC-004.3: 支持树形表格展示(宝箱类型可展开子奖品) +- AC-004.4: 显示概率统计(无限赏等类型) +- AC-004.5: 支持排序字段直接编辑 +- AC-004.6: 支持添加、编辑、删除奖品 + +### US-005: 奖品新增/编辑 +作为后台管理员,我需要新增和编辑奖品,以便配置抽奖奖品。 + +**验收标准:** +- AC-005.1: 支持配置奖品基础信息(名称、类型、售价、采购价、参考价) +- AC-005.2: 支持选择奖品分类(现货/预售/货币/宝箱) +- AC-005.3: 支持选择奖品等级(A/B/C/D/E等) +- AC-005.4: 根据盒子类型显示数量或概率字段 +- AC-005.5: 翻倍赏支持配置赠送倍率 +- AC-005.6: 预售类型支持配置预售时间 +- AC-005.7: 支持配置赠送货币 +- AC-005.8: 支持上传奖品图片和详情图 + +### US-006: 盒子类型管理 +作为后台管理员,我需要管理盒子类型,以便配置类型属性。 + +**验收标准:** +- AC-006.1: 显示类型列表(ID、名称、Key、排序) +- AC-006.2: 支持首页显示、分类显示开关 +- AC-006.3: 支持配置支付方式(微信/余额/货币/优惠券) +- AC-006.4: 支持配置角标文字 +- AC-006.5: 支持新增、编辑、删除类型 + +### US-007: 盒子扩展设置 +作为后台管理员,我需要为单个盒子配置独立的支付方式。 + +**验收标准:** +- AC-007.1: 显示盒子基本信息 +- AC-007.2: 支持多选支付方式 +- AC-007.3: 支持选择支付类型(抵扣/支付) +- AC-007.4: 支持删除扩展设置恢复默认 + +## 非功能需求 + +### NFR-001: 性能 +- 盒子列表分页加载,每页默认20条 +- 图片使用懒加载 +- 表单提交防重复点击 + +### NFR-002: 用户体验 +- 表单验证实时反馈 +- 操作成功/失败提示 +- 删除操作二次确认 +- 图片上传支持预览 + +### NFR-003: 兼容性 +- 支持 Chrome、Firefox、Edge 最新版本 +- 响应式布局适配不同屏幕 + +## 约束条件 + +- 后端API已完成,使用现有的 GoodsController 和 PrizesController +- 遵循现有项目的代码规范和目录结构 +- 使用 Element Plus 组件库 +- 使用 TypeScript 编写 diff --git a/.kiro/specs/goods-management-frontend/tasks.md b/.kiro/specs/goods-management-frontend/tasks.md new file mode 100644 index 00000000..299783e8 --- /dev/null +++ b/.kiro/specs/goods-management-frontend/tasks.md @@ -0,0 +1,233 @@ +# 商品管理模块前端迁移任务清单 + +## 任务概览 + +| 阶段 | 任务数 | 预计工时 | +|------|--------|----------| +| 1. 基础设施 | 2 | 2h | +| 2. 盒子列表 | 4 | 6h | +| 3. 盒子新增/编辑 | 3 | 8h | +| 4. 奖品管理 | 4 | 6h | +| 5. 盒子类型管理 | 2 | 3h | +| 6. 测试 | 2 | 3h | +| **总计** | **17** | **28h** | + +--- + +## 阶段1: 基础设施 + +### Task 1.1: 创建API接口层 +- [ ] 创建 `src/api/business/goods.ts` +- [ ] 实现盒子管理API(getList, getDetail, create, update, delete, setStatus) +- [ ] 实现奖品管理API(getPrizes, addPrize, getDetail, update, delete) +- [ ] 实现盒子类型API(getList, create, update, delete) +- [ ] 定义请求/响应类型接口 + +**关联需求:** US-001, US-002, US-004, US-006 + +### Task 1.2: 创建类型定义和配置 +- [ ] 创建盒子类型枚举 `GoodsType` +- [ ] 创建盒子类型标签映射 `GoodsTypeLabels` +- [ ] 创建盒子类型字段配置 `GoodsTypeFieldConfigs` +- [ ] 创建奖品分类枚举 `PrizeCategory` +- [ ] 创建数据模型接口(GoodsItem, PrizeItem等) + +**关联需求:** US-002, US-005 + +--- + +## 阶段2: 盒子列表 + +### Task 2.1: 创建盒子列表页面 +- [ ] 创建 `src/views/business/goods/index.vue` +- [ ] 实现页面布局(搜索区 + 表格区) +- [ ] 集成搜索表单和表格组件 +- [ ] 实现分页逻辑 + +**关联需求:** US-001 (AC-001.1, AC-001.2) + +### Task 2.2: 创建搜索表单组件 +- [ ] 创建 `src/views/business/goods/components/GoodsSearchForm.vue` +- [ ] 实现盒子标题输入框 +- [ ] 实现状态下拉选择(上架/下架/售罄) +- [ ] 实现盒子类型下拉选择 +- [ ] 实现搜索和重置按钮 + +**关联需求:** US-001 (AC-001.1) + +### Task 2.3: 创建盒子表格组件 +- [ ] 创建 `src/views/business/goods/components/GoodsTable.vue` +- [ ] 实现表格列配置(ID、类型、名称、价格、套数、图片、状态等) +- [ ] 实现图片预览功能 +- [ ] 实现状态切换开关 +- [ ] 实现排序字段直接编辑 +- [ ] 福利屋类型显示时间信息 + +**关联需求:** US-001 (AC-001.2, AC-001.3, AC-001.7) + +### Task 2.4: 实现盒子操作功能 +- [ ] 实现编辑按钮(打开编辑弹窗) +- [ ] 实现删除按钮(二次确认) +- [ ] 实现复制按钮 +- [ ] 实现奖品按钮(打开奖品列表弹窗) +- [ ] 实现扩展设置按钮(打开扩展设置弹窗) +- [ ] 实现清空抽奖按钮(危险操作,二次确认) + +**关联需求:** US-001 (AC-001.4, AC-001.5, AC-001.6) + +--- + +## 阶段3: 盒子新增/编辑 + +### Task 3.1: 创建盒子新增弹窗 +- [ ] 创建 `src/views/business/goods/components/GoodsAddDialog.vue` +- [ ] 实现盒子类型选择(单选按钮组) +- [ ] 实现基础信息表单(名称、价格、排序、描述) +- [ ] 实现首抽五折、是否最新开关 +- [ ] 实现图片上传(封面图、详情图) +- [ ] 实现表单验证 + +**关联需求:** US-002 (AC-002.1, AC-002.3, AC-002.4, AC-002.7) + +### Task 3.2: 实现盒子类型条件字段 +- [ ] 实现根据类型动态显示/隐藏字段逻辑 +- [ ] 一番赏/幸运赏:套数、锁箱、每日限购 +- [ ] 无限赏/翻倍赏:怒气值开关、怒气值、道具卡选择 +- [ ] 福利屋:开始时间、结束时间、开奖时间、限购次数 +- [ ] 领主赏:领主开关、领主返还、领主奖品选择 +- [ ] 连击赏:连击次数、连击奖品选择 +- [ ] 实现自动下架配置(利润值、抽数阈值、下架金额) +- [ ] 实现解锁金额配置 + +**关联需求:** US-002 (AC-002.2, AC-002.5, AC-002.6, AC-002.8, AC-002.9, AC-002.10) + +### Task 3.3: 创建盒子编辑弹窗 +- [ ] 创建 `src/views/business/goods/components/GoodsEditDialog.vue` +- [ ] 复用新增弹窗的表单结构 +- [ ] 禁用盒子类型选择 +- [ ] 实现数据回显 +- [ ] 实现更新逻辑 + +**关联需求:** US-003 (AC-003.1, AC-003.2, AC-003.3) + +--- + +## 阶段4: 奖品管理 + +### Task 4.1: 创建奖品列表弹窗 +- [ ] 创建 `src/views/business/goods/components/PrizeListDialog.vue` +- [ ] 实现奖品搜索(标题) +- [ ] 实现动态列配置(根据盒子类型显示数量/概率) +- [ ] 实现树形表格(宝箱类型展开子奖品) +- [ ] 显示概率统计(无限赏等类型) +- [ ] 实现排序字段直接编辑 + +**关联需求:** US-004 (AC-004.1, AC-004.2, AC-004.3, AC-004.4, AC-004.5) + +### Task 4.2: 创建奖品新增弹窗 +- [ ] 创建 `src/views/business/goods/components/PrizeAddDialog.vue` +- [ ] 实现基础信息表单(名称、售价、采购价、参考价) +- [ ] 实现奖品分类选择(现货/预售/货币/宝箱) +- [ ] 实现奖品等级选择(A/B/C/D/E) +- [ ] 实现图片上传(奖品图、详情图) +- [ ] 实现表单验证 + +**关联需求:** US-005 (AC-005.1, AC-005.2, AC-005.3, AC-005.8) + +### Task 4.3: 实现奖品条件字段 +- [ ] 根据盒子类型显示数量或概率字段 +- [ ] 翻倍赏显示赠送倍率 +- [ ] 领主赏显示是否领主开关 +- [ ] 预售类型显示预售时间 +- [ ] 实现赠送货币配置组件 + +**关联需求:** US-005 (AC-005.4, AC-005.5, AC-005.6, AC-005.7) + +### Task 4.4: 创建奖品编辑弹窗 +- [ ] 创建 `src/views/business/goods/components/PrizeEditDialog.vue` +- [ ] 复用新增弹窗的表单结构 +- [ ] 实现数据回显 +- [ ] 实现更新逻辑 +- [ ] 实现删除功能 + +**关联需求:** US-004 (AC-004.6) + +--- + +## 阶段5: 盒子类型管理 + +### Task 5.1: 创建盒子类型管理页面 +- [ ] 创建 `src/views/business/goods/type.vue` +- [ ] 实现类型列表表格(ID、名称、Key、排序) +- [ ] 实现首页显示、分类显示开关 +- [ ] 显示支付方式、角标文字 +- [ ] 实现新增、编辑、删除操作 + +**关联需求:** US-006 (AC-006.1, AC-006.2, AC-006.3, AC-006.4, AC-006.5) + +### Task 5.2: 创建类型新增/编辑弹窗 +- [ ] 创建 `src/views/business/goods/components/TypeAddDialog.vue` +- [ ] 创建 `src/views/business/goods/components/TypeEditDialog.vue` +- [ ] 实现类型名称、Key、排序输入 +- [ ] 实现首页显示、分类显示开关 +- [ ] 实现支付方式多选 +- [ ] 实现角标文字输入 +- [ ] 实现支付类型选择(抵扣/支付) + +**关联需求:** US-006 (AC-006.2, AC-006.3, AC-006.4, AC-006.5) + +--- + +## 阶段6: 扩展功能和测试 + +### Task 6.1: 创建盒子扩展设置弹窗 +- [ ] 创建 `src/views/business/goods/components/GoodsExtendDialog.vue` +- [ ] 显示盒子基本信息 +- [ ] 实现支付方式多选 +- [ ] 实现支付类型选择 +- [ ] 实现保存和删除扩展设置 + +**关联需求:** US-007 (AC-007.1, AC-007.2, AC-007.3, AC-007.4) + +### Task 6.2: 配置路由和权限 +- [ ] 在 `src/router/modules/business.ts` 添加路由配置 +- [ ] 配置盒子管理路由 `/business/goods` +- [ ] 配置盒子类型路由 `/business/goods/type` +- [ ] 配置权限标识 `goods:list`, `goods:type` + +**关联需求:** 所有 + +--- + +## 阶段7: 属性测试 + +### Task 7.1: 创建属性测试 +- [ ] 创建 `GoodsManagementFrontendPropertyTests.cs` +- [ ] 测试盒子类型字段配置一致性 +- [ ] 测试盒子创建有效数据成功 +- [ ] 测试盒子创建无效类型失败 +- [ ] 测试奖品创建有效数据成功 +- [ ] 测试奖品概率总和不超过100% + +**关联需求:** NFR-001 + +--- + +## 验收检查清单 + +### 功能验收 +- [ ] 盒子列表正常显示,支持搜索、分页 +- [ ] 盒子新增支持10种类型,字段动态显示正确 +- [ ] 盒子编辑类型不可修改,其他字段可编辑 +- [ ] 奖品列表根据盒子类型显示不同列 +- [ ] 奖品新增/编辑功能正常 +- [ ] 盒子类型管理功能正常 +- [ ] 盒子扩展设置功能正常 + +### 非功能验收 +- [ ] 分页加载性能正常 +- [ ] 图片懒加载生效 +- [ ] 表单验证实时反馈 +- [ ] 操作提示正确显示 +- [ ] 删除操作有二次确认 +- [ ] 属性测试全部通过 diff --git a/docs/后台管理系统-功能分析清单.md b/docs/后台管理系统-功能分析清单.md index 6591c5e2..cc9c9c79 100644 --- a/docs/后台管理系统-功能分析清单.md +++ b/docs/后台管理系统-功能分析清单.md @@ -82,10 +82,10 @@ 由于模块较多,建议分批次分析: ### 第一批(本次会话) -- [ ] User/ - 用户管理模块 +- [x] User/ - 用户管理模块 ✅ 前端迁移已完成 (2026-01-17) ### 第二批 -- [ ] Goods/ - 商品管理模块 +- [ ] Goods/ - 商品管理模块 ⏳ 进行中 ### 第三批 - [ ] Order/ - 订单管理模块 diff --git a/docs/后台管理系统迁移批次规划.md b/docs/后台管理系统迁移批次规划.md index ca738020..cf6ceb89 100644 --- a/docs/后台管理系统迁移批次规划.md +++ b/docs/后台管理系统迁移批次规划.md @@ -36,7 +36,7 @@ | 序号 | 模块 | 功能 | 复杂度 | 后端状态 | 前端状态 | |------|------|------|--------|----------|----------| | 1 | Index/ | 首页仪表盘 | ⭐⭐⭐ | ✅ 已完成 | ⏳ 待迁移 | -| 2 | User/ | 用户管理(基础) | ⭐⭐⭐⭐⭐ | ✅ 已完成 | ⏳ 待迁移 | +| 2 | User/ | 用户管理(基础) | ⭐⭐⭐⭐⭐ | ✅ 已完成 | ✅ 已完成 | | 3 | Goods/ | 商品管理(基础) | ⭐⭐⭐⭐⭐ | ✅ 已完成 | ⏳ 待迁移 | | 4 | Order/ | 订单管理(基础) | ⭐⭐⭐⭐ | ✅ 已完成 | ⏳ 待迁移 | @@ -343,10 +343,10 @@ graph TD ### 批次1交付物 - [ ] 仪表盘页面(Vue 3 + Element Plus) -- [ ] 用户管理页面(列表、详情、操作) +- [x] 用户管理页面(列表、详情、操作)✅ 2026-01-17 完成 - [ ] 商品管理页面(盒子、奖品) - [ ] 订单管理页面(列表、发货) -- [ ] 单元测试和属性测试 +- [x] 用户管理单元测试和属性测试 ✅ 2026-01-17 完成 ### 批次2交付物 - [ ] 财务管理页面(流水、充值) @@ -433,4 +433,5 @@ graph TD | 日期 | 版本 | 更新内容 | |------|------|----------| | 2026-01-17 | v1.0 | 初始版本,完成9个批次规划 | +| 2026-01-17 | v1.1 | 用户管理模块前端迁移完成 |