fix(p0): 前端API路径全量迁移到 /templates/{templateId}/editor #666

Merged
auto-approve-bot merged 1 commits from fix/p0-template-editor-api-migration into develop 2026-07-21 08:08:48 +08:00
19 changed files with 70 additions and 62 deletions
+1 -1
View File
@@ -227,7 +227,7 @@ test.describe("Core generation flow", () => {
const path = new URL(url).pathname
return (
response.request().method() === "POST" &&
(path.endsWith("/template-editors") || path.endsWith("/template-editors/"))
(path.endsWith("/templates/drafts") || path.endsWith("/templates/drafts/"))
)
},
{ timeout: 30_000 },
@@ -345,71 +345,71 @@ export interface EditPlanListResponse {
/** 获取模板草稿列表(支持分页和筛选) */
export async function getEditPlans(params?: EditPlanListParams): Promise<EditPlanListResponse> {
const response = await apiClient.get<EditPlanListResponse>("/template-editors", {
const response = await apiClient.get<EditPlanListResponse>("/templates/drafts", {
params,
})
return response.data
}
/** 获取单个模板草稿 */
export async function getEditPlan(planId: string): Promise<EditPlan> {
const response = await apiClient.get(`/template-editors/${planId}`)
export async function getEditPlan(templateId: string): Promise<EditPlan> {
const response = await apiClient.get(`/templates/${templateId}/editor`)
return response.data
}
/** 创建模板草稿 */
export async function createEditPlan(data: CreateEditPlanRequest): Promise<EditPlan> {
const response = await apiClient.post("/template-editors", data)
const response = await apiClient.post("/templates/drafts", data)
return response.data
}
/** 更新模板草稿 */
export async function updateEditPlan(
planId: string,
templateId: string,
data: UpdateEditPlanRequest,
): Promise<EditPlan> {
const response = await apiClient.put(`/template-editors/${planId}`, data)
const response = await apiClient.put(`/templates/${templateId}/editor`, data)
return response.data
}
/** 删除模板草稿 */
export async function deleteEditPlan(planId: string): Promise<void> {
await apiClient.delete(`/template-editors/${planId}`)
export async function deleteEditPlan(templateId: string): Promise<void> {
await apiClient.delete(`/templates/${templateId}/editor`)
}
/** 触发生成 */
export async function generateEditPlan(planId: string): Promise<GenerateResponse> {
const response = await apiClient.post(`/template-editors/${planId}/generate`)
export async function generateEditPlan(templateId: string): Promise<GenerateResponse> {
const response = await apiClient.post(`/templates/${templateId}/editor/generate`)
return response.data
}
/** 获取生成状态(轮询用) */
export async function getGenerationStatus(planId: string): Promise<GenerationStatusResponse> {
const response = await apiClient.get(`/template-editors/${planId}/generation-status`)
export async function getGenerationStatus(templateId: string): Promise<GenerationStatusResponse> {
const response = await apiClient.get(`/templates/${templateId}/editor/generation-status`)
return response.data
}
/** AI 推荐片段方案 */
export async function aiRecommendClips(
planId: string,
templateId: string,
data: AIRecommendRequest,
): Promise<AIRecommendResponse> {
const response = await apiClient.post(`/template-editors/${planId}/ai-recommend`, data)
const response = await apiClient.post(`/templates/${templateId}/editor/ai-recommend`, data)
return response.data
}
/** AI 生成封面 */
export async function generateCover(
planId: string,
templateId: string,
data: GenerateCoverRequest,
): Promise<GenerateCoverResponse> {
const response = await apiClient.post(`/template-editors/${planId}/generate-cover`, data)
const response = await apiClient.post(`/templates/${templateId}/editor/generate-cover`, data)
return response.data
}
/** 获取模板草稿关联的生成记录 */
export async function getEditPlanGenerations(planId: string): Promise<EditPlanGeneration[]> {
const response = await apiClient.get(`/template-editors/${planId}/generations`)
export async function getEditPlanGenerations(templateId: string): Promise<EditPlanGeneration[]> {
const response = await apiClient.get(`/templates/${templateId}/editor/generations`)
return response.data.items || []
}
@@ -420,8 +420,8 @@ export async function getGenerationTaskResults(taskId: string): Promise<Generate
}
/** 取消生成任务 */
export async function cancelGeneration(planId: string): Promise<void> {
await apiClient.post(`/template-editors/${planId}/cancel`)
export async function cancelGeneration(templateId: string): Promise<void> {
await apiClient.post(`/templates/${templateId}/editor/cancel`)
}
/* ============================================================
@@ -493,11 +493,11 @@ export interface EditPlanClipListParams {
/** 获取片段列表 */
export async function getEditPlanClips(
planId: string,
templateId: string,
params?: EditPlanClipListParams,
): Promise<EditPlanClipListResponse> {
const response = await apiClient.get<EditPlanClipListResponse>(
`/template-editors/${planId}/clips`,
`/templates/${templateId}/editor/clips`,
{
params,
},
@@ -506,36 +506,38 @@ export async function getEditPlanClips(
}
/** 获取单个片段详情 */
export async function getEditPlanClip(planId: string, clipId: string): Promise<EditPlanClip> {
const response = await apiClient.get<EditPlanClip>(`/template-editors/${planId}/clips/${clipId}`)
export async function getEditPlanClip(templateId: string, clipId: string): Promise<EditPlanClip> {
const response = await apiClient.get<EditPlanClip>(
`/templates/${templateId}/editor/clips/${clipId}`,
)
return response.data
}
/** 创建片段 */
export async function createEditPlanClip(
planId: string,
templateId: string,
data: CreateEditPlanClipRequest,
): Promise<EditPlanClip> {
const response = await apiClient.post<EditPlanClip>(`/template-editors/${planId}/clips`, data)
const response = await apiClient.post<EditPlanClip>(`/templates/${templateId}/editor/clips`, data)
return response.data
}
/** 更新片段 */
export async function updateEditPlanClip(
planId: string,
templateId: string,
clipId: string,
data: UpdateEditPlanClipRequest,
): Promise<EditPlanClip> {
const response = await apiClient.put<EditPlanClip>(
`/template-editors/${planId}/clips/${clipId}`,
`/templates/${templateId}/editor/clips/${clipId}`,
data,
)
return response.data
}
/** 删除片段 */
export async function deleteEditPlanClip(planId: string, clipId: string): Promise<void> {
await apiClient.delete(`/template-editors/${planId}/clips/${clipId}`)
export async function deleteEditPlanClip(templateId: string, clipId: string): Promise<void> {
await apiClient.delete(`/templates/${templateId}/editor/clips/${clipId}`)
}
/* ============================================================
@@ -572,11 +574,11 @@ export interface ClipsFromAssetsResponse {
/** 片段重排序(拖拽排序后一次性提交) */
export async function reorderEditPlanClips(
planId: string,
templateId: string,
items: ClipReorderItem[],
): Promise<ClipReorderResponse> {
const response = await apiClient.post<ClipReorderResponse>(
`/template-editors/${planId}/clips/reorder`,
`/templates/${templateId}/editor/clips/reorder`,
{ items },
)
return response.data
@@ -584,11 +586,11 @@ export async function reorderEditPlanClips(
/** 批量删除片段 */
export async function batchDeleteEditPlanClips(
planId: string,
templateId: string,
clipIds: string[],
): Promise<ClipBatchDeleteResponse> {
const response = await apiClient.post<ClipBatchDeleteResponse>(
`/template-editors/${planId}/clips/batch-delete`,
`/templates/${templateId}/editor/clips/batch-delete`,
{ clip_ids: clipIds },
)
return response.data
@@ -596,12 +598,12 @@ export async function batchDeleteEditPlanClips(
/** 从素材批量创建片段(追加到时间线末尾) */
export async function createClipsFromAssets(
planId: string,
templateId: string,
assetIds: string[],
clipType = "main",
): Promise<ClipsFromAssetsResponse> {
const response = await apiClient.post<ClipsFromAssetsResponse>(
`/template-editors/${planId}/clips/from-assets`,
`/templates/${templateId}/editor/clips/from-assets`,
{ asset_ids: assetIds, clip_type: clipType },
)
return response.data
@@ -618,8 +620,14 @@ export interface CopyEditPlanRequest {
}
/** 复制模板草稿(含所有片段配置) */
export async function copyEditPlan(planId: string, data?: CopyEditPlanRequest): Promise<EditPlan> {
const response = await apiClient.post<EditPlan>(`/template-editors/${planId}/copy`, data || {})
export async function copyEditPlan(
templateId: string,
data?: CopyEditPlanRequest,
): Promise<EditPlan> {
const response = await apiClient.post<EditPlan>(
`/templates/${templateId}/editor/copy`,
data || {},
)
return response.data
}
+1 -1
View File
@@ -9,7 +9,7 @@
*/
import apiClient from "./client"
import type { TitleConfig, SubtitleConfig, BgmConfig } from "./editingPlanner"
import type { EditPlanConfig } from "./editPlans"
import type { EditPlanConfig } from "./templateEditor"
/* ──────────── 类型定义 ──────────── */
@@ -12,8 +12,8 @@
import React, { useState, useMemo, useCallback, useRef, useEffect } from "react"
import "./AssetSelector.css"
import { Input, Select, Button } from "@/components/ui"
import type { MediaAsset } from "@/api/editPlans"
import { MATERIAL_TYPE_LABELS, MATERIAL_TYPE_ICONS, QUALITY_OPTIONS } from "@/api/editPlans"
import type { MediaAsset } from "@/api/templateEditor"
import { MATERIAL_TYPE_LABELS, MATERIAL_TYPE_ICONS, QUALITY_OPTIONS } from "@/api/templateEditor"
/* ──────────── 类型 ──────────── */
@@ -20,8 +20,8 @@ import {
getTemplateCategories,
MODE_LABELS,
} from "@/api/editingPlanner"
import type { MediaAsset, TransitionEffect, TitleConfig } from "@/api/editPlans"
import { getMediaAssets, getEditPlan, getEditPlanClips } from "@/api/editPlans"
import type { MediaAsset, TransitionEffect, TitleConfig } from "@/api/templateEditor"
import { getMediaAssets, getEditPlan, getEditPlanClips } from "@/api/templateEditor"
import { useUndoRedo } from "./hooks/useUndoRedo"
import type {
ClipData,
+1 -1
View File
@@ -6,7 +6,7 @@ import React, { useRef, useState, useCallback } from "react"
import { useNavigate } from "react-router-dom"
import type { TemplateMode } from "@/api/editingPlanner"
import type { ClipData, ClipType } from "../types"
import { TRANSITION_OPTIONS } from "@/api/editPlans"
import { TRANSITION_OPTIONS } from "@/api/templateEditor"
import type { AssetItem } from "@/api/assets"
interface SubtitleSettings {
@@ -4,8 +4,8 @@
*/
import React from "react"
import { CloseOutlined, InboxOutlined } from "@ant-design/icons"
import type { EditPlanGeneration } from "@/api/editPlans"
import { PLAN_STATUS_LABELS } from "@/api/editPlans"
import type { EditPlanGeneration } from "@/api/templateEditor"
import { PLAN_STATUS_LABELS } from "@/api/templateEditor"
interface GenerationHistoryModalProps {
open: boolean
@@ -7,7 +7,7 @@ import React, { useCallback } from "react"
import { Drawer } from "antd"
import type { IntroOutroConfig, IntroOutroItem, IntroOutroKind, TransitionType } from "../types"
import { DEFAULT_INTRO_OUTRO } from "../types"
import { TRANSITION_OPTIONS } from "@/api/editPlans"
import { TRANSITION_OPTIONS } from "@/api/templateEditor"
/* ──────────── 常量 ──────────── */
+1 -1
View File
@@ -5,7 +5,7 @@
import React, { useState } from "react"
import type { EditingTemplate } from "@/api/editingPlanner"
import { MODE_LABELS } from "@/api/editingPlanner"
import type { MediaAsset } from "@/api/editPlans"
import type { MediaAsset } from "@/api/templateEditor"
import AssetSelector from "@/components/AssetSelector/AssetSelector"
interface MediaPanelProps {
+1 -1
View File
@@ -5,7 +5,7 @@
*/
import React from "react"
import type { ClipData, ClipType } from "../types"
import type { TitleConfig } from "@/api/editPlans"
import type { TitleConfig } from "@/api/templateEditor"
import type { CoverConfig } from "../types"
interface SubtitleSettings {
+1 -1
View File
@@ -10,7 +10,7 @@
*/
import React, { useState, useRef, useCallback, useEffect, useLayoutEffect, useMemo } from "react"
import type { ClipData, ClipType, TrimConfig } from "../types"
import { TRANSITION_OPTIONS } from "@/api/editPlans"
import { TRANSITION_OPTIONS } from "@/api/templateEditor"
interface TimelinePanelProps {
clips: ClipData[]
@@ -5,7 +5,7 @@
*/
import React, { useCallback } from "react"
import { Drawer, Slider } from "antd"
import { TRANSITION_OPTIONS } from "@/api/editPlans"
import { TRANSITION_OPTIONS } from "@/api/templateEditor"
import type { TransitionConfig, TransitionType } from "../types"
import { DEFAULT_TRANSITION } from "../types"
@@ -18,7 +18,7 @@ import type {
CreateEditPlanClipRequest,
UpdateEditPlanClipRequest,
ClipReorderItem,
} from "@/api/editPlans"
} from "@/api/templateEditor"
import {
getEditPlanClips,
createEditPlanClip,
@@ -27,7 +27,7 @@ import {
reorderEditPlanClips,
batchDeleteEditPlanClips,
createClipsFromAssets,
} from "@/api/editPlans"
} from "@/api/templateEditor"
import { useUndoRedo } from "./useUndoRedo"
const QUERY_KEY = "editPlanClips"
+3 -3
View File
@@ -30,8 +30,8 @@ import {
updateEditPlan,
getGenerationTaskResults,
getGenerationStatus,
} from "@/api/editPlans"
import type { GeneratedVideo, EditPlanConfig, TitleConfig } from "@/api/editPlans"
} from "@/api/templateEditor"
import type { GeneratedVideo, EditPlanConfig, TitleConfig } from "@/api/templateEditor"
import type { CoverConfig } from "../editing-planner/types"
import { getEditingTemplates } from "@/api/editingPlanner"
import { getTitles } from "@/api/titles"
@@ -44,7 +44,7 @@ import { synthesizeSpeech, getTTSJobStatus, saveTtsToLibrary } from "@/api/tts"
import { getTags, createTag } from "@/api/tags"
import { useCloneProgress } from "@/hooks/useCloneProgress"
import { useSearchParams, useNavigate } from "react-router-dom"
import { getEditPlan } from "@/api/editPlans"
import { getEditPlan } from "@/api/templateEditor"
import "./generate.css"
const { Text } = Typography
+1 -1
View File
@@ -23,7 +23,7 @@ import {
copyEditPlan,
getMediaAssets,
getMediaAsset,
} from "@/api/editPlans"
} from "@/api/templateEditor"
const mockGet = vi.fn()
const mockPost = vi.fn()
@@ -2,7 +2,7 @@ import React from "react"
import { describe, it, expect, vi } from "vitest"
import { render, screen } from "@testing-library/react"
import AssetSelector from "@/components/AssetSelector/AssetSelector"
import type { MediaAsset } from "@/api/editPlans"
import type { MediaAsset } from "@/api/templateEditor"
vi.mock("@/components/ui", () => ({
Input: ({ placeholder }: any) => <input placeholder={placeholder} />,
@@ -146,7 +146,7 @@ vi.mock("@/api/editingPlanner", () => ({
MODE_LABELS: { pip: "画中画", intro_outro: "片头片尾", watermark: "水印" },
}))
vi.mock("@/api/editPlans", () => ({
vi.mock("@/api/templateEditor", () => ({
getMediaAssets: vi.fn().mockResolvedValue({ items: [] }),
getEditPlanGenerations: vi.fn().mockResolvedValue({ items: [] }),
generateCover: vi.fn().mockResolvedValue({}),
@@ -213,7 +213,7 @@ vi.mock("@/api/titles", () => ({
getTitles: vi.fn().mockResolvedValue({ items: [] }),
}))
vi.mock("@/api/editPlans", () => ({
vi.mock("@/api/templateEditor", () => ({
createEditPlan: vi.fn().mockResolvedValue({ id: "test-plan" }),
generateEditPlan: vi.fn().mockResolvedValue({ task_id: "test-task" }),
updateEditPlan: vi.fn().mockResolvedValue({}),
@@ -32,7 +32,7 @@ vi.mock("antd", () => ({
},
}))
vi.mock("@/api/editPlans", () => ({
vi.mock("@/api/templateEditor", () => ({
getEditPlanClips: vi.fn().mockResolvedValue({ items: [], total: 0 }),
createEditPlanClip: vi.fn().mockResolvedValue({}),
updateEditPlanClip: vi.fn().mockResolvedValue({}),