From 68000596d8fd3dc0fea6323d82eac036060cc3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=B7=E9=BE=99?= Date: Tue, 12 Aug 2025 18:44:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=8E=B7=E5=8F=96=E7=9B=B8?= =?UTF-8?q?=E4=BC=BC=E8=A7=92=E8=89=B2=E5=88=97=E8=A1=A8=E5=92=8C=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E9=87=8D=E6=96=B0=E7=94=9F=E6=88=90=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E5=88=B0=E8=A7=92=E8=89=B2=E5=BA=93=E7=9A=84=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E5=90=8C=E6=97=B6=E6=9B=B4=E6=96=B0=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E5=BA=93=E5=88=97=E8=A1=A8=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E7=94=A8=E6=88=B7ID=E5=92=8C?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0=E3=80=82=E4=BC=98=E5=8C=96=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E7=94=A8=E4=BE=8B=EF=BC=8C=E7=A1=AE=E4=BF=9D?= =?UTF-8?q?=E8=A7=92=E8=89=B2=E4=BF=9D=E5=AD=98=E5=8A=9F=E8=83=BD=E7=9A=84?= =?UTF-8?q?=E5=AE=8C=E6=95=B4=E6=80=A7=E5=92=8C=E5=8F=AF=E7=94=A8=E6=80=A7?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/video_flow.ts | 65 +++++++++++++++++- app/service/Interaction/RoleService.ts | 63 ++++++++++++++++-- app/service/usecase/RoleEditUseCase.ts | 92 ++++++++++++++++++++++++-- 3 files changed, 208 insertions(+), 12 deletions(-) diff --git a/api/video_flow.ts b/api/video_flow.ts index 4cb2329..15cc525 100644 --- a/api/video_flow.ts +++ b/api/video_flow.ts @@ -867,8 +867,42 @@ export const faceRecognition = async (request: { * 获取所有角色列表接口 * @returns Promise> 所有角色列表 */ -export const getAllCharacterList = async (): Promise> => { - return post>("/character/list_all"); +export const getAllCharacterList = async (request:{ + user_id:string; +}): Promise> => { + return post>("/character/list_all", request); +}; + +/** + * 获取相似角色列表接口 + * @param request - 获取相似角色请求参数 + * @returns Promise> + */ +export const getSimilarCharacters = async (request: { + /** 用户ID */ + userId: string; + /** 用户描述(角色描述) */ + user_description: string; + /** 相似度限制 */ + similar_limit: number; +}): Promise; + /** 总数量 */ + total_count: number; +}>> => { + return post("/character/get_similar_characters", request); }; /** @@ -976,4 +1010,31 @@ export const getCharacterShots = async (request: { return post("/character/get_character_scenes", request); }; +/** + * 保存重新生成的角色到角色库 + * @param request - 保存重新生成角色请求参数 + * @returns Promise> + */ +export const saveRegeneratedCharacter = async (request: { + /** 用户ID */ + user_id: string; + /** 项目ID,用于从项目脚本中提取角色信息 */ + project_id: string; + /** 修改前的用户名称,用于在脚本中查找对应角色 */ + original_character_name: string; + /** 角色描述文本 */ + character_description: string; + /** 角色图片URL */ + character_image: string; + /** 多个视频地址(支持任意数量) */ + video_urls: string[]; +}): Promise> => { + return post("/character/save_regenerated_character", request); +}; + diff --git a/app/service/Interaction/RoleService.ts b/app/service/Interaction/RoleService.ts index e6d4566..293fee1 100644 --- a/app/service/Interaction/RoleService.ts +++ b/app/service/Interaction/RoleService.ts @@ -35,6 +35,8 @@ interface UseRoleService { replaceRoleWithLibrary: (replaceRoleId: string) => Promise; /** 上传图片到七牛云 */ uploadImageToQiniu: (file: File) => Promise; + /** 保存重新生成的角色到角色库 */ + saveRoleToLibrary: () => Promise; } /** @@ -249,13 +251,23 @@ export const useRoleServiceHook = (): UseRoleService => { setRoleEditUseCase(useCase); } - const roleLibraryList = await useCase!.getRoleLibraryList(); + // 从localStorage获取当前用户信息 + const User = JSON.parse(localStorage.getItem("currentUser") || "{}"); + + if (!User.id) { + throw new Error('无法获取用户ID,请重新登录'); + } + + // 获取当前选中角色的描述 + const userDescription = selectedRole?.generateText || ''; + + const roleLibraryList = await useCase!.getRoleLibraryList(User.id, userDescription); setUserRoleLibrary(roleLibraryList); } catch (error) { console.error('获取用户角色库失败:', error); throw error; } - }, [roleEditUseCase]); + }, [roleEditUseCase, selectedRole]); /** * 替换角色 @@ -299,7 +311,7 @@ export const useRoleServiceHook = (): UseRoleService => { console.error('替换角色失败:', error); throw error; } - }, [selectedRole, roleEditUseCase, userRoleLibrary]); + }, [selectedRole, roleEditUseCase, userRoleLibrary, selectRole]); /** * 上传图片到七牛云 @@ -318,6 +330,48 @@ export const useRoleServiceHook = (): UseRoleService => { } }, [roleEditUseCase]); + /** + * 保存重新生成的角色到角色库 + * @description 将当前选中的角色保存到角色库中 + * @throws {Error} 当没有选中角色、UseCase未初始化或缺少项目ID时抛出错误 + * @returns {Promise} 保存完成后的Promise + */ + const saveRoleToLibrary = useCallback(async () => { + if (!selectedRole) { + throw new Error('请先选择要保存的角色'); + } + + if (!roleEditUseCase) { + throw new Error('角色编辑UseCase未初始化'); + } + + if (!projectId) { + throw new Error('缺少项目ID,无法保存角色到角色库'); + } + + try { + // 从localStorage获取当前用户信息 + const User = JSON.parse(localStorage.getItem("currentUser") || "{}"); + + if (!User.id) { + throw new Error('无法获取用户ID,请重新登录'); + } + + // 调用保存重新生成角色到角色库的方法 + const result = await roleEditUseCase.saveRegeneratedCharacterToLibrary( + selectedRole, + projectId, + User.id + ); + + console.log('角色保存到角色库成功:', result); + + } catch (error) { + console.error('保存角色到角色库失败:', error); + throw error; + } + }, [selectedRole, roleEditUseCase, projectId]); + return { // 响应式数据 roleList, @@ -334,6 +388,7 @@ export const useRoleServiceHook = (): UseRoleService => { regenerateRole, fetchUserRoleLibrary, replaceRoleWithLibrary, - uploadImageToQiniu + uploadImageToQiniu, + saveRoleToLibrary }; }; diff --git a/app/service/usecase/RoleEditUseCase.ts b/app/service/usecase/RoleEditUseCase.ts index a2c8ca9..7222d5a 100644 --- a/app/service/usecase/RoleEditUseCase.ts +++ b/app/service/usecase/RoleEditUseCase.ts @@ -7,11 +7,12 @@ import { regenerateRole, getRoleShots, replaceRole, - getAllCharacterList, getCharacterListByProjectWithHighlight, updateAndRegenerateCharacter, getUserRoleLibrary, generateCharacterDescription, + saveRegeneratedCharacter, + getSimilarCharacters, } from '@/api/video_flow'; export interface RoleResponse { @@ -134,16 +135,52 @@ export class RoleEditUseCase { }); } + /** + * 解析相似角色列表接口返回的数据 + * @description 将接口返回的相似角色列表数据转换为RoleEntity数组 + * @param {any} similarCharacterData - 相似角色列表数据 + * @returns {RoleEntity[]} 角色实体数组 + * @throws {Error} 如果数据格式不正确则抛出异常 + */ + parseSimilarCharacterList(similarCharacterData: any): RoleEntity[] { + if (!similarCharacterData || !Array.isArray(similarCharacterData.characters)) { + throw new Error('相似角色数据格式错误'); + } + + return similarCharacterData.characters.map((char: any, index: number) => { + /** 角色实体对象 */ + const roleEntity: RoleEntity = { + id: char.id || `role_${Date.now()}_${index}`, + name: char.name || '', + generateText: char.description || '', + tags: [], // 相似角色接口可能不返回标签,暂时为空 + imageUrl: char.image_url || '', + loadingProgress: 100, + disableEdit: false, + updatedAt: Date.now() + }; + + return roleEntity; + }); + } + /** * 获取角色库的角色列表 + * @param userId 用户ID + * @param userDescription 用户描述(角色描述) * @returns Promise 角色库列表 */ - async getRoleLibraryList(): Promise { + async getRoleLibraryList(userId: string, userDescription: string): Promise { try { - // 使用新的角色列表接口获取角色库 - const response = await getAllCharacterList(); + // 使用新的相似角色接口获取角色库 + const response = await getSimilarCharacters({ + userId, + user_description: userDescription, + similar_limit: 15 // 固定为15 + }); + if (response.successful) { - const roleList = this.parseNewRoleList(response.data); + const roleList = this.parseSimilarCharacterList(response.data); return roleList; } else { throw new Error(response.message || '获取角色库失败'); @@ -316,7 +353,7 @@ export class RoleEditUseCase { return []; } - /** + /** * @description 根据图片地址获取角色实体数据 * @param imageUrl 图片地址 * @returns Promise 角色实体数据 @@ -347,4 +384,47 @@ export class RoleEditUseCase { } } + /** + * @description 保存重新生成的角色到角色库 + * @param roleData 角色实体数据 + * @param projectId 项目ID + * @param userId 用户ID + * @param originalCharacterName 原始角色名称 + * @param videoUrls 视频URL列表 + * @returns Promise<{character_id: string, message: string}> 保存结果 + */ + async saveRegeneratedCharacterToLibrary( + roleData: RoleEntity, + projectId: string, + userId: string, + ): Promise<{character_id: string, message: string}> { + try { + + // 调用保存重新生成角色的API + const response = await saveRegeneratedCharacter({ + user_id: userId, + project_id: projectId, + original_character_name: roleData.name, + character_description: roleData.generateText, + character_image: roleData.imageUrl, + video_urls: [] + }); + + if (response.successful) { + console.log('角色保存到角色库成功:', response.data); + return { + character_id: response.data.character_id, + message: response.data.message + }; + } else { + throw new Error(response.message || '保存角色到角色库失败'); + } + } catch (error) { + console.error('保存角色到角色库失败:', error); + throw error; + } + } + + + }