进度: 10/13 故事完成 (76.9%) 最近更新: 2025-12-15 (故事10:购物车商品名称显示优化完成) 当前状态: 故事1-10已完成,故事11-13待开始
新增父子商品多规格支持功能,在商品添加购物车或立即购买时,能同时支持单规格和多规格选择,以子商品作为多规格选项,并支持手动指定子商品。
GoodsParentChildPanel.tsx)ChildGoodsList.tsx)和批量创建(BatchSpecCreatorInline.tsx)组件GoodsSpecSelector组件但被注释,购物车支持spec字段但无规格选择逻辑publicGoodsRoutesMt(公共商品路由)adminGoodsRoutesMt(已聚合父子商品管理API)name字段作为规格名称id、name、price、stockid、name、price、stockname字段已经包含完整的规格信息,spec字段可能暂时不需要/api/v1/goods):默认只返回父商品(spuId=0)/api/v1/goods/:id):
GET /api/v1/goods/:id/children - 获取指定父商品的子商品列表POST /api/v1/goods/:id/set-as-parent - 将普通商品设为父商品DELETE /api/v1/goods/:id/parent - 解除子商品的父子关系POST /api/v1/goods/batch-create-children - 批量创建子商品(支持事务)admin-goods-aggregated.mt.ts聚合基础CRUD和父子商品管理路由,保持adminGoodsRoutesMt名称不变,前端代码无需修改spuId查询参数过滤,管理员可通过spuId=0只查看父商品故事1:管理后台父子商品配置功能 ✅ 已完成 (2025-12-07)
故事2:父子商品管理UI体验优化 ✅ 已完成 (2025-12-10)
adminGoodsRoutesMt中聚合父子商品管理API(获取子商品列表、设为父商品、解除关系、批量创建)GoodsParentChildPanel.tsx组件已创建并支持创建/编辑模式ChildGoodsList.tsx和BatchSpecCreatorInline.tsx组件已创建并集成到面板中GoodsManagement.tsx已集成新面板到创建和编辑表单admin-goods-aggregated.mt.ts聚合基础CRUD和父子商品管理路由,保持adminGoodsRoutesMt名称不变onDataChange回调实现面板与表单数据的实时同步故事3:子商品行内编辑功能 ✅ 已完成 (2025-12-11)
ChildGoodsList.tsx组件中添加行内编辑模式ChildGoodsList组件,支持editingChildId状态管理ChildGoodsList组件,添加了行内编辑功能ChildGoodsInlineEditForm组件,支持所有必需字段的编辑handleEdit函数逻辑:行内编辑现在优先于onEditChild回调enableInlineEdit配置选项,支持灵活控制行内编辑行为packages/goods-management-ui-mt/src/components/ChildGoodsInlineEditForm.tsx - 行内编辑表单组件packages/goods-management-ui-mt/tests/unit/ChildGoodsInlineEditForm.test.tsx - 行内编辑表单测试packages/goods-management-ui-mt/src/components/ChildGoodsList.tsx - 扩展行内编辑功能packages/goods-management-ui-mt/tests/unit/ChildGoodsList.test.tsx - 更新测试,添加行内编辑功能测试docs/stories/006.003.child-goods-inline-edit.story.md - 更新任务状态和开发记录故事4:商品API父子商品支持优化 ✅ 已完成 (2025-12-12)
spuId=0过滤只显示父商品@Index(['tenantId', 'spuId'])优化查询性能故事5:父子商品多规格选择组件开发 ✅ 已实现 (2025-12-12)
GoodsSpecSelector组件public-goods-aggregated.mt.ts聚合路由,确保子商品API正确暴露mini/tests/components/goods-spec-selector.test.tsx,8个测试通过故事6:商品详情页规格选择集成 ✅ 已完成
mini/src/pages/goods-detail/index.tsx - 移除过时注释,更新库存限制逻辑以支持规格库存mini/tests/unit/components/goods-spec-selector/goods-spec-selector.test.tsx - 修复测试期望和关闭按钮选择器mini/tests/unit/components/taro/Button.test.tsx - 移动Taro原生Button测试到标准位置mini/tests/unit/pages/goods-detail/goods-detail.test.tsx - 商品详情页集成测试(参照OrderButtonBar.test.tsx模式重写)mini/tests/e2e/goods-detail-spec.e2e.test.ts - E2E测试占位文件mini/tests/pages/goods-detail.test.tsx → mini/tests/unit/pages/goods-detail/goods-detail.test.tsxmini/tests/components/goods-spec-selector.test.tsx → mini/tests/unit/components/goods-spec-selector/goods-spec-selector.test.tsxmini/tests/components/Button.test.tsx → mini/tests/unit/components/taro/Button.test.tsx故事7:购物车和订单规格支持 ✅ 已完成 (2025-12-13)
addToCart逻辑,支持添加子商品(使用子商品信息填充CartItem)name字段显示完整规格信息CartContext.tsx) 已更新注释,明确支持子商品ID,购物车逻辑天然支持父子商品CreateOrderRequestDto) 已支持子商品ID,OrderGoodsMt实体正确存储子商品IDname字段(包含规格信息)实现完整规格显示CartContext.test.tsx),5个测试全部通过mini/src/contexts/CartContext.tsx - 更新接口注释和函数说明mini/tests/unit/contexts/CartContext.test.tsx - 修复测试中的useEffect依赖循环问题docs/stories/006.007.story.md - 更新任务状态和开发记录mini/tests/unit/contexts/CartContext.test.tsx - 购物车规格支持测试文件故事8:购物车页面规格切换功能 ✅ 已完成 (2025-12-13)
GoodsSpecSelector组件)CartContext或购物车组件,支持规格切换逻辑GoodsSpecSelector组件mini/src/contexts/CartContext.tsx - 扩展CartContext,添加switchSpec函数,更新CartItem接口,修复数据迁移逻辑(parentGoodsId默认值从item.id改为0)mini/src/pages/cart/index.tsx - 集成GoodsSpecSelector组件,添加规格切换功能,清理多余的调试信息mini/tests/unit/contexts/CartContext.test.tsx - 添加switchSpec函数单元测试mini/tests/unit/pages/cart/index.test.tsx - 添加购物车页面规格切换组件测试,修复测试结构使用真实CartContext,解决空购物车状态测试问题,修复库存不足提示测试,添加7个完整的规格切换集成测试mini/tests/__mocks__/taroMock.ts - 扩展Taro API mock,添加request方法支持mini/src/components/goods-spec-selector/index.tsx - 改进错误处理,解析API响应体获取具体错误消息mini/src/pages/goods-detail/index.tsx - 修复parentGoodsId计算逻辑,正确处理父子商品关系mini/tests/unit/pages/goods-detail/goods-detail.test.tsx - 更新测试期望,添加parentGoodsId字段验证docs/stories/006.008.cart-spec-switching.story.md - 更新任务状态和开发记录故事9:父子商品名称关联查询优化(为购物车显示做准备) ✅ 已完成
spuName字段冗余存储父商品名称,但存在数据一致性问题:当父商品名称更新时,不会自动同步更新子商品的spuName字段。这导致购物车等场景显示的商品名称可能不一致。故事9的目标是为故事10提供基础支持,建立可靠的父子商品名称关联查询机制。parent对象关联查询获取父商品信息,为购物车提供准确、实时的父商品名称,解决spuName字段的数据一致性问题。parent对象包含完整的父商品基本信息(至少包含id、name字段)parent字段的类型从z.any()改为具体的父商品Schema,确保类型安全goods.parent?.name获取父商品名称,用于故事10的商品名称显示优化spuName字段,前端使用parent.name获取父商品名称GoodsServiceMt.getById方法,确保parent对象包含必要字段;更新商品Schema类型定义,并从商品Schema中移除spuName字段goods.parent?.name获取父商品名称,不再依赖spuName字段,无需专门的工具函数parent对象信息parent对象包含完整的父商品基本信息(id、name等)goods.parent?.name获取父商品名称(为故事10做准备)spuName字段,前端代码直接使用parent.name获取父商品名称packages/goods-module-mt/src/schemas/parent-goods.schema.mt.ts - 父商品精简Schema定义packages/goods-module-mt/src/schemas/public-goods.schema.mt.ts - 更新parent和children字段类型,移除spuNamepackages/goods-module-mt/src/schemas/admin-goods.schema.mt.ts - 更新parent和children字段类型,移除spuNamepackages/goods-module-mt/src/schemas/user-goods.schema.mt.ts - 移除spuName字段packages/goods-module-mt/src/schemas/goods.schema.mt.ts - 更新UpdateGoodsDto,移除spuName字段packages/goods-module-mt/src/schemas/index.mt.ts - 导出ParentGoodsSchemapackages/goods-module-mt/src/services/goods.service.mt.ts - 完善getById方法,添加租户过滤和完整字段选择packages/goods-module-mt/tests/integration/admin-goods-parent-child.integration.test.ts - 更新测试验证parent对象packages/goods-module-mt/tests/integration/admin-goods-routes.integration.test.ts - 更新测试packages/goods-module-mt/tests/integration/public-goods-children.integration.test.ts - 更新测试验证spuName移除packages/goods-module-mt/tests/integration/public-goods-parent-filter.integration.test.ts - 更新测试验证parent对象完整性mini/src/pages/cart/index.tsx - 购物车页面,验证数据基础可用性packages/goods-module-mt/src/entities/goods.entity.mt.ts - 验证spuName字段保留在实体中故事10:购物车商品名称显示优化 ✅ 已完成
mini/src/pages/cart/index.tsx:253)使用goodsName = latestGoods?.name || item.name显示商品名称,对于子商品只显示规格名称,而没有显示父商品名称。购物车页面已经将商品名称和规格名称分开显示(goods-title显示商品名称,specs-text显示规格名称),但子商品的商品名称显示的是规格名称,而不是父商品名称,导致商品信息显示不完整。parent对象获取父商品名称,商品名称显示父商品名称,规格名称显示子商品规格名称,提供清晰完整的商品信息。parentGoodsId === 0),保持现有显示方式不变,直接显示商品名称mini/src/pages/order-submit/index.tsx:277)等所有显示商品名称的地方都遵循同样的显示逻辑mini/src/pages/cart/index.tsx)的商品名称显示逻辑,在goodsName计算时判断是否为子商品(通过parentGoodsId !== 0或spuId > 0)parent.name获取父商品名称(通过故事9实现的关联查询),不再使用spuName字段latestGoods?.name || '选择规格'显示子商品规格名称(子商品的name字段就是规格名称)mini/src/pages/order-submit/index.tsx)的商品名称显示逻辑,遵循同样的显示原则parent.name获取父商品名称,不再依赖spuName字段,统一处理父子商品名称获取逻辑parent对象CartItem接口中的spec字段,避免数据冗余(子商品的name字段已经包含规格信息)mini/src/pages/cart/index.tsx - 修改商品名称显示逻辑(第253行goodsName计算),移除对item.spec的依赖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函数parent.name)故事11:子商品删除功能实现 ⏳ 待开始
ChildGoodsList组件)提供了删除按钮,但该按钮没有实际作用。点击删除按钮时,handleDelete函数仅检查onDeleteChild回调是否存在,而父组件GoodsParentChildPanel并未传递此回调,导致删除操作无效。管理员无法在管理界面中直接删除子商品规格。GoodsParentChildPanel组件中为ChildGoodsList组件传递onDeleteChild回调函数GoodsParentChildPanel组件中添加onDeleteChild回调函数,处理子商品删除逻辑DELETE /api/v1/goods/:id)删除子商品实体,或使用解除父子关系API(DELETE /api/v1/goods/:id/parent)仅解除关系但保留商品(根据业务需求选择)refetch刷新子商品列表数据packages/goods-management-ui-mt/src/components/GoodsParentChildPanel.tsx - 添加onDeleteChild回调函数和删除确认对话框packages/goods-management-ui-mt/src/components/ChildGoodsList.tsx - 可能需优化删除按钮的视觉反馈故事12:商品详情页规格选择流程优化 ⏳ 待开始
mini/src/pages/goods-detail/index.tsx中的handleAddToCart和handleBuyNow函数,添加规格选择判断逻辑showSpecModal状态与操作流程关联GoodsSpecSelector组件的onConfirm回调,支持直接执行购物车添加或购买操作mini/src/pages/goods-detail/index.tsx - 重构规格选择流程,合并操作逻辑mini/src/components/goods-spec-selector/index.tsx - 扩展组件支持直接操作执行mini/src/contexts/CartContext.tsx中的购物车添加逻辑mini/src/components/goods-spec-action-context.tsx - 规格选择操作上下文组件(可选)mini/src/components/selected-spec-display.tsx - 已选规格信息显示组件(可选)故事13:父子商品列表缓存自动刷新优化 ⏳ 待开始
GoodsParentChildPanel 组件中添加 useQueryClientbatchCreateChildrenMutation 的 onSuccess 回调,使用 queryClient.invalidateQueries 使相关查询失效['goods-children', goodsId, tenantId] 和 ['goods', 'children', 'list', parentGoodsId, tenantId]packages/goods-management-ui-mt/src/components/GoodsParentChildPanel.tsx - 添加 useQueryClient,修改 mutation 的 onSuccess 回调packages/goods-management-ui-mt/src/components/ChildGoodsList.tsx - 确保行内编辑后的 refetch 逻辑正确packages/goods-management-ui-mt/tests/unit/GoodsParentChildPanel.test.tsx - 添加缓存刷新测试packages/goods-management-ui-mt/tests/unit/ChildGoodsList.test.tsx - 更新测试验证缓存刷新spuId字段:0表示父商品或单规格商品,>0表示子商品spuName字段存储父商品名称(冗余字段,故事9中移除,改用关联查询)spuId=0条件CartItem使用子商品的id、name、price、stockCartItem使用父商品的id、name、price、stockname字段已经包含完整规格信息,spec字段可暂时忽略或设置为相同值spuName字段同步问题史诗创建时间:2025-12-06 创建人:John (Product Manager) 技术栈:TypeORM + Hono + React + Taro小程序 + 多租户架构 优先级:高(支持电商核心功能)