Parcourir la source

对遗漏的方法增加积分预检

lh il y a 3 semaines
Parent
commit
ea3846883b

+ 50 - 1
app/Http/Controllers/AIGeneration/VideoGenerationController.php

@@ -5,6 +5,7 @@ namespace App\Http\Controllers\AIGeneration;
 use Illuminate\Routing\Controller as BaseController;
 use App\Libs\Utils;
 use App\Services\AIGeneration\AIVideoGenerationService;
+use App\Services\PointsService;
 use App\Transformer\AIGeneration\AIGenerationTransformer;
 use Illuminate\Http\Request;
 use Illuminate\Http\JsonResponse;
@@ -17,11 +18,14 @@ class VideoGenerationController extends BaseController
 {
     use ApiResponse;
     private $aiVideoGenerationService;
+    private $pointsService;
 
     public function __construct(
-        AIVideoGenerationService $aiVideoGenerationService
+        AIVideoGenerationService $aiVideoGenerationService,
+        PointsService $pointsService
     ) {
         $this->aiVideoGenerationService = $aiVideoGenerationService;
+        $this->pointsService = $pointsService;
     }
 
     /**
@@ -154,6 +158,21 @@ class VideoGenerationController extends BaseController
             }
         }
 
+        // 余额预检:按预估时长计算所需积分,不足直接报错
+        $chargeDuration = (int)getProp($data, 'video_duration', 5);
+        if ($chargeDuration <= 0) {
+            $chargeDuration = 5;
+        }
+        $this->pointsService->checkUserPointsEnough(
+            $this->pointsService->getVideoChargePoints([
+                'model' => (string)getProp($data, 'model', ''),
+                'video_resolution' => strtolower((string)getProp($data, 'video_resolution', '720p')),
+                'video_duration' => $chargeDuration,
+                'ratio' => (string)getProp($data, 'ratio', '9:16'),
+                'generate_audio' => (int)getProp($data, 'generate_audio', 1),
+            ])
+        );
+
         $task = $this->aiVideoGenerationService->createJimengTask($data);
         return $this->success(['task_id' => $task->id, 'status' => $task->status]);
     }
@@ -451,6 +470,21 @@ class VideoGenerationController extends BaseController
         // 验证 content 数组内容
         $this->validateSeedanceContent($data['content']);
     
+        // 余额预检:按预估时长计算所需积分,不足直接报错
+        $chargeDuration = (int)getProp($data, 'video_duration', 5);
+        if ($chargeDuration <= 0) {
+            $chargeDuration = 5;
+        }
+        $this->pointsService->checkUserPointsEnough(
+            $this->pointsService->getVideoChargePoints([
+                'model' => (string)getProp($data, 'model', ''),
+                'video_resolution' => strtolower((string)getProp($data, 'video_resolution', '720p')),
+                'video_duration' => $chargeDuration,
+                'ratio' => (string)getProp($data, 'ratio', '9:16'),
+                'generate_audio' => (int)getProp($data, 'generate_audio', 1),
+            ])
+        );
+
         $task = $this->aiVideoGenerationService->createSeedanceTask($data);
         return $this->success(['task_id' => $task->id, 'status' => $task->status]);
     }
@@ -823,6 +857,21 @@ class VideoGenerationController extends BaseController
             ];
         }
 
+        // 余额预检:按预估时长计算所需积分,不足直接报错
+        $chargeDuration = (int)getProp($data, 'video_duration', 5);
+        if ($chargeDuration <= 0) {
+            $chargeDuration = 5;
+        }
+        $this->pointsService->checkUserPointsEnough(
+            $this->pointsService->getVideoChargePoints([
+                'model' => (string)getProp($data, 'model', ''),
+                'video_resolution' => strtolower((string)getProp($data, 'video_resolution', '720p')),
+                'video_duration' => $chargeDuration,
+                'ratio' => (string)getProp($data, 'aspect_ratio', getProp($data, 'ratio', '9:16')),
+                'generate_audio' => (int)getProp($data, 'generate_audio', 1),
+            ])
+        );
+
         $task = $this->aiVideoGenerationService->createKelingOmniTask($data);
         return $this->success(['task_id' => $task->id, 'status' => $task->status]);
     }

+ 33 - 17
app/Http/Controllers/Anime/AnimeController.php

@@ -2684,18 +2684,39 @@ class AnimeController extends BaseController
 
         $data = $request->all();
 
-        // 创建视频生成任务
-        $result = $this->AnimeService->generateVideo($data);
-        $taskId = $result['task_id'];
+        $sseHeaders = [
+            'Content-Type' => 'text/event-stream',
+            'Cache-Control' => 'no-cache',
+            'Connection' => 'keep-alive',
+            'X-Accel-Buffering' => 'no', // 禁用 Nginx 缓冲
+        ];
 
-        // 创建任务中心记录并关联视频任务ID
-        $taskCenter = $this->taskCenterService->createTask('video', [
-            'title'       => '文生视频',
-            'ref_task_id' => $taskId,
-            // 'prompt'      => getProp($data, 'prompt', ''),
-            // 'params'      => json_encode($data, JSON_UNESCAPED_UNICODE),
-        ]);
-        $taskCenterId = $taskCenter->id;
+        try {
+            // 创建视频生成任务
+            $result = $this->AnimeService->generateVideo($data);
+            $taskId = $result['task_id'];
+
+            // 创建任务中心记录并关联视频任务ID
+            $taskCenter = $this->taskCenterService->createTask('video', [
+                'title'       => '文生视频',
+                'ref_task_id' => $taskId,
+                // 'prompt'      => getProp($data, 'prompt', ''),
+                // 'params'      => json_encode($data, JSON_UNESCAPED_UNICODE),
+            ]);
+            $taskCenterId = $taskCenter->id;
+        } catch (\Throwable $e) {
+            // 创建阶段所有报错统一通过 SSE type=error 返回
+            return response()->stream(function () use ($e) {
+                echo "data: " . json_encode([
+                    'type' => 'error',
+                    'message' => preg_replace('/^\d+:/', '', $e->getMessage()),
+                ], JSON_UNESCAPED_UNICODE) . "\n\n";
+                if (ob_get_level() > 0) {
+                    ob_flush();
+                }
+                flush();
+            }, 200, $sseHeaders);
+        }
 
         // 设置 SSE 响应头
         return response()->stream(function () use ($taskId, $taskCenterId, $result) {
@@ -2792,12 +2813,7 @@ class AnimeController extends BaseController
                 flush();
             }
 
-        }, 200, [
-            'Content-Type' => 'text/event-stream',
-            'Cache-Control' => 'no-cache',
-            'Connection' => 'keep-alive',
-            'X-Accel-Buffering' => 'no', // 禁用 Nginx 缓冲
-        ]);
+        }, 200, $sseHeaders);
     }
 
     /**

+ 1 - 1
app/Services/AIGeneration/AIVideoGenerationService.php

@@ -213,7 +213,7 @@ class AIVideoGenerationService
             $task->updateStatus(MpGenerateVideoTask::STATUS_FAILED, [
                 'error_message' => $error['error_message'],
                 'result_json' => $error['payload'],
-                'extra_params' => array_merge($task->extra_params, ['api_response' => $error['payload']])
+                'extra_params' => array_merge((array)$task->extra_params, ['api_response' => $error['payload']])
             ]);
             Utils::throwError('1001:'.$e->getMessage());
         }

+ 15 - 0
app/Services/Anime/AnimeService.php

@@ -5300,6 +5300,21 @@ class AnimeService
         }
         $reference_audios = array_slice($reference_audios, 0, 3);
 
+        // 余额预检:按预估时长计算所需积分,不足直接报错
+        $chargeDuration = (int)ceil((float)$video_duration);
+        if ($chargeDuration <= 0) {
+            $chargeDuration = 5; // 无时长时按默认5秒预估
+        }
+        $this->pointsService->checkUserPointsEnough(
+            $this->pointsService->getVideoChargePoints([
+                'model' => $model,
+                'video_resolution' => strtolower($video_resolution ?? '720p'),
+                'video_duration' => $chargeDuration,
+                'ratio' => $ratio,
+                'generate_audio' => (int)$generate_audio,
+            ])
+        );
+
         // 构建视频生成参数(用户参数直接透传,提示词不做处理)
         $videoParams = [
             'model' => $model,