1
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
3. 原“排行”页内容并入“发现”页的子 Tab 中,不再作为一级主 Tab 独立展示。
|
||||
4. 创作页只保留新建创作入口;原创作页作品列表拆到一级“草稿” Tab,替换原“存档” Tab。
|
||||
5. 原“存档”列表结构并入“我的”页面的“玩过”列表弹层,作为每个已玩作品的可继续存档入口。
|
||||
6. 移动端推荐页与底部 Tab 栏参考用户给定样式,使用大画面推荐流、顶部品牌/通知、悬浮胶囊底部导航;保留当前平台已有明暗两套主题色 token。
|
||||
6. 移动端推荐页与底部 Tab 栏参考用户给定样式,使用大画面推荐流、顶部品牌与悬浮胶囊底部导航;右上角不保留通知按钮,账号相关入口统一进入“我的”和账号面板;保留当前平台已有明暗两套主题色 token。
|
||||
|
||||
## 2. 状态映射
|
||||
|
||||
|
||||
@@ -122,6 +122,7 @@
|
||||
## 9. 2026-05-08 创作首页通知入口下线
|
||||
|
||||
- `CreativeAgentHome` 顶栏右上角不再展示“通知与账户”按钮,避免创作首页把通知入口放在首屏高频区域。
|
||||
- 2026-05-12 平台入口页同步移除移动端和桌面端右上角通知铃铛;移动端顶栏只保留品牌,未登录时保留登录按钮,桌面端只保留账号入口。
|
||||
- 账号入口仍保留在侧边栏底部,创作首页顶栏维持左侧菜单、居中品牌的轻量结构。
|
||||
- 当前账号相关入口统一保留在平台首页受保护动作、个人页、存档页与账号弹窗,不再占用全局悬浮层。
|
||||
|
||||
@@ -220,4 +221,12 @@
|
||||
|
||||
---
|
||||
|
||||
## 19. 2026-05-12 登录协议与个人页法律入口
|
||||
|
||||
- 登录弹窗的法律协议确认应挂在短信 / 密码登录提交按钮上方,法律链接只打开独立 `LegalDocumentModal`,不能顺手勾选同意。
|
||||
- 法律弹窗通过 portal 挂到 `body` 时必须显式带 `platform-theme--*` 和高于登录遮罩的层级,否则容易丢主题变量或被登录弹窗遮住。
|
||||
- “我的”页常用功能区固定为 3 列,法律信息区放在设置入口下方;备案号作为外链进入工信部备案站,入口保持轻量,不在页面内展开长文。
|
||||
|
||||
---
|
||||
|
||||
_文档目的:交接给下一个 Agent 时,优先读本文件 + `UI_CODING_STANDARD.md`,再改 `uiAssets.ts` / `App.tsx` / `index.css`。_
|
||||
|
||||
@@ -96,7 +96,7 @@ Match3D 必须形成独立玩法域,后续技术方案至少需要覆盖:
|
||||
2. 创建流程采用入口表单收集关键配置。
|
||||
3. 表单必须在进入结果页前确认:
|
||||
- 题材主题
|
||||
- 3D 素材风格
|
||||
- 2D 素材风格
|
||||
- 难度选项
|
||||
4. `需要消除次数` 与难度 `1~10` 数值不再作为独立输入框展示,由难度选项派生。
|
||||
5. 生成抓大鹅草稿消耗 `20` 光点,生成按钮必须显式展示。
|
||||
@@ -110,7 +110,7 @@ Match3D 必须形成独立玩法域,后续技术方案至少需要覆盖:
|
||||
13. 清空圆形空间中全部物品即胜利。
|
||||
14. 倒计时结束或备选栏满即失败。
|
||||
15. 胜利 / 失败后展示结算界面。
|
||||
16. 入口页的 3D 素材风格选择会进入素材图提示词,并作为结果页手动 Rodin 3D 模型生成的默认提示词依据。
|
||||
16. 入口页的 2D 素材风格选择会进入素材图提示词,并作为后续物品素材新增和重绘的默认提示词依据。
|
||||
17. 点击、入槽、消除、失败、胜利的即时反馈效果由前端先行呈现,后端负责权威确认、状态落库和成绩可信性。
|
||||
|
||||
---
|
||||
@@ -124,7 +124,7 @@ Match3D 必须形成独立玩法域,后续技术方案至少需要覆盖:
|
||||
3. 不做排行榜正式展示。
|
||||
4. 不做道具,但需要预留功能口。
|
||||
5. 不做洗牌、重置、旋转、放大等局内操作。
|
||||
6. 不做多批次真实 3D 模型生成;当前草稿生成只固定产出 `3` 个 GLB 模型并写入 OSS。
|
||||
6. 不做首屏真实 3D 模型生成;当前草稿生成以多视角 2D 物品素材为主,并写入 OSS。
|
||||
7. 不做真实 3D 物理遮挡。
|
||||
8. 不做真实物理碰撞结算。
|
||||
9. 不做必须试玩通关才能发布的门槛。
|
||||
@@ -143,7 +143,7 @@ Match3D 首版参考拼图后期的入口表单收集方式,而不是早期的
|
||||
表单的职责是帮助用户确认可以直接编译 demo 的最小配置:
|
||||
|
||||
1. 题材主题。
|
||||
2. 3D 素材风格。
|
||||
2. 2D 素材风格。
|
||||
3. 游戏难度选项。
|
||||
|
||||
`需要消除次数` 与游戏难度数值仍属于后端会话配置,但不再要求用户手填。当前入口页固定采用以下映射:
|
||||
@@ -152,7 +152,7 @@ Match3D 首版参考拼图后期的入口表单收集方式,而不是早期的
|
||||
轻松 -> 需要消除 8 次,难度 2
|
||||
标准 -> 需要消除 12 次,难度 4
|
||||
进阶 -> 需要消除 16 次,难度 6
|
||||
硬核 -> 需要消除 20 次,难度 8
|
||||
硬核 -> 需要消除 21 次,难度 8
|
||||
```
|
||||
|
||||
## 6.2 必填配置
|
||||
@@ -161,7 +161,7 @@ Match3D 首版参考拼图后期的入口表单收集方式,而不是早期的
|
||||
|
||||
题材决定后续生成或选择物品素材的方向。用户可以自定义主题,例如水果、玩具、食物、符号等。
|
||||
|
||||
当前抓大鹅草稿生成会固定生成 `3` 个题材物品:素材图切割出的独立图片会作为 Rodin 图生 3D 参考图,生成出的 GLB 模型必须转存 OSS,并随作品 profile 的 `generatedItemAssets` 持久化。运行态优先使用这些生成模型;只有模型缺失、加载失败或未进入 3D 渲染模式时,才回退到 25 个默认积木件视觉键。默认素材不使用透明气泡,也不在图案上放文字标识。
|
||||
当前抓大鹅草稿会按难度生成题材物品:素材图切割出的多视角 2D 图片必须转存 OSS,并随作品 profile 的 `generatedItemAssets` 持久化。运行态优先使用这些生成图片;只有图片缺失、读取失败或未进入生成素材模式时,才回退到默认积木件视觉键。默认素材不使用透明气泡,也不在图案上放文字标识。
|
||||
|
||||
可消除物尺寸使用五档相对体积规则:XL 型相对体积为 `1.60~2.30`,L 型为 `1.25~1.60`,M 型为 `1.00`,XS 型为 `0.65~0.85`,S 型为 `0.35~0.50`。单局中 XL / L / M / XS / S 按本局使用的消除物类型数的 `20% / 30% / 30% / 15% / 5%` 分配;非整数配额按最大余数补齐,确保总数等于本局使用类型数量。同一关卡内同一个颜色和造型的物品只能对应一个尺寸档位;可存在同尺寸但不同颜色和造型的物品。后端运行态通过 `radius` 下发权威尺寸,前端只按快照表现。
|
||||
|
||||
@@ -183,19 +183,25 @@ Match3D 首版参考拼图后期的入口表单收集方式,而不是早期的
|
||||
|
||||
首版 demo 中,用户只需凭感觉选择难度;具体难度规则由系统内部解释。后续优化阶段再细化难度曲线、生成算法和遮挡策略。
|
||||
|
||||
### 3D 素材风格
|
||||
### 2D 素材风格
|
||||
|
||||
入口页在题材主题与难度之间展示 `3D素材风格` 横向滑动选择。首批固定选项为:
|
||||
入口页在题材主题与难度之间展示 `2D素材风格` 横向滑动选择。首批固定选项为:
|
||||
|
||||
```text
|
||||
黏土手作 / 低多边形 / 玩具塑料 / 木质雕刻 / 体素积木 / 金属机甲 / 自定义
|
||||
扁平图标 / 赛璐璐卡通 / 像素复古 / 手绘水彩 / 贴纸描边 / 厚涂图标 / 自定义
|
||||
```
|
||||
|
||||
每个内置选项使用 VectorEngine `gpt-image-2-all` 生成的画风参考图展示;参考图保存在 `public/match3d-style-references/`,只作为入口选择的视觉提示,不作为用户上传参考图。选择内置风格时,前端提交 `assetStyleId`、`assetStyleLabel` 与对应 `assetStylePrompt`。选择 `自定义` 时必须弹出独立面板,用户填写描述后才允许应用;自定义描述作为 `assetStylePrompt` 进入后端生成链路。
|
||||
|
||||
## 6.3 参考图片
|
||||
|
||||
抓大鹅入口页不展示参考图片上传。题材表现由题材文本和草稿切割图片链路承接;草稿生成阶段会直接以切割图片作为 Rodin 图生模型参考图生成首批 GLB。结果页 `3D素材` Tab 仍可对单个素材触发重新生成。
|
||||
抓大鹅入口页不展示参考图片上传。题材表现由题材文本和草稿切割图片链路承接;草稿生成阶段会生成多视角 2D 物品素材并写入作品 profile。结果页 `素材配置 > 物品` 继续承接物品素材预览、删除、批量新增和音效配置。
|
||||
|
||||
## 6.4 生成音效开关
|
||||
|
||||
抓大鹅入口页在生成按钮前提供 `生成音效` Toggle,默认关闭。关闭时,草稿生成只保存 `generatedItemAssets[].soundPrompt`,不调用 Vidu 生成点击音效。
|
||||
|
||||
用户打开 Toggle 后,前端在创建会话和执行 `match3d_compile_draft` 时提交 `generateClickSound=true`。后端完成物品名称与 `soundPrompt` 生成后,在图片素材生成阶段为每个生成物品调用 Vidu 生成点击音效,并把结果写入对应 `generatedItemAssets[].clickSound`。音效生成复用通用创作音频接口和资产落点;结果页仍保留单个物品音效的手动补生成入口。
|
||||
|
||||
---
|
||||
|
||||
@@ -222,9 +228,9 @@ Match3D 首版参考拼图后期的入口表单收集方式,而不是早期的
|
||||
|
||||
## 7.3 素材生成边界
|
||||
|
||||
抓大鹅草稿生成链路会生成首批 `3` 个题材物品素材:文本模型生成物品名,VectorEngine 生成 `2*2` 素材图并切割独立图片,再以每张独立图片调用 Rodin 图生 3D,下载 `.glb` 并转存 OSS。入口页选择的 `assetStylePrompt` 必须写入素材图提示词;结果页手动 Rodin 图生模型时,继续以该物品图片和默认提示词作为起点。
|
||||
抓大鹅草稿生成链路会根据难度生成题材物品素材:文本模型生成物品名,VectorEngine 分批生成 `1:1` 素材图并切割为每个物品 `5` 张不同视角图片,再转存 OSS。入口页选择的 `assetStylePrompt` 必须写入素材图提示词;结果页批量新增物品时继续以该风格作为默认提示词起点。
|
||||
|
||||
生成出的独立图片与 GLB 模型都必须作为草稿页 `3D素材` Tab 的预览资产返回。模型生成成功时 `generatedItemAssets[].status = model_ready`,并携带 `modelSrc`、`modelObjectKey`、`modelFileName`、`taskUuid` 和 `subscriptionKey`;正式平台资产绑定和更完整的二次编辑流程以后续技术方案为准。
|
||||
生成出的独立图片必须作为结果页 `素材配置 > 物品` 的预览资产返回。图片素材生成成功时 `generatedItemAssets[].status = image_ready`,并携带 `imageViews[]`,兼容字段 `imageSrc` / `imageObjectKey` 指向首张视角图;正式平台资产绑定和更完整的二次编辑流程以后续技术方案为准。
|
||||
|
||||
## 7.4 发布前试玩
|
||||
|
||||
@@ -277,13 +283,16 @@ totalItemCount = clearCount * 3
|
||||
|
||||
每种物品数量必须是 `3` 的倍数,避免生成无法通关的局。
|
||||
|
||||
生成的消除物类型数由用户填写的需要消除次数决定:
|
||||
生成的消除物类型数由难度档位决定:
|
||||
|
||||
```text
|
||||
itemTypeCount = clearCount <= 25 ? clearCount : 25
|
||||
轻松 = 3
|
||||
标准 = 9
|
||||
进阶 = 15
|
||||
硬核 = 21
|
||||
```
|
||||
|
||||
当 `clearCount <= 25` 时,本局生成的 `itemTypeId` 数量等于 `clearCount`,每种类型默认生成 `3` 件;当 `clearCount > 25` 时,本局最多生成 `25` 种 `itemTypeId`,后续消除组按这 `25` 种类型轮转补齐,且每种类型最终数量仍必须保持 `3` 的倍数。
|
||||
当前四档难度分别生成 `3 / 9 / 15 / 21` 种 `itemTypeId`。历史草稿若仍保留 `clearCount = 20` 的硬核配置,运行时和素材生成都必须兼容映射为 `21` 种物品,不得回退成 `20` 种。
|
||||
|
||||
同一局内这些类型必须分别使用不同的形状和颜色组合,不能出现两个组看起来像同一种物体的情况。
|
||||
|
||||
@@ -297,13 +306,13 @@ itemTypeCount = clearCount <= 25 ? clearCount : 25
|
||||
|
||||
## 8.5 物品资产
|
||||
|
||||
当前 demo 使用生成 GLB 优先、默认积木兜底的物品资产策略。
|
||||
当前 demo 使用生成 2D 图片优先、默认积木兜底的物品资产策略。
|
||||
|
||||
1. demo 至少提供 `25` 种彼此不同的颜色与几何造型组合默认素材,支撑 `clearCount > 25` 时的类型上限和 GLB 缺失兜底。
|
||||
2. 有 `generatedItemAssets[].modelSrc` 或 `modelObjectKey` 时,运行态与备选栏必须优先读取该 GLB;默认积木件只作为加载失败、模型缺失或 2D 回退时的兜底素材池。
|
||||
3. 前端读取生成模型必须通过 `/api/assets/read-bytes` 获取私有 OSS 字节,再交给 Three.js `GLTFLoader` 解析;不得直接把 `/generated-match3d-assets/...` 当裸 URL 请求。
|
||||
4. 当前固定 `clearCount = 3` 的生成草稿中,运行态 `match3d-type-01/02/03` 按类型编号顺序映射到生成出的 `3` 个模型;后续恢复更大生成数量时,模型列表顺序必须继续与类型编号稳定对应。
|
||||
5. 默认积木视觉键仍需映射为无文字的纯色 2D 图标和程序化 3D 积木模型,不能显示为透明气泡或文字标记。
|
||||
1. demo 至少提供 `25` 种彼此不同的颜色与几何造型组合默认素材,支撑 `clearCount > 25` 时的类型上限和图片缺失兜底。
|
||||
2. 有 `generatedItemAssets[].imageViews`、`imageSrc` 或 `imageObjectKey` 时,运行态与备选栏必须优先读取该 2D 图片素材;默认积木件只作为加载失败或图片缺失时的兜底素材池。
|
||||
3. 前端读取 generated legacy 图片必须通过 `/api/assets/read-url` 换签后加载;不得直接把 `/generated-match3d-assets/...` 当裸 URL 请求。
|
||||
4. 运行态 `match3d-type-01/02/03` 等类型按类型编号顺序映射到生成出的图片素材列表;后续更大生成数量时,素材列表顺序必须继续与类型编号稳定对应。
|
||||
5. 默认积木视觉键仍需映射为无文字的纯色 2D 图标,不能显示为透明气泡或文字标记。
|
||||
6. 用户题材主题后续会映射为符合常识预期的物品集合。
|
||||
|
||||
示例:水果题材可以对应红色苹果、黄色香蕉、紫色葡萄等。
|
||||
@@ -334,7 +343,7 @@ itemTypeCount = clearCount <= 25 ? clearCount : 25
|
||||
|
||||
飞行动画过程中,物品不再与其他物品产生碰撞。
|
||||
|
||||
当前 3D 实验模式下,物品进入备选栏后必须从圆形空间的物理世界移除;备选栏只展示该物品同款 3D 模型的独立预览,固定为斜 `45` 度便于识别,不再参与场内碰撞、重力或堆叠。
|
||||
物品进入备选栏后必须从圆形空间的可点击列表移除;备选栏展示该物品同款 2D 素材图,不再参与场内点击、遮挡或堆叠。
|
||||
|
||||
前端播放即时反馈的同时,必须向后端提交点击意图。后端确认后固化入槽结果;后端拒绝时,前端恢复物品位置和备选栏表现。
|
||||
|
||||
@@ -344,7 +353,7 @@ itemTypeCount = clearCount <= 25 ? clearCount : 25
|
||||
|
||||
1. 每次点击进入即时反馈流程后,前端先把物品表现为进入备选栏。
|
||||
2. 备选栏中每出现 `3` 个相同物品 id,前端立即播放自动消除效果并腾出格子。
|
||||
3. 3D 模式下,备选栏格子展示从场内取出的同款 3D 模型预览,视角固定斜 `45` 度,不使用另一套不一致的 UI 图标;托盘预览必须共享一个 WebGL renderer,并按 `7` 格容器实际宽高把模型居中摆放到对应格子,不能因多个预览上下文导致中心场地模型不可见;WebGL 回退或 `2D` 模式下才使用保留的 2D 图标。
|
||||
3. 备选栏格子展示从场内取出的同款 2D 素材图,不使用另一套不一致的 UI 图标;图片缺失或读取失败时才使用保留的默认图标。
|
||||
4. 后端确认后固化真实备选栏和消除结果;若后端返回状态不一致,前端必须以最新后端快照校正。
|
||||
5. 如果备选栏满且无法消除,前端可以立即展示失败过渡,最终失败状态以后端确认为准。
|
||||
|
||||
@@ -671,11 +680,12 @@ GET /api/runtime/match3d/runs/:runId
|
||||
|
||||
## 14.2 入口表单
|
||||
|
||||
入口表单只展示三个输入块:
|
||||
入口表单只展示四个输入块:
|
||||
|
||||
1. `想做一个什么题材的抓大鹅?` 大文本输入框。
|
||||
2. `3D素材风格` 横向滑动风格卡,最后一个为 `自定义`。
|
||||
2. `2D素材风格` 横向滑动风格卡,最后一个为 `自定义`。
|
||||
3. `难度` 选项按钮。
|
||||
4. `生成音效` Toggle,默认关闭。
|
||||
|
||||
入口页不展示参考图、`需要消除次数` 数值输入、`难度数值` 滑杆,也不展示 `题材 / 物品 / 难度` 三个摘要框。`需要消除次数` 和 `difficulty` 由难度选项派生后提交给后端。
|
||||
|
||||
@@ -704,24 +714,25 @@ GET /api/runtime/match3d/runs/:runId
|
||||
首版 PRD 对应 demo 验收标准:
|
||||
|
||||
1. 用户可从平台创作入口进入“抓大鹅”模板。
|
||||
2. 入口表单能确认题材主题、3D 素材风格和难度选项,并提交派生后的消除次数与难度数值。
|
||||
2. 入口表单能确认题材主题、2D 素材风格和难度选项,并提交派生后的消除次数与难度数值。
|
||||
3. 入口页不展示参考图上传。
|
||||
4. 内置风格显示画风参考图,自定义风格通过独立面板填写并进入提交 payload。
|
||||
5. 移动端入口页所有内容一屏展示,不产生纵向滚动。
|
||||
6. 系统可生成待发布结果页,并在草稿中返回首批切割图片与 OSS GLB 模型素材预览。
|
||||
7. 用户可编辑游戏名称、标签、封面图等基础信息。
|
||||
8. 用户可发布前试玩,且试玩失败不阻断发布。
|
||||
9. 运行态能展示圆形空间、倒计时、物品和 `7` 格备选栏;存在 `generatedItemAssets` 模型时必须优先展示生成 GLB,而不是默认积木素材。
|
||||
10. 物品可重叠、遮挡、堆叠。
|
||||
11. 被完全遮挡物品不可点击,露出可点击区域的物品可点击。
|
||||
12. 点击通过后物品飞入备选栏。
|
||||
13. 备选栏中 `3` 个相同物品 id 自动消除。
|
||||
14. 清空空间中全部物品后胜利。
|
||||
15. 倒计时结束或备选栏满后失败。
|
||||
16. 胜利结算展示使用时间。
|
||||
17. 失败结算展示完成进度和重新开始按钮。
|
||||
18. 局内即时反馈由前端先行呈现,关键状态以后端确认快照校正。
|
||||
19. 相关中文文档通过编码检查。
|
||||
6. `生成音效` 关闭时草稿生成不产生 `clickSound`;打开时首批生成物品随图片素材生成并持久化点击音效。
|
||||
7. 系统可生成待发布结果页,并在草稿中返回首批多视角 2D 切割图片素材预览。
|
||||
8. 用户可编辑游戏名称、标签、封面图等基础信息。
|
||||
9. 用户可发布前试玩,且试玩失败不阻断发布。
|
||||
10. 运行态能展示圆形空间、倒计时、物品和 `7` 格备选栏;存在 `generatedItemAssets` 图片素材时必须优先展示生成 2D 素材,而不是默认积木素材。
|
||||
11. 物品可重叠、遮挡、堆叠。
|
||||
12. 被完全遮挡物品不可点击,露出可点击区域的物品可点击。
|
||||
13. 点击通过后物品飞入备选栏。
|
||||
14. 备选栏中 `3` 个相同物品 id 自动消除。
|
||||
15. 清空空间中全部物品后胜利。
|
||||
16. 倒计时结束或备选栏满后失败。
|
||||
17. 胜利结算展示使用时间。
|
||||
18. 失败结算展示完成进度和重新开始按钮。
|
||||
19. 局内即时反馈由前端先行呈现,关键状态以后端确认快照校正。
|
||||
20. 相关中文文档通过编码检查。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
# “我的”页签法律信息与登录协议确认 PRD
|
||||
|
||||
## 1. 目标
|
||||
|
||||
在平台“我的”页签底部补齐法律信息入口和备案信息;同时在登录弹窗中增加协议确认,用户首次登录必须手动勾选同意后才能继续登录。
|
||||
|
||||
## 2. 入口与布局
|
||||
|
||||
### 2.1 “我的”页签常用功能
|
||||
|
||||
- 已登录用户在“我的”页签看到常用功能区。
|
||||
- 常用功能区移动端和网页端都使用 3 列网格。
|
||||
- 每个功能入口保持图标、主标题、短副标题结构。
|
||||
- 不新增独立“我的”页面,只扩展现有个人页签。
|
||||
|
||||
### 2.2 法律信息区
|
||||
|
||||
法律信息区放在“我的”页签底部、设置入口之后。
|
||||
|
||||
区块内容:
|
||||
|
||||
- 区块标题:`法律信息`。
|
||||
- 三个列表入口:
|
||||
- `用户协议`
|
||||
- `隐私政策`
|
||||
- `免责声明`
|
||||
- 每个入口点击后打开独立模态面板,不在当前页签下方展开内容。
|
||||
- 备案信息固定显示在法律入口下方:
|
||||
- 文案:`京ICP备2026025677号`
|
||||
- 点击跳转到 `https://beian.miit.gov.cn/`
|
||||
- 外链在新窗口打开,并使用 `rel="noreferrer"`。
|
||||
|
||||
## 3. 法律内容面板
|
||||
|
||||
### 3.1 内容来源
|
||||
|
||||
三份法律内容读取仓库现有 Markdown 文件:
|
||||
|
||||
- `media/files/user_agreement.md`
|
||||
- `media/files/privacy_policy.md`
|
||||
- `media/files/disclaimer.md`
|
||||
|
||||
### 3.2 展示规则
|
||||
|
||||
- 使用平台主题变量渲染,暗色和亮色主题都必须可读。
|
||||
- 面板最大高度不超过视口,正文区域内部滚动。
|
||||
- 标题固定在面板顶部,底部保留确认按钮 `我知道了`。
|
||||
- Markdown 首版只需要支持标题、段落、列表和加粗文本。
|
||||
- 不把 Markdown 原文作为纯文本整段堆叠,必须保留基本阅读层级。
|
||||
|
||||
## 4. 登录协议确认
|
||||
|
||||
### 4.1 展示位置
|
||||
|
||||
登录弹窗的短信登录和密码登录表单都在提交按钮上方展示协议确认行:
|
||||
|
||||
`我已阅读并同意《用户协议》《隐私政策》和《免责声明》`
|
||||
|
||||
其中三段蓝色链接分别打开对应法律内容面板。
|
||||
|
||||
### 4.2 勾选规则
|
||||
|
||||
- 使用本地存储 key `genarrative.auth.legal-consent.v1` 记录是否已经确认。
|
||||
- 首次打开登录弹窗时,如果没有本地确认记录,勾选框默认为未选中。
|
||||
- 后续打开登录弹窗时,如果本地已有确认记录,勾选框默认为选中。
|
||||
- 用户未勾选时:
|
||||
- 登录按钮禁用。
|
||||
- 点击法律链接只打开内容面板,不自动勾选。
|
||||
- 用户勾选后:
|
||||
- 立即写入本地确认记录。
|
||||
- 短信登录和密码登录都可继续使用。
|
||||
|
||||
## 5. 验收
|
||||
|
||||
- 已登录“我的”页签常用功能区为 3 列。
|
||||
- “我的”页签底部出现 `法律信息`、三个入口和 `京ICP备2026025677号`。
|
||||
- 三个法律入口都能打开独立可滚动面板。
|
||||
- 备案号点击打开 `https://beian.miit.gov.cn/`。
|
||||
- 首次登录弹窗协议勾选为空,登录按钮禁用。
|
||||
- 勾选协议后登录按钮恢复可用,并持久化本地确认状态。
|
||||
- 再次打开登录弹窗时协议勾选默认选中。
|
||||
|
||||
## 6. 2026-05-12 落地记录
|
||||
|
||||
- 法律文档解析与弹窗复用 `src/components/common/legalDocuments.ts` 和 `src/components/common/LegalDocumentModal.tsx`。
|
||||
- “我的”页签在 `src/components/rpg-entry/RpgEntryHomeView.tsx` 中接入 3 列常用功能、法律入口和备案链接。
|
||||
- 登录协议确认在 `src/components/auth/LoginScreen.tsx` 中接入,短信登录和密码登录共用同一确认行。
|
||||
- 定向验证:
|
||||
- `npm run test -- src/components/auth/AuthGate.test.tsx src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx`
|
||||
- `npx eslint src/components/auth/LoginScreen.tsx src/components/auth/AuthGate.test.tsx src/components/common/LegalDocumentModal.tsx src/components/common/legalDocuments.ts src/components/rpg-entry/RpgEntryHomeView.tsx src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx --max-warnings 0`
|
||||
@@ -12,6 +12,7 @@
|
||||
- [AI 原生拼图玩法创作工具与玩法系统 PRD](./AI_NATIVE_PUZZLE_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-04-22.md):拼图玩法创作、结果页、发布、广场和运行时主链路。
|
||||
- [AI 原生方洞挑战玩法创作工具与玩法系统 PRD](./AI_NATIVE_SQUARE_HOLE_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-05-04.md):方洞挑战创作、发布与试玩闭环。
|
||||
- [后台管理独立前端工程 PRD](./ADMIN_WEB_CONSOLE_PRD_2026-04-30.md):后台管理端产品边界。
|
||||
- [“我的”页签法律信息与登录协议确认 PRD](./PROFILE_LEGAL_INFO_AND_AUTH_AGREEMENT_PRD_2026-05-12.md):定义个人页法律入口、备案链接、法律内容弹窗和首次登录协议勾选规则。
|
||||
|
||||
## 使用规则
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
## 1. 范围
|
||||
|
||||
本方案用于改造 `生成抓大鹅草稿` 的首版生成链路:点击按钮后先进入独立生成过程页,生成结束后自动进入抓大鹅草稿页,并在草稿页 `3D素材` Tab 预览本次生成的 3D 模型。
|
||||
本方案用于改造 `生成抓大鹅草稿` 的首版生成链路:点击按钮后先进入独立生成过程页,生成结束后自动进入抓大鹅结果页,并在结果页 `素材配置 > 物品` 预览本次生成的 2D 多视角物品素材。
|
||||
|
||||
本次只把任意难度都收敛为 `3` 件物品。后续难度曲线恢复时,再把物品数、网格数和手动 3D 任务数量从配置中放开。
|
||||
草稿生成不再调用 Hyper3D Rodin,也不再生成 GLB 模型。物品素材继续沿用原来的“生成图片 -> 网格拆分 -> 上传 OSS -> 写回草稿”机制,但每个物品必须生成 `5` 个不同视角的 2D 视图。试玩和正式运行态的消除次数、总物品数和物品种类数以结果页 `难度配置` 保存的难度为准。难度对应物品种类固定为:轻松 `3` 种、标准 `9` 种、进阶 `15` 种、硬核 `21` 种。历史硬核草稿若仍保存 `clearCount = 20`,运行态按新硬核升为 `21` 次消除、`63` 件总物品。正式发布前如果已生成 `image_ready` 物品种类不足当前难度要求,必须阻断发布;试玩不阻断,但启动时把物品种类自动降到当前可用 2D 素材数量。
|
||||
|
||||
## 2. 前端流程
|
||||
|
||||
@@ -20,34 +20,36 @@
|
||||
生成页步骤固定为:
|
||||
|
||||
```text
|
||||
生成游戏名称 -> 生成物品名称 -> 生成素材图 -> 切割独立图片 -> 上传图片资产 -> 生成3D模型 -> 写入草稿页
|
||||
生成游戏名称 -> 生成物品名称与背景音乐名称 -> 生成背景提示词 -> 分批生成1K素材图 -> 切割五视角图片 -> 上传图片资产 -> 生成背景音乐 -> 生成背景图 -> 写入草稿页
|
||||
```
|
||||
|
||||
生成页只展示题材和物品数量,不展示玩法规则说明。
|
||||
|
||||
当前 `match3d-generating` 进度页不是后端 task 状态订阅页,而是一个覆盖 `match3d_compile_draft` 长 action 的本地时间进度页:前端每 500ms 以本地时间刷新阶段展示,真正的生成完成仍以 action 返回为准。为避免长 action 未返回时页面完全无感,生成页在 `match3d_compile_draft` 执行期间每 3 秒旁路读取一次 session 和 work detail,并用 profile 中已写回的 `generatedItemAssets` 更新 `生成3D模型` 的完成数量。Hyper3D 控制台中看到 3 个 Rodin 任务已经 `Done` 后,页面仍可能继续停留在 `生成3D模型`,此时通常表示后端还在等待下载列表、下载 GLB、转存 OSS 或写回 `generated_item_assets_json`;若 `generatedItemAssets` 已出现 `model_ready`,前端应逐步显示完成数量。排查时应看 api-server 日志中的 `抓大鹅 Rodin 状态轮询返回`、`抓大鹅 Rodin 下载列表轮询返回`、`抓大鹅 Rodin GLB 下载完成` 和 `抓大鹅 Rodin GLB 转存 OSS 完成`。
|
||||
当前 `match3d-generating` 进度页不是后端 task 状态订阅页,而是一个覆盖 `match3d_compile_draft` 长 action 的本地时间进度页:前端每 500ms 以本地时间刷新阶段展示,真正的生成完成仍以 action 返回为准。为避免长 action 未返回时页面完全无感,生成页在 `match3d_compile_draft` 执行期间每 3 秒旁路读取一次 session 和 work detail,并用 profile 中已写回的 `generatedItemAssets` 更新图片素材完成数量。若 `generatedItemAssets` 已出现 `image_ready` 且带 `imageViews`,前端应逐步显示完成数量。
|
||||
|
||||
## 3. 后端编排边界
|
||||
|
||||
外部模型和 OSS 上传全部由 `api-server` 编排,不进入 SpacetimeDB reducer。SpacetimeDB 继续只负责 Match3D 会话、草稿和作品 profile 的确定性写入。
|
||||
外部生图、音频生成和 OSS 上传全部由 `api-server` 编排,不进入 SpacetimeDB reducer。SpacetimeDB 继续只负责 Match3D 会话、草稿和作品 profile 的确定性写入。
|
||||
|
||||
`match3d_compile_draft` action 的后端顺序为:
|
||||
|
||||
1. 读取 session config。
|
||||
2. 将本次 MVP 的 `clearCount` 固定为 `3`,并同步用于草稿编译。
|
||||
3. 先调用 SpacetimeDB compile procedure 写入草稿。首次执行使用新 `profileId`;重试时复用 session draft / work profile 中已有 `profileId`。这一步不能等待 LLM、图片、OSS 或 Rodin 成功后才执行。
|
||||
4. 基于入口页题材设定文本调用文本模型生成作品元信息。模型固定请求 `gpt-4o`,只返回 JSON,其中 `gameName` 为 4 到 12 个中文字符的游戏名称,`tags` 为 3 到 6 个中文短标签;`summary` 首版必须保持空字符串,结果页 `作品描述` 默认留给用户填写。文本模型不可用时保留第 3 步的本地兜底,不阻断草稿。
|
||||
5. 调用文本模型生成 `3` 个题材下的短物品名称。
|
||||
6. 调用项目当前图片链路 VectorEngine `gpt-image-2-all` 生成一张 `1:1` 素材图,提示词必须合入入口页选择的 `assetStylePrompt`。历史 `nanobanana2` 图片选项当前按项目统一决策回落到 VectorEngine,不重新接入 APIMart 图片网关。
|
||||
7. 将素材图按 `n*n` 网格切割成独立图片。当前 `3` 件物品使用 `2*2` 网格,取前 `3` 格。
|
||||
8. 将素材图和每张独立图片上传到 OSS,其中独立图片作为草稿页素材预览和 Rodin 图生模型参考图;每次获得可恢复的图片资产后,都要回写 `match3d_work_profile.generated_item_assets_json`。
|
||||
9. 使用每张独立图片作为参考图,并行调用 Hyper3D Rodin 图生模型;所有 3D 模型任务必须在同一阶段同时提交、同时轮询状态、同时下载并转存 OSS,禁止逐个物品串行等待模型完成。每个任务按官方 `check-status_reset_v` / `download-results_reset_v` 文档轮询状态和下载:状态查询使用 `subscription_key`,整体完成态以 `jobs[]` 聚合为准;下载查询使用生成响应顶层 `uuid` 作为 `task_uuid`,不能使用 `jobs.uuids` 子任务 uuid。只有 `jobs` 全部进入 `Done` 才能视为任务完成,任一 job `Failed` 则失败。完成后选择 `.glb` 下载文件,并把 GLB 转存到 OSS。Rodin 的 `subscriptionKey` 是上游 opaque token,不做 256 字符这类短文本长度限制。Rodin 任务状态进入完成态后,下载列表仍可能延迟发布;后端必须对下载列表继续轮询,并兼容 `url`、`downloadUrl`、`fileUrl`、`signedUrl` 等下载字段别名,只有预览图而没有模型文件时不能伪装成 GLB 成功。
|
||||
10. Rodin 每批完成后继续回写 `generated_item_assets_json`。成功素材状态为 `model_ready`;失败素材保留图片引用并记录 `error`,下次 `match3d_compile_draft` 只继续缺失模型的素材,不重复生成已完成的 GLB。
|
||||
11. 在 HTTP 返回的 draft/profile DTO 中附带本次生成的素材资产预览信息;后续重进草稿页时从 work profile 的持久化 `generatedItemAssets` 恢复同一批素材。
|
||||
2. 草稿编译先创建可恢复 profile;素材生成数量由入口页难度派生的物品种类决定:轻松 `3` 种、标准 `9` 种、进阶 `15` 种、硬核 `21` 种。
|
||||
3. 先调用 SpacetimeDB compile procedure 写入草稿。首次执行使用新 `profileId`;重试时复用 session draft / work profile 中已有 `profileId`。这一步不能等待 LLM、图片、音频或 OSS 成功后才执行。
|
||||
4. 基于入口页题材设定文本调用文本模型生成作品生成计划。模型固定请求 `gpt-4o`,只返回 JSON,其中 `gameName` 为 4 到 12 个中文字符的游戏名称,`tags` 为 3 到 6 个中文短标签;`summary` 首版必须保持空字符串,结果页 `作品描述` 默认留给用户填写。生成计划还必须包含 `backgroundMusic.title`、`backgroundMusic.style`、`backgroundMusic.prompt`、`backgroundPrompt`,以及 `items[]` 中每个物品的 `name` 与 `soundPrompt`。`backgroundMusic.title` 是背景音乐名称,`backgroundMusic.prompt` 固定为空字符串,用于后续 Suno 纯音乐生成;`backgroundPrompt` 用于生成局内竖屏背景图,必须描述绿色纵向背景与居中浅锅/圆盘状竞技区融合为一张完整背景图,且不包含 UI、文字、按钮、倒计时或物品。文本模型不可用时保留第 3 步的本地兜底,不阻断草稿。
|
||||
5. 后端从同一份作品生成计划读取当前难度所需数量的短物品名称和音效提示词;不得再只生成物品名称而丢失后续音效生成上下文。
|
||||
6. 调用项目当前图片链路 VectorEngine `gpt-image-2-all` 生成 `1:1`、`1024x1024` 素材图,提示词必须合入入口页选择的 `assetStylePrompt`。历史 `nanobanana2` 图片选项当前按项目统一决策回落到 VectorEngine,不重新接入 APIMart 图片网关。
|
||||
7. 每个物品固定需要 `5` 个不同视角。单张素材图最多切成 `5*5 = 25` 格;因此单张图最多承载 `5` 个物品。若草稿物品数超过 `5`,后端按每批最多 `5` 个物品自动分批,多张素材图并行生成。
|
||||
8. 将每张素材图按 `n*n` 网格切割成独立图片,并按物品顺序连续分配 `5` 张视角图。每个物品 JSON 写入 `imageViews[]`,同时把第一个视角兼容写入 `imageSrc/imageObjectKey`。
|
||||
9. 将素材图和每张独立视角图片上传到 OSS。每次获得可恢复的图片资产后,都要回写 `match3d_work_profile.generated_item_assets_json`。成功素材状态为 `image_ready`;失败素材保留已成功图片引用并记录 `error`。每个素材 JSON 同步保存 `soundPrompt`,首个素材 JSON 同步保存 `backgroundMusicTitle` 与 `backgroundMusicStyle`,`backgroundMusicPrompt` 保存为空字符串作为兼容字段。
|
||||
10. 后端在图片素材生成后使用 `backgroundMusic.title` 提交 Suno 背景音乐任务,`prompt` 为空,`tags` 来自 `backgroundMusic.style`,并固定走纯音乐生成。轮询完成后通过通用创作音频资产链路转存 OSS、确认 `asset_object`、绑定到 `match3d_work/background_music`,再写回首个素材的 `backgroundMusic`。音乐生成失败只记录 warning,不阻断草稿页进入,用户可在结果页 `素材配置 > 背景音乐` 重试。
|
||||
11. 若入口页 `generateClickSound=true`,后端在图片素材生成后继续为缺少 `clickSound` 的已生成物品并行提交 Vidu 点击音效任务,轮询完成后通过通用创作音频资产链路转存 OSS、确认 `asset_object`、绑定实体并写回对应素材的 `clickSound`;若开关关闭则只保存 `soundPrompt`,不调用音频生成。
|
||||
12. 背景图生成同样由 `api-server` 调用 VectorEngine `gpt-image-2-all`,尺寸固定为 `9:16`,并固定传入 `public/match3d-background-references/pot-fused-reference.png` 作为参考图。参考图只表达抓大鹅绿色页面背景和锅状圆形竞技区的融合构图,不包含 HUD、物品、文字或按钮。生成后的背景图上传到 `generated-match3d-assets/{sessionId}/{profileId}/background/{taskId}/background.png`,并作为 `backgroundAsset` 挂在首个 `generatedItemAssets[]` JSON 上;HTTP DTO 同时顶层输出 `backgroundPrompt`、`backgroundImageSrc`、`backgroundImageObjectKey` 与 `generatedBackgroundAsset`。
|
||||
13. 在 HTTP 返回的 draft/profile DTO 中附带本次生成的素材资产预览信息、背景音乐资产信息和背景资产信息;后续重进草稿页时从 work profile 的持久化 `generatedItemAssets` 恢复同一批素材、音乐与背景。
|
||||
|
||||
若文本模型不可用或返回无法解析,后端必须降级为 `{themeText}抓大鹅` 与本地标签兜底,不阻断素材生成;但描述仍保持空字符串。
|
||||
|
||||
草稿生成阶段会调用 Hyper3D Rodin 并等待 GLB 下载完成;前端 `match3d_compile_draft` action 请求超时必须覆盖该长耗时链路,当前 Match3D client 使用 20 分钟超时。Rodin 单模型状态轮询预算为 10 分钟,下载列表发布轮询预算为 5 分钟;GLB 下载和 OSS PutObject 各自设置 3 分钟 HTTP 超时,避免上游下载或转存连接长期悬挂。由于 3 个模型并行生成,总耗时按最慢模型计算,不能按模型数量线性叠加。结果页 `3D素材` Tab 直接加载已生成模型;用户点击 `重新生成` 时再复用 Rodin 安全代理,首版重新生成只更新当前页面内预览状态,后续正式资产绑定以独立技术方案为准。
|
||||
草稿生成阶段不再调用 Hyper3D Rodin,不生成 GLB,也不等待任何模型轮询。前端 `match3d_compile_draft` action 的长耗时主要来自文本生成、分批 1K 生图、切图、OSS 上传、背景图和可选音频生成。批量新增物品由 `POST /api/creation/match3d/works/{profileId}/item-assets` 复用同一套 2D 素材图生成、5x5 切图、OSS 上传和可选点击音效链路,只补齐本次新增物品并把 `imageViews[]` 写回 `generatedItemAssets`。
|
||||
|
||||
## 4. 图片提示词
|
||||
|
||||
@@ -55,27 +57,35 @@
|
||||
|
||||
```text
|
||||
生成一张1:1图片
|
||||
生成2*2网格素材图
|
||||
生成不超过5*5网格素材图
|
||||
整体画风遵循:...
|
||||
只绘制这些物品:...
|
||||
不要出现文字、水印、UI、边框
|
||||
```
|
||||
|
||||
`包含若干个物品名称` 在落地中解释为“按生成出的物品名称绘制对应主体”,不要求图片上写出物品名称。这样可以避免文字渲染污染切图和后续手动 3D 模型参考。
|
||||
`包含若干个物品名称` 在落地中解释为“按生成出的物品名称绘制对应主体”,不要求图片上写出物品名称。这样可以避免文字渲染污染切图和局内 2D 素材表现。
|
||||
|
||||
入口页内置风格参考图通过同一 VectorEngine `gpt-image-2-all` 能力生成,保存路径固定为:
|
||||
入口页内置 2D 风格参考图通过同一 VectorEngine `gpt-image-2-all` 能力生成,执行命令为 `npm run assets:match3d-style-references -- --live`,保存路径固定为:
|
||||
|
||||
```text
|
||||
public/match3d-style-references/clay-toy.png
|
||||
public/match3d-style-references/low-poly.png
|
||||
public/match3d-style-references/toy-plastic.png
|
||||
public/match3d-style-references/wood-carved.png
|
||||
public/match3d-style-references/voxel-block.png
|
||||
public/match3d-style-references/metal-mecha.png
|
||||
public/match3d-style-references/flat-icon.png
|
||||
public/match3d-style-references/cel-cartoon.png
|
||||
public/match3d-style-references/pixel-retro.png
|
||||
public/match3d-style-references/watercolor.png
|
||||
public/match3d-style-references/sticker-outline.png
|
||||
public/match3d-style-references/painterly-icon.png
|
||||
```
|
||||
|
||||
这些图片只作为入口页风格选择的视觉参考,不进入用户草稿资产,不替代生成时的物品素材图。
|
||||
|
||||
局内背景生成固定参考图路径为:
|
||||
|
||||
```text
|
||||
public/match3d-background-references/pot-fused-reference.png
|
||||
```
|
||||
|
||||
这张图作为 VectorEngine `image` 参考输入使用,用来锁定“绿色竖屏背景 + 居中锅状竞技区”的构图。每次草稿生成仍会根据 `backgroundPrompt` 生成新的题材化背景图;参考图本身不作为运行态最终背景。
|
||||
|
||||
## 5. OSS 路径
|
||||
|
||||
新增 generated legacy prefix:
|
||||
@@ -88,47 +98,56 @@ generated-match3d-assets
|
||||
|
||||
```text
|
||||
generated-match3d-assets/{sessionId}/{profileId}/material-sheet/{taskId}/sheet.png
|
||||
generated-match3d-assets/{sessionId}/{profileId}/items/{itemSlug}/image/image.png
|
||||
generated-match3d-assets/{sessionId}/{profileId}/items/{itemSlug}/model/{taskUuid}/model.glb
|
||||
generated-match3d-assets/{sessionId}/{profileId}/items/{itemSlug}/views/view-01.png
|
||||
generated-match3d-assets/{sessionId}/{profileId}/items/{itemSlug}/views/view-02.png
|
||||
generated-match3d-assets/{sessionId}/{profileId}/items/{itemSlug}/views/view-03.png
|
||||
generated-match3d-assets/{sessionId}/{profileId}/items/{itemSlug}/views/view-04.png
|
||||
generated-match3d-assets/{sessionId}/{profileId}/items/{itemSlug}/views/view-05.png
|
||||
generated-match3d-assets/{sessionId}/{profileId}/background/{taskId}/background.png
|
||||
```
|
||||
|
||||
`itemSlug` 必须带 `itemId` 前缀,例如 `match3d-item-1-item`。中文物品名清洗后可能都退回 `item`,不能只用物品名做路径,否则多张切割图会写到同一个 object key,导致草稿页预览图全部一致。
|
||||
|
||||
HTTP DTO 同时返回 `imageSrc`、`imageObjectKey`、`modelSrc`、`modelObjectKey`、`modelFileName`、`taskUuid`、`subscriptionKey` 和 `status`。模型生成成功后 `status = model_ready`;若后续允许部分模型失败降级,失败素材必须带 `error`,且不能伪装成可预览模型。前端模型预览必须通过 `/api/assets/read-bytes` 读取私有 GLB 字节并转成 Blob URL 后交给 Three.js,不直接请求裸 `/generated-match3d-assets/...` 路径。
|
||||
HTTP DTO 同时返回兼容字段 `imageSrc`、`imageObjectKey`,以及正式 2D 字段 `imageViews[]`、`backgroundAsset` 和 `status`。图片素材生成成功后 `status = image_ready`;背景生成成功后首个素材的 `backgroundAsset.status = image_ready`。前端通过 `/api/assets/read-url` 将 generated legacy path 换签后加载私有图片,不直接请求裸 `/generated-match3d-assets/...` 路径。运行态背景图同样通过 `/api/assets/read-url` 换签后作为全屏 `object-cover` 背景加载。
|
||||
|
||||
## 5.1 运行态模型消费
|
||||
## 5.1 运行态 2D 素材消费
|
||||
|
||||
生成模型不仅用于结果页预览,也必须进入游戏运行态。运行态入口的传递链路为:
|
||||
生成的 2D 五视角素材不仅用于结果页预览,也必须进入游戏运行态。运行态入口的传递链路为:
|
||||
|
||||
```text
|
||||
Match3DWorkProfile / PlatformMatch3DGalleryCard
|
||||
-> Match3DRuntimeShell(generatedItemAssets)
|
||||
-> Match3DRuntimeShell(generatedItemAssets, backgroundImageSrc)
|
||||
-> Match3DPhysicsBoard / Match3DTrayPreviewBoard
|
||||
```
|
||||
|
||||
`Match3DPhysicsBoard` 与 `Match3DTrayPreviewBoard` 按运行快照中的 `itemTypeId` 稳定排序后,把生成出的模型顺序映射到对应类型。当前 MVP 固定 `clearCount = 3`,因此 `match3d-type-01/02/03` 分别对应生成列表的第 `1/2/3` 个模型;后续恢复更多物品生成时,后端必须继续保证 `generatedItemAssets` 顺序与类型编号一致。
|
||||
运行态按运行快照中的 `itemTypeId` 稳定排序后,把 `generatedItemAssets` 顺序映射到对应类型。加载某个物品实例时,从该类型素材的 `imageViews[]` 中按实例 id 稳定随机选择一个视角;若历史数据没有 `imageViews[]`,则回退到 `imageSrc/imageObjectKey`。没有生成图片或图片加载失败时,继续使用默认积木图标兜底。
|
||||
|
||||
运行态背景优先读取 `backgroundImageSrc` / `generatedBackgroundAsset.imageSrc`,为空时从 `generatedItemAssets[].backgroundAsset.imageSrc/imageObjectKey` 兜底。`Match3DRuntimeShell` 只保留顶部返回、倒计时、重开三个控件;进度、组数、版本等状态信息不得再作为顶部常驻 UI 出现,避免遮挡生成背景和锅状竞技区。
|
||||
|
||||
前端加载规则:
|
||||
|
||||
1. 优先读取 `modelSrc`;为空时使用 `modelObjectKey`。
|
||||
2. 通过 `readAssetBytes` 调用 `/api/assets/read-bytes`,由同源后端读取 OSS 私有对象字节。
|
||||
3. 使用 Three.js `GLTFLoader.parseAsync` 解析 GLB 字节,并按物品类型缓存模板。
|
||||
4. 场内每个物品和备选栏预览都从模板 clone 独立对象,点击命中继续写入 `itemInstanceId`。
|
||||
5. 物理碰撞和边界仍沿用现有 `visualKey` 的程序化几何,生成 GLB 只替换视觉模型,不承接规则真相。
|
||||
6. 模型缺失、读取失败或 WebGL 回退时,继续使用默认积木素材,不能阻断开局、点击、入槽或结算;调试模式下需要输出加载失败的 `itemTypeId`、模型来源和错误信息,便于区分“资产没有传入”和“GLB 字节读取或解析失败”。
|
||||
1. 优先读取 `imageViews[]` 中的 `imageSrc/imageObjectKey`,为空时使用兼容字段 `imageSrc/imageObjectKey`。
|
||||
2. 对 generated legacy path 通过同源 `/api/assets/read-url` 换签后交给浏览器图片加载。
|
||||
3. 场内物品、点击命中和备选栏继续使用后端快照中的 `itemInstanceId/itemTypeId/x/y/radius/layer`;生成 2D 图片只替换视觉表现,不承接规则真相。
|
||||
4. 同一物品类型的多个实例可以展示不同视角,但同一实例在本局中应稳定使用同一个视角,避免移动或入槽时闪图。
|
||||
5. 图片缺失、读取失败或解码失败时,继续使用默认积木素材,不能阻断开局、点击、入槽或结算。
|
||||
|
||||
结果页点击 `试玩` 时,前端必须把当前结果页可见的 `generatedItemAssets` 带入运行态启动入参。`PUT /api/runtime/match3d/works/{profileId}` 若因为并发或旧快照返回了缺少素材的 profile,`Match3DResultView` 需要把当前 draft / profile 的素材重新合并到运行态 profile,并在启动试玩前调用生成素材保存接口把当前可见的 `generatedItemAssets` 写回作品 profile;不能只在内存里把素材补到 `onStartTestRun(profile)`。发布同理必须先落库当前素材,再调用 `publish_match3d_work`,否则公开推荐流和正式运行态只能读到旧 profile 快照,历史草稿尤其容易表现为结果页有 3D 模型、正式游戏仍是默认积木。若历史草稿同时存在旧 `draft.generatedItemAssets` 和较新的 `profile.generatedItemAssets`,同 `itemId` 下以 profile 中已有的 `modelSrc` / `modelObjectKey` 补齐 draft,不能让旧 draft 把模型状态覆盖回 `image_ready`。`PlatformEntryFlowShellImpl` 在渲染 `match3d-runtime` 时按 `run.profileId` 优先使用当前 `match3dProfile.generatedItemAssets`,只有 profileId 不匹配时才读取 `selectedPublicWorkDetail.generatedItemAssets`。推荐流内嵌正式运行态也必须走同一解析器;当推荐卡片摘要缺少素材时,启动前补读 `getMatch3DWorkDetail(profileId)`,把详情里的生成模型写入 `match3dProfile` 后再传给运行态。这样可以避免从公开详情页残留状态或推荐卡片旧摘要进入试玩 / 正式游戏时,把已生成草稿的 3D 模型覆盖成空列表。
|
||||
结果页点击 `试玩` 时,前端必须把当前结果页可见的 `generatedItemAssets` 带入运行态启动入参。`PUT /api/runtime/match3d/works/{profileId}` 若因为并发或旧快照返回了缺少素材的 profile,`Match3DResultView` 需要把当前 draft / profile 的素材重新合并到运行态 profile,并在启动试玩前调用生成素材保存接口把当前可见的 `generatedItemAssets` 写回作品 profile;不能只在内存里把素材补到 `onStartTestRun(profile)`。发布同理必须先落库当前素材,再调用 `publish_match3d_work`,否则公开推荐流和正式运行态只能读到旧 profile 快照。若历史草稿同时存在旧 `draft.generatedItemAssets` 和较新的 `profile.generatedItemAssets`,同 `itemId` 下以 profile 中已有的 `imageViews[]`、`imageSrc` 或 `imageObjectKey` 补齐 draft,不能让旧 draft 把素材覆盖成空列表。`PlatformEntryFlowShellImpl` 在渲染 `match3d-runtime` 时按 `run.profileId` 优先使用当前 `match3dProfile.generatedItemAssets`,只有 profileId 不匹配时才读取 `selectedPublicWorkDetail.generatedItemAssets`。推荐流内嵌正式运行态也必须走同一解析器;当推荐卡片摘要缺少素材时,启动前补读 `getMatch3DWorkDetail(profileId)`,把详情里的生成图片素材写入 `match3dProfile` 后再传给运行态。这样可以避免从公开详情页残留状态或推荐卡片旧摘要进入试玩 / 正式游戏时,把已生成草稿的 2D 素材覆盖成空列表。
|
||||
|
||||
历史草稿若仍保存 `status = model_ready`、`modelSrc` 或 `modelObjectKey`,仅作为旧版本兼容读取,不再参与新素材生产。历史外部模型链接转存接口只用于清理旧数据,不能被新草稿生成、批量新增或结果页普通编辑入口调用。
|
||||
|
||||
生成完成后自动进入试玩依赖 `selectionStageRef.current === 'match3d-generating'` 的同步判断。执行 `match3d_compile_draft` 前切到生成页时,必须同时写 `selectionStageRef.current = 'match3d-generating'` 和 `setSelectionStage('match3d-generating')`;只调用 React state 会让 action 很快返回时读到旧 stage,表现为生成页已经 100% 但不进入试玩或结果页。拼图、大鱼吃小鱼、方洞挑战等同类生成页也遵循同一规则。
|
||||
|
||||
## 6. 自动保存与草稿恢复
|
||||
|
||||
点击 `生成抓大鹅草稿` 后,草稿存档创建与素材生成解耦:
|
||||
|
||||
1. 首次 compile 必须先写 `match3d_work_profile` 草稿行,即使后续卡在文本模型、图片生成、OSS 上传、Rodin 生成或下载转存任意阶段。
|
||||
1. 首次 compile 必须先写 `match3d_work_profile` 草稿行,即使后续卡在文本模型、图片生成、音频生成或 OSS 上传任意阶段。
|
||||
2. 失败态前端要重新读取 session / work detail,并刷新草稿作品架,保证用户离开生成页后仍能在草稿 Tab 找到这份作品。
|
||||
3. 重新生成时优先使用当前 session 的 `draft.profileId` 或 `publishedProfileId`,不得重新创建 session;后端读取同一 profile 的 `generated_item_assets_json` 后,只补齐缺失图片或缺失模型的阶段。
|
||||
4. 已有 `status = model_ready` 且带 `modelSrc` / `modelObjectKey` 的素材视为完成,不再重复调用 Rodin。
|
||||
3. 重新生成时优先使用当前 session 的 `draft.profileId` 或 `publishedProfileId`,不得重新创建 session;后端读取同一 profile 的 `generated_item_assets_json` 后,只补齐缺失图片或缺失音频的阶段。
|
||||
4. 已有 `status = image_ready` 且带 `imageViews[]` 或 `imageSrc/imageObjectKey` 的素材视为完成,不再重复生成图片。
|
||||
|
||||
抓大鹅结果页的基础信息自动保存继续调用 `PUT /api/runtime/match3d/works/{profileId}` 更新名称、题材、描述、标签、封面、消除数和难度;该保存不得清空 `generated_item_assets_json`。结果页 `3D素材` Tab 手动点击 `重新生成` 并拿到 GLB 下载文件后,必须把当前素材草稿重新序列化成 `generatedItemAssets` 并写回作品 profile;否则页面内预览会显示新模型,但试玩、发布和重进草稿仍会读取旧的空模型快照。SpacetimeDB `update_match3d_work` / `publish_match3d_work` 必须保留当前行的生成素材 JSON。
|
||||
抓大鹅结果页的基础信息自动保存继续调用 `PUT /api/runtime/match3d/works/{profileId}` 更新名称、题材、描述、标签、封面、消除数和难度;该保存不得清空 `generated_item_assets_json`。结果页 `素材配置 > 物品` 只在独立面板中预览和编辑当前素材,不再提供单项重新生成入口;删除单项或批量新增成功后,都必须把当前素材列表重新序列化成 `generatedItemAssets` 并写回作品 profile,否则试玩、发布和重进草稿会读取旧素材快照。SpacetimeDB `update_match3d_work` / `publish_match3d_work` 必须保留当前行的生成素材 JSON。
|
||||
|
||||
草稿架重进路径为:
|
||||
|
||||
@@ -136,22 +155,56 @@ Match3DWorkProfile / PlatformMatch3DGalleryCard
|
||||
草稿 Tab -> getMatch3DWorkDetail(profileId) -> Match3DResultView(profile.generatedItemAssets)
|
||||
```
|
||||
|
||||
因此 `map_match3d_work_summary_response` / `map_match3d_work_profile_response` 需要从 work profile snapshot 反序列化 `generated_item_assets_json` 并输出 `generatedItemAssets`。前端 `Match3DResultView` 的读取顺序为:有 `draft.generatedItemAssets` 时先用 draft 保留本次生成顺序和图片;同 `itemId` 在 `profile.generatedItemAssets` 中已有模型字段时,用 profile 模型字段补齐 draft;从草稿架重进没有 draft 时,用 `profile.generatedItemAssets`;两者都没有才回退到默认 3D 素材占位。
|
||||
因此 `map_match3d_work_summary_response` / `map_match3d_work_profile_response` 需要从 work profile snapshot 反序列化 `generated_item_assets_json` 并输出 `generatedItemAssets` 与顶层背景字段。前端 `Match3DResultView` 的读取顺序为:有 `draft.generatedItemAssets` 时先用 draft 保留本次生成顺序和图片;同 `itemId` 在 `profile.generatedItemAssets` 中已有 `imageViews[]` 或 `imageSrc/imageObjectKey` 时,用 profile 图片字段补齐 draft;背景资产同样必须从 profile 或 draft 的首个 `backgroundAsset` 保留到保存 payload;从草稿架重进没有 draft 时,用 `profile.generatedItemAssets`;两者都没有才回退到默认素材占位。
|
||||
|
||||
结果页 `作品信息` Tab 字段命名对齐拼图草稿:
|
||||
|
||||
1. `作品名称` 对应 Match3D `gameName`。
|
||||
2. `作品描述` 对应 Match3D `summary`,草稿生成默认空。
|
||||
3. `作品标签` 对应 Match3D `tags`,可由 AI 首次生成并允许用户继续编辑。
|
||||
4. 封面图与作品名称不再拆成左右两个大模块;封面只作为同一 Tab 内的可选上传入口,避免和作品基础信息割裂。
|
||||
4. 封面图与作品名称不再拆成左右两个大模块;封面只作为同一 Tab 内的可选入口,避免和作品基础信息割裂。点击封面图必须弹出独立编辑面板,不允许在当前作品信息面板下方展开。封面面板布局参考拼图创作页上传卡:移动端优先、左侧/上方为方形预览,右侧/下方为提示词与操作区。面板支持三类输入:本地上传图片、上传后开启 AI 重绘、直接引用 `物品素材` 或 `UI素材` 中已有图片作为封面或 AI 重绘参考图。AI 重绘通过 `api-server` 的 Match3D 作品封面生成接口调用 VectorEngine `gpt-image-2-all`,生成结果转存到 `generated-match3d-assets/{sessionId}/{profileId}/cover/{taskId}/cover.png` 后再写回 `coverImageSrc`;关闭 AI 重绘时只把选中的 Data URL 或 generated legacy path 写入封面字段。
|
||||
|
||||
`3D素材` 详情页只保留:
|
||||
结果页 `难度配置` Tab 取代旧 `玩法配置`,不再展示旧的分散输入项。该 Tab 必须与创作入口页使用同一组难度选项,并统一把原“类型素材图片 / 局内类型”等口径归一为 `物品种类`:
|
||||
|
||||
1. 模型预览区:优先加载 `modelSrc` 对应 GLB,缺失时加载 `modelObjectKey`,支持拖动旋转;没有模型时展示空预览。
|
||||
| 难度 | clearCount | difficulty | 总物品数 | 物品种类 |
|
||||
| ---- | ---------: | ---------: | -------: | -------: |
|
||||
| 轻松 | 8 | 2 | 24 | 3 |
|
||||
| 标准 | 12 | 4 | 36 | 9 |
|
||||
| 进阶 | 16 | 6 | 48 | 15 |
|
||||
| 硬核 | 21 | 8 | 63 | 21 |
|
||||
|
||||
预览区展示 `需要消除`、`总物品数`、`物品种类` 和 `已生成物品种类`。历史草稿如果保存的是旧 `clearCount/difficulty`,前端按 `clearCount` 精确命中优先、否则按 `difficulty` 就近归一到上述选项,并把归一后的数值保存回 profile。发布校验以 `generatedItemAssets[]` 中有 `imageViews[]` 或 `imageSrc/imageObjectKey` 的 `image_ready` 素材数量为准;试玩启动时用同一数量计算 `itemTypeCountOverride`,不足时自动降低,不修改草稿难度配置本身。
|
||||
|
||||
结果页 `素材配置` Tab 取代旧一级素材入口,并包含三个子 Tab:
|
||||
|
||||
1. `物品`:显示 2D 物品素材列表、五视角预览、素材名称、点击音效提示词和点击音效生成入口。
|
||||
2. `UI`:预览生成的竖屏游戏背景图,读取顺序为 draft 顶层背景、draft `generatedBackgroundAsset`、profile 顶层背景、profile `generatedBackgroundAsset`、`generatedItemAssets[].backgroundAsset`、本地参考图兜底。该页必须展示默认画面描述提示词,默认值来自草稿生成计划的 `backgroundPrompt` 或持久化 `backgroundAsset.prompt`;用户修改后点击重新生成,后端继续固定使用 `public/match3d-background-references/pot-fused-reference.png` 作为 VectorEngine `image` 参考图,并把新的 `backgroundAsset` 写回同一份 `generated_item_assets_json`。UI 子 Tab 还必须提供独立的运行态 UI 预览面板,直接用当前背景图模拟抓大鹅竖屏页面的顶部返回、倒计时、重开控件、锅状竞技区和底部托盘,不在 Tab 下方内联展开。
|
||||
3. `背景音乐`:承载原一级音乐 Tab 的背景音乐曲名、风格、生成进度和试听控件;背景音乐始终按纯音乐生成,前端不提供提示词输入。
|
||||
|
||||
旧一级 `音乐` Tab 删除;抓大鹅背景音乐入口只保留在 `素材配置 > 背景音乐`。
|
||||
|
||||
`素材配置 > 物品` 详情页只保留:
|
||||
|
||||
1. 五视角预览区:优先展示 `imageViews[]`,缺失时展示兼容字段 `imageSrc/imageObjectKey`。
|
||||
2. 素材名称输入。
|
||||
3. `重新生成` 按钮。
|
||||
3. 可编辑的点击音效提示词输入。
|
||||
4. 点击音效生成入口。
|
||||
|
||||
详情页不再展示参考图、用途、提示词、文生/图生切换、状态查询、下载列表、taskUuid 或 subscriptionKey。
|
||||
详情页不再展示参考图、用途、模型提示词、文生/图生切换、状态查询、下载列表、taskUuid 或 subscriptionKey。
|
||||
|
||||
`物品素材` 列表项点击必须弹出独立预览面板,不允许在列表右侧或列表下方内联展示。预览面板只承担查看五视角图片、编辑素材名称、编辑点击音效提示词和生成点击音效;不再展示 `重新生成` 按钮。列表项自身支持单项删除,删除后立即把剩余 `generatedItemAssets` 写回作品 profile。批量新增通过列表顶部按钮打开独立面板,面板内每个输入框只输入一个物品名称,`新增物品名称` 按钮追加一个输入框;提交后按输入框顺序清洗、去重并调用 Match3D 作品批量生图接口。生成进度同时显示在批量新增面板和 `素材配置 > 物品` 列表顶部,面板可关闭,后台生成继续推进,不阻塞封面、音频等其他生成操作。后端复用草稿生成的素材图、切图、OSS 上传和可选点击音效流程,但仅作用于本次新增名称,不重新生成已有物品,不新增 SpacetimeDB 表,最终仍写回同一份 `generated_item_assets_json`。
|
||||
|
||||
## 6.1 音频生成与扣费
|
||||
|
||||
抓大鹅结果页音频生成复用通用创作音频路由:
|
||||
|
||||
1. `素材配置 > 背景音乐` 默认读取首个 `generatedItemAssets[0].backgroundMusicTitle/backgroundMusicStyle`,用户可继续编辑曲名和风格;`backgroundMusicPrompt` 保留为空字符串兼容旧 JSON,生成请求固定传空 `prompt`。
|
||||
2. 物品点击音效默认读取对应 `generatedItemAssets[].soundPrompt`,用户可在 `素材配置 > 物品` 详情面板内编辑。
|
||||
3. 背景音乐与物品音效生成过程必须显示进度条;提交任务、等待生成、转存资产和完成分别推进到不同进度,不再只展示旋转图标。
|
||||
4. 音频生成完成后立即展示浏览器原生 audio 控件,支持试听。
|
||||
5. `POST /api/creation/audio/background-music/{task_id}/asset` 和 `POST /api/creation/audio/sound-effect/{task_id}/asset` 在真正拿到音频并转存资产前,由后端按 `taskId + 资产槽位` 幂等预扣 `10` 光点;任务仍在处理中时不扣费。资产下载、OSS 转存或资产绑定失败时后端自动退款。前端只展示生成按钮和进度,不自行计算或写入钱包。
|
||||
|
||||
入口页 `生成音效` Toggle 复用同一扣费与资产绑定规则。默认关闭,关闭时草稿生成阶段不产生音频任务也不扣除音频光点;开启时每个首批物品的点击音效按单独任务和单独 `match3d_click_sound` 资产槽位扣费。音效生成失败不阻断草稿结果页进入,失败素材保留 `soundPrompt`,用户可在结果页物品详情面板手动重试。
|
||||
|
||||
## 7. 验收
|
||||
|
||||
@@ -173,4 +226,4 @@ cargo check -p spacetime-client --manifest-path server-rs\Cargo.toml
|
||||
cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml
|
||||
```
|
||||
|
||||
真实草稿生成需要本地私密环境配置 `VECTOR_ENGINE_API_KEY`、`HYPER3D_API_KEY` 和 OSS 访问变量。后端改动后使用 `npm run api-server` 启动,并检查 `/healthz`。
|
||||
真实草稿生成需要本地私密环境配置 `VECTOR_ENGINE_API_KEY` 和 OSS 访问变量;开启音频生成还需要对应音频上游配置。后端改动后使用 `npm run api-server` 启动,并检查 `/healthz`。
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
>
|
||||
> 2026-05-10 更新:抓大鹅入口页对齐拼图入口页,直接嵌入创作页模板 Tab。入口表单不再展示参考图、消除次数输入、难度数值滑杆和题材/物品/难度摘要框,仅保留题材主题大输入框和难度选项。难度选项负责派生 `clearCount` 与 `difficulty`,生成按钮必须展示 `消耗20光点`。
|
||||
>
|
||||
> 2026-05-10 补充:入口页新增 `3D素材风格` 横向滑动选择,首批风格参考图通过 VectorEngine `gpt-image-2-all` 生成并保存到 `public/match3d-style-references/`。最后一个选项为 `自定义`,点击后弹出独立面板填写画风描述。
|
||||
> 2026-05-12 补充:入口页风格选择收敛为 `2D素材风格`,首批常见 2D 素材风格参考图通过 `npm run assets:match3d-style-references -- --live` 调用 VectorEngine `gpt-image-2-all` 生成并保存到 `public/match3d-style-references/`。最后一个选项为 `自定义`,点击后弹出独立面板填写画风描述。
|
||||
|
||||
## 1. 阶段边界
|
||||
|
||||
@@ -40,11 +40,12 @@ badge: 可创建
|
||||
|
||||
创作页 `选择模板` Tab 中切换到 `抓大鹅` 时,直接渲染该表单,不创建会话,也不跳到独立工作台。点击生成后才创建 Match3D 会话并执行 `match3d_compile_draft`。
|
||||
|
||||
表单只展示三个输入块:
|
||||
表单只展示四个输入块:
|
||||
|
||||
1. `想做一个什么题材的抓大鹅?`:大文本输入框,收集 `themeText`。
|
||||
2. `3D素材风格`:横向滑动风格卡,选择会写入 `assetStyleId`、`assetStyleLabel` 与 `assetStylePrompt`。
|
||||
2. `2D素材风格`:横向滑动风格卡,选择会写入 `assetStyleId`、`assetStyleLabel` 与 `assetStylePrompt`。
|
||||
3. `难度`:四个选项按钮,选项内部派生消除次数和难度数值。
|
||||
4. `生成音效`:Toggle,默认关闭,开启后提交 `generateClickSound=true`。
|
||||
|
||||
当前难度映射固定为:
|
||||
|
||||
@@ -52,7 +53,7 @@ badge: 可创建
|
||||
轻松 -> clearCount 8, difficulty 2
|
||||
标准 -> clearCount 12, difficulty 4
|
||||
进阶 -> clearCount 16, difficulty 6
|
||||
硬核 -> clearCount 20, difficulty 8
|
||||
硬核 -> clearCount 21, difficulty 8
|
||||
```
|
||||
|
||||
入口页不再上传参考图,提交 payload 中 `referenceImageSrc` 固定为 `null`。如果从旧会话或旧草稿恢复,前端只根据已有 `difficulty` 选择最接近的难度选项,并按当前选项重新派生 `clearCount` 与 `difficulty`。
|
||||
@@ -60,7 +61,7 @@ badge: 可创建
|
||||
内置风格选项为:
|
||||
|
||||
```text
|
||||
黏土手作 / 低多边形 / 玩具塑料 / 木质雕刻 / 体素积木 / 金属机甲 / 自定义
|
||||
扁平图标 / 赛璐璐卡通 / 像素复古 / 手绘水彩 / 贴纸描边 / 厚涂图标 / 自定义
|
||||
```
|
||||
|
||||
自定义风格必须在弹出面板中填写描述后才能应用。入口表单必须在移动端创作页可视区内完成题材、风格、难度和生成按钮的展示,页面自身不产生纵向滚动;风格卡只允许横向滑动。
|
||||
|
||||
@@ -275,6 +275,12 @@ type Match3DAutoSaveState = 'idle' | 'saving' | 'saved' | 'error';
|
||||
|
||||
F2 不实现运行态本身;只冻结结果页如何发起试玩。
|
||||
|
||||
### 12.1 生成完成自动试玩补充(2026-05-12)
|
||||
|
||||
抓大鹅表单生成草稿完成后,如果用户仍停留在 `match3d-generating` 进度页,前端应立即用刚生成的 `Match3DWorkProfile` 启动试玩,并把运行态返回目标设置为 `match3d-result`。试玩过程中点击左上角返回时,进入同一份抓大鹅草稿结果页查看与编辑。
|
||||
|
||||
该自动试玩只响应当前等待中的生成页;如果用户已经返回草稿 Tab 或切到其它页面,后台生成完成只更新草稿可见状态,不主动切屏。自动启动失败时,仍保留结果页草稿作为兜底入口。
|
||||
|
||||
---
|
||||
|
||||
## 13. 发布接口
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# 平台移动端推荐页卡片与滑动热区布局 2026-05-12
|
||||
|
||||
## 背景
|
||||
|
||||
移动端推荐页承载嵌入式作品运行态,顶部品牌栏和底部导航上方留白会压缩首屏可玩区域。推荐页同时需要纵向切换作品,但不能让切换手势覆盖作品运行态内部的点击、拖拽、滑动热区。
|
||||
|
||||
## 落地口径
|
||||
|
||||
1. 仅推荐页隐藏移动端顶部品牌栏,发现、创作、草稿、我的页继续保留原顶部结构。
|
||||
2. 推荐页外层使用独立 shell class,把原顶部区域和底部导航上方额外留白让给推荐卡片。
|
||||
3. 推荐页运行态画面保持独立可交互区域,不挂平台切换作品的 pointer 手势。
|
||||
4. 切换作品的纵向手势只绑定在卡片底部作品信息区;底部信息区可以扩大触控高度,但不得绝对定位覆盖运行态画面。
|
||||
5. 点赞、分享、改造按钮继续阻止 pointer 事件冒泡,避免按钮点击误触发切换作品。
|
||||
|
||||
## 验收
|
||||
|
||||
1. 手机竖屏进入推荐页时,首屏不显示顶部品牌标题。
|
||||
2. 推荐卡片上沿贴近可视区域顶部,下沿贴近底部导航上方。
|
||||
3. 在作品运行态画面内点击、拖拽或滑动,只触发作品自身交互。
|
||||
4. 在底部作品信息区上下滑动,可以切换推荐作品。
|
||||
5. 点赞、分享、改造按钮可正常点击,不触发作品切换。
|
||||
@@ -6,6 +6,12 @@
|
||||
|
||||
2026-05-03 后入口进一步收口为画面描述直创:入口表单只保留画面描述、参考图和图片模型选择;作品名称、作品描述、作品标签全部进入结果页补全。若本文件早期段落仍提到入口必填作品名称或作品描述,以 `PUZZLE_PICTURE_ONLY_CREATION_AND_AI_TAGS_2026-05-03.md` 为准。
|
||||
|
||||
## 首访新手引导隐藏
|
||||
|
||||
2026-05-12 起,平台首访不再自动进入 `puzzle-onboarding` 新手引导步骤。前端应直接停留在平台入口;旧新手引导面板、生成接口和保存接口暂时保留为休眠代码,后续只有在产品明确恢复时才重新打开分流开关。
|
||||
|
||||
首访隐藏不写入 `genarrative.puzzle-onboarding.first-visit.v1`,避免把“引导未展示”误记录成玩家已主动完成或跳过。
|
||||
|
||||
## 入口表单
|
||||
|
||||
### 2026-05-03 画面描述直创补充
|
||||
@@ -87,10 +93,27 @@
|
||||
|
||||
## 结果页
|
||||
|
||||
拼图草稿结果页分为两个 Tab:
|
||||
拼图草稿结果页分为四个 Tab:
|
||||
|
||||
1. 拼图关卡列表:默认展示草稿生成出的第一关。列表项参考 RPG 草稿卡片样式,显示画面图、关卡名称和轻量状态。支持新增关卡、删除关卡。点击列表项进入独立关卡详情页,不在列表项下方展开。关卡详情页可编辑关卡名称、画面描述、生成或重新生成画面,并在已有正式图后支持关卡测试。
|
||||
2. 作品信息:展示并编辑作品名称、作品描述、作品标签。
|
||||
3. UI:展示并编辑拼图运行态 UI 背景提示词,支持基于作品名称、作品描述、标签和首关信息重新生成 9:16 UI 背景图。生成 action 为 `generate_puzzle_ui_background`,图片生成在 `api-server` 中读取 `public/ui-previews/puzzle-image-compact-ui-2026-05-08.png` 作为非拼图 UI 背景参考图,并调用 VectorEngine `gpt-image-2-all` 的 `9:16` 图片生成链路。生成结果写入首关 `levels_json` 的 `uiBackgroundPrompt`、`uiBackgroundImageSrc`、`uiBackgroundImageObjectKey`,不新增 SpacetimeDB 表字段。
|
||||
4. 音乐:编辑并生成背景音乐,音乐资产暂存到首关 `levels_json[0].backgroundMusic`。
|
||||
|
||||
### 2026-05-12 UI 背景生成补充
|
||||
|
||||
1. UI 背景图只生成拼图棋盘以外的运行态背景与 UI 容器层次,提示词必须要求中央正方形拼图区和外部 UI 背景之间有明确描边、容器或留白边界。
|
||||
2. UI 背景图不得生成文字、水印、按钮文字、数字、拼图碎片、完整拼图图像或教程浮层,避免与真实拼图图块和运行态 HUD 混淆。
|
||||
3. 结果页 UI Tab 支持直接修改提示词并重新生成;点击生成前会把本地首关 `uiBackgroundPrompt` 同步进 `levelsJson`,使自动保存尚未完成时后端仍能拿到最新提示词。
|
||||
4. `api-server` 负责读取参考图、拼接生成 prompt、调用 VectorEngine、下载并转存 OSS;SpacetimeDB 只通过 `save_puzzle_ui_background` procedure 保存结果,不做外部 I/O。
|
||||
5. 拼图运行态读取 `currentLevel.uiBackgroundImageSrc` 渲染为全屏背景;无 UI 背景图时继续使用原封面模糊背景兜底。棋盘本身仍由正式拼图图生成,不能把 UI 背景当作拼图切块来源。
|
||||
|
||||
### 2026-05-12 草稿生成完成自动试玩补充
|
||||
|
||||
1. 玩家停留在拼图草稿生成进度页等待 `compile_puzzle_draft` 完成时,前端必须先把最新 session / profile 记为草稿结果页状态,再自动启动本地拼图试玩。
|
||||
2. 自动试玩的返回目标固定为 `puzzle-result`。玩家在试玩过程中点击左上角返回后,应进入同一份拼图草稿结果页继续查看和编辑。
|
||||
3. 自动试玩只在当前仍处于 `puzzle-generating` 时触发;若玩家已返回草稿 Tab 或切到其它页面,后台生成完成只标记草稿已生成,不得强行抢屏进入试玩。
|
||||
4. 若自动启动试玩失败,前端保留草稿结果页作为兜底查看入口,并展示已有错误态,不应丢失已生成草稿。
|
||||
|
||||
### 2026-04-30 关卡列表卡片交互补充
|
||||
|
||||
@@ -107,7 +130,7 @@
|
||||
6. api-server 处理 `generate_puzzle_images` 时,若 action 带有 `levelsJson`,必须用这份关卡快照覆盖本次生成的草稿关卡视图后再定位 `levelId`。若请求明确传入 `levelId` 但关卡列表中不存在该关卡,必须返回错误,不得静默回退第一关。
|
||||
7. 历史拼图素材入口和本地上传参考图入口统一收口到 `画面图` 图卡右下角,避免 `画面描述` 输入区同时承载文本编辑和素材入口;无正式图时也展示空图态图卡。
|
||||
8. 历史拼图素材列表必须由服务端按当前登录账号过滤,只返回 `asset_kind = puzzle_cover_image` 且 `owner_user_id = 当前账号` 的资产;不得依赖前端过滤,也不得展示其他账号素材。
|
||||
9. `画面图` 图卡本身就是上传热区,详情页不再保留右下角独立“上传参考图”按钮;历史入口统一使用带 `History` 图标和 `历史` 小字的按钮。入口页空图态的“点击上传拼图图片”只作为图卡内轻量提示,不使用胶囊按钮、边框或背景样式。
|
||||
9. `画面图` 图卡本身就是上传热区,详情页不再保留右下角独立“上传参考图”按钮;历史入口统一使用带 `History` 图标和 `历史` 小字的按钮。入口页历史按钮固定在图片上传区域右上角;空图态只展示“上传图片/填写画面描述”轻量提示,不再展示额外规则说明文案。
|
||||
|
||||
### 2026-05-10 关卡生图交互补充
|
||||
|
||||
@@ -128,6 +151,7 @@
|
||||
1. 从拼图创作入口只能看到作品名称、作品描述、画面描述和参考图上传,不出现 Agent 聊天输入、补齐设定、锚点问答。
|
||||
2. 点击确认后进入拼图草稿生成进度页,并自动完成草稿编译、首图生成、正式图选择。
|
||||
3. 首图生成请求使用玩家画面描述作为 prompt;上传参考图时走图生图;作品详情页展示玩家作品描述。
|
||||
4. 结果页包含“拼图关卡”和“作品信息”两个 Tab;关卡列表默认至少一关,支持新增、删除和进入关卡详情。
|
||||
4. 结果页包含“拼图关卡”“作品信息”“UI”“音乐”四个 Tab;关卡列表默认至少一关,支持新增、删除和进入关卡详情。
|
||||
5. 关卡详情页支持生成或重新生成画面;已有正式图后显示吸底“关卡测试”入口。
|
||||
6. 发布、作品测试、自动保存作品名称、作品描述、作品标签和关卡列表仍可用。
|
||||
7. UI Tab 可修改提示词并重新生成背景图;生成后运行态应显示 `uiBackgroundImageSrc`,且拼图棋盘区域和 UI 背景区域有明确边界。
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
# 拼图与抓大鹅结果页音乐 Tab 2026-05-11
|
||||
# 拼图与抓大鹅结果页音乐入口 2026-05-11
|
||||
|
||||
## 1. 范围
|
||||
|
||||
本方案把 VectorEngine 音频生成能力从视觉小说结果页扩展到拼图与抓大鹅结果页:
|
||||
|
||||
1. 拼图结果页新增 `音乐` Tab,支持通过 Suno 生成作品背景音乐。
|
||||
2. 抓大鹅结果页新增 `音乐` Tab,支持通过 Suno 生成作品背景音乐。
|
||||
3. 抓大鹅 `3D素材` Tab 支持为每个生成物体通过 Vidu 生成点击音效。
|
||||
2. 抓大鹅结果页在 `素材配置 > 背景音乐` 中支持通过 Suno 生成作品背景音乐;旧一级 `音乐` Tab 已删除。
|
||||
3. 抓大鹅 `素材配置 > 物品` 支持为每个生成物体通过 Vidu 生成点击音效。
|
||||
4. 拼图运行态与抓大鹅运行态内置默认关卡音频配置:通用点击音效 `/audio/ui-click-soft.wav`、过关音效 `/audio/ui-level-clear.wav`、倒计时临界音效 `/audio/ui-countdown-warning.wav`。
|
||||
5. 拼图和抓大鹅草稿生成阶段会自动生成背景音乐并转存 OSS,结果页继续支持试听和重新生成。
|
||||
|
||||
本轮不新增 SpacetimeDB 表,不修改表字段,不把供应商密钥下发到前端。
|
||||
|
||||
@@ -28,8 +30,9 @@
|
||||
3. 下载音频字节。
|
||||
4. 写入 OSS 私有对象。
|
||||
5. 确认 `asset_object` 并绑定 `asset_entity_binding`。
|
||||
6. 音频真正可下载并准备转存时,按 `taskId + assetKind + entityId + slot` 幂等扣除 `10` 光点;任务仍在处理中不扣费,转存或资产绑定失败自动退款。
|
||||
|
||||
视觉小说原路由保持兼容,内部继续复用同一套提交、轮询、转存逻辑。
|
||||
通用背景音乐提交允许 `prompt = ""`。拼图和抓大鹅草稿生成都按纯音乐处理:后端提交 Suno 时固定带 `make_instrumental = true`,只用 `title` 和 `tags` 约束作品气质,不把歌词或规则描述写入 prompt。视觉小说原路由保持兼容,内部继续复用同一套提交、轮询、转存逻辑。
|
||||
|
||||
## 3. 数据落点
|
||||
|
||||
@@ -50,7 +53,7 @@
|
||||
}
|
||||
```
|
||||
|
||||
运行态后续可从当前关卡快照或作品详情读取该字段作为背景音乐源;若字段为空,继续使用现有程序化背景音乐兜底。
|
||||
草稿生成阶段在生成首关作品题目后,使用作品题目作为 Suno `title`,`prompt` 为空,`tags` 使用轻快、拼图、循环、instrumental。生成失败只记录 warning,不阻断草稿进入结果页。运行态从 `PuzzleRuntimeLevelSnapshot.backgroundMusic.audioSrc` 读取该字段作为背景音乐源,游戏开始后自动循环播放;若字段为空,保持静默背景音乐兜底。
|
||||
|
||||
### 3.2 抓大鹅
|
||||
|
||||
@@ -59,7 +62,7 @@
|
||||
1. 作品背景音乐暂存到第一个 `Match3DGeneratedItemAsset.backgroundMusic`,表示当前 work profile 的作品级背景音乐。
|
||||
2. 单个物体点击音效保存到对应 `Match3DGeneratedItemAsset.clickSound`。
|
||||
|
||||
这是一个兼容性折中:当前 Match3D work profile 没有 work-level metadata 字段,而 `generated_item_assets_json` 已经随作品详情、草稿架、运行态入口稳定传递。后续若新增正式作品 metadata 表达,应迁移 `backgroundMusic` 到作品级字段。
|
||||
这是一个兼容性折中:当前 Match3D work profile 没有 work-level metadata 字段,而 `generated_item_assets_json` 已经随作品详情、草稿架、运行态入口稳定传递。草稿生成阶段的文本计划在生成物品名称时同步生成 `backgroundMusic.title` 作为背景音乐名称,`backgroundMusic.prompt` 固定为空字符串,后端用该名称作为 Suno `title` 并生成纯音乐。后续若新增正式作品 metadata 表达,应迁移 `backgroundMusic` 到作品级字段。
|
||||
|
||||
## 4. 前端交互
|
||||
|
||||
@@ -68,6 +71,19 @@
|
||||
1. `音乐` Tab 只展示必要输入、生成按钮、状态与音频预览,不展示供应商规则说明。
|
||||
2. 生成完成后立即写回本地草稿状态,并触发既有保存链路或专用保存接口。
|
||||
3. 抓大鹅每个物体音效生成入口放在对应素材详情面板内,不在列表下方展开大段配置。
|
||||
4. 抓大鹅物体音效提示词允许在素材详情面板内编辑;背景音乐只允许在 `素材配置 > 背景音乐` 编辑曲名和风格,生成请求固定使用空 `prompt`。
|
||||
5. 背景音乐和物体音效生成期间都显示进度条,生成完成后展示 audio 控件试听。
|
||||
6. 背景音乐重新生成只要求曲名非空;重新生成继续按纯音乐提交,`prompt = ""`。
|
||||
|
||||
### 4.1 运行态默认点击音效
|
||||
|
||||
1. `src/services/runtimeAudioFeedback.ts` 提供通用关卡音频配置 `DEFAULT_RUNTIME_LEVEL_AUDIO_CONFIG`,内部缓存 `HTMLAudioElement`,失败时静默兜底,不阻塞玩法交互。
|
||||
2. 拼图点击、按压或拖拽拼块时播放默认通用点击音效,并继续保留既有触觉反馈。
|
||||
3. 抓大鹅点击物体时优先播放该物体绑定的 `clickSound.audioSrc`;若作品没有生成物体点击音效,则回退播放 `/audio/ui-click-soft.wav`。
|
||||
4. 拼图关卡 `currentLevel.status` 首次进入 `cleared` 时播放默认过关音效;抓大鹅 run `status` 首次进入 `won` 时播放默认过关音效。
|
||||
5. 拼图使用 `displayRemainingMs`,抓大鹅使用 `timeLeftMs`。当剩余时间进入默认阈值 `5_000ms` 后,每个自然秒桶最多播放一次倒计时音效,归零后停止。
|
||||
6. 默认关卡音效跟随现有 `musicVolume` 设置,不新增独立音量 UI,不在运行态界面增加说明文案。
|
||||
7. 拼图和抓大鹅运行态背景音乐同样跟随 `musicVolume`,读取 generated legacy path 时先换签,再交给隐藏 `<audio loop preload="auto">` 自动播放;浏览器拒绝自动播放时静默失败,不阻断游戏交互。
|
||||
|
||||
## 5. 验收
|
||||
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
- 亮色主题下上传卡片必须使用白色或暖浅色卡面,不得显示整块黑色底。
|
||||
- 上传卡片固定为 1:1 正方形,避免拼图主画面在首屏出现非正方形预期。
|
||||
- 移动端表单主体不可依赖纵向拖动查看核心控件;玩法卡带、描述输入框和底部生成按钮占位固定后,上传卡片必须按剩余高度等比例缩放,仍保持 1:1。
|
||||
- 上传卡片底部不再叠加文件名 bar;`点击上传拼图图片` 入口必须显示在拼图画面卡片内部。
|
||||
- 上传卡片底部不再叠加文件名 bar;`上传图片/填写画面描述` 入口必须显示在拼图画面卡片内部。
|
||||
- 上传卡片上方固定展示 `拼图画面` 标题。
|
||||
- 无图状态下,上传卡片内部、`点击上传拼图图片` 按钮上方展示 11px 级辅助提示 `若没有合适的图片可以通过填写画面描述生成画面`,提示用户可不上传图片、直接填写画面描述生成画面。
|
||||
- 上传成功后,`AI重绘` 开关显示在卡片左下角,右上角显示移除拼图图片图标按钮;移除必须先弹出二次确认。
|
||||
- 叠在上传卡片上的 `AI重绘`、移除图标和上传入口必须和卡面保持足够对比,避免浅色主题重映射后不可读。
|
||||
- 无图状态下,上传卡片内部只保留 `上传图片/填写画面描述` 轻量提示,不再展示额外规则说明文案。
|
||||
- 历史素材按钮固定在上传卡片右上角;上传成功后,`AI重绘` 开关显示在卡片左下角,移除拼图图片图标按钮显示在卡片左上角;移除必须先弹出二次确认。
|
||||
- 叠在上传卡片上的历史按钮、`AI重绘`、移除图标和上传入口必须和卡面保持足够对比,避免浅色主题重映射后不可读。
|
||||
3. 画面描述输入框高度固定,移动端保持约 `6rem`,不随剩余屏幕高度变大或变小,避免把上传参考图和提交区挤出首屏。
|
||||
4. 创作 Tab 顶部玩法卡带的选中态只使用卡内暗色蒙版、细描边或内描边,不使用粉色外发光、外扩阴影或会从卡片边缘突出的高饱和边。
|
||||
5. 输入区保留:
|
||||
@@ -93,7 +93,7 @@ size = 1024x1024
|
||||
拼图入口上传区左下角展示 `AI重绘` 开关,默认打开;未上传拼图图片前不显示开关,上传成功后才显示。上传成功后右上角展示移除图标按钮,点击后必须二次确认。
|
||||
|
||||
1. `AI重绘=true`
|
||||
- 上传区文案为 `点击上传拼图图片`,上传图作为生图参考图。
|
||||
- 上传区文案为 `上传图片/填写画面描述`,上传图作为生图参考图。
|
||||
- 未上传图片时,输入框标题为 `画面描述`。
|
||||
- 已上传图片时,输入框标题为 `画面AI重绘要求(提示词)`。
|
||||
- 展示图片模型切换。
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
## 文档列表
|
||||
|
||||
- [PUBLIC_WORK_DETAIL_NOT_FOUND_RECOVERY_2026-05-11.md](./PUBLIC_WORK_DETAIL_NOT_FOUND_RECOVERY_2026-05-11.md):记录直接访问公开作品详情深链时作品不存在或已下架的回首页修复,避免关闭提示后停在 `work-detail` 空状态白屏。
|
||||
- [PLATFORM_MOBILE_RECOMMEND_CARD_SAFE_SWIPE_LAYOUT_2026-05-12.md](./PLATFORM_MOBILE_RECOMMEND_CARD_SAFE_SWIPE_LAYOUT_2026-05-12.md):冻结移动端推荐页隐藏顶部品牌栏、扩大推荐卡片可用高度,以及只在底部作品信息区承接切换作品手势的布局口径。
|
||||
- [CHILD_MOTION_DEMO_WARMUP_IMPLEMENTATION_SPEC_2026-05-09.md](./CHILD_MOTION_DEMO_WARMUP_IMPLEMENTATION_SPEC_2026-05-09.md):冻结儿童动作识别互动玩法 Demo 固定热身关的开发落地规格,覆盖横屏展示、摄像头背景虚化、角色剪影、绿色圆环 2 秒保持、动作教学、当前会话内空间边界记录和后续关卡安全暂停规则。
|
||||
- [RUNTIME_INPUT_DEVICE_ABSTRACTION_2026-05-10.md](./RUNTIME_INPUT_DEVICE_ABSTRACTION_2026-05-10.md):记录运行态输入设备抽象层,明确鼠标、触控、mocap 等设备统一归一为通用拖拽语义,玩法组件只负责解释目标和落点。
|
||||
- [RUST_WORKSPACE_DEPENDENCY_CONSOLIDATION_2026-05-07.md](./RUST_WORKSPACE_DEPENDENCY_CONSOLIDATION_2026-05-07.md):记录 `server-rs` Cargo 依赖集中配置口径,第三方版本和 workspace 内部 crate path 统一维护在根 `server-rs/Cargo.toml`,成员 crate 只保留 feature/optional 差异;同时冻结 `shared-contracts` 不得反向依赖 `platform-*`,避免 SpacetimeDB 模块发布时拉入 `wasm-bindgen`。
|
||||
@@ -16,8 +17,8 @@
|
||||
- [RECOMMEND_RUNTIME_AUTH_FAILURE_ISOLATION_FIX_2026-05-09.md](./RECOMMEND_RUNTIME_AUTH_FAILURE_ISOLATION_FIX_2026-05-09.md):记录平台推荐页自动加载作品、公开拼图作品完整运行态、平台 bootstrap 私有投影刷新和展示层图片换签的局部请求 `401` 不应扩散成全局登出的修复,覆盖 `authImpact: local` 请求策略、推荐页 embedded 运行态启动、拼图开局/排行榜/下一关和回归测试。
|
||||
- [AUTH_GATE_LOGIN_RACE_GUARD_FIX_2026-05-09.md](./AUTH_GATE_LOGIN_RACE_GUARD_FIX_2026-05-09.md):记录 `AuthGate` 登录成功后又被旧 hydrate 覆盖回未登录态的竞态根因、版本号保护修复与回归测试。
|
||||
- [HYPER3D_RODIN_GEN2_MODEL_GENERATION_2026-05-08.md](./HYPER3D_RODIN_GEN2_MODEL_GENERATION_2026-05-08.md):记录 Hyper3D Rodin Gen-2 文生 3D 模型、图生 3D 模型、状态查询和下载列表的后端代理、环境变量、请求约束与验收边界。
|
||||
- [MATCH3D_RODIN_ASSET_TAB_2026-05-10.md](./MATCH3D_RODIN_ASSET_TAB_2026-05-10.md):记录抓大鹅结果页多 Tab 改造与 Rodin 3D 素材列表/详情页的前端接入边界,明确首版只复用 Hyper3D 后端代理,不新增表或正式资产写入。
|
||||
- [MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md](./MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md):冻结抓大鹅草稿生成过程页、3 件物品名称生成、VectorEngine 1:1 素材图、n*n 切图、并行 Rodin 图生 3D 与 OSS 回填草稿页的端到端边界。
|
||||
- [MATCH3D_RODIN_ASSET_TAB_2026-05-10.md](./MATCH3D_RODIN_ASSET_TAB_2026-05-10.md):历史记录抓大鹅 Rodin 3D 素材列表/详情页的早期接入边界;当前新草稿不再调用 Rodin 或生成 GLB。
|
||||
- [MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md](./MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md):冻结抓大鹅草稿生成过程页、按题材生成 UI 背景提示词、VectorEngine 2D 五视角素材、UI 背景图、背景音乐和 OSS 回填草稿页的端到端边界。
|
||||
- [VOLCENGINE_SPEECH_STREAMING_INTEGRATION_2026-05-08.md](./VOLCENGINE_SPEECH_STREAMING_INTEGRATION_2026-05-08.md):记录火山引擎大模型 ASR 双向流式、TTS WebSocket 双向流式和 TTS HTTP SSE 单向流式的后端代理、环境变量、协议帧和验收边界。
|
||||
- [VECTOR_ENGINE_AUDIO_GENERATION_SUNO_VIDU_2026-05-08.md](./VECTOR_ENGINE_AUDIO_GENERATION_SUNO_VIDU_2026-05-08.md):记录视觉小说结果页接入 VectorEngine Suno 文生背景音乐与 Vidu 文生音效的接口、环境变量、后端路由、OSS 资产回写和前端弹层交互边界。
|
||||
- [PROFILE_FEEDBACK_BACKEND_INTEGRATION_2026-05-08.md](./PROFILE_FEEDBACK_BACKEND_INTEGRATION_2026-05-08.md):冻结“我的”页签帮助与反馈入口的后端接入方案,覆盖 `POST /api/profile/feedback`、`profile_feedback_submission`、凭证图片 Data URL 校验和前端预览/提交边界。
|
||||
|
||||
Reference in New Issue
Block a user