fix(core): 资产详情大图随数据显示,缩略图已出大图不再卡转圈

- 三视图/立绘大图改为跟数据(url)走,出图完成即显示,不再被在途轮询的
  busy 标志挡住——根治「小缩略图已出、大图一直转圈」
- 一并带上工作区其余改动(script_agent / services / tests / ai-tools / actor-library / App)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
zyc
2026-06-18 10:57:02 +08:00
co-authored by Claude Opus 4.8
parent fe38d3a512
commit 326c34ecd1
7 changed files with 200 additions and 47 deletions
+41
View File
@@ -80,6 +80,47 @@ class NormalizeDraftTests(SimpleTestCase):
self.assertEqual(draft["segments"][0]["narration"], "一句完整口播")
self.assertEqual(draft["segments"][0]["dialogue"], []) # 字符串不进结构化对白
def test_empty_segments_skeleton_yields_to_richer_scenes(self):
"""真实回归(全空根因):模型把内容放 scenes/voiceover/visual,却另给一个**空 segments 骨架**。
必须挑内容最丰富的数组(scenes),而不是见 segments 是 list 就用→落 4 个空镜。"""
raw = json.dumps({
"scenes": [
{"sceneIndex": 1, "sceneTitle": "通勤", "voiceover": "手机一卡效率掉线", "visual": "地铁口拿出亮银色机身"},
{"sceneIndex": 2, "sceneTitle": "办公", "voiceover": "A19多任务很跟手", "visual": "办公桌俯拍切换应用"},
],
"segments": [{"index": 0, "role": "钩子", "narration": "", "visual": ""}, {"index": 1, "role": "痛点", "narration": "", "visual": ""}],
"total_duration": 30,
}, ensure_ascii=False)
draft = normalize_draft(raw, aspect_ratio="9:16", total_duration=30)
self.assertEqual(draft["segments"][0]["narration"], "手机一卡效率掉线")
self.assertEqual(draft["segments"][0]["visual"], "地铁口拿出亮银色机身")
def test_script_key_with_visual_object_is_flattened(self):
"""真实回归:数组键叫 script、visual 写成 {setting,camera,key_shots} 对象。
必须认出 script 数组并把 visual 对象拍平成一句,而非留空。"""
raw = json.dumps({
"script": [
{"scene_id": 1, "scene_title": "通勤", "voiceover": "选手机看重流畅好看",
"visual": {"setting": "地铁口", "camera": "竖屏手持跟拍", "key_shots": ["拿出亮银色机身"]}},
],
"total_duration": 15,
}, ensure_ascii=False)
draft = normalize_draft(raw, aspect_ratio="9:16", total_duration=15)
seg = draft["segments"][0]
self.assertEqual(seg["narration"], "选手机看重流畅好看")
self.assertIn("地铁口", seg["visual"])
self.assertIn("竖屏手持跟拍", seg["visual"])
def test_audio_field_fills_narration(self):
"""真实回归:shots 用 audio 放口播(GPT 变体),旁白曾因 audio 不在词典而留空。"""
raw = json.dumps({
"shots": [{"scene": 1, "visual": "咖啡厅办公把玩机身", "audio": "这款亮银色是我的高光决定"}],
"total_duration": 15,
}, ensure_ascii=False)
draft = normalize_draft(raw, aspect_ratio="9:16", total_duration=15)
self.assertEqual(draft["segments"][0]["narration"], "这款亮银色是我的高光决定")
self.assertEqual(draft["segments"][0]["visual"], "咖啡厅办公把玩机身")
def test_canonical_flat_schema_still_works(self):
"""契约内的扁平 schema(segments/narration/visual)不受兼容改动影响。"""
raw = json.dumps({