Browse Source

fix: 抽奖记录

super-yimizi 1 month ago
parent
commit
60a7e96093

+ 9 - 34
application/api/controller/Lottery.php

@@ -151,6 +151,9 @@ class Lottery extends Api
         $activityId = $this->request->post('lottery_id/d');
         $userId = $this->auth->id;
         $result = LotteryService::drawLottery($activityId, $userId);
+
+        // 处理图片
+        $result['prize']['image'] = cdnurl($result['prize']['image']);
         $this->success('抽奖成功', $result);
     }
 
@@ -198,41 +201,8 @@ class Lottery extends Api
         $pageSize = $this->request->param('pageSize/d', 20);
 
         $userId = $this->auth->id;
-        $where = ['user_id' => $userId];
-        if ($activityId) {
-            $where['activity_id'] = $activityId;
-        }
-
+        
         $records = LotteryRecordService::getUserDrawRecords($userId, $activityId, $page, $pageSize);
-
-    
-        // foreach ($records as $record) {
-        //     $item = [
-        //         'id' => $record->id,
-        //         'activity_id' => $record->activity_id,
-        //         'activity_name' => $record->activity->name ?? '',
-        //         'prize_id' => $record->prize_id,
-        //         'prize_name' => $record->prize->name ?? '',
-        //         'prize_type' => $record->prize->type ?? 0,
-        //         'prize_image' => $record->prize->image ?? '',
-        //         'is_win' => $record->is_win,
-        //         'draw_time' => $record->draw_time,
-        //         'trigger_type_text' => $record->trigger_type_text
-        //     ];
-
-        //     // 如果中奖,获取中奖记录详情
-        //     if ($record->is_win && $record->winRecord) {
-        //         $item['win_record'] = [
-        //             'id' => $record->winRecord->id,
-        //             'deliver_status' => $record->winRecord->deliver_status,
-        //             'deliver_status_text' => $record->winRecord->deliver_status_text,
-        //             'deliver_time' => $record->winRecord->deliver_time,
-        //             'exchange_code' => $record->winRecord->exchange_code
-        //         ];
-        //     }
-
-        // }
-
         $this->success('获取成功',  $records);
     }
 
@@ -426,6 +396,11 @@ class Lottery extends Api
             'total_amount' => $orderInfo->amount,
             'goods' => $goodsList            
         ];
+        //  用户 订单 是否已经分发过 抽奖机会
+        $isGranted = LotteryChanceService::isGrantedChanceForOrder($orderInfo, $userId);
+        if($isGranted){
+            $this->error('该订单已分发过抽奖机会');
+        }
         $grantedChances = LotteryChanceService::checkAndGrantChanceForOrderOne($orderInfo, $userId);
         $this->success('获取成功', $grantedChances);
     }

+ 50 - 1
application/common/Service/Lottery/LotteryChanceService.php

@@ -66,6 +66,7 @@ class LotteryChanceService
                 return [
                     'lottery_id' => $activity->id,
                     'lottery_name' => $activity->name,
+                    'lottery_type' => $activity->lottery_type,
                     'chances' => $chances,
                     'granted_time' => time()
                 ];
@@ -935,7 +936,7 @@ class LotteryChanceService
                 'get_time' => time()
             ];
             
-            $validation = LotteryUserChanceRecord::validateRecord($recordData);
+            $validation = self::validateChanceRecord($recordData);
             if ($validation !== true) {
                 throw new Exception($validation);
             }
@@ -1473,4 +1474,52 @@ class LotteryChanceService
         
         return $stats;
     }
