9732cc51ee
CI/CD Pipeline / Check if frontend-only change (push) Has been cancelled
CI/CD Pipeline / Validate - Code Quality (push) Has been cancelled
CI/CD Pipeline / Validate - Type Check (mypy) (push) Has been cancelled
CI/CD Pipeline / Validate - Migration (alembic) (push) Has been cancelled
CI/CD Pipeline / Unit Tests (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Lint (push) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (push) Has been cancelled
CI/CD Pipeline / PR Build API Image (push) Has been cancelled
CI/CD Pipeline / PR Build Web Image (push) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (push) Has been cancelled
CI/CD Pipeline / Build Staging API Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Web Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
CI/CD Pipeline / Build Production API Image (push) Has been cancelled
CI/CD Pipeline / Build Production Web Image (push) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Production (push) Has been cancelled
CI/CD Pipeline / Production Browser E2E (push) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (push) Has been cancelled
CI/CD Pipeline / Canary Release to Production (push) Has been cancelled
CI/CD Pipeline / CI Gate (push) Has been cancelled
111 lines
4.0 KiB
TypeScript
Executable File
111 lines
4.0 KiB
TypeScript
Executable File
import { useEffect } from "react"
|
|
import type { CoverConfig } from "../../../editing-planner/types"
|
|
import type { TitleSettings } from "../../types"
|
|
import type { TitleConfig } from "@/api/template-editor"
|
|
import { getEditPlan } from "@/api/template-editor"
|
|
|
|
interface UsePlanConfigLoaderOptions {
|
|
editPlanId: string | null
|
|
planConfigStr: string | null
|
|
setTitleSettings: (settings: TitleSettings | ((prev: TitleSettings) => TitleSettings)) => void
|
|
setCoverSettings: (settings: CoverConfig | ((prev: CoverConfig) => CoverConfig)) => void
|
|
setSelectedMaterials: (ids: string[]) => void
|
|
}
|
|
|
|
/**
|
|
* 从 URL 参数或编辑计划 ID 加载表单配置
|
|
*/
|
|
export function usePlanConfigLoader({
|
|
editPlanId,
|
|
planConfigStr,
|
|
setTitleSettings,
|
|
setCoverSettings,
|
|
setSelectedMaterials,
|
|
}: UsePlanConfigLoaderOptions) {
|
|
/** 解析 plan_config 并自动填充表单 */
|
|
useEffect(() => {
|
|
if (!planConfigStr) return
|
|
try {
|
|
const config = JSON.parse(planConfigStr) as {
|
|
title_config?: {
|
|
content?: string
|
|
ai_auto_select?: boolean
|
|
position?: string
|
|
font_preset?: string
|
|
font_size?: number
|
|
font_color?: string
|
|
}
|
|
subtitle_config?: { enabled?: boolean }
|
|
bgm_config?: { enabled?: boolean; music_id?: string }
|
|
mode?: string
|
|
total_duration?: number
|
|
segments?: Array<{ media_asset_id?: string; material_type?: string }>
|
|
}
|
|
|
|
if (config.title_config) {
|
|
const tc = config.title_config as TitleConfig
|
|
setTitleSettings((prev: TitleSettings) => ({
|
|
...prev,
|
|
title: tc.content || "",
|
|
aiAutoSelect: tc.ai_auto_select || false,
|
|
position: tc.position || prev.position,
|
|
font: tc.font_preset || prev.font,
|
|
size: tc.font_size || prev.size,
|
|
color: tc.font_color || prev.color,
|
|
}))
|
|
}
|
|
if (config.segments && config.segments.length > 0) {
|
|
const assetIds = config.segments
|
|
.map((s) => s.media_asset_id)
|
|
.filter((id): id is string => !!id)
|
|
if (assetIds.length > 0) {
|
|
setSelectedMaterials(assetIds)
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.warn("解析 plan_config 失败:", err)
|
|
}
|
|
}, [planConfigStr, setTitleSettings, setSelectedMaterials])
|
|
|
|
/** 如果没有 plan_config,尝试通过 edit_plan_id 从后端拉取配置 */
|
|
useEffect(() => {
|
|
if (!editPlanId || planConfigStr) return
|
|
const loadPlanConfig = async () => {
|
|
try {
|
|
const plan = await getEditPlan(editPlanId)
|
|
if (plan.name) setTitleSettings((prev: TitleSettings) => ({ ...prev, title: plan.name }))
|
|
const cfg = plan.config
|
|
if (cfg?.title_config) {
|
|
setTitleSettings((prev: TitleSettings) => ({
|
|
...prev,
|
|
aiAutoSelect: cfg.title_config!.ai_auto_select,
|
|
title: cfg.title_config!.content || prev.title,
|
|
position: cfg.title_config!.position || prev.position,
|
|
font: cfg.title_config!.font_preset || prev.font,
|
|
size: cfg.title_config!.font_size || prev.size,
|
|
color: cfg.title_config!.font_color || prev.color,
|
|
}))
|
|
}
|
|
if (cfg?.cover_config) {
|
|
const cc = cfg.cover_config as CoverConfig
|
|
setCoverSettings((prev: CoverConfig) => ({
|
|
...prev,
|
|
enabled: cc.enabled ?? prev.enabled,
|
|
mode: cc.mode || prev.mode,
|
|
frame_time: cc.frame_time ?? prev.frame_time,
|
|
upload_url: cc.upload_url || prev.upload_url,
|
|
ai_suggested_time: cc.ai_suggested_time ?? prev.ai_suggested_time,
|
|
thumbnail_url: cc.thumbnail_url || prev.thumbnail_url,
|
|
}))
|
|
}
|
|
if (cfg?.asset_ids) {
|
|
setSelectedMaterials(cfg.asset_ids.filter((v): v is string => typeof v === "string"))
|
|
}
|
|
} catch (err) {
|
|
console.warn("加载模板草稿配置失败:", err)
|
|
}
|
|
}
|
|
loadPlanConfig()
|
|
}, [editPlanId, planConfigStr, setTitleSettings, setCoverSettings, setSelectedMaterials])
|
|
}
|