forked from 77media/video-flow
更新角色和视频任务的保存逻辑,重构SaveEditUseCase以支持角色和视频任务的管理,优化相关服务的接口调用。
This commit is contained in:
parent
2ab25bc72c
commit
7abf41a83d
@ -1108,8 +1108,13 @@ export const checkShotVideoStatus = async (request: {
|
|||||||
export const modifyCharacterOrScene = async (request: {
|
export const modifyCharacterOrScene = async (request: {
|
||||||
/** 项目ID */
|
/** 项目ID */
|
||||||
project_id: string;
|
project_id: string;
|
||||||
/** 角色ID(可能为null) */
|
/** 新的角色库角色 */
|
||||||
character_id?: string | null;
|
character_id: {
|
||||||
|
/** 角色ID */
|
||||||
|
character_id: string;
|
||||||
|
/** 角色名称 */
|
||||||
|
name: string;
|
||||||
|
}[];
|
||||||
/** 视频任务关联列表 */
|
/** 视频任务关联列表 */
|
||||||
video_tasks: Array<{
|
video_tasks: Array<{
|
||||||
/** 生成视频的任务ID */
|
/** 生成视频的任务ID */
|
||||||
@ -1117,30 +1122,7 @@ export const modifyCharacterOrScene = async (request: {
|
|||||||
/** 该任务对应的video_id列表 */
|
/** 该任务对应的video_id列表 */
|
||||||
video_ids: string[];
|
video_ids: string[];
|
||||||
}>;
|
}>;
|
||||||
}): Promise<ApiResponse<{
|
}) => {
|
||||||
/** 项目ID */
|
|
||||||
project_id: string;
|
|
||||||
/** 自动检测到的修改类型("character" 或 "scene") */
|
|
||||||
modify_type: "character" | "scene";
|
|
||||||
/** 传入的视频任务列表 */
|
|
||||||
video_tasks: Array<{
|
|
||||||
task_id: string;
|
|
||||||
video_ids: string[];
|
|
||||||
}>;
|
|
||||||
/** 处理结果描述 */
|
|
||||||
message: string;
|
|
||||||
/** 详细处理信息 */
|
|
||||||
details: Record<string, any>;
|
|
||||||
/** 警告信息(如有) */
|
|
||||||
warning: string | null;
|
|
||||||
/** 启动的视频检测任务列表 */
|
|
||||||
video_check_tasks: Array<{
|
|
||||||
task_id: string;
|
|
||||||
video_ids: string[];
|
|
||||||
}>;
|
|
||||||
/** 启动的视频检测任务数量 */
|
|
||||||
video_check_started: number;
|
|
||||||
}>> => {
|
|
||||||
return post<ApiResponse<{
|
return post<ApiResponse<{
|
||||||
project_id: string;
|
project_id: string;
|
||||||
modify_type: "character" | "scene";
|
modify_type: "character" | "scene";
|
||||||
|
|||||||
@ -1,8 +1,12 @@
|
|||||||
import { useState, useCallback, useMemo } from 'react';
|
import { useState, useCallback, useMemo } from "react";
|
||||||
import { RoleEntity, AITextEntity } from '../domain/Entities';
|
import { RoleEntity, AITextEntity } from "../domain/Entities";
|
||||||
import { RoleEditUseCase } from '../usecase/RoleEditUseCase';
|
import { RoleEditUseCase } from "../usecase/RoleEditUseCase";
|
||||||
import { getUploadToken, uploadToQiniu } from '@/api/common';
|
import { getUploadToken, uploadToQiniu } from "@/api/common";
|
||||||
import { analyzeImageDescription, checkShotVideoStatus } from '@/api/video_flow';
|
import {
|
||||||
|
analyzeImageDescription,
|
||||||
|
checkShotVideoStatus,
|
||||||
|
} from "@/api/video_flow";
|
||||||
|
import { SaveEditUseCase } from "../usecase/SaveEditUseCase";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色服务Hook返回值接口
|
* 角色服务Hook返回值接口
|
||||||
@ -52,11 +56,12 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
const [selectedRole, setSelectedRole] = useState<RoleEntity | null>(null);
|
const [selectedRole, setSelectedRole] = useState<RoleEntity | null>(null);
|
||||||
const [currentRoleText, setCurrentRoleText] = useState<string | null>(null);
|
const [currentRoleText, setCurrentRoleText] = useState<string | null>(null);
|
||||||
const [userRoleLibrary, setUserRoleLibrary] = useState<RoleEntity[]>([]);
|
const [userRoleLibrary, setUserRoleLibrary] = useState<RoleEntity[]>([]);
|
||||||
const [projectId, setProjectId] = useState<string>(''); // 添加项目ID状态
|
const [projectId, setProjectId] = useState<string>(""); // 添加项目ID状态
|
||||||
const [cacheRole, setCacheRole] = useState<RoleEntity | null>(null);
|
const [cacheRole, setCacheRole] = useState<RoleEntity | null>(null);
|
||||||
|
|
||||||
// UseCase实例 - 在角色选择时初始化
|
// UseCase实例 - 在角色选择时初始化
|
||||||
const [roleEditUseCase, setRoleEditUseCase] = useState<RoleEditUseCase | null>(null);
|
const [roleEditUseCase, setRoleEditUseCase] =
|
||||||
|
useState<RoleEditUseCase | null>(null);
|
||||||
|
|
||||||
// 计算属性
|
// 计算属性
|
||||||
/**
|
/**
|
||||||
@ -64,7 +69,7 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
* @description 获取当前选中角色的图片URL
|
* @description 获取当前选中角色的图片URL
|
||||||
*/
|
*/
|
||||||
const roleImageUrl = useMemo(() => {
|
const roleImageUrl = useMemo(() => {
|
||||||
return selectedRole?.imageUrl || '';
|
return selectedRole?.imageUrl || "";
|
||||||
}, [selectedRole]);
|
}, [selectedRole]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,31 +91,32 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
setRoleList(roleList);
|
setRoleList(roleList);
|
||||||
setRoleEditUseCase(newRoleEditUseCase);
|
setRoleEditUseCase(newRoleEditUseCase);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取角色列表失败:', error);
|
console.error("获取角色列表失败:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 选择角色
|
* 选择角色
|
||||||
* @description 根据角色ID选择角色,并初始化相关的UseCase实例
|
* @description 根据角色ID选择角色,并初始化相关的UseCase实例
|
||||||
* @param roleId 角色ID
|
* @param roleId 角色ID
|
||||||
*/
|
*/
|
||||||
const selectRole = useCallback(async (role: RoleEntity) => {
|
const selectRole = useCallback(
|
||||||
console.log('selectRole', role);
|
async (role: RoleEntity) => {
|
||||||
|
console.log("selectRole", role);
|
||||||
// 根据 role.name 完全替换掉旧的数据
|
// 根据 role.name 完全替换掉旧的数据
|
||||||
setRoleList(prev => prev.map(r => r.name === role.name ? role : r));
|
setRoleList((prev) => prev.map((r) => (r.name === role.name ? role : r)));
|
||||||
setSelectedRole(role);
|
setSelectedRole(role);
|
||||||
// 如果缓存角色为空,则设置缓存角色,名字不同也切换
|
// 如果缓存角色为空,则设置缓存角色,名字不同也切换
|
||||||
if(!cacheRole||cacheRole.name!==role.name){
|
if (!cacheRole || cacheRole.name !== role.name) {
|
||||||
setCacheRole(role);
|
setCacheRole(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用selectRole方法
|
// 调用selectRole方法
|
||||||
roleEditUseCase!.selectRole(role);
|
roleEditUseCase!.selectRole(role);
|
||||||
|
},
|
||||||
}, [roleEditUseCase]);
|
[roleEditUseCase]
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 优化AI文本
|
* 优化AI文本
|
||||||
@ -120,36 +126,39 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
*/
|
*/
|
||||||
const optimizeRoleText = useCallback(async () => {
|
const optimizeRoleText = useCallback(async () => {
|
||||||
if (!roleEditUseCase) {
|
if (!roleEditUseCase) {
|
||||||
throw new Error('角色编辑UseCase未初始化');
|
throw new Error("角色编辑UseCase未初始化");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!currentRoleText) {
|
if (!currentRoleText) {
|
||||||
throw new Error('没有可优化的文本内容');
|
throw new Error("没有可优化的文本内容");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!selectedRole) {
|
if (!selectedRole) {
|
||||||
throw new Error('没有选中的角色');
|
throw new Error("没有选中的角色");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { optimizedDescription, keywords } = await roleEditUseCase.optimizeRoleDescription(selectedRole);
|
const { optimizedDescription, keywords } =
|
||||||
|
await roleEditUseCase.optimizeRoleDescription(selectedRole);
|
||||||
setCurrentRoleText(optimizedDescription);
|
setCurrentRoleText(optimizedDescription);
|
||||||
// 更新角色列表中的对应角色描述和标签
|
// 更新角色列表中的对应角色描述和标签
|
||||||
setRoleList(prev =>
|
setRoleList((prev) =>
|
||||||
prev.map(role =>
|
prev.map((role) =>
|
||||||
role.id === selectedRole?.id
|
role.id === selectedRole?.id
|
||||||
? {
|
? {
|
||||||
...role,
|
...role,
|
||||||
generateText: optimizedDescription,
|
generateText: optimizedDescription,
|
||||||
tags: keywords.map(keyword => ({
|
tags: keywords.map((keyword) => ({
|
||||||
id: `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
id: `tag_${Date.now()}_${Math.random()
|
||||||
|
.toString(36)
|
||||||
|
.substr(2, 9)}`,
|
||||||
/** 名称 */
|
/** 名称 */
|
||||||
name: keyword,
|
name: keyword,
|
||||||
/** 内容 */
|
/** 内容 */
|
||||||
content: keyword,
|
content: keyword,
|
||||||
loadingProgress: 100,
|
loadingProgress: 100,
|
||||||
disableEdit: false
|
disableEdit: false,
|
||||||
}))
|
})),
|
||||||
}
|
}
|
||||||
: role
|
: role
|
||||||
)
|
)
|
||||||
@ -157,18 +166,22 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
|
|
||||||
// 更新当前选中角色
|
// 更新当前选中角色
|
||||||
if (selectedRole) {
|
if (selectedRole) {
|
||||||
selectRole({ ...selectedRole, generateText: optimizedDescription, tags: keywords.map(keyword => ({
|
selectRole({
|
||||||
|
...selectedRole,
|
||||||
|
generateText: optimizedDescription,
|
||||||
|
tags: keywords.map((keyword) => ({
|
||||||
id: `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
id: `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
||||||
/** 名称 */
|
/** 名称 */
|
||||||
name: keyword,
|
name: keyword,
|
||||||
/** 内容 */
|
/** 内容 */
|
||||||
content: keyword,
|
content: keyword,
|
||||||
loadingProgress: 100,
|
loadingProgress: 100,
|
||||||
disableEdit: false
|
disableEdit: false,
|
||||||
})) });
|
})),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('优化角色文本失败:', error);
|
console.error("优化角色文本失败:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}, [roleEditUseCase, currentRoleText, selectedRole, selectRole]);
|
}, [roleEditUseCase, currentRoleText, selectedRole, selectRole]);
|
||||||
@ -180,16 +193,17 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
* @throws {Error} 当没有可编辑的文本或UseCase未初始化时抛出错误
|
* @throws {Error} 当没有可编辑的文本或UseCase未初始化时抛出错误
|
||||||
* @returns {Promise<void>} 修改完成后的Promise
|
* @returns {Promise<void>} 修改完成后的Promise
|
||||||
*/
|
*/
|
||||||
const updateRoleText = useCallback(async (newContent: string) => {
|
const updateRoleText = useCallback(
|
||||||
|
async (newContent: string) => {
|
||||||
if (!roleEditUseCase) {
|
if (!roleEditUseCase) {
|
||||||
throw new Error('角色编辑UseCase未初始化');
|
throw new Error("角色编辑UseCase未初始化");
|
||||||
}
|
}
|
||||||
|
|
||||||
setCurrentRoleText(newContent);
|
setCurrentRoleText(newContent);
|
||||||
|
|
||||||
// 更新角色列表中的对应角色描述
|
// 更新角色列表中的对应角色描述
|
||||||
setRoleList(prev =>
|
setRoleList((prev) =>
|
||||||
prev.map(role =>
|
prev.map((role) =>
|
||||||
role.id === selectedRole?.id
|
role.id === selectedRole?.id
|
||||||
? { ...role, generateText: newContent }
|
? { ...role, generateText: newContent }
|
||||||
: role
|
: role
|
||||||
@ -200,7 +214,9 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
if (selectedRole) {
|
if (selectedRole) {
|
||||||
selectRole({ ...selectedRole, generateText: newContent });
|
selectRole({ ...selectedRole, generateText: newContent });
|
||||||
}
|
}
|
||||||
}, [roleEditUseCase, selectRole, selectedRole]);
|
},
|
||||||
|
[roleEditUseCase, selectRole, selectedRole]
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重新生成角色
|
* 重新生成角色
|
||||||
@ -210,15 +226,15 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
*/
|
*/
|
||||||
const regenerateRole = useCallback(async () => {
|
const regenerateRole = useCallback(async () => {
|
||||||
if (!roleEditUseCase) {
|
if (!roleEditUseCase) {
|
||||||
throw new Error('角色编辑UseCase未初始化');
|
throw new Error("角色编辑UseCase未初始化");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!selectedRole || !currentRoleText) {
|
if (!selectedRole || !currentRoleText) {
|
||||||
throw new Error('缺少重新生成角色所需的数据');
|
throw new Error("缺少重新生成角色所需的数据");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!projectId) {
|
if (!projectId) {
|
||||||
throw new Error('缺少项目ID,无法重新生成角色');
|
throw new Error("缺少项目ID,无法重新生成角色");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -230,15 +246,13 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
selectRole(newRoleEntity);
|
selectRole(newRoleEntity);
|
||||||
|
|
||||||
// 更新角色列表
|
// 更新角色列表
|
||||||
setRoleList(prev =>
|
setRoleList((prev) =>
|
||||||
prev.map(role =>
|
prev.map((role) =>
|
||||||
role.id === newRoleEntity.id
|
role.id === newRoleEntity.id ? newRoleEntity : role
|
||||||
? newRoleEntity
|
|
||||||
: role
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('重新生成角色失败:', error);
|
console.error("重新生成角色失败:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}, [roleEditUseCase, selectedRole, currentRoleText, projectId, selectRole]);
|
}, [roleEditUseCase, selectedRole, currentRoleText, projectId, selectRole]);
|
||||||
@ -263,16 +277,19 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
const User = JSON.parse(localStorage.getItem("currentUser") || "{}");
|
const User = JSON.parse(localStorage.getItem("currentUser") || "{}");
|
||||||
|
|
||||||
if (!User.id) {
|
if (!User.id) {
|
||||||
throw new Error('无法获取用户ID,请重新登录');
|
throw new Error("无法获取用户ID,请重新登录");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前选中角色的描述
|
// 获取当前选中角色的描述
|
||||||
const userDescription = selectedRole?.generateText || '';
|
const userDescription = selectedRole?.generateText || "";
|
||||||
|
|
||||||
const roleLibraryList = await useCase!.getRoleLibraryList(User.id, userDescription);
|
const roleLibraryList = await useCase!.getRoleLibraryList(
|
||||||
|
User.id,
|
||||||
|
userDescription
|
||||||
|
);
|
||||||
setUserRoleLibrary(roleLibraryList);
|
setUserRoleLibrary(roleLibraryList);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取用户角色库失败:', error);
|
console.error("获取用户角色库失败:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}, [roleEditUseCase, selectedRole]);
|
}, [roleEditUseCase, selectedRole]);
|
||||||
@ -284,43 +301,46 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
* @throws {Error} 当未选择角色、API调用失败或UseCase未初始化时抛出错误
|
* @throws {Error} 当未选择角色、API调用失败或UseCase未初始化时抛出错误
|
||||||
* @returns {Promise<void>} 替换完成后的Promise
|
* @returns {Promise<void>} 替换完成后的Promise
|
||||||
*/
|
*/
|
||||||
const replaceRoleWithLibrary = useCallback(async (replaceRoleId: string) => {
|
const replaceRoleWithLibrary = useCallback(
|
||||||
|
async (replaceRoleId: string) => {
|
||||||
if (!selectedRole) {
|
if (!selectedRole) {
|
||||||
throw new Error('请先选择角色');
|
throw new Error("请先选择角色");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!roleEditUseCase) {
|
if (!roleEditUseCase) {
|
||||||
throw new Error('角色编辑UseCase未初始化');
|
throw new Error("角色编辑UseCase未初始化");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await roleEditUseCase.replaceRoleById(selectedRole.id, replaceRoleId);
|
await roleEditUseCase.replaceRoleById(selectedRole.id, replaceRoleId);
|
||||||
|
|
||||||
// 更新角色列表
|
// 更新角色列表
|
||||||
const libraryRole = userRoleLibrary.find(role => role.id === replaceRoleId);
|
const libraryRole = userRoleLibrary.find(
|
||||||
|
(role) => role.id === replaceRoleId
|
||||||
|
);
|
||||||
if (libraryRole) {
|
if (libraryRole) {
|
||||||
const updatedRole = {
|
const updatedRole = {
|
||||||
...selectedRole,
|
...selectedRole,
|
||||||
name: libraryRole.name,
|
name: libraryRole.name,
|
||||||
generateText: libraryRole.generateText,
|
generateText: libraryRole.generateText,
|
||||||
imageUrl: libraryRole.imageUrl,
|
imageUrl: libraryRole.imageUrl,
|
||||||
fromDraft: false
|
fromDraft: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
selectRole(updatedRole);
|
selectRole(updatedRole);
|
||||||
setRoleList(prev =>
|
setRoleList((prev) =>
|
||||||
prev.map(role =>
|
prev.map((role) =>
|
||||||
role.id === selectedRole.id
|
role.id === selectedRole.id ? updatedRole : role
|
||||||
? updatedRole
|
|
||||||
: role
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('替换角色失败:', error);
|
console.error("替换角色失败:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}, [selectedRole, roleEditUseCase, userRoleLibrary, selectRole]);
|
},
|
||||||
|
[selectedRole, roleEditUseCase, userRoleLibrary, selectRole]
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传图片并更新角色信息
|
* 上传图片并更新角色信息
|
||||||
@ -328,9 +348,10 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
* @param file 要上传的文件
|
* @param file 要上传的文件
|
||||||
* @returns {Promise<void>} 上传和分析完成后的Promise
|
* @returns {Promise<void>} 上传和分析完成后的Promise
|
||||||
*/
|
*/
|
||||||
const uploadImageAndUpdateRole = useCallback(async (file: File) => {
|
const uploadImageAndUpdateRole = useCallback(
|
||||||
|
async (file: File) => {
|
||||||
if (!selectedRole) {
|
if (!selectedRole) {
|
||||||
throw new Error('请先选择要更新的角色');
|
throw new Error("请先选择要更新的角色");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -340,7 +361,7 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
|
|
||||||
// 2. 调用图片分析接口获取描述
|
// 2. 调用图片分析接口获取描述
|
||||||
const result = await analyzeImageDescription({
|
const result = await analyzeImageDescription({
|
||||||
image_url: imageUrl
|
image_url: imageUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result.successful) {
|
if (!result.successful) {
|
||||||
@ -361,29 +382,26 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
/** 内容 */
|
/** 内容 */
|
||||||
content: highlight,
|
content: highlight,
|
||||||
loadingProgress: 100,
|
loadingProgress: 100,
|
||||||
disableEdit: false
|
disableEdit: false,
|
||||||
}))
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
// 更新选中的角色
|
// 更新选中的角色
|
||||||
selectRole(updatedRole);
|
selectRole(updatedRole);
|
||||||
|
|
||||||
// 更新角色列表中的对应角色
|
// 更新角色列表中的对应角色
|
||||||
setRoleList(prev =>
|
setRoleList((prev) =>
|
||||||
prev.map(role =>
|
prev.map((role) => (role.id === selectedRole.id ? updatedRole : role))
|
||||||
role.id === selectedRole.id
|
|
||||||
? updatedRole
|
|
||||||
: role
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log('角色图片和描述更新成功:', updatedRole);
|
console.log("角色图片和描述更新成功:", updatedRole);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('上传图片并分析失败:', error);
|
console.error("上传图片并分析失败:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}, [selectedRole, roleEditUseCase, selectRole]);
|
},
|
||||||
|
[selectedRole, roleEditUseCase, selectRole]
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存重新生成的角色到角色库
|
* 保存重新生成的角色到角色库
|
||||||
@ -393,15 +411,15 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
*/
|
*/
|
||||||
const saveRoleToLibrary = useCallback(async () => {
|
const saveRoleToLibrary = useCallback(async () => {
|
||||||
if (!selectedRole) {
|
if (!selectedRole) {
|
||||||
throw new Error('请先选择要保存的角色');
|
throw new Error("请先选择要保存的角色");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!roleEditUseCase) {
|
if (!roleEditUseCase) {
|
||||||
throw new Error('角色编辑UseCase未初始化');
|
throw new Error("角色编辑UseCase未初始化");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!projectId) {
|
if (!projectId) {
|
||||||
throw new Error('缺少项目ID,无法保存角色到角色库');
|
throw new Error("缺少项目ID,无法保存角色到角色库");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -409,7 +427,7 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
const User = JSON.parse(localStorage.getItem("currentUser") || "{}");
|
const User = JSON.parse(localStorage.getItem("currentUser") || "{}");
|
||||||
|
|
||||||
if (!User.id) {
|
if (!User.id) {
|
||||||
throw new Error('无法获取用户ID,请重新登录');
|
throw new Error("无法获取用户ID,请重新登录");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用保存重新生成角色到角色库的方法
|
// 调用保存重新生成角色到角色库的方法
|
||||||
@ -418,11 +436,22 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
projectId,
|
projectId,
|
||||||
String(User.id)
|
String(User.id)
|
||||||
);
|
);
|
||||||
|
selectRole({
|
||||||
|
...selectedRole,
|
||||||
|
id: result.character_id,
|
||||||
|
fromDraft: true,
|
||||||
|
});
|
||||||
|
|
||||||
console.log('角色保存到角色库成功:', result);
|
SaveEditUseCase.setCharacterId([
|
||||||
|
...SaveEditUseCase.characterId,
|
||||||
|
{
|
||||||
|
character_id: result.character_id,
|
||||||
|
name: selectedRole.name,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
console.log("角色保存到角色库成功:", result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('保存角色到角色库失败:', error);
|
console.error("保存角色到角色库失败:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}, [selectedRole, roleEditUseCase, projectId]);
|
}, [selectedRole, roleEditUseCase, projectId]);
|
||||||
@ -435,21 +464,21 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
*/
|
*/
|
||||||
const saveData = useCallback(async () => {
|
const saveData = useCallback(async () => {
|
||||||
if (!projectId) {
|
if (!projectId) {
|
||||||
throw new Error('缺少项目ID,无法保存数据');
|
throw new Error("缺少项目ID,无法保存数据");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await checkShotVideoStatus({
|
const result = await checkShotVideoStatus({
|
||||||
project_id: projectId
|
project_id: projectId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result.successful) {
|
if (!result.successful) {
|
||||||
throw new Error(`保存数据失败: ${result.message}`);
|
throw new Error(`保存数据失败: ${result.message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('数据保存成功');
|
console.log("数据保存成功");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('保存数据失败:', error);
|
console.error("保存数据失败:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}, [projectId]);
|
}, [projectId]);
|
||||||
@ -472,6 +501,6 @@ export const useRoleServiceHook = (): UseRoleService => {
|
|||||||
replaceRoleWithLibrary,
|
replaceRoleWithLibrary,
|
||||||
uploadImageAndUpdateRole,
|
uploadImageAndUpdateRole,
|
||||||
saveRoleToLibrary,
|
saveRoleToLibrary,
|
||||||
saveData
|
saveData,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import {
|
|||||||
import { VideoSegmentEntity } from "../domain/Entities";
|
import { VideoSegmentEntity } from "../domain/Entities";
|
||||||
import { LensType, SimpleCharacter } from "../domain/valueObject";
|
import { LensType, SimpleCharacter } from "../domain/valueObject";
|
||||||
import { getUploadToken, uploadToQiniu } from "@/api/common";
|
import { getUploadToken, uploadToQiniu } from "@/api/common";
|
||||||
|
import { SaveEditUseCase } from "../usecase/SaveEditUseCase";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 视频片段服务Hook接口
|
* 视频片段服务Hook接口
|
||||||
@ -181,7 +182,13 @@ export const useShotService = (): UseShotService => {
|
|||||||
|
|
||||||
// 保存任务ID用于后续状态查询
|
// 保存任务ID用于后续状态查询
|
||||||
setGenerateTaskIds(prev => prev.add(taskResult.task_id));
|
setGenerateTaskIds(prev => prev.add(taskResult.task_id));
|
||||||
|
SaveEditUseCase.setVideoTasks([
|
||||||
|
...SaveEditUseCase.videoTasks,
|
||||||
|
{
|
||||||
|
task_id: taskResult.task_id,
|
||||||
|
video_ids: [selectedSegment!.id],
|
||||||
|
},
|
||||||
|
]);
|
||||||
// 如果重新生成的是现有片段,更新其状态为处理中 (0: 视频加载中)
|
// 如果重新生成的是现有片段,更新其状态为处理中 (0: 视频加载中)
|
||||||
if (selectedSegment) {
|
if (selectedSegment) {
|
||||||
setVideoSegments((prev) =>
|
setVideoSegments((prev) =>
|
||||||
|
|||||||
190
app/service/usecase/SaveEditUseCase.ts
Normal file
190
app/service/usecase/SaveEditUseCase.ts
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
import { modifyCharacterOrScene } from '@/api/video_flow';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存编辑用例类
|
||||||
|
* @description 保存接口所需的参数数据,提供保存和清空方法
|
||||||
|
*/
|
||||||
|
export class SaveEditUseCase {
|
||||||
|
static projectId: string = '';
|
||||||
|
static characterId: {
|
||||||
|
/** 角色ID */
|
||||||
|
character_id: string;
|
||||||
|
/** 角色名称 */
|
||||||
|
name: string;
|
||||||
|
}[] = [];
|
||||||
|
static videoTasks: Array<{
|
||||||
|
task_id: string;
|
||||||
|
video_ids: string[];
|
||||||
|
}> = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置项目ID
|
||||||
|
* @param projectId 项目ID
|
||||||
|
*/
|
||||||
|
static setProjectId(projectId: string): void {
|
||||||
|
SaveEditUseCase.projectId = projectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置角色ID
|
||||||
|
* @param characterId 角色ID
|
||||||
|
*/
|
||||||
|
static setCharacterId(characterId: {
|
||||||
|
/** 角色ID */
|
||||||
|
character_id: string;
|
||||||
|
/** 角色名称 */
|
||||||
|
name: string;
|
||||||
|
}[]): void {
|
||||||
|
// 使用Set根据character_id去重
|
||||||
|
const seenIds = new Set<string>();
|
||||||
|
SaveEditUseCase.characterId = characterId.filter(character => {
|
||||||
|
if (seenIds.has(character.character_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seenIds.add(character.character_id);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置视频任务列表
|
||||||
|
* @param videoTasks 视频任务列表
|
||||||
|
*/
|
||||||
|
static setVideoTasks(videoTasks: Array<{
|
||||||
|
task_id: string;
|
||||||
|
video_ids: string[];
|
||||||
|
}>): void {
|
||||||
|
// 使用Set根据task_id去重
|
||||||
|
const seenIds = new Set<string>();
|
||||||
|
SaveEditUseCase.videoTasks = videoTasks.filter(task => {
|
||||||
|
if (seenIds.has(task.task_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seenIds.add(task.task_id);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加视频任务
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @param videoIds 视频ID列表
|
||||||
|
*/
|
||||||
|
static addVideoTask(taskId: string, videoIds: string[]): void {
|
||||||
|
SaveEditUseCase.videoTasks.push({
|
||||||
|
task_id: taskId,
|
||||||
|
video_ids: videoIds,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主要保存方法
|
||||||
|
* @description 调用保存接口,传入当前类内保存的数据
|
||||||
|
* @returns Promise<保存结果>
|
||||||
|
*/
|
||||||
|
static async saveData(): Promise<{
|
||||||
|
success: boolean;
|
||||||
|
message: string;
|
||||||
|
data?: any;
|
||||||
|
}> {
|
||||||
|
try {
|
||||||
|
if (!SaveEditUseCase.projectId) {
|
||||||
|
throw new Error('项目ID不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SaveEditUseCase.videoTasks.length === 0) {
|
||||||
|
throw new Error('视频任务列表不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await modifyCharacterOrScene({
|
||||||
|
project_id: SaveEditUseCase.projectId,
|
||||||
|
character_id: SaveEditUseCase.characterId,
|
||||||
|
video_tasks: SaveEditUseCase.videoTasks,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.successful) {
|
||||||
|
throw new Error(response.message || '保存数据失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: '数据保存成功',
|
||||||
|
data: response.data,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存数据失败:', error);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: error instanceof Error ? error.message : '保存数据失败',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存角色数据方法
|
||||||
|
* @description 保存character_id数据
|
||||||
|
* @returns Promise<保存结果>
|
||||||
|
*/
|
||||||
|
static async saveRoleData(): Promise<{
|
||||||
|
success: boolean;
|
||||||
|
message: string;
|
||||||
|
data?: any;
|
||||||
|
}> {
|
||||||
|
// 角色数据保存就是保存character_id
|
||||||
|
return SaveEditUseCase.saveData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存镜头数据方法
|
||||||
|
* @description 保存video_tasks数据
|
||||||
|
* @returns Promise<保存结果>
|
||||||
|
*/
|
||||||
|
static async saveShotData(): Promise<{
|
||||||
|
success: boolean;
|
||||||
|
message: string;
|
||||||
|
data?: any;
|
||||||
|
}> {
|
||||||
|
// 镜头数据保存就是保存video_tasks
|
||||||
|
return SaveEditUseCase.saveData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空数据方法
|
||||||
|
* @description 清空当前类内保存的所有数据
|
||||||
|
*/
|
||||||
|
static clearData(): void {
|
||||||
|
SaveEditUseCase.projectId = '';
|
||||||
|
SaveEditUseCase.characterId = [];
|
||||||
|
SaveEditUseCase.videoTasks = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前保存的数据
|
||||||
|
* @returns 当前保存的数据对象
|
||||||
|
*/
|
||||||
|
static getCurrentData(): {
|
||||||
|
projectId: string;
|
||||||
|
characterId: {
|
||||||
|
character_id: string;
|
||||||
|
name: string;
|
||||||
|
}[];
|
||||||
|
videoTasks: Array<{
|
||||||
|
task_id: string;
|
||||||
|
video_ids: string[];
|
||||||
|
}>;
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
projectId: SaveEditUseCase.projectId,
|
||||||
|
characterId: [...SaveEditUseCase.characterId],
|
||||||
|
videoTasks: [...SaveEditUseCase.videoTasks],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建保存编辑用例实例
|
||||||
|
* @returns {SaveEditUseCase} 保存编辑用例实例
|
||||||
|
*/
|
||||||
|
export const createSaveEditUseCase = (): SaveEditUseCase => {
|
||||||
|
return new SaveEditUseCase();
|
||||||
|
};
|
||||||
@ -13,6 +13,8 @@ import { usePlaybackControls } from "./work-flow/use-playback-controls";
|
|||||||
import { AlertCircle, RefreshCw, Pause, Play, ChevronLast } from "lucide-react";
|
import { AlertCircle, RefreshCw, Pause, Play, ChevronLast } from "lucide-react";
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { GlassIconButton } from '@/components/ui/glass-icon-button';
|
import { GlassIconButton } from '@/components/ui/glass-icon-button';
|
||||||
|
import { SaveEditUseCase } from "@/app/service/usecase/SaveEditUseCase";
|
||||||
|
import { useSearchParams } from "next/navigation";
|
||||||
|
|
||||||
export default function WorkFlow() {
|
export default function WorkFlow() {
|
||||||
console.log('WorkFlow--0294877777777777')
|
console.log('WorkFlow--0294877777777777')
|
||||||
@ -20,6 +22,10 @@ export default function WorkFlow() {
|
|||||||
const [isEditModalOpen, setIsEditModalOpen] = React.useState(false);
|
const [isEditModalOpen, setIsEditModalOpen] = React.useState(false);
|
||||||
const [activeEditTab, setActiveEditTab] = React.useState('1');
|
const [activeEditTab, setActiveEditTab] = React.useState('1');
|
||||||
|
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const episodeId = searchParams.get('episodeId') || '';
|
||||||
|
|
||||||
|
SaveEditUseCase.setProjectId(episodeId);
|
||||||
// 使用自定义 hooks 管理状态
|
// 使用自定义 hooks 管理状态
|
||||||
const {
|
const {
|
||||||
taskObject,
|
taskObject,
|
||||||
@ -262,7 +268,10 @@ export default function WorkFlow() {
|
|||||||
<EditModal
|
<EditModal
|
||||||
isOpen={isEditModalOpen}
|
isOpen={isEditModalOpen}
|
||||||
activeEditTab={activeEditTab}
|
activeEditTab={activeEditTab}
|
||||||
onClose={() => setIsEditModalOpen(false)}
|
onClose={() => {
|
||||||
|
SaveEditUseCase.clearData();
|
||||||
|
setIsEditModalOpen(false)
|
||||||
|
}}
|
||||||
taskStatus={taskObject?.taskStatus || '1'}
|
taskStatus={taskObject?.taskStatus || '1'}
|
||||||
taskSketch={taskSketch}
|
taskSketch={taskSketch}
|
||||||
sketchVideo={taskVideos}
|
sketchVideo={taskVideos}
|
||||||
|
|||||||
@ -109,7 +109,6 @@ const [pendingSwitchTabId, setPendingSwitchTabId] = useState<string | null>(null
|
|||||||
if (disabled) return;
|
if (disabled) return;
|
||||||
// 切换前 检查是否更新
|
// 切换前 检查是否更新
|
||||||
const isUpdate = checkUpdate(activeTab);
|
const isUpdate = checkUpdate(activeTab);
|
||||||
console.log('contentEditableRef---isUpdate', isUpdate);
|
|
||||||
if (isUpdate) {
|
if (isUpdate) {
|
||||||
setPendingSwitchTabId(tabId); // 记录要切换到的目标tab
|
setPendingSwitchTabId(tabId); // 记录要切换到的目标tab
|
||||||
setRemindFallbackText('You must click Apply button to save the current changes.');
|
setRemindFallbackText('You must click Apply button to save the current changes.');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user