| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733 |
- <?php
- namespace App\Module\Task\Services;
- use App\Module\Task\Enums\TASK_STATUS;
- use App\Module\Task\Models\Task;
- use App\Module\Task\Models\TaskUserTask;
- use App\Module\Task\Repositorys\TaskAchievementConditionRepository;
- use App\Module\Task\Repositorys\TaskConditionRepository;
- use App\Module\Task\Repositorys\TaskUserProgressRepository;
- use App\Module\Task\Repositorys\TaskUserTaskRepository;
- use App\Module\Task\Services\TaskRewardGroupService;
- use App\Module\Game\Services\TaskTempService;
- use Illuminate\Support\Carbon;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- /**
- * 任务条件服务类
- *
- * 提供任务条件相关的服务,包括条件验证、进度更新等功能。
- * 该类主要处理任务条件的逻辑,与TaskProgressService配合使用。
- */
- class TaskConditionService
- {
- /**
- * 任务条件数据仓库
- *
- * @var TaskConditionRepository
- */
- protected $conditionRepository;
-
- /**
- * 任务达成条件数据仓库
- *
- * @var TaskAchievementConditionRepository
- */
- protected $achievementConditionRepository;
-
- /**
- * 用户任务数据仓库
- *
- * @var TaskUserTaskRepository
- */
- protected $userTaskRepository;
-
- /**
- * 用户任务进度数据仓库
- *
- * @var TaskUserProgressRepository
- */
- protected $userProgressRepository;
- /**
- * 构造函数
- *
- * @param TaskConditionRepository $conditionRepository
- * @param TaskAchievementConditionRepository $achievementConditionRepository
- * @param TaskUserTaskRepository $userTaskRepository
- * @param TaskUserProgressRepository $userProgressRepository
- */
- public function __construct(
- TaskConditionRepository $conditionRepository,
- TaskAchievementConditionRepository $achievementConditionRepository,
- TaskUserTaskRepository $userTaskRepository,
- TaskUserProgressRepository $userProgressRepository
- ) {
- $this->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;
- }
- // 检查是否是自动任务
- $displayParams = $task->display_params ?? [];
- if (!isset($displayParams['auto_complete']) || !$displayParams['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 {
- DB::beginTransaction();
- // 标记任务为已完成
- $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
- ]);
- // 检查是否自动发放奖励
- $displayParams = $task->display_params ?? [];
- if (isset($displayParams['auto_reward']) && $displayParams['auto_reward']) {
- $this->autoClaimReward($userId, $taskId, $task, $userTask);
- }
- // 检查是否需要自动重置(循环任务)
- if ($task->reset_type === 'immediate' && $task->max_completions === -1) {
- $this->autoResetTask($userId, $taskId, $task);
- }
- DB::commit();
- } catch (\Exception $e) {
- DB::rollBack();
- 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;
- }
- // 检查是否是自动接取任务
- $displayParams = $task->display_params ?? [];
- if (!isset($displayParams['auto_accept']) || !$displayParams['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;
- }
- }
- }
|