+
+    /**
+     * 检查用户订单是否已经分发过抽奖机会
+     * 
+     * @param array $orderInfo 订单信息
+     * @param int $userId 用户ID
+     * @return bool 是否已分发过
+     */
+    public static function isGrantedChanceForOrder($orderInfo, $userId)
+    {
+        if (empty($orderInfo) || empty($userId) || empty($orderInfo['id'])) {
+            return false;
+        }
+
+        // 查询是否存在该订单的机会记录
+        $count = LotteryUserChanceRecord::where('user_id', $userId)
+                                       ->where('order_id', $orderInfo['id'])
+                                       ->count();
+        
+        return $count > 0;
+    }
+
+    /**
+     * 检查用户是否对指定条件已经获得过抽奖机会(用于防重复)
+     * 
+     * @param int $activityId 活动ID
+     * @param int $userId 用户ID
+     * @param int $conditionId 条件ID
+     * @param string $conditionValue 条件值
+     * @return bool 是否已获得过
+     */
+    public static function isGrantedChanceForCondition($activityId, $userId, $conditionId, $conditionValue = '')
+    {
+        $where = [
+            'activity_id' => $activityId,
+            'user_id' => $userId,
+            'condition_id' => $conditionId
+        ];
+
+        // 如果有条件值,也要匹配
+        if (!empty($conditionValue)) {
+            $where['condition_value'] = $conditionValue;
+        }
+
+        $count = LotteryUserChanceRecord::where($where)->count();
+        
+        return $count > 0;
+    }
 } 

+ 116 - 3
application/common/Service/Lottery/LotteryRecordService.php

@@ -113,9 +113,122 @@ class LotteryRecordService
             $query->where('activity_id', $activityId);
         }
         
