diff --git a/apps/web/src/pages/editing-planner/EditingPlanner.tsx b/apps/web/src/pages/editing-planner/EditingPlanner.tsx index a1ba02c91..aca676760 100755 --- a/apps/web/src/pages/editing-planner/EditingPlanner.tsx +++ b/apps/web/src/pages/editing-planner/EditingPlanner.tsx @@ -63,19 +63,15 @@ import SaveModal from "./components/SaveModal" import type { SubtitleStyleConfig } from "./types/subtitle" import { DEFAULT_SUBTITLE_STYLE } from "./types/subtitle" import { DEFAULT_BGM_MIX_CONFIG, type BgmMixConfig } from "@/api/bgm" +import { MODE_LIST, FILTER_CATEGORIES } from "./constants" +import { + calculateTotalDuration, + getCurrentTemplate, + getFilteredTemplates, + getSelectedClip, +} from "./utils/selectors" import "./EditingPlanner.css" -/* ──────────── 常量 ──────────── */ - -const MODE_LIST: { key: TemplateMode; label: string; icon: string }[] = [ - { key: "pip", label: "混剪", icon: "🖼️" }, - { key: "voice_over", label: "人物口播", icon: "🎙️" }, - { key: "one_take", label: "一镜到底", icon: "🎥" }, - { key: "voice_pip", label: "口播+混剪", icon: "🎭" }, -] - -const FILTER_CATEGORIES = ["全部", "种草", "知识", "日常", "推荐"] - /* ──────────── 组件 ──────────── */ const EditingPlanner: React.FC = () => { @@ -449,9 +445,9 @@ const EditingPlanner: React.FC = () => { /* ──────────── 计算 ──────────── */ - const currentTemplate = templates.find((t) => t.id === loadedTemplateId) - const totalDuration = clips.reduce((sum, c) => sum + c.duration, 0) - const selectedClip = clips.find((c) => c.id === selectedClipId) || null + const currentTemplate = getCurrentTemplate(templates, loadedTemplateId) + const totalDuration = calculateTotalDuration(clips) + const selectedClip = getSelectedClip(clips, selectedClipId) /* rAF 帧推进 — 播放时平滑更新播放头位置 */ useEffect(() => { @@ -478,11 +474,7 @@ const EditingPlanner: React.FC = () => { } }, [isPlaying, totalDuration]) - const filteredTemplates = templates.filter((t) => { - if (currentFilter !== "全部" && t.category !== currentFilter) return false - if (searchQuery && !t.name.toLowerCase().includes(searchQuery.toLowerCase())) return false - return true - }) + const filteredTemplates = getFilteredTemplates(templates, currentFilter, searchQuery) /* ──────────── 事件 ──────────── */ diff --git a/apps/web/src/pages/editing-planner/constants.ts b/apps/web/src/pages/editing-planner/constants.ts new file mode 100644 index 000000000..bdba18cc4 --- /dev/null +++ b/apps/web/src/pages/editing-planner/constants.ts @@ -0,0 +1,12 @@ +import type { TemplateMode } from "@/api/editing-planner" + +/* ──────────── 常量 ──────────── */ + +export const MODE_LIST: { key: TemplateMode; label: string; icon: string }[] = [ + { key: "pip", label: "混剪", icon: "🖼️" }, + { key: "voice_over", label: "人物口播", icon: "🎙️" }, + { key: "one_take", label: "一镜到底", icon: "🎥" }, + { key: "voice_pip", label: "口播+混剪", icon: "🎭" }, +] + +export const FILTER_CATEGORIES = ["全部", "种草", "知识", "日常", "推荐"] diff --git a/apps/web/src/pages/editing-planner/utils/selectors.ts b/apps/web/src/pages/editing-planner/utils/selectors.ts new file mode 100644 index 000000000..06c72f598 --- /dev/null +++ b/apps/web/src/pages/editing-planner/utils/selectors.ts @@ -0,0 +1,41 @@ +import type { EditingTemplate } from "@/api/editing-planner" +import type { ClipData } from "../types" + +/** + * 计算所有片段的总时长 + */ +export function calculateTotalDuration(clips: ClipData[]): number { + return clips.reduce((sum, c) => sum + c.duration, 0) +} + +/** + * 获取当前选中的模板 + */ +export function getCurrentTemplate( + templates: EditingTemplate[], + loadedTemplateId: string | null, +): EditingTemplate | undefined { + return templates.find((t) => t.id === loadedTemplateId) +} + +/** + * 根据分类和搜索词筛选模板 + */ +export function getFilteredTemplates( + templates: EditingTemplate[], + currentFilter: string, + searchQuery: string, +): EditingTemplate[] { + return templates.filter((t) => { + if (currentFilter !== "全部" && t.category !== currentFilter) return false + if (searchQuery && !t.name.toLowerCase().includes(searchQuery.toLowerCase())) return false + return true + }) +} + +/** + * 获取当前选中的片段 + */ +export function getSelectedClip(clips: ClipData[], selectedClipId: string | null): ClipData | null { + return clips.find((c) => c.id === selectedClipId) || null +} diff --git a/apps/web/src/test/pages/editing-planner/smoke.test.tsx b/apps/web/src/test/pages/editing-planner/smoke.test.tsx old mode 100644 new mode 100755 index 9e3cdbdcc..f4f1f990b --- a/apps/web/src/test/pages/editing-planner/smoke.test.tsx +++ b/apps/web/src/test/pages/editing-planner/smoke.test.tsx @@ -8,6 +8,12 @@ import { describe, it, expect } from "vitest" // 主组件 import "@/pages/editing-planner/EditingPlanner" +// 常量 +import "@/pages/editing-planner/constants" + +// 工具函数 +import "@/pages/editing-planner/utils/selectors" + // 子组件 import "@/pages/editing-planner/components/BgmSelector" import "@/pages/editing-planner/components/ClipPropertiesPanel"