/** * 模板相关 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 "./editing-planner" import type { EditPlanConfig } from "./template-editor" /* ──────────── 类型定义 ──────────── */ /** 模板条目(后端 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分钟以上" }, ]