From e17a451e6e65a823f699665803e3b16e1dcab3c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=B7=E9=BE=99?= Date: Tue, 12 Aug 2025 20:06:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9B=BE=E7=89=87=E5=88=86?= =?UTF-8?q?=E6=9E=90=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=8E=A5=E6=94=B6=E5=9B=BE?= =?UTF-8?q?=E7=89=87URL=E5=B9=B6=E7=94=9F=E6=88=90=E6=8F=8F=E8=BF=B0?= =?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?=E4=BF=A1=E6=81=AF=E4=B8=8A=E4=BC=A0=E9=80=BB=E8=BE=91=E4=BB=A5?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BE=E7=89=87=E5=88=86=E6=9E=90=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A7=92=E8=89=B2=E9=80=89=E6=8B=A9=E5=92=8C?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=B5=81=E7=A8=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/video_flow.ts | 24 +++++++++ app/service/Interaction/RoleService.ts | 69 +++++++++++++++++++++---- components/ui/character-tab-content.tsx | 2 +- 3 files changed, 83 insertions(+), 12 deletions(-) diff --git a/api/video_flow.ts b/api/video_flow.ts index 15cc525..ae1791c 100644 --- a/api/video_flow.ts +++ b/api/video_flow.ts @@ -1037,4 +1037,28 @@ export const saveRegeneratedCharacter = async (request: { return post("/character/save_regenerated_character", request); }; +/** + * 分析图片并生成描述 + * @description 接收图片URL,调用AI服务分析图片并生成详细描述 + * @param request - 图片分析请求参数 + * @returns Promise> + */ +export const analyzeImageDescription = async (request: { + /** 图片的URL地址,必须是有效的HTTP/HTTPS链接 */ + image_url: string; +}): Promise> => { + return post>("/character/analyze_image_description", request); +}; + diff --git a/app/service/Interaction/RoleService.ts b/app/service/Interaction/RoleService.ts index 293fee1..17ba847 100644 --- a/app/service/Interaction/RoleService.ts +++ b/app/service/Interaction/RoleService.ts @@ -2,6 +2,7 @@ import { useState, useCallback, useMemo } from 'react'; import { RoleEntity, AITextEntity } from '../domain/Entities'; import { RoleEditUseCase } from '../usecase/RoleEditUseCase'; import { getUploadToken, uploadToQiniu } from '@/api/common'; +import { analyzeImageDescription } from '@/api/video_flow'; /** * 角色服务Hook返回值接口 @@ -33,8 +34,8 @@ interface UseRoleService { fetchUserRoleLibrary: () => Promise; /** 替换角色 */ replaceRoleWithLibrary: (replaceRoleId: string) => Promise; - /** 上传图片到七牛云 */ - uploadImageToQiniu: (file: File) => Promise; + /** 上传图片并更新角色信息 */ + uploadImageAndUpdateRole: (file: File) => Promise; /** 保存重新生成的角色到角色库 */ saveRoleToLibrary: () => Promise; } @@ -314,21 +315,67 @@ export const useRoleServiceHook = (): UseRoleService => { }, [selectedRole, roleEditUseCase, userRoleLibrary, selectRole]); /** - * 上传图片到七牛云 - * @description 上传图片文件到七牛云存储 + * 上传图片并更新角色信息 + * @description 上传图片文件到七牛云存储,然后调用AI接口分析图片生成描述和高亮标签,最后更新当前选中角色的图片、描述和标签 * @param file 要上传的文件 - * @returns {Promise} 上传成功后的图片URL + * @returns {Promise} 上传和分析完成后的Promise */ - const uploadImageToQiniu = useCallback(async (file: File) => { + const uploadImageAndUpdateRole = useCallback(async (file: File) => { + if (!selectedRole) { + throw new Error('请先选择要更新的角色'); + } + try { + // 1. 上传图片到七牛云 const { token } = await getUploadToken(); - const url = await uploadToQiniu(file, token); - const roleEntity = await roleEditUseCase?.getRoleByImage(url); + const imageUrl = await uploadToQiniu(file, token); + + // 2. 调用图片分析接口获取描述 + const result = await analyzeImageDescription({ + image_url: imageUrl + }); + + if (!result.successful) { + throw new Error(`图片分析失败: ${result.message}`); + } + + const { description, highlights } = result.data; + + // 3. 更新当前选中角色的图片、描述和标签 + const updatedRole = { + ...selectedRole, + imageUrl: imageUrl, + generateText: description, + tags: highlights.map((highlight: string, index: number) => ({ + id: `tag_${Date.now()}_${index}`, + /** 名称 */ + name: highlight, + /** 内容 */ + content: highlight, + loadingProgress: 100, + disableEdit: false + })) + }; + + // 更新选中的角色 + selectRole(updatedRole); + + // 更新角色列表中的对应角色 + setRoleList(prev => + prev.map(role => + role.id === selectedRole.id + ? updatedRole + : role + ) + ); + + console.log('角色图片和描述更新成功:', updatedRole); + } catch (error) { - console.error('上传图片到七牛云失败:', error); + console.error('上传图片并分析失败:', error); throw error; } - }, [roleEditUseCase]); + }, [selectedRole, roleEditUseCase, selectRole]); /** * 保存重新生成的角色到角色库 @@ -388,7 +435,7 @@ export const useRoleServiceHook = (): UseRoleService => { regenerateRole, fetchUserRoleLibrary, replaceRoleWithLibrary, - uploadImageToQiniu, + uploadImageAndUpdateRole, saveRoleToLibrary }; }; diff --git a/components/ui/character-tab-content.tsx b/components/ui/character-tab-content.tsx index e4055f3..2922bc2 100644 --- a/components/ui/character-tab-content.tsx +++ b/components/ui/character-tab-content.tsx @@ -178,7 +178,7 @@ export function CharacterTabContent({ setIgnoreReplace(false); setIsRegenerate(false); - selectRole(roleData[index].id); + selectRole(roleData[index]); }; // 从角色库中选择角色