| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- <?php
- namespace App\Module\Task\Services;
- use App\Module\Task\Enums\TASK_STATUS;
- use App\Module\Task\Models\TaskAchievementCondition;
- use App\Module\Task\Models\TaskCondition;
- 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 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 (!class_exists($handlerClass)) {
- throw new \Exception('条件处理器类不存在');
- }
-
- // 实例化条件处理器
- $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;
- }
-
- // 检查条件参数是否匹配
- if (!$handler->isMatch($params, $achievementCondition->condition_params)) {
- continue;
- }
-
- // 获取用户任务进度
- $userProgress = $this->userProgressRepository->getUserProgress($userId, $achievementCondition->id);
-
- // 如果进度记录不存在,创建新记录
- if (!$userProgress) {
- $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,
- ]);
- }
-
- // 更新进度值
- $newValue = $userProgress->current_value + $increment;
- if ($newValue > $userProgress->target_value) {
- $newValue = $userProgress->target_value;
- }
-
- $userProgress->current_value = $newValue;
- $userProgress->save();
-
- // 计算任务总进度
- $this->calculateTaskTotalProgress($userId, $achievementCondition->task_id);
-
- $updatedTasks[] = [
- 'task_id' => $achievementCondition->task_id,
- 'condition_id' => $achievementCondition->id,
- 'current_value' => $newValue,
- 'target_value' => $userProgress->target_value,
- 'progress' => min(100, round($newValue / $userProgress->target_value * 100)),
- ];
- }
-
- 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(),
- ];
- }
- }
- }
|