12 KiB
12 KiB
Implementation Plan: 抽奖系统迁移
Overview
本任务列表将PHP抽奖系统迁移到.NET 8,按照接口优先级逐个迁移。每迁移一个接口前,需要先查看PHP代码了解详细业务逻辑;迁移完成后,需要在API接口文档.md中标记迁移状态。
Tasks
-
1. 基础设施准备
- 1.1 创建抽奖相关的DTO和Request/Response模型
- 在HoneyBox.Model/Models/Lottery目录下创建相关模型
- 包括PrizeOrderLogResponseDto、InfiniteShangLogResponseDto等
- 包括LotteryDrawRequest、LotteryDrawResult等内部模型
- Requirements: 1.1-10.4
- 1.2 创建服务接口定义
- 在HoneyBox.Core/Interfaces目录下创建ILotteryService接口
- 扩展现有IPrizeService接口(如需要)
- Requirements: 1.1-10.4
- 1.3 注册服务到DI容器
- 在ServiceModule.cs中注册LotteryService
- Requirements: 1.1-10.4
- 1.1 创建抽奖相关的DTO和Request/Response模型
-
2. 一番赏抽奖结果查询接口
- 2.1 查看PHP代码了解一番赏抽奖结果逻辑
- 阅读server/php/app/api/controller/Order.php中的prizeorderlog方法
- 理解订单奖品查询、字段映射逻辑
- Requirements: 1.1-1.4
- 2.2 实现LotteryService - GetPrizeOrderLogAsync
- 根据order_num查询订单
- 查询order_item表获取抽奖结果
- 返回奖品列表(包含title, imgurl, price, money, prize_code, luck_no)
- Requirements: 1.1-1.4
- 2.3 实现控制器接口 POST /api/prizeorderlog
- 调用LotteryService.GetPrizeOrderLogAsync
- 更新API接口文档标记迁移状态
- Requirements: 1.1-1.4
- * 2.4 编写抽奖结果查询属性测试
- Property 1: 抽奖结果查询正确性
- Validates: Requirements 1.1, 1.3
- 2.1 查看PHP代码了解一番赏抽奖结果逻辑
-
3. 无限赏抽奖结果查询接口
- 3.1 查看PHP代码了解无限赏抽奖结果逻辑
- 阅读server/php/app/api/controller/Infinite.php中的infinite_prizeorderlog方法
- 理解无限赏订单类型和查询逻辑
- Requirements: 2.1-2.3
- 3.2 实现LotteryService - GetInfinitePrizeOrderLogAsync
- 根据order_num查询无限赏订单
- 查询order_item表(order_type=2)
- 返回奖品列表
- Requirements: 2.1-2.3
- 3.3 实现控制器接口 POST /api/infinite_prizeorderlog
- 调用LotteryService.GetInfinitePrizeOrderLogAsync
- 更新API接口文档标记迁移状态
- Requirements: 2.1-2.3
- 3.1 查看PHP代码了解无限赏抽奖结果逻辑
-
4. Checkpoint - 抽奖结果查询测试验证
- 确保一番赏和无限赏抽奖结果查询接口测试通过
- 如有问题请询问用户
-
5. 无限赏中奖记录查询接口
- 5.1 查看PHP代码了解无限赏中奖记录逻辑
- 阅读server/php/app/api/controller/Infinite.php中的infinite_shang_log方法
- 理解分页、用户信息脱敏逻辑
- Requirements: 4.1-4.3
- 5.2 实现LotteryService - GetInfiniteShangLogAsync
- 查询order_item表(order_type=2, source=1)
- 分页返回中奖记录
- 用户昵称脱敏处理
- Requirements: 4.1-4.3
- 5.3 实现控制器接口 POST /api/infinite_shang_log
- 调用LotteryService.GetInfiniteShangLogAsync
- 更新API接口文档标记迁移状态
- Requirements: 4.1-4.3
- * 5.4 编写中奖记录分页属性测试
- Property 2: 中奖记录分页正确性
- Validates: Requirements 4.1
- 5.1 查看PHP代码了解无限赏中奖记录逻辑
-
6. 每日抽奖记录查询接口
- 6.1 查看PHP代码了解每日抽奖记录逻辑
- 阅读server/php/app/api/controller/Infinite.php中的infinite_prizerecords方法
- 理解日期过滤逻辑
- Requirements: 5.1-5.3
- 6.2 实现LotteryService - GetDailyPrizeRecordsAsync
- 查询当天的中奖记录
- 按时间倒序排列
- Requirements: 5.1-5.3
- 6.3 实现控制器接口 POST /api/infinite_prizerecords
- 调用LotteryService.GetDailyPrizeRecordsAsync
- 更新API接口文档标记迁移状态
- Requirements: 5.1-5.3
- 6.1 查看PHP代码了解每日抽奖记录逻辑
-
7. Checkpoint - 中奖记录查询测试验证
- 确保无限赏中奖记录和每日记录查询接口测试通过
- 如有问题请询问用户
-
8. 道具卡抽奖接口
- 8.1 查看PHP代码了解道具卡抽奖逻辑
- 阅读server/php/app/api/controller/Infinite.php中的item_card_chou方法
- 理解道具卡验证、抽奖执行、状态更新逻辑
- Requirements: 6.1-6.4
- 8.2 实现LotteryService - DrawWithItemCardAsync
- 验证道具卡所有权和状态
- 执行抽奖逻辑
- 标记道具卡为已使用
- 创建抽奖记录
- Requirements: 6.1-6.4
- 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
- 8.1 查看PHP代码了解道具卡抽奖逻辑
-
9. 抽奖算法引擎实现
- 9.1 查看PHP代码了解抽奖算法
- 阅读server/php/app/api/controller/Notify.php中的drawprize_notice方法
- 阅读相关抽奖逻辑代码
- 理解概率计算、权重随机选择算法
- Requirements: 7.1-7.7
- 9.2 实现LotteryEngine - 概率计算
- 实现CalculateProbabilitiesAsync方法
- 概率 = surplus_stock / total_surplus_stock * 100
- 排除库存为0的奖品
- Requirements: 7.1, 7.3
- 9.3 实现LotteryEngine - 权重随机选择
- 实现SelectPrizeByWeight方法
- 使用权重随机算法选择奖品
- Requirements: 7.2
- * 9.4 编写概率计算属性测试
- Property 4: 概率计算正确性
- Validates: Requirements 7.1
- * 9.5 编写权重随机分布属性测试
- Property 5: 权重随机分布正确性
- Validates: Requirements 7.2
- 9.1 查看PHP代码了解抽奖算法
-
10. 库存管理实现
- 10.1 查看PHP代码了解库存扣减逻辑
- 阅读server/php/app/common/model/GoodsList.php中的库存操作方法
- 理解原子扣减、并发控制逻辑
- Requirements: 8.1-8.4
- 10.2 实现InventoryManager - 原子库存扣减
- 实现DeductStockAsync方法
- 使用乐观锁或行级锁确保原子性
- 验证库存可用性
- Requirements: 8.1, 8.4
- 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
- 10.1 查看PHP代码了解库存扣减逻辑
-
11. Checkpoint - 抽奖引擎测试验证
- 确保抽奖算法和库存管理测试通过
- 如有问题请询问用户
-
12. 抽奖记录持久化实现
- 12.1 查看PHP代码了解抽奖记录创建逻辑
- 阅读server/php/app/api/controller/Notify.php中的记录创建代码
- 理解order_item表字段映射
- Requirements: 9.1-9.4
- 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
- 12.1 查看PHP代码了解抽奖记录创建逻辑
-
13. 完整抽奖流程集成
- 13.1 实现LotteryEngine - DrawAsync完整流程
- 整合概率计算、权重选择、库存扣减、记录创建
- 实现错误处理和重试逻辑
- Requirements: 7.1-7.7, 8.1-8.4, 9.1-9.4
- 13.2 实现LotteryEngine - DrawMultipleAsync
- 支持多次抽奖
- 循环调用DrawAsync
- Requirements: 7.1-7.7
- 13.1 实现LotteryEngine - DrawAsync完整流程
-
14. Checkpoint - 完整抽奖流程测试验证
- 确保完整抽奖流程测试通过
- 如有问题请询问用户
-
15. API响应格式验证
- 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
- 15.1 验证所有接口响应格式
-
16. 集成测试
- 16.1 编写抽奖结果查询集成测试
- 测试一番赏抽奖结果查询
- 测试无限赏抽奖结果查询
- Requirements: 1.1-2.3
- 16.2 编写中奖记录查询集成测试
- 测试无限赏中奖记录查询
- 测试每日抽奖记录查询
- 测试分页和过滤功能
- Requirements: 3.1-5.3
- 16.3 编写道具卡抽奖集成测试
- 测试有效道具卡抽奖
- 测试无效道具卡错误处理
- Requirements: 6.1-6.4
- 16.4 编写抽奖引擎集成测试
- 测试完整抽奖流程
- 测试库存扣减
- 测试记录创建
- Requirements: 7.1-9.4
- 16.1 编写抽奖结果查询集成测试
-
17. 文档更新和最终验证
- 17.1 更新API接口文档
- 确认所有迁移接口都已标记
- 记录新接口地址
- Requirements: 10.1-10.4
- 17.2 创建HTTP测试文件
- 在HoneyBox.Api目录下创建lottery-system.http测试文件
- 包含所有抽奖系统相关接口的测试请求
- 17.1 更新API接口文档
-
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%
权重随机算法
// 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;
}
}