# LotteryRecordService 重构说明 ## 概述 本次重构将抽奖记录和中奖记录相关的业务逻辑从 `LotteryService` 中分离出来,创建了专门的 `LotteryRecordService` 服务类,实现了更好的职责分离和代码组织。 ## 重构内容 ### 1. 新增服务类 **文件位置**: `application/common/Service/lottery/LotteryRecordService.php` **主要功能**: - 抽奖记录管理 - 中奖记录管理 - 奖品发放处理 - 统计和查询功能 ### 2. 抽奖记录相关方法 #### 核心方法 - `createDrawRecord()` - 创建抽奖记录 - `getUserDrawCount()` - 获取用户抽奖次数 - `getUserWinCount()` - 获取用户中奖次数 - `getActivityDrawStats()` - 获取活动抽奖统计 - `getUserDrawRecords()` - 获取用户抽奖记录列表 - `getActivityDrawRecords()` - 获取活动抽奖记录列表 - `getDrawRecordDetail()` - 获取抽奖记录详情 - `hasUserDrawnForOrder()` - 检查用户是否已为指定订单抽奖 #### 统计方法 - `getUserDrawHistoryStats()` - 获取用户抽奖历史统计 - `getActivityDrawRanking()` - 获取活动抽奖排行榜 - `getActivityDrawTimeDistribution()` - 获取活动抽奖时间分布统计 ### 3. 中奖记录相关方法 #### 核心方法 - `createWinRecord()` - 创建中奖记录 - `markWinRecordAsDelivered()` - 标记中奖记录为发放成功 - `markWinRecordAsFailed()` - 标记中奖记录为发放失败 - `getPendingWinRecords()` - 获取待发放的中奖记录 - `getUserWinRecords()` - 获取用户中奖记录 - `getActivityWinStats()` - 获取活动中奖统计 #### 地址和快递信息 - `setWinRecordDeliveryAddress()` - 设置中奖记录收货地址 - `setWinRecordExpressInfo()` - 设置中奖记录快递信息 #### 兑换码管理 - `setWinRecordExchangeCode()` - 设置中奖记录兑换码 - `markWinRecordCodeUsed()` - 标记中奖记录兑换码已使用 #### 批量处理 - `batchProcessPendingWinRecords()` - 批量处理待发放的中奖记录 - `manualDeliverPrize()` - 手动发放奖品(管理员操作) - `cancelWinRecord()` - 取消中奖记录 #### 自动发放 - `autoDeliverPrize()` - 自动发放奖品 - `deliverCoupon()` - 发放优惠券 - `deliverRedPacket()` - 发放红包 - `deliverExchangeCode()` - 发放兑换码 - `deliverGoods()` - 发放商城商品 ### 4. 从 LotteryService 移除的方法 以下方法已从 `LotteryService` 中移除,迁移到 `LotteryRecordService`: #### 抽奖记录方法 - `createDrawRecord()` - `getUserDrawCount()` - `getUserWinCount()` - `getActivityDrawStats()` - `getUserDrawRecords()` - `getActivityDrawRecords()` - `getDrawRecordDetail()` - `hasUserDrawnForOrder()` - `getUserDrawHistoryStats()` - `getActivityDrawRanking()` - `getActivityDrawTimeDistribution()` #### 中奖记录方法 - `createWinRecord()` - `markWinRecordAsDelivered()` - `markWinRecordAsFailed()` - `setWinRecordDeliveryAddress()` - `setWinRecordExpressInfo()` - `setWinRecordExchangeCode()` - `markWinRecordCodeUsed()` - `getPendingWinRecords()` - `getUserWinRecords()` - `getActivityWinStats()` - `batchProcessPendingWinRecords()` - `manualDeliverPrize()` - `cancelWinRecord()` ### 5. API 控制器更新 **文件**: `application/api/controller/Lottery.php` #### 更新的方法调用 - `getUserDrawCount()` → `LotteryRecordService::getUserDrawCount()` - `getUserWinCount()` → `LotteryRecordService::getUserWinCount()` - `getUserDrawRecords()` → `LotteryRecordService::getUserDrawRecords()` - `getUserWinRecords()` → `LotteryRecordService::getUserWinRecords()` - `getActivityDrawRanking()` → `LotteryRecordService::getActivityDrawRanking()` #### 新增引用 ```php use app\common\Service\lottery\LotteryRecordService; ``` ### 6. LotteryService 更新 #### 更新的方法调用 - `createDrawRecord()` → `LotteryRecordService::createDrawRecord()` - `createWinRecord()` → `LotteryRecordService::createWinRecord()` - `autoDeliverPrize()` → `LotteryRecordService::autoDeliverPrize()` - `hasUserDrawnForOrder()` → `LotteryRecordService::hasUserDrawnForOrder()` #### 发放方法更新 - `markWinRecordAsDelivered()` → `LotteryRecordService::markWinRecordAsDelivered()` - `setWinRecordExchangeCode()` → `LotteryRecordService::setWinRecordExchangeCode()` ## 架构优势 ### 1. 职责分离 - **LotteryService**: 专注于抽奖核心逻辑、奖品管理、活动管理 - **LotteryRecordService**: 专注于记录管理、发放处理、统计查询 - **LotteryChanceService**: 专注于抽奖机会管理 - **LotteryActivityService**: 专注于活动状态管理 ### 2. 代码复用 - 记录相关功能集中在一个服务类中,避免重复代码 - 统一的记录处理接口,便于维护和扩展 ### 3. 可测试性 - 每个服务类职责单一,便于单元测试 - 业务逻辑与数据访问分离,提高测试覆盖率 ### 4. 可维护性 - 清晰的代码结构,便于理解和维护 - 统一的错误处理和日志记录 ## 使用示例 ### 创建抽奖记录 ```php $drawRecord = LotteryRecordService::createDrawRecord( $activityId, $userId, $prizeId, $isWin, $triggerType, $triggerOrderId, $triggerAmount, $winInfo ); ``` ### 创建中奖记录 ```php $winRecord = LotteryRecordService::createWinRecord( $drawRecord->id, $activityId, $userId, $prizeId, $prizeName, $prizeType, $prizeValue ); ``` ### 获取用户抽奖统计 ```php $drawCount = LotteryRecordService::getUserDrawCount($activityId, $userId); $winCount = LotteryRecordService::getUserWinCount($activityId, $userId); ``` ### 批量处理待发放记录 ```php $processedCount = LotteryRecordService::batchProcessPendingWinRecords(50); ``` ## 注意事项 1. **依赖关系**: `LotteryRecordService` 依赖 `LotteryService` 中的兑换码管理方法 2. **数据库事务**: 涉及多个表操作时,建议使用数据库事务 3. **错误处理**: 所有方法都包含适当的异常处理 4. **性能优化**: 大量数据查询时建议使用分页和索引优化 ## 后续优化建议 1. **缓存机制**: 对于频繁查询的统计数据,可以考虑添加缓存 2. **异步处理**: 奖品发放等耗时操作可以考虑异步处理 3. **监控日志**: 添加详细的业务操作日志,便于问题排查 4. **单元测试**: 为每个服务类编写完整的单元测试用例