taskRepository = $taskRepository; $this->userTaskRepository = $userTaskRepository; $this->rewardRepository = $rewardRepository; } /** * 获取用户可用的任务列表 * * @param int $userId 用户ID * @param string|null $type 任务类型(可选) * @param int|null $categoryId 任务分类ID(可选) * @param bool $includeCompleted 是否包含已完成的任务 * @return array 任务列表 */ public function getAvailableTasks(int $userId, ?string $type = null, ?int $categoryId = null, bool $includeCompleted = false): array { // 获取用户信息(可以调用用户模块的服务) // $userInfo = UserService::getUserInfo($userId); // 获取用户等级 $userLevel = 1; // 默认等级,实际应从用户信息中获取 // 获取符合条件的任务 $tasks = $this->taskRepository->getAvailableTasks($type, $categoryId, $userLevel); // 获取用户任务状态 $userTasks = $this->userTaskRepository->getUserTasks($userId); // 将用户任务状态合并到任务数据中 $result = []; foreach ($tasks as $task) { $userTask = $userTasks->where('task_id', $task['id'])->first(); // 如果任务已完成且不包含已完成任务,则跳过 if ($userTask && $userTask['status'] >= TASK_STATUS::COMPLETED->value && !$includeCompleted) { continue; } // 合并任务数据和用户任务状态 $taskData = $task; $taskData['user_status'] = $userTask ? $userTask['status'] : TASK_STATUS::NOT_ACCEPTED->value; $taskData['progress'] = $userTask ? $userTask['progress'] : 0; $taskData['completed_at'] = $userTask && $userTask['completed_at'] ? $userTask['completed_at'] : null; $taskData['rewarded_at'] = $userTask && $userTask['rewarded_at'] ? $userTask['rewarded_at'] : null; // 获取任务奖励 $taskData['rewards'] = $this->rewardRepository->getRewardsByTaskId($task['id']); $result[] = $taskData; } return $result; } /** * 接取任务 * * @param int $userId 用户ID * @param int $taskId 任务ID * @return array 接取结果 */ public function acceptTask(int $userId, int $taskId): array { try { // 开始事务 DB::beginTransaction(); // 获取任务信息 $task = $this->taskRepository->find($taskId); if (!$task || !$task->is_active) { throw new \Exception('任务不存在或未激活'); } // 检查任务是否已过期 if ($task->end_time && Carbon::now()->greaterThan($task->end_time)) { throw new \Exception('任务已过期'); } // 检查用户是否已接取该任务 $userTask = $this->userTaskRepository->getUserTask($userId, $taskId); if ($userTask) { throw new \Exception('已接取该任务'); } // 检查任务前置条件 // $this->checkTaskPrerequisites($userId, $task); // 检查任务接取消耗 // $this->checkAndConsumeTaskCosts($userId, $task); // 创建用户任务记录 $userTask = $this->userTaskRepository->createUserTask([ 'user_id' => $userId, 'task_id' => $taskId, 'status' => TASK_STATUS::IN_PROGRESS->value, 'progress' => 0, 'accepted_at' => Carbon::now(), ]); // 提交事务 DB::commit(); return [ 'success' => true, 'message' => '任务接取成功', 'user_task' => $userTask, ]; } catch (\Exception $e) { // 回滚事务 DB::rollBack(); 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 completeTask(int $userId, int $taskId): array { try { // 开始事务 DB::beginTransaction(); // 获取用户任务 $userTask = $this->userTaskRepository->getUserTask($userId, $taskId); if (!$userTask) { throw new \Exception('未接取该任务'); } // 检查任务状态 if ($userTask->status !== TASK_STATUS::IN_PROGRESS->value) { throw new \Exception('任务状态不正确'); } // 检查任务进度 if ($userTask->progress < 100) { throw new \Exception('任务进度未达到100%'); } // 更新任务状态 $userTask->status = TASK_STATUS::COMPLETED->value; $userTask->completed_at = Carbon::now(); $userTask->save(); // 获取任务信息 $task = $this->taskRepository->find($taskId); // 触发任务完成事件 event(new TaskCompletedEvent( $userId, $taskId, $task->name, $userTask->completed_at )); // 提交事务 DB::commit(); return [ 'success' => true, 'message' => '任务完成成功', 'user_task' => $userTask, ]; } catch (\Exception $e) { // 回滚事务 DB::rollBack(); 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 claimTaskReward(int $userId, int $taskId): array { try { // 开始事务 DB::beginTransaction(); // 获取用户任务 $userTask = $this->userTaskRepository->getUserTask($userId, $taskId); if (!$userTask) { throw new \Exception('未接取该任务'); } // 检查任务状态 if ($userTask->status !== TASK_STATUS::COMPLETED->value) { throw new \Exception('任务未完成,无法领取奖励'); } // 获取任务信息 $task = $this->taskRepository->find($taskId); // 获取任务奖励 $rewards = $this->rewardRepository->getRewardsByTaskId($taskId); // 发放奖励 $rewardResults = $this->distributeRewards($userId, $rewards); // 更新任务状态 $userTask->status = TASK_STATUS::REWARDED->value; $userTask->rewarded_at = Carbon::now(); $userTask->save(); // 记录奖励领取日志 // $this->recordRewardLog($userId, $taskId, $userTask->id, $rewards); // 触发奖励领取事件 event(new TaskRewardClaimedEvent( $userId, $taskId, $task->name, $rewards, $userTask->rewarded_at, true )); // 提交事务 DB::commit(); return [ 'success' => true, 'message' => '奖励领取成功', 'rewards' => $rewardResults, ]; } catch (\Exception $e) { // 回滚事务 DB::rollBack(); Log::error('奖励领取失败', [ 'user_id' => $userId, 'task_id' => $taskId, 'error' => $e->getMessage(), ]); // 触发奖励领取失败事件 event(new TaskRewardClaimedEvent( $userId, $taskId, $task->name ?? '未知任务', [], Carbon::now(), false )); return [ 'success' => false, 'message' => $e->getMessage(), ]; } } /** * 发放奖励 * * @param int $userId 用户ID * @param array $rewards 奖励列表 * @return array 发放结果 */ protected function distributeRewards(int $userId, array $rewards): array { $results = []; foreach ($rewards as $reward) { try { switch ($reward['reward_type']) { case 'item': // 调用物品模块服务添加物品 // $itemResult = ItemService::addItem( // $userId, // $reward['reward_param2'], // $reward['quantity'], // [ // 'source_type' => 'task_reward', // 'source_id' => $reward['task_id'], // ] // ); // 模拟物品发放结果 $itemResult = [ 'success' => true, 'message' => '物品发放成功', ]; $results[] = [ 'type' => 'item', 'param1' => $reward['reward_param1'], 'param2' => $reward['reward_param2'], 'quantity' => $reward['quantity'], 'success' => $itemResult['success'], 'message' => $itemResult['message'] ?? '', ]; break; case 'currency': // 调用货币模块服务添加货币 // $currencyResult = CurrencyService::addCurrency( // $userId, // $reward['reward_param1'], // $reward['reward_param2'], // $reward['quantity'], // [ // 'source_type' => 'task_reward', // 'source_id' => $reward['task_id'], // ] // ); // 模拟货币发放结果 $currencyResult = [ 'success' => true, 'message' => '货币发放成功', ]; $results[] = [ 'type' => 'currency', 'param1' => $reward['reward_param1'], 'param2' => $reward['reward_param2'], 'quantity' => $reward['quantity'], 'success' => $currencyResult['success'], 'message' => $currencyResult['message'] ?? '', ]; break; case 'experience': // 调用经验模块服务添加经验 // $expResult = ExperienceService::addExperience( // $userId, // $reward['reward_param1'], // $reward['quantity'], // [ // 'source_type' => 'task_reward', // 'source_id' => $reward['task_id'], // ] // ); // 模拟经验发放结果 $expResult = [ 'success' => true, 'message' => '经验发放成功', ]; $results[] = [ 'type' => 'experience', 'param1' => $reward['reward_param1'], 'param2' => $reward['reward_param2'], 'quantity' => $reward['quantity'], 'success' => $expResult['success'], 'message' => $expResult['message'] ?? '', ]; break; // 其他奖励类型... default: $results[] = [ 'type' => $reward['reward_type'], 'param1' => $reward['reward_param1'], 'param2' => $reward['reward_param2'], 'quantity' => $reward['quantity'], 'success' => false, 'message' => '未知的奖励类型', ]; break; } } catch (\Exception $e) { Log::error('奖励发放失败', [ 'user_id' => $userId, 'reward' => $reward, 'error' => $e->getMessage(), ]); $results[] = [ 'type' => $reward['reward_type'], 'param1' => $reward['reward_param1'], 'param2' => $reward['reward_param2'], 'quantity' => $reward['quantity'], 'success' => false, 'message' => $e->getMessage(), ]; } } return $results; } /** * 获取任务详情 * * @param int $userId 用户ID * @param int $taskId 任务ID * @return array 任务详情 */ public function getTaskDetail(int $userId, int $taskId): array { // 获取任务信息 $task = $this->taskRepository->find($taskId); if (!$task) { return [ 'success' => false, 'message' => '任务不存在', ]; } // 获取用户任务状态 $userTask = $this->userTaskRepository->getUserTask($userId, $taskId); // 获取任务奖励 $rewards = $this->rewardRepository->getRewardsByTaskId($taskId); // 构建任务详情 $taskDetail = $task->toArray(); $taskDetail['user_status'] = $userTask ? $userTask->status : TASK_STATUS::NOT_ACCEPTED->value; $taskDetail['progress'] = $userTask ? $userTask->progress : 0; $taskDetail['completed_at'] = $userTask && $userTask->completed_at ? $userTask->completed_at : null; $taskDetail['rewarded_at'] = $userTask && $userTask->rewarded_at ? $userTask->rewarded_at : null; $taskDetail['rewards'] = $rewards; return [ 'success' => true, 'task' => $taskDetail, ]; } /** * 放弃任务 * * @param int $userId 用户ID * @param int $taskId 任务ID * @return array 放弃结果 */ public function abandonTask(int $userId, int $taskId): array { try { // 获取用户任务 $userTask = $this->userTaskRepository->getUserTask($userId, $taskId); if (!$userTask) { throw new \Exception('未接取该任务'); } // 检查任务状态 if ($userTask->status !== TASK_STATUS::IN_PROGRESS->value) { throw new \Exception('只能放弃进行中的任务'); } // 删除用户任务记录 $userTask->delete(); 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 * @param int $progress 进度值(0-100) * @return array 更新结果 */ public function updateTaskProgress(int $userId, int $taskId, int $progress): array { try { // 获取用户任务 $userTask = $this->userTaskRepository->getUserTask($userId, $taskId); if (!$userTask) { throw new \Exception('未接取该任务'); } // 检查任务状态 if ($userTask->status !== TASK_STATUS::IN_PROGRESS->value) { throw new \Exception('只能更新进行中的任务进度'); } // 验证进度值 if ($progress < 0 || $progress > 100) { throw new \Exception('进度值必须在0-100之间'); } // 更新任务进度 $userTask->progress = $progress; $userTask->save(); // 如果进度达到100%,自动完成任务 if ($progress === 100) { return $this->completeTask($userId, $taskId); } return [ 'success' => true, 'message' => '任务进度更新成功', 'progress' => $progress, ]; } catch (\Exception $e) { Log::error('任务进度更新失败', [ 'user_id' => $userId, 'task_id' => $taskId, 'progress' => $progress, 'error' => $e->getMessage(), ]); return [ 'success' => false, 'message' => $e->getMessage(), ]; } } /** * 批量领取任务奖励 * * @param int $userId 用户ID * @param array $taskIds 任务ID列表 * @return array 领取结果 */ public function batchClaimTaskRewards(int $userId, array $taskIds): array { $results = []; $successCount = 0; $failCount = 0; foreach ($taskIds as $taskId) { $result = $this->claimTaskReward($userId, $taskId); $results[$taskId] = $result; if ($result['success']) { $successCount++; } else { $failCount++; } } return [ 'success' => $failCount === 0, 'message' => "成功领取{$successCount}个任务奖励,失败{$failCount}个", 'results' => $results, ]; } }