-        return $query->with(['activity', 'prize', 'winRecord'])
-                     ->order('draw_time', 'desc')
-                     ->paginate($pageSize, false, ['page' => $page]);
+        // 1. 先分页查询抽奖记录
+        $records = $query->field('id,activity_id,prize_id,is_win,trigger_type,trigger_order_id,trigger_amount,draw_time')
+                        ->order('draw_time', 'desc')
+                        ->paginate($pageSize, false, ['page' => $page]);
+        
+        if (empty($records) || $records->isEmpty()) {
+            return $records;
+        }
+        
+        // 2. 收集关联ID
+        $activityIds = [];
+        $prizeIds = [];
+        $drawRecordIds = [];
+        
+        foreach ($records as $record) {
+            $activityIds[] = $record->activity_id;
+            $prizeIds[] = $record->prize_id;
+            if ($record->is_win) {
+                $drawRecordIds[] = $record->id;
+            }
+        }
+        
+        // 去重
+        $activityIds = array_unique($activityIds);
+        $prizeIds = array_unique($prizeIds);
+        $drawRecordIds = array_unique($drawRecordIds);
+        
+        // 3. 批量查询关联数据
+        $activities = [];
+        if (!empty($activityIds)) {
+            $activityList = \app\common\model\lottery\LotteryActivity::whereIn('id', $activityIds)
+                                ->field('id,name,status,lottery_type')
+                                ->select();
+            foreach ($activityList as $activity) {
+                $activities[$activity->id] = $activity;
+            }
+        }
+        
+        $prizes = [];
+        if (!empty($prizeIds)) {
+            $prizeList = \app\common\model\lottery\LotteryPrize::whereIn('id', $prizeIds)
+                            ->field('id,name,image,activity_id,type')
+                            ->select();
+            foreach ($prizeList as $prize) {
+                $prizes[$prize->id] = $prize;
+            }
+        }
+        
+        $winRecords = [];
+        if (!empty($drawRecordIds)) {
+            $winRecordList = \app\common\model\lottery\LotteryWinRecord::whereIn('draw_record_id', $drawRecordIds)
+                                ->field('id,draw_record_id,deliver_status,deliver_time,exchange_code,receiver_name,receiver_mobile,receiver_address,express_company,express_number,exchange_code')
+                                ->select();
+            foreach ($winRecordList as $winRecord) {
+                $winRecords[$winRecord->draw_record_id] = $winRecord;
+            }
+        }
+        
+        // 4. 将关联数据作为字段附加到记录中
+        foreach ($records as $record) {
+            // 附加活动信息字段
+            $activity = $activities[$record->activity_id] ?? null;
+            $record->activity_name = $activity ? $activity->name : '';
+            $record->activity_status = $activity ? $activity->status : 0;
+            $record->activity_lottery_type = $activity ? $activity->lottery_type : 0;
+            
+            // 附加奖品信息字段
+            $prize = $prizes[$record->prize_id] ?? null;
+            $record->prize_name = $prize ? $prize->name : '';
+            $record->prize_image = $prize ? cdnurl($prize->image) : '';
+            $record->prize_type = $prize ? $prize->type : 0;
+            
+            // 附加中奖记录信息字段(仅限中奖记录)
+            if ($record->is_win) {
+                $winRecord = $winRecords[$record->id] ?? null;
+                $record->win_record_id = $winRecord ? $winRecord->id : 0;
+                $record->deliver_status = $winRecord ? $winRecord->deliver_status : 0;
+                $record->deliver_time = $winRecord ? $winRecord->deliver_time : 0;
+                $record->exchange_code = $winRecord ? $winRecord->exchange_code : '';
+                $record->receiver_name = $winRecord ? $winRecord->receiver_name : '';
+                $record->receiver_mobile = $winRecord ? $winRecord->receiver_mobile : '';
+                $record->receiver_address = $winRecord ? $winRecord->receiver_address : '';
+                $record->express_company = $winRecord ? $winRecord->express_company : '';
+                $record->express_number = $winRecord ? $winRecord->express_number : '';
+            } else {
+                $record->win_record_id = 0;
+                $record->deliver_status = 0;
+                $record->deliver_time = 0;
+                $record->exchange_code = '';
+                $record->receiver_name = '';
+                $record->receiver_mobile = '';
+                $record->receiver_address = '';
+                $record->express_company = '';
+                $record->express_number = '';
+            }
+            
+            // 添加触发类型文本
+            $record->trigger_type_text = static::getTriggerTypeText($record->trigger_type);
+        }
+        
+        return $records;
+    }
+    
+    /**
+     * 获取触发类型文本
+     */
+    private static function getTriggerTypeText($triggerType)
+    {
+        $map = [
+            1 => '购买商品',
+            2 => '订单消费', 
+            3 => '充值',
+            4 => '累计消费'
+        ];
+        
+        return $map[$triggerType] ?? '未知';
     }
 
     /**

+ 116 - 10
application/common/Service/Lottery/LotteryService.php

@@ -40,33 +40,44 @@ class LotteryService
         if (!$activity || !self::isActivityRunning($activity)) {
             throw new BusinessException('活动不存在或未开始', ErrorCodeEnum::LOTTERY_ACTIVITY_NOT_FOUND);
         }
-        // 2. 验证抽奖时间
-        if (!self::isActivityRunning($activity)) {
-            throw new BusinessException('不在抽奖时间内', ErrorCodeEnum::LOTTERY_NOT_IN_TIME);
+
+        // 2. 验证开奖时间(仅对按时间开奖有效)
+        if ($activity->lottery_type == LotteryEnum::LOTTERY_TYPE_TIME) {
+            $now = time();
+            if ($activity->lottery_time && $now >= $activity->lottery_time) {
+                throw new BusinessException('开奖时间已过,无法参与', ErrorCodeEnum::LOTTERY_NOT_IN_TIME);
+            }
         }
 
-        // 3. 验证用户资格
+        // 3. 验证参与人数限制(仅对按人数开奖有效)
+        if ($activity->lottery_type == LotteryEnum::LOTTERY_TYPE_PEOPLE) {
+            $drawStats = LotteryRecordService::getActivityDrawStats($activityId);
+            if ($drawStats['total_draw'] >= $activity->lottery_people_num) {
+                throw new BusinessException('参与人数已满,无法参与', ErrorCodeEnum::LOTTERY_REACH_LIMIT);
+            }
+        }
+        // 4. 验证用户资格
         if (!static::validateUserQualification($activity, $userId)) {
             throw new BusinessException('用户不符合参与条件', ErrorCodeEnum::LOTTERY_USER_NOT_QUALIFIED);
         }
 
-        // 4. 检查用户抽奖机会
+        // 5. 检查用户抽奖机会
         $userChance = LotteryChanceService::getUserChance($activityId, $userId);
         if (!$userChance || !LotteryChanceService::hasChance($userChance)) {
             throw new BusinessException('没有抽奖机会', ErrorCodeEnum::LOTTERY_NO_CHANCE);
         }
 
-        // 5. 检查用户参与次数限制
+        // 6. 检查用户参与次数限制
         if (!static::checkUserDrawLimit($activity, $userId)) {
             throw new BusinessException('已达到参与次数上限', ErrorCodeEnum::LOTTERY_REACH_LIMIT);
         }
 
-        // 6. 防重复抽奖检查(基于订单)
+        // 7. 防重复抽奖检查(基于订单)
         if ($triggerOrderId && static::hasDrawnForOrder($activityId, $userId, $triggerOrderId)) {
             throw new BusinessException('该订单已参与过抽奖', ErrorCodeEnum::LOTTERY_ORDER_ALREADY_DRAWN);
         }
 
-        // TODO: 7. 使用分布式锁防止并发(暂时移除,后续实现)
+        // TODO: 8. 使用分布式锁防止并发(暂时移除,后续实现)
         // $lockKey = "lottery_lock_{$activityId}_{$userId}";
         // $lockAcquired = static::acquireLock($lockKey, 10);
         // if (!$lockAcquired) {
@@ -74,8 +85,8 @@ class LotteryService
         // }
 
         // try {
-            // 7. 开始抽奖流程
-            return static::processDrawLottery($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount);
+            // 8. 根据开奖方式处理抽奖流程
+            return static::handleLotteryByType($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount);
         // } finally {
         //     // 释放锁
         //     static::releaseLock($lockKey);
@@ -83,6 +94,29 @@ class LotteryService
     }
 
     /**
+     * 根据开奖方式处理抽奖
+     */
+    private static function handleLotteryByType($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount)
+    {
+        switch ($activity->lottery_type) {
+            case LotteryEnum::LOTTERY_TYPE_INSTANT:
+                // 即抽即中:直接执行抽奖
+                return static::processDrawLottery($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount);
+                
+            case LotteryEnum::LOTTERY_TYPE_TIME:
+                // 按时间开奖:记录参与,等待定时任务开奖
+                return static::recordParticipation($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount);
+                
+            case LotteryEnum::LOTTERY_TYPE_PEOPLE:
+                // 按人数开奖:记录参与,检查是否达到开奖人数
+                return static::handlePeopleBasedLottery($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount);
+                
+            default:
+                throw new BusinessException('不支持的开奖方式', ErrorCodeEnum::LOTTERY_ACTIVITY_NOT_FOUND);
+        }
+    }
+
+    /**
      * 处理抽奖核心逻辑
      */
     private static function processDrawLottery($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount)
