|
@@ -12365,7 +12365,8 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
|
|
|
|
|
|
|
|
$episode_content = DB::table('mp_anime_episodes')->where('id', $episode_id)->value('content');
|
|
$episode_content = DB::table('mp_anime_episodes')->where('id', $episode_id)->value('content');
|
|
|
if ($episode_content) {
|
|
if ($episode_content) {
|
|
|
- $reference_content = "\n\n【本集原始内容】\n{$episode_content}\n\n【本集生成剧本内容】\n{$reference_content}";
|
|
|
|
|
|
|
+ // $reference_content = "\n\n【本集原始内容】\n{$episode_content}\n\n【本集生成剧本内容】\n{$reference_content}";
|
|
|
|
|
+ $reference_content = "\n\n【本集原始内容】\n{$episode_content}";
|
|
|
}else {
|
|
}else {
|
|
|
$reference_content = "\n\n【原分段剧本内容】\n{$reference_content}";
|
|
$reference_content = "\n\n【原分段剧本内容】\n{$reference_content}";
|
|
|
}
|
|
}
|
|
@@ -12871,6 +12872,34 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
+ // 预览确认模式(check_mode=1):不落库,返回展示参数供前端确认后调用 saveEpisodeActs 保存
|
|
|
|
|
+ if ($check_mode === 1) {
|
|
|
|
|
+ // 预览生成即扣除积分并记录 token 明细(与 check_mode=0 保存时扣费一致)
|
|
|
|
|
+ $this->chargeChatSuccess($uid, $this->pointsService->getTokensFromUsage($usage), [
|
|
|
|
|
+ 'anime_id' => $target_anime_id,
|
|
|
|
|
+ 'episode_id' => $target_episode_id,
|
|
|
|
|
+ 'model' => $model,
|
|
|
|
|
+ 'source' => 'regenerateSegmentScript',
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ return [
|
|
|
|
|
+ 'check_mode' => 1,
|
|
|
|
|
+ 'anime_id' => $target_anime_id,
|
|
|
|
|
+ 'episode_id' => $target_episode_id,
|
|
|
|
|
+ 'title' => getProp($episode, 'title', ''),
|
|
|
|
|
+ 'episode_number' => $target_episode_number,
|
|
|
|
|
+ 'is_generated' => getProp($episode, 'is_generated', 0),
|
|
|
|
|
+ 'acts' => array_map(function ($seg) {
|
|
|
|
|
+ return [
|
|
|
|
|
+ 'act_number' => $seg['act_number'],
|
|
|
|
|
+ 'act_duration' => $seg['act_duration'],
|
|
|
|
|
+ 'act_content' => $seg['act_content'],
|
|
|
|
|
+ 'act_show_content' => $seg['act_show_content'],
|
|
|
|
|
+ ];
|
|
|
|
|
+ }, $parsed_segments),
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 整个剧集模式:删除原有记录并批量保存新记录
|
|
// 整个剧集模式:删除原有记录并批量保存新记录
|
|
|
DB::beginTransaction();
|
|
DB::beginTransaction();
|
|
|
|
|
|
|
@@ -12962,6 +12991,115 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
|
+ * 保存剧集片段(预览确认模式使用):删除旧数据并批量保存新数据到 mp_episode_segments
|
|
|
|
|
+ *
|
|
|
|
|
+ * 逻辑与 regenerateSegmentScript 的 episode_id + check_mode=0 保存保持一致。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param array $data 请求参数:episode_id 必填,acts 必填(预览返回的片段数组)
|
|
|
|
|
+ * @return array
|
|
|
|
|
+ */
|
|
|
|
|
+ public function saveEpisodeActs($data) {
|
|
|
|
|
+ $uid = Site::getUid();
|
|
|
|
|
+ $episode_id = (int)getProp($data, 'episode_id', 0);
|
|
|
|
|
+ $acts = getProp($data, 'acts', []);
|
|
|
|
|
+
|
|
|
|
|
+ if (!$episode_id) {
|
|
|
|
|
+ Utils::throwError('20003:请提供剧集ID');
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!is_array($acts) || empty($acts)) {
|
|
|
|
|
+ Utils::throwError('20003:请提供片段数据');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $episode = DB::table('mp_anime_episodes')->where('id', $episode_id)->first();
|
|
|
|
|
+ if (!$episode) {
|
|
|
|
|
+ Utils::throwError('20003:剧集不存在');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 用户校验:只能调整自己的剧集
|
|
|
|
|
+ $anime = DB::table('mp_animes')->where('id', $episode->anime_id)->first();
|
|
|
|
|
+ if (!$anime || (int)$anime->user_id !== (int)$uid) {
|
|
|
|
|
+ Utils::throwError('20003:没有权限操作该剧集');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $anime_id = (int)$episode->anime_id;
|
|
|
|
|
+ $episode_number = (int)$episode->episode_number;
|
|
|
|
|
+ $now = date('Y-m-d H:i:s');
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ DB::beginTransaction();
|
|
|
|
|
+
|
|
|
|
|
+ // 删除原有的所有片段记录
|
|
|
|
|
+ DB::table('mp_episode_segments')
|
|
|
|
|
+ ->where('episode_id', $episode_id)
|
|
|
|
|
+ ->delete();
|
|
|
|
|
+
|
|
|
|
|
+ // 批量插入新的片段记录
|
|
|
|
|
+ $segments_to_insert = [];
|
|
|
|
|
+ $index = 0;
|
|
|
|
|
+ foreach ($acts as $act) {
|
|
|
|
|
+ if (!is_array($act)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $index++;
|
|
|
|
|
+ $segments_to_insert[] = [
|
|
|
|
|
+ 'anime_id' => $anime_id,
|
|
|
|
|
+ 'episode_id' => $episode_id,
|
|
|
|
|
+ 'episode_number' => $episode_number,
|
|
|
|
|
+ 'act_number' => (int)getProp($act, 'act_number', $index),
|
|
|
|
|
+ 'act_title' => (string)getProp($act, 'act_title', ''),
|
|
|
|
|
+ 'act_duration' => (float)getProp($act, 'act_duration', 0),
|
|
|
|
|
+ 'act_content' => (string)getProp($act, 'act_content', ''),
|
|
|
|
|
+ // 'act_show_content' => (string)getProp($act, 'act_show_content', ''),
|
|
|
|
|
+ 'created_at' => $now,
|
|
|
|
|
+ 'updated_at' => $now,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (empty($segments_to_insert)) {
|
|
|
|
|
+ DB::rollBack();
|
|
|
|
|
+ Utils::throwError('20003:没有有效的片段数据');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ DB::table('mp_episode_segments')->insert($segments_to_insert);
|
|
|
|
|
+
|
|
|
|
|
+ DB::commit();
|
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
|
+ DB::rollBack();
|
|
|
|
|
+ dLog('deepseek')->error('保存剧集片段失败: ' . $e->getMessage(), [
|
|
|
|
|
+ 'episode_id' => $episode_id,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ Utils::throwError('20003:保存失败,请重试');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 查询保存后的所有片段记录
|
|
|
|
|
+ $saved_segments = DB::table('mp_episode_segments')
|
|
|
|
|
+ ->where('episode_id', $episode_id)
|
|
|
|
|
+ ->orderBy('act_number')
|
|
|
|
|
+ ->get();
|
|
|
|
|
+
|
|
|
|
|
+ $saved_acts = [];
|
|
|
|
|
+ foreach ($saved_segments as $saved_segment) {
|
|
|
|
|
+ $saved_acts[] = [
|
|
|
|
|
+ 'act_id' => $saved_segment->id,
|
|
|
|
|
+ 'act_number' => $saved_segment->act_number,
|
|
|
|
|
+ 'act_duration' => $saved_segment->video_duration ? $saved_segment->video_duration : $saved_segment->act_duration,
|
|
|
|
|
+ 'act_content' => $saved_segment->act_content,
|
|
|
|
|
+ 'act_show_content' => $saved_segment->act_show_content,
|
|
|
|
|
+ 'video_url' => $saved_segment->video_url ?? '',
|
|
|
|
|
+ 'video_duration' => $saved_segment->video_duration ?? 0,
|
|
|
|
|
+ 'video_time_point_start'=> $saved_segment->video_time_point_start ?? 0,
|
|
|
|
|
+ 'video_time_point_end' => $saved_segment->video_time_point_end ?? 0,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return [
|
|
|
|
|
+ 'anime_id' => $anime_id,
|
|
|
|
|
+ 'episode_id' => $episode_id,
|
|
|
|
|
+ 'acts' => $saved_acts,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
* 清理分镜内容:去除时长、旁白音色等非分镜行,只保留完整分镜内容(分镜标记统一为【分镜N】/【镜头N】)
|
|
* 清理分镜内容:去除时长、旁白音色等非分镜行,只保留完整分镜内容(分镜标记统一为【分镜N】/【镜头N】)
|
|
|
*
|
|
*
|
|
|
* @param string $actContent
|
|
* @param string $actContent
|