mixvideo-v2/apps/desktop/src/services/comfyuiService.ts

298 lines
8.1 KiB
TypeScript

/**
* ComfyUI API 服务层
* 封装所有 ComfyUI API 调用,提供类型安全的前端服务接口
*/
import { invoke } from '@tauri-apps/api/core';
import type {
ComfyuiConfig,
Workflow,
PublishWorkflowRequest,
PublishWorkflowResponse,
DeleteWorkflowResponse,
ExecuteWorkflowRequest,
ExecuteWorkflowResponse,
GetWorkflowSpecRequest,
GetWorkflowSpecResponse,
ServerStatus,
ServerFiles,
ApiRootResponse,
} from '../types/comfyui';
/**
* ComfyUI API 服务类
*/
export class ComfyuiService {
// ============================================================================
// 工作流管理
// ============================================================================
/**
* 获取所有工作流
*/
static async getAllWorkflows(): Promise<Workflow[]> {
try {
const workflows = await invoke<Workflow[]>('comfyui_get_all_workflows');
return workflows;
} catch (error) {
console.error('Failed to get workflows:', error);
throw new Error(`获取工作流列表失败: ${error}`);
}
}
/**
* 发布工作流
*/
static async publishWorkflow(request: PublishWorkflowRequest): Promise<PublishWorkflowResponse> {
try {
const response = await invoke<PublishWorkflowResponse>('comfyui_publish_workflow', { request });
return response;
} catch (error) {
console.error('Failed to publish workflow:', error);
throw new Error(`发布工作流失败: ${error}`);
}
}
/**
* 删除工作流
*/
static async deleteWorkflow(workflowName: string): Promise<DeleteWorkflowResponse> {
try {
const response = await invoke<DeleteWorkflowResponse>('comfyui_delete_workflow', {
workflow_name: workflowName
});
return response;
} catch (error) {
console.error('Failed to delete workflow:', error);
throw new Error(`删除工作流失败: ${error}`);
}
}
// ============================================================================
// 工作流执行
// ============================================================================
/**
* 执行工作流
*/
static async executeWorkflow(request: ExecuteWorkflowRequest): Promise<ExecuteWorkflowResponse> {
try {
const response = await invoke<ExecuteWorkflowResponse>('comfyui_execute_workflow', { request });
return response;
} catch (error) {
console.error('Failed to execute workflow:', error);
throw new Error(`执行工作流失败: ${error}`);
}
}
/**
* 获取工作流规范
*/
static async getWorkflowSpec(request: GetWorkflowSpecRequest): Promise<GetWorkflowSpecResponse> {
try {
const response = await invoke<GetWorkflowSpecResponse>('comfyui_get_workflow_spec', { request });
return response;
} catch (error) {
console.error('Failed to get workflow spec:', error);
throw new Error(`获取工作流规范失败: ${error}`);
}
}
// ============================================================================
// 服务器管理
// ============================================================================
/**
* 获取服务器状态
*/
static async getServersStatus(): Promise<ServerStatus[]> {
try {
const servers = await invoke<ServerStatus[]>('comfyui_get_servers_status');
return servers;
} catch (error) {
console.error('Failed to get servers status:', error);
throw new Error(`获取服务器状态失败: ${error}`);
}
}
/**
* 获取服务器文件列表
*/
static async listServerFiles(serverIndex: number): Promise<ServerFiles> {
try {
const files = await invoke<ServerFiles>('comfyui_list_server_files', {
server_index: serverIndex
});
return files;
} catch (error) {
console.error('Failed to get server files:', error);
throw new Error(`获取服务器文件失败: ${error}`);
}
}
// ============================================================================
// API 信息
// ============================================================================
/**
* 获取 API 根信息
*/
static async getApiRoot(): Promise<ApiRootResponse> {
try {
const apiInfo = await invoke<ApiRootResponse>('comfyui_get_api_root');
return apiInfo;
} catch (error) {
console.error('Failed to get API root:', error);
throw new Error(`获取API信息失败: ${error}`);
}
}
// ============================================================================
// 连接和配置管理
// ============================================================================
/**
* 测试连接
*/
static async testConnection(): Promise<boolean> {
try {
const isConnected = await invoke<boolean>('comfyui_test_connection');
return isConnected;
} catch (error) {
console.error('Failed to test connection:', error);
throw new Error(`连接测试失败: ${error}`);
}
}
/**
* 获取配置
*/
static async getConfig(): Promise<ComfyuiConfig> {
try {
const config = await invoke<ComfyuiConfig>('comfyui_get_config');
return config;
} catch (error) {
console.error('Failed to get config:', error);
throw new Error(`获取配置失败: ${error}`);
}
}
/**
* 更新配置
*/
static async updateConfig(config: ComfyuiConfig): Promise<boolean> {
try {
const success = await invoke<boolean>('comfyui_update_config', { config });
return success;
} catch (error) {
console.error('Failed to update config:', error);
throw new Error(`更新配置失败: ${error}`);
}
}
// ============================================================================
// 辅助方法
// ============================================================================
/**
* 解析工作流名称,提取基础名称和版本
*/
static parseWorkflowName(fullName: string): { baseName: string; version?: string } {
// 工作流名称格式: 'my_workflow [20250101120000]'
const match = fullName.match(/^(.+?)\s*\[(.+?)\]$/);
if (match) {
return {
baseName: match[1].trim(),
version: match[2].trim(),
};
}
return { baseName: fullName };
}
/**
* 格式化工作流名称
*/
static formatWorkflowName(baseName: string, version?: string): string {
if (version) {
return `${baseName} [${version}]`;
}
return baseName;
}
/**
* 验证 JSON 字符串
*/
static validateJson(jsonString: string): { valid: boolean; error?: string } {
try {
JSON.parse(jsonString);
return { valid: true };
} catch (error) {
return {
valid: false,
error: error instanceof Error ? error.message : 'Invalid JSON format'
};
}
}
/**
* 格式化文件大小
*/
static formatFileSize(sizeKb: number): string {
if (sizeKb < 1024) {
return `${sizeKb.toFixed(1)} KB`;
} else if (sizeKb < 1024 * 1024) {
return `${(sizeKb / 1024).toFixed(1)} MB`;
} else {
return `${(sizeKb / (1024 * 1024)).toFixed(1)} GB`;
}
}
/**
* 格式化时间
*/
static formatDateTime(dateString: string): string {
try {
const date = new Date(dateString);
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
} catch (error) {
return dateString;
}
}
/**
* 获取服务器状态显示文本
*/
static getServerStatusText(server: ServerStatus): string {
if (!server.is_reachable) {
return '不可达';
}
if (server.is_free) {
return '空闲';
}
const { running_count, pending_count } = server.queue_details;
return `运行中: ${running_count}, 等待: ${pending_count}`;
}
/**
* 获取服务器状态颜色
*/
static getServerStatusColor(server: ServerStatus): 'success' | 'warning' | 'error' {
if (!server.is_reachable) {
return 'error';
}
if (server.is_free) {
return 'success';
}
return 'warning';
}
}
export default ComfyuiService;