feat: 编辑器加载计划时优先从后端clips表还原片段
CI/CD Pipeline / Frontend Lint (push) Failing after 34s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 35s
CI/CD Pipeline / Unit Tests (push) Successful in 1m48s
CI/CD Pipeline / Integration Tests (push) Successful in 1m26s
CI Build & Deploy Pipeline / Production Browser E2E (push) Failing after 1492h21m41s
CI Build & Deploy Pipeline / Deploy Production (push) Failing after 1492h21m41s
CI Build & Deploy Pipeline / Staging E2E Tests (push) Failing after 1492h21m42s
CI Build & Deploy Pipeline / Build Production Worker Image (push) Failing after 1492h21m42s
CI Build & Deploy Pipeline / Build Production API Image (push) Failing after 1492h21m43s
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Failing after 1492h21m44s
CI Build & Deploy Pipeline / Build Staging API Image (push) Failing after 1492h21m45s
CI Build & Deploy Pipeline / Build Staging Worker Image (push) Failing after 1492h21m44s
CI Build & Deploy Pipeline / Staging API Integration Tests (push) Failing after 1492h53m29s
CI Build & Deploy Pipeline / Build Production Web Image (push) Failing after 1492h53m31s
CI Build & Deploy Pipeline / Build Staging Web Image (push) Failing after 1492h53m33s

- 加载计划时并行请求 clips 列表
- 优先从后端 clips 表还原片段(含 config.tts_config / trim_config)
- 无 clips 数据时从 config.segments 兜底(老数据兼容)
- 形成完整闭环:编辑→同步→生成→重新加载
This commit is contained in:
2026-07-16 11:08:04 +08:00
parent da07dbd1de
commit 33ccb16bd3
@@ -417,8 +417,16 @@ const EditingPlanner: React.FC = () => {
*/
useEffect(() => {
if (!loadedPlanId) return;
getEditPlan(loadedPlanId)
.then((plan) => {
// 并行加载计划基本信息 + 片段列表
Promise.all([
getEditPlan(loadedPlanId),
getEditPlanClips(loadedPlanId, { limit: 500 }).catch(() => ({
items: [],
total: 0,
})),
])
.then(([plan, clipsRes]) => {
// 设置关联的模板(触发模板加载 effect)
setLoadedTemplateId(plan.template_id);
@@ -458,8 +466,41 @@ const EditingPlanner: React.FC = () => {
}));
}
// 还原片段 — 延迟设置,等模板加载 effect 先执行 resetClips
if (cfg.segments && cfg.segments.length > 0) {
// 还原片段:优先从后端 clips 表,其次从 config.segments 兜底
const backendClips = clipsRes?.items || [];
if (backendClips.length > 0) {
// 从后端 clips 表还原
const sorted = [...backendClips].sort(
(a, b) => a.order - b.order,
);
const mapped: ClipData[] = sorted.map((clip) => ({
id: clip.id,
template_segment_id:
(clip.config?.template_segment_id as string) || "",
type: (clip.clip_type === "voiceover"
? "voice"
: "pip") as ClipType,
duration: clip.duration || 3,
startOffset: 0,
script_text: clip.text_content || "",
order: clip.order,
media_asset_id: clip.asset_id || undefined,
transition:
clip.transition_effect && clip.transition_effect !== "none"
? {
type: clip.transition_effect as TransitionEffect["type"],
duration: clip.transition_duration || 0.3,
}
: undefined,
speed: clip.playback_speed
? { rate: clip.playback_speed, pitchCorrection: true }
: undefined,
tts_config: (clip.config?.tts_config as TtsConfig) || undefined,
trim_config: (clip.config?.trim_config as TrimConfig) || undefined,
}));
setTimeout(() => resetClips(mapped), 100);
} else if (cfg.segments && cfg.segments.length > 0) {
// 兜底:从 config.segments 还原(老数据兼容)
const mapped: ClipData[] = cfg.segments.map((seg, idx) => ({
id: `seg-${idx}`,
template_segment_id: `seg-${idx}`,