306 lines
12 KiB
Markdown
306 lines
12 KiB
Markdown
# Implementation Plan: 抽奖系统迁移
|
||
|
||
## Overview
|
||
|
||
本任务列表将PHP抽奖系统迁移到.NET 8,按照接口优先级逐个迁移。每迁移一个接口前,需要先查看PHP代码了解详细业务逻辑;迁移完成后,需要在API接口文档.md中标记迁移状态。
|
||
|
||
## Tasks
|
||
|
||
- [x] 1. 基础设施准备
|
||
- [x] 1.1 创建抽奖相关的DTO和Request/Response模型
|
||
- 在HoneyBox.Model/Models/Lottery目录下创建相关模型
|
||
- 包括PrizeOrderLogResponseDto、InfiniteShangLogResponseDto等
|
||
- 包括LotteryDrawRequest、LotteryDrawResult等内部模型
|
||
- _Requirements: 1.1-10.4_
|
||
- [x] 1.2 创建服务接口定义
|
||
- 在HoneyBox.Core/Interfaces目录下创建ILotteryService接口
|
||
- 扩展现有IPrizeService接口(如需要)
|
||
- _Requirements: 1.1-10.4_
|
||
- [x] 1.3 注册服务到DI容器
|
||
- 在ServiceModule.cs中注册LotteryService
|
||
- _Requirements: 1.1-10.4_
|
||
|
||
- [x] 2. 一番赏抽奖结果查询接口
|
||
- [x] 2.1 查看PHP代码了解一番赏抽奖结果逻辑
|
||
- 阅读server/php/app/api/controller/Order.php中的prizeorderlog方法
|
||
- 理解订单奖品查询、字段映射逻辑
|
||
- _Requirements: 1.1-1.4_
|
||
- [x] 2.2 实现LotteryService - GetPrizeOrderLogAsync
|
||
- 根据order_num查询订单
|
||
- 查询order_item表获取抽奖结果
|
||
- 返回奖品列表(包含title, imgurl, price, money, prize_code, luck_no)
|
||
- _Requirements: 1.1-1.4_
|
||
- [x] 2.3 实现控制器接口 POST /api/prizeorderlog
|
||
- 调用LotteryService.GetPrizeOrderLogAsync
|
||
- 更新API接口文档标记迁移状态
|
||
- _Requirements: 1.1-1.4_
|
||
- [ ]* 2.4 编写抽奖结果查询属性测试
|
||
- **Property 1: 抽奖结果查询正确性**
|
||
- **Validates: Requirements 1.1, 1.3**
|
||
|
||
- [x] 3. 无限赏抽奖结果查询接口
|
||
- [x] 3.1 查看PHP代码了解无限赏抽奖结果逻辑
|
||
- 阅读server/php/app/api/controller/Infinite.php中的infinite_prizeorderlog方法
|
||
- 理解无限赏订单类型和查询逻辑
|
||
- _Requirements: 2.1-2.3_
|
||
- [x] 3.2 实现LotteryService - GetInfinitePrizeOrderLogAsync
|
||
- 根据order_num查询无限赏订单
|
||
- 查询order_item表(order_type=2)
|
||
- 返回奖品列表
|
||
- _Requirements: 2.1-2.3_
|
||
- [x] 3.3 实现控制器接口 POST /api/infinite_prizeorderlog
|
||
- 调用LotteryService.GetInfinitePrizeOrderLogAsync
|
||
- 更新API接口文档标记迁移状态
|
||
- _Requirements: 2.1-2.3_
|
||
|
||
- [x] 4. Checkpoint - 抽奖结果查询测试验证
|
||
- 确保一番赏和无限赏抽奖结果查询接口测试通过
|
||
- 如有问题请询问用户
|
||
|
||
- [x] 5. 无限赏中奖记录查询接口
|
||
- [x] 5.1 查看PHP代码了解无限赏中奖记录逻辑
|
||
- 阅读server/php/app/api/controller/Infinite.php中的infinite_shang_log方法
|
||
- 理解分页、用户信息脱敏逻辑
|
||
- _Requirements: 4.1-4.3_
|
||
- [x] 5.2 实现LotteryService - GetInfiniteShangLogAsync
|
||
- 查询order_item表(order_type=2, source=1)
|
||
- 分页返回中奖记录
|
||
- 用户昵称脱敏处理
|
||
- _Requirements: 4.1-4.3_
|
||
- [x] 5.3 实现控制器接口 POST /api/infinite_shang_log
|
||
- 调用LotteryService.GetInfiniteShangLogAsync
|
||
- 更新API接口文档标记迁移状态
|
||
- _Requirements: 4.1-4.3_
|
||
- [ ]* 5.4 编写中奖记录分页属性测试
|
||
- **Property 2: 中奖记录分页正确性**
|
||
- **Validates: Requirements 4.1**
|
||
|
||
- [x] 6. 每日抽奖记录查询接口
|
||
- [x] 6.1 查看PHP代码了解每日抽奖记录逻辑
|
||
- 阅读server/php/app/api/controller/Infinite.php中的infinite_prizerecords方法
|
||
- 理解日期过滤逻辑
|
||
- _Requirements: 5.1-5.3_
|
||
- [x] 6.2 实现LotteryService - GetDailyPrizeRecordsAsync
|
||
- 查询当天的中奖记录
|
||
- 按时间倒序排列
|
||
- _Requirements: 5.1-5.3_
|
||
- [x] 6.3 实现控制器接口 POST /api/infinite_prizerecords
|
||
- 调用LotteryService.GetDailyPrizeRecordsAsync
|
||
- 更新API接口文档标记迁移状态
|
||
- _Requirements: 5.1-5.3_
|
||
|
||
- [x] 7. Checkpoint - 中奖记录查询测试验证
|
||
- 确保无限赏中奖记录和每日记录查询接口测试通过
|
||
- 如有问题请询问用户
|
||
|
||
- [x] 8. 道具卡抽奖接口
|
||
- [x] 8.1 查看PHP代码了解道具卡抽奖逻辑
|
||
- 阅读server/php/app/api/controller/Infinite.php中的item_card_chou方法
|
||
- 理解道具卡验证、抽奖执行、状态更新逻辑
|
||
- _Requirements: 6.1-6.4_
|
||
- [x] 8.2 实现LotteryService - DrawWithItemCardAsync
|
||
- 验证道具卡所有权和状态
|
||
- 执行抽奖逻辑
|
||
- 标记道具卡为已使用
|
||
- 创建抽奖记录
|
||
- _Requirements: 6.1-6.4_
|
||
- [x] 8.3 实现控制器接口 POST /api/item_card_chou
|
||
- 调用LotteryService.DrawWithItemCardAsync
|
||
- 更新API接口文档标记迁移状态
|
||
- _Requirements: 6.1-6.4_
|
||
- [ ]* 8.4 编写道具卡使用属性测试
|
||
- **Property 10: 道具卡使用正确性**
|
||
- **Validates: Requirements 6.1, 6.2, 6.3**
|
||
|
||
- [x] 9. 抽奖算法引擎实现
|
||
- [x] 9.1 查看PHP代码了解抽奖算法
|
||
- 阅读server/php/app/api/controller/Notify.php中的drawprize_notice方法
|
||
- 阅读相关抽奖逻辑代码
|
||
- 理解概率计算、权重随机选择算法
|
||
- _Requirements: 7.1-7.7_
|
||
- [x] 9.2 实现LotteryEngine - 概率计算
|
||
- 实现CalculateProbabilitiesAsync方法
|
||
- 概率 = surplus_stock / total_surplus_stock * 100
|
||
- 排除库存为0的奖品
|
||
- _Requirements: 7.1, 7.3_
|
||
- [x] 9.3 实现LotteryEngine - 权重随机选择
|
||
- 实现SelectPrizeByWeight方法
|
||
- 使用权重随机算法选择奖品
|
||
- _Requirements: 7.2_
|
||
- [ ]* 9.4 编写概率计算属性测试
|
||
- **Property 4: 概率计算正确性**
|
||
- **Validates: Requirements 7.1**
|
||
- [ ]* 9.5 编写权重随机分布属性测试
|
||
- **Property 5: 权重随机分布正确性**
|
||
- **Validates: Requirements 7.2**
|
||
|
||
- [x] 10. 库存管理实现
|
||
- [x] 10.1 查看PHP代码了解库存扣减逻辑
|
||
- 阅读server/php/app/common/model/GoodsList.php中的库存操作方法
|
||
- 理解原子扣减、并发控制逻辑
|
||
- _Requirements: 8.1-8.4_
|
||
- [x] 10.2 实现InventoryManager - 原子库存扣减
|
||
- 实现DeductStockAsync方法
|
||
- 使用乐观锁或行级锁确保原子性
|
||
- 验证库存可用性
|
||
- _Requirements: 8.1, 8.4_
|
||
- [x] 10.3 实现InventoryManager - 获取可用奖品池
|
||
- 实现GetAvailablePrizePoolAsync方法
|
||
- 过滤surplus_stock > 0的奖品
|
||
- _Requirements: 7.3_
|
||
- [ ]* 10.4 编写库存扣减属性测试
|
||
- **Property 6: 库存扣减原子性**
|
||
- **Validates: Requirements 7.4, 8.1**
|
||
- [ ]* 10.5 编写并发安全属性测试
|
||
- **Property 7: 并发安全性**
|
||
- **Validates: Requirements 8.3**
|
||
|
||
- [x] 11. Checkpoint - 抽奖引擎测试验证
|
||
- 确保抽奖算法和库存管理测试通过
|
||
- 如有问题请询问用户
|
||
|
||
- [x] 12. 抽奖记录持久化实现
|
||
- [x] 12.1 查看PHP代码了解抽奖记录创建逻辑
|
||
- 阅读server/php/app/api/controller/Notify.php中的记录创建代码
|
||
- 理解order_item表字段映射
|
||
- _Requirements: 9.1-9.4_
|
||
- [x] 12.2 实现LotteryEngine - 创建抽奖记录
|
||
- 实现CreateDrawRecordAsync方法
|
||
- 设置正确的user_id, goods_id, goodslist_id, shang_id
|
||
- 生成唯一prize_code
|
||
- 设置source=1, 正确的order_type
|
||
- _Requirements: 9.1-9.4_
|
||
- [ ]* 12.3 编写抽奖记录持久化属性测试
|
||
- **Property 8: 抽奖记录持久化完整性**
|
||
- **Validates: Requirements 9.1, 9.2, 9.3, 9.4**
|
||
|
||
- [x] 13. 完整抽奖流程集成
|
||
- [x] 13.1 实现LotteryEngine - DrawAsync完整流程
|
||
- 整合概率计算、权重选择、库存扣减、记录创建
|
||
- 实现错误处理和重试逻辑
|
||
- _Requirements: 7.1-7.7, 8.1-8.4, 9.1-9.4_
|
||
- [x] 13.2 实现LotteryEngine - DrawMultipleAsync
|
||
- 支持多次抽奖
|
||
- 循环调用DrawAsync
|
||
- _Requirements: 7.1-7.7_
|
||
|
||
- [x] 14. Checkpoint - 完整抽奖流程测试验证
|
||
- 确保完整抽奖流程测试通过
|
||
- 如有问题请询问用户
|
||
|
||
- [x] 15. API响应格式验证
|
||
- [x] 15.1 验证所有接口响应格式
|
||
- 确保status、msg、data结构一致
|
||
- 确保字段命名与PHP API一致(snake_case)
|
||
- _Requirements: 10.1-10.4_
|
||
- [ ]* 15.2 编写API响应格式属性测试
|
||
- **Property 9: API响应格式一致性**
|
||
- **Validates: Requirements 10.1, 10.2, 10.3, 10.4**
|
||
|
||
- [x] 16. 集成测试
|
||
- [x] 16.1 编写抽奖结果查询集成测试
|
||
- 测试一番赏抽奖结果查询
|
||
- 测试无限赏抽奖结果查询
|
||
- _Requirements: 1.1-2.3_
|
||
- [x] 16.2 编写中奖记录查询集成测试
|
||
- 测试无限赏中奖记录查询
|
||
- 测试每日抽奖记录查询
|
||
- 测试分页和过滤功能
|
||
- _Requirements: 3.1-5.3_
|
||
- [x] 16.3 编写道具卡抽奖集成测试
|
||
- 测试有效道具卡抽奖
|
||
- 测试无效道具卡错误处理
|
||
- _Requirements: 6.1-6.4_
|
||
- [x] 16.4 编写抽奖引擎集成测试
|
||
- 测试完整抽奖流程
|
||
- 测试库存扣减
|
||
- 测试记录创建
|
||
- _Requirements: 7.1-9.4_
|
||
|
||
- [x] 17. 文档更新和最终验证
|
||
- [x] 17.1 更新API接口文档
|
||
- 确认所有迁移接口都已标记
|
||
- 记录新接口地址
|
||
- _Requirements: 10.1-10.4_
|
||
- [x] 17.2 创建HTTP测试文件
|
||
- 在HoneyBox.Api目录下创建lottery-system.http测试文件
|
||
- 包含所有抽奖系统相关接口的测试请求
|
||
|
||
- [ ] 18. 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代码了解详细业务逻辑,确保功能一致性
|
||
- 抽奖系统涉及概率公平性,需要特别注意算法准确性
|
||
- 库存管理需要确保并发安全,防止超发
|
||
|
||
## 接口迁移清单
|
||
|
||
| 序号 | PHP接口 | 新接口地址 | 状态 |
|
||
|------|---------|-----------|------|
|
||
| 1 | POST /prizeorderlog | POST /api/prizeorderlog | ✅ |
|
||
| 2 | POST /infinite_prizeorderlog | POST /api/infinite_prizeorderlog | ✅ |
|
||
| 3 | POST /infinite_shang_log | POST /api/infinite_shang_log | ✅ |
|
||
| 4 | POST /infinite_prizerecords | POST /api/infinite_prizerecords | ✅ |
|
||
| 5 | POST /item_card_chou | POST /api/item_card_chou | ✅ |
|
||
|
||
## 关键业务逻辑说明
|
||
|
||
### 抽奖类型
|
||
|
||
| order_type | 类型名称 | 说明 |
|
||
|------------|---------|------|
|
||
| 1 | 一番赏 | 标准一番赏抽奖 |
|
||
| 2 | 无限赏 | 无限池抽奖 |
|
||
| 3 | 擂台赏 | 擂台赏抽奖 |
|
||
| 4 | 转转赏 | 转转赏抽奖 |
|
||
| 5 | 福利屋 | 福利屋抽奖 |
|
||
| 6 | 商城赏 | 商城赏抽奖 |
|
||
| 7 | 翻倍赏 | 翻倍赏抽奖 |
|
||
| 8 | 抽卡机 | 抽卡机抽奖 |
|
||
|
||
### 奖品来源
|
||
|
||
| source | 说明 |
|
||
|--------|------|
|
||
| 0 | 购买获得 |
|
||
| 1 | 抽奖获得 |
|
||
|
||
### 概率计算公式
|
||
|
||
```
|
||
单个奖品概率 = (该奖品剩余库存 / 所有可抽奖品总剩余库存) * 100%
|
||
```
|
||
|
||
### 权重随机算法
|
||
|
||
```csharp
|
||
// 1. 计算总权重
|
||
var totalWeight = prizes.Sum(p => p.SurplusStock);
|
||
|
||
// 2. 生成随机数 [0, totalWeight)
|
||
var random = new Random();
|
||
var randomValue = random.NextDouble() * totalWeight;
|
||
|
||
// 3. 累加权重,找到命中的奖品
|
||
double currentWeight = 0;
|
||
foreach (var prize in prizes)
|
||
{
|
||
currentWeight += prize.SurplusStock;
|
||
if (randomValue < currentWeight)
|
||
{
|
||
return prize;
|
||
}
|
||
}
|
||
```
|