# 世界草稿自动资产可见性修复说明 2026-04-20 更新时间:`2026-04-20` ## 1. 问题现象 在世界草稿生成完成后,用户反馈: 1. 草稿里看不到角色主形象 2. 场景里看不到每一幕的背景图 这类反馈容易被误判成“自动资产没有生成”,但实际排查后发现,问题主要集中在**结果页展示链路**,同时叠加了一个**fallback 资源不可预览**的问题。 ## 2. 链路排查结论 本轮检查后确认: 1. 服务端自动资产服务会把角色主形象写回 `draftProfile.playableNpcs[].imageSrc / generatedVisualAssetId` 2. 服务端自动资产服务会把幕背景图写回 `draftProfile.sceneChapters[].acts[].backgroundImageSrc / backgroundAssetId` 3. `agent draft -> result profile` 的适配层也会保留这些字段 真正的问题出在后续两个环节。 ## 3. 根因 ### 3.1 结果页可扮演角色卡优先用了运行时预览 结果页 `CustomWorldEntityCatalog` 的可扮演角色卡,之前优先显示: 1. `previewCharacter` 2. 再回退到 `role.imageSrc` 这会导致: 1. 草稿里已经有真实生成主图 2. 但界面仍优先渲染模板/运行时预览角色 3. 用户视觉上看不到最新生成主形象 ### 3.2 场景页没有把多幕背景图真正展示出来 结果页 `场景` Tab 之前只展示: 1. 开局场景 2. 地点卡 但没有把: `sceneChapterBlueprints[].acts[].backgroundImageSrc` 按可见结构渲染到结果页中。 因此即使后端已经生成并回写每一幕背景图,用户仍然只能看到“场景主图/地点图”,看不到“每一幕的图”。 ### 3.3 fallback 自动资产写回的是 `.txt` 在没有 DashScope 图像能力时,`CustomWorldAgentAutoAssetService` 的 fallback 生成器之前会写: 1. 角色主形象:`master.txt` 2. 幕背景图:`scene.txt` 这虽然保证了字段被回写,但前端无法把 `.txt` 当图片展示,于是会进一步加重“好像没生成”的感知。 ### 3.4 Agent 结果页入口优先读取 legacyResultProfile,遮蔽了最新资产字段 世界草稿结果页不是直接读取当前 `draftProfile`,而是先经过: 1. `buildCustomWorldProfileFromAgentDraft` 2. `normalizeCustomWorldProfileRecord` 如果 `draftProfile.legacyResultProfile` 存在,旧逻辑会直接优先返回这份历史编译结果。 但自动资产服务在 Phase3/Phase4 后续补齐时,更新的是当前 `draftProfile` 中的: 1. `playableNpcs[].imageSrc / generatedVisualAssetId` 2. `storyNpcs[].imageSrc / generatedVisualAssetId` 3. `landmarks[].imageSrc` 4. `sceneChapters[].acts[].backgroundImageSrc / backgroundAssetId` 这会导致: 1. 服务端真实已经生成并回写了最新角色主图和分幕图 2. 结果页入口却仍然取到一份更早的 `legacyResultProfile` 3. 页面看到的是“旧草稿快照”,不是“当前带资产的草稿结果” 因此用户会表现为“完全看不到这轮刚生成出来的图片”。 ## 4. 修复策略 ### 4.1 结果页角色卡优先显示真实生成主图 在 `src/components/CustomWorldEntityCatalog.tsx` 中调整逻辑: 1. 若 `role.imageSrc` 已存在,则优先显示该图片 2. 只有在缺失真实主图时,才回退到运行时角色预览 这样可扮演角色卡能直接展示当前草稿回写的角色主形象。 ### 4.2 场景列表改为只展示场景卡,章节内容留在二级页 结合后续体验反馈,本轮又进一步收口了结果页结构: 1. `结果页 -> 场景列表` 不再直接展开章节与分幕内容 2. 场景列表卡片只负责展示: - 场景名 - 场景摘要 - 场景图 3. 场景卡图片优先取该场景章节的首幕 `backgroundImageSrc` 4. 若首幕图缺失,再回退到场景主图 / 地标图 5. 章节标题、幕标题、幕目标等信息只在点击场景后的二级编辑页中查看 这样结果页列表保持清爽,但用户仍然能在列表里直接看到当前场景已生成的图片。 ### 4.3 fallback 改为可显示 PNG 在 `server-node/src/services/customWorldAgentAutoAssetService.ts` 中调整 fallback: 1. 不再写 `master.txt / scene.txt` 2. 改为写合法可显示的占位 `png` 3. prompt 信息单独写进 `manifest.json` 4. 角色主形象 fallback PNG 统一输出为 `1:1` 这样即使当前环境没有真实图像生成能力,草稿层也仍然会回写“前端能直接显示的图片资源”。 ### 4.4 结果页读取 legacy profile 时强制合并当前草稿的最新资产字段 在 `src/services/customWorldAgentDraftResult.ts` 中补上合并逻辑: 1. 若存在 `legacyResultProfile`,继续保留它的完整运行时字段 2. 但会把当前 `draftProfile` 里最新回写的角色主图、地标图、分幕图再覆盖回结果页 profile 3. 这样结果页既不会丢失旧 runtime profile 的完整结构,也不会再被旧快照遮蔽最新图片资产 这一层修的是结果页真实入口,而不是仅修展示组件。 ## 5. 影响范围 本次修复涉及: 1. `src/components/CustomWorldEntityCatalog.tsx` 2. `src/components/CustomWorldResultView.test.tsx` 3. `src/services/customWorldAgentDraftResult.test.ts` 4. `server-node/src/services/customWorldAgentAutoAssetService.ts` 5. `server-node/src/services/customWorldAgentAutoAssetService.test.ts` 6. `docs/technical/CUSTOM_WORLD_AUTO_ASSET_VISIBILITY_FIX_2026-04-20.md` 7. 历史 saved profile 资产同步脚本 / 数据修复动作 ## 6. 验收标准 修复后需要满足: 1. 世界草稿结果页的可扮演角色卡能直接看到生成主形象 2. 世界草稿结果页的场景列表能直接看到场景图片,且优先展示首幕背景图 3. 场景章节与分幕内容只在场景二级页中展示 3. `agent draft -> result profile` 不会丢失角色主图与幕背景字段 4. fallback 环境下回写的仍是前端可显示图片,而不是文本文件 5. 角色主形象 fallback PNG 尺寸必须满足 `1:1` 6. 即使存在 `legacyResultProfile`,结果页也必须展示当前草稿最新同步的角色主图与幕背景图 ## 6.1 历史保存档案补充结论 本轮在真实 PostgreSQL 数据中又确认了一类历史问题: 1. `agent session` 中的草稿资产字段可能已经补齐 2. 但较早时刻自动保存过的 `custom_world_profiles.payload_json` 仍停留在旧路径 3. 用户如果从作品库打开的是 saved profile,就会继续看到旧图或空图 因此这次修复除了改默认生成与展示逻辑,还需要对受影响的历史 saved profile 做一次同步刷新。 ## 7. 后续建议 后续继续迭代这条链路时,建议保持: 1. “资产已生成”必须和“用户已看见”同时验证,不能只验证字段回写 2. 结果页与草稿工作区都要把多幕背景视为正式资产,不要只停留在编辑弹层里 3. 所有 fallback 资源都应保持为 UI 可直接消费的媒体格式