|
|
@@ -0,0 +1,149 @@
|
|
|
+# Story 003.003: 修复商品价格显示不一致问题
|
|
|
+
|
|
|
+## Status
|
|
|
+Draft
|
|
|
+
|
|
|
+## Story
|
|
|
+**As a** 小程序用户,
|
|
|
+**I want** 在商品列表页和详情页看到一致的商品价格,
|
|
|
+**so that** 不会因为价格显示不一致而产生困惑
|
|
|
+
|
|
|
+## Acceptance Criteria
|
|
|
+1. 确保商品列表页的`price`字段与商品详情页的`price`字段数据来源一致 (`mini/src/pages/goods-list/index.tsx:166`, `mini/src/pages/goods-detail/index.tsx:227`)
|
|
|
+2. 修复商品详情页中规格选择时的价格计算逻辑,确保选中规格后价格正确更新 (`mini/src/pages/goods-detail/index.tsx:110-119`, `mini/src/components/goods-spec-selector/index.tsx`)
|
|
|
+3. 验证促销价格逻辑,确保商品列表页和详情页显示的促销价格一致
|
|
|
+4. 在商品详情页添加价格验证,确保显示的价格与后端API返回的价格一致
|
|
|
+
|
|
|
+## Tasks / Subtasks
|
|
|
+- [ ] **验证商品价格数据一致性** (AC: 1, 4)
|
|
|
+ - [ ] 检查商品列表页价格字段的数据来源 (`mini/src/pages/goods-list/index.tsx:166`)
|
|
|
+ - [ ] 检查商品详情页价格字段的数据来源 (`mini/src/pages/goods-detail/index.tsx:227`)
|
|
|
+ - [ ] 确保两个页面使用相同的API响应字段获取价格
|
|
|
+ - [ ] 添加价格验证逻辑,比较显示价格与API返回价格
|
|
|
+
|
|
|
+- [ ] **修复规格选择器价格计算逻辑** (AC: 2)
|
|
|
+ - [ ] 修复商品详情页中规格选择时的价格计算逻辑 (`mini/src/pages/goods-detail/index.tsx:110-119`)
|
|
|
+ - [ ] 确保选中规格后价格正确更新,使用规格价格而非商品基础价格
|
|
|
+ - [ ] 验证规格选择器中的价格显示逻辑 (`mini/src/components/goods-spec-selector/index.tsx:103`)
|
|
|
+ - [ ] 确保规格价格计算包含数量乘法的正确性
|
|
|
+
|
|
|
+- [ ] **验证促销价格一致性** (AC: 3)
|
|
|
+ - [ ] 检查促销价格在商品列表页和详情页的显示逻辑
|
|
|
+ - [ ] 确保促销价格计算逻辑在两个页面中一致
|
|
|
+ - [ ] 验证促销价格覆盖基础价格时的显示优先级
|
|
|
+ - [ ] 测试促销活动期间的价格显示准确性
|
|
|
+
|
|
|
+- [ ] **添加价格验证和错误处理** (AC: 4)
|
|
|
+ - [ ] 在商品详情页添加价格验证逻辑
|
|
|
+ - [ ] 当显示价格与API返回价格不一致时提供错误提示
|
|
|
+ - [ ] 添加价格数据同步检查机制
|
|
|
+ - [ ] 实现价格显示异常时的降级处理
|
|
|
+
|
|
|
+- [ ] **编写测试用例**
|
|
|
+ - [ ] 编写商品价格一致性测试用例 (`mini/tests/unit/pages/goods-list/goods-list.test.tsx`)
|
|
|
+ - [ ] 编写规格选择价格计算测试用例 (`mini/tests/unit/components/goods-spec-selector/goods-spec-selector.test.tsx`)
|
|
|
+ - [ ] 编写促销价格显示测试用例 (`mini/tests/unit/pages/goods-detail/goods-detail.test.tsx`)
|
|
|
+ - [ ] 编写价格验证逻辑测试用例 (`mini/tests/unit/utils/price-validation.test.ts`)
|
|
|
+
|
|
|
+## Dev Notes
|
|
|
+
|
|
|
+### 技术栈信息 [Source: architecture/tech-stack.md#现有技术栈维护]
|
|
|
+- **前端框架**: React 19.1.0 + TypeScript
|
|
|
+- **小程序框架**: Taro
|
|
|
+- **状态管理**: @tanstack/react-query (服务端状态管理)
|
|
|
+- **HTTP客户端**: 基于Hono Client的封装
|
|
|
+- **API调用**: RPC类型安全
|
|
|
+
|
|
|
+### 项目结构信息 [Source: architecture/source-tree.md#实际项目结构]
|
|
|
+- **小程序项目**: `mini/src/`
|
|
|
+- **商品列表页**: `mini/src/pages/goods-list/index.tsx`
|
|
|
+- **商品详情页**: `mini/src/pages/goods-detail/index.tsx`
|
|
|
+- **规格选择器组件**: `mini/src/components/goods-spec-selector/index.tsx`
|
|
|
+- **API客户端**: `mini/src/api.ts` - RPC客户端配置
|
|
|
+
|
|
|
+### 商品实体价格字段定义 [Source: packages/goods-module/src/entities/goods.entity.ts]
|
|
|
+- **price字段**: `decimal(10,2)` - 售卖价,默认值0.00
|
|
|
+- **costPrice字段**: `decimal(10,2)` - 成本价,默认值0.00
|
|
|
+- **价格精度**: 保留两位小数,使用decimal类型确保精度
|
|
|
+
|
|
|
+### 商品Schema价格验证规则 [Source: packages/goods-module/src/schemas/goods.schema.ts]
|
|
|
+- **price验证**: `z.coerce.number().multipleOf(0.01, '价格最多保留两位小数').min(0, '价格不能为负数').default(0)`
|
|
|
+- **costPrice验证**: `z.coerce.number().multipleOf(0.01, '成本价最多保留两位小数').min(0, '成本价不能为负数').default(0)`
|
|
|
+- **类型转换**: 使用`z.coerce.number()`确保字符串到数字的正确转换
|
|
|
+
|
|
|
+### 价格显示逻辑分析
|
|
|
+- **商品列表页**: 使用`goods.price`字段直接显示 (`mini/src/pages/goods-list/index.tsx:166`)
|
|
|
+- **商品详情页**: 使用`(selectedSpec?.price || goods.price).toFixed(2)`显示 (`mini/src/pages/goods-detail/index.tsx:227`)
|
|
|
+- **规格选择器**: 使用模拟数据,需要与实际SKU API集成
|
|
|
+
|
|
|
+### 先前故事洞察 [Source: docs/stories/003.002.order-goods-display-fix.story.md#Dev Agent Record]
|
|
|
+- **关联查询架构**: 故事003.002实现了订单商品关联关系,使用一对多关联替代JSON解析
|
|
|
+- **类型安全**: 通过TypeORM关联关系和Zod Schema确保类型安全
|
|
|
+- **文件URL统一**: 统一使用`fullUrl`字段和`z.url()`验证器
|
|
|
+
|
|
|
+### 编码标准 [Source: architecture/coding-standards.md#关键集成规则]
|
|
|
+- **RPC客户端架构**: 直接使用导出的客户端实例
|
|
|
+- **类型安全**: 使用Hono的InferRequestType和InferResponseType
|
|
|
+- **组件调用规范**: 直接调用 `api.$method` 方法
|
|
|
+- **错误处理**: 完善的错误处理和用户反馈机制
|
|
|
+
|
|
|
+### 测试要求 [Source: docs/architecture/testing-strategy.md#测试金字塔策略]
|
|
|
+- **测试框架**: Jest (小程序) + Testing Library
|
|
|
+- **测试类型**: 组件单元测试 + 集成测试
|
|
|
+- **测试位置**: `mini/tests/unit/` 目录
|
|
|
+- **覆盖率要求**: 核心业务逻辑 > 80%
|
|
|
+- **具体测试要求**:
|
|
|
+ - 商品列表页价格显示测试
|
|
|
+ - 商品详情页价格显示测试
|
|
|
+ - 规格选择价格计算测试
|
|
|
+ - 促销价格一致性测试
|
|
|
+
|
|
|
+## Testing
|
|
|
+
|
|
|
+### 小程序前端测试
|
|
|
+#### 测试标准 [Source: docs/architecture/testing-strategy.md#测试金字塔策略]
|
|
|
+- **测试框架**: Jest + Testing Library
|
|
|
+- **测试类型**: 组件单元测试 + 集成测试
|
|
|
+- **测试位置**: `mini/tests/unit/` 目录
|
|
|
+- **覆盖率要求**: 核心业务逻辑 > 80%
|
|
|
+
|
|
|
+#### 具体测试要求
|
|
|
+- **商品列表页价格测试** `mini/tests/unit/pages/goods-list/goods-list.test.tsx`
|
|
|
+ - 验证商品列表页中价格字段的正确显示 (参考 `mini/src/pages/goods-list/index.tsx:166`)
|
|
|
+ - 验证价格格式化逻辑(保留两位小数)
|
|
|
+ - 验证价格数据来源与API响应一致 (参考 `packages/goods-module/src/schemas/goods.schema.ts:13-16`)
|
|
|
+
|
|
|
+- **商品详情页价格测试** `mini/tests/unit/pages/goods-detail/goods-detail.test.tsx`
|
|
|
+ - 验证商品详情页基础价格显示 (参考 `mini/src/pages/goods-detail/index.tsx:227`)
|
|
|
+ - 验证规格选择时的价格更新逻辑 (参考 `mini/src/pages/goods-detail/index.tsx:110-119`)
|
|
|
+ - 验证促销价格显示优先级
|
|
|
+ - 验证价格与API返回数据的一致性
|
|
|
+
|
|
|
+- **规格选择器组件测试** `mini/tests/unit/components/goods-spec-selector/goods-spec-selector.test.tsx`
|
|
|
+ - 验证规格选择时的价格计算 (参考 `mini/src/components/goods-spec-selector/index.tsx:103`)
|
|
|
+ - 验证数量变化时的总价计算 (参考 `mini/src/components/goods-spec-selector/index.tsx:144`)
|
|
|
+ - 验证规格价格覆盖基础价格的逻辑
|
|
|
+
|
|
|
+- **价格验证测试** `mini/tests/unit/utils/price-validation.test.ts`
|
|
|
+ - 验证价格一致性检查逻辑
|
|
|
+ - 测试价格显示异常时的错误处理
|
|
|
+ - 验证价格数据同步机制 (参考 `packages/goods-module/src/entities/goods.entity.ts:15-16`)
|
|
|
+
|
|
|
+## Change Log
|
|
|
+| Date | Version | Description | Author |
|
|
|
+|------|---------|-------------|---------|
|
|
|
+| 2025-11-23 | 1.0 | 初始故事创建 | Bob |
|
|
|
+
|
|
|
+## Dev Agent Record
|
|
|
+
|
|
|
+### Agent Model Used
|
|
|
+- Claude Code (d8d-model)
|
|
|
+
|
|
|
+### Debug Log References
|
|
|
+
|
|
|
+### Completion Notes List
|
|
|
+
|
|
|
+### File List
|
|
|
+
|
|
|
+## QA Results
|
|
|
+*Results from QA Agent QA review of the completed story implementation*
|