1
This commit is contained in:
@@ -32,15 +32,15 @@
|
||||
- 数据来源沿用 `featuredEntries + latestEntries` 去重后的公开作品列表。
|
||||
- 首个可运行作品自动进入推荐页内嵌运行态,主视口不再展示作品封面卡。
|
||||
- 主视口占据顶部栏与作品信息区之间的主要空间,使用平台主题 token 控制运行容器背景、边框、阴影、加载态文字和错误态按钮;亮色主题不得残留纯黑底白字加载块。
|
||||
- 主视口下方展示当前作品的游玩、点赞、评论/改造等紧凑指标、作者头像、作者名与作品名,不写规则说明类文案。
|
||||
- 主视口下方展示当前作品操作区与基础信息:作者头像、作者名、作品名、点赞按钮、点赞数、分享按钮、改造按钮;不展示游玩次数、评论入口或额外心形收藏入口,不写规则说明类文案。
|
||||
- 作品信息区不再提供详情箭头或点击详情入口;点击该区域无效,上滑切换下一个推荐作品,下滑切换上一个推荐作品。
|
||||
- 推荐页切换参考短视频上下滑交互:当前运行画布位于中间,上一个/下一个作品的封面预览提前挂载在画布上下屏幕外;拖动作品信息区时三屏轨道跟随位移,松手后完成切换或回弹。
|
||||
- 用户停留在推荐页时,底部当前 Tab 从“推荐”切换为“下一个”,图标使用向下的倒三角 / 双下箭头语义,点击后切换下一个推荐作品。
|
||||
- 推荐页不再展示额外的底部作品切换块;当前作品的完整操作继续收敛在详情页和作品自身运行态中。
|
||||
- 推荐页不再展示额外的底部作品切换块;当前作品的点赞、分享与改造在推荐页底部操作区直接完成,其它作品深层操作继续由详情页和作品自身运行态承接。
|
||||
- 推荐页嵌入运行只调整平台外壳容器、主题注入和玩法壳层配色,不改写作品数据、关卡设定、道具设定或图片资产。
|
||||
- 屏幕外预览只允许使用公开封面、作品名和类型,不提前启动其它作品 run,不触发道具、计时、存档或作品数据变更。
|
||||
- 推荐页嵌入拼图玩法时隐藏拼图左上返回按钮,并在设置弹层中隐藏退出入口;作品切换前对当前拼图 run 执行既有“保存并退出”收口,正式 run 的交互状态以已写回后端的快照为准。
|
||||
- 点赞、改造、复制作品号等完整操作继续收敛在详情页,详情入口由作品自身运行态或其它广场列表承接,推荐页作品信息区只负责展示和上下滑切换。
|
||||
- 底部操作区移除游玩次数、评论功能和额外心形收藏入口;点赞按钮可直接点击并刷新公开读模型返回的点赞数,分享按钮复制作品号与公开作品链接,改造按钮只保留改造 icon 并复用既有改造入口。操作按钮只响应自身点击,按钮外的信息区点击无效,拖动时仍跟随整张推荐卡上下切换作品。
|
||||
- 无数据、加载中、启动失败和暂不支持内嵌运行的作品沿用短状态文案。
|
||||
|
||||
桌面端仍保持现有首页布局,只把一级导航文案从“首页”改为“推荐”。
|
||||
@@ -93,6 +93,7 @@
|
||||
11. 仅推荐页嵌入拼图态隐藏返回与设置内退出入口;详情页、新手引导和普通拼图运行态继续保留原有退出能力。
|
||||
12. 推荐页切换作品前,如果当前作品是拼图,必须先执行当前拼图 run 的退出收口,再启动下一作品。
|
||||
13. 已登录推荐页的上/下滑切换必须展示相邻作品的屏幕外预览,并在拖动不足阈值时回弹;相邻预览不得提前启动玩法运行态。
|
||||
14. 推荐页底部区域不展示游玩次数、评论入口和额外心形收藏入口;点赞、分享和改造都使用 icon 按钮,点赞数紧邻点赞按钮展示。
|
||||
|
||||
## 8. 2026-05-07 未登录三栏补充
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
1. 玩家需要优先依赖画面主体、构图和色块识别位置。
|
||||
2. 编号覆盖会削弱“完整图片被逐步复原”的视觉奖励。
|
||||
3. 合成后的拼图块只保留原图切片、外轮廓描边和必要的拖拽层级,不叠加额外的色块、暗层或蒙版,避免破坏原图识别。
|
||||
3. 单块和合成后的拼图块只保留原图切片、外轮廓描边和必要的拖拽层级,不叠加额外的色块、暗层或蒙版,避免破坏原图识别。
|
||||
|
||||
### 3. 设置能力
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# AI 原生抓大鹅 Match3D 玩法创作工具与玩法系统 PRD
|
||||
|
||||
更新时间:`2026-04-30`
|
||||
更新时间:`2026-05-10`
|
||||
|
||||
## 0. 文档目的
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
## 1. 一句话定义
|
||||
|
||||
让百梦主通过 Agent 对话确认题材、需要消除次数和难度,系统编译出一个可试玩、可发布的单局抓大鹅玩法作品;玩家在 `10` 分钟倒计时内点击圆形空间中可见物品,把物品放入下方 `7` 格备选栏,每凑齐 `3` 个同物品 id 自动消除,最终清空圆形空间内全部物品即胜利。
|
||||
让百梦主在创作页通过表单确认题材主题和难度选项,系统根据难度选项派生需要消除次数与难度数值,并编译出一个可试玩、可发布的单局抓大鹅玩法作品;玩家在 `10` 分钟倒计时内点击圆形空间中可见物品,把物品放入下方 `7` 格备选栏,每凑齐 `3` 个同物品 id 自动消除,最终清空圆形空间内全部物品即胜利。
|
||||
|
||||
---
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
```text
|
||||
平台创作入口
|
||||
-> 选择“抓大鹅”
|
||||
-> Agent 对话确认题材、需要消除次数、难度
|
||||
-> 入口表单确认题材主题、难度选项
|
||||
-> 生成待发布结果页
|
||||
-> 编辑作品基础信息
|
||||
-> 发布前试玩
|
||||
@@ -62,7 +62,7 @@
|
||||
## 3.1 复用什么
|
||||
|
||||
1. 复用平台创作中心入口。
|
||||
2. 复用 Agent-first 创作体验。
|
||||
2. 复用拼图式创作页入口表单体验。
|
||||
3. 复用“创作会话 -> 结果页 -> 发布 -> 运行态”的平台主链。
|
||||
4. 复用作品基础信息、标签、封面、发布接口和作品管理体验。
|
||||
5. 复用现有 Rust / SpacetimeDB 后端基线。
|
||||
@@ -93,13 +93,13 @@ Match3D 必须形成独立玩法域,后续技术方案至少需要覆盖:
|
||||
首版 demo 必须满足:
|
||||
|
||||
1. 平台新增“抓大鹅”玩法创作入口。
|
||||
2. 创建流程采用 Agent 对话收集关键配置。
|
||||
3. Agent 必须在进入结果页前确认:
|
||||
2. 创建流程采用入口表单收集关键配置。
|
||||
3. 表单必须在进入结果页前确认:
|
||||
- 题材主题
|
||||
- 需要消除次数
|
||||
- 难度 `1~10`
|
||||
4. 支持系统自动补全配置,用户确认后开始创造。
|
||||
5. 题材阶段允许上传参考图片。
|
||||
- 3D 素材风格
|
||||
- 难度选项
|
||||
4. `需要消除次数` 与难度 `1~10` 数值不再作为独立输入框展示,由难度选项派生。
|
||||
5. 生成抓大鹅草稿消耗 `20` 光点,生成按钮必须显式展示。
|
||||
6. 结果页支持编辑游戏名称、标签、封面图等基础发布信息。
|
||||
7. 发布前支持试玩,并允许随时停止和修改配置。
|
||||
8. 发布不要求试玩通关。
|
||||
@@ -110,7 +110,8 @@ Match3D 必须形成独立玩法域,后续技术方案至少需要覆盖:
|
||||
13. 清空圆形空间中全部物品即胜利。
|
||||
14. 倒计时结束或备选栏满即失败。
|
||||
15. 胜利 / 失败后展示结算界面。
|
||||
16. 点击、入槽、消除、失败、胜利的即时反馈效果由前端先行呈现,后端负责权威确认、状态落库和成绩可信性。
|
||||
16. 入口页的 3D 素材风格选择会进入素材图提示词,并作为结果页手动 Rodin 3D 模型生成的默认提示词依据。
|
||||
17. 点击、入槽、消除、失败、胜利的即时反馈效果由前端先行呈现,后端负责权威确认、状态落库和成绩可信性。
|
||||
|
||||
---
|
||||
|
||||
@@ -137,13 +138,22 @@ Match3D 必须形成独立玩法域,后续技术方案至少需要覆盖:
|
||||
|
||||
## 6.1 创作方式
|
||||
|
||||
Match3D 首版参考拼图早期的 Agent 对话收集锚点,而不是拼图后期的纯表单入口。
|
||||
Match3D 首版参考拼图后期的入口表单收集方式,而不是早期的 Agent 对话锚点收集。
|
||||
|
||||
Agent 的职责是帮助用户确认可以直接编译 demo 的最小配置:
|
||||
表单的职责是帮助用户确认可以直接编译 demo 的最小配置:
|
||||
|
||||
1. 题材主题。
|
||||
2. 需要消除次数。
|
||||
3. 游戏难度。
|
||||
2. 3D 素材风格。
|
||||
3. 游戏难度选项。
|
||||
|
||||
`需要消除次数` 与游戏难度数值仍属于后端会话配置,但不再要求用户手填。当前入口页固定采用以下映射:
|
||||
|
||||
```text
|
||||
轻松 -> 需要消除 8 次,难度 2
|
||||
标准 -> 需要消除 12 次,难度 4
|
||||
进阶 -> 需要消除 16 次,难度 6
|
||||
硬核 -> 需要消除 20 次,难度 8
|
||||
```
|
||||
|
||||
## 6.2 必填配置
|
||||
|
||||
@@ -151,13 +161,13 @@ Agent 的职责是帮助用户确认可以直接编译 demo 的最小配置:
|
||||
|
||||
题材决定后续生成或选择物品素材的方向。用户可以自定义主题,例如水果、玩具、食物、符号等。
|
||||
|
||||
首版 demo 不接入真实图片生成。当前运行态可消除物统一使用参考图方向的 25 个积木件类型表现,不使用透明气泡,也不在图案上放文字标识。前端首版用差异化颜色、积木造型和 3D 程序化模型表现可消除物,避免玩家在堆叠状态下难以辨认。
|
||||
首版 demo 不接入真实图片生成。当前运行态可消除物统一使用题材方向的 25 个积木件类型表现,不使用透明气泡,也不在图案上放文字标识。前端首版用差异化颜色、积木造型和 3D 程序化模型表现可消除物,避免玩家在堆叠状态下难以辨认。
|
||||
|
||||
可消除物尺寸使用五档相对体积规则: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` 下发权威尺寸,前端只按快照表现。
|
||||
|
||||
### 需要消除次数
|
||||
|
||||
用户输入任意正整数。
|
||||
该字段由难度选项派生,不作为入口页独立输入框展示。
|
||||
|
||||
该字段不是胜利条件,而是本局总物品规模配置:
|
||||
|
||||
@@ -169,21 +179,23 @@ Agent 的职责是帮助用户确认可以直接编译 demo 的最小配置:
|
||||
|
||||
### 难度
|
||||
|
||||
用户输入 `1~10` 的数字,代表从低到高的难度感受。
|
||||
用户选择 `轻松 / 标准 / 进阶 / 硬核` 之一,系统派生 `1~10` 范围内的难度数值。
|
||||
|
||||
首版 demo 中,用户只需凭感觉选择难度;具体难度规则由系统内部解释。后续优化阶段再细化难度曲线、生成算法和遮挡策略。
|
||||
|
||||
## 6.3 自动配置
|
||||
### 3D 素材风格
|
||||
|
||||
如果用户不想逐项填写,系统可以自动补全题材、需要消除次数和难度。
|
||||
入口页在题材主题与难度之间展示 `3D素材风格` 横向滑动选择。首批固定选项为:
|
||||
|
||||
自动补全后的配置必须展示给用户确认,用户确认后才能开始创造。
|
||||
```text
|
||||
黏土手作 / 低多边形 / 玩具塑料 / 木质雕刻 / 体素积木 / 金属机甲 / 自定义
|
||||
```
|
||||
|
||||
## 6.4 参考图片
|
||||
每个内置选项使用 VectorEngine `gpt-image-2-all` 生成的画风参考图展示;参考图保存在 `public/match3d-style-references/`,只作为入口选择的视觉提示,不作为用户上传参考图。选择内置风格时,前端提交 `assetStyleId`、`assetStyleLabel` 与对应 `assetStylePrompt`。选择 `自定义` 时必须弹出独立面板,用户填写描述后才允许应用;自定义描述作为 `assetStylePrompt` 进入后端生成链路。
|
||||
|
||||
题材阶段允许用户上传参考图片。
|
||||
## 6.3 参考图片
|
||||
|
||||
首版只支持图片参考,不支持视频参考。参考图片用于影响题材表现,不作为运行时规则裁决依据。
|
||||
抓大鹅入口页不展示参考图片上传。题材表现先由题材文本和草稿切割图片链路承接;后续需要 3D 模型时,在结果页 `3D素材` Tab 以切割图片作为图生模型参考图手动触发。
|
||||
|
||||
---
|
||||
|
||||
@@ -210,9 +222,9 @@ Agent 的职责是帮助用户确认可以直接编译 demo 的最小配置:
|
||||
|
||||
## 7.3 素材生成边界
|
||||
|
||||
首版结果页暂时不生成额外素材。
|
||||
抓大鹅草稿生成链路会生成首批 `3` 个题材物品素材:文本模型生成物品名,VectorEngine 生成 `2*2` 素材图并切割独立图片。入口页选择的 `assetStylePrompt` 必须写入素材图提示词;结果页手动 Rodin 图生模型时,继续以该物品图片和默认提示词作为起点。
|
||||
|
||||
后续如果需要生成题材物品、伪 3D 物品、场景背景或封面图,需要先补充本文档或新增技术方案,再进入编码。
|
||||
生成出的独立图片先作为草稿页 `3D素材` Tab 的预览资产返回,状态为 `image_ready`,模型文件为空。正式平台资产绑定、Rodin 生成模型转存和二次编辑流程以后续技术方案为准。
|
||||
|
||||
## 7.4 发布前试玩
|
||||
|
||||
@@ -415,15 +427,14 @@ itemTypeCount = clearCount <= 25 ? clearCount : 25
|
||||
|
||||
前端负责所有游戏过程中需要即时呈现的反馈效果:
|
||||
|
||||
1. 展示 Agent 创作界面。
|
||||
1. 展示表单式创作界面。
|
||||
2. 展示结果页和基础编辑表单。
|
||||
3. 上传参考图片。
|
||||
4. 展示运行态场景、物品、倒计时和备选栏。
|
||||
5. 基于最新后端快照执行 2D 命中检测、悬停、按压和选中反馈。
|
||||
6. 发送玩家点击意图。
|
||||
7. 在等待后端确认期间,先行播放飞入、入槽、三消、腾格、胜利和失败过渡效果。
|
||||
8. 收到后端确认后,把本地表现校正到权威快照。
|
||||
9. 展示结算界面。
|
||||
3. 展示运行态场景、物品、倒计时和备选栏。
|
||||
4. 基于最新后端快照执行 2D 命中检测、悬停、按压和选中反馈。
|
||||
5. 发送玩家点击意图。
|
||||
6. 在等待后端确认期间,先行播放飞入、入槽、三消、腾格、胜利和失败过渡效果。
|
||||
7. 收到后端确认后,把本地表现校正到权威快照。
|
||||
8. 展示结算界面。
|
||||
|
||||
前端可以做即时表现预判,但不得把预判结果作为最终规则真相或成绩来源。
|
||||
|
||||
@@ -444,7 +455,7 @@ itemTypeCount = clearCount <= 25 ? clearCount : 25
|
||||
```ts
|
||||
interface Match3DCreatorConfig {
|
||||
themeText: string;
|
||||
referenceImageSrc?: string;
|
||||
referenceImageSrc?: string | null;
|
||||
clearCount: number;
|
||||
difficulty: number;
|
||||
}
|
||||
@@ -453,9 +464,9 @@ interface Match3DCreatorConfig {
|
||||
字段说明:
|
||||
|
||||
1. `themeText`:题材主题。
|
||||
2. `referenceImageSrc`:可选参考图片。
|
||||
3. `clearCount`:需要消除次数,必须为正整数。
|
||||
4. `difficulty`:难度,范围为 `1~10`。
|
||||
2. `referenceImageSrc`:历史兼容字段,入口页固定提交为 `null`。
|
||||
3. `clearCount`:由难度选项派生的需要消除次数,必须为正整数。
|
||||
4. `difficulty`:由难度选项派生的难度数值,范围为 `1~10`。
|
||||
|
||||
## 11.2 作品结构
|
||||
|
||||
@@ -656,15 +667,17 @@ GET /api/runtime/match3d/runs/:runId
|
||||
|
||||
创作入口只展示必要信息,不默认堆叠玩法规则说明。
|
||||
|
||||
## 14.2 Agent 工作区
|
||||
## 14.2 入口表单
|
||||
|
||||
Agent 每轮优先追问最影响 demo 生成的一个问题。
|
||||
入口表单只展示三个输入块:
|
||||
|
||||
已确认的信息应清晰展示给用户确认:
|
||||
1. `想做一个什么题材的抓大鹅?` 大文本输入框。
|
||||
2. `3D素材风格` 横向滑动风格卡,最后一个为 `自定义`。
|
||||
3. `难度` 选项按钮。
|
||||
|
||||
1. 题材主题。
|
||||
2. 需要消除次数。
|
||||
3. 难度。
|
||||
入口页不展示参考图、`需要消除次数` 数值输入、`难度数值` 滑杆,也不展示 `题材 / 物品 / 难度` 三个摘要框。`需要消除次数` 和 `difficulty` 由难度选项派生后提交给后端。
|
||||
|
||||
抓大鹅入口页必须适配移动端创作页一屏内展示,页面自身不产生纵向滚动。题材输入框、风格横滑区、难度按钮和生成按钮根据可视高度自适应压缩,风格区只允许横向滑动。
|
||||
|
||||
## 14.3 结果页
|
||||
|
||||
@@ -689,22 +702,24 @@ Agent 每轮优先追问最影响 demo 生成的一个问题。
|
||||
首版 PRD 对应 demo 验收标准:
|
||||
|
||||
1. 用户可从平台创作入口进入“抓大鹅”模板。
|
||||
2. Agent 能确认题材、需要消除次数和难度。
|
||||
3. 用户可上传参考图片。
|
||||
4. 系统可生成待发布结果页。
|
||||
5. 用户可编辑游戏名称、标签、封面图等基础信息。
|
||||
6. 用户可发布前试玩,且试玩失败不阻断发布。
|
||||
7. 运行态能展示圆形空间、倒计时、物品和 `7` 格备选栏。
|
||||
8. 物品可重叠、遮挡、堆叠。
|
||||
9. 被完全遮挡物品不可点击,露出可点击区域的物品可点击。
|
||||
10. 点击通过后物品飞入备选栏。
|
||||
11. 备选栏中 `3` 个相同物品 id 自动消除。
|
||||
12. 清空空间中全部物品后胜利。
|
||||
13. 倒计时结束或备选栏满后失败。
|
||||
14. 胜利结算展示使用时间。
|
||||
15. 失败结算展示完成进度和重新开始按钮。
|
||||
16. 局内即时反馈由前端先行呈现,关键状态以后端确认快照校正。
|
||||
17. 相关中文文档通过编码检查。
|
||||
2. 入口表单能确认题材主题、3D 素材风格和难度选项,并提交派生后的消除次数与难度数值。
|
||||
3. 入口页不展示参考图上传。
|
||||
4. 内置风格显示画风参考图,自定义风格通过独立面板填写并进入提交 payload。
|
||||
5. 移动端入口页所有内容一屏展示,不产生纵向滚动。
|
||||
6. 系统可生成待发布结果页,并在草稿中返回首批切割图片素材预览。
|
||||
7. 用户可编辑游戏名称、标签、封面图等基础信息。
|
||||
8. 用户可发布前试玩,且试玩失败不阻断发布。
|
||||
9. 运行态能展示圆形空间、倒计时、物品和 `7` 格备选栏。
|
||||
10. 物品可重叠、遮挡、堆叠。
|
||||
11. 被完全遮挡物品不可点击,露出可点击区域的物品可点击。
|
||||
12. 点击通过后物品飞入备选栏。
|
||||
13. 备选栏中 `3` 个相同物品 id 自动消除。
|
||||
14. 清空空间中全部物品后胜利。
|
||||
15. 倒计时结束或备选栏满后失败。
|
||||
16. 胜利结算展示使用时间。
|
||||
17. 失败结算展示完成进度和重新开始按钮。
|
||||
18. 局内即时反馈由前端先行呈现,关键状态以后端确认快照校正。
|
||||
19. 相关中文文档通过编码检查。
|
||||
|
||||
---
|
||||
|
||||
@@ -719,7 +734,7 @@ Agent 每轮优先追问最影响 demo 生成的一个问题。
|
||||
## 阶段 B:创作与结果页
|
||||
|
||||
1. 新增平台创作入口。
|
||||
2. 接入 Agent 会话。
|
||||
2. 接入创作会话。
|
||||
3. 编译草稿并进入结果页。
|
||||
4. 复用基础信息编辑和发布链。
|
||||
|
||||
|
||||
@@ -110,9 +110,10 @@
|
||||
```text
|
||||
平台创作中心
|
||||
-> 选择视觉小说
|
||||
-> 选择创作起点:一句话 / 文档 / 空白
|
||||
-> 进入 visual-novel-agent-workspace
|
||||
-> Agent 生成或补齐底稿
|
||||
-> 视觉小说入口页只展示一句话创作输入框和视觉画风选项
|
||||
-> 点击生成草稿
|
||||
-> 进入 visual-novel-generating
|
||||
-> 生成或补齐底稿
|
||||
-> 进入 visual-novel-result
|
||||
-> 编辑世界观、角色、场景、剧情阶段、资产和运行时配置
|
||||
-> 点击试玩
|
||||
@@ -154,10 +155,11 @@
|
||||
|
||||
1. 作品标题。
|
||||
2. 一句话简介。
|
||||
3. 世界观摘要。
|
||||
4. 玩家身份。
|
||||
5. 3 到 6 个主要角色。
|
||||
6. 3 到 8 个可用场景。
|
||||
3. 视觉画风。
|
||||
4. 世界观摘要。
|
||||
5. 玩家身份。
|
||||
6. 3 到 6 个主要角色。
|
||||
7. 3 到 8 个可用场景。
|
||||
7. 3 到 6 个剧情阶段。
|
||||
8. 初始场景、初始旁白和第一轮可选行动。
|
||||
|
||||
@@ -772,20 +774,23 @@ service client 要复用现有请求封装、鉴权和错误提示风格,不
|
||||
|
||||
### 12.1 工作台
|
||||
|
||||
工作台只展示创作需要的输入和状态:
|
||||
入口页只展示创作需要的输入和状态:
|
||||
|
||||
1. 创作起点选择:一句话、文档、空白。
|
||||
2. 文本输入框和文档上传。
|
||||
3. Agent 对话区域。
|
||||
4. 底稿生成进度。
|
||||
5. 进入结果页按钮。
|
||||
1. 一句话创作输入框。
|
||||
2. 视觉画风选项,参考抓大鹅入口页的横向卡片选择结构。
|
||||
3. 生成草稿按钮。
|
||||
4. 错误、忙碌与禁用态。
|
||||
|
||||
点击生成草稿后进入 `visual-novel-generating` 过程页,过程页复用平台已有生成进度面板,展示一句话输入、画风和草稿生成阶段;完成后自动进入 `visual-novel-result` 草稿页。
|
||||
|
||||
不展示:
|
||||
|
||||
1. 平台规则说明。
|
||||
2. 外部仓库平台功能介绍。
|
||||
3. 回放、分享回放、录像、复盘入口。
|
||||
4. 大段字段解释。
|
||||
3. 文档 / 空白创建入口。
|
||||
4. Agent 对话侧栏。
|
||||
5. 回放、分享回放、录像、复盘入口。
|
||||
6. 大段字段解释。
|
||||
|
||||
### 12.2 结果页
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ HYPER3D_MODEL_REQUEST_TIMEOUT_MS / RODIN_MODEL_REQUEST_TIMEOUT_MS
|
||||
7. 火山引擎语音能力由 `platform-speech` 收口协议帧与上游鉴权,`api-server` 只暴露平台鉴权后的代理路由,不向前端返回任何密钥字段。
|
||||
8. Hyper3D Rodin Gen-2 使用公开默认 `https://api.hyper3d.com/api/v2`,API Key 只读取 `HYPER3D_API_KEY` / `RODIN_API_KEY`,不复用文本 LLM、图片或音频网关密钥。
|
||||
9. APIMart 当前只保留给创意 Agent 的 `gpt-5` Responses 文本/多模态理解链路;GPT-image-2 图片生成不得再读取 APIMart 配置。
|
||||
10. 本地 `npm run api-server`、`npm run dev:rust` 与 `npm run dev` 的环境文件优先级固定为外层 shell 变量最高,其后 `.env`、`.env.local`、`.env.secrets.local` 逐层覆盖;真实密钥建议放在 `.env.secrets.local`,防止 `.env` 中的空示例值覆盖私密配置。
|
||||
|
||||
## 示例文件
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ RODIN_MODEL_REQUEST_TIMEOUT_MS
|
||||
|
||||
1. `HYPER3D_API_KEY` / `RODIN_API_KEY` 只允许写入本地或生产私密环境,不提交到 Git。
|
||||
2. 缺少 API Key 时,后端返回 `503 SERVICE_UNAVAILABLE`。
|
||||
3. `HYPER3D_BASE_URL` 默认使用公开 API 基础地址;如果团队后续改用代理网关,可通过环境变量覆盖。
|
||||
3. 本地真实联调推荐把 key 放在 `.env.secrets.local`;`npm run api-server`、`npm run dev:rust` 与 `npm run dev` 均应保持“外层 shell 变量优先,随后 `.env`、`.env.local`、`.env.secrets.local` 逐层覆盖”的口径,避免 `.env` 里的空示例值压掉私密 key。
|
||||
4. `HYPER3D_BASE_URL` 默认使用公开 API 基础地址;如果团队后续改用代理网关,可通过环境变量覆盖。
|
||||
|
||||
## 4. 后端路由
|
||||
|
||||
@@ -91,6 +92,7 @@ RODIN_MODEL_REQUEST_TIMEOUT_MS
|
||||
6. `meshMode` 限定为 `Quad/Raw`,默认 `Quad`。
|
||||
7. `addons` 首版只允许 `HighPack`。
|
||||
8. `bboxCondition` 必须为 3 个正数,按上游要求序列化为 JSON 字符串。
|
||||
9. `subscriptionKey` 是 Hyper3D 返回的 opaque token,状态查询只校验非空,不在本地做 256 字符等固定长度限制,避免长 token 阻断抓大鹅草稿内联模型生成。
|
||||
|
||||
## 6. 返回语义
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
# 抓大鹅草稿素材生成流水线 2026-05-10
|
||||
|
||||
## 1. 范围
|
||||
|
||||
本方案用于改造 `生成抓大鹅草稿` 的首版生成链路:点击按钮后先进入独立生成过程页,生成结束后自动进入抓大鹅草稿页,并在草稿页 `3D素材` Tab 预览本次生成的 3D 模型。
|
||||
|
||||
本次只把任意难度都收敛为 `3` 件物品。后续难度曲线恢复时,再把物品数、网格数和手动 3D 任务数量从配置中放开。
|
||||
|
||||
## 2. 前端流程
|
||||
|
||||
入口仍复用 `Match3DAgentWorkspace` 表单。点击 `生成抓大鹅草稿` 后:
|
||||
|
||||
1. 创建 Match3D session。
|
||||
2. 进入 `match3d-generating` 生成过程页。
|
||||
3. 过程页复用拼图生成页的 `CustomWorldGenerationView` 结构。
|
||||
4. 生成成功后自动进入 `match3d-result`。
|
||||
5. 生成失败时停留在生成过程页,允许重新生成或返回创作中心。
|
||||
|
||||
生成页步骤固定为:
|
||||
|
||||
```text
|
||||
生成物品名称 -> 生成素材图 -> 切割独立图片 -> 生成 3D 模型 -> 上传图片与模型资产 -> 写入草稿页
|
||||
```
|
||||
|
||||
生成页只展示题材和物品数量,不展示玩法规则说明。
|
||||
|
||||
## 3. 后端编排边界
|
||||
|
||||
外部模型和 OSS 上传全部由 `api-server` 编排,不进入 SpacetimeDB reducer。SpacetimeDB 继续只负责 Match3D 会话、草稿和作品 profile 的确定性写入。
|
||||
|
||||
`match3d_compile_draft` action 的后端顺序为:
|
||||
|
||||
1. 读取 session config。
|
||||
2. 将本次 MVP 的 `clearCount` 固定为 `3`,并同步用于草稿编译。
|
||||
3. 调用文本模型生成 `3` 个题材下的短物品名称。
|
||||
4. 调用项目当前图片链路 VectorEngine `gpt-image-2-all` 生成一张 `1:1` 素材图,提示词必须合入入口页选择的 `assetStylePrompt`。历史 `nanobanana2` 图片选项当前按项目统一决策回落到 VectorEngine,不重新接入 APIMart 图片网关。
|
||||
5. 将素材图按 `n*n` 网格切割成独立图片。当前 `3` 件物品使用 `2*2` 网格,取前 `3` 格。
|
||||
6. 将素材图和每张独立图片上传到 OSS,其中独立图片作为 Rodin 图生模型参考图。
|
||||
7. 对每张独立图片调用 Hyper3D Rodin Gen-2 图生模型,等待任务完成,读取 GLB 下载文件并转存到 `generated-match3d-assets`。
|
||||
8. 调用现有 SpacetimeDB compile procedure 写入草稿,并把本次生成的独立物品图片与模型文件引用序列化写入 `match3d_work_profile.generated_item_assets_json`。这一步对标拼图的 `save_puzzle_generated_images`:生成资产不能只挂在本次 HTTP response 上,否则退出结果页后从草稿架读取 `getMatch3DWorkDetail` 会丢失素材列表。
|
||||
9. 在 HTTP 返回的 draft/profile DTO 中附带本次生成的素材资产预览信息,模型生成成功时状态为 `model_ready`;后续重进草稿页时从 work profile 的持久化 `generatedItemAssets` 恢复同一批素材。
|
||||
|
||||
草稿生成阶段会调用 Hyper3D Rodin,并等待 GLB 模型文件可下载;不得把上游下载 URL 直接写入 Match3D profile,必须先转存 OSS,再保存 `/generated-match3d-assets/...` 引用。结果页 `3D素材` Tab 的重新生成按钮仍可手动触发 Rodin 任务,但正式持久化仍以后端草稿生成链路写入的模型文件为准。
|
||||
|
||||
## 4. 图片提示词
|
||||
|
||||
素材图提示词必须显式包含:
|
||||
|
||||
```text
|
||||
生成一张1:1图片
|
||||
生成2*2网格素材图
|
||||
整体画风遵循:...
|
||||
只绘制这些物品:...
|
||||
不要出现文字、水印、UI、边框
|
||||
```
|
||||
|
||||
`包含若干个物品名称` 在落地中解释为“按生成出的物品名称绘制对应主体”,不要求图片上写出物品名称。这样可以避免文字渲染污染切图和后续手动 3D 模型参考。
|
||||
|
||||
入口页内置风格参考图通过同一 VectorEngine `gpt-image-2-all` 能力生成,保存路径固定为:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
这些图片只作为入口页风格选择的视觉参考,不进入用户草稿资产,不替代生成时的物品素材图。
|
||||
|
||||
## 5. OSS 路径
|
||||
|
||||
新增 generated legacy prefix:
|
||||
|
||||
```text
|
||||
generated-match3d-assets
|
||||
```
|
||||
|
||||
建议对象分组:
|
||||
|
||||
```text
|
||||
generated-match3d-assets/{sessionId}/{profileId}/material-sheet/{taskId}/sheet.png
|
||||
generated-match3d-assets/{sessionId}/{profileId}/items/{itemSlug}/image.png
|
||||
generated-match3d-assets/{sessionId}/{profileId}/items/{itemSlug}/model/{taskUuid}/model.glb
|
||||
```
|
||||
|
||||
`itemSlug` 必须带 `itemId` 前缀,例如 `match3d-item-1-item`。中文物品名清洗后可能都退回 `item`,不能只用物品名做路径,否则多张切割图会写到同一个 object key,导致草稿页预览图全部一致。
|
||||
|
||||
HTTP DTO 同时返回 `imageSrc`、`imageObjectKey`、`modelSrc`、`modelObjectKey`、`modelFileName`、`taskUuid`、`subscriptionKey` 和 `status = model_ready`。前端模型预览不得直接请求裸 `/generated-match3d-assets/...` 路径;需要通过 `/api/assets/read-bytes` 读取模型字节,转成 Blob URL 后交给 Three.js GLTFLoader 加载,以绕开私有 bucket CORS。
|
||||
|
||||
## 6. 自动保存与草稿恢复
|
||||
|
||||
抓大鹅结果页的基础信息自动保存继续调用 `PUT /api/runtime/match3d/works/{profileId}` 更新名称、题材、描述、标签、封面、消除数和难度;该保存不得清空 `generated_item_assets_json`。SpacetimeDB `update_match3d_work` / `publish_match3d_work` 必须保留当前行的生成素材 JSON。
|
||||
|
||||
草稿架重进路径为:
|
||||
|
||||
```text
|
||||
草稿 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;从草稿架重进没有 draft 时,用 `profile.generatedItemAssets`;两者都没有才回退到默认 3D 素材占位。
|
||||
|
||||
`3D素材` 详情页只保留:
|
||||
|
||||
1. 模型预览区:优先加载 `modelSrc` 对应 GLB,支持拖动旋转;没有模型时展示空预览。
|
||||
2. 素材名称输入。
|
||||
3. `重新生成` 按钮。
|
||||
|
||||
详情页不再展示参考图、用途、提示词、文生/图生切换、状态查询、下载列表、taskUuid 或 subscriptionKey。
|
||||
|
||||
## 7. 验收
|
||||
|
||||
建议执行:
|
||||
|
||||
```powershell
|
||||
npm run check:encoding
|
||||
npm run test -- src\services\miniGameDraftGenerationProgress.test.ts
|
||||
npm run test -- src\components\match3d-result\Match3DResultView.test.tsx
|
||||
npm run typecheck
|
||||
cargo test -p shared-contracts match3d --manifest-path server-rs\Cargo.toml
|
||||
cargo test -p spacetime-client match3d --manifest-path server-rs\Cargo.toml
|
||||
cargo test -p platform-oss --manifest-path server-rs\Cargo.toml
|
||||
cargo test -p api-server match3d --manifest-path server-rs\Cargo.toml
|
||||
cargo check -p api-server --manifest-path server-rs\Cargo.toml
|
||||
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`。
|
||||
@@ -1,6 +1,10 @@
|
||||
# 抓大鹅 Match3D F1 创作入口与 Agent UI 落地记录 2026-04-30
|
||||
|
||||
> 2026-05-08 更新:抓大鹅创作端入口已重新开放,当前 `match3d.visible` 为 `true`。本文件记录 F1 接入能力,入口是否展示以 `NEW_WORK_ENTRY_CONFIG_2026-05-01.md` 和 `src/config/newWorkEntryConfig.ts` 为准。
|
||||
>
|
||||
> 2026-05-10 更新:抓大鹅入口页对齐拼图入口页,直接嵌入创作页模板 Tab。入口表单不再展示参考图、消除次数输入、难度数值滑杆和题材/物品/难度摘要框,仅保留题材主题大输入框和难度选项。难度选项负责派生 `clearCount` 与 `difficulty`,生成按钮必须展示 `消耗20光点`。
|
||||
>
|
||||
> 2026-05-10 补充:入口页新增 `3D素材风格` 横向滑动选择,首批风格参考图通过 VectorEngine `gpt-image-2-all` 生成并保存到 `public/match3d-style-references/`。最后一个选项为 `自定义`,点击后弹出独立面板填写画风描述。
|
||||
|
||||
## 1. 阶段边界
|
||||
|
||||
@@ -30,19 +34,38 @@ badge: 可创建
|
||||
|
||||
入口来源统一走 `getVisiblePlatformCreationTypes()`,因此创作首页首屏卡带与“选择创作类型”弹层会同时出现抓大鹅。
|
||||
|
||||
## 4. Agent 工作区
|
||||
## 4. 入口表单工作区
|
||||
|
||||
新增 `Match3DAgentWorkspace`,复用通用 `CreationAgentWorkspace`。
|
||||
新增 `Match3DAgentWorkspace`,组件名继续兼容既有路由、草稿恢复和父层分流;当前主入口已从固定 Agent 追问收口为拼图式表单。
|
||||
|
||||
Agent 只收集三类锚点:
|
||||
创作页 `选择模板` Tab 中切换到 `抓大鹅` 时,直接渲染该表单,不创建会话,也不跳到独立工作台。点击生成后才创建 Match3D 会话并执行 `match3d_compile_draft`。
|
||||
|
||||
1. 题材主题。
|
||||
2. 需要消除次数。
|
||||
3. 难度。
|
||||
表单只展示三个输入块:
|
||||
|
||||
工作区支持参考图片上传入口。图片在 F1 中先以 Data URL 形式随消息 payload 带给 mock client;B5 接入后由后端 facade 替换为正式资产上传与引用。
|
||||
1. `想做一个什么题材的抓大鹅?`:大文本输入框,收集 `themeText`。
|
||||
2. `3D素材风格`:横向滑动风格卡,选择会写入 `assetStyleId`、`assetStyleLabel` 与 `assetStylePrompt`。
|
||||
3. `难度`:四个选项按钮,选项内部派生消除次数和难度数值。
|
||||
|
||||
UI 中不默认展示玩法规则长文,只展示进度、锚点、聊天内容和必要按钮。
|
||||
当前难度映射固定为:
|
||||
|
||||
```text
|
||||
轻松 -> clearCount 8, difficulty 2
|
||||
标准 -> clearCount 12, difficulty 4
|
||||
进阶 -> clearCount 16, difficulty 6
|
||||
硬核 -> clearCount 20, difficulty 8
|
||||
```
|
||||
|
||||
入口页不再上传参考图,提交 payload 中 `referenceImageSrc` 固定为 `null`。如果从旧会话或旧草稿恢复,前端只根据已有 `difficulty` 选择最接近的难度选项,并按当前选项重新派生 `clearCount` 与 `difficulty`。
|
||||
|
||||
内置风格选项为:
|
||||
|
||||
```text
|
||||
黏土手作 / 低多边形 / 玩具塑料 / 木质雕刻 / 体素积木 / 金属机甲 / 自定义
|
||||
```
|
||||
|
||||
自定义风格必须在弹出面板中填写描述后才能应用。入口表单必须在移动端创作页可视区内完成题材、风格、难度和生成按钮的展示,页面自身不产生纵向滚动;风格卡只允许横向滑动。
|
||||
|
||||
生成按钮文案为 `生成抓大鹅草稿`,按钮内必须同时展示 `消耗20光点`。UI 中不默认展示玩法规则长文,也不展示隐藏派生数值的摘要框。
|
||||
|
||||
## 5. mock client
|
||||
|
||||
@@ -84,10 +107,13 @@ POST /api/creation/match3d/sessions/:sessionId/compile
|
||||
|
||||
## 8. 验收口径
|
||||
|
||||
1. 创作首页能看到“抓大鹅 / 经典消除玩法”。
|
||||
2. 弹层选择“抓大鹅”能进入 Agent 工作区。
|
||||
3. 输入题材、消除次数、难度后进度到 `100%`。
|
||||
4. 点击“生成结果页”进入草稿承接页。
|
||||
5. 可从草稿承接页返回 Agent 修改。
|
||||
6. `npm run check:encoding` 通过。
|
||||
7. `npm run typecheck` 通过。
|
||||
1. 创作页 `选择模板` Tab 能看到 `抓大鹅 / 经典消除玩法`。
|
||||
2. 切换到 `抓大鹅` Tab 后,页面内直接显示抓大鹅入口表单,不提前创建会话。
|
||||
3. 表单不展示参考图、`需要消除次数`、`难度数值`、`题材`、`物品`、`难度`摘要框。
|
||||
4. 输入题材、选择风格和难度后,提交 payload 包含派生后的 `clearCount` 与 `difficulty`,`referenceImageSrc` 为 `null`,并包含 `assetStyleId`、`assetStyleLabel` 与 `assetStylePrompt`。
|
||||
5. 生成按钮展示 `消耗20光点`。
|
||||
6. 点击 `自定义` 风格弹出独立面板,填写后应用到提交 payload;未填写时不能应用空自定义风格。
|
||||
7. 移动端创作页内抓大鹅入口内容不产生纵向滚动,风格卡横向滑动。
|
||||
8. 点击生成后创建会话并进入草稿生成/结果页链路。
|
||||
9. `npm run check:encoding` 通过。
|
||||
10. `npm run typecheck` 通过。
|
||||
|
||||
75
docs/technical/MATCH3D_RODIN_ASSET_TAB_2026-05-10.md
Normal file
75
docs/technical/MATCH3D_RODIN_ASSET_TAB_2026-05-10.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# 抓大鹅 Rodin 3D 素材 Tab 接入方案 2026-05-10
|
||||
|
||||
## 1. 范围
|
||||
|
||||
本方案用于把抓大鹅结果页调整为多 Tab 工作台,并新增 `3D素材` Tab。该 Tab 专门服务抓大鹅玩法内物件、奖励、障碍等 3D 素材的 Rodin 生成试验。
|
||||
|
||||
本次复用已有 Hyper3D Rodin Gen-2 后端安全代理,不新增 SpacetimeDB 表;草稿生成链路会把 Rodin 模型转存到 OSS,并通过 Match3D 作品 profile 的 `generatedItemAssets` 恢复。不得把 Hyper3D API Key、上游下载 URL 或本地 Data URL 写成正式资产真相。
|
||||
|
||||
## 2. 页面结构
|
||||
|
||||
抓大鹅结果页拆为三个 Tab:
|
||||
|
||||
1. `作品信息`:承接封面、游戏名称、标签、简介。
|
||||
2. `玩法配置`:承接题材、消除次数、难度、参考图与局内数量摘要。
|
||||
3. `3D素材`:展示 Rodin 素材列表,点击列表项进入详情生成页。
|
||||
|
||||
`3D素材` Tab 的列表布局参考 RPG 结果页角色列表:移动端纵向卡片,桌面端多列紧凑卡片;卡片展示素材名和状态。详情页只保留模型预览、素材名称和 `重新生成` 按钮。
|
||||
|
||||
## 3. Rodin 任务边界
|
||||
|
||||
前端只维护当前页面内的临时重新生成任务状态:
|
||||
|
||||
1. 素材槽位名称。
|
||||
2. 模型预览。草稿生成的 `/generated-match3d-assets/...` GLB 必须通过同源 `/api/assets/read-bytes` 由后端换签并读取字节,前端再转成 Blob URL 后交给 Three.js GLTFLoader,避免浏览器直接 `fetch` OSS 签名 URL 时被 CORS 拦截。
|
||||
3. 图生模型参考图只作为重新生成的隐藏输入来源,不在详情页展示。上传图片在前端直接读成 Data URL;草稿生成的 `/generated-match3d-assets/...` 图片必须通过 `/api/assets/read-bytes` 转成 Data URL 后提交给 Hyper3D。
|
||||
4. Hyper3D `taskUuid` 与 `subscriptionKey`。
|
||||
5. 查询到的状态、进度与下载文件列表。
|
||||
|
||||
正式资产链后续再接:
|
||||
|
||||
1. 下载文件转存 OSS。
|
||||
2. `asset_object` 确认。
|
||||
3. `asset_entity_binding` 绑定到 Match3D 作品或物件槽位。
|
||||
|
||||
首版不得把上游下载 URL 直接写入 Match3D profile,也不得把 Data URL 持久化到 SpacetimeDB。
|
||||
|
||||
## 4. 接口复用
|
||||
|
||||
继续使用既有前端 client:
|
||||
|
||||
```text
|
||||
src/services/hyper3dModelGenerationService.ts
|
||||
```
|
||||
|
||||
对应后端路由:
|
||||
|
||||
```text
|
||||
POST /api/assets/hyper3d/text-to-model
|
||||
POST /api/assets/hyper3d/image-to-model
|
||||
POST /api/assets/hyper3d/status
|
||||
POST /api/assets/hyper3d/download
|
||||
```
|
||||
|
||||
请求参数默认使用:
|
||||
|
||||
```text
|
||||
geometryFileFormat = glb
|
||||
material = PBR
|
||||
quality = medium
|
||||
meshMode = Quad
|
||||
previewRender = true
|
||||
conditionMode = concat
|
||||
```
|
||||
|
||||
## 5. 验收
|
||||
|
||||
建议执行:
|
||||
|
||||
```powershell
|
||||
npm run check:encoding
|
||||
npm run test -- src\components\match3d-result\Match3DResultView.test.tsx
|
||||
npm run typecheck
|
||||
```
|
||||
|
||||
真实 Rodin 生成会消耗 Hyper3D Credit,只在本地私密环境配置 `HYPER3D_API_KEY` 或 `RODIN_API_KEY` 后手动验证。
|
||||
@@ -262,3 +262,14 @@ cannon-es
|
||||
3. 可见 mesh 初始以较小比例显示,再用缓动动画放大到完整尺寸;视觉缩放不得反向修改 body shape、质量、边界半径或生成高度避让计算。
|
||||
4. 入场动画继续服从第 18 节的创建限流和第 19 节的生成高度避让;不能为了动画效果把物体直接放进已有堆叠内部。
|
||||
5. 动画结束后 mesh 缩放必须回到 `1`,避免影响后续点击可读性和托盘对应关系。
|
||||
|
||||
## 21. 高 DPR 移动端 WebGL 画布尺寸锁定
|
||||
|
||||
2026-05-10 针对移动端试玩入口中 3D 锅体和物体从中心区域向右下溢出的问题,补充 WebGL canvas 布局口径。
|
||||
|
||||
编码口径:
|
||||
|
||||
1. 中心 3D 棋盘和托盘 3D 预览都允许通过 `renderer.setPixelRatio(...)` 提升绘制清晰度,但 `WebGLRenderer.domElement` 的 CSS 显示尺寸必须单独锁定为 `position: absolute; inset: 0; width: 100%; height: 100%; display: block`。
|
||||
2. `renderer.setSize(width, height, false)` 只负责绘图缓冲区与当前容器尺寸同步,不能依赖 canvas 默认属性尺寸承载 CSS 布局;否则高 DPR 设备会把绘图缓冲区尺寸当成页面尺寸显示,导致棋盘内容放大并从容器右下溢出。
|
||||
3. 移动端验收仍以 `390px` 竖屏为基准:顶部状态、圆形棋盘和 `7` 格备选栏都必须完整可见,锅体内容应落在屏幕中间的圆形区域内。
|
||||
4. 该修复只影响 WebGL 画布 CSS 布局,不改变相机、物理世界、碰撞体、点击命中、后端权威快照或托盘规则。
|
||||
|
||||
@@ -76,13 +76,14 @@
|
||||
4. 首图文生图 prompt 由 api-server 拼接固定拼图约束后统一压缩到 `500` 字符以内,避免玩家长画面描述触发 DashScope 参数非法;进度页和结果页仍展示玩家原始画面描述,不展示压缩后的内部 prompt。
|
||||
5. 图片生成仍在 api-server 内完成,遵守 SpacetimeDB reducer 不做网络 I/O 的约束。
|
||||
6. 参考图以 Data URL 进入 `POST /api/runtime/puzzle/agent/sessions` 和 `POST /api/runtime/puzzle/agent/sessions/{sessionId}/actions`,这两条路由必须单独放宽 JSON body 上限;不要放大全局默认 body limit。
|
||||
7. 前端仍应优先压缩参考图;后端 body 上限只用于容纳合理尺寸的单张参考图,超大原图不应直接落入 SpacetimeDB 或作为作品字段持久化。
|
||||
8. 作品更新接口 `PUT /api/runtime/puzzle/works/{profileId}` 必须支持作品信息和关卡列表一起写入,前端自动保存不得只写旧单关字段。
|
||||
9. `StartPuzzleRunRequest` 新增可选 `levelId`。详情页或草稿结果页单独体验某关时传入目标关卡,后端从作品/草稿的 `levels` 中选取该关卡生成运行态。
|
||||
10. `ExecutePuzzleAgentActionRequest` 必须保留 `pictureDescription` 字段。表单直达生成时,`compile_puzzle_draft` 优先用 `pictureDescription` 作为首图 prompt,再回退到旧 `promptText`;避免生成页展示的是玩家画面描述,但后端实际用作品名称或旧摘要出图。
|
||||
11. `compile_puzzle_draft` 中的图片上游失败不得映射成 `400 BAD_REQUEST`。DashScope 返回 `InvalidParameter` 或任务失败时,api-server 统一按 `502 UPSTREAM_ERROR` 暴露,并在 `details.message` 中保留“拼图图片生成失败:...”的业务原因,避免生成页只显示“请求参数不合法”。
|
||||
12. `compile_puzzle_draft` 前置光点预扣失败不得映射成 `400 BAD_REQUEST`。余额不足返回 `409 CONFLICT`,SpacetimeDB procedure 不可用、绑定不匹配、钱包服务异常等统一按 `502 UPSTREAM_ERROR` 暴露,并在 `details.message` 中保留真实钱包错误。
|
||||
13. 生成拼图作品草稿动作涉及的表单 seed prompt 与首图 prompt 来源选择统一收口在 `server-rs/crates/api-server/src/prompt/puzzle/draft.rs`;`puzzle.rs` 只负责调用 SpacetimeDB、计费、图片服务和持久化,不再直接拼草稿 prompt 文本。
|
||||
7. 前端仍应优先压缩参考图,入口上传图和裁剪图统一压到单边 1024 以内;后端 body 上限只用于容纳合理尺寸的单张参考图,超大原图不应直接落入 SpacetimeDB 或作为作品字段持久化,后端解析后会拒绝超过 8MB 字节的参考图。
|
||||
8. `aiRedraw = true` 且存在 `referenceImageSrc` 时,api-server 必须走 VectorEngine `POST /v1/images/edits` multipart 图生图接口;无参考图或入口页 `aiRedraw = false` 时不走图生图,关闭 AI 重绘会直接应用上传图为首关正式图。
|
||||
9. 作品更新接口 `PUT /api/runtime/puzzle/works/{profileId}` 必须支持作品信息和关卡列表一起写入,前端自动保存不得只写旧单关字段。
|
||||
10. `StartPuzzleRunRequest` 新增可选 `levelId`。详情页或草稿结果页单独体验某关时传入目标关卡,后端从作品/草稿的 `levels` 中选取该关卡生成运行态。
|
||||
11. `ExecutePuzzleAgentActionRequest` 必须保留 `pictureDescription` 字段。表单直达生成时,`compile_puzzle_draft` 优先用 `pictureDescription` 作为首图 prompt,再回退到旧 `promptText`;避免生成页展示的是玩家画面描述,但后端实际用作品名称或旧摘要出图。
|
||||
12. `compile_puzzle_draft` 中的图片上游失败不得映射成 `400 BAD_REQUEST`。DashScope 返回 `InvalidParameter` 或任务失败时,api-server 统一按 `502 UPSTREAM_ERROR` 暴露,并在 `details.message` 中保留“拼图图片生成失败:...”的业务原因,避免生成页只显示“请求参数不合法”。
|
||||
13. `compile_puzzle_draft` 前置光点预扣失败不得映射成 `400 BAD_REQUEST`。余额不足返回 `409 CONFLICT`,SpacetimeDB procedure 不可用、绑定不匹配、钱包服务异常等统一按 `502 UPSTREAM_ERROR` 暴露,并在 `details.message` 中保留真实钱包错误。
|
||||
14. 生成拼图作品草稿动作涉及的表单 seed prompt 与首图 prompt 来源选择统一收口在 `server-rs/crates/api-server/src/prompt/puzzle/draft.rs`;`puzzle.rs` 只负责调用 SpacetimeDB、计费、图片服务和持久化,不再直接拼草稿 prompt 文本。
|
||||
|
||||
## 结果页
|
||||
|
||||
@@ -104,10 +105,23 @@
|
||||
4. 底部吸底操作区只承载动作按钮,不默认写玩法说明或规则解释,避免压缩移动端编辑空间。
|
||||
5. 关卡详情面板内触发生成画面时,前端必须把当前编辑态完整 `levelsJson` 随 `generate_puzzle_images` action 一起提交。这样新建关卡在自动保存完成前立即生成,也能由后端写回目标关卡。
|
||||
6. api-server 处理 `generate_puzzle_images` 时,若 action 带有 `levelsJson`,必须用这份关卡快照覆盖本次生成的草稿关卡视图后再定位 `levelId`。若请求明确传入 `levelId` 但关卡列表中不存在该关卡,必须返回错误,不得静默回退第一关。
|
||||
7. 历史拼图素材入口只在已有正式图的 `画面图` 区域右下角展示,不再放在 `画面描述` 输入区;本地上传参考图入口仍保留在画面描述输入区右下角。
|
||||
7. 历史拼图素材入口和本地上传参考图入口统一收口到 `画面图` 图卡右下角,避免 `画面描述` 输入区同时承载文本编辑和素材入口;无正式图时也展示空图态图卡。
|
||||
8. 历史拼图素材列表必须由服务端按当前登录账号过滤,只返回 `asset_kind = puzzle_cover_image` 且 `owner_user_id = 当前账号` 的资产;不得依赖前端过滤,也不得展示其他账号素材。
|
||||
9. `画面图` 图卡本身就是上传热区,详情页不再保留右下角独立“上传参考图”按钮;历史入口统一使用带 `History` 图标和 `历史` 小字的按钮。入口页空图态的“点击上传拼图图片”只作为图卡内轻量提示,不使用胶囊按钮、边框或背景样式。
|
||||
|
||||
画面描述区域不再展示候选图实际 prompt 或“请生成一张适合……”之类内部提示词模块。参考图入口保留在画面描述编辑区域内,便于重新生成时继续带入。结果页编辑关卡画面描述时只同步该关卡 `pictureDescription`;作品描述只在作品信息 Tab 编辑,作品详情页不得再回退使用画面描述。
|
||||
### 2026-05-10 关卡生图交互补充
|
||||
|
||||
1. 关卡详情页的 `画面图` 与 `画面描述` 模块对齐入口页拼图表单:画面图使用稳定正方形图卡,画面描述使用固定高度输入区并保留图片模型选择。
|
||||
2. 新建关卡或无正式图关卡也展示 `画面图` 图卡;空图态只保留图标化占位和生成中状态,不追加规则说明文案。
|
||||
3. 关卡详情页删除手填 `参考图链接或资产ID` 输入框。参考图只能通过本地上传或历史拼图素材选择进入本次生成请求;字段 `levels[].pictureReference` 继续作为后端生成后的复用字段透传,不作为用户可手填表单项。
|
||||
4. 单关生成等待估算从 `30` 秒调整为 `90` 秒;生成按钮内展示小字 `等待时间可以制作更多关卡哦~`,不得另起说明面板。
|
||||
5. 触发某一关生成时,前端必须立即把该关 `generationStatus` 标为 `generating` 并随当前 `levelsJson` 写入草稿自动保存链路;后端生成完成后再写回 `ready`。
|
||||
6. `generationStatus = generating` 的关卡在详情弹窗关闭后仍保留进度展示,再次打开同一关详情能继续看到生成进度;关卡列表卡片也必须展示生成中的轻量状态。
|
||||
7. 单关图片生成必须作为后台 action 执行,不占用拼图结果页全局 busy 状态;生成期间仍允许编辑作品信息、编辑关卡、新增关卡、删除其他关卡、关卡测试和继续触发其他可并行动作。
|
||||
8. 发布是唯一必须等待全部图片生成完成的草稿结果页动作;发布检查需要把 `generationStatus = generating` 的关卡列为 blocker,避免未完成资源进入广场。
|
||||
9. 后台生图回包只合并对应关卡的图片候选、正式图、资产 ID 与生成状态,不得覆盖用户等待期间对关卡名、画面描述、作品信息或新增关卡所做的本地编辑。
|
||||
|
||||
画面描述区域不再展示候选图实际 prompt 或“请生成一张适合……”之类内部提示词模块。参考图入口统一放在画面图图卡内,便于重新生成时继续带入,同时保持画面描述输入区只负责文本编辑。结果页编辑关卡画面描述时只同步该关卡 `pictureDescription`;作品描述只在作品信息 Tab 编辑,作品详情页不得再回退使用画面描述。
|
||||
|
||||
## 验收
|
||||
|
||||
|
||||
@@ -10,9 +10,12 @@
|
||||
- [VECTOR_ENGINE_GPT_IMAGE_2_GENERATION_2026-05-09.md](./VECTOR_ENGINE_GPT_IMAGE_2_GENERATION_2026-05-09.md):记录 GPT-image-2 图片生成从 APIMart 迁移到 VectorEngine `gpt-image-2-all` 的接口、环境变量、尺寸映射、错误口径和验收命令。
|
||||
- [SPACETIMEDB_PUBLISH_SCCACHE_FALLBACK_2026-05-09.md](./SPACETIMEDB_PUBLISH_SCCACHE_FALLBACK_2026-05-09.md):记录本地 `spacetime publish` 被 sccache wrapper 通信异常阻断时的根因、debug 构建参数口径和手动排障命令。
|
||||
- [AUTH_RESTORE_AND_RECOMMEND_LOADING_FIX_2026-05-09.md](./AUTH_RESTORE_AND_RECOMMEND_LOADING_FIX_2026-05-09.md):记录刷新网页后登录态失效和推荐页作品卡卡在加载中的联合修复,覆盖 `AuthGate` 本地 token 优先恢复、refresh 失败不清 token、推荐页启动请求版本保护和错误态收口。
|
||||
- [USER_TAG_INVITE_AND_PUZZLE_LEADERBOARD_2026-05-10.md](./USER_TAG_INVITE_AND_PUZZLE_LEADERBOARD_2026-05-10.md):冻结用户标签字段、后台邀请码授予标签、用户填写邀请码后合并账号标签,以及拼图排行榜只展示白名单标签 `北科` 的落地口径。
|
||||
- [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 回填草稿页的端到端边界。
|
||||
- [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 校验和前端预览/提交边界。
|
||||
@@ -81,7 +84,7 @@
|
||||
- [PROFILE_INVITE_CODE_REGISTRATION_AND_ADMIN_2026-04-30.md](./PROFILE_INVITE_CODE_REGISTRATION_AND_ADMIN_2026-04-30.md):冻结邀请码从“我的 Tab 填写”迁到注册环节的前后端边界、`profile_invite_code.metadata_json` 表结构扩展、管理员邀请码虚拟主体和奖励规则。
|
||||
- [MATCH3D_CREATION_AND_RUNTIME_MINIMAL_IMPLEMENTATION_2026-04-30.md](./MATCH3D_CREATION_AND_RUNTIME_MINIMAL_IMPLEMENTATION_2026-04-30.md):冻结抓大鹅 Match3D 首版 demo 的独立玩法域、表与 procedure、HTTP facade、前端即时反馈/后端权威确认协议,以及可并行开发包。
|
||||
- [MATCH3D_DOMAIN_AND_CONTRACTS_STAGE1_2026-04-30.md](./MATCH3D_DOMAIN_AND_CONTRACTS_STAGE1_2026-04-30.md):冻结抓大鹅 Match3D B1+B2 的纯领域规则 crate、Rust/TypeScript shared contracts,以及 Stage1 不触碰 SpacetimeDB 表和 api-server 的边界。
|
||||
- [MATCH3D_F1_CREATION_ENTRY_AND_AGENT_UI_2026-04-30.md](./MATCH3D_F1_CREATION_ENTRY_AND_AGENT_UI_2026-04-30.md):记录抓大鹅 F1 创作入口、Agent 工作区、参考图入口、本地 mock client 与后续 B5 HTTP facade 替换点。
|
||||
- [MATCH3D_F1_CREATION_ENTRY_AND_AGENT_UI_2026-04-30.md](./MATCH3D_F1_CREATION_ENTRY_AND_AGENT_UI_2026-04-30.md):记录抓大鹅 F1 创作入口与当前拼图式内嵌 Tab 表单,明确入口页仅保留题材大输入框和难度选项,由难度选项派生消除次数与难度数值。
|
||||
- [MATCH3D_F2_RESULT_AND_PUBLISH_2026-04-30.md](./MATCH3D_F2_RESULT_AND_PUBLISH_2026-04-30.md):冻结抓大鹅 F2 结果页、基础信息编辑、发布前试玩入口、发布门槛、自动保存和已发布作品二次编辑恢复口径。
|
||||
- [MATCH3D_SPACETIME_CLIENT_AND_API_FACADE_2026-04-30.md](./MATCH3D_SPACETIME_CLIENT_AND_API_FACADE_2026-04-30.md):记录抓大鹅 B4+B5 已落地的 SpacetimeDB bindings、`spacetime-client` facade、`api-server` HTTP 路由、shared contract 对齐和验收命令。
|
||||
- [MATCH3D_CREATION_ENTRY_COMING_SOON_2026-05-01.md](./MATCH3D_CREATION_ENTRY_COMING_SOON_2026-05-01.md):记录抓大鹅创作页入口重新开放、首屏与弹层分流一致,以及公开广场失败不污染创作错误态的边界。
|
||||
|
||||
@@ -71,8 +71,9 @@ SELECT * FROM auth_store_snapshot WHERE snapshot_id = 'default';
|
||||
|
||||
### `user_account`
|
||||
|
||||
- 作用:用户账号主表,保存用户名、公开百梦号、手机号掩码、登录方式、密码登录开关和 token 版本。
|
||||
- 结构:`user_id PK: String`, `public_user_code: String`, `username: String`, `display_name: String`, `avatar_url: Option<String>`, `phone_number_masked: Option<String>`, `phone_number_e164: Option<String>`, `login_method: String`, `binding_status: String`, `wechat_bound: bool`, `password_hash: Option<String>`, `password_login_enabled: bool`, `token_version: u64`。
|
||||
- 作用:用户账号主表,保存用户名、公开百梦号、手机号掩码、登录方式、密码登录开关、token 版本和默认不前端展示的运营标签。
|
||||
- 结构:`user_id PK: String`, `public_user_code: String`, `username: String`, `display_name: String`, `avatar_url: Option<String>`, `phone_number_masked: Option<String>`, `phone_number_e164: Option<String>`, `login_method: String`, `binding_status: String`, `wechat_bound: bool`, `password_hash: String`, `password_login_enabled: bool`, `token_version: u64`, `user_tags: Vec<String>`。
|
||||
- 说明:`user_tags` 默认空数组,只允许后端白名单投影到特定业务接口;不得在登录态、个人资料等通用前端响应中直接暴露。
|
||||
- 索引:`username`, `public_user_code`。
|
||||
|
||||
```sql
|
||||
@@ -255,10 +256,11 @@ SELECT * FROM profile_redeem_code_usage WHERE user_id = '<user_id>';
|
||||
|
||||
### `profile_invite_code`
|
||||
|
||||
- 作用:用户邀请中心的邀请码主表,也承载后台运营预置邀请码。
|
||||
- 结构:`user_id PK: String`, `invite_code: String`, `metadata_json: String`, `created_at: Timestamp`, `updated_at: Timestamp`。
|
||||
- 作用:用户邀请中心的邀请码主表,也承载后台运营预置邀请码和使用后授予账号的运营标签。
|
||||
- 结构:`user_id PK: String`, `invite_code: String`, `metadata_json: String`, `created_at: Timestamp`, `updated_at: Timestamp`, `starts_at: Option<Timestamp>`, `expires_at: Option<Timestamp>`, `granted_user_tags: Vec<String>`。
|
||||
- 索引:主键 `user_id`,唯一索引 `invite_code`。
|
||||
- 后台读取:`GET /admin/api/profile/invite-codes` 只返回 `user_id` 以 `admin:` 开头的后台预置码;普通用户自己的邀请码不得进入后台运营列表。
|
||||
- 说明:`granted_user_tags` 默认空数组;用户注册填写该邀请码后合并进 `user_account.user_tags`,不回改历史用户。
|
||||
|
||||
```sql
|
||||
SELECT * FROM profile_invite_code WHERE user_id = '<user_id>';
|
||||
@@ -661,8 +663,9 @@ SELECT * FROM match3d_agent_message WHERE session_id = '<session_id>' ORDER BY c
|
||||
|
||||
### `match3d_work_profile`
|
||||
|
||||
- 作用:抓大鹅 Match3D 作品主表,保存作品基础信息、配置、发布状态和游玩次数。
|
||||
- 结构:`profile_id PK: String`, `owner_user_id: String`, `source_session_id: String`, `author_display_name: String`, `game_name: String`, `theme_text: String`, `summary_text: String`, `tags_json: String`, `cover_image_src: String`, `cover_asset_id: String`, `clear_count: u32`, `difficulty: u32`, `config_json: String`, `publication_status: String`, `play_count: u32`, `updated_at: Timestamp`, `published_at: Option<Timestamp>`。
|
||||
- 作用:抓大鹅 Match3D 作品主表,保存作品基础信息、配置、发布状态、游玩次数和草稿生成出的独立物品素材引用。
|
||||
- 结构:`profile_id PK: String`, `owner_user_id: String`, `source_session_id: String`, `author_display_name: String`, `game_name: String`, `theme_text: String`, `summary_text: String`, `tags_json: String`, `cover_image_src: String`, `cover_asset_id: String`, `clear_count: u32`, `difficulty: u32`, `config_json: String`, `publication_status: String`, `play_count: u32`, `updated_at: Timestamp`, `published_at: Option<Timestamp>`, `generated_item_assets_json: Option<String>`。
|
||||
- 说明:`generated_item_assets_json` 保存 `Match3DGeneratedItemAsset` 数组 JSON,用于草稿页退出后从作品架重进时恢复 `3D素材` Tab 中的切割图片预览;基础信息自动保存和发布必须保留该字段。
|
||||
- 索引:`owner_user_id`, `publication_status`。
|
||||
|
||||
```sql
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
# 用户标签、邀请码授予与拼图榜单展示方案
|
||||
|
||||
更新时间:`2026-05-10`
|
||||
|
||||
## 1. 目标
|
||||
|
||||
本次新增用户标签系统的最小闭环:
|
||||
|
||||
1. `user_account` 增加账号标签字段,默认空。
|
||||
2. 后台预置邀请码可配置授予标签。
|
||||
3. 用户填写带标签的邀请码后,把标签合并到自己的账号。
|
||||
4. 标签默认不在前端资料页、邀请中心或通用接口展示。
|
||||
5. 拼图排行榜仅对白名单标签做展示,首版只展示 `北科`。
|
||||
|
||||
## 2. 数据字段
|
||||
|
||||
### `user_account.user_tags`
|
||||
|
||||
- 类型:`Vec<String>`。
|
||||
- 默认:空数组。
|
||||
- 语义:账号级运营标签,属于后台与服务端投影数据,不作为普通前端个人资料字段。
|
||||
- 写入:首版只由邀请码兑换链路合并写入。
|
||||
- 迁移:旧迁移包和旧数据库按空数组兼容。
|
||||
|
||||
### `profile_invite_code.granted_user_tags`
|
||||
|
||||
- 类型:`Vec<String>`。
|
||||
- 默认:空数组。
|
||||
- 语义:使用该邀请码后授予被邀请账号的标签列表。
|
||||
- 范围:后台运营预置码和普通用户个人邀请码都可存字段,但后台表单首版只允许管理员配置预置码。
|
||||
- 迁移:旧邀请码按空数组兼容。
|
||||
|
||||
## 3. 标签归一化
|
||||
|
||||
标签由 `module-runtime` 提供统一归一化:
|
||||
|
||||
1. trim 后为空的标签丢弃。
|
||||
2. 同一邀请码或同一账号内标签去重,保留首次出现顺序。
|
||||
3. 单个标签最长 `16` 字符,单次最多 `8` 个标签。
|
||||
4. 当前不做中英文互译,不把中文标签改写为英文。
|
||||
|
||||
## 4. 邀请码授予流程
|
||||
|
||||
用户填写邀请码时,后端按原有校验顺序完成身份、绑定状态、邀请码存在、自邀请与时间窗校验。校验通过后:
|
||||
|
||||
1. 写入 `profile_referral_relation`。
|
||||
2. 发放原有双方奖励。
|
||||
3. 读取 `profile_invite_code.granted_user_tags`。
|
||||
4. 将这些标签合并进 `user_account.user_tags`。
|
||||
|
||||
管理员更新邀请码时,`grantedUserTags` 代表覆盖该邀请码之后授予的标签集合;空数组代表不授予标签。更新邀请码不会回溯修改已经使用过该邀请码的账号。
|
||||
|
||||
## 5. API 契约
|
||||
|
||||
后台邀请码 upsert 请求增加:
|
||||
|
||||
```json
|
||||
{
|
||||
"inviteCode": "BEIKE2026",
|
||||
"grantedUserTags": ["北科"],
|
||||
"metadata": {},
|
||||
"startsAt": null,
|
||||
"expiresAt": null
|
||||
}
|
||||
```
|
||||
|
||||
后台邀请码列表和 upsert 返回增加同名字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"inviteCode": "BEIKE2026",
|
||||
"grantedUserTags": ["北科"]
|
||||
}
|
||||
```
|
||||
|
||||
用户侧邀请中心、账号资料、登录返回和普通 profile 接口不返回 `userTags`。
|
||||
|
||||
## 6. 拼图排行榜展示
|
||||
|
||||
拼图排行榜返回项增加 `visibleTags: string[]`。
|
||||
|
||||
服务端构造排行榜时,从 `user_account.user_tags` 中仅投影允许公开展示的标签。首版公开展示白名单:
|
||||
|
||||
```text
|
||||
北科
|
||||
```
|
||||
|
||||
前端拼图通关弹窗按如下规则展示:
|
||||
|
||||
1. 昵称保持第一行。
|
||||
2. `visibleTags` 非空时在昵称下方显示小标签。
|
||||
3. 没有 `visibleTags` 时不占额外文案。
|
||||
4. 本地兜底 run 的榜单 `visibleTags` 始终为空。
|
||||
|
||||
## 7. 验收
|
||||
|
||||
1. 新账号 `user_account.user_tags` 默认为空。
|
||||
2. 后台创建邀请码时可填写 `北科`,列表和结果面板可回显。
|
||||
3. 用户填写该邀请码后,账号表 `user_tags` 包含 `北科`。
|
||||
4. 不带标签的邀请码不改变账号标签。
|
||||
5. 拼图排行榜中带 `北科` 的用户昵称下方显示 `北科`,其它标签不显示。
|
||||
6. 执行 `npm run check:encoding`、`cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml`,并按影响范围执行后台 typecheck / 拼图前端测试。
|
||||
@@ -110,12 +110,13 @@ VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS=180000
|
||||
1. 所有 GPT-image-2 生图请求都走 `POST {VECTOR_ENGINE_BASE_URL}/v1/images/generations`。
|
||||
2. 请求体 `model = gpt-image-2-all`,尺寸为 VectorEngine 支持的像素尺寸。
|
||||
3. 请求体不再包含 `official_fallback`。
|
||||
4. 参考图字段使用 `image`,不再使用 APIMart 的 `image_urls`。
|
||||
4. 无参考图时使用 `POST {VECTOR_ENGINE_BASE_URL}/v1/images/generations`;有参考图且处于 AI 重绘时改走 `POST {VECTOR_ENGINE_BASE_URL}/v1/images/edits`;入口页关闭 AI 重绘时直接应用上传图,不调用图片生成。
|
||||
5. 拼图入口页上传图生成首图后,返回的首关 `pictureReference` 保留该 Data URL;结果页重新生成在用户未重新上传参考图时会继续把 `pictureReference` 作为 `referenceImageSrc` 传给后端。
|
||||
6. 缺少 `VECTOR_ENGINE_BASE_URL` 或 `VECTOR_ENGINE_API_KEY` 时返回 `503 SERVICE_UNAVAILABLE`,`details.provider = "vector-engine"`。
|
||||
7. 上游错误映射为 `502 UPSTREAM_ERROR`,保留 `upstreamStatus`、业务 message 和截断后的 raw excerpt。
|
||||
8. 运行 `npm run check:encoding`、`cargo test -p api-server openai_image --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server puzzle --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server custom_world_ai --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server character_visual --manifest-path server-rs/Cargo.toml`。
|
||||
9. 后端改动后使用 `npm run api-server` 重启,并确认 `/healthz`。
|
||||
6. 拼图有参考图时,后端 prompt 会显式要求以参考图为第一优先级,保留主体、构图、视角、姿态、配色和光影氛围;入口页会把参考图压到单边 1024 以内,后端拒绝超过 8MB 的参考图字节。
|
||||
7. 缺少 `VECTOR_ENGINE_BASE_URL` 或 `VECTOR_ENGINE_API_KEY` 时返回 `503 SERVICE_UNAVAILABLE`,`details.provider = "vector-engine"`。
|
||||
8. 上游错误映射为 `502 UPSTREAM_ERROR`,保留 `upstreamStatus`、业务 message 和截断后的 raw excerpt。
|
||||
9. 运行 `npm run check:encoding`、`cargo test -p api-server openai_image --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server puzzle --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server custom_world_ai --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server character_visual --manifest-path server-rs/Cargo.toml`。
|
||||
10. 后端改动后使用 `npm run api-server` 重启,并确认 `/healthz`。
|
||||
|
||||
## 拼图链路排障日志
|
||||
|
||||
|
||||
Reference in New Issue
Block a user