Просмотр исходного кода

视频任务生成失败时增加失败对话记录

lh 1 месяц назад
Родитель
Сommit
bfb9ae3997

+ 6 - 0
app/Console/Commands/CheckVideoGenerationTasksCommand.php

@@ -8,6 +8,9 @@ use Illuminate\Support\Facades\DB;
 
 class CheckVideoGenerationTasksCommand extends Command
 {
+    /** @var AIVideoGenerationService */
+    private $videoGenerationService;
+
     /**
      * The name and signature of the console command.
      *
@@ -30,6 +33,8 @@ class CheckVideoGenerationTasksCommand extends Command
      */
     public function handle(AIVideoGenerationService $videoGenerationService)
     {
+        $this->videoGenerationService = $videoGenerationService;
+
         dLog('command')->info('开始检查视频生成任务状态...');
 
         // 执行50s
@@ -197,6 +202,7 @@ class CheckVideoGenerationTasksCommand extends Command
                         'video_task_id' => $videoTaskId,
                         'error' => $videoTask->error_message
                     ]);
+                    $this->videoGenerationService->addVideoGenerationFailedRecord($videoTask, $videoTask->error_message);
                     
                 } else {
                     // 仍在处理中,不更新

+ 102 - 0
app/Services/AIGeneration/AIVideoGenerationService.php

@@ -426,6 +426,7 @@ class AIVideoGenerationService
         } elseif ($statusInfo['status'] === 'failed') {
             logDB('generate', 'error', '即梦AI视频生成任务失败', ['id' => $task->id, 'error' => $statusInfo['error_message']]);
             $task->updateStatus(MpGenerateVideoTask::STATUS_FAILED, $statusInfo);
+            $this->addVideoGenerationFailedRecord($task, $statusInfo['error_message']);
             
             // 同步更新分镜表状态为失败(兼容全能模式)
             $segment_id = $this->getSegmentIdFromTask($task);
@@ -445,6 +446,7 @@ class AIVideoGenerationService
             $task->updateStatus(MpGenerateVideoTask::STATUS_FAILED, [
                 'error_message' => '任务处理超时(超过12小时)'
             ]);
+            $this->addVideoGenerationFailedRecord($task, '任务处理超时(超过12小时)');
             
             // 同步更新分镜表状态为失败(兼容全能模式)
             $segment_id = $this->getSegmentIdFromTask($task);
@@ -1195,6 +1197,7 @@ class AIVideoGenerationService
                 'error_message' => $statusInfo['error_message'],
                 'result_json'   => $statusInfo['result_json'] ?? []
             ]);
+            $this->addVideoGenerationFailedRecord($task, $statusInfo['error_message']);
             
             // 同步更新分镜表状态为失败(兼容全能模式)
             $segment_id = $this->getSegmentIdFromTask($task);
@@ -1214,6 +1217,7 @@ class AIVideoGenerationService
             $task->updateStatus(MpGenerateVideoTask::STATUS_FAILED, [
                 'error_message' => '任务处理超时(超过48小时)'
             ]);
+            $this->addVideoGenerationFailedRecord($task, '任务处理超时(超过48小时)');
             
             // 同步更新分镜表状态为失败(兼容全能模式)
             $segment_id = $this->getSegmentIdFromTask($task);
