Преглед изворни кода

新增剧本资产相关接口

lh пре 5 дана
родитељ
комит
3a62c494cb
3 измењених фајлова са 194 додато и 0 уклоњено
  1. 22 0
      app/Http/Controllers/Anime/AnimeController.php
  2. 168 0
      app/Services/Anime/AnimeService.php
  3. 4 0
      routes/api.php

+ 22 - 0
app/Http/Controllers/Anime/AnimeController.php

@@ -2285,6 +2285,28 @@ class AnimeController extends BaseController
         return $this->success($result);
     }
 
+    /**
+     * 保存剧本资产关联关系
+     * @param Request $request
+     * @return mixed
+     */
+    public function saveScriptProducts(Request $request) {
+        $data = $request->all();
+        $result = $this->AnimeService->saveScriptProducts($data);
+        return $this->success(['success' => $result ? 1 : 0]);
+    }
+
+    /**
+     * 获取剧本关联的资产列表
+     * @param Request $request
+     * @return mixed
+     */
+    public function getScriptProducts(Request $request) {
+        $data = $request->all();
+        $result = $this->AnimeService->getScriptProducts($data);
+        return $this->success($result);
+    }
+
     private function handleVideoTimePointEnd() {
         // 处理音频时长,循环查询dub_video_task_queue列表中的任务
         $queueLength = Redis::llen('dub_video_task_queue');

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

@@ -6344,6 +6344,174 @@ class AnimeService
     }
 
     /**
+     * 保存剧本资产关联关系
+     * @param array $data 请求参数
+     * @return bool
+     */
+    public function saveScriptProducts($data) {
+        $uid = Site::getUid();
+        $cpid = Site::getCpid();
+        $script_id = getProp($data, 'script_id');
+        $products = getProp($data, 'products', []);
+
+        if (!$script_id) {
+            Utils::throwError('20003:请提供剧本ID');
+        }
+
+        // 验证剧本是否存在
+        $script = DB::table('mp_scripts')
+            ->where('id', $script_id)
+            ->where('is_deleted', 0)
+            ->first();
+            
+        if (!$script) {
+            Utils::throwError('20003:剧本不存在');
+        }
+
+        // 解析 products(可能是 JSON 字符串或数组)
+        if (is_string($products)) {
+            $products = json_decode($products, true);
+            if (json_last_error() !== JSON_ERROR_NONE) {
+                Utils::throwError('20003:产品数据格式错误');
+            }
+        }
+
+        if (!is_array($products) || empty($products)) {
+            Utils::throwError('20003:产品数据不能为空');
+        }
+
+        // 验证每个 product_id 是否存在
+        $productIds = array_column($products, 'product_id');
+        $validProductIds = DB::table('mp_products')
+            ->where('cpid', $cpid)
+            // ->where('user_id', $uid)
+            ->where('is_deleted', 0)
+            ->whereIn('id', $productIds)
+            ->pluck('id')
+            ->toArray();
+
+        // 检查是否有无效的 product_id
+        $invalidIds = array_diff($productIds, $validProductIds);
+        if (!empty($invalidIds)) {
+            Utils::throwError('20003:以下资产ID不存在或无权访问 ' . implode(', ', $invalidIds));
+        }
+
+        // 准备插入数据
+        $records = [];
+        $now = now();
+
+        foreach ($products as $product) {
+            if (!isset($product['product_id']) || !isset($product['episode_number'])) {
+                continue;
+            }
+
+            $productId = $product['product_id'];
+            $episodeNumbers = $product['episode_number'];
+
+            // 如果 episode_number 是数组,则展开成多条记录
+            if (is_array($episodeNumbers)) {
+                foreach ($episodeNumbers as $episodeNumber) {
+                    $records[] = [
+                        'script_id' => $script_id,
+                        'product_id' => $productId,
+                        'episode_number' => $episodeNumber,
+                        'created_at' => $now,
+                        'updated_at' => $now,
+                    ];
+                }
+            } else {
+                // 如果 episode_number 是单个值,直接插入
+                $records[] = [
+                    'script_id' => $script_id,
+                    'product_id' => $productId,
+                    'episode_number' => $episodeNumbers,
+                    'created_at' => $now,
+                    'updated_at' => $now,
+                ];
+            }
+        }
+
+        if (empty($records)) {
+            Utils::throwError('20003:没有有效的产品数据');
+        }
+
+        // 批量插入数据(使用 insertOrIgnore 避免重复插入)
+        return DB::table('mp_script_product_mappings')->insertOrIgnore($records);
+    }
+
+    /**
+     * 获取剧本关联的资产列表
+     * @param array $data 请求参数
+     * @return array
+     */
+    public function getScriptProducts($data) {
+        $uid = Site::getUid();
+        $cpid = Site::getCpid();
+        $script_id = getProp($data, 'script_id');
+        $episode_number = getProp($data, 'episode_number');
+
+        if (!$script_id) {
+            Utils::throwError('20003:请提供剧本ID');
+        }
+
+        // 验证剧本是否存在
+        $script = DB::table('mp_scripts')
+            ->where('id', $script_id)
+            ->where('is_deleted', 0)
+            ->first();
+            
+        if (!$script) {
+            Utils::throwError('20003:剧本不存在');
+        }
+
+        // 联表查询资产信息
+        $query = DB::table('mp_script_product_mappings as mapping')
+            ->join('mp_products as product', 'mapping.product_id', '=', 'product.id')
+            ->where('mapping.script_id', $script_id)
+            ->where('product.cpid', $cpid)
+            // ->where('product.user_id', $uid)
+            ->where('product.is_deleted', 0);
+
+        // 如果提供了 episode_number,则过滤指定集数
+        if ($episode_number !== null && $episode_number !== '') {
+            $query->where('mapping.episode_number', $episode_number);
+        }
+
+        $products = $query->select(
+                'mapping.script_id',
+                'mapping.product_id',
+                'mapping.episode_number',
+                'product.product_name',
+                'product.product',
+                'product.pic_prompt',
+                'product.url',
+                'product.three_view_image_url',
+                'mapping.created_at'
+            )
+            ->orderBy('mapping.episode_number', 'asc')
+            ->orderBy('mapping.id', 'asc')
+            ->get()
+            ->map(function ($item) {
+                return [
+                    'script_id' => $item->script_id,
+                    'episode_number' => $item->episode_number,
+                    'product_id' => $item->product_id,
+                    'product_name' => $item->product_name,
+                    'product' => (int)$item->product,
+                    'pic_prompt' => $item->pic_prompt,
+                    'url' => $item->url,
+                    // 'three_view_image_url' => $item->three_view_image_url,
+                    'created_at' => $item->created_at,
+                ];
+            })
+            ->toArray();
+
+        return [
+            'list' => $products,
+        ];
+    }
+
+    /**
      * 处理act_content中的{}标记,替换为product_name(图+序号)格式,并收集参考图片
      * @param string $actContent 原始内容
      * @param array $products 产品数组(包含product_name和url)

+ 4 - 0
routes/api.php

@@ -229,6 +229,10 @@ Route::group(['middleware' => ['bindToken', 'bindExportToken', 'checkLogin']], f
             Route::get('getFolderPath', [AnimeController::class, 'getFolderPath']); // 获取文件夹路径
             // 生成三视图(基于参考图生成主体的标准正面、侧面、后面三视图,主体完整。在最左侧添加主体正视图的特写,主体清晰完整。背景修改成纯白色,整体保持与参考图一致的美术风格和色彩搭配。画面无说明文字)
             Route::post('generateThreeView', [AnimeController::class, 'generateThreeView']);
+            
+            // 剧本资产关联管理
+            Route::post('saveScriptProducts', [AnimeController::class, 'saveScriptProducts']);     // 保存剧本资产关联
+            Route::get('getScriptProducts', [AnimeController::class, 'getScriptProducts']);        // 获取剧本关联的资产列表
 
             // 提示词模板管理
             Route::get('promptTemplates', [PromptTemplateController::class, 'promptTemplates']);          // 提示词模板列表