Browse Source

✨ feat(docs): 新增父子商品多规格选择组件开发故事文档

- 创建故事文档 006.005.parent-child-goods-multi-spec-selector.story.md
- 定义用户故事:作为商品购买用户,希望在商品详情页选择子商品作为规格选项
- 制定验收标准:激活现有组件、支持父子商品关系、集成真实API、适配多租户、完善测试
- 详细规划开发任务:组件分析、API集成、多租户适配、页面集成、测试覆盖
- 提供技术栈、源码树、数据模型、API接口等开发上下文信息
- 明确编码标准、测试框架和项目结构注意事项
yourname 1 month ago
parent
commit
bdac94a82f
1 changed files with 165 additions and 0 deletions
  1. 165 0
      docs/stories/006.005.parent-child-goods-multi-spec-selector.story.md

+ 165 - 0
docs/stories/006.005.parent-child-goods-multi-spec-selector.story.md

@@ -0,0 +1,165 @@
+# Story 006.005: 父子商品多规格选择组件开发
+
+## Status
+Draft
+
+## Story
+**As a** 商品购买用户
+**I want** 在商品详情页选择子商品作为规格选项
+**so that** 我能够购买特定规格(如颜色、尺寸、配置等)的商品
+
+## Acceptance Criteria
+1. 激活并增强现有的`GoodsSpecSelector`组件,移除模拟数据
+2. 组件支持父子商品关系,以子商品名称作为规格选项显示
+3. 规格选择实际选择对应的子商品ID,而不仅仅是规格名称
+4. 组件适配多租户商品数据查询,包含正确的tenantId过滤
+5. 规格选择器能正确显示子商品名称作为规格,并能选择对应的子商品
+6. 选择规格后,组件应显示子商品的价格、库存等信息
+
+## Tasks / Subtasks
+- [ ] 分析现有GoodsSpecSelector组件实现 (AC: 1)
+  - [ ] 查看当前组件代码和模拟数据逻辑
+  - [ ] 分析组件在商品详情页中的使用方式(当前被注释)
+  - [ ] 确定需要修改的接口和数据结构
+- [ ] 修改GoodsSpecSelector组件支持父子商品关系 (AC: 2, 3)
+  - [ ] 更新SpecOption接口,支持子商品ID、价格、库存等字段
+  - [ ] 修改组件props,接收父商品ID而不是通用商品ID
+  - [ ] 实现子商品数据获取逻辑,替换模拟数据
+  - [ ] 更新规格选择逻辑,确保选择的是子商品ID
+- [ ] 集成子商品列表API调用 (AC: 2, 3)
+  - [ ] 在组件中添加API调用获取子商品列表(GET /api/v1/goods/{id}/children)
+  - [ ] 处理API加载状态、错误状态和空状态
+  - [ ] 将API响应数据转换为组件所需的SpecOption格式
+  - [ ] 确保API调用包含多租户参数
+- [ ] 适配多租户数据查询 (AC: 4)
+  - [ ] 确保API调用包含正确的tenantId参数
+  - [ ] 验证父子商品在同一租户下的数据一致性
+  - [ ] 添加租户数据隔离的安全检查
+- [ ] 在商品详情页取消注释并集成组件 (AC: 5)
+  - [ ] 取消商品详情页中对GoodsSpecSelector组件的注释
+  - [ ] 更新商品详情页的规格选择状态管理
+  - [ ] 集成组件与"立即购买"和"加入购物车"功能
+  - [ ] 确保向后兼容性(无规格商品保持现有行为)
+- [ ] 添加单元测试和集成测试 (AC: 1-6)
+  - [ ] 为GoodsSpecSelector组件添加单元测试
+  - [ ] 测试组件渲染、规格选择、API调用等场景
+  - [ ] 添加商品详情页集成测试
+  - [ ] 确保测试覆盖多租户场景
+  - [ ] 验证所有测试通过
+
+## Dev Notes
+
+### 技术栈信息 [Source: architecture/tech-stack.md]
+- **前端框架**: React 19.1.0 + TypeScript
+- **小程序框架**: Taro(微信小程序)
+- **构建工具**: Vite 7.0.0
+- **状态管理**: @tanstack/react-query (服务端状态)
+- **UI组件库**: shadcn/ui (基于Radix UI)
+- **样式**: Tailwind CSS 4.1.11
+- **HTTP客户端**: 基于Hono Client的封装 + axios适配器
+
+### 源码树信息 [Source: architecture/source-tree.md]
+- **小程序项目位置**: `mini/` - 小程序项目 (Taro + React)
+- **组件位置**: `mini/src/components/goods-spec-selector/index.tsx` - 现有规格选择器组件
+- **页面位置**: `mini/src/pages/goods-detail/index.tsx` - 商品详情页面(当前组件被注释)
+- **API客户端位置**: `mini/src/api.ts` - API客户端配置
+- **测试位置**: `mini/tests/` - 小程序测试文件
+
+### 数据模型信息 [Source: docs/stories/006.004.goods-api-parent-child-support-optimization.story.md:68-73]
+- **商品实体字段**:
+  - `id`: number - 商品ID
+  - `spuId`: number - 主商品ID,0表示父商品或单规格商品,>0表示子商品
+  - `spuName`: string | null - 主商品名称
+  - `tenantId`: number - 租户ID,用于多租户数据隔离
+  - `state`: number - 状态(1可用,2不可用)
+  - `name`: string - 商品名称(子商品名称作为规格名称)
+  - `price`: number - 商品价格
+  - `stock`: number - 商品库存
+- **父子商品关系**: 通过spuId字段建立父子关系,子商品的spuId指向父商品的id
+
+### API信息 [Source: docs/prd/epic-006-parent-child-goods-multi-spec-support.md:79]
+- **获取子商品列表API**: `GET /api/v1/goods/{id}/children` - 已实现,返回指定父商品的子商品列表
+- **API响应格式**: 返回子商品数组,每个子商品包含id、name、price、stock等字段
+- **API路由位置**: `packages/goods-module-mt/src/routes/public-goods-children.mt.ts`
+
+### 现有组件分析
+- **`GoodsSpecSelector`当前状态** [Source: mini/src/components/goods-spec-selector/index.tsx]:
+  - 使用模拟数据(mockSpecs),未调用真实API
+  - 当前SpecOption接口:id、name、price、stock、image
+  - 当前props:visible、onClose、onConfirm、goodsId、currentSpec、currentQuantity
+  - 需要修改:将goodsId改为parentGoodsId,添加API调用逻辑
+- **`GoodsDetailPage`当前状态** [Source: mini/src/pages/goods-detail/index.tsx:11]:
+  - 规格选择功能被注释(第11行:`// import { GoodsSpecSelector } from '@/components/goods-spec-selector'`)
+  - 规格选择状态管理被注释(第45-46行)
+  - 需要取消注释并更新组件集成
+
+### 多租户支持要求 [Source: docs/stories/006.004.goods-api-parent-child-support-optimization.story.md:139]
+- 保持多租户支持完整,所有查询必须包含tenantId过滤
+- 父子商品必须在同一租户下
+- API调用需要传递正确的租户上下文
+
+### RPC客户端架构 [Source: architecture/coding-standards.md:28-33]
+- 使用单例模式的客户端管理器确保全局唯一的客户端实例
+- 组件中应使用`clientManager.get().api.$method`调用API
+- 类型安全:使用Hono的InferRequestType和InferResponseType确保类型一致性
+- 测试Mock:在测试中正确mock客户端管理器的get()方法调用链
+
+### 文件位置
+- **组件文件**: `mini/src/components/goods-spec-selector/index.tsx`
+- **组件样式**: `mini/src/components/goods-spec-selector/index.css`(如果存在)
+- **页面文件**: `mini/src/pages/goods-detail/index.tsx`
+- **API客户端**: `mini/src/api.ts`
+- **测试文件**: `mini/tests/components/goods-spec-selector.test.tsx`(需要创建)
+- **集成测试**: `mini/tests/pages/goods-detail.test.tsx`(需要更新)
+
+### 编码标准 [Source: architecture/coding-standards.md]
+- **测试框架**: Vitest + Testing Library
+- **测试位置**: `tests`文件夹与源码并列(例如:`mini/tests/components/`)
+- **覆盖率目标**: 核心业务逻辑 > 80%
+- **测试类型**: 单元测试、集成测试
+
+### Testing
+- **测试框架**: Vitest + Testing Library
+- **测试文件位置**:
+  - 组件单元测试: `mini/tests/components/goods-spec-selector.test.tsx`
+  - 页面集成测试: `mini/tests/pages/goods-detail.test.tsx`
+- **测试标准**:
+  - 组件渲染测试:验证组件正确渲染规格选项
+  - API调用测试:验证组件正确调用子商品列表API
+  - 用户交互测试:验证规格选择、数量调整等功能
+  - 多租户测试:验证API调用包含正确的tenantId参数
+  - 错误处理测试:验证API错误、空状态等情况
+- **测试模式**:
+  - 使用`vi.mock()` mock API客户端
+  - 使用`render`函数渲染组件
+  - 使用`fireEvent`模拟用户交互
+  - 验证组件状态变化和回调调用
+- **具体测试要求**:
+  - 测试组件使用真实API而不是模拟数据
+  - 测试规格选择正确传递子商品ID
+  - 测试多租户参数正确传递
+  - 测试商品详情页集成功能
+  - 确保向后兼容性
+
+### 项目结构注意事项
+- 保持多租户支持完整,所有API调用必须包含tenantId参数
+- 父子商品关系数据一致性验证
+- 保持API向后兼容性,不影响现有功能
+- 组件修改保持现有接口兼容性(尽可能)
+
+## Change Log
+| Date | Version | Description | Author |
+|------|---------|-------------|--------|
+| 2025-12-12 | 1.0 | 初始故事创建 | Bob (Scrum Master) |
+
+## Dev Agent Record
+
+### Agent Model Used
+
+### Debug Log References
+
+### Completion Notes List
+
+### File List
+
+## QA Results