/** * 模板相关 API * 对接后端模板管理接口: * - GET /api/v1/templates — 模板列表(分页/筛选) * - GET /api/v1/templates/{id} — 模板详情 * - POST /api/v1/templates/{id}/copy — 复制模板 * - POST /api/v1/templates/{id}/generate — 从模板生成剪辑计划 * - POST /api/v1/templates/{id}/toggle-favorite — 收藏/取消收藏 */ import apiClient from "./client"; import type { TitleConfig, SubtitleConfig, BgmConfig } from "./editingPlanner"; import type { EditPlanConfig } from "./editPlans"; /* ──────────── 类型定义 ──────────── */ /** 模板条目(后端 TemplateResponse) */ export interface TemplateItem { id: string; user_id?: string; name: string; description?: string; mode?: string; category: string; tags?: string[]; /** 预估时长(后端字段名 estimated_duration) */ estimated_duration?: number; /** @deprecated 后端已改名为 estimated_duration,保留兼容 */ target_duration?: number; clip_count?: number; /** 使用次数 */ usage_count?: number; thumbnail_url?: string; preview_url?: string; is_active?: boolean; is_favorite?: boolean; /** 素材规则(片段配置) */ segments?: TemplateSegment[]; /** 字幕样式 */ subtitle_config?: SubtitleConfig; /** BGM 配置 */ bgm_config?: BgmConfig; /** 标题配置 */ title_config?: TitleConfig; /** 视频比例 */ aspect_ratio?: string; created_at?: string; updated_at?: string; } /** 模板片段(素材规则) */ export interface TemplateSegment { id?: string; segment_order: number; duration_min: number; duration_max: number; material_type: string | null; description?: string; } /** 模板列表查询参数 */ export interface TemplateListParams { page?: number; page_size?: number; category?: string; tags?: string; keyword?: string; /** 时长筛选(秒):short < 30, medium 30-120, long > 120 */ duration_range?: "short" | "medium" | "long"; } /** 模板列表分页响应 */ export interface TemplateListResponse { items: TemplateItem[]; total: number; page: number; page_size: number; } /** 从模板生成剪辑计划请求 */ export interface GenerateFromTemplateRequest { asset_ids?: string[]; name?: string; config?: EditPlanConfig; } /** 从模板生成剪辑计划响应 */ export interface GenerateFromTemplateResponse { plan_id: string; template_id: string; status: string; name: string; } /** 复制模板响应 */ export interface CopyTemplateResponse { id: string; name: string; source_template_id: string; } /* ──────────── API 函数 ──────────── */ /** 获取模板列表(支持分页和筛选) */ export const getTemplates = async ( params?: TemplateListParams, ): Promise => { const { data } = await apiClient.get("/templates", { params, }); return data; }; /** 获取模板列表(兼容旧接口,返回数组) */ export const getTemplatesList = async (): Promise => { const response = await apiClient.get("/templates"); return response.data.items || response.data || []; }; /** 获取单个模板详情 */ export const getTemplate = async ( templateId: string, ): Promise => { const response = await apiClient.get(`/templates/${templateId}`); return response.data; }; /** 收藏 / 取消收藏模板 */ export const toggleFavoriteTemplate = async ( templateId: string, ): Promise<{ is_favorite: boolean }> => { const response = await apiClient.post( `/templates/${templateId}/toggle-favorite`, ); return response.data; }; /** 复制模板(创建副本到我的模板) */ export const copyTemplate = async ( templateId: string, ): Promise => { const response = await apiClient.post( `/templates/${templateId}/copy`, ); return response.data; }; /** 从模板生成剪辑计划 */ export const generateFromTemplate = async ( templateId: string, data?: GenerateFromTemplateRequest, ): Promise => { const response = await apiClient.post( `/templates/${templateId}/generate`, data, ); return response.data; }; /* ──────────── 常量 ──────────── */ /** 模板分类选项 */ export const TEMPLATE_CATEGORY_OPTIONS = [ { value: "", label: "全部分类" }, { value: "口播", label: "口播" }, { value: "种草", label: "种草" }, { value: "产品", label: "产品" }, { value: "品牌", label: "品牌" }, { value: "混剪", label: "混剪" }, { value: "Vlog", label: "Vlog" }, ]; /** 时长筛选选项 */ export const TEMPLATE_DURATION_OPTIONS = [ { value: "", label: "全部时长" }, { value: "short", label: "30秒以内" }, { value: "medium", label: "30秒-2分钟" }, { value: "long", label: "2分钟以上" }, ];