# 大鱼吃小鱼结果页主图占位预览修复说明 2026-04-23
日期:`2026-04-23`
## 1. 问题现象
在“深海谜境 / 大鱼吃小鱼”结果页中,等级卡片会显示:
1. `主图 已生成`
2. 操作后会出现“已应用主图”感知
但实际结果页看不到角色主图,卡片里只有一张蓝色底图。
## 2. 排查结论
本次沿着“结果页展示 -> API action -> SpacetimeDB procedure -> 资产路径”全链检查后确认:
1. 前端确实成功触发了 `big_fish_generate_level_main_image`
2. SpacetimeDB 侧确实把资产槽位状态写成了 `ready`
3. 但这条链路没有接真实图像模型,也没有接 OSS 真实资产对象
4. 旧实现只回写一个 `/generated-big-fish/...png` 占位 URL
5. 同时仓库里没有实际把这张占位图写到 `public/generated-big-fish/...`
6. 因此前端读到的是一个“看起来像图片地址、实际上没有真实文件”的路径
7. `
` 加载失败后,卡片底层蓝色渐变背景暴露出来,于是用户只能看到蓝色图块
## 3. 根因拆解
### 3.1 状态成功过早
`generate_big_fish_asset` 当前最小实现只负责:
1. 写 `asset slot`
2. 写 `prompt snapshot`
3. 标记 `status = ready`
它并不代表真实主图已经生成完成。
### 3.2 预览资源未真正落盘
旧实现会构造:
`/generated-big-fish/{asset_kind}/{level_part}/{seed}.png`
但没有同步在 `public/generated-big-fish/...` 写出对应文件。
### 3.3 结果页直接吃裸 `assetUrl`
Big Fish 结果页主图卡之前直接:
1. 取 `slot.assetUrl`
2. 塞进 `
`
一旦文件不存在,就只剩下卡片自己的蓝色渐变背景。
### 3.4 UI 文案误导
旧文案把当前阶段写成:
1. `已生成`
2. `已生成并设为正式资产`
这会让用户自然理解为“真实主图已经出来了”,与当前最小实现不一致。
## 4. 本次修复策略
本轮不直接接真实模型生成,而是先把最小可见闭环补完整。
### 4.1 API action 写出可预览占位图
在 Rust `api-server` 的 Big Fish action 处理中:
1. 复用拼图玩法“写本地可预览占位图”的方式
2. 在调用 `generate_big_fish_asset` 之前,先把 Big Fish 占位图真正写到:
`public/generated-big-fish/...`
3. 保证 SpacetimeDB 里写入的占位 URL 至少对应一个真实可访问文件
### 4.2 结果页改用统一图片渲染组件
Big Fish 结果页主图和背景预览改为:
1. 使用 `ResolvedAssetImage`
2. 统一走现有图片渲染链路
3. 避免后续接 OSS / 旧 generated 路径兼容时再重复返工
### 4.3 状态文案改准
当前还是占位资产阶段,因此把结果页状态文案改为:
1. `占位已生成`
2. `生成并应用占位图`
避免继续把“槽位 ready”误说成“真实主图已完成”。
### 4.4 结果页露出背景预览
除了等级主图卡,本轮顺手把场地背景卡也接上真实预览图渲染,避免出现:
1. 状态显示完成
2. 右侧仍只是一块纯渐变底图
## 5. 修复后的链路语义
修复后 Big Fish 当前资产链路语义明确为:
1. 点击生成
2. `api-server` 先写出本地可访问占位图
3. `spacetime-module` 写正式资产槽位和提示词快照
4. 前端读取 `assetUrl` 并真实渲染预览
也就是说:
1. 当前可以保证“用户看得见”
2. 但仍然不是“真实模型图像生成”
3. 后续真实模型 / OSS worker 接入后,再把占位图链替换成正式资产真相链
## 6. 验收标准
本次修复后需要满足:
1. 结果页等级卡在主图生成后能直接看到真实可加载图片,不再只剩蓝色底图
2. 场地背景生成后右侧卡片能看到真实可加载图片
3. Big Fish 结果页图片渲染统一走现有图片组件,不再直接裸 `
` 吃易失路径
4. 当前 UI 文案不再把占位图误称为真实主图
5. 若本地占位图写盘失败,则 action 不能继续回到“ready 成功”状态
## 7. 后续建议
下一阶段继续补 Big Fish 真实资产链时,建议按下面顺序推进:
1. 先引入 Big Fish `asset_object + asset_entity_binding` 正式槽位设计
2. 再接真实图片 / 动作生成 worker
3. 最后把当前 `/generated-big-fish/...` 本地占位路径迁为兼容层,而不是继续作为真相路径