| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- <?php
- namespace App\Module\Task\Services;
- use App\Module\Task\Enums\TASK_STATUS;
- use App\Module\Task\Events\TaskCompletedEvent;
- use App\Module\Task\Logics\TaskLogic;
- use App\Module\Task\Repositorys\TaskRepository;
- 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 TaskLogic
- */
- protected $taskLogic;
- /**
- * 构造函数
- *
- * @param TaskRepository $taskRepository
- * @param TaskUserTaskRepository $userTaskRepository
- * @param TaskLogic $taskLogic
- */
- public function __construct(
- TaskRepository $taskRepository,
- TaskUserTaskRepository $userTaskRepository,
- TaskLogic $taskLogic
- ) {
- $this->taskRepository = $taskRepository;
- $this->userTaskRepository = $userTaskRepository;
- $this->taskLogic = $taskLogic;
- }
- /**
- * 获取用户可用的任务列表
- *
- * @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->taskLogic->getTaskRewardInfo($task['id'])['rewards'];
- $result[] = $taskData;
- }
- return $result;
- }
- /**
- * 接取任务
- *
- * @param int $userId 用户ID
- * @param int $taskId 任务ID
- * @return \UCore\Dto\Res 接取结果
- */
- public function acceptTask(int $userId, int $taskId): \UCore\Dto\Res
- {
- 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 \UCore\Dto\Res::success('任务接取成功', [
- 'user_task' => $userTask,
- ]);
- } catch (\Exception $e) {
- // 回滚事务
- DB::rollBack();
- Log::error('任务接取失败', [
- 'user_id' => $userId,
- 'task_id' => $taskId,
- 'error' => $e->getMessage(),
- ]);
- return \UCore\Dto\Res::error($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,
- true,
- []
- ));
- // 提交事务
- 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 \UCore\Dto\Res 领取结果
- */
- public function claimTaskReward(int $userId, int $taskId): \UCore\Dto\Res
- {
- return $this->taskLogic->claimTaskReward($userId, $taskId);
- }
- /**
- * 获取任务奖励信息
- *
- * @param int $taskId 任务ID
- * @return \UCore\Dto\Res 奖励信息
- */
- public function getTaskRewardInfo(int $taskId): \UCore\Dto\Res
- {
- return $this->taskLogic->getTaskRewardInfo($taskId);
- }
- /**
- * 迁移任务奖励到奖励组
- *
- * @param int $taskId 任务ID
- * @return array 迁移结果
- */
- public function migrateTaskReward(int $taskId): array
- {
- return $this->taskLogic->migrateTaskReward($taskId);
- }
- /**
- * 获取任务详情
- *
- * @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->taskLogic->getTaskRewardInfo($taskId)['rewards'];
- // 构建任务详情
- $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,
- ];
- }
- }
|