fix(core): 删脚本分镜联动删故事板帧 + 演员库自取 person + 分镜编辑行抽组件

- views.py: delete-script-segment 同步删对应 StoryboardFrame(原 SET_NULL 留孤儿帧致故事板仍显示已删的场),并重排剩余帧 sort_order
- actor-library.tsx: 演员库改自取 person 资产(全局 assets 已懒加载不再全量预载,否则演员库全空),保存后 reload 即时入列
- pipeline.tsx: 抽出 EditableShotField 组件、PromptBox 参数化
- 附 perf-report 产物

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
zyc
2026-06-17 19:18:15 +08:00
co-authored by Claude Opus 4.8
parent f1bc5933ef
commit c62abed536
5 changed files with 174 additions and 182 deletions
+11
View File
@@ -43,6 +43,8 @@ from .models import (
ProjectStage,
ScriptSegment,
ScriptVersion,
StoryboardFrame,
StoryboardVersion,
SubtitleTrack,
Timeline,
TimelineClip,
@@ -429,6 +431,15 @@ class ProjectViewSet(TeamScopedViewSetMixin, ModelViewSet):
script = segment.script_version
if script.segments.count() <= 1:
return Response({"detail": "至少保留一个分镜"}, status=status.HTTP_400_BAD_REQUEST)
# 删本场脚本时,它对应的故事板分镜帧也一起删 —— frame.script_segment 是 SET_NULL,
# 不主动删会留下孤儿帧,故事板里仍显示这一(已删的)场。各版本受影响的帧统一收口后重排 sort_order。
affected_storyboards = list(StoryboardVersion.objects.filter(frames__script_segment=segment).distinct())
StoryboardFrame.objects.filter(script_segment=segment).delete()
for sb in affected_storyboards:
for index, frame in enumerate(sb.frames.order_by("sort_order")):
if frame.sort_order != index:
frame.sort_order = index
frame.save(update_fields=["sort_order", "updated_at"])
segment.delete()
for index, seg in enumerate(script.segments.order_by("sort_order")):
if seg.sort_order != index: