Selaa lähdekoodia

📝 docs(stories): 创建购物车商品名称显示优化故事006.010

🤖 Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 1 kuukausi sitten
vanhempi
sitoutus
d0f2f199c2
1 muutettua tiedostoa jossa 167 lisäystä ja 0 poistoa
  1. 167 0
      docs/stories/006.010.story.md

+ 167 - 0
docs/stories/006.010.story.md

@@ -0,0 +1,167 @@
+# Story 006.010: 购物车商品名称显示优化
+
+## Status
+Approved
+
+## Story
+**As a** 购物车用户,
+**I want** 父子商品在购物车中分开显示商品名称和规格名称,
+**so that** 我能清晰了解商品全貌,父子商品信息显示完整准确
+
+## Acceptance Criteria
+1. 购物车中父子商品显示时,商品名称显示父商品名称,规格名称显示子商品规格名称
+2. 单规格商品显示保持不变
+3. 订单提交页面、订单详情页等所有相关页面显示一致
+4. 现有功能不受影响,无回归问题
+5. 父子商品信息显示清晰完整,用户能直观了解商品全貌
+
+## Tasks / Subtasks
+- [ ] 任务1:修改购物车页面商品名称显示逻辑 (AC: 1, 2, 5)
+  - [ ] 检查购物车页面当前显示逻辑 (`mini/src/pages/cart/index.tsx:253`)
+  - [ ] 修改 `goodsName` 计算逻辑:判断是否为子商品(通过 `parentGoodsId !== 0` 或 `spuId > 0`)
+  - [ ] 如果是子商品,商品名称使用 `latestGoods?.parent?.name` 获取父商品名称
+  - [ ] 规格名称使用 `latestGoods?.name || '选择规格'` 显示子商品规格名称
+  - [ ] 对于单规格商品(`parentGoodsId === 0`),保持现有显示方式不变
+  - [ ] 移除对 `item.spec` 字段的依赖(子商品的 `name` 字段已包含规格信息)
+  - [ ] 验证购物车总价计算不受影响
+- [ ] 任务2:修改订单提交页面商品名称显示逻辑 (AC: 3)
+  - [ ] 检查订单提交页面当前显示逻辑 (`mini/src/pages/order-submit/index.tsx:277`)
+  - [ ] 应用与购物车页面相同的父子商品名称显示逻辑
+  - [ ] 确保商品名称和规格名称分开显示,保持一致性
+  - [ ] 验证订单创建和提交流程不受影响
+- [ ] 任务3:移除 CartContext 中的 spec 字段 (AC: 4)
+  - [ ] 检查 `CartItem` 接口中的 `spec` 字段 (`mini/src/contexts/CartContext.tsx`)
+  - [ ] 移除 `spec` 字段定义(子商品的 `name` 字段已包含规格信息)
+  - [ ] 更新 `switchSpec` 函数,移除对 `spec` 字段的依赖
+  - [ ] 检查其他可能使用 `spec` 字段的地方并更新
+  - [ ] 验证购物车功能正常工作,包括规格切换功能
+- [ ] 任务4:更新商品详情页面的 spec 字段逻辑 (AC: 4)
+  - [ ] 检查商品详情页面添加购物车时设置 `spec` 字段的逻辑 (`mini/src/pages/goods-detail/index.tsx`)
+  - [ ] 移除设置 `spec` 字段的代码(不再需要,使用子商品 `name` 字段)
+  - [ ] 验证添加购物车功能正常工作
+- [ ] 任务5:编写和更新测试 (AC: 4)
+  - [ ] 为购物车页面商品名称显示逻辑添加单元测试
+  - [ ] 为订单提交页面商品名称显示逻辑添加单元测试
+  - [ ] 更新现有购物车测试,验证移除 `spec` 字段后的兼容性
+  - [ ] 添加集成测试验证父子商品名称显示准确性
+  - [ ] 运行现有测试套件,确保无回归问题
+- [ ] 任务6:验证多租户兼容性和向后兼容性 (AC: 4)
+  - [ ] 验证父子商品在同一租户下的约束
+  - [ ] 确保商品详情API返回的 `parent` 对象包含完整信息
+  - [ ] 验证单规格商品和无父子关系的商品功能不受影响
+  - [ ] 进行端到端测试验证完整流程
+
+## Dev Notes
+
+### 先前故事洞察
+- **故事9(父子商品名称关联查询优化)**:已建立可靠的父子商品名称关联查询机制,商品详情API返回完整的 `parent` 对象,包含父商品基本信息(id、name、price、costPrice、stock、imageFileId、goodsType、spuId)
+- **故事8(购物车页面规格切换功能)**:已扩展 `CartContext`,`CartItem` 接口包含 `parentGoodsId` 字段,购物车页面已集成规格选择器
+- **故事4-7**:商品API已支持父子商品关系,购物车和订单系统已支持子商品规格
+- **关键设计决策**:规格=子商品的名称,规格选择=选择子商品,购物车逻辑简化(使用子商品的 `id`、`name`、`price`、`stock`)
+- **当前实现状态**:`GoodsServiceMt.getById` 方法已返回完整的 `parent` 对象,购物车页面可通过 `latestGoods?.parent?.name` 获取父商品名称
+- [Source: docs/stories/006.009.parent-child-goods-name-relation-query.story.md#Dev-Notes]
+
+### 数据模型
+- **商品实体 (`GoodsMt`)**:
+  - `spuId` 字段:0表示父商品或单规格商品,>0表示子商品
+  - `spuName` 字段:父商品名称(冗余字段,已从API响应中移除,保留在实体中保持向后兼容性)
+  - `tenantId` 字段:租户ID,父子商品必须在同一租户下
+  - `name` 字段:商品名称,对于子商品就是规格名称
+  - [Source: packages/goods-module-mt/src/entities/goods.entity.mt.ts#L76-L81]
+
+- **商品Schema**:
+  - `PublicGoodsSchema`:包含 `parent: ParentGoodsSchema.nullable().optional()` 和 `children: z.array(PublicGoodsSchema).nullable().optional()` 字段,无 `spuName` 字段
+  - `ParentGoodsSchema`:父商品精简Schema,包含 id、name、price、costPrice、stock、imageFileId、goodsType、spuId 字段
+  - [Source: packages/goods-module-mt/src/schemas/parent-goods.schema.mt.ts]
+  - [Source: packages/goods-module-mt/src/schemas/public-goods.schema.mt.ts#L125-L127]
+
+- **购物车数据模型**:
+  - `CartItem` 接口:包含 `parentGoodsId` 字段,`spec` 字段待移除
+  - 购物车项使用子商品的 `id`、`name`、`price`、`stock` 信息
+  - [Source: mini/src/contexts/CartContext.tsx#L4-L13]
+
+### API 规范
+- **商品详情API** (`GET /api/v1/goods/:id`):
+  - 父商品:返回商品详情 + `children` 数组(子商品列表)
+  - 子商品:返回子商品详情 + `parent` 对象(父商品基本信息)
+  - `parent` 对象字段:id、name、price、costPrice、stock、imageFileId、goodsType、spuId
+  - API不再返回 `spuName` 字段,前端使用 `parent.name` 获取父商品名称
+  - [Source: packages/goods-module-mt/src/services/goods.service.mt.ts#L120-L126]
+
+- **购物车数据获取**:
+  - 购物车页面通过 `goodsMap` 存储从商品详情API获取的最新商品信息
+  - 可通过 `latestGoods?.parent?.name` 获取父商品名称
+  - [Source: mini/src/pages/cart/index.tsx#L251-L253]
+
+### 组件规范
+- **购物车页面 (`cart/index.tsx`)**:
+  - 当前商品名称显示:`goodsName = latestGoods?.name || item.name`(第253行)
+  - 购物车项包含 `parentGoodsId` 字段
+  - 需要修改的逻辑:判断是否为子商品,商品名称使用 `parent.name`,规格名称使用子商品 `name`
+  - [Source: mini/src/pages/cart/index.tsx#L253]
+
+- **订单提交页面 (`order-submit/index.tsx`)**:
+  - 当前商品名称显示:`item.name`(第277行)
+  - 需要应用与购物车页面相同的显示逻辑
+  - [Source: mini/src/pages/order-submit/index.tsx#L277]
+
+- **购物车上下文 (`CartContext`)**:
+  - `CartItem` 接口包含 `parentGoodsId` 字段,`spec` 字段待移除
+  - `switchSpec` 函数支持规格切换,需要更新以移除 `spec` 字段依赖
+  - [Source: mini/src/contexts/CartContext.tsx#L4-L13]
+
+- **商品详情页面 (`goods-detail/index.tsx`)**:
+  - 添加购物车时可能设置 `spec` 字段,需要移除相关代码
+  - [Source: mini/src/pages/goods-detail/index.tsx]
+
+### 文件位置
+- **主要修改文件**:
+  - `mini/src/pages/cart/index.tsx` - 修改商品名称显示逻辑(第253行 `goodsName` 计算)
+  - `mini/src/pages/order-submit/index.tsx` - 修改商品名称显示逻辑(第277行 `item.name` 显示)
+  - `mini/src/pages/goods-detail/index.tsx` - 移除添加购物车时设置 `spec` 字段的逻辑
+  - `mini/src/contexts/CartContext.tsx` - 移除 `CartItem` 接口中的 `spec` 字段,更新 `switchSpec` 函数
+  - [Source: docs/prd/epic-006-parent-child-goods-multi-spec-support.md#故事10]
+
+- **测试文件**:
+  - `mini/tests/unit/pages/cart/index.test.tsx` - 更新购物车页面测试
+  - `mini/tests/unit/pages/order-submit/index.test.tsx` - 添加订单提交页面测试(如不存在则创建)
+  - `mini/tests/unit/contexts/CartContext.test.tsx` - 更新购物车上下文测试
+  - [Source: docs/architecture/testing-strategy.md#单元测试-unit-tests]
+
+### 技术约束
+- **多租户要求**:所有操作必须包含 `tenantId` 过滤,父子商品必须在同一租户下
+- **向后兼容性**:现有功能不受影响,数据库实体保留 `spuName` 字段,仅从API响应中移除
+- **性能考虑**:关联查询不应显著影响API响应时间,购物车页面显示逻辑应保持高效
+- **数据一致性**:通过关联查询解决 `spuName` 字段同步问题,确保父子商品名称显示准确
+- [Source: docs/architecture/tech-stack.md]
+- [Source: docs/architecture/source-tree.md]
+
+### 测试标准
+- **测试框架**:mini项目使用Jest,商品模块使用Vitest
+- **测试位置**:`tests` 文件夹与源码并列(例如:`mini/tests/unit/pages/cart/index.test.tsx`)
+- **单元测试位置**:`mini/tests/unit/` 目录下对应页面和组件的测试文件
+- **集成测试位置**:`mini/tests/integration/` 目录(如适用)
+- **测试覆盖率**:核心业务逻辑 > 80%,关键函数 > 90%
+- **测试策略**:验证父子商品名称显示准确性、单规格商品显示不变、现有功能无回归
+- **RPC客户端架构最佳实践**:使用单例模式的客户端管理器,在测试中正确mock客户端管理器的get()方法调用链
+- [Source: docs/architecture/testing-strategy.md#单元测试-unit-tests]
+- [Source: docs/architecture/coding-standards.md#rpc客户端架构最佳实践]
+
+## Change Log
+| Date | Version | Description | Author |
+|------|---------|-------------|--------|
+| 2025-12-14 | 1.0 | 初始故事创建 | Bob (Scrum Master) |
+
+## Dev Agent Record
+*此部分由开发代理在实施过程中填写*
+
+### Agent Model Used
+
+### Debug Log References
+
+### Completion Notes List
+
+### File List
+
+## QA Results
+*此部分由QA代理在审查完成后填写*