import { invoke } from '@tauri-apps/api/core' import { useAuthStore } from '../stores/useAuthStore' // 统一的响应格式 export interface TemplateResponse { success: boolean message: string data?: any output?: string error?: string } // 模板信息接口 export interface TemplateInfo { id: string name: string description: string thumbnail_path: string draft_content_path: string resources_path: string created_at: string updated_at: string canvas_config: any duration: number material_count: number track_count: number tags: string[] is_cloud: boolean user_id: string } // 请求接口 export interface BatchImportRequest { source_folder: string user_id?: string verbose?: boolean json_output?: boolean } export interface TemplateListRequest { user_id?: string include_cloud?: boolean limit?: number verbose?: boolean json_output?: boolean } export interface TemplateGetRequest { template_id: string user_id?: string verbose?: boolean json_output?: boolean } export interface TemplateDeleteRequest { template_id: string user_id?: string verbose?: boolean json_output?: boolean } export interface TemplateSearchRequest { query: string user_id?: string include_cloud?: boolean limit?: number verbose?: boolean json_output?: boolean } // 批量导入结果 export interface BatchImportResult { imported_count: number failed_count: number imported_templates: Array<{ id: string name: string path: string }> failed_templates: Array<{ name: string path: string error: string }> message: string } // 统计信息 export interface TemplateStats { total_templates: number user_templates: number cloud_templates: number total_materials: number total_tracks: number total_duration: number average_duration: number } // 标签信息 export interface TagInfo { tag: string count: number } // 轨道片段信息 export interface TrackSegment { id: string type: 'video' | 'audio' | 'image' | 'text' | 'effect' name: string start_time: number end_time: number duration: number resource_path?: string properties?: any effects?: any[] } // 轨道信息 export interface Track { id: string name: string type: 'video' | 'audio' | 'effect' | 'text' | 'sticker' | 'image' index: number segments: TrackSegment[] properties?: any } // 模板详细信息 export interface TemplateDetail { id: string name: string description: string canvas_config: any tracks: Track[] duration: number fps: number sample_rate?: number } export class TemplateServiceV2 { /** * 获取当前用户ID */ private static getCurrentUserId(): string { const authState = useAuthStore.getState() if (!authState.isAuthenticated || !authState.user?.id) { throw new Error('用户未登录,请先登录后再进行操作') } return authState.user.id } /** * 批量导入模板 (新版本) */ static async batchImportTemplates(sourceFolder: string, userId?: string): Promise { try { const request: BatchImportRequest = { source_folder: sourceFolder, user_id: userId || this.getCurrentUserId(), verbose: false, json_output: true } const response = await invoke('batch_import_templates_cli', { request }) if (!response.success) { throw new Error(response.error || response.message || 'Import failed') } return response.data as BatchImportResult } catch (error) { console.error('Batch import templates failed:', error) throw error } } /** * 获取模板列表 (新版本) */ static async getTemplates(includeCloud: boolean = true, limit: number = 100, userId?: string): Promise { try { const request: TemplateListRequest = { user_id: userId || this.getCurrentUserId(), include_cloud: includeCloud, limit: limit, verbose: false, json_output: true } const response = await invoke('get_templates_cli', { request }) if (!response.success) { throw new Error(response.error || response.message || 'Failed to get templates') } return response.data?.templates || [] } catch (error) { console.error('Get templates failed:', error) throw error } } /** * 获取单个模板 (新版本) */ static async getTemplate(templateId: string, userId?: string): Promise { try { const request: TemplateGetRequest = { template_id: templateId, user_id: userId || this.getCurrentUserId(), verbose: false, json_output: true } const response = await invoke('get_template_cli', { request }) if (!response.success) { throw new Error(response.error || response.message || 'Failed to get template') } return response.data as TemplateInfo } catch (error) { console.error('Get template failed:', error) throw error } } /** * 获取模板详细信息 (新版本) * 注意:目前使用原版本的get_template_detail命令,因为CLI版本还未实现详细信息功能 */ static async getTemplateDetail(templateId: string): Promise { try { // 暂时使用原版本的命令,直到CLI版本实现详细信息功能 const response = await invoke('get_template_detail', { template_id: templateId }) const detail = JSON.parse(response) if (!detail) { return null } return detail as TemplateDetail } catch (error) { console.error('Get template detail failed:', error) return null } } /** * 删除模板 (新版本) */ static async deleteTemplate(templateId: string, userId?: string): Promise { try { const request: TemplateDeleteRequest = { template_id: templateId, user_id: userId || this.getCurrentUserId(), verbose: false, json_output: true } const response = await invoke('delete_template_cli', { request }) if (!response.success) { throw new Error(response.error || response.message || 'Failed to delete template') } return response.data?.deleted || false } catch (error) { console.error('Delete template failed:', error) throw error } } /** * 搜索模板 (新功能) */ static async searchTemplates( query: string, includeCloud: boolean = true, limit: number = 50, userId?: string ): Promise { try { const request: TemplateSearchRequest = { query: query, user_id: userId || this.getCurrentUserId(), include_cloud: includeCloud, limit: limit, verbose: false, json_output: true } const response = await invoke('search_templates_cli', { request }) if (!response.success) { throw new Error(response.error || response.message || 'Failed to search templates') } return response.data?.templates || [] } catch (error) { console.error('Search templates failed:', error) throw error } } /** * 获取模板统计信息 (新功能) */ static async getTemplateStats(userId?: string): Promise { try { const response = await invoke('get_template_stats_cli', { user_id: userId || this.getCurrentUserId(), verbose: false }) if (!response.success) { throw new Error(response.error || response.message || 'Failed to get template stats') } return response.data as TemplateStats } catch (error) { console.error('Get template stats failed:', error) throw error } } /** * 获取热门标签 (新功能) */ static async getPopularTags(limit: number = 20, userId?: string): Promise { try { const response = await invoke('get_popular_tags_cli', { user_id: userId || this.getCurrentUserId(), limit: limit, verbose: false }) if (!response.success) { throw new Error(response.error || response.message || 'Failed to get popular tags') } return response.data?.tags || [] } catch (error) { console.error('Get popular tags failed:', error) throw error } } /** * 根据标签获取模板 (新功能) */ static async getTemplatesByTag( tag: string, includeCloud: boolean = true, limit: number = 50, userId?: string ): Promise { try { const response = await invoke('get_templates_by_tag_cli', { tag: tag, user_id: userId || this.getCurrentUserId(), include_cloud: includeCloud, limit: limit, verbose: false }) if (!response.success) { throw new Error(response.error || response.message || 'Failed to get templates by tag') } return response.data?.templates || [] } catch (error) { console.error('Get templates by tag failed:', error) throw error } } /** * 验证模板文件夹结构 */ static validateTemplateFolder(folderPath: string): boolean { // 这个方法保持不变,依赖后端验证 return true } /** * 格式化持续时间 */ static formatDuration(seconds: number): string { const minutes = Math.floor(seconds / 60) const remainingSeconds = seconds % 60 return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}` } /** * 格式化日期 */ static formatDate(dateString: string): string { try { const date = new Date(dateString) return date.toLocaleDateString('zh-CN', { year: 'numeric', month: 'short', day: 'numeric' }) } catch { return dateString } } /** * 获取模板缩略图URL */ static getThumbnailUrl(template: TemplateInfo): string { if (template.thumbnail_path) { // 如果是相对路径,转换为绝对路径 if (!template.thumbnail_path.startsWith('http') && !template.thumbnail_path.startsWith('/')) { return `file://${template.resources_path}/${template.thumbnail_path}` } return template.thumbnail_path } return '' } /** * 检查模板是否为云端模板 */ static isCloudTemplate(template: TemplateInfo): boolean { return template.is_cloud || false } /** * 检查模板是否属于当前用户 */ static isUserTemplate(template: TemplateInfo, userId?: string): boolean { return template.user_id === (userId || this.getCurrentUserId()) } }