with('conditions'); } $activity = $query->find($activityId); if (!$activity) { return null; } return ActivityConfigDto::fromModel($activity, $withConditions); } /** * 获取用户可参与的活动列表 * * @param int $userId 用户ID * @return array */ public function getUserAvailableActivities(int $userId): array { // 获取进行中的活动 $activities = ActivityConfig::where('status', ACTIVITY_STATUS::IN_PROGRESS) ->where('start_time', '<=', now()) ->where('end_time', '>=', now()) ->orderBy('display_order', 'desc') ->get(); $result = []; foreach ($activities as $activity) { // 检查用户是否已参与且完成或失败 $participation = ActivityParticipation::where('user_id', $userId) ->where('activity_id', $activity->id) ->whereIn('completion_status', [PARTICIPATION_STATUS::COMPLETED, PARTICIPATION_STATUS::FAILED]) ->first(); // 如果用户已完成或失败,则跳过 if ($participation) { continue; } // 检查参与条件 if ($this->checkParticipationConditions($userId, $activity->id)) { $result[] = ActivityConfigDto::fromModel($activity); } } return $result; } /** * 参与活动 * * @param int $userId 用户ID * @param int $activityId 活动ID * @return ActivityParticipationDto * @throws Exception */ public function participateActivity(int $userId, int $activityId): ActivityParticipationDto { // 获取活动信息 $activity = ActivityConfig::findOrFail($activityId); // 检查活动状态 if ($activity->status !== ACTIVITY_STATUS::IN_PROGRESS) { throw new Exception('活动未开始或已结束'); } // 检查活动时间 $now = now(); if ($activity->start_time > $now || $activity->end_time < $now) { throw new Exception('不在活动时间范围内'); } // 检查用户是否已参与且完成或失败 $existingParticipation = ActivityParticipation::where('user_id', $userId) ->where('activity_id', $activityId) ->whereIn('completion_status', [PARTICIPATION_STATUS::COMPLETED, PARTICIPATION_STATUS::FAILED]) ->first(); if ($existingParticipation) { throw new Exception('您已完成或失败此活动,无法再次参与'); } // 检查参与条件 if (!$this->checkParticipationConditions($userId, $activityId)) { throw new Exception('不满足活动参与条件'); } // 检查事务是否已开启 \UCore\Db\Helper::check_tr(); // 查找或创建参与记录 $participation = ActivityParticipation::firstOrNew([ 'user_id' => $userId, 'activity_id' => $activityId, ]); $isNewParticipation = !$participation->exists; // 设置参与记录属性 $participation->participate_time = $now; $participation->reward_status = REWARD_STATUS::NOT_CLAIMED; $participation->completion_status = PARTICIPATION_STATUS::IN_PROGRESS; $participation->save(); // 创建或更新用户活动数据 $userData = UserActivityData::firstOrNew([ 'user_id' => $userId, 'activity_id' => $activityId, ]); if (!$userData->exists) { $userData->progress = 0; $userData->progress_data = []; } $userData->last_update = $now; $userData->save(); // 如果是新参与,触发用户参与活动事件 if ($isNewParticipation) { Event::dispatch(new UserParticipatedEvent($userId, $activityId)); } // 返回参与记录DTO return ActivityParticipationDto::fromModel($participation); } /** * 更新活动进度 * * @param int $userId 用户ID * @param int $activityId 活动ID * @param int $progress 进度值 * @param array|null $progressData 进度数据 * @return bool * @throws Exception */ public function updateActivityProgress(int $userId, int $activityId, int $progress, ?array $progressData = null): bool { // 获取用户参与记录 $participation = ActivityParticipation::where('user_id', $userId) ->where('activity_id', $activityId) ->first(); if (!$participation) { throw new Exception('用户未参与此活动'); } if ($participation->completion_status !== PARTICIPATION_STATUS::IN_PROGRESS) { throw new Exception('活动已完成或失败,无法更新进度'); } // 检查事务是否已开启 \UCore\Db\Helper::check_tr(); // 更新用户活动数据 $userData = UserActivityData::firstOrNew([ 'user_id' => $userId, 'activity_id' => $activityId, ]); $oldProgress = $userData->progress; $userData->progress = $progress; if ($progressData !== null) { $userData->progress_data = $progressData; } $userData->last_update = now(); $userData->save(); // 检查是否满足完成条件 $isCompleted = $this->checkCompletionConditions($userId, $activityId); if ($isCompleted) { // 更新参与记录为已完成 $participation->completion_status = PARTICIPATION_STATUS::COMPLETED; $participation->completion_time = now(); $participation->save(); // 触发活动完成事件 Event::dispatch(new ActivityCompletedEvent($userId, $activityId)); } // 触发活动进度更新事件 Event::dispatch(new ActivityProgressUpdatedEvent($userId, $activityId, $oldProgress, $progress)); return true; } /** * 领取活动奖励 * * @param int $userId 用户ID * @param int $activityId 活动ID * @return bool * @throws Exception */ public function claimActivityReward(int $userId, int $activityId): bool { // 获取用户参与记录 $participation = ActivityParticipation::where('user_id', $userId) ->where('activity_id', $activityId) ->first(); if (!$participation) { throw new Exception('用户未参与此活动'); } if ($participation->completion_status !== PARTICIPATION_STATUS::COMPLETED) { throw new Exception('活动未完成,无法领取奖励'); } if ($participation->reward_status === REWARD_STATUS::CLAIMED) { throw new Exception('奖励已领取'); } // 检查事务是否已开启 \UCore\Db\Helper::check_tr(); // 获取活动信息 $activity = ActivityConfig::findOrFail($activityId); // 更新参与记录为已领取 $participation->reward_status = REWARD_STATUS::CLAIMED; $participation->save(); // 发放奖励 $rewardResult = $this->grantActivityReward($userId, $activity); // 触发奖励领取事件 Event::dispatch(new ActivityRewardClaimedEvent($userId, $activityId, $rewardResult)); return true; } /** * 检查参与条件 * * @param int $userId 用户ID * @param int $activityId 活动ID * @return bool */ private function checkParticipationConditions(int $userId, int $activityId): bool { // 获取活动的参与条件 $conditions = ActivityCondition::where('activity_id', $activityId) ->where('is_participation_condition', true) ->get(); // 如果没有参与条件,则默认可以参与 if ($conditions->isEmpty()) { return true; } // 检查每个条件 foreach ($conditions as $condition) { // 根据条件类型进行检查 $conditionChecker = new ConditionLogic(); if (!$conditionChecker->checkCondition($userId, $condition)) { return false; } } return true; } /** * 检查完成条件 * * @param int $userId 用户ID * @param int $activityId 活动ID * @return bool */ private function checkCompletionConditions(int $userId, int $activityId): bool { // 获取活动的完成条件 $conditions = ActivityCondition::where('activity_id', $activityId) ->where('is_completion_condition', true) ->get(); // 如果没有完成条件,则默认已完成 if ($conditions->isEmpty()) { return true; } // 检查每个条件 foreach ($conditions as $condition) { // 根据条件类型进行检查 $conditionChecker = new ConditionLogic(); if (!$conditionChecker->checkCondition($userId, $condition)) { return false; } } return true; } /** * 发放活动奖励 * * @param int $userId 用户ID * @param ActivityConfig $activity 活动配置 * @return array 奖励结果 */ private function grantActivityReward(int $userId, ActivityConfig $activity): array { $result = [ 'success' => true, 'rewards' => [] ]; // 如果活动配置了奖励组 if ($activity->reward_group_id || $activity->reward_group_code) { try { // 使用奖励组服务发放奖励 $rewardGroupId = $activity->reward_group_id; $rewardGroupCode = $activity->reward_group_code; // 调用奖励组服务 $rewardService = new \App\Module\Game\Services\RewardService(); $rewardResult = $rewardService::grantReward( $userId, $rewardGroupId ?: $rewardGroupCode, REWARD_SOURCE_TYPE::ACTIVITY, $activity->id ); if ($rewardResult->success) { $result['rewards'] = $rewardResult->items; } else { Log::error('活动奖励发放失败', [ 'user_id' => $userId, 'activity_id' => $activity->id, 'error' => $rewardResult->errorMessage ]); $result['success'] = false; $result['error'] = $rewardResult->errorMessage; } } catch (Exception $e) { Log::error('活动奖励发放异常', [ 'user_id' => $userId, 'activity_id' => $activity->id, 'error' => $e->getMessage() ]); $result['success'] = false; $result['error'] = $e->getMessage(); } } return $result; } }