From 26e99b28cc457e9f8c06ded412dc18c0d5f7c6b2 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Sun, 26 Jul 2026 17:09:47 +0800 Subject: [PATCH] =?UTF-8?q?refactor(api):=20=E6=8B=86=E5=88=86=20templates?= =?UTF-8?q?.ts=20=E4=B8=BA=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=EF=BC=88typ?= =?UTF-8?q?es/constants/templates/index=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 168 行的 templates.ts 拆分为目录化结构: - types.ts: 类型定义(TemplateItem/TemplateSegment 等) - constants.ts: 常量配置(分类/时长筛选选项) - templates.ts: 全部 6 个 API 函数 - index.ts: 统一入口 re-export,保持 @/api/templates 路径向后兼容 主入口从 168 行减少到约 35 行,按职责清晰分层。 --- apps/web/src/api/templates.ts | 168 ------------------------ apps/web/src/api/templates/constants.ts | 22 ++++ apps/web/src/api/templates/index.ts | 28 ++++ apps/web/src/api/templates/templates.ts | 59 +++++++++ apps/web/src/api/templates/types.ts | 90 +++++++++++++ 5 files changed, 199 insertions(+), 168 deletions(-) delete mode 100644 apps/web/src/api/templates.ts create mode 100644 apps/web/src/api/templates/constants.ts create mode 100644 apps/web/src/api/templates/index.ts create mode 100644 apps/web/src/api/templates/templates.ts create mode 100644 apps/web/src/api/templates/types.ts diff --git a/apps/web/src/api/templates.ts b/apps/web/src/api/templates.ts deleted file mode 100644 index a7a5587f0..000000000 --- a/apps/web/src/api/templates.ts +++ /dev/null @@ -1,168 +0,0 @@ -/** - * 模板相关 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分钟以上" }, -] diff --git a/apps/web/src/api/templates/constants.ts b/apps/web/src/api/templates/constants.ts new file mode 100644 index 000000000..e0952e079 --- /dev/null +++ b/apps/web/src/api/templates/constants.ts @@ -0,0 +1,22 @@ +/** + * 模板相关常量 + */ + +/** 模板分类选项 */ +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分钟以上" }, +] diff --git a/apps/web/src/api/templates/index.ts b/apps/web/src/api/templates/index.ts new file mode 100644 index 000000000..bece1cbb4 --- /dev/null +++ b/apps/web/src/api/templates/index.ts @@ -0,0 +1,28 @@ +/** + * 模板相关 API — 目录化入口 + * 保持与原 templates.ts 相同导出,向后兼容 + */ + +// 类型 +export type { + TemplateItem, + TemplateSegment, + TemplateListParams, + TemplateListResponse, + GenerateFromTemplateRequest, + GenerateFromTemplateResponse, + CopyTemplateResponse, +} from "./types" + +// 常量 +export { TEMPLATE_CATEGORY_OPTIONS, TEMPLATE_DURATION_OPTIONS } from "./constants" + +// API 函数 +export { + getTemplates, + getTemplatesList, + getTemplate, + toggleFavoriteTemplate, + copyTemplate, + generateFromTemplate, +} from "./templates" diff --git a/apps/web/src/api/templates/templates.ts b/apps/web/src/api/templates/templates.ts new file mode 100644 index 000000000..d388f932a --- /dev/null +++ b/apps/web/src/api/templates/templates.ts @@ -0,0 +1,59 @@ +/** + * 模板相关 API 函数 + * 对接后端模板管理接口 + */ +import apiClient from "../client" +import type { + CopyTemplateResponse, + GenerateFromTemplateRequest, + GenerateFromTemplateResponse, + TemplateItem, + TemplateListParams, + TemplateListResponse, +} from "./types" + +/** 获取模板列表(支持分页和筛选) */ +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 +} diff --git a/apps/web/src/api/templates/types.ts b/apps/web/src/api/templates/types.ts new file mode 100644 index 000000000..8b0575dd7 --- /dev/null +++ b/apps/web/src/api/templates/types.ts @@ -0,0 +1,90 @@ +/** + * 模板相关类型定义 + */ +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 +} -- 2.54.0