fix: 修复火山云 API 响应格式解析问题

问题修复:
-  修复响应结构不匹配导致的解析失败
-  更新数据结构以匹配火山云 API 的实际响应格式
-  添加调试日志以便排查 API 响应问题

技术改进:
- 重构响应数据结构,支持火山云嵌套格式 (ResponseMetadata + Result)
- 更新前端类型定义和数据访问路径
- 添加详细的响应解析错误信息
- 保持向后兼容性

响应格式变更:
- 原格式: { code, message, data, ... }
- 新格式: { ResponseMetadata: {...}, Result: { code, message, data, ... } }

现在 OmniHuman 主体识别功能应该可以正确解析火山云 API 响应了!
This commit is contained in:
imeepos 2025-08-05 18:36:46 +08:00
parent 4ce50b15d7
commit d58499b564
3 changed files with 60 additions and 15 deletions

View File

@ -92,9 +92,33 @@ pub struct RealmanAvatarPictureCreateRoleOmniRequest {
pub image_url: String,
}
/// OmniHuman 主体识别响应
/// 火山云 API 响应元数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VolcanoResponseMetadata {
#[serde(rename = "Action")]
pub action: String,
#[serde(rename = "Region")]
pub region: String,
#[serde(rename = "RequestId")]
pub request_id: String,
#[serde(rename = "Service")]
pub service: String,
#[serde(rename = "Version")]
pub version: String,
}
/// OmniHuman 主体识别响应 (火山云格式)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RealmanAvatarPictureCreateRoleOmniResponse {
#[serde(rename = "ResponseMetadata")]
pub response_metadata: VolcanoResponseMetadata,
#[serde(rename = "Result")]
pub result: RealmanAvatarPictureCreateRoleOmniResult,
}
/// OmniHuman 主体识别结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RealmanAvatarPictureCreateRoleOmniResult {
pub code: i32,
pub message: String,
pub data: Option<RealmanAvatarPictureCreateRoleOmniData>,
@ -561,10 +585,16 @@ impl VolcanoVideoService {
return Err(anyhow!("OmniHuman 主体识别 API 调用失败: {} - {}", status, error_text));
}
let api_response: RealmanAvatarPictureCreateRoleOmniResponse = response.json().await?;
// 先获取响应文本进行调试
let response_text = response.text().await?;
info!("OmniHuman API 原始响应: {}", response_text);
if api_response.code != 10000 {
return Err(anyhow!("OmniHuman 主体识别 API 返回错误: {} - {}", api_response.code, api_response.message));
// 尝试解析响应
let api_response: RealmanAvatarPictureCreateRoleOmniResponse = serde_json::from_str(&response_text)
.map_err(|e| anyhow!("解析响应失败: {} - 响应内容: {}", e, response_text))?;
if api_response.result.code != 10000 {
return Err(anyhow!("OmniHuman 主体识别 API 返回错误: {} - {}", api_response.result.code, api_response.result.message));
}
info!("OmniHuman 主体识别任务提交成功: {:?}", api_response);

View File

@ -90,11 +90,11 @@ const OmniHumanDetectionTool: React.FC = () => {
setUploadProgress(100);
setResult(response);
if (response.code === 10000) {
if (response.Result.code === 10000) {
success('主体识别任务提交成功');
} else {
setErrorMessage(`识别失败: ${response.message}`);
error(`识别失败: ${response.message}`);
setErrorMessage(`识别失败: ${response.Result.message}`);
error(`识别失败: ${response.Result.message}`);
}
} catch (err) {
const errMsg = err instanceof Error ? err.message : '未知错误';
@ -221,17 +221,17 @@ const OmniHumanDetectionTool: React.FC = () => {
<span className="text-green-800 font-medium"></span>
</div>
<div className="text-sm text-green-700">
<p>ID: {result.data?.task_id}</p>
<p>ID: {result.request_id}</p>
<p>: {result.time_elapsed}</p>
<p>ID: {result.Result.data?.task_id}</p>
<p>ID: {result.Result.request_id}</p>
<p>: {result.Result.time_elapsed}</p>
</div>
</div>
{result.data?.image_urls && result.data.image_urls.length > 0 && (
{result.Result.data?.image_urls && result.Result.data.image_urls.length > 0 && (
<div>
<h4 className="font-medium text-gray-900 mb-2"></h4>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{result.data.image_urls.map((url, index) => (
{result.Result.data.image_urls.map((url, index) => (
<div key={index} className="border border-gray-200 rounded-lg p-4 bg-gray-50">
<img
src={url}
@ -254,11 +254,11 @@ const OmniHumanDetectionTool: React.FC = () => {
</div>
)}
{result.data?.resp_data && (
{result.Result.data?.resp_data && (
<div>
<h4 className="font-medium text-gray-900 mb-2"></h4>
<div className="p-3 bg-gray-50 border border-gray-200 rounded text-sm font-mono">
{result.data.resp_data}
{result.Result.data.resp_data}
</div>
</div>
)}

View File

@ -412,7 +412,15 @@ export interface RealmanAvatarPictureCreateRoleOmniData {
algorithm_base_resp?: any;
}
export interface RealmanAvatarPictureCreateRoleOmniResponse {
export interface VolcanoResponseMetadata {
Action: string;
Region: string;
RequestId: string;
Service: string;
Version: string;
}
export interface RealmanAvatarPictureCreateRoleOmniResult {
/** 业务侧错误码 */
code: number;
/** 描述信息 */
@ -426,3 +434,10 @@ export interface RealmanAvatarPictureCreateRoleOmniResponse {
/** 内部服务耗时 */
time_elapsed: string;
}
export interface RealmanAvatarPictureCreateRoleOmniResponse {
/** 火山云响应元数据 */
ResponseMetadata: VolcanoResponseMetadata;
/** 实际结果数据 */
Result: RealmanAvatarPictureCreateRoleOmniResult;
}