@@ -163,6 +197,78 @@ class LotteryService
     }
 
     /**
+     * 记录参与(用于按时间开奖和按人数开奖)
+     */
+    private static function recordParticipation($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount)
+    {
+        // 开启事务
+        Db::startTrans();
+        
+        try {
+            // 1. 消耗用户抽奖机会
+            $userChance = LotteryChanceService::getUserChance($activity->id, $userId);
+            if (!LotteryChanceService::useChance($userChance)) {
+                throw new Exception('抽奖机会使用失败');
+            }
+
+            // 2. 创建参与记录(未开奖状态)
+            $drawRecord = LotteryRecordService::createDrawRecord(
+                $activity->id,
+                $userId,
+                0, // 暂时没有奖品ID
+                0, // 未开奖
+                $triggerType,
+                $triggerOrderId,
+                $triggerAmount,
+                [] // 暂时没有中奖信息
+            );
+
+            // 提交事务
+            Db::commit();
+
+            // 3. 返回参与结果
+            return [
+                'draw_id' => $drawRecord->id,
+                'is_win' => 0,
+                'status' => 'waiting', // 等待开奖
+                'lottery_type' => $activity->lottery_type,
+                'lottery_time' => $activity->lottery_time ?? 0,
+                'message' => $activity->lottery_type == LotteryEnum::LOTTERY_TYPE_TIME ? 
+                           '参与成功,等待' . date('Y-m-d H:i:s', $activity->lottery_time) . '开奖' : 
+                           '参与成功,等待开奖'
+            ];
+
+        } catch (Exception $e) {
+            Db::rollback();
+            throw $e;
+        }
+    }
+
+    /**
+     * 处理按人数开奖
+     */
+    private static function handlePeopleBasedLottery($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount)
+    {
+        // 先记录参与
+        $result = static::recordParticipation($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount);
+        
+        // 检查是否达到开奖人数
+        $drawStats = LotteryRecordService::getActivityDrawStats($activity->id);
+        $participantCount = $drawStats['total_draw'];
+        
+        if ($participantCount >= $activity->lottery_people_num) {
+            // 达到人数,触发开奖(这里可以异步处理)
+            // TODO: 触发按人数开奖的处理逻辑
+            $result['message'] = '参与成功,已达到开奖人数,正在开奖中...';
+        } else {
+            $remainingCount = $activity->lottery_people_num - $participantCount;
+            $result['message'] = "参与成功,还需要{$remainingCount}人参与即可开奖";
+        }
+        
+        return $result;
+    }
+
+    /**
      * 获取可用奖品列表
      */
     private static function getAvailablePrizes($activity)

