From 365e2c46152ed6c9a696163d6d8e723efbb271a7 Mon Sep 17 00:00:00 2001 From: imeepos Date: Tue, 5 Aug 2025 18:55:31 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=20API=20=E5=93=8D=E5=BA=94=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题修复: - 修复查询结果响应中缺少 task_id 字段导致的解析失败 - 重构数据结构,区分提交任务和查询结果的不同响应格式 - 添加类型守卫确保类型安全的数据访问 - 优化轮询逻辑,正确检测任务完成状态 (status: 'done') 技术改进: - 分离提交和查询的数据结构: * RealmanAvatarPictureCreateRoleOmniSubmitData (包含 task_id) * RealmanAvatarPictureCreateRoleOmniResultData (包含 status, image_urls, resp_data) - 使用 TypeScript 联合类型和类型守卫确保类型安全 - 更新前端代码使用正确的数据访问路径 - 完善错误处理和状态检测逻辑 现在 OmniHuman 主体识别功能可以正确解析查询结果响应了! --- .../services/volcano_video_service.rs | 23 +++++++--- .../pages/tools/OmniHumanDetectionTool.tsx | 42 +++++++++++++------ apps/desktop/src/types/videoGeneration.ts | 15 ++++--- 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/apps/desktop/src-tauri/src/business/services/volcano_video_service.rs b/apps/desktop/src-tauri/src/business/services/volcano_video_service.rs index 064c30d..e52d5d7 100644 --- a/apps/desktop/src-tauri/src/business/services/volcano_video_service.rs +++ b/apps/desktop/src-tauri/src/business/services/volcano_video_service.rs @@ -136,21 +136,32 @@ pub struct RealmanAvatarPictureCreateRoleOmniResult { pub time_elapsed: String, } -/// OmniHuman 主体识别返回数据 +/// OmniHuman 主体识别提交任务返回数据 #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct RealmanAvatarPictureCreateRoleOmniData { +pub struct RealmanAvatarPictureCreateRoleOmniSubmitData { + /// 任务ID + pub task_id: String, +} + +/// OmniHuman 主体识别查询结果返回数据 +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct RealmanAvatarPictureCreateRoleOmniResultData { /// 输出处理过的图片url数组(单张图) pub image_urls: Option>, /// 返回图base64数组 pub binary_data_base64: Option>, - /// 任务ID - pub task_id: String, /// 算法返回数据 pub resp_data: Option, /// 任务状态 pub status: Option, - /// 算法返回信息 - pub algorithm_base_resp: Option, +} + +/// OmniHuman 主体识别返回数据(兼容两种情况) +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum RealmanAvatarPictureCreateRoleOmniData { + Submit(RealmanAvatarPictureCreateRoleOmniSubmitData), + Result(RealmanAvatarPictureCreateRoleOmniResultData), } /// 火山云视频生成服务 diff --git a/apps/desktop/src/pages/tools/OmniHumanDetectionTool.tsx b/apps/desktop/src/pages/tools/OmniHumanDetectionTool.tsx index 593bf05..cdec831 100644 --- a/apps/desktop/src/pages/tools/OmniHumanDetectionTool.tsx +++ b/apps/desktop/src/pages/tools/OmniHumanDetectionTool.tsx @@ -13,7 +13,11 @@ import { open } from '@tauri-apps/plugin-dialog'; import { useNotifications } from '../../components/NotificationSystem'; import videoGenerationService from '../../services/videoGenerationService'; import fileUploadService from '../../services/fileUploadService'; -import { RealmanAvatarPictureCreateRoleOmniResponse } from '../../types/videoGeneration'; +import { + RealmanAvatarPictureCreateRoleOmniResponse, + RealmanAvatarPictureCreateRoleOmniResultData, + RealmanAvatarPictureCreateRoleOmniSubmitData +} from '../../types/videoGeneration'; const OmniHumanDetectionTool: React.FC = () => { const [selectedImage, setSelectedImage] = useState(''); @@ -26,6 +30,16 @@ const OmniHumanDetectionTool: React.FC = () => { const { addNotification, success, error } = useNotifications(); + // 类型守卫:检查是否为查询结果数据 + const isResultData = (data: any): data is RealmanAvatarPictureCreateRoleOmniResultData => { + return data && typeof data === 'object' && ('status' in data || 'image_urls' in data || 'resp_data' in data); + }; + + // 类型守卫:检查是否为提交任务数据 + const isSubmitData = (data: any): data is RealmanAvatarPictureCreateRoleOmniSubmitData => { + return data && typeof data === 'object' && 'task_id' in data; + }; + // 轮询查询结果 const pollForResult = useCallback(async (taskId: string): Promise => { const maxAttempts = 30; // 最多轮询30次 @@ -36,12 +50,15 @@ const OmniHumanDetectionTool: React.FC = () => { const result = await videoGenerationService.realmanAvatarPictureCreateRoleOmniGetResult(taskId); // 检查任务状态 - if (result.Result.data?.status === 'completed' || result.Result.data?.image_urls?.length) { - // 任务完成,返回结果 - return result; - } else if (result.Result.data?.status === 'failed') { - // 任务失败 - throw new Error('任务处理失败'); + if (result.Result.data && isResultData(result.Result.data)) { + const resultData = result.Result.data; + if (resultData.status === 'done' || resultData.image_urls?.length) { + // 任务完成,返回结果 + return result; + } else if (resultData.status === 'failed') { + // 任务失败 + throw new Error('任务处理失败'); + } } // 任务还在处理中,继续轮询 @@ -125,7 +142,8 @@ const OmniHumanDetectionTool: React.FC = () => { setUploadProgress(80); if (submitResponse.Result.code === 10000) { - const taskId = submitResponse.Result.data?.task_id; + const data = submitResponse.Result.data; + const taskId = data && isSubmitData(data) ? data.task_id : undefined; if (taskId) { setCurrentTaskId(taskId); success('主体识别任务提交成功,正在处理中...'); @@ -269,17 +287,17 @@ const OmniHumanDetectionTool: React.FC = () => { 识别成功
-

