|
|
@@ -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)
|