|
|
@@ -6831,6 +6831,16 @@ class AnimeService
|
|
|
// 根据is_public参数确定存储的user_id(公共库user_id=0,cpid保持不变)
|
|
|
$store_uid = $is_public ? 0 : $uid;
|
|
|
|
|
|
+ // 新增参数:剧本ID和剧集序号(多个序号用英文逗号隔开)
|
|
|
+ $script_id = (int)getProp($data, 'script_id', 0);
|
|
|
+ $episode_number = trim(getProp($data, 'episode_number', ''));
|
|
|
+ if ($script_id && $episode_number === '') {
|
|
|
+ Utils::throwError('20003:剧集序号不能为空');
|
|
|
+ }
|
|
|
+ if (!$script_id && $episode_number !== '') {
|
|
|
+ Utils::throwError('20003:请提供剧本ID');
|
|
|
+ }
|
|
|
+
|
|
|
$product_name = trim(getProp($data, 'product_name'));
|
|
|
if (!$product_name) Utils::throwError('20003:名称不能为空');
|
|
|
$product_name = preg_replace('/^[\s*\[\]【】[]{}{}\x{3000}]+|[\s*\[\]【】[]{}{}\x{3000}]+$/u', '', $product_name);
|
|
|
@@ -6877,23 +6887,38 @@ class AnimeService
|
|
|
$parent_level = $parent->level;
|
|
|
}
|
|
|
|
|
|
- $id = DB::table('mp_products')->insertGetId([
|
|
|
- 'user_id' => $store_uid,
|
|
|
- 'cpid' => $cpid,
|
|
|
- 'type' => 1, // 1=角色图片
|
|
|
- 'parent_id' => $parent_id,
|
|
|
- 'level' => $parent_level + 1,
|
|
|
- 'product_name' => $product_name,
|
|
|
- 'url' => $url,
|
|
|
- 'pic_prompt' => $pic_prompt,
|
|
|
- 'product' => $product,
|
|
|
- 'versions' => json_encode($versions, 256),
|
|
|
- 'sort_order' => time(), // 使用时间戳作为排序权重
|
|
|
- 'created_at' => date('Y-m-d H:i:s'),
|
|
|
- 'updated_at' => date('Y-m-d H:i:s')
|
|
|
- ]);
|
|
|
+ // 创建资产并保存剧本资产关联关系(同一事务)
|
|
|
+ DB::beginTransaction();
|
|
|
+ try {
|
|
|
+ $id = DB::table('mp_products')->insertGetId([
|
|
|
+ 'user_id' => $store_uid,
|
|
|
+ 'cpid' => $cpid,
|
|
|
+ 'type' => 1, // 1=角色图片
|
|
|
+ 'parent_id' => $parent_id,
|
|
|
+ 'level' => $parent_level + 1,
|
|
|
+ 'product_name' => $product_name,
|
|
|
+ 'url' => $url,
|
|
|
+ 'pic_prompt' => $pic_prompt,
|
|
|
+ 'product' => $product,
|
|
|
+ 'versions' => json_encode($versions, 256),
|
|
|
+ 'sort_order' => time(), // 使用时间戳作为排序权重
|
|
|
+ 'created_at' => date('Y-m-d H:i:s'),
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s')
|
|
|
+ ]);
|
|
|
|
|
|
- if (!$id) Utils::throwError('20003:创建失败');
|
|
|
+ if (!$id) Utils::throwError('20003:创建失败');
|
|
|
+
|
|
|
+ // 保存剧本资产关联关系
|
|
|
+ if ($script_id) {
|
|
|
+ $this->saveProductScriptMapping($id, $script_id, $episode_number);
|
|
|
+ }
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ DB::rollback();
|
|
|
+ throw $e;
|
|
|
+ }
|
|
|
+
|
|
|
return [
|
|
|
'id' => $id,
|
|
|
'type' => 1,
|
|
|
@@ -6916,6 +6941,16 @@ class AnimeService
|
|
|
$versions = getProp($data, 'versions');
|
|
|
$is_public = getProp($data, 'is_public', 0); // 0=个人资产库 1=公共资产库
|
|
|
|
|
|
+ // 新增参数:剧本ID和剧集序号(多个序号用英文逗号隔开)
|
|
|
+ $script_id = (int)getProp($data, 'script_id', 0);
|
|
|
+ $episode_number = trim(getProp($data, 'episode_number', ''));
|
|
|
+ if ($script_id && $episode_number === '') {
|
|
|
+ Utils::throwError('20003:剧集序号不能为空');
|
|
|
+ }
|
|
|
+ if (!$script_id && $episode_number !== '') {
|
|
|
+ Utils::throwError('20003:请提供剧本ID');
|
|
|
+ }
|
|
|
+
|
|
|
// 根据is_public参数确定查询的user_id(公共库user_id=0,cpid保持不变)
|
|
|
$query_uid = $is_public ? 0 : $uid;
|
|
|
|
|
|
@@ -6976,7 +7011,7 @@ class AnimeService
|
|
|
$updateData['pic_prompt'] = $pic_prompt;
|
|
|
}
|
|
|
|
|
|
- if (empty($updateData)) {
|
|
|
+ if (empty($updateData) && !$script_id) {
|
|
|
Utils::throwError('20003:没有需要更新的数据');
|
|
|
}
|
|
|
|
|
|
@@ -7030,11 +7065,157 @@ class AnimeService
|
|
|
$updateData['versions'] = json_encode($versions, 256);
|
|
|
}
|
|
|
|
|
|
- $updateData['updated_at'] = date('Y-m-d H:i:s');
|
|
|
+ if (!empty($updateData)) {
|
|
|
+ $updateData['updated_at'] = date('Y-m-d H:i:s');
|
|
|
+ }
|
|
|
|
|
|
- return DB::table('mp_products')
|
|
|
- ->where('cpid', $cpid)
|
|
|
- ->where('id', $id)->update($updateData);
|
|
|
+ // 更新资产并保存剧本资产关联关系(同一事务)
|
|
|
+ DB::beginTransaction();
|
|
|
+ try {
|
|
|
+ $updated = true;
|
|
|
+ if (!empty($updateData)) {
|
|
|
+ $updated = DB::table('mp_products')
|
|
|
+ ->where('cpid', $cpid)
|
|
|
+ ->where('id', $id)
|
|
|
+ ->update($updateData);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存剧本资产关联关系
|
|
|
+ if ($script_id) {
|
|
|
+ $this->saveProductScriptMapping($id, $script_id, $episode_number);
|
|
|
+ }
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ DB::rollback();
|
|
|
+ throw $e;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $updated;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存单一资产与剧本剧集的关联关系
|
|
|
+ *
|
|
|
+ * @param int $product_id 资产ID
|
|
|
+ * @param int $script_id 剧本ID
|
|
|
+ * @param string $episode_number_str 剧集序号,多个序号用英文逗号隔开(序号从1开始)
|
|
|
+ * @return int 新增关联数量
|
|
|
+ */
|
|
|
+ private function saveProductScriptMapping($product_id, $script_id, $episode_number_str) {
|
|
|
+ // 验证剧本是否存在
|
|
|
+ $script = DB::table('mp_scripts')
|
|
|
+ ->where('id', $script_id)
|
|
|
+ ->where('is_deleted', 0)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$script) {
|
|
|
+ Utils::throwError('20003:剧本不存在');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用 splitContent 拆分剧本内容获取总集数
|
|
|
+ $totalEpisodes = $this->getScriptTotalEpisodeCount($script);
|
|
|
+
|
|
|
+ // 解析剧集序号(英文逗号分隔)
|
|
|
+ $episodes = [];
|
|
|
+ foreach (explode(',', $episode_number_str) as $item) {
|
|
|
+ $item = trim($item);
|
|
|
+ if ($item === '' || !is_numeric($item)) {
|
|
|
+ Utils::throwError('20003:剧集序号格式不正确,多个序号请用英文逗号隔开');
|
|
|
+ }
|
|
|
+ $episodes[] = (int)$item;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 去重并校验序号范围(序号从1开始)
|
|
|
+ $episodes = array_values(array_unique($episodes));
|
|
|
+ if (empty($episodes)) {
|
|
|
+ Utils::throwError('20003:剧集序号不能为空');
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach ($episodes as $episode) {
|
|
|
+ if ($episode < 1 || $episode > $totalEpisodes) {
|
|
|
+ Utils::throwError('20003:剧集序号 ' . $episode . ' 超出范围,剧本共 ' . $totalEpisodes . ' 集(序号从1开始)');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $now = now();
|
|
|
+
|
|
|
+ // 过滤已存在的关联,避免重复
|
|
|
+ $existingEpisodes = DB::table('mp_script_product_mappings')
|
|
|
+ ->where('script_id', $script_id)
|
|
|
+ ->where('product_id', $product_id)
|
|
|
+ ->whereIn('episode_number', $episodes)
|
|
|
+ ->pluck('episode_number')
|
|
|
+ ->all();
|
|
|
+
|
|
|
+ $mappingRecords = [];
|
|
|
+ foreach ($episodes as $episode) {
|
|
|
+ if (in_array($episode, $existingEpisodes)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $mappingRecords[] = [
|
|
|
+ 'script_id' => $script_id,
|
|
|
+ 'product_id' => $product_id,
|
|
|
+ 'episode_number' => $episode,
|
|
|
+ 'created_at' => $now,
|
|
|
+ 'updated_at' => $now,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $insertedCount = 0;
|
|
|
+ if (!empty($mappingRecords)) {
|
|
|
+ $insertedCount = DB::table('mp_script_product_mappings')->insert($mappingRecords) ? count($mappingRecords) : 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $insertedCount;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取剧本总集数(通过 splitContent 拆分剧本内容)
|
|
|
+ *
|
|
|
+ * @param object $script 剧本记录
|
|
|
+ * @return int 总集数
|
|
|
+ */
|
|
|
+ private function getScriptTotalEpisodeCount($script) {
|
|
|
+ if (empty($script->content)) {
|
|
|
+ Utils::throwError('20003:剧本内容为空,无法确定剧集数量');
|
|
|
+ }
|
|
|
+
|
|
|
+ $totalEpisodes = count(splitContent($script->content));
|
|
|
+ if ($totalEpisodes < 1) {
|
|
|
+ Utils::throwError('20003:剧本内容无法拆分出剧集');
|
|
|
+ }
|
|
|
+
|
|
|
+ return $totalEpisodes;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取剧本总集数
|
|
|
+ *
|
|
|
+ * @param array $data 包含 script_id(剧本ID)
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public function getScriptTotalEpisodes($data) {
|
|
|
+ $script_id = (int)getProp($data, 'script_id', 0);
|
|
|
+ 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:剧本不存在');
|
|
|
+ }
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'script_id' => $script_id,
|
|
|
+ 'script_name' => $script->script_name ?? 'script_' . $script_id,
|
|
|
+ 'total_episodes' => $this->getScriptTotalEpisodeCount($script),
|
|
|
+ ];
|
|
|
}
|
|
|
|
|
|
/**
|