@@ -1,179 +0,0 @@
|
||||
import { useState, useCallback } from "react"
|
||||
import { message } from "antd"
|
||||
import {
|
||||
createEditingTemplate,
|
||||
updateEditingTemplate,
|
||||
type SaveTemplatePayload,
|
||||
type TemplateMode,
|
||||
} from "@/api/editing-planner"
|
||||
import type {
|
||||
ClipData,
|
||||
WatermarkConfig,
|
||||
IntroOutroConfig,
|
||||
PipConfig,
|
||||
FilterConfig,
|
||||
ChromaKeyConfig,
|
||||
StickerConfig,
|
||||
} from "../../types"
|
||||
import type { SubtitleStyleConfig } from "../../types/subtitle"
|
||||
import type { TitleConfig } from "@/api/template-editor"
|
||||
import type { BgmMixConfig } from "@/api/bgm"
|
||||
|
||||
interface UseTemplateSaveOptions {
|
||||
currentMode: TemplateMode
|
||||
clips: ClipData[]
|
||||
totalDuration: number
|
||||
titleConfig: TitleConfig
|
||||
subtitleSettings: SubtitleStyleConfig
|
||||
bgmSettings: BgmMixConfig
|
||||
watermarkSettings: WatermarkConfig
|
||||
introOutroSettings: IntroOutroConfig
|
||||
pipSettings: PipConfig
|
||||
filterSettings: FilterConfig
|
||||
chromaKeySettings: ChromaKeyConfig
|
||||
stickerSettings: StickerConfig
|
||||
loadedTemplateId: string | null
|
||||
loadTemplates: () => Promise<void>
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板保存(创建/更新)
|
||||
*/
|
||||
export function useTemplateSave(options: UseTemplateSaveOptions) {
|
||||
const {
|
||||
currentMode,
|
||||
clips,
|
||||
totalDuration,
|
||||
titleConfig,
|
||||
subtitleSettings,
|
||||
bgmSettings,
|
||||
watermarkSettings,
|
||||
introOutroSettings,
|
||||
pipSettings,
|
||||
filterSettings,
|
||||
chromaKeySettings,
|
||||
stickerSettings,
|
||||
loadedTemplateId,
|
||||
loadTemplates,
|
||||
} = options
|
||||
|
||||
const [saveModalOpen, setSaveModalOpen] = useState(false)
|
||||
const [draftName, setDraftName] = useState("")
|
||||
const [draftCategory, setDraftCategory] = useState("")
|
||||
const [draftTags, setDraftTags] = useState("")
|
||||
const [saveLoading, setSaveLoading] = useState(false)
|
||||
|
||||
const handleOpenSaveModal = useCallback(() => {
|
||||
setSaveModalOpen(true)
|
||||
}, [])
|
||||
|
||||
const handleSave = useCallback(async () => {
|
||||
if (!draftName.trim()) {
|
||||
message.warning("请输入模板名称")
|
||||
return
|
||||
}
|
||||
setSaveLoading(true)
|
||||
try {
|
||||
const payload: SaveTemplatePayload = {
|
||||
name: draftName,
|
||||
mode: currentMode,
|
||||
category: draftCategory,
|
||||
tags: draftTags
|
||||
.split(",")
|
||||
.map((t) => t.trim())
|
||||
.filter(Boolean),
|
||||
title_config: titleConfig,
|
||||
subtitle_config: {
|
||||
enabled: subtitleSettings.enabled,
|
||||
position: subtitleSettings.position,
|
||||
font: subtitleSettings.font,
|
||||
color: subtitleSettings.fontColor,
|
||||
size: subtitleSettings.fontSize,
|
||||
animation: subtitleSettings.animation,
|
||||
},
|
||||
bgm_config: {
|
||||
enabled: bgmSettings.enabled,
|
||||
music_id: bgmSettings.music_id,
|
||||
},
|
||||
estimated_duration: totalDuration,
|
||||
segments: clips.map((c, i) => ({
|
||||
segment_order: i,
|
||||
duration_min: c.duration,
|
||||
duration_max: c.duration,
|
||||
material_type: c.type === "voice" ? "voiceover" : "video",
|
||||
transition: c.transition
|
||||
? { type: c.transition.type, duration: c.transition.duration }
|
||||
: undefined,
|
||||
playback_speed: c.speed ? c.speed.rate : undefined,
|
||||
tts_config: c.tts_config
|
||||
? {
|
||||
mode: c.tts_config.mode,
|
||||
text: c.tts_config.text,
|
||||
voice_id: c.tts_config.voice_id,
|
||||
speed: c.tts_config.speed,
|
||||
pitch: c.tts_config.pitch,
|
||||
volume: c.tts_config.volume,
|
||||
subtitle_sync: c.tts_config.subtitle_sync,
|
||||
}
|
||||
: undefined,
|
||||
trim_config: c.trim_config
|
||||
? {
|
||||
start_time: c.trim_config.start_time,
|
||||
end_time: c.trim_config.end_time,
|
||||
}
|
||||
: undefined,
|
||||
})),
|
||||
watermark_config: { ...watermarkSettings },
|
||||
intro_outro_config: { ...introOutroSettings },
|
||||
pip_config: { ...pipSettings },
|
||||
filter_config: { ...filterSettings },
|
||||
green_screen_config: { ...chromaKeySettings },
|
||||
sticker_config: { ...stickerSettings },
|
||||
}
|
||||
if (loadedTemplateId) {
|
||||
await updateEditingTemplate(loadedTemplateId, payload)
|
||||
} else {
|
||||
await createEditingTemplate(payload)
|
||||
}
|
||||
message.success(loadedTemplateId ? "模板保存成功" : "模板创建成功")
|
||||
setSaveModalOpen(false)
|
||||
loadTemplates()
|
||||
} catch {
|
||||
message.error("保存失败")
|
||||
} finally {
|
||||
setSaveLoading(false)
|
||||
}
|
||||
}, [
|
||||
draftName,
|
||||
draftCategory,
|
||||
draftTags,
|
||||
currentMode,
|
||||
clips,
|
||||
totalDuration,
|
||||
titleConfig,
|
||||
subtitleSettings,
|
||||
bgmSettings,
|
||||
watermarkSettings,
|
||||
introOutroSettings,
|
||||
pipSettings,
|
||||
filterSettings,
|
||||
chromaKeySettings,
|
||||
stickerSettings,
|
||||
loadedTemplateId,
|
||||
loadTemplates,
|
||||
])
|
||||
|
||||
return {
|
||||
saveModalOpen,
|
||||
setSaveModalOpen,
|
||||
draftName,
|
||||
setDraftName,
|
||||
draftCategory,
|
||||
setDraftCategory,
|
||||
draftTags,
|
||||
setDraftTags,
|
||||
saveLoading,
|
||||
handleOpenSaveModal,
|
||||
handleSave,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user