deepSeekService = $deepSeekService; } /** * Execute the console command. * * @return int */ public function handle() { dLog('command')->info('开始执行批量生成分集任务...'); $anime_tasks = DB::table('mp_batch_episode_generation_details')->where('status', 'pending')->pluck('anime_id')->toArray(); foreach ($anime_tasks as $anime_id) { dLog('command')->info("~~~~~~开始执行($anime_id)任务~~~~~~"); try { // 查找状态为 pending 的任务,按 anime_id 和 episode_number 排序 $task = DB::table('mp_batch_episode_generation_details') ->where('status', 'pending') ->orderBy('anime_id') ->orderBy('episode_number') ->first(); if (!$task) { dLog('command')->info('[' . date('Y-m-d H:i:s') . '] 没有待处理的任务'); return 0; } dLog('command')->info('[' . date('Y-m-d H:i:s') . '] 找到待处理任务 - Anime ID: ' . $task->anime_id . ', Episode: ' . $task->episode_number); // 检查前一集是否已完成(如果不是第1集) if ($task->episode_number > 1) { $prevEpisodeNumber = $task->episode_number - 1; // 检查前一集是否在批量任务中 $prevTaskInBatch = DB::table('mp_batch_episode_generation_details') ->where('anime_id', $task->anime_id) ->where('episode_number', $prevEpisodeNumber) ->first(); if ($prevTaskInBatch && $prevTaskInBatch->status !== 'completed') { dLog('command')->info('[' . date('Y-m-d H:i:s') . '] 前一集(第' . $prevEpisodeNumber . '集)尚未完成,跳过当前任务'); return 0; } // 检查前一集是否已在系统中生成(查询 mp_anime_episodes) $prevEpisodeExists = DB::table('mp_anime_episodes') ->where('anime_id', $task->anime_id) ->where('episode_number', $prevEpisodeNumber) ->where('is_default', 1) ->exists(); if (!$prevEpisodeExists) { dLog('command')->error('[' . date('Y-m-d H:i:s') . '] 前一集(第' . $prevEpisodeNumber . '集)不存在,无法继续生成'); // 标记为失败 DB::table('mp_batch_episode_generation_details') ->where('id', $task->id) ->update([ 'status' => 'failed', 'error_message' => "前一集(第{$prevEpisodeNumber}集)不存在,无法继续生成", 'updated_at' => now() ]); return 1; } } // 检查当前集是否已经存在(避免重复生成) $currentEpisodeExists = DB::table('mp_anime_episodes') ->where('anime_id', $task->anime_id) ->where('episode_number', $task->episode_number) ->where('is_default', 1) ->exists(); if ($currentEpisodeExists) { dLog('command')->info('[' . date('Y-m-d H:i:s') . '] 第' . $task->episode_number . '集已存在,跳过生成'); // 标记为已完成 DB::table('mp_batch_episode_generation_details') ->where('id', $task->id) ->update([ 'status' => 'completed', 'completed_at' => now(), 'updated_at' => now() ]); return 0; } // 标记为处理中 DB::table('mp_batch_episode_generation_details') ->where('id', $task->id) ->update([ 'status' => 'processing', 'updated_at' => now() ]); // 设置用户上下文(绑定到容器) app()->instance('siteData', [ 'uid' => $task->uid, 'cpid' => $task->cpid ]); // 解析请求数据 $requestData = json_decode($task->request_data, true); $requestData['episode_number'] = $task->episode_number; // 使用"继续策划下一集"逻辑 $requestData['prompt'] = '继续策划下一集'; dLog('command')->info('[' . date('Y-m-d H:i:s') . '] 开始生成第' . $task->episode_number . '集...'); // 调用非流式生成方法 $result = $this->deepSeekService->chatForAceNonStream($requestData); // 检查是否有错误 if (isset($result['error']) && $result['error']) { dLog('command')->error('[' . date('Y-m-d H:i:s') . '] 生成失败: ' . $result['error']); // 更新重试次数 $retryCount = $task->retry_count + 1; // 标记为失败 DB::table('mp_batch_episode_generation_details') ->where('id', $task->id) ->update([ 'status' => 'pending', 'error_message' => $result['error'], 'retry_count' => $retryCount, 'updated_at' => now() ]); // 记录错误日志 logDB('batch_episode_generation', 'error', "第{$task->episode_number}集生成失败", [ 'anime_id' => $task->anime_id, 'episode_number' => $task->episode_number, 'error' => $result['error'] ]); return 1; } // 标记为完成 DB::table('mp_batch_episode_generation_details') ->where('id', $task->id) ->update([ 'status' => 'completed', 'result_data' => json_encode($result, JSON_UNESCAPED_UNICODE), 'completed_at' => now(), 'updated_at' => now() ]); dLog('command')->info('[' . date('Y-m-d H:i:s') . '] 第' . $task->episode_number . '集生成成功'); return 0; } catch (\Exception $e) { dLog('command')->error('[' . date('Y-m-d H:i:s') . '] 生成失败: ' . $e->getMessage()); if (isset($task)) { // 更新重试次数 $retryCount = $task->retry_count + 1; // 标记为失败 DB::table('mp_batch_episode_generation_details') ->where('id', $task->id) ->update([ 'status' => 'pending', 'error_message' => $e->getMessage(), 'retry_count' => $retryCount, 'updated_at' => now() ]); // 记录错误日志 logDB('batch_episode_generation', 'error', "第{$task->episode_number}集生成失败", [ 'anime_id' => $task->anime_id, 'episode_number' => $task->episode_number, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); } return 1; } } } }