@@ -1685,6 +1689,7 @@ class AIVideoGenerationService
                 }
             } elseif ($taskStatus === MpGenerateVideoTask::STATUS_FAILED) {
                 // 任务失败,更新分镜表状态
+                $this->addVideoGenerationFailedRecord($task, $updateData['error_message'] ?? '任务执行失败');
                 DB::table('mp_episode_segments')
                     ->where('video_task_id', $task->id)
                     ->update([
@@ -2225,6 +2230,7 @@ class AIVideoGenerationService
                 'error_message' => $statusInfo['error_message'],
                 'result_json' => $statusInfo['result_json'] ?? []
             ]);
+            $this->addVideoGenerationFailedRecord($task, $statusInfo['error_message']);
             
             // 同步更新分镜表状态为失败(兼容全能模式)
             $segment_id = $this->getSegmentIdFromTask($task);
@@ -2244,6 +2250,7 @@ class AIVideoGenerationService
             $task->updateStatus(MpGenerateVideoTask::STATUS_FAILED, [
                 'error_message' => '任务处理超时(超过24小时)'
             ]);
+            $this->addVideoGenerationFailedRecord($task, '任务处理超时(超过24小时)');
             
             // 同步更新分镜表状态为失败(兼容全能模式)
             $segment_id = $this->getSegmentIdFromTask($task);
@@ -2921,6 +2928,97 @@ class AIVideoGenerationService
     }
 
     /**
+     * 视频任务失败时写入一条对话记录
+     *
+     * @param MpGenerateVideoTask|array|object $task
+     * @param string|null $errorMessage
+     * @return void
+     */
+    public function addVideoGenerationFailedRecord($task, $errorMessage = null)
+    {
+        $returnErrorMsg = mapErrorMessage($errorMessage);
+        // 未知异常时保留原始错误信息;原始错误为空则保留默认提示
+        if ($returnErrorMsg === '未知异常,请重试' && $errorMessage !== null && $errorMessage !== '') {
+            $returnErrorMsg = $errorMessage;
+        }
+        try {
+            $videoTaskId = getProp($task, 'id');
+
+            $segment_id = getProp($task, 'alias_segment_id');
+            $act_id = getProp($task, 'alias_act_id');
+
+            if (!empty($segment_id)) {
+                $segment = DB::table('mp_episode_segments as a')->leftJoin('mp_animes as b', 'a.anime_id', 'b.id')
+                    ->where('a.segment_id', $segment_id)
+                    ->select('b.user_id as uid', 'a.anime_id', 'a.episode_number', 'a.tail_frame', 'a.act_content', 'a.act_show_content', 'a.segment_id')
+                    ->first();
+                $recordField = 'segment_id';
+                $recordValue = $segment_id;
+            } elseif (!empty($act_id)) {
+                $segment = DB::table('mp_episode_segments as a')->leftJoin('mp_animes as b', 'a.anime_id', 'b.id')
+                    ->where('a.id', $act_id)
+                    ->select('b.user_id as uid', 'a.anime_id', 'a.episode_number', 'a.tail_frame', 'a.act_content', 'a.act_show_content', 'a.id as act_id')
+                    ->first();
+                $recordField = 'act_id';
+                $recordValue = $act_id;
+            } else {
+                dLog('generate')->warning('无法确定失败记录查询模式,任务缺少segment_id和act_id', [
+                    'video_task_id' => $videoTaskId
+                ]);
+                return;
+            }
+
+            if (!$segment) {
+                dLog('generate')->warning('分镜信息不存在,无法添加失败对话记录', [
+                    'video_task_id' => $videoTaskId,
+                    'segment_id_or_act_id' => $recordValue
+                ]);
+                return;
+            }
+
+            // 同一视频任务只写一次失败记录(无任务ID时不做幂等判断,兼容手动添加记录)
+            if (!empty($videoTaskId)) {
+                $exists = DB::table('mp_anime_records')
+                    ->where('video_task_id', $videoTaskId)
+                    ->where('role', 'assistant')
+                    ->where('content', 'LIKE', '视频生成失败%')
+                    ->exists();
+
+                if ($exists) {
+                    return;
+                }
+            }
+
+            $now = date('Y-m-d H:i:s');
+            DB::table('mp_anime_records')->insert([
+                'uid'           => getProp($segment, 'uid'),
+                'anime_id'      => getProp($segment, 'anime_id'),
+                'sequence'      => getProp($segment, 'episode_number'),
+                'role'          => 'assistant',
+                'content'       => '视频生成失败,异常原因:' . (string)$returnErrorMsg,
+                $recordField    => $recordValue,
+                'video_url'     => '',
+                'video_task_id' => $videoTaskId ?: null,
+                'reference_images' => json_encode([], 256),
+                'created_at'    => $now,
+                'updated_at'    => $now
+            ]);
+
+            dLog('generate')->info('视频生成失败对话记录添加成功', [
+                'video_task_id' => $videoTaskId,
+                'segment_id_or_act_id' => $recordValue,
+                'error_message' => $errorMessage
+            ]);
+
+        } catch (\Exception $e) {
+            dLog('generate')->error('添加视频生成失败对话记录失败: ' . $e->getMessage(), [
+                'video_task_id' => getProp($task, 'id'),
+                'error_message' => $errorMessage
+            ]);
+        }
+    }
+
+    /**
      * 创建统一API视频生成任务(智帧20等新模型)
      *
      * @param array $params
@@ -3413,6 +3511,7 @@ class AIVideoGenerationService
                 'error_message' => $statusInfo['error_message'],
                 'result_json' => $statusInfo['result_json'] ?? []
             ]);
+            $this->addVideoGenerationFailedRecord($task, $statusInfo['error_message']);
             
             // 同步更新分镜表状态为失败(兼容全能模式)
             $segment_id = $this->getSegmentIdFromTask($task);
@@ -3432,6 +3531,7 @@ class AIVideoGenerationService
             $task->updateStatus(MpGenerateVideoTask::STATUS_FAILED, [
                 'error_message' => '任务处理超时(超过48小时)'
             ]);
+            $this->addVideoGenerationFailedRecord($task, '任务处理超时(超过48小时)');
             
             // 同步更新分镜表状态为失败(兼容全能模式)
             $segment_id = $this->getSegmentIdFromTask($task);
@@ -4173,6 +4273,7 @@ class AIVideoGenerationService
                 'error_message' => $statusInfo['error_message'],
                 'result_json' => $statusInfo['result_json'] ?? []
             ]);
+            $this->addVideoGenerationFailedRecord($task, $statusInfo['error_message']);
             
             // 不更新原始任务状态,保留480p任务的成功状态
         }
@@ -4188,6 +4289,7 @@ class AIVideoGenerationService
             $task->updateStatus(MpGenerateVideoTask::STATUS_FAILED, [
                 'error_message' => '任务处理超时(超过48小时)'
             ]);
+            $this->addVideoGenerationFailedRecord($task, '任务处理超时(超过48小时)');
         }
     }
 }