import { invoke } from '@tauri-apps/api/core'; import { save } from '@tauri-apps/plugin-dialog'; import { GroundingSource } from '../types/ragGrounding'; /** * 图片下载选项 */ export interface ImageDownloadOptions { /** 建议的文件名 */ suggestedName?: string; /** 文件扩展名 */ extension?: string; /** 是否显示保存对话框 */ showSaveDialog?: boolean; } /** * 图片下载结果 */ export interface ImageDownloadResult { /** 是否成功 */ success: boolean; /** 保存的文件路径 */ filePath?: string; /** 错误信息 */ error?: string; } /** * 图片下载服务 * 支持从URI下载图片到本地 */ export class ImageDownloadService { /** * 下载图片到本地 */ static async downloadImage( source: GroundingSource, options: ImageDownloadOptions = {} ): Promise { try { const { suggestedName, extension = 'jpg', showSaveDialog = true } = options; // 检查图片URI if (!source.uri) { return { success: false, error: '图片URI不存在' }; } // 生成建议的文件名 const defaultName = suggestedName || this.generateFileName(source); const fileName = `${defaultName}.${extension}`; let filePath: string | null = null; if (showSaveDialog) { // 显示保存对话框 filePath = await save({ defaultPath: fileName, filters: [ { name: '图片文件', extensions: ['jpg', 'jpeg', 'png', 'webp', 'gif'] }, { name: '所有文件', extensions: ['*'] } ] }); if (!filePath) { return { success: false, error: '用户取消了保存操作' }; } } else { // 使用默认下载目录 filePath = await this.getDefaultDownloadPath(fileName); } // 调用后端下载命令 await invoke('download_image_from_uri', { uri: source.uri, filePath: filePath }); return { success: true, filePath: filePath }; } catch (error) { console.error('图片下载失败:', error); return { success: false, error: error instanceof Error ? error.message : '下载失败' }; } } /** * 批量下载图片 */ static async downloadImages( sources: GroundingSource[], options: ImageDownloadOptions = {} ): Promise { const results: ImageDownloadResult[] = []; for (const source of sources) { const result = await this.downloadImage(source, { ...options, showSaveDialog: false // 批量下载时不显示对话框 }); results.push(result); } return results; } /** * 生成文件名 */ private static generateFileName(source: GroundingSource): string { const title = source.title || 'fashion_image'; const timestamp = new Date().toISOString().slice(0, 19).replace(/[:-]/g, ''); // 清理文件名中的特殊字符 const cleanTitle = title .replace(/[^\w\s-]/g, '') .replace(/\s+/g, '_') .toLowerCase(); return `${cleanTitle}_${timestamp}`; } /** * 获取默认下载路径 */ private static async getDefaultDownloadPath(fileName: string): Promise { try { // 调用后端获取默认下载目录 const downloadDir = await invoke('get_default_download_directory'); return `${downloadDir}/${fileName}`; } catch (error) { // 如果获取失败,使用当前目录 return fileName; } } /** * 检查图片是否可下载 */ static isDownloadable(source: GroundingSource): boolean { return !!(source.uri && source.uri.startsWith('http')); } /** * 获取图片信息 */ static getImageInfo(source: GroundingSource): { title: string; description: string; size?: string; format?: string; } { const imageData = source.content?.text || source.content; return { title: source.title || '时尚图片', description: imageData?.description || '', size: imageData?.size, format: this.extractImageFormat(source.uri) }; } /** * 从URI提取图片格式 */ private static extractImageFormat(uri?: string): string | undefined { if (!uri) return undefined; const match = uri.match(/\.([a-zA-Z0-9]+)(?:\?|$)/); return match ? match[1].toLowerCase() : undefined; } } export default ImageDownloadService;