+ 50 - 1
application/common/Service/lottery/LotteryChanceService.php

@@ -66,6 +66,7 @@ class LotteryChanceService
                 return [
                     'lottery_id' => $activity->id,
                     'lottery_name' => $activity->name,
+                    'lottery_type' => $activity->lottery_type,
                     'chances' => $chances,
                     'granted_time' => time()
                 ];
@@ -935,7 +936,7 @@ class LotteryChanceService
                 'get_time' => time()
             ];
             
-            $validation = LotteryUserChanceRecord::validateRecord($recordData);
+            $validation = self::validateChanceRecord($recordData);
             if ($validation !== true) {
                 throw new Exception($validation);
             }
@@ -1473,4 +1474,52 @@ class LotteryChanceService
         
         return $stats;
     }
+
+    /**
+     * 检查用户订单是否已经分发过抽奖机会
+     * 
+     * @param array $orderInfo 订单信息
+     * @param int $userId 用户ID
+     * @return bool 是否已分发过
+     */
+    public static function isGrantedChanceForOrder($orderInfo, $userId)
+    {
+        if (empty($orderInfo) || empty($userId) || empty($orderInfo['id'])) {
+            return false;
+        }
+
+        // 查询是否存在该订单的机会记录
+        $count = LotteryUserChanceRecord::where('user_id', $userId)
+                                       ->where('order_id', $orderInfo['id'])
+                                       ->count();
+        
+        return $count > 0;
+    }
+
+    /**
+     * 检查用户是否对指定条件已经获得过抽奖机会(用于防重复)
+     * 
+     * @param int $activityId 活动ID
+     * @param int $userId 用户ID
+     * @param int $conditionId 条件ID
+     * @param string $conditionValue 条件值
+     * @return bool 是否已获得过
+     */
+    public static function isGrantedChanceForCondition($activityId, $userId, $conditionId, $conditionValue = '')
+    {
+        $where = [
+            'activity_id' => $activityId,
+            'user_id' => $userId,
+            'condition_id' => $conditionId
+        ];
+
+        // 如果有条件值,也要匹配
+        if (!empty($conditionValue)) {
+            $where['condition_value'] = $conditionValue;
+        }
+
+        $count = LotteryUserChanceRecord::where($where)->count();
+        
+        return $count > 0;
+    }
 } 

+ 116 - 3
application/common/Service/lottery/LotteryRecordService.php

@@ -113,9 +113,122 @@ class LotteryRecordService
             $query->where('activity_id', $activityId);
         }
         
