info('开始清理过期任务...'); // 获取命令选项 $userId = $this->option('user-id'); $taskId = $this->option('task-id'); $days = $this->option('days'); $batchSize = $this->option('batch-size'); $dryRun = $this->option('dry-run'); // 清理已过期的任务(任务的结束时间已过) $this->cleanExpiredByEndTime($userId, $taskId, $days, $batchSize, $dryRun); // 清理已超时的任务(任务的时间限制已过) $this->cleanExpiredByTimeLimit($userId, $taskId, $days, $batchSize, $dryRun); $this->info('过期任务清理完成'); return 0; } /** * 清理已过期的任务(任务的结束时间已过) * * @param int|null $userId 用户ID * @param int|null $taskId 任务ID * @param int $days 天数 * @param int $batchSize 批处理大小 * @param bool $dryRun 是否仅检查 * @return void */ protected function cleanExpiredByEndTime(?int $userId, ?int $taskId, int $days, int $batchSize, bool $dryRun): void { $this->info('清理已过期的任务(任务的结束时间已过)...'); // 获取已过期的任务 $expiredTasks = Task::where('end_time', '<', Carbon::now()->subDays($days)) ->where('is_active', true) ->get(); if ($expiredTasks->isEmpty()) { $this->info('没有找到已过期的任务'); return; } $this->info("找到 {$expiredTasks->count()} 个已过期的任务"); if ($dryRun) { $this->warn('仅检查模式,不执行实际操作'); return; } // 创建进度条 $bar = $this->output->createProgressBar($expiredTasks->count()); $bar->start(); // 处理每个过期任务 foreach ($expiredTasks as $task) { try { // 构建查询 $query = TaskUserTask::query() ->where('task_id', $task->id) ->whereIn('status', [TASK_STATUS::NOT_ACCEPTED->value, TASK_STATUS::IN_PROGRESS->value]); // 应用过滤条件 if ($userId) { $query->where('user_id', $userId); } // 分批处理 $query->chunk($batchSize, function ($userTasks) use ($task) { foreach ($userTasks as $userTask) { DB::beginTransaction(); try { // 记录日志 Log::info('清理过期任务', [ 'user_id' => $userTask->user_id, 'task_id' => $userTask->task_id, 'reason' => '任务结束时间已过', 'end_time' => $task->end_time, ]); // 删除用户任务 $userTask->delete(); DB::commit(); } catch (\Exception $e) { DB::rollBack(); Log::error('清理过期任务失败', [ 'user_id' => $userTask->user_id, 'task_id' => $userTask->task_id, 'error' => $e->getMessage(), ]); } } }); // 更新任务状态 $task->is_active = false; $task->save(); } catch (\Exception $e) { $this->error("处理任务异常: 任务ID={$task->id}, 错误: {$e->getMessage()}"); } $bar->advance(); } $bar->finish(); $this->newLine(2); } /** * 清理已超时的任务(任务的时间限制已过) * * @param int|null $userId 用户ID * @param int|null $taskId 任务ID * @param int $days 天数 * @param int $batchSize 批处理大小 * @param bool $dryRun 是否仅检查 * @return void */ protected function cleanExpiredByTimeLimit(?int $userId, ?int $taskId, int $days, int $batchSize, bool $dryRun): void { $this->info('清理已超时的任务(任务的时间限制已过)...'); // 构建查询 $query = TaskUserTask::query() ->where('status', TASK_STATUS::IN_PROGRESS->value) ->where('accepted_at', '<', Carbon::now()->subDays($days)) ->whereHas('task', function ($query) { $query->whereNotNull('time_limit'); }); // 应用过滤条件 if ($userId) { $query->where('user_id', $userId); } if ($taskId) { $query->where('task_id', $taskId); } // 获取符合条件的任务数量 $totalTasks = $query->count(); if ($totalTasks === 0) { $this->info('没有找到已超时的任务'); return; } $this->info("找到 {$totalTasks} 个已超时的任务"); if ($dryRun) { $this->warn('仅检查模式,不执行实际操作'); return; } // 创建进度条 $bar = $this->output->createProgressBar($totalTasks); $bar->start(); // 分批处理 $query->with('task')->chunk($batchSize, function ($userTasks) use ($bar) { foreach ($userTasks as $userTask) { DB::beginTransaction(); try { // 计算任务是否超时 $acceptedAt = $userTask->accepted_at; $timeLimit = $userTask->task->time_limit; $expireAt = $acceptedAt->addSeconds($timeLimit); if (Carbon::now()->greaterThan($expireAt)) { // 记录日志 Log::info('清理超时任务', [ 'user_id' => $userTask->user_id, 'task_id' => $userTask->task_id, 'reason' => '任务时间限制已过', 'accepted_at' => $acceptedAt, 'time_limit' => $timeLimit, 'expire_at' => $expireAt, ]); // 删除用户任务 $userTask->delete(); } DB::commit(); } catch (\Exception $e) { DB::rollBack(); Log::error('清理超时任务失败', [ 'user_id' => $userTask->user_id, 'task_id' => $userTask->task_id, 'error' => $e->getMessage(), ]); $this->error("处理任务异常: 用户ID={$userTask->user_id}, 任务ID={$userTask->task_id}, 错误: {$e->getMessage()}"); } $bar->advance(); } }); $bar->finish(); $this->newLine(2); } }