任务ID: {result.Result.data?.task_id || currentTaskId}

+

任务ID: {currentTaskId || (result.Result.data && isSubmitData(result.Result.data) ? result.Result.data.task_id : '未知')}

请求ID: {result.Result.request_id}

处理时间: {result.Result.time_elapsed}

- {result.Result.data?.image_urls && result.Result.data.image_urls.length > 0 && ( + {result.Result.data && isResultData(result.Result.data) && result.Result.data.image_urls && result.Result.data.image_urls.length > 0 && (

处理后的图片

- {result.Result.data.image_urls.map((url, index) => ( + {result.Result.data.image_urls.map((url: string, index: number) => (
{
)} - {result.Result.data?.resp_data && ( + {result.Result.data && isResultData(result.Result.data) && result.Result.data.resp_data && (

算法返回数据

diff --git a/apps/desktop/src/types/videoGeneration.ts b/apps/desktop/src/types/videoGeneration.ts index 2c69b60..43d518d 100644 --- a/apps/desktop/src/types/videoGeneration.ts +++ b/apps/desktop/src/types/videoGeneration.ts @@ -397,21 +397,26 @@ export interface RealmanAvatarPictureCreateRoleOmniRequest { image_url: string; } -export interface RealmanAvatarPictureCreateRoleOmniData { +export interface RealmanAvatarPictureCreateRoleOmniSubmitData { + /** 任务ID */ + task_id: string; +} + +export interface RealmanAvatarPictureCreateRoleOmniResultData { /** 输出处理过的图片url数组(单张图) */ image_urls?: string[]; /** 返回图base64数组 */ binary_data_base64?: string[]; - /** 任务ID */ - task_id: string; /** 算法返回数据 */ resp_data?: string; /** 任务状态 */ status?: string; - /** 算法返回信息 */ - algorithm_base_resp?: any; } +export type RealmanAvatarPictureCreateRoleOmniData = + | RealmanAvatarPictureCreateRoleOmniSubmitData + | RealmanAvatarPictureCreateRoleOmniResultData; + export interface VolcanoResponseMetadata { Action: string; Region: string;