-        return $query->with(['activity', 'prize', 'winRecord'])
-                     ->order('draw_time', 'desc')
-                     ->paginate($pageSize, false, ['page' => $page]);
+        // 1. 先分页查询抽奖记录
+        $records = $query->field('id,activity_id,prize_id,is_win,trigger_type,trigger_order_id,trigger_amount,draw_time')
+                        ->order('draw_time', 'desc')
+                        ->paginate($pageSize, false, ['page' => $page]);
+        
+        if (empty($records) || $records->isEmpty()) {
+            return $records;
+        }
+        
+        // 2. 收集关联ID
+        $activityIds = [];
+        $prizeIds = [];
+        $drawRecordIds = [];
+        
+        foreach ($records as $record) {
+            $activityIds[] = $record->activity_id;
+            $prizeIds[] = $record->prize_id;
+            if ($record->is_win) {
+                $drawRecordIds[] = $record->id;
+            }
+        }
+        
+        // 去重
+        $activityIds = array_unique($activityIds);
+        $prizeIds = array_unique($prizeIds);
+        $drawRecordIds = array_unique($drawRecordIds);
+        
+        // 3. 批量查询关联数据
+        $activities = [];
+        if (!empty($activityIds)) {
+            $activityList = \app\common\model\lottery\LotteryActivity::whereIn('id', $activityIds)
+                                ->field('id,name,status,lottery_type')
+                                ->select();
+            foreach ($activityList as $activity) {
+                $activities[$activity->id] = $activity;
+            }
+        }
+        
+        $prizes = [];
+        if (!empty($prizeIds)) {
+            $prizeList = \app\common\model\lottery\LotteryPrize::whereIn('id', $prizeIds)
+                            ->field('id,name,image,activity_id,type')
+                            ->select();
+            foreach ($prizeList as $prize) {
+                $prizes[$prize->id] = $prize;
+            }
+        }
+        
+        $winRecords = [];
+        if (!empty($drawRecordIds)) {
+            $winRecordList = \app\common\model\lottery\LotteryWinRecord::whereIn('draw_record_id', $drawRecordIds)
+                                ->field('id,draw_record_id,deliver_status,deliver_time,exchange_code,receiver_name,receiver_mobile,receiver_address,express_company,express_number,exchange_code')
+                                ->select();
+            foreach ($winRecordList as $winRecord) {
+                $winRecords[$winRecord->draw_record_id] = $winRecord;
+            }
+        }
+        
+        // 4. 将关联数据作为字段附加到记录中
+        foreach ($records as $record) {
+            // 附加活动信息字段
+            $activity = $activities[$record->activity_id] ?? null;
+            $record->activity_name = $activity ? $activity->name : '';
+            $record->activity_status = $activity ? $activity->status : 0;
+            $record->activity_lottery_type = $activity ? $activity->lottery_type : 0;
+            
+            // 附加奖品信息字段
+            $prize = $prizes[$record->prize_id] ?? null;
+            $record->prize_name = $prize ? $prize->name : '';
+            $record->prize_image = $prize ? cdnurl($prize->image) : '';
+            $record->prize_type = $prize ? $prize->type : 0;
+            
+            // 附加中奖记录信息字段(仅限中奖记录)
+            if ($record->is_win) {
+                $winRecord = $winRecords[$record->id] ?? null;
+                $record->win_record_id = $winRecord ? $winRecord->id : 0;
+                $record->deliver_status = $winRecord ? $winRecord->deliver_status : 0;
+                $record->deliver_time = $winRecord ? $winRecord->deliver_time : 0;
+                $record->exchange_code = $winRecord ? $winRecord->exchange_code : '';
+                $record->receiver_name = $winRecord ? $winRecord->receiver_name : '';
+                $record->receiver_mobile = $winRecord ? $winRecord->receiver_mobile : '';
+                $record->receiver_address = $winRecord ? $winRecord->receiver_address : '';
+                $record->express_company = $winRecord ? $winRecord->express_company : '';
+                $record->express_number = $winRecord ? $winRecord->express_number : '';
+            } else {
+                $record->win_record_id = 0;
+                $record->deliver_status = 0;
+                $record->deliver_time = 0;
+                $record->exchange_code = '';
+                $record->receiver_name = '';
+                $record->receiver_mobile = '';
+                $record->receiver_address = '';
+                $record->express_company = '';
+                $record->express_number = '';
+            }
+            
+            // 添加触发类型文本
+            $record->trigger_type_text = static::getTriggerTypeText($record->trigger_type);
+        }
+        
+        return $records;
+    }
+    
+    /**
+     * 获取触发类型文本
+     */
+    private static function getTriggerTypeText($triggerType)
+    {
+        $map = [
+            1 => '购买商品',
+            2 => '订单消费', 
+            3 => '充值',
+            4 => '累计消费'
+        ];
+        
+        return $map[$triggerType] ?? '未知';
     }
 
     /**

+ 116 - 10
application/common/Service/lottery/LotteryService.php

@@ -40,33 +40,44 @@ class LotteryService
         if (!$activity || !self::isActivityRunning($activity)) {
             throw new BusinessException('活动不存在或未开始', ErrorCodeEnum::LOTTERY_ACTIVITY_NOT_FOUND);
         }
-        // 2. 验证抽奖时间
-        if (!self::isActivityRunning($activity)) {
-            throw new BusinessException('不在抽奖时间内', ErrorCodeEnum::LOTTERY_NOT_IN_TIME);
+
+        // 2. 验证开奖时间(仅对按时间开奖有效)
+        if ($activity->lottery_type == LotteryEnum::LOTTERY_TYPE_TIME) {
+            $now = time();
+            if ($activity->lottery_time && $now >= $activity->lottery_time) {
+                throw new BusinessException('开奖时间已过,无法参与', ErrorCodeEnum::LOTTERY_NOT_IN_TIME);
+            }
         }
 
-        // 3. 验证用户资格
+        // 3. 验证参与人数限制(仅对按人数开奖有效)
+        if ($activity->lottery_type == LotteryEnum::LOTTERY_TYPE_PEOPLE) {
+            $drawStats = LotteryRecordService::getActivityDrawStats($activityId);
+            if ($drawStats['total_draw'] >= $activity->lottery_people_num) {
+                throw new BusinessException('参与人数已满,无法参与', ErrorCodeEnum::LOTTERY_REACH_LIMIT);
+            }
+        }
+        // 4. 验证用户资格
         if (!static::validateUserQualification($activity, $userId)) {
             throw new BusinessException('用户不符合参与条件', ErrorCodeEnum::LOTTERY_USER_NOT_QUALIFIED);
         }
 
-        // 4. 检查用户抽奖机会
+        // 5. 检查用户抽奖机会
         $userChance = LotteryChanceService::getUserChance($activityId, $userId);
         if (!$userChance || !LotteryChanceService::hasChance($userChance)) {
             throw new BusinessException('没有抽奖机会', ErrorCodeEnum::LOTTERY_NO_CHANCE);
         }
 
-        // 5. 检查用户参与次数限制
+        // 6. 检查用户参与次数限制
         if (!static::checkUserDrawLimit($activity, $userId)) {
             throw new BusinessException('已达到参与次数上限', ErrorCodeEnum::LOTTERY_REACH_LIMIT);
         }
 
-        // 6. 防重复抽奖检查(基于订单)
+        // 7. 防重复抽奖检查(基于订单)
         if ($triggerOrderId && static::hasDrawnForOrder($activityId, $userId, $triggerOrderId)) {
             throw new BusinessException('该订单已参与过抽奖', ErrorCodeEnum::LOTTERY_ORDER_ALREADY_DRAWN);
         }
 
-        // TODO: 7. 使用分布式锁防止并发(暂时移除,后续实现)
+        // TODO: 8. 使用分布式锁防止并发(暂时移除,后续实现)
         // $lockKey = "lottery_lock_{$activityId}_{$userId}";
         // $lockAcquired = static::acquireLock($lockKey, 10);
         // if (!$lockAcquired) {
@@ -74,8 +85,8 @@ class LotteryService
         // }
 
         // try {
-            // 7. 开始抽奖流程
-            return static::processDrawLottery($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount);
+            // 8. 根据开奖方式处理抽奖流程
+            return static::handleLotteryByType($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount);
         // } finally {
         //     // 释放锁
         //     static::releaseLock($lockKey);
@@ -83,6 +94,29 @@ class LotteryService
     }
 
     /**
+     * 根据开奖方式处理抽奖
+     */
+    private static function handleLotteryByType($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount)
+    {
+        switch ($activity->lottery_type) {
+            case LotteryEnum::LOTTERY_TYPE_INSTANT:
+                // 即抽即中:直接执行抽奖
+                return static::processDrawLottery($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount);
+                
+            case LotteryEnum::LOTTERY_TYPE_TIME:
+                // 按时间开奖:记录参与,等待定时任务开奖
+                return static::recordParticipation($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount);
+                
+            case LotteryEnum::LOTTERY_TYPE_PEOPLE:
+                // 按人数开奖:记录参与,检查是否达到开奖人数
+                return static::handlePeopleBasedLottery($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount);
+                
+            default:
+                throw new BusinessException('不支持的开奖方式', ErrorCodeEnum::LOTTERY_ACTIVITY_NOT_FOUND);
+        }
+    }
+
+    /**
      * 处理抽奖核心逻辑
      */
     private static function processDrawLottery($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount)
