diff --git a/.kiro/specs/goods-system-migration/design.md b/.kiro/specs/goods-system-migration/design.md new file mode 100644 index 00000000..a5da1b9c --- /dev/null +++ b/.kiro/specs/goods-system-migration/design.md @@ -0,0 +1,365 @@ +# Design Document: 商品系统迁移 + +## Overview + +本设计文档描述将PHP商品系统迁移到.NET 8的技术方案。商品系统是抽赏平台的核心模块,需要实现商品列表、详情、箱号管理、收藏、奖品统计、中奖记录等功能,同时保持与原PHP API的兼容性。 + +## Architecture + +### 系统架构图 + +```mermaid +graph TB + subgraph "API Layer" + GC[GoodsController] + CC[CollectionController] + end + + subgraph "Service Layer" + GS[GoodsService] + CS[CollectionService] + PS[PrizeService] + CacheS[GoodsCacheService] + end + + subgraph "Data Layer" + DB[(MySQL Database)] + Redis[(Redis Cache)] + end + + GC --> GS + GC --> PS + CC --> CS + GS --> CacheS + GS --> DB + CS --> DB + PS --> DB + CacheS --> Redis +``` + +### 数据流图 + +```mermaid +sequenceDiagram + participant Client + participant Controller + participant Service + participant Cache + participant Database + + Client->>Controller: GET /goods + Controller->>Service: GetGoodsListAsync() + Service->>Cache: TryGetGoodsList() + alt Cache Hit + Cache-->>Service: Cached Data + else Cache Miss + Service->>Database: Query Goods + Database-->>Service: Goods Data + Service->>Cache: SetGoodsList() + end + Service-->>Controller: GoodsListDto + Controller-->>Client: JSON Response +``` + +## Components and Interfaces + +### 1. GoodsService + +```csharp +public interface IGoodsService +{ + // 商品列表查询 + Task> GetGoodsListAsync(GoodsQueryRequest request, int userId); + + // 商品详情查询 + Task GetGoodsDetailAsync(int goodsId, int goodsNum, int userId); + + // 商品子奖品查询 + Task> GetGoodsChildrenAsync(int goodsId, int goodsNum, int goodsListId); + + // 商品扩展配置查询 + Task GetGoodsExtendAsync(int goodsId, int goodsType); + + // 箱号列表查询 + Task> GetBoxListAsync(int goodsId); + + // 箱号详情查询 + Task> GetBoxDetailAsync(int goodsId, int pageNo, int sort); +} +``` + +### 2. CollectionService + +```csharp +public interface ICollectionService +{ + // 收藏/取消收藏 + Task ToggleCollectionAsync(int userId, int goodsId, int goodsNum, string action); + + // 收藏列表查询 + Task> GetCollectionListAsync(int userId, int page, int limit); + + // 检查收藏状态 + Task IsCollectedAsync(int userId, int goodsId, int goodsNum); +} +``` + +### 3. PrizeService + +```csharp +public interface IPrizeService +{ + // 奖品数量统计 + Task GetPrizeCountAsync(int goodsId); + + // 奖品内容查询 + Task GetPrizeContentAsync(int goodsId, int num); + + // 中奖记录查询 + Task GetPrizeLogsAsync(int goodsId, int goodsNum, int shangId, int page); +} +``` + +### 4. GoodsCacheService + +```csharp +public interface IGoodsCacheService +{ + // 获取商品参与次数 + Task GetJoinCountAsync(int goodsId); + + // 更新商品参与次数 + Task IncrementJoinCountAsync(int goodsId); + + // 清除商品缓存 + Task InvalidateGoodsCacheAsync(int goodsId); +} +``` + +## Data Models + +### Request Models + +```csharp +public class GoodsQueryRequest +{ + public int Type { get; set; } = -1; + public int Page { get; set; } = 1; + public int PageSize { get; set; } = 15; +} + +public class GoodsDetailRequest +{ + public int GoodsId { get; set; } + public int GoodsNum { get; set; } = 0; +} + +public class BoxDetailRequest +{ + public int GoodsId { get; set; } + public int PageNo { get; set; } = 0; + public int Sort { get; set; } = 0; // 0=箱号升序, 1=箱号降序, 2=余量降序 +} + +public class CollectionRequest +{ + public int GoodsId { get; set; } + public int GoodsNum { get; set; } + public string Action { get; set; } // "add" or "remove" +} + +public class PrizeLogsRequest +{ + public int GoodsId { get; set; } + public int GoodsNum { get; set; } + public int ShangId { get; set; } = 0; + public int Page { get; set; } = 1; +} +``` + +### Response Models + +```csharp +public class GoodsListDto +{ + public int Id { get; set; } + public string Title { get; set; } + public string ImgUrl { get; set; } + public string Price { get; set; } + public int Type { get; set; } + public string TypeText { get; set; } + public int Stock { get; set; } + public int SaleStock { get; set; } + public int Status { get; set; } + public int LockIs { get; set; } + public int IsShouZhe { get; set; } + public int NewIs { get; set; } + public int JoinCount { get; set; } + public int NeedDrawNum { get; set; } +} + +public class GoodsDetailResponse +{ + public GoodsInfoDto Goods { get; set; } + public LockInfoDto LockInfo { get; set; } + public List JoinUser { get; set; } + public int JoinCount { get; set; } + public List GoodsList { get; set; } + public LimitInfoDto LimitInfo { get; set; } +} + +public class GoodsListItemDto +{ + public int Id { get; set; } + public int ShangId { get; set; } + public ShangInfoDto ShangInfo { get; set; } + public string Title { get; set; } + public int Stock { get; set; } + public int SurplusStock { get; set; } + public string ImgUrl { get; set; } + public int GoodsType { get; set; } + public string Price { get; set; } + public string ScMoney { get; set; } + public string SaleTime { get; set; } + public string Pro { get; set; } + public bool Children { get; set; } +} + +public class BoxDetailDto +{ + public int Num { get; set; } + public int SurplusAllStock { get; set; } + public List GoodsList { get; set; } +} + +public class PrizeLogsResponse +{ + public List Category { get; set; } + public List Data { get; set; } + public int LastPage { get; set; } +} +``` + +## Correctness Properties + +*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.* + +### Property 1: 商品列表过滤和排序正确性 + +*For any* goods query with type filter, the returned list SHALL only contain goods matching the specified type (or all goods if type=-1), with status=1, unlock_amount <= user consumption, sorted by sort DESC then id DESC. + +**Validates: Requirements 1.1, 1.4, 1.5, 1.6** + +### Property 2: 商品详情数据完整性 + +*For any* goods detail request, the response SHALL contain complete goods info, lock_info structure, join_user list, collection_is flag, and limitInfo structure with all required fields present. + +**Validates: Requirements 2.1, 2.4, 2.5, 2.6, 2.7** + +### Property 3: 奖品概率计算正确性 + +*For any* prize item in goods detail, the probability (pro) SHALL be calculated as (surplus_stock / total_surplus_stock * 100) and formatted correctly. + +**Validates: Requirements 2.3, 3.2** + +### Property 4: 子奖品数据完整性 + +*For any* child prize request, the response SHALL contain all child items with real_pro calculated and shang_info included for each item. + +**Validates: Requirements 3.1, 3.2, 3.3** + +### Property 5: 箱号管理数据正确性 + +*For any* box detail request, the response SHALL contain boxes with correct surplus_stock, support specified sort order, and include goodslist summary for each box. + +**Validates: Requirements 5.1, 5.2, 5.3, 5.4** + +### Property 6: 收藏操作往返一致性 + +*For any* collection add operation followed by collection list query, the added goods SHALL appear in the list; for any remove operation, the goods SHALL not appear in the list. + +**Validates: Requirements 6.1, 6.2, 6.4** + +### Property 7: 中奖记录数据完整性 + +*For any* prize logs request, the response SHALL contain paginated records with user_info, prize_info, shang_info, and addtime for each record, supporting shang_id filtering. + +**Validates: Requirements 8.1, 8.2, 8.3, 8.4** + +### Property 8: API响应格式一致性 + +*For any* API response, the structure SHALL contain status (int), msg (string), and data (object) fields consistent with PHP API format. + +**Validates: Requirements 10.1, 10.3** + +## Error Handling + +### 错误码定义 + +| 错误码 | 描述 | 场景 | +|--------|------|------| +| 0 | 请求失败 | 通用错误 | +| 1 | 请求成功 | 成功响应 | +| -1 | 未登录 | Token无效或过期 | +| -2 | 商品不存在 | 商品ID无效 | +| -3 | 商品已下架 | 商品状态非1 | +| -4 | 已收藏 | 重复收藏 | +| -5 | 未收藏 | 取消未收藏的商品 | + +### 异常处理策略 + +```csharp +public class GoodsNotFoundException : BusinessException +{ + public GoodsNotFoundException(int goodsId) + : base(-2, $"商品不存在: {goodsId}") { } +} + +public class GoodsOfflineException : BusinessException +{ + public GoodsOfflineException(int goodsId) + : base(-3, $"商品已下架: {goodsId}") { } +} + +public class AlreadyCollectedException : BusinessException +{ + public AlreadyCollectedException() + : base(-4, "已收藏") { } +} +``` + +## Testing Strategy + +### 单元测试 + +- 测试商品列表过滤逻辑 +- 测试概率计算算法 +- 测试箱号排序逻辑 +- 测试收藏状态切换 + +### 属性测试 + +使用FsCheck或类似库进行属性测试: + +- **Property 1**: 商品列表过滤和排序 - 生成随机商品数据,验证过滤和排序正确性 +- **Property 3**: 概率计算 - 生成随机库存数据,验证概率计算公式 +- **Property 6**: 收藏往返 - 生成随机收藏操作,验证状态一致性 +- **Property 8**: API格式 - 验证所有响应符合标准格式 + +### 集成测试 + +- 测试完整的商品查询流程 +- 测试缓存命中和失效 +- 测试与数据库的交互 + +### 测试配置 + +```csharp +// 属性测试配置 +[Property(MaxTest = 100)] +public Property GoodsListFilteringProperty() +{ + // 生成随机商品和查询条件 + // 验证过滤结果正确性 +} +``` diff --git a/.kiro/specs/goods-system-migration/requirements.md b/.kiro/specs/goods-system-migration/requirements.md new file mode 100644 index 00000000..ba7dc0a7 --- /dev/null +++ b/.kiro/specs/goods-system-migration/requirements.md @@ -0,0 +1,130 @@ +# Requirements Document + +## Introduction + +本文档定义了将PHP商品系统迁移到.NET 8的需求规范。商品系统是抽赏平台的核心模块,包括商品列表、详情、分类、库存管理、收藏、中奖记录等功能。迁移过程需要保持与原PHP系统的功能一致性和API兼容性。 + +## Glossary + +- **Goods_Service**: 商品服务,负责商品列表、详情、配置等查询功能 +- **Collection_Service**: 收藏服务,负责用户商品收藏管理 +- **Prize_Service**: 奖品服务,负责奖品统计和中奖记录查询 +- **Cache_Service**: 缓存服务,负责商品数据的Redis缓存管理 +- **GoodsType**: 商品类型,包括一番赏、无限赏、擂台赏、积分赏等 +- **GoodsList**: 商品奖品列表,包含每个商品的奖品配置 +- **GoodsExtend**: 商品扩展配置,包含支付方式、抵扣设置等 +- **BoxNumber**: 箱号,商品的分箱编号 +- **ShangId**: 赏品分类ID,如A赏、B赏、C赏等 + +## Requirements + +### Requirement 1: 商品列表查询 + +**User Story:** As a user, I want to browse goods list with category filtering, so that I can find products I'm interested in. + +#### Acceptance Criteria + +1. WHEN a user requests goods list with type parameter, THE Goods_Service SHALL return paginated goods matching the specified type +2. WHEN type parameter is -1, THE Goods_Service SHALL return all available goods +3. WHEN a user requests goods list, THE Goods_Service SHALL include join_count from Redis cache or database +4. THE Goods_Service SHALL filter out goods with status != 1 (inactive goods) +5. THE Goods_Service SHALL apply unlock_amount filtering based on user's total consumption +6. THE Goods_Service SHALL return goods sorted by sort field descending, then by id descending + +### Requirement 2: 商品详情查询 + +**User Story:** As a user, I want to view goods details including prize list and probability, so that I can make informed decisions. + +#### Acceptance Criteria + +1. WHEN a user requests goods detail, THE Goods_Service SHALL return complete goods information including prize list +2. WHEN goods_num is 0, THE Goods_Service SHALL automatically select an available box number +3. THE Goods_Service SHALL calculate and return probability (pro) for each prize item +4. THE Goods_Service SHALL return lock_info including lock status, lock user info, and remaining time +5. THE Goods_Service SHALL return join_user list (recent participants' avatars) +6. THE Goods_Service SHALL return collection_is indicating if user has collected this goods +7. THE Goods_Service SHALL return limitInfo including daily and global purchase limits + +### Requirement 3: 商品子奖品查询 + +**User Story:** As a user, I want to view child prizes of a parent prize, so that I can see detailed prize breakdown. + +#### Acceptance Criteria + +1. WHEN a user requests children prizes, THE Goods_Service SHALL return all child items for the specified goods_list_id +2. THE Goods_Service SHALL calculate real_pro (real probability) for each child prize +3. THE Goods_Service SHALL include shang_info for each child prize + +### Requirement 4: 商品扩展配置查询 + +**User Story:** As a user, I want to know available payment methods for a goods, so that I can choose my preferred payment. + +#### Acceptance Criteria + +1. WHEN a user requests goods extend config, THE Goods_Service SHALL return payment method settings +2. IF goods has specific extend config, THE Goods_Service SHALL return goods-specific settings +3. IF goods has no specific extend config, THE Goods_Service SHALL return default settings from goods_type table + +### Requirement 5: 商品箱号管理 + +**User Story:** As a user, I want to browse and select different box numbers, so that I can choose my preferred box. + +#### Acceptance Criteria + +1. WHEN a user requests box list, THE Goods_Service SHALL return paginated box groups (e.g., 1-10, 11-20) +2. WHEN a user requests box detail, THE Goods_Service SHALL return boxes with surplus stock info +3. THE Goods_Service SHALL support sorting by box number (asc/desc) and surplus stock (desc) +4. THE Goods_Service SHALL include goodslist summary for each box + +### Requirement 6: 商品收藏功能 + +**User Story:** As a user, I want to collect/uncollect goods, so that I can easily find my favorite products. + +#### Acceptance Criteria + +1. WHEN a user adds a goods to collection, THE Collection_Service SHALL create a collection record +2. WHEN a user removes a goods from collection, THE Collection_Service SHALL delete the collection record +3. IF user already collected the goods, THE Collection_Service SHALL return error when adding again +4. WHEN a user requests collection list, THE Collection_Service SHALL return paginated collection with goods info + +### Requirement 7: 商品奖品统计 + +**User Story:** As a user, I want to see prize statistics, so that I can understand the prize distribution. + +#### Acceptance Criteria + +1. WHEN a user requests prize count, THE Prize_Service SHALL return total and surplus count by category +2. WHEN a user requests prize content, THE Prize_Service SHALL return detailed prize list for specified box + +### Requirement 8: 中奖记录查询 + +**User Story:** As a user, I want to view winning records, so that I can see who won what prizes. + +#### Acceptance Criteria + +1. WHEN a user requests prize logs, THE Prize_Service SHALL return paginated winning records +2. THE Prize_Service SHALL support filtering by shang_id (prize category) +3. THE Prize_Service SHALL return category list for filtering options +4. THE Prize_Service SHALL include user info, prize info, and winning time for each record + +### Requirement 9: 缓存管理 + +**User Story:** As a system, I want to cache frequently accessed data, so that I can improve response performance. + +#### Acceptance Criteria + +1. THE Cache_Service SHALL cache goods list with 30 seconds expiry +2. THE Cache_Service SHALL cache goods detail with 5 minutes expiry +3. THE Cache_Service SHALL cache join_count with 5 minutes expiry +4. WHEN goods data changes, THE Cache_Service SHALL invalidate related cache keys + +### Requirement 10: API兼容性 + +**User Story:** As a frontend developer, I want the new API to be compatible with existing calls, so that I don't need to modify frontend code. + +#### Acceptance Criteria + +1. THE Goods_Service SHALL maintain the same request/response format as PHP API +2. THE Goods_Service SHALL use POST method for endpoints that PHP uses POST +3. THE Goods_Service SHALL return status, msg, data structure consistent with PHP API +4. WHEN migration is complete, THE API documentation SHALL be updated with migration status diff --git a/.kiro/specs/goods-system-migration/tasks.md b/.kiro/specs/goods-system-migration/tasks.md new file mode 100644 index 00000000..01d5a100 --- /dev/null +++ b/.kiro/specs/goods-system-migration/tasks.md @@ -0,0 +1,260 @@ +# Implementation Plan: 商品系统迁移 + +## Overview + +本任务列表将PHP商品系统迁移到.NET 8,按照接口优先级逐个迁移。每迁移一个接口前,需要先查看PHP代码了解详细业务逻辑;迁移完成后,需要在API接口文档.md中标记迁移状态。 + +## Tasks + +- [ ] 1. 基础设施准备 + - [ ] 1.1 创建商品相关的DTO和Request/Response模型 + - 在HoneyBox.Model/Models目录下创建Goods相关模型 + - 包括GoodsListDto、GoodsDetailResponse、BoxDetailDto、CollectionDto、PrizeLogsResponse等 + - _Requirements: 1.1-10.3_ + - [ ] 1.2 创建服务接口定义 + - 在HoneyBox.Core/Interfaces目录下创建IGoodsService、ICollectionService、IPrizeService、IGoodsCacheService接口 + - _Requirements: 1.1-10.3_ + - [ ] 1.3 创建数据库实体模型 + - 创建Goods、GoodsList、GoodsType、GoodsExtend、GoodsCollection等实体 + - 配置EF Core映射 + - _Requirements: 1.1-10.3_ + - [ ] 1.4 注册服务到DI容器 + - 在ServiceModule.cs中注册新服务 + - _Requirements: 1.1-10.3_ + +- [ ] 2. 商品列表服务实现 + - [ ] 2.1 查看PHP代码了解商品列表业务逻辑 + - 阅读server/php/app/api/controller/Goods.php中的goods_list方法 + - 理解type过滤、unlock_amount过滤、分页、排序逻辑 + - 理解join_count统计逻辑 + - _Requirements: 1.1-1.6_ + - [ ] 2.2 实现GoodsService - 商品列表 + - 实现GetGoodsListAsync方法 + - 实现type过滤逻辑 + - 实现unlock_amount过滤逻辑 + - 实现排序逻辑(sort DESC, id DESC) + - 实现join_count从Redis获取 + - _Requirements: 1.1-1.6_ + - [ ]* 2.3 编写商品列表属性测试 + - **Property 1: 商品列表过滤和排序正确性** + - **Validates: Requirements 1.1, 1.4, 1.5, 1.6** + +- [ ] 3. 商品详情服务实现 + - [ ] 3.1 查看PHP代码了解商品详情业务逻辑 + - 阅读server/php/app/api/controller/Goods.php中的goods_detail方法 + - 理解奖品列表查询、概率计算、锁箱信息、参与用户统计 + - _Requirements: 2.1-2.7_ + - [ ] 3.2 实现GoodsService - 商品详情 + - 实现GetGoodsDetailAsync方法 + - 实现自动选择箱号逻辑(goods_num=0时) + - 实现奖品列表查询 + - 实现概率计算逻辑 + - 实现锁箱信息查询 + - 实现参与用户头像列表 + - 实现收藏状态查询 + - 实现限购信息查询 + - _Requirements: 2.1-2.7_ + - [ ]* 3.3 编写商品详情属性测试 + - **Property 2: 商品详情数据完整性** + - **Property 3: 奖品概率计算正确性** + - **Validates: Requirements 2.1, 2.3, 2.4, 2.5, 2.6, 2.7** + +- [ ] 4. 商品子奖品服务实现 + - [ ] 4.1 查看PHP代码了解子奖品业务逻辑 + - 阅读server/php/app/api/controller/Goods.php中的goods_children方法 + - 理解子奖品查询和real_pro计算 + - _Requirements: 3.1-3.3_ + - [ ] 4.2 实现GoodsService - 子奖品查询 + - 实现GetGoodsChildrenAsync方法 + - 实现real_pro计算逻辑 + - 实现shang_info关联查询 + - _Requirements: 3.1-3.3_ + - [ ]* 4.3 编写子奖品属性测试 + - **Property 4: 子奖品数据完整性** + - **Validates: Requirements 3.1, 3.2, 3.3** + +- [ ] 5. 商品扩展配置服务实现 + - [ ] 5.1 查看PHP代码了解扩展配置业务逻辑 + - 阅读server/php/app/api/controller/Goods.php中的goods_extend方法 + - 理解配置优先级(商品配置 > 类型默认配置) + - _Requirements: 4.1-4.3_ + - [ ] 5.2 实现GoodsService - 扩展配置 + - 实现GetGoodsExtendAsync方法 + - 实现配置优先级逻辑 + - _Requirements: 4.1-4.3_ + +- [ ] 6. Checkpoint - 核心商品服务测试验证 + - 确保商品列表、详情、子奖品、扩展配置服务测试通过 + - 如有问题请询问用户 + +- [ ] 7. 箱号管理服务实现 + - [ ] 7.1 查看PHP代码了解箱号管理业务逻辑 + - 阅读server/php/app/api/controller/Goods.php中的goods_num_list、goods_num_detail方法 + - 理解箱号分组、排序、余量统计逻辑 + - _Requirements: 5.1-5.4_ + - [ ] 7.2 实现GoodsService - 箱号列表 + - 实现GetBoxListAsync方法 + - 实现箱号分组逻辑(每10个一组) + - _Requirements: 5.1_ + - [ ] 7.3 实现GoodsService - 箱号详情 + - 实现GetBoxDetailAsync方法 + - 实现排序逻辑(箱号升序/降序、余量降序) + - 实现余量统计 + - 实现goodslist摘要 + - _Requirements: 5.2-5.4_ + - [ ]* 7.4 编写箱号管理属性测试 + - **Property 5: 箱号管理数据正确性** + - **Validates: Requirements 5.1, 5.2, 5.3, 5.4** + +- [ ] 8. 收藏服务实现 + - [ ] 8.1 查看PHP代码了解收藏业务逻辑 + - 阅读server/php/app/api/controller/Goods.php中的collection、collection_list方法 + - 理解收藏/取消收藏逻辑 + - _Requirements: 6.1-6.4_ + - [ ] 8.2 实现CollectionService + - 实现ToggleCollectionAsync方法(收藏/取消收藏) + - 实现GetCollectionListAsync方法(收藏列表) + - 实现IsCollectedAsync方法(检查收藏状态) + - 实现重复收藏检查 + - _Requirements: 6.1-6.4_ + - [ ]* 8.3 编写收藏服务属性测试 + - **Property 6: 收藏操作往返一致性** + - **Validates: Requirements 6.1, 6.2, 6.4** + +- [ ] 9. 奖品统计服务实现 + - [ ] 9.1 查看PHP代码了解奖品统计业务逻辑 + - 阅读server/php/app/api/controller/Goods.php中的goods_prize_count、goods_prize_content方法 + - 理解统计计算逻辑 + - _Requirements: 7.1-7.2_ + - [ ] 9.2 实现PrizeService - 奖品统计 + - 实现GetPrizeCountAsync方法 + - 实现GetPrizeContentAsync方法 + - _Requirements: 7.1-7.2_ + +- [ ] 10. 中奖记录服务实现 + - [ ] 10.1 查看PHP代码了解中奖记录业务逻辑 + - 阅读server/php/app/api/controller/Goods.php中的goods_prize_logs方法 + - 理解分类筛选、分页逻辑 + - _Requirements: 8.1-8.4_ + - [ ] 10.2 实现PrizeService - 中奖记录 + - 实现GetPrizeLogsAsync方法 + - 实现shang_id筛选 + - 实现分类列表查询 + - 实现用户信息、奖品信息关联 + - _Requirements: 8.1-8.4_ + - [ ]* 10.3 编写中奖记录属性测试 + - **Property 7: 中奖记录数据完整性** + - **Validates: Requirements 8.1, 8.2, 8.3, 8.4** + +- [ ] 11. 缓存服务实现 + - [ ] 11.1 实现GoodsCacheService + - 实现GetJoinCountAsync方法 + - 实现IncrementJoinCountAsync方法 + - 实现InvalidateGoodsCacheAsync方法 + - 配置缓存过期时间 + - _Requirements: 9.1-9.4_ + +- [ ] 12. Checkpoint - 服务层测试验证 + - 确保所有服务层单元测试通过 + - 确保所有属性测试通过 + - 如有问题请询问用户 + +- [ ] 13. 控制器实现 - GoodsController + - [ ] 13.1 实现商品列表接口 POST /goods_list + - 调用GoodsService.GetGoodsListAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 1.1-1.6_ + - [ ] 13.2 实现商品详情接口 POST /goods_detail + - 调用GoodsService.GetGoodsDetailAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 2.1-2.7_ + - [ ] 13.3 实现商品子奖品接口 POST /goods_children + - 调用GoodsService.GetGoodsChildrenAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 3.1-3.3_ + - [ ] 13.4 实现商品扩展配置接口 POST /goods_extend + - 调用GoodsService.GetGoodsExtendAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 4.1-4.3_ + - [ ] 13.5 实现箱号列表接口 POST /goods_num_list + - 调用GoodsService.GetBoxListAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 5.1_ + - [ ] 13.6 实现箱号详情接口 POST /goods_num_detail + - 调用GoodsService.GetBoxDetailAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 5.2-5.4_ + - [ ] 13.7 实现奖品数量统计接口 POST /goods_prize_count + - 调用PrizeService.GetPrizeCountAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 7.1_ + - [ ] 13.8 实现奖品内容接口 POST /goods_prize_content + - 调用PrizeService.GetPrizeContentAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 7.2_ + - [ ] 13.9 实现中奖记录接口 POST /goods_prize_logs + - 调用PrizeService.GetPrizeLogsAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 8.1-8.4_ + +- [ ] 14. 控制器实现 - CollectionController + - [ ] 14.1 实现收藏/取消收藏接口 POST /collection + - 调用CollectionService.ToggleCollectionAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 6.1-6.3_ + - [ ] 14.2 实现收藏列表接口 POST /collection_list + - 调用CollectionService.GetCollectionListAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 6.4_ + +- [ ] 15. Checkpoint - 控制器测试验证 + - 确保所有控制器接口可正常访问 + - 使用Postman或HTTP文件测试各接口 + - 如有问题请询问用户 + +- [ ] 16. API响应格式验证 + - [ ] 16.1 验证所有接口响应格式 + - 确保status、msg、data结构一致 + - 确保字段命名与PHP API一致(snake_case) + - _Requirements: 10.1, 10.3_ + - [ ]* 16.2 编写API格式属性测试 + - **Property 8: API响应格式一致性** + - **Validates: Requirements 10.1, 10.3** + +- [ ] 17. 集成测试 + - [ ] 17.1 编写商品列表集成测试 + - 测试完整的商品查询流程 + - 测试分类筛选 + - _Requirements: 1.1-1.6_ + - [ ] 17.2 编写商品详情集成测试 + - 测试商品详情查询 + - 测试概率计算 + - _Requirements: 2.1-2.7_ + - [ ] 17.3 编写收藏功能集成测试 + - 测试收藏/取消收藏流程 + - _Requirements: 6.1-6.4_ + +- [ ] 18. 文档更新和最终验证 + - [ ] 18.1 更新API接口文档 + - 确认所有迁移接口都已标记 + - 记录新接口地址 + - _Requirements: 10.4_ + - [ ] 18.2 创建HTTP测试文件 + - 在HoneyBox.Api目录下创建goods-system.http测试文件 + - 包含所有商品系统相关接口的测试请求 + +- [ ] 19. Final Checkpoint - 完整功能验证 + - 确保所有测试通过 + - 确保API文档已更新 + - 确保与前端兼容性 + - 如有问题请询问用户 + +## Notes + +- Tasks marked with `*` are optional and can be skipped for faster MVP +- Each task references specific requirements for traceability +- Checkpoints ensure incremental validation +- Property tests validate universal correctness properties +- Unit tests validate specific examples and edge cases +- 每迁移完成一个接口,都需要在docs/API接口文档.md中标记迁移状态和新接口地址 +- 迁移前必须先查看PHP代码了解详细业务逻辑,确保功能一致性