fix: 修复火山云 API 响应格式解析问题
问题修复:
- 修复响应结构不匹配导致的解析失败
- 更新数据结构以匹配火山云 API 的实际响应格式
- 添加调试日志以便排查 API 响应问题
技术改进:
- 重构响应数据结构,支持火山云嵌套格式 (ResponseMetadata + Result)
- 更新前端类型定义和数据访问路径
- 添加详细的响应解析错误信息
- 保持向后兼容性
响应格式变更:
- 原格式: { code, message, data, ... }
- 新格式: { ResponseMetadata: {...}, Result: { code, message, data, ... } }
现在 OmniHuman 主体识别功能应该可以正确解析火山云 API 响应了!
This commit is contained in:
parent
4ce50b15d7
commit
d58499b564
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue