conditionRepository = $conditionRepository; $this->achievementConditionRepository = $achievementConditionRepository; $this->userTaskRepository = $userTaskRepository; $this->userProgressRepository = $userProgressRepository; } /** * 获取所有可用的任务条件 * * @return array 条件列表 */ public function getAllConditions(): array { return $this->conditionRepository->getActiveConditions(); } /** * 获取任务的所有达成条件 * * @param int $taskId 任务ID * @param string|null $conditionType 条件类型(prerequisite=前置条件,progress=进度条件) * @return array 达成条件列表 */ public function getTaskConditions(int $taskId, ?string $conditionType = null): array { return $this->achievementConditionRepository->getConditionsByTaskId($taskId, $conditionType); } /** * 验证任务前置条件 * * @param int $userId 用户ID * @param int $taskId 任务ID * @return array 验证结果 */ public function validatePrerequisiteConditions(int $userId, int $taskId): array { try { // 获取任务的前置条件 $prerequisites = $this->getTaskConditions($taskId, 'prerequisite'); if (empty($prerequisites)) { return [ 'success' => true, 'message' => '无前置条件', ]; } // 验证每个前置条件 $failedConditions = []; foreach ($prerequisites as $prerequisite) { $condition = $this->conditionRepository->find($prerequisite['condition_id']); if (!$condition) { continue; } // 获取条件处理器类 $handlerClass = $condition->handler_class; if (!class_exists($handlerClass)) { Log::error('条件处理器类不存在', [ 'condition_id' => $condition->id, 'handler_class' => $handlerClass, ]); continue; } // 实例化条件处理器 $handler = new $handlerClass(); // 验证条件 $isValid = $handler->validate($userId, $prerequisite['condition_params']); if (!$isValid) { $failedConditions[] = [ 'condition_id' => $condition->id, 'name' => $condition->name, 'description' => $condition->description, ]; } } if (!empty($failedConditions)) { return [ 'success' => false, 'message' => '前置条件未满足', 'failed_conditions' => $failedConditions, ]; } return [ 'success' => true, 'message' => '前置条件已满足', ]; } catch (\Exception $e) { Log::error('验证前置条件失败', [ 'user_id' => $userId, 'task_id' => $taskId, 'error' => $e->getMessage(), ]); return [ 'success' => false, 'message' => '验证前置条件失败: ' . $e->getMessage(), ]; } } /** * 更新任务进度条件 * * @param int $userId 用户ID * @param string $conditionCode 条件代码 * @param array $params 条件参数 * @param int $increment 增量值 * @return array 更新结果 */ public function updateProgressCondition(int $userId, string $conditionCode, array $params, int $increment = 1): array { try { // 获取条件 $condition = $this->conditionRepository->getByCode($conditionCode); if (!$condition) { throw new \Exception('条件不存在'); } // 获取使用该条件的任务达成条件 $achievementConditions = $condition->achievementConditions() ->where('condition_type', 'progress') ->get(); if ($achievementConditions->isEmpty()) { return [ 'success' => true, 'message' => '无相关任务进度需要更新', 'updated_tasks' => [], ]; } // 获取条件处理器类 $handlerClass = $condition->handler_class; if (empty($handlerClass)) { throw new \Exception('条件处理器类未配置: ' . $condition->code); } if (!class_exists($handlerClass)) { throw new \Exception('条件处理器类不存在: ' . $handlerClass); } // 实例化条件处理器 $handler = new $handlerClass(); // 更新任务进度 $updatedTasks = []; foreach ($achievementConditions as $achievementCondition) { // 获取用户任务 $userTask = $this->userTaskRepository->getUserTask($userId, $achievementCondition->task_id); if (!$userTask || $userTask->status !== TASK_STATUS::IN_PROGRESS->value) { continue; } // 检查条件参数是否匹配 $conditionParams = $achievementCondition->condition_params ?? []; if (!$handler->isMatch($params, $conditionParams)) { Log::info('跳过任务:条件参数不匹配', [ 'event_params' => $params, 'condition_params' => $conditionParams ]); continue; } // 计算实际的进度增量 $actualIncrement = $handler->calculateProgress($params, $conditionParams); Log::info('计算进度增量', [ 'actual_increment' => $actualIncrement, 'params' => $params, 'condition_params' => $conditionParams ]); if ($actualIncrement <= 0) { Log::info('跳过任务:进度增量为0或负数'); continue; } // 获取用户任务进度 $userProgress = $this->userProgressRepository->getUserProgress($userId, $achievementCondition->id); Log::info('获取用户任务进度', [ 'user_progress_exists' => $userProgress ? 'yes' : 'no', 'achievement_condition_id' => $achievementCondition->id ]); // 如果进度记录不存在,创建新记录 if (!$userProgress) { Log::info('创建新的进度记录', [ 'user_id' => $userId, 'task_id' => $achievementCondition->task_id, 'achievement_condition_id' => $achievementCondition->id, 'target_value' => $achievementCondition->target_value ]); $userProgress = $this->userProgressRepository->createUserProgress([ 'user_id' => $userId, 'task_id' => $achievementCondition->task_id, 'achievement_condition_id' => $achievementCondition->id, 'current_value' => 0, 'target_value' => $achievementCondition->target_value, ]); Log::info('进度记录创建结果', [ 'created_progress_id' => $userProgress ? $userProgress->id : 'null' ]); } // 更新进度值 $oldValue = $userProgress->current_value; $newValue = $oldValue + $actualIncrement; if ($newValue > $userProgress->target_value) { $newValue = $userProgress->target_value; } Log::info('更新进度值', [ 'old_value' => $oldValue, 'increment' => $actualIncrement, 'new_value' => $newValue, 'target_value' => $userProgress->target_value ]); $userProgress->current_value = $newValue; $saveResult = $userProgress->save(); Log::info('保存进度结果', [ 'save_result' => $saveResult, 'final_current_value' => $userProgress->current_value ]); // 计算任务总进度 $progressResult = $this->calculateTaskTotalProgress($userId, $achievementCondition->task_id); // 检查任务是否完成,如果是自动任务则自动处理 if ($progressResult['success'] && $progressResult['progress'] >= 100) { $this->handleAutoTaskCompletion($userId, $achievementCondition->task_id); } $taskProgress = min(100, round($newValue / $userProgress->target_value * 100)); // 记录任务进度更新到暂存系统 $task = $userTask->task; TaskTempService::recordTaskProgressUpdate( $userId, $achievementCondition->task_id, $task->name ?? '未知任务', $progressResult['progress'] ?? $taskProgress, [ 'condition_id' => $achievementCondition->id, 'condition_name' => $condition->name ?? '未知条件', 'current_value' => $newValue, 'target_value' => $userProgress->target_value, 'increment' => $actualIncrement, ] ); $updatedTasks[] = [ 'task_id' => $achievementCondition->task_id, 'condition_id' => $achievementCondition->id, 'current_value' => $newValue, 'target_value' => $userProgress->target_value, 'progress' => $taskProgress, ]; } return [ 'success' => true, 'message' => '任务进度更新成功', 'updated_tasks' => $updatedTasks, ]; } catch (\Exception $e) { Log::error('更新任务进度失败', [ 'user_id' => $userId, 'condition_code' => $conditionCode, 'params' => $params, 'increment' => $increment, 'error' => $e->getMessage(), ]); return [ 'success' => false, 'message' => '更新任务进度失败: ' . $e->getMessage(), ]; } } /** * 计算任务总进度 * * @param int $userId 用户ID * @param int $taskId 任务ID * @return array 计算结果 */ public function calculateTaskTotalProgress(int $userId, int $taskId): array { try { // 获取用户任务 $userTask = $this->userTaskRepository->getUserTask($userId, $taskId); if (!$userTask || $userTask->status !== TASK_STATUS::IN_PROGRESS->value) { throw new \Exception('任务不存在或状态不正确'); } // 获取任务的进度条件 $progressConditions = $this->getTaskConditions($taskId, 'progress'); if (empty($progressConditions)) { throw new \Exception('任务没有进度条件'); } // 计算总进度 $totalProgress = 0; $completedConditions = 0; foreach ($progressConditions as $condition) { // 获取用户任务进度 $userProgress = $this->userProgressRepository->getUserProgress($userId, $condition['id']); if (!$userProgress) { continue; } // 计算条件进度百分比 $conditionProgress = min(100, round($userProgress->current_value / $userProgress->target_value * 100)); // 如果条件是必要条件,累加进度 if ($condition['is_required']) { $totalProgress += $conditionProgress; } // 如果条件已完成,增加完成条件计数 if ($conditionProgress >= 100) { $completedConditions++; } } // 计算平均进度 $requiredConditions = array_filter($progressConditions, function ($condition) { return $condition['is_required']; }); $requiredCount = count($requiredConditions); if ($requiredCount > 0) { $totalProgress = round($totalProgress / $requiredCount); } else { $totalProgress = 0; } // 更新用户任务进度 $userTask->progress = $totalProgress; $userTask->save(); return [ 'success' => true, 'message' => '任务总进度计算成功', 'progress' => $totalProgress, 'completed_conditions' => $completedConditions, 'total_conditions' => count($progressConditions), ]; } catch (\Exception $e) { Log::error('计算任务总进度失败', [ 'user_id' => $userId, 'task_id' => $taskId, 'error' => $e->getMessage(), ]); return [ 'success' => false, 'message' => '计算任务总进度失败: ' . $e->getMessage(), ]; } } /** * 重置任务进度 * * @param int $userId 用户ID * @param int $taskId 任务ID * @return array 重置结果 */ public function resetTaskProgress(int $userId, int $taskId): array { try { // 获取用户任务 $userTask = $this->userTaskRepository->getUserTask($userId, $taskId); if (!$userTask) { throw new \Exception('任务不存在'); } // 获取任务的进度条件 $progressConditions = $this->getTaskConditions($taskId, 'progress'); // 重置每个条件的进度 foreach ($progressConditions as $condition) { $userProgress = $this->userProgressRepository->getUserProgress($userId, $condition['id']); if ($userProgress) { $userProgress->current_value = 0; $userProgress->save(); } } // 重置用户任务进度 $userTask->progress = 0; $userTask->status = TASK_STATUS::IN_PROGRESS->value; $userTask->completed_at = null; $userTask->rewarded_at = null; $userTask->save(); return [ 'success' => true, 'message' => '任务进度重置成功', ]; } catch (\Exception $e) { Log::error('重置任务进度失败', [ 'user_id' => $userId, 'task_id' => $taskId, 'error' => $e->getMessage(), ]); return [ 'success' => false, 'message' => '重置任务进度失败: ' . $e->getMessage(), ]; } } /** * 处理自动任务完成 * * @param int $userId 用户ID * @param int $taskId 任务ID * @return void */ protected function handleAutoTaskCompletion(int $userId, int $taskId): void { try { // 获取任务信息 $task = Task::find($taskId); if (!$task) { return; } // 检查是否是自动完成任务(使用新的auto_complete字段) if (!$task->auto_complete) { return; } // 获取用户任务 $userTask = $this->userTaskRepository->getUserTask($userId, $taskId); if (!$userTask || $userTask->status !== TASK_STATUS::IN_PROGRESS->value) { return; } // 自动完成任务 $this->autoCompleteTask($userId, $taskId, $task, $userTask); } catch (\Exception $e) { Log::error('处理自动任务完成失败', [ 'user_id' => $userId, 'task_id' => $taskId, 'error' => $e->getMessage() ]); } } /** * 自动完成任务 * * @param int $userId 用户ID * @param int $taskId 任务ID * @param mixed $task 任务对象 * @param mixed $userTask 用户任务对象 * @return void */ protected function autoCompleteTask(int $userId, int $taskId, $task, $userTask): void { try { // 检查事务状态,确保调用者已开启事务 \UCore\Db\Helper::check_tr(); // 标记任务为已完成 $userTask->status = TASK_STATUS::COMPLETED->value; $userTask->completed_at = Carbon::now(); $userTask->save(); Log::info('自动完成任务', [ 'user_id' => $userId, 'task_id' => $taskId, 'task_name' => $task->name ]); // 检查是否自动发放奖励(使用新的auto_reward字段) if ($task->auto_reward) { $this->autoClaimReward($userId, $taskId, $task, $userTask); } // 检查是否需要自动重置(循环任务) if ($task->auto_reset && $task->reset_type === 'immediate' && $task->max_completions === -1) { $this->autoResetTask($userId, $taskId, $task); } } catch (\Exception $e) { Log::error('自动完成任务失败', [ 'user_id' => $userId, 'task_id' => $taskId, 'error' => $e->getMessage() ]); } } /** * 自动领取奖励 * * @param int $userId 用户ID * @param int $taskId 任务ID * @param mixed $task 任务对象 * @param mixed $userTask 用户任务对象 * @return void */ protected function autoClaimReward(int $userId, int $taskId, $task, $userTask): void { try { // 检查任务是否有奖励组 if (!$task->reward_group_id) { return; } // 使用奖励组服务发放奖励 $result = TaskRewardGroupService::distributeRewards( $userId, $taskId, $userTask->id ); if ($result['success']) { // 更新任务状态为已领取奖励 $userTask->status = TASK_STATUS::REWARDED->value; $userTask->rewarded_at = Carbon::now(); $userTask->save(); Log::info('自动领取任务奖励成功', [ 'user_id' => $userId, 'task_id' => $taskId, 'task_name' => $task->name, 'rewards' => $result['rewards'] ?? [] ]); } else { Log::error('自动领取任务奖励失败', [ 'user_id' => $userId, 'task_id' => $taskId, 'error' => $result['message'] ?? '未知错误' ]); } } catch (\Exception $e) { Log::error('自动领取奖励异常', [ 'user_id' => $userId, 'task_id' => $taskId, 'error' => $e->getMessage() ]); } } /** * 自动重置任务(循环任务) * * @param int $userId 用户ID * @param int $taskId 任务ID * @param mixed $task 任务对象 * @return void */ protected function autoResetTask(int $userId, int $taskId, $task): void { try { // 重置任务进度 $resetResult = $this->resetTaskProgress($userId, $taskId); if ($resetResult['success']) { Log::info('自动重置循环任务成功', [ 'user_id' => $userId, 'task_id' => $taskId, 'task_name' => $task->name ]); } else { Log::error('自动重置循环任务失败', [ 'user_id' => $userId, 'task_id' => $taskId, 'error' => $resetResult['message'] ]); } } catch (\Exception $e) { Log::error('自动重置任务异常', [ 'user_id' => $userId, 'task_id' => $taskId, 'error' => $e->getMessage() ]); } } /** * 自动接取任务 * * @param int $userId 用户ID * @param int $taskId 任务ID * @return bool 是否成功接取 */ public function autoAcceptTask(int $userId, int $taskId): bool { try { // 获取任务信息 $task = Task::find($taskId); if (!$task || !$task->is_active) { return false; } // 检查是否是自动接取任务(使用新的auto_accept字段) if (!$task->auto_accept) { return false; } // 检查用户是否已接取该任务 $userTask = $this->userTaskRepository->getUserTask($userId, $taskId); if ($userTask) { return true; // 已接取 } // 创建用户任务记录 $userTask = TaskUserTask::create([ 'user_id' => $userId, 'task_id' => $taskId, 'status' => TASK_STATUS::IN_PROGRESS->value, 'progress' => 0, 'accepted_at' => Carbon::now(), ]); Log::info('自动接取任务成功', [ 'user_id' => $userId, 'task_id' => $taskId, 'task_name' => $task->name ]); return true; } catch (\Exception $e) { Log::error('自动接取任务失败', [ 'user_id' => $userId, 'task_id' => $taskId, 'error' => $e->getMessage() ]); return false; } } /** * 自动接取所有符合条件的自动任务 * * @param int $userId 用户ID * @return void */ public function autoAcceptAllEligibleTasks(int $userId): void { try { // 获取所有配置了自动接取的激活任务 $autoAcceptTasks = Task::where('is_active', 1) ->where('auto_accept', 1) ->get(); foreach ($autoAcceptTasks as $task) { // 检查用户是否已接取该任务 $userTask = $this->userTaskRepository->getUserTask($userId, $task->id); if ($userTask) { continue; // 已接取,跳过 } // 尝试自动接取任务 $this->autoAcceptTask($userId, $task->id); } } catch (\Exception $e) { Log::error('自动接取所有符合条件的任务失败', [ 'user_id' => $userId, 'error' => $e->getMessage() ]); } } }