@@ -163,6 +197,78 @@ class LotteryService
     }
 
     /**
+     * 记录参与(用于按时间开奖和按人数开奖)
+     */
+    private static function recordParticipation($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount)
+    {
+        // 开启事务
+        Db::startTrans();
+        
+        try {
+            // 1. 消耗用户抽奖机会
+            $userChance = LotteryChanceService::getUserChance($activity->id, $userId);
+            if (!LotteryChanceService::useChance($userChance)) {
+                throw new Exception('抽奖机会使用失败');
+            }
+
+            // 2. 创建参与记录(未开奖状态)
+            $drawRecord = LotteryRecordService::createDrawRecord(
+                $activity->id,
+                $userId,
+                0, // 暂时没有奖品ID
+                0, // 未开奖
+                $triggerType,
+                $triggerOrderId,
+                $triggerAmount,
+                [] // 暂时没有中奖信息
+            );
+
+            // 提交事务
+            Db::commit();
+
+            // 3. 返回参与结果
+            return [
+                'draw_id' => $drawRecord->id,
+                'is_win' => 0,
+                'status' => 'waiting', // 等待开奖
+                'lottery_type' => $activity->lottery_type,
+                'lottery_time' => $activity->lottery_time ?? 0,
+                'message' => $activity->lottery_type == LotteryEnum::LOTTERY_TYPE_TIME ? 
+                           '参与成功,等待' . date('Y-m-d H:i:s', $activity->lottery_time) . '开奖' : 
+                           '参与成功,等待开奖'
+            ];
+
+        } catch (Exception $e) {
+            Db::rollback();
+            throw $e;
+        }
+    }
+
+    /**
+     * 处理按人数开奖
+     */
+    private static function handlePeopleBasedLottery($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount)
+    {
+        // 先记录参与
+        $result = static::recordParticipation($activity, $userId, $triggerType, $triggerOrderId, $triggerAmount);
+        
+        // 检查是否达到开奖人数
+        $drawStats = LotteryRecordService::getActivityDrawStats($activity->id);
+        $participantCount = $drawStats['total_draw'];
+        
+        if ($participantCount >= $activity->lottery_people_num) {
+            // 达到人数,触发开奖(这里可以异步处理)
+            // TODO: 触发按人数开奖的处理逻辑
+            $result['message'] = '参与成功,已达到开奖人数,正在开奖中...';
+        } else {
+            $remainingCount = $activity->lottery_people_num - $participantCount;
+            $result['message'] = "参与成功,还需要{$remainingCount}人参与即可开奖";
+        }
+        
+        return $result;
+    }
+
+    /**
      * 获取可用奖品列表
      */
     private static function getAvailablePrizes($activity)