| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639 |
- <?php
- namespace App\Module\Task\Services;
- use App\Module\Task\Enums\TASK_STATUS;
- use App\Module\Task\Enums\TASK_TYPE;
- use App\Module\Task\Events\TaskCompletedEvent;
- use App\Module\Task\Events\TaskRewardClaimedEvent;
- use App\Module\Task\Models\Task;
- use App\Module\Task\Models\TaskReward;
- use App\Module\Task\Models\TaskUserTask;
- use App\Module\Task\Repositorys\TaskRepository;
- use App\Module\Task\Repositorys\TaskRewardRepository;
- use App\Module\Task\Repositorys\TaskUserTaskRepository;
- use Carbon\Carbon;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- /**
- * 任务服务类
- *
- * 提供任务相关的核心服务,包括任务查询、接取、完成、奖励领取等功能。
- * 该类是任务模块对外提供服务的主要入口。
- */
- class TaskService
- {
- /**
- * 任务数据仓库
- *
- * @var TaskRepository
- */
- protected $taskRepository;
-
- /**
- * 用户任务数据仓库
- *
- * @var TaskUserTaskRepository
- */
- protected $userTaskRepository;
-
- /**
- * 任务奖励数据仓库
- *
- * @var TaskRewardRepository
- */
- protected $rewardRepository;
-
- /**
- * 构造函数
- *
- * @param TaskRepository $taskRepository
- * @param TaskUserTaskRepository $userTaskRepository
- * @param TaskRewardRepository $rewardRepository
- */
- public function __construct(
- TaskRepository $taskRepository,
- TaskUserTaskRepository $userTaskRepository,
- TaskRewardRepository $rewardRepository
- ) {
- $this->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,
- ];
- }
- }
|