|
|
@@ -2318,6 +2318,432 @@ class AnimeService
|
|
|
return compact('pics', 'videos');
|
|
|
}
|
|
|
|
|
|
+ public function addAct($data) {
|
|
|
+ $prev_act_id = getProp($data, 'prev_act_id');
|
|
|
+ $act_title = getProp($data, 'act_title', '');
|
|
|
+ $act_content = getProp($data, 'act_content', '');
|
|
|
+ $act_duration = getProp($data, 'act_duration', 0);
|
|
|
+ $video_url = getProp($data, 'video_url');
|
|
|
+
|
|
|
+ // 根据prev_act_id获取记录
|
|
|
+ $prev_segment = DB::table('mp_episode_segments')->where('id', $prev_act_id)->first();
|
|
|
+ if (!$prev_segment) Utils::throwError('20003:该片段不存在');
|
|
|
+
|
|
|
+ $anime_id = getProp($prev_segment, 'anime_id');
|
|
|
+ $episode_id = getProp($prev_segment, 'episode_id');
|
|
|
+ $episode_number = getProp($prev_segment, 'episode_number');
|
|
|
+ $prev_act_number = getProp($prev_segment, 'act_number');
|
|
|
+
|
|
|
+ // 获取新的act_number
|
|
|
+ $new_act_number = $prev_act_number + 1;
|
|
|
+
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ // 更新后续所有act的act_number(全能模式下每个act只有一条记录)
|
|
|
+ DB::table('mp_episode_segments')
|
|
|
+ ->where('anime_id', $anime_id)
|
|
|
+ ->where('episode_id', $episode_id)
|
|
|
+ ->where('act_number', '>', $prev_act_number)
|
|
|
+ ->increment('act_number');
|
|
|
+
|
|
|
+ // 插入新片段记录
|
|
|
+ $insert_data = [
|
|
|
+ 'anime_id' => $anime_id,
|
|
|
+ 'episode_id' => $episode_id,
|
|
|
+ 'episode_number' => $episode_number,
|
|
|
+ 'act_number' => $new_act_number,
|
|
|
+ 'created_at' => date('Y-m-d H:i:s'),
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s')
|
|
|
+ ];
|
|
|
+ if ($act_title) {
|
|
|
+ $insert_data['act_title'] = $act_title;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($act_content) {
|
|
|
+ $insert_data['act_content'] = $act_content;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($act_duration) {
|
|
|
+ $insert_data['act_duration'] = $act_duration;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($video_url) {
|
|
|
+ $insert_data['origin_video_url'] = $video_url;
|
|
|
+ $insert_data['current_type'] = 2;
|
|
|
+ $compressed_video_url = compressVideo($video_url);
|
|
|
+ $insert_data['video_url'] = $compressed_video_url ?: $video_url;
|
|
|
+ }
|
|
|
+
|
|
|
+ $id = DB::table('mp_episode_segments')->insertGetId($insert_data);
|
|
|
+ if (!$id) {
|
|
|
+ Utils::throwError('20003:新增片段失败!');
|
|
|
+ }
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ }catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ Utils::throwError('20003:'.$e->getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ $segment = DB::table('mp_episode_segments')->selectRaw("id as act_id,anime_id,episode_id,episode_number,act_number,act_title,act_duration,act_content,video_url,video_duration,video_time_point_start,video_time_point_end")->where('id', $id)->first();
|
|
|
+ $segment = $segment ? (array)$segment : [];
|
|
|
+ return $segment;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function editAct($data) {
|
|
|
+ $act_id = getProp($data, 'act_id');
|
|
|
+ $act_content = getProp($data, 'act_content');
|
|
|
+ $act_duration = getProp($data, 'act_duration');
|
|
|
+ $act_title = getProp($data, 'act_title');
|
|
|
+ $image_url = getProp($data, 'image_url');
|
|
|
+ $video_url = getProp($data, 'video_url');
|
|
|
+
|
|
|
+ // 参数验证
|
|
|
+ if (!$act_id) Utils::throwError('20003:请提供片段ID');
|
|
|
+
|
|
|
+ // 验证片段是否存在(全能模式下每个act只有一条记录)
|
|
|
+ $segment = DB::table('mp_episode_segments')
|
|
|
+ ->where('id', $act_id)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$segment) Utils::throwError('20003:该片段不存在');
|
|
|
+
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ // 准备更新数据
|
|
|
+ $update_data = [
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s')
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 更新act相关字段
|
|
|
+ if (!empty($act_content)) {
|
|
|
+ $update_data['act_content'] = $act_content;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!empty($act_duration)) {
|
|
|
+ $update_data['act_duration'] = $act_duration;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!empty($act_title)) {
|
|
|
+ $update_data['act_title'] = $act_title;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理图片上传
|
|
|
+ if ($image_url) {
|
|
|
+ $update_data['img_url'] = $image_url;
|
|
|
+ $update_data['current_type'] = 1;
|
|
|
+
|
|
|
+ // 同时写入一个图片生成任务记录
|
|
|
+ if ($act_id) {
|
|
|
+ $pic_task = [
|
|
|
+ 'alias_act_id' => $act_id,
|
|
|
+ 'ref_img_url' => json_encode([]),
|
|
|
+ 'status' => 'success',
|
|
|
+ 'result_url' => json_encode([$image_url], 256),
|
|
|
+ 'model' => '',
|
|
|
+ 'created_at' => date('Y-m-d H:i:s'),
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s'),
|
|
|
+ ];
|
|
|
+
|
|
|
+ DB::table('mp_generate_pic_tasks')->insert($pic_task);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理视频上传
|
|
|
+ if ($video_url) {
|
|
|
+ $update_data['origin_video_url'] = $video_url;
|
|
|
+ $compressed_video_url = compressVideo($video_url);
|
|
|
+ $update_data['current_type'] = 2;
|
|
|
+ $update_data['video_url'] = $compressed_video_url ?: $video_url;
|
|
|
+
|
|
|
+ // 同时写入一个视频生成任务记录
|
|
|
+ if ($act_id) {
|
|
|
+ $video_task = [
|
|
|
+ 'alias_act_id' => $act_id,
|
|
|
+ 'status' => 'success',
|
|
|
+ 'result_url' => $update_data['origin_video_url'],
|
|
|
+ 'compressed_url' => $update_data['video_url'],
|
|
|
+ 'created_at' => date('Y-m-d H:i:s'),
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s'),
|
|
|
+ ];
|
|
|
+
|
|
|
+ DB::table('mp_generate_video_tasks')->insert($video_task);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新片段信息
|
|
|
+ $result = DB::table('mp_episode_segments')
|
|
|
+ ->where('id', $act_id)
|
|
|
+ ->update($update_data);
|
|
|
+
|
|
|
+ if ($result === false) {
|
|
|
+ Utils::throwError('20003:更新片段失败');
|
|
|
+ }
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+
|
|
|
+ return true;
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ dLog('anime')->error('更新片段失败', [
|
|
|
+ 'act_id' => $act_id,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+ Utils::throwError('20003:更新片段失败 ' . $e->getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public function copyAct($data) {
|
|
|
+ $act_id = getProp($data, 'act_id');
|
|
|
+
|
|
|
+ // 根据act_id获取记录(全能模式下每个act只有一条记录)
|
|
|
+ $source_segment = DB::table('mp_episode_segments')->where('id', $act_id)->first();
|
|
|
+ if (!$source_segment) Utils::throwError('20003:请选择片段');
|
|
|
+ $video_url = getProp($source_segment, 'video_url');
|
|
|
+ if (!$video_url) Utils::throwError('20003:该片段没有视频无法复制');
|
|
|
+
|
|
|
+ $anime_id = getProp($source_segment, 'anime_id');
|
|
|
+ $episode_id = getProp($source_segment, 'episode_id');
|
|
|
+ $episode_number = getProp($source_segment, 'episode_number');
|
|
|
+ $act_number = getProp($source_segment, 'act_number');
|
|
|
+
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ // 新act的编号
|
|
|
+ $new_act_number = $act_number + 1;
|
|
|
+
|
|
|
+ // 更新后续所有act的act_number
|
|
|
+ DB::table('mp_episode_segments')
|
|
|
+ ->where('anime_id', $anime_id)
|
|
|
+ ->where('episode_id', $episode_id)
|
|
|
+ ->where('act_number', '>', $act_number)
|
|
|
+ ->increment('act_number');
|
|
|
+
|
|
|
+ // 复制该片段记录
|
|
|
+ $segment_data = (array)$source_segment;
|
|
|
+ unset($segment_data['id']);
|
|
|
+ $segment_data['act_number'] = $new_act_number;
|
|
|
+ $segment_data['created_at'] = $segment_data['updated_at'] = date('Y-m-d H:i:s');
|
|
|
+
|
|
|
+ $id = DB::table('mp_episode_segments')->insertGetId($segment_data);
|
|
|
+ if (!$id) {
|
|
|
+ Utils::throwError('20003:复制片段失败');
|
|
|
+ }
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ }catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ Utils::throwError('20003:'.$e->getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 返回新复制的记录
|
|
|
+ $new_segment = DB::table('mp_episode_segments')->selectRaw("id as act_id,anime_id,episode_id,episode_number,act_number,act_title,act_duration,act_content,video_url,video_duration,video_time_point_start,video_time_point_end")->where('id', $id)->first();
|
|
|
+ $new_segment = $new_segment ? (array)$new_segment : [];
|
|
|
+ $new_segment['act_id'] = $id;
|
|
|
+ return $new_segment;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function moveAct($data) {
|
|
|
+ $act_id = getProp($data, 'act_id');
|
|
|
+ $target_act_id = getProp($data, 'target_act_id');
|
|
|
+
|
|
|
+ // 获取源片段信息
|
|
|
+ $source_segment = DB::table('mp_episode_segments')->where('id', $act_id)->first();
|
|
|
+ if (!$source_segment) Utils::throwError('20003:请选择片段');
|
|
|
+
|
|
|
+ // 获取目标片段信息
|
|
|
+ $target_segment = DB::table('mp_episode_segments')->where('id', $target_act_id)->first();
|
|
|
+ if (!$target_segment) Utils::throwError('20003:目标片段不存在');
|
|
|
+
|
|
|
+ $anime_id = getProp($source_segment, 'anime_id');
|
|
|
+ $episode_id = getProp($source_segment, 'episode_id');
|
|
|
+ $source_act_number = getProp($source_segment, 'act_number');
|
|
|
+ $target_act_number = getProp($target_segment, 'act_number');
|
|
|
+
|
|
|
+ // 验证源片段和目标片段必须属于同一个动漫的同一集
|
|
|
+ $target_anime_id = getProp($target_segment, 'anime_id');
|
|
|
+ $target_episode_id = getProp($target_segment, 'episode_id');
|
|
|
+
|
|
|
+ if ($anime_id != $target_anime_id || $episode_id != $target_episode_id) {
|
|
|
+ Utils::throwError('20003:只能在同一动漫的同一集内移动片段');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果源片段和目标片段相同,无需移动
|
|
|
+ if ($source_act_number == $target_act_number) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ if ($source_act_number < $target_act_number) {
|
|
|
+ // 向后移动:源片段移动到目标片段之后
|
|
|
+ // 1. 将源片段和目标片段之间的所有片段编号减1
|
|
|
+ DB::table('mp_episode_segments')
|
|
|
+ ->where('anime_id', $anime_id)
|
|
|
+ ->where('episode_id', $episode_id)
|
|
|
+ ->where('act_number', '>', $source_act_number)
|
|
|
+ ->where('act_number', '<=', $target_act_number)
|
|
|
+ ->decrement('act_number');
|
|
|
+
|
|
|
+ // 2. 将源片段移动到目标片段之后
|
|
|
+ $new_act_number = $target_act_number;
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // 向前移动:源片段移动到目标片段之后
|
|
|
+ // 1. 将目标片段之后到源片段之前的所有片段编号加1
|
|
|
+ DB::table('mp_episode_segments')
|
|
|
+ ->where('anime_id', $anime_id)
|
|
|
+ ->where('episode_id', $episode_id)
|
|
|
+ ->where('act_number', '>', $target_act_number)
|
|
|
+ ->where('act_number', '<', $source_act_number)
|
|
|
+ ->increment('act_number');
|
|
|
+
|
|
|
+ // 2. 将源片段移动到目标片段之后
|
|
|
+ $new_act_number = $target_act_number + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 更新源片段的编号
|
|
|
+ $update_result = DB::table('mp_episode_segments')
|
|
|
+ ->where('id', $act_id)
|
|
|
+ ->update([
|
|
|
+ 'act_number' => $new_act_number,
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s')
|
|
|
+ ]);
|
|
|
+
|
|
|
+ if (!$update_result) {
|
|
|
+ Utils::throwError('20003:更新片段编号失败');
|
|
|
+ }
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ return true;
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ Utils::throwError('20003:' . $e->getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public function delAct($data) {
|
|
|
+ $act_id = getProp($data, 'act_id');
|
|
|
+
|
|
|
+ // 根据act_id获取记录(全能模式下每个act只有一条记录)
|
|
|
+ $segment = DB::table('mp_episode_segments')->where('id', $act_id)->first();
|
|
|
+ if (!$segment) Utils::throwError('20003:请选择片段');
|
|
|
+
|
|
|
+ $anime_id = getProp($segment, 'anime_id');
|
|
|
+ $episode_id = getProp($segment, 'episode_id');
|
|
|
+ $act_number = getProp($segment, 'act_number');
|
|
|
+
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ // 删除该片段记录
|
|
|
+ $deleted = DB::table('mp_episode_segments')->where('id', $act_id)->delete();
|
|
|
+ if (!$deleted) {
|
|
|
+ Utils::throwError('20003:删除片段失败');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新后续act的编号
|
|
|
+ DB::table('mp_episode_segments')
|
|
|
+ ->where('anime_id', $anime_id)
|
|
|
+ ->where('episode_id', $episode_id)
|
|
|
+ ->where('act_number', '>', $act_number)
|
|
|
+ ->decrement('act_number');
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ }catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ Utils::throwError('20003:'.$e->getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function applyAct($data) {
|
|
|
+ $act_id = getProp($data, 'act_id');
|
|
|
+ $url = getProp($data, 'url');
|
|
|
+
|
|
|
+ if (!$act_id) Utils::throwError('20003:请选择片段');
|
|
|
+ if (!$url) Utils::throwError('20003:URL不能为空');
|
|
|
+
|
|
|
+ // 获取URL的文件扩展名
|
|
|
+ $urlPath = parse_url($url, PHP_URL_PATH);
|
|
|
+ $extension = strtolower(pathinfo($urlPath, PATHINFO_EXTENSION));
|
|
|
+
|
|
|
+ // 定义图片和视频的扩展名
|
|
|
+ $imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'];
|
|
|
+ $videoExtensions = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm', 'm4v'];
|
|
|
+
|
|
|
+ // 判断是图片还是视频
|
|
|
+ $updateData = ['updated_at' => date('Y-m-d H:i:s')];
|
|
|
+
|
|
|
+ if (in_array($extension, $imageExtensions)) {
|
|
|
+ // 图片类型
|
|
|
+ $updateData['img_url'] = $url;
|
|
|
+ $updateData['current_type'] = 1;
|
|
|
+ } elseif (in_array($extension, $videoExtensions)) {
|
|
|
+ // 视频类型
|
|
|
+ $updateData['video_url'] = $url;
|
|
|
+ $updateData['current_type'] = 2;
|
|
|
+ } else {
|
|
|
+ Utils::throwError('20003:不支持的文件类型');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新片段记录(全能模式下每个act只有一条记录)
|
|
|
+ $result = DB::table('mp_episode_segments')
|
|
|
+ ->where('id', $act_id)
|
|
|
+ ->update($updateData);
|
|
|
+
|
|
|
+ if (!$result) {
|
|
|
+ Utils::throwError('20003:更新片段失败');
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function actChatHistory($data) {
|
|
|
+ $act_id = getProp($data, 'act_id');
|
|
|
+
|
|
|
+ if (!$act_id) Utils::throwError('20003:请选择片段!');
|
|
|
+
|
|
|
+ $query = DB::table('mp_anime_records')->where('act_id', $act_id)->select('role', 'content', 'act_id', 'image_url', 'video_url', 'created_at');
|
|
|
+
|
|
|
+ $chat = $query->orderBy('id')->get()->map(function ($value) {
|
|
|
+ $value = (array)$value;
|
|
|
+ $value['created_at'] = transDate($value['created_at']);
|
|
|
+ return $value;
|
|
|
+ })->toArray();
|
|
|
+
|
|
|
+ // 获取历史图片
|
|
|
+ $url = [];
|
|
|
+ $pic_history = DB::table('mp_generate_pic_tasks')->where('alias_act_id', $act_id)->where('status', 'success')->orderBy('created_at', 'desc')->get();
|
|
|
+ foreach($pic_history as $task) {
|
|
|
+ $result_url = getProp($task, 'result_url');
|
|
|
+ if (is_json($result_url)) {
|
|
|
+ $url = array_merge($url, json_decode($result_url, true));
|
|
|
+ }else {
|
|
|
+ $url[] = $result_url;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取历史视频
|
|
|
+ $video_history = DB::table('mp_generate_video_tasks')->where('alias_act_id', $act_id)->where('status', 'success')->orderBy('created_at', 'desc')->get();
|
|
|
+ foreach($video_history as $task) {
|
|
|
+ $result_url = getProp($task, 'compressed_url');
|
|
|
+ if (is_json($result_url)) {
|
|
|
+ $url = array_merge($url, json_decode($result_url, true));
|
|
|
+ }else {
|
|
|
+ $url[] = $result_url;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return compact('chat', 'url');
|
|
|
+ }
|
|
|
+
|
|
|
public function applyAudioData($data) {
|
|
|
$segment_id = getProp($data, 'segment_id');
|
|
|
$global_data = getProp($data, 'global_data');
|