fix: 修改openapi.json
This commit is contained in:
@@ -51,6 +51,8 @@ pub struct OutfitImageRecord {
|
||||
pub completed_at: Option<DateTime<Utc>>,
|
||||
pub duration_ms: Option<u64>,
|
||||
pub comfyui_prompt_id: Option<String>, // ComfyUI 任务ID,用于精确匹配任务状态更新
|
||||
pub generation_type: Option<String>, // 生成方式: "standard" | "comfyui"
|
||||
pub comfyui_task_id: Option<String>, // ComfyUI 任务ID
|
||||
|
||||
// 关联数据
|
||||
pub product_images: Vec<ProductImage>,
|
||||
@@ -74,6 +76,8 @@ impl OutfitImageRecord {
|
||||
completed_at: None,
|
||||
duration_ms: None,
|
||||
comfyui_prompt_id: None,
|
||||
generation_type: Some("standard".to_string()),
|
||||
comfyui_task_id: None,
|
||||
product_images: Vec::new(),
|
||||
outfit_images: Vec::new(),
|
||||
}
|
||||
@@ -131,6 +135,30 @@ impl OutfitImageRecord {
|
||||
pub fn set_comfyui_prompt_id(&mut self, prompt_id: String) {
|
||||
self.comfyui_prompt_id = Some(prompt_id);
|
||||
}
|
||||
|
||||
/// 标记为失败(ComfyUI 专用)
|
||||
pub fn mark_failed(&mut self, error_message: String) {
|
||||
self.status = OutfitImageStatus::Failed;
|
||||
self.error_message = Some(error_message);
|
||||
self.completed_at = Some(Utc::now());
|
||||
self.progress = 0.0;
|
||||
|
||||
if let Some(started_at) = self.started_at {
|
||||
self.duration_ms = Some((Utc::now() - started_at).num_milliseconds() as u64);
|
||||
}
|
||||
}
|
||||
|
||||
/// 完成生成(ComfyUI 专用)
|
||||
pub fn complete_generation(&mut self, result_urls: Vec<String>) {
|
||||
self.status = OutfitImageStatus::Completed;
|
||||
self.result_urls = result_urls;
|
||||
self.completed_at = Some(Utc::now());
|
||||
self.progress = 1.0;
|
||||
|
||||
if let Some(started_at) = self.started_at {
|
||||
self.duration_ms = Some((Utc::now() - started_at).num_milliseconds() as u64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 商品图片
|
||||
@@ -212,6 +240,7 @@ pub struct OutfitImageGenerationRequest {
|
||||
pub generation_prompt: Option<String>, // 可选的生成提示词
|
||||
pub style_preferences: Option<Vec<String>>, // 风格偏好
|
||||
pub product_index: Option<usize>, // 商品编号(用于调试文件命名)
|
||||
pub use_comfyui: Option<bool>, // 是否使用 ComfyUI 生成
|
||||
}
|
||||
|
||||
/// 穿搭图片生成响应
|
||||
@@ -222,6 +251,8 @@ pub struct OutfitImageGenerationResponse {
|
||||
pub generation_time_ms: u64,
|
||||
pub success: bool,
|
||||
pub error_message: Option<String>,
|
||||
pub generation_type: Option<String>, // 生成方式: "standard" | "comfyui"
|
||||
pub task_id: Option<String>, // ComfyUI 任务ID
|
||||
}
|
||||
|
||||
/// 穿搭图片统计信息
|
||||
|
||||
@@ -698,6 +698,8 @@ impl OutfitImageRepository {
|
||||
completed_at,
|
||||
duration_ms: row.get(11)?,
|
||||
comfyui_prompt_id: row.get(12)?,
|
||||
generation_type: Some("standard".to_string()), // 默认为标准生成
|
||||
comfyui_task_id: None, // 新增字段
|
||||
product_images: Vec::new(), // 将在调用方加载
|
||||
outfit_images: Vec::new(), // 将在调用方加载
|
||||
})
|
||||
|
||||
@@ -3,6 +3,9 @@ use tracing::{info, error, warn};
|
||||
use anyhow::{Result, anyhow};
|
||||
use chrono::Utc;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use reqwest;
|
||||
use serde_json;
|
||||
|
||||
use crate::app_state::AppState;
|
||||
use crate::data::models::outfit_image::{
|
||||
@@ -276,6 +279,11 @@ pub async fn execute_outfit_image_generation(
|
||||
info!("🎨 执行穿搭图片生成: {:?}", request);
|
||||
let start_time = Utc::now();
|
||||
|
||||
// 检查是否使用 ComfyUI
|
||||
if request.use_comfyui.unwrap_or(false) {
|
||||
return execute_comfyui_generation(state, app_handle, request).await;
|
||||
}
|
||||
|
||||
// 首先创建生成记录
|
||||
let record_id = create_outfit_image_record(state.clone(), request.clone()).await?;
|
||||
|
||||
@@ -316,6 +324,8 @@ pub async fn execute_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("standard".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -342,6 +352,8 @@ pub async fn execute_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("standard".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -363,6 +375,8 @@ pub async fn execute_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("standard".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -375,6 +389,8 @@ pub async fn execute_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("standard".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -398,6 +414,8 @@ pub async fn execute_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("standard".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -427,6 +445,8 @@ pub async fn execute_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("standard".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -451,6 +471,8 @@ pub async fn execute_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(error_msg),
|
||||
generation_type: Some("standard".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -485,6 +507,8 @@ pub async fn execute_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(error_msg),
|
||||
generation_type: Some("standard".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -583,6 +607,8 @@ pub async fn execute_outfit_image_generation(
|
||||
generation_time_ms: total_duration,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("standard".to_string()),
|
||||
task_id: None,
|
||||
}
|
||||
} else {
|
||||
let success_message = if has_errors {
|
||||
@@ -628,6 +654,8 @@ pub async fn execute_outfit_image_generation(
|
||||
generation_time_ms: total_duration,
|
||||
success: true,
|
||||
error_message: if has_errors { Some(error_messages.join("; ")) } else { None },
|
||||
generation_type: Some("standard".to_string()),
|
||||
task_id: None,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -670,6 +698,7 @@ pub async fn execute_outfit_image_task(
|
||||
generation_prompt: record.generation_prompt.clone(),
|
||||
style_preferences: None,
|
||||
product_index: Some(0), // 默认商品编号为0
|
||||
use_comfyui: record.generation_type.as_ref().map(|t| t == "comfyui"),
|
||||
};
|
||||
|
||||
// 立即更新记录状态为"生成中"
|
||||
@@ -905,6 +934,8 @@ async fn perform_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("comfyui".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -925,6 +956,8 @@ async fn perform_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("comfyui".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -946,6 +979,8 @@ async fn perform_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("comfyui".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -958,6 +993,8 @@ async fn perform_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("comfyui".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -981,6 +1018,8 @@ async fn perform_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("comfyui".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1010,6 +1049,8 @@ async fn perform_outfit_image_generation(
|
||||
generation_time_ms: 0,
|
||||
success: false,
|
||||
error_message: Some(user_error.message),
|
||||
generation_type: Some("comfyui".to_string()),
|
||||
task_id: None,
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1302,3 +1343,179 @@ pub fn create_prompt_id_based_progress_callback(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// API配置
|
||||
struct ApiConfig {
|
||||
base_url: String,
|
||||
bearer_token: String,
|
||||
}
|
||||
|
||||
impl Default for ApiConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base_url: "https://bowongai-test--text-video-agent-fastapi-app.modal.run".to_string(),
|
||||
bearer_token: "bowong7777".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 执行 ComfyUI 生成
|
||||
async fn execute_comfyui_generation(
|
||||
state: State<'_, AppState>,
|
||||
app_handle: AppHandle,
|
||||
request: OutfitImageGenerationRequest,
|
||||
) -> Result<OutfitImageGenerationResponse, String> {
|
||||
info!("🎨 执行 ComfyUI 穿搭图片生成: {:?}", request);
|
||||
let start_time = Utc::now();
|
||||
|
||||
// 首先创建生成记录
|
||||
let record_id = create_outfit_image_record(state.clone(), request.clone()).await?;
|
||||
|
||||
// 获取数据库和仓库
|
||||
let database = state.get_database();
|
||||
let outfit_repo = OutfitImageRepository::new(database.clone());
|
||||
|
||||
// 更新记录为 ComfyUI 生成类型
|
||||
if let Ok(Some(mut record)) = outfit_repo.get_record_by_id(&record_id) {
|
||||
record.generation_type = Some("comfyui".to_string());
|
||||
record.start_processing();
|
||||
if let Err(e) = outfit_repo.update_record(&record) {
|
||||
error!("更新记录为 ComfyUI 类型失败: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
let config = ApiConfig::default();
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(Duration::from_secs(120))
|
||||
.build()
|
||||
.map_err(|e| format!("创建HTTP客户端失败: {}", e))?;
|
||||
|
||||
// 1. 提交 ComfyUI 异步任务
|
||||
let prompt = build_comfyui_prompt(&request);
|
||||
let submit_url = format!("{}/api/comfy/async/submit/task", config.base_url);
|
||||
|
||||
let submit_response = client
|
||||
.post(&submit_url)
|
||||
.header("Authorization", format!("Bearer {}", config.bearer_token))
|
||||
.json(&serde_json::json!({"prompt": prompt}))
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| format!("提交ComfyUI任务失败: {}", e))?;
|
||||
|
||||
let task_response: serde_json::Value = submit_response.json().await
|
||||
.map_err(|e| format!("解析任务响应失败: {}", e))?;
|
||||
|
||||
let task_id = task_response["task_id"].as_str()
|
||||
.ok_or("未获取到任务ID")?;
|
||||
|
||||
info!("📝 ComfyUI 任务已提交,任务ID: {}", task_id);
|
||||
|
||||
// 更新记录的 ComfyUI 任务ID
|
||||
if let Ok(Some(mut record)) = outfit_repo.get_record_by_id(&record_id) {
|
||||
record.comfyui_task_id = Some(task_id.to_string());
|
||||
if let Err(e) = outfit_repo.update_record(&record) {
|
||||
error!("更新 ComfyUI 任务ID 失败: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 轮询任务状态直到完成
|
||||
let status_url = format!("{}/api/comfy/async/task/status", config.base_url);
|
||||
let mut attempts = 0;
|
||||
let max_attempts = 60; // 最多等待5分钟
|
||||
|
||||
loop {
|
||||
if attempts >= max_attempts {
|
||||
// 更新记录为失败状态
|
||||
if let Ok(Some(mut record)) = outfit_repo.get_record_by_id(&record_id) {
|
||||
record.mark_failed("ComfyUI任务超时".to_string());
|
||||
let _ = outfit_repo.update_record(&record);
|
||||
}
|
||||
return Err("ComfyUI任务超时".to_string());
|
||||
}
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
attempts += 1;
|
||||
|
||||
let status_response = client
|
||||
.get(&format!("{}?task_id={}", status_url, task_id))
|
||||
.header("Authorization", format!("Bearer {}", config.bearer_token))
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| format!("查询任务状态失败: {}", e))?;
|
||||
|
||||
let status: serde_json::Value = status_response.json().await
|
||||
.map_err(|e| format!("解析状态响应失败: {}", e))?;
|
||||
|
||||
info!("📊 ComfyUI 任务状态: {:?}", status);
|
||||
|
||||
match status["status"].as_str() {
|
||||
Some("completed") => {
|
||||
let result_urls = status["result_urls"].as_array()
|
||||
.map(|arr| arr.iter().filter_map(|v| v.as_str().map(String::from)).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
info!("✅ ComfyUI 生成完成,结果URLs: {:?}", result_urls);
|
||||
|
||||
// 更新记录为完成状态
|
||||
if let Ok(Some(mut record)) = outfit_repo.get_record_by_id(&record_id) {
|
||||
record.complete_generation(result_urls.clone());
|
||||
if let Err(e) = outfit_repo.update_record(&record) {
|
||||
error!("更新记录完成状态失败: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// 发送完成事件
|
||||
let _ = app_handle.emit("outfit_generation_completed", &record_id);
|
||||
|
||||
let generation_time = (Utc::now() - start_time).num_milliseconds() as u64;
|
||||
|
||||
return Ok(OutfitImageGenerationResponse {
|
||||
record_id,
|
||||
generated_images: result_urls,
|
||||
generation_time_ms: generation_time,
|
||||
success: true,
|
||||
error_message: None,
|
||||
generation_type: Some("comfyui".to_string()),
|
||||
task_id: Some(task_id.to_string()),
|
||||
});
|
||||
}
|
||||
Some("failed") => {
|
||||
let error_msg = status["error_message"].as_str()
|
||||
.unwrap_or("ComfyUI任务失败");
|
||||
|
||||
error!("❌ ComfyUI 任务失败: {}", error_msg);
|
||||
|
||||
// 更新记录为失败状态
|
||||
if let Ok(Some(mut record)) = outfit_repo.get_record_by_id(&record_id) {
|
||||
record.mark_failed(error_msg.to_string());
|
||||
let _ = outfit_repo.update_record(&record);
|
||||
}
|
||||
|
||||
return Err(error_msg.to_string());
|
||||
}
|
||||
_ => {
|
||||
// 继续等待,更新进度
|
||||
if let Ok(Some(mut record)) = outfit_repo.get_record_by_id(&record_id) {
|
||||
record.progress = (attempts as f32 / max_attempts as f32) * 100.0;
|
||||
let _ = outfit_repo.update_record(&record);
|
||||
|
||||
// 发送进度事件
|
||||
let _ = app_handle.emit("outfit_generation_progress", &record_id);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn build_comfyui_prompt(request: &OutfitImageGenerationRequest) -> serde_json::Value {
|
||||
// 构建 ComfyUI 工作流 prompt
|
||||
// 这里需要根据实际的 ComfyUI 工作流结构来构建
|
||||
serde_json::json!({
|
||||
"model_id": request.model_id,
|
||||
"model_image_id": request.model_image_id,
|
||||
"product_images": request.product_image_paths,
|
||||
"prompt": request.generation_prompt.as_ref().unwrap_or(&"".to_string()),
|
||||
"style_preferences": request.style_preferences
|
||||
})
|
||||
}
|
||||
|
||||
@@ -54,6 +54,26 @@ export const OutfitImageGallery: React.FC<OutfitImageGalleryProps> = ({
|
||||
const [filter, setFilter] = useState<FilterType>('all');
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
// 渲染生成方式标识
|
||||
const renderGenerationType = (record: OutfitImageRecord) => {
|
||||
if (record.generation_type === 'comfyui') {
|
||||
return (
|
||||
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800 border border-blue-200">
|
||||
<span className="w-2 h-2 bg-blue-500 rounded-full mr-1"></span>
|
||||
ComfyUI
|
||||
</span>
|
||||
);
|
||||
} else if (record.generation_type === 'standard') {
|
||||
return (
|
||||
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-purple-100 text-purple-800 border border-purple-200">
|
||||
<span className="w-2 h-2 bg-purple-500 rounded-full mr-1"></span>
|
||||
标准
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
// 图片预览模态框状态
|
||||
const [previewModal, setPreviewModal] = useState<{
|
||||
isOpen: boolean;
|
||||
@@ -340,10 +360,13 @@ export const OutfitImageGallery: React.FC<OutfitImageGalleryProps> = ({
|
||||
{/* 记录头部 */}
|
||||
<div className="p-4 border-b border-gray-100">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className={`inline-flex items-center px-2 py-1 text-xs rounded-full ${getStatusColor(record.status)}`}>
|
||||
{getStatusIcon(record.status)}
|
||||
<span className="ml-1">{getStatusLabel(record.status)}</span>
|
||||
</span>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className={`inline-flex items-center px-2 py-1 text-xs rounded-full ${getStatusColor(record.status)}`}>
|
||||
{getStatusIcon(record.status)}
|
||||
<span className="ml-1">{getStatusLabel(record.status)}</span>
|
||||
</span>
|
||||
{renderGenerationType(record)}
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
{record.status === OutfitImageStatus.Failed && (
|
||||
<button
|
||||
@@ -494,6 +517,7 @@ export const OutfitImageGallery: React.FC<OutfitImageGalleryProps> = ({
|
||||
{getStatusIcon(record.status)}
|
||||
<span className="ml-1">{getStatusLabel(record.status)}</span>
|
||||
</span>
|
||||
{renderGenerationType(record)}
|
||||
<span className="text-sm text-gray-500">
|
||||
{formatDate(record.created_at)}
|
||||
</span>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { X, Sparkles } from 'lucide-react';
|
||||
import { Model } from '../types/model';
|
||||
@@ -26,6 +26,28 @@ export const OutfitImageGenerationModal: React.FC<OutfitImageGenerationModalProp
|
||||
onBatchGenerate,
|
||||
isGenerating = false
|
||||
}) => {
|
||||
// 新增状态
|
||||
const [useComfyUI, setUseComfyUI] = useState(false);
|
||||
|
||||
// 创建新的处理函数
|
||||
const handleGenerate = async (request: OutfitImageGenerationRequest) => {
|
||||
const enhancedRequest = {
|
||||
...request,
|
||||
use_comfyui: useComfyUI
|
||||
};
|
||||
await onGenerate(enhancedRequest);
|
||||
};
|
||||
|
||||
const handleBatchGenerate = async (requests: OutfitImageGenerationRequest[]) => {
|
||||
if (onBatchGenerate) {
|
||||
const enhancedRequests = requests.map(request => ({
|
||||
...request,
|
||||
use_comfyui: useComfyUI
|
||||
}));
|
||||
await onBatchGenerate(enhancedRequests);
|
||||
}
|
||||
};
|
||||
|
||||
// 键盘事件处理
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
@@ -87,12 +109,48 @@ export const OutfitImageGenerationModal: React.FC<OutfitImageGenerationModalProp
|
||||
{/* 主要内容区域 */}
|
||||
<div className="flex-1 overflow-y-auto p-6">
|
||||
<div className="max-w-2xl mx-auto">
|
||||
{/* 生成方式选择开关 */}
|
||||
<div className="flex items-center justify-between mb-6 p-4 bg-gradient-to-r from-gray-50 to-blue-50 rounded-xl border border-gray-200">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`w-10 h-10 rounded-lg flex items-center justify-center ${
|
||||
useComfyUI ? 'bg-blue-500' : 'bg-purple-500'
|
||||
}`}>
|
||||
{useComfyUI ? (
|
||||
<span className="text-white text-lg">🎨</span>
|
||||
) : (
|
||||
<span className="text-white text-lg">⚡</span>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-gray-900">
|
||||
{useComfyUI ? 'ComfyUI 高质量生成' : '标准快速生成'}
|
||||
</h3>
|
||||
<p className="text-xs text-gray-600">
|
||||
{useComfyUI ? '使用 ComfyUI 工作流,生成质量更高' : '使用标准算法,生成速度更快'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => setUseComfyUI(!useComfyUI)}
|
||||
className={`relative inline-flex h-7 w-12 items-center rounded-full transition-all duration-200 ${
|
||||
useComfyUI ? 'bg-blue-500 shadow-lg' : 'bg-gray-300'
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`inline-block h-5 w-5 transform rounded-full bg-white shadow-md transition-transform duration-200 ${
|
||||
useComfyUI ? 'translate-x-6' : 'translate-x-1'
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 穿搭图片生成器 */}
|
||||
<OutfitImageGenerator
|
||||
modelId={model.id}
|
||||
modelPhotos={model.photos}
|
||||
onGenerate={onGenerate}
|
||||
onBatchGenerate={onBatchGenerate}
|
||||
onGenerate={handleGenerate}
|
||||
onBatchGenerate={handleBatchGenerate}
|
||||
onClose={onClose}
|
||||
isGenerating={isGenerating}
|
||||
enableBatchMode={true}
|
||||
|
||||
@@ -610,6 +610,7 @@ const ModelDetail: React.FC = () => {
|
||||
<span className="text-lg mr-2">✨</span>
|
||||
生成穿搭图片
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
{/* 统计信息 */}
|
||||
|
||||
@@ -21,6 +21,8 @@ export interface OutfitImageRecord {
|
||||
completed_at?: string;
|
||||
duration_ms?: number;
|
||||
comfyui_prompt_id?: string; // ComfyUI 任务ID,用于精确匹配任务状态更新
|
||||
generation_type?: string; // 生成方式: "standard" | "comfyui"
|
||||
comfyui_task_id?: string; // ComfyUI 任务ID
|
||||
|
||||
// 关联数据
|
||||
product_images: ProductImage[];
|
||||
@@ -58,6 +60,7 @@ export interface OutfitImageGenerationRequest {
|
||||
generation_prompt?: string; // 可选的生成提示词
|
||||
style_preferences?: string[]; // 风格偏好
|
||||
product_index?: number; // 商品编号(用于调试文件命名)
|
||||
use_comfyui?: boolean; // 是否使用 ComfyUI 生成
|
||||
}
|
||||
|
||||
export interface OutfitImageGenerationResponse {
|
||||
@@ -66,6 +69,8 @@ export interface OutfitImageGenerationResponse {
|
||||
generation_time_ms: number;
|
||||
success: boolean;
|
||||
error_message?: string;
|
||||
generation_type?: string; // 生成方式: "standard" | "comfyui"
|
||||
task_id?: string; // ComfyUI 任务ID
|
||||
}
|
||||
|
||||
export interface OutfitImageStats {
|
||||
|
||||
847
openapi.json
847
openapi.json
@@ -181,7 +181,7 @@
|
||||
"视频模板管理"
|
||||
],
|
||||
"summary": "获取视频模板列表",
|
||||
"description": "获取视频模板列表,支持分页和按任务类型筛选\n\nArgs:\n task_type: 任务类型,如果为None则返回所有模板\n page: 页码,从1开始,默认1\n page_size: 每页记录数,默认100,最大1000\n \nReturns:\n {\n \"status\": True, \n \"data\": [模板数据列表], \n \"page\": 当前页码,\n \"page_size\": 每页数量,\n \"total\": 总记录数,\n \"total_pages\": 总页数\n }",
|
||||
"description": "获取视频模板列表,支持分页和按任务类型筛选\n\nArgs:\n category: 模版分类标签, 默认为 全部\n task_type: 任务类型,如果为None则返回所有模板\n page: 页码,从1开始,默认1\n page_size: 每页记录数,默认100,最大1000\n \nReturns:\n {\n \"status\": True, \n \"data\": [模板数据列表], \n \"page\": 当前页码,\n \"page_size\": 每页数量,\n \"total\": 总记录数,\n \"total_pages\": 总页数\n }",
|
||||
"operationId": "query_video_template_v2_api_template_default_get",
|
||||
"parameters": [
|
||||
{
|
||||
@@ -226,6 +226,18 @@
|
||||
"title": "Page Size"
|
||||
},
|
||||
"description": "每页数量"
|
||||
},
|
||||
{
|
||||
"name": "category",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"description": "模版分类,标签",
|
||||
"default": "全部",
|
||||
"title": "Category"
|
||||
},
|
||||
"description": "模版分类,标签"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -1071,190 +1083,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/veo/submit": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"veo视频生成"
|
||||
],
|
||||
"summary": "异步: 仅支持 text--> video",
|
||||
"description": "提交视频生成任务",
|
||||
"operationId": "submit_video_generation_api_veo_submit_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/VideoRequest"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"deprecated": true
|
||||
}
|
||||
},
|
||||
"/api/veo/async/submit": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"veo视频生成"
|
||||
],
|
||||
"summary": "异步:text-->video or text + img --> video",
|
||||
"operationId": "submit_iv_submit_api_veo_async_submit_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Body_submit_iv_submit_api_veo_async_submit_post"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"deprecated": true
|
||||
}
|
||||
},
|
||||
"/api/veo/sync/generate/video": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"veo视频生成"
|
||||
],
|
||||
"summary": "同步: 生成视频【文本+图片 OR 文生成视频】",
|
||||
"operationId": "sync_img_2video_api_veo_sync_generate_video_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Body_sync_img_2video_api_veo_sync_generate_video_post"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"deprecated": true
|
||||
}
|
||||
},
|
||||
"/api/veo/task/{task_id}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"veo视频生成"
|
||||
],
|
||||
"summary": "异步: 获取任务执行状态",
|
||||
"description": "异步获取任务运行结果",
|
||||
"operationId": "get_task_status_api_veo_task__task_id__get",
|
||||
"deprecated": true,
|
||||
"parameters": [
|
||||
{
|
||||
"name": "task_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Task Id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/veo/health": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"veo视频生成"
|
||||
],
|
||||
"summary": "健康检查",
|
||||
"description": "健康检查接口",
|
||||
"operationId": "health_check_api_veo_health_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"deprecated": true
|
||||
}
|
||||
},
|
||||
"/api/mj/video/async/submit": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@@ -1444,127 +1272,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/tt/video/async/submit/task": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"🔥midjourney视频生成接口"
|
||||
],
|
||||
"summary": "异步:提交任务,支持图片链接或者文件",
|
||||
"operationId": "async_submit_task_api_tt_video_async_submit_task_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Body_async_submit_task_api_tt_video_async_submit_task_post"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"deprecated": true
|
||||
}
|
||||
},
|
||||
"/api/tt/video/async/query/status": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"🔥midjourney视频生成接口"
|
||||
],
|
||||
"summary": "异步查询任务状态",
|
||||
"operationId": "query_task_status_async_api_tt_video_async_query_status_post",
|
||||
"deprecated": true,
|
||||
"parameters": [
|
||||
{
|
||||
"name": "task_id",
|
||||
"in": "query",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Task Id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/tt/video/sync/generate/video": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"🔥midjourney视频生成接口"
|
||||
],
|
||||
"summary": "同步生成视频【text+img-->video】",
|
||||
"operationId": "sync_gen_video_api_tt_video_sync_generate_video_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Body_sync_gen_video_api_tt_video_sync_generate_video_post"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"deprecated": true
|
||||
}
|
||||
},
|
||||
"/api/302/mj/async/generate/image": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@@ -1660,7 +1367,7 @@
|
||||
"🔥302ai Midjourney图片生成"
|
||||
],
|
||||
"summary": "异步查询任务状态",
|
||||
"description": "Args:\n task_id: 任务id\n task_type: 任务类型:image【生图】, describe【反推提示词】\n\nReturns:",
|
||||
"description": "Args:\n\n cdn_flag: 是否cdn转换,默认为False 【cnd 转换耗时】\n\n task_id: 任务id\n\n task_type: 任务类型:image【生图】, describe【反推提示词】\n\nReturns:",
|
||||
"operationId": "async_query_status_api_302_mj_async_query_status_get",
|
||||
"parameters": [
|
||||
{
|
||||
@@ -1681,6 +1388,16 @@
|
||||
"default": "image",
|
||||
"title": "Task Type"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "cdn_flag",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"title": "Cdn Flag"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -2217,6 +1934,249 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/302/hedra/v2/submit/task": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"hedra 口型合成【2.0】"
|
||||
],
|
||||
"summary": "提交口型合成任务",
|
||||
"operationId": "submit_character_task_api_302_hedra_v2_submit_task_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Body_submit_character_task_api_302_hedra_v2_submit_task_post"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"deprecated": true
|
||||
}
|
||||
},
|
||||
"/api/302/hedra/v2/task/status": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"hedra 口型合成【2.0】"
|
||||
],
|
||||
"summary": "查询任务状态",
|
||||
"operationId": "query_task_status_api_302_hedra_v2_task_status_get",
|
||||
"deprecated": true,
|
||||
"parameters": [
|
||||
{
|
||||
"name": "task_id",
|
||||
"in": "query",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"description": "task_id",
|
||||
"title": "Task Id"
|
||||
},
|
||||
"description": "task_id"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/302/hedra/v2/upload": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"hedra 口型合成【2.0】"
|
||||
],
|
||||
"summary": "上传文件到hedra服务器仅支持,image, audio",
|
||||
"operationId": "internal_upload_file_api_302_hedra_v2_upload_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Body_internal_upload_file_api_302_hedra_v2_upload_post"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"deprecated": true
|
||||
}
|
||||
},
|
||||
"/api/302/hedra/v3/file/upload": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"hedra 口型合成【3.0】"
|
||||
],
|
||||
"summary": "上传文件到hedra平台,返回资源的id",
|
||||
"operationId": "upload_file_to_hedra_api_302_hedra_v3_file_upload_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Body_upload_file_to_hedra_api_302_hedra_v3_file_upload_post"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/302/hedra/v3/submit/task": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"hedra 口型合成【3.0】"
|
||||
],
|
||||
"summary": "异步提交任务",
|
||||
"operationId": "handler_hedra_task_submit_api_302_hedra_v3_submit_task_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Body_handler_hedra_task_submit_api_302_hedra_v3_submit_task_post"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/302/hedra/v3/task/status": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"hedra 口型合成【3.0】"
|
||||
],
|
||||
"summary": "查询任务状态",
|
||||
"operationId": "handler_query_task_status_api_302_hedra_v3_task_status_get",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "task_id",
|
||||
"in": "query",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"description": "任务id",
|
||||
"title": "Task Id"
|
||||
},
|
||||
"description": "任务id"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/302/hl_router/sync/generate/speech": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@@ -2864,45 +2824,6 @@
|
||||
],
|
||||
"title": "Body_async_gen_video_api_jm_async_generate_video_post"
|
||||
},
|
||||
"Body_async_submit_task_api_tt_video_async_submit_task_post": {
|
||||
"properties": {
|
||||
"prompt": {
|
||||
"type": "string",
|
||||
"title": "Prompt",
|
||||
"description": "生成视频的提示词"
|
||||
},
|
||||
"img_url": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Img Url",
|
||||
"description": "首帧参数图url"
|
||||
},
|
||||
"img_file": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "binary"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Img File",
|
||||
"description": "首帧参考图文件"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"prompt"
|
||||
],
|
||||
"title": "Body_async_submit_task_api_tt_video_async_submit_task_post"
|
||||
},
|
||||
"Body_desc_img_by_file_api_302_mj_sync_file_img_describe_post": {
|
||||
"properties": {
|
||||
"img_file": {
|
||||
@@ -3137,6 +3058,46 @@
|
||||
],
|
||||
"title": "Body_generate_video_api_api_jm_generate_video_post"
|
||||
},
|
||||
"Body_handler_hedra_task_submit_api_302_hedra_v3_submit_task_post": {
|
||||
"properties": {
|
||||
"img_file": {
|
||||
"type": "string",
|
||||
"format": "binary",
|
||||
"title": "Img File",
|
||||
"description": "图片文件"
|
||||
},
|
||||
"audio_file": {
|
||||
"type": "string",
|
||||
"format": "binary",
|
||||
"title": "Audio File",
|
||||
"description": "音频文件"
|
||||
},
|
||||
"prompt": {
|
||||
"type": "string",
|
||||
"title": "Prompt",
|
||||
"description": "文本提示词",
|
||||
"default": ""
|
||||
},
|
||||
"resolution": {
|
||||
"type": "string",
|
||||
"title": "Resolution",
|
||||
"description": "分辨率支持: 720p, 540p",
|
||||
"default": "720p"
|
||||
},
|
||||
"aspect_ratio": {
|
||||
"type": "string",
|
||||
"title": "Aspect Ratio",
|
||||
"description": "尺寸: 1:1, 16:9, 9:16",
|
||||
"default": "1:1"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"img_file",
|
||||
"audio_file"
|
||||
],
|
||||
"title": "Body_handler_hedra_task_submit_api_302_hedra_v3_submit_task_post"
|
||||
},
|
||||
"Body_hl_tts_api_302_hl_router_sync_generate_speech_post": {
|
||||
"properties": {
|
||||
"text": {
|
||||
@@ -3174,6 +3135,43 @@
|
||||
],
|
||||
"title": "Body_hl_tts_api_302_hl_router_sync_generate_speech_post"
|
||||
},
|
||||
"Body_internal_upload_file_api_302_hedra_v2_upload_post": {
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"format": "binary",
|
||||
"title": "File",
|
||||
"description": "上传文件到hedra服务器,仅支持image与audio"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"file"
|
||||
],
|
||||
"title": "Body_internal_upload_file_api_302_hedra_v2_upload_post"
|
||||
},
|
||||
"Body_submit_character_task_api_302_hedra_v2_submit_task_post": {
|
||||
"properties": {
|
||||
"avatar_file": {
|
||||
"type": "string",
|
||||
"format": "binary",
|
||||
"title": "Avatar File",
|
||||
"description": "人像照片"
|
||||
},
|
||||
"audio_file": {
|
||||
"type": "string",
|
||||
"format": "binary",
|
||||
"title": "Audio File",
|
||||
"description": "音频文件"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"avatar_file",
|
||||
"audio_file"
|
||||
],
|
||||
"title": "Body_submit_character_task_api_302_hedra_v2_submit_task_post"
|
||||
},
|
||||
"Body_submit_iv_submit_api_302_veo_video_async_submit_post": {
|
||||
"properties": {
|
||||
"prompt": {
|
||||
@@ -3201,34 +3199,6 @@
|
||||
],
|
||||
"title": "Body_submit_iv_submit_api_302_veo_video_async_submit_post"
|
||||
},
|
||||
"Body_submit_iv_submit_api_veo_async_submit_post": {
|
||||
"properties": {
|
||||
"prompt": {
|
||||
"type": "string",
|
||||
"title": "Prompt",
|
||||
"description": "生成视频的提示词"
|
||||
},
|
||||
"img_file": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "binary"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Img File",
|
||||
"description": "首帧参考图"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"prompt",
|
||||
"img_file"
|
||||
],
|
||||
"title": "Body_submit_iv_submit_api_veo_async_submit_post"
|
||||
},
|
||||
"Body_submit_task_api_302_mj_video_async_submit_post": {
|
||||
"properties": {
|
||||
"prompt": {
|
||||
@@ -3287,7 +3257,7 @@
|
||||
"type": "string",
|
||||
"title": "Model",
|
||||
"description": "生图的模型",
|
||||
"default": "seedance_i2v"
|
||||
"default": "302/seedance_i2v"
|
||||
},
|
||||
"duration": {
|
||||
"type": "integer",
|
||||
@@ -3340,7 +3310,7 @@
|
||||
"type": "string",
|
||||
"title": "Model",
|
||||
"description": "生图的模型默认.mj",
|
||||
"default": "midjourney-v7-t2i"
|
||||
"default": "302/midjourney-v7-t2i"
|
||||
},
|
||||
"prompt": {
|
||||
"type": "string",
|
||||
@@ -3399,57 +3369,6 @@
|
||||
],
|
||||
"title": "Body_sync_gen_video_api_302_mj_video_sync_generate_video_post"
|
||||
},
|
||||
"Body_sync_gen_video_api_tt_video_sync_generate_video_post": {
|
||||
"properties": {
|
||||
"prompt": {
|
||||
"type": "string",
|
||||
"title": "Prompt",
|
||||
"description": "生成视频的提示词"
|
||||
},
|
||||
"img_url": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Img Url",
|
||||
"description": "首帧参数图url"
|
||||
},
|
||||
"img_file": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "binary"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Img File",
|
||||
"description": "首帧参考图文件"
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"title": "Timeout",
|
||||
"description": "超时时间",
|
||||
"default": 300
|
||||
},
|
||||
"interval": {
|
||||
"type": "integer",
|
||||
"title": "Interval",
|
||||
"description": "轮询间隔",
|
||||
"default": 3
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"prompt"
|
||||
],
|
||||
"title": "Body_sync_gen_video_api_tt_video_sync_generate_video_post"
|
||||
},
|
||||
"Body_sync_generate_video_v2_api_302_jm_sync_generate_video_post": {
|
||||
"properties": {
|
||||
"prompt": {
|
||||
@@ -3593,46 +3512,6 @@
|
||||
],
|
||||
"title": "Body_sync_img_2video_api_302_veo_video_sync_generate_video_post"
|
||||
},
|
||||
"Body_sync_img_2video_api_veo_sync_generate_video_post": {
|
||||
"properties": {
|
||||
"prompt": {
|
||||
"type": "string",
|
||||
"title": "Prompt",
|
||||
"description": "生成视频的提示词"
|
||||
},
|
||||
"img_file": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "binary"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Img File",
|
||||
"description": "首帧参考图,可选"
|
||||
},
|
||||
"max_wait_time": {
|
||||
"type": "integer",
|
||||
"title": "Max Wait Time",
|
||||
"description": "最大等待时间,单位秒",
|
||||
"default": 500
|
||||
},
|
||||
"interval": {
|
||||
"type": "integer",
|
||||
"title": "Interval",
|
||||
"description": "轮询间隔,单位秒",
|
||||
"default": 5
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"prompt",
|
||||
"img_file"
|
||||
],
|
||||
"title": "Body_sync_img_2video_api_veo_sync_generate_video_post"
|
||||
},
|
||||
"Body_sync_submit_task_api_mj_video_sync_gen_post": {
|
||||
"properties": {
|
||||
"img_file": {
|
||||
@@ -3665,6 +3544,27 @@
|
||||
],
|
||||
"title": "Body_upload_file_api_file_upload_post"
|
||||
},
|
||||
"Body_upload_file_to_hedra_api_302_hedra_v3_file_upload_post": {
|
||||
"properties": {
|
||||
"local_file": {
|
||||
"type": "string",
|
||||
"format": "binary",
|
||||
"title": "Local File",
|
||||
"description": "待上传的文件,支持音频,图片"
|
||||
},
|
||||
"purpose": {
|
||||
"type": "string",
|
||||
"title": "Purpose",
|
||||
"description": "上传文件的用途: 支持\"image\" \"audio\" \"video\" \"voice\"",
|
||||
"default": "image"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"local_file"
|
||||
],
|
||||
"title": "Body_upload_file_to_hedra_api_302_hedra_v3_file_upload_post"
|
||||
},
|
||||
"Body_upload_material_file_api_302_hl_router_sync_file_upload_post": {
|
||||
"properties": {
|
||||
"audio_file": {
|
||||
@@ -3867,19 +3767,6 @@
|
||||
"type"
|
||||
],
|
||||
"title": "ValidationError"
|
||||
},
|
||||
"VideoRequest": {
|
||||
"properties": {
|
||||
"prompt": {
|
||||
"type": "string",
|
||||
"title": "Prompt"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"prompt"
|
||||
],
|
||||
"title": "VideoRequest"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user