This commit is contained in:
2026-05-14 14:21:17 +08:00
parent 7a75f5d612
commit d33c937ebc
191 changed files with 1916 additions and 1549 deletions
@@ -2,7 +2,7 @@
> **For Hermes:** Use subagent-driven-development skill to implement this plan task-by-task.
**Goal:** 在百梦后台新增“埋点数据”页,展示每条埋点原始事件的详细字段,并支持导出为 Excel 可直接打开的表格文件。
**Goal:** 在陶泥儿后台新增“埋点数据”页,展示每条埋点原始事件的详细字段,并支持导出为 Excel 可直接打开的表格文件。
**Architecture:** 后端继续由 `api-server` 作为后台 BFF,经 SpacetimeDB HTTP SQL 只读查询 `tracking_event`,不改变表结构和 reducer。前端在 `apps/admin-web` 中新增独立路由与页面,页面渲染后端返回的原始明细,并在浏览器侧导出 Excel 兼容的 `.xls` HTML 表格,避免新增依赖。
@@ -45,7 +45,7 @@
修复:
1. 在 `map_password_entry_error(...)` 中补充 `InvalidPublicUserCode`
2. 返回中文错误文案 `百梦号格式不正确`
2. 返回中文错误文案 `陶泥号格式不正确`
### 3.3 `module-custom-world` 的 `Display` 分支未覆盖新字段错误
@@ -34,9 +34,10 @@ GENARRATIVE_LLM_BASE_URL=
GENARRATIVE_LLM_API_KEY=
GENARRATIVE_LLM_MODEL=
# APIMart / OpenAI 兼容 Responses 文本网关
# APIMart / OpenAI 兼容 Responses 文本网关与抓大鹅 nanobanana 物品素材图
APIMART_BASE_URL=
APIMART_API_KEY=
APIMART_IMAGE_REQUEST_TIMEOUT_MS=180000
# VectorEngine / GPT-image-2 / Suno / Vidu 生成网关
VECTOR_ENGINE_BASE_URL=https://api.vectorengine.ai
@@ -104,10 +105,10 @@ HYPER3D_MODEL_REQUEST_TIMEOUT_MS / RODIN_MODEL_REQUEST_TIMEOUT_MS
6. VectorEngine 图片与音频生成只读取 `VECTOR_ENGINE_BASE_URL` / `VECTOR_ENGINE_API_KEY`,其中 GPT-image-2 图片生成额外读取 `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS`;不复用 `APIMART_*`、`GENARRATIVE_LLM_*` 或前端变量。拼图 Agent 的生成 action 不做前端自动重试,避免一次点击在上游超时后重复触发外部生图与钱包扣退费;若 VectorEngine 请求达到该超时窗口,api-server 返回 `504 Gateway Timeout`,`error.details.provider` 为 `vector-engine`,并保留具体超时 message。
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 配置。
9. APIMart 当前保留给创意 Agent 的 `gpt-5` Responses 文本/多模态理解链路,并用于抓大鹅物品素材 sheet 的 `nanobanana2` / Gemini 图片模型;GPT-image-2 图片生成不得读取 APIMart 配置。
10. 本地 `npm run api-server`、`npm run dev:rust`、`npm run dev` 与 `npm run dev:web` 的环境文件优先级固定为非空外层 shell 变量最高,其后 `.env`、`.env.local`、`.env.secrets.local` 逐层覆盖;真实密钥建议放在 `.env.secrets.local`,防止 `.env` 中的空示例值覆盖私密配置。外层 shell 变量如果是空字符串或全空白,不再遮蔽本地 env 文件中的真实值。
11. OSS 客户端只在 `ALIYUN_OSS_BUCKET`、`ALIYUN_OSS_ENDPOINT`、`ALIYUN_OSS_ACCESS_KEY_ID`、`ALIYUN_OSS_ACCESS_KEY_SECRET` 四项齐全时初始化。四项全部缺失表示未启用 OSS;部分缺失时 `api-server` 记录 warning 并继续启动,具体上传、换签或读取 generated 私有资产的接口返回 `OSS 未完成环境变量配置`,并在 `error.details.missingEnv` 中列出缺失变量。
12. 抓大鹅 2D 草稿素材生成需要同时具备 VectorEngine 与 OSS 配置:VectorEngine 负责 `gpt-image-2-all` 生成 1K 素材图,OSS 负责保存 5x5 切割后的五视角图片。缺少 VectorEngine 或 OSS 时应通过 `error.details.reason` 向前端暴露具体缺项,不能只显示泛化“服务暂不可用”。素材图生成、封面生成和背景图生成在调用 VectorEngine 前必须先预检 OSS,避免已消耗外部生图后才发现无法落库。
12. 抓大鹅 2D 草稿素材生成需要同时具备 APIMart、VectorEngine 与 OSS 配置:APIMart `gemini-3.1-flash-image-preview` 负责生成 5x5 物品素材 sheet,VectorEngine `gpt-image-2-all` 负责封面、9:16 背景图和 1:1 容器 UI 图,OSS 负责保存切割后的五视角图片及其它生成图。缺少 APIMart、VectorEngine 或 OSS 时应通过 `error.details.reason` 向前端暴露具体缺项,不能只显示泛化“服务暂不可用”。素材图、封面图和背景图生成在调用外部生图前必须先预检 OSS,避免已消耗外部生图后才发现无法落库。
13. 拼图有参考图且开启 AI 重绘时使用 VectorEngine `POST /v1/images/edits` multipart 接口。若返回 `error sending request for url`,代表后端未收到 HTTP 响应;响应 `details` 会带 `reason`、`source`、`connect`、`body`、`timeout` 和 `endpoint`,排查时优先检查服务器网络、DNS、防火墙、代理和参考图大小。拼图图片客户端强制 HTTP/1.1,以降低上游 multipart HTTP/2 连接中断风险。
14. 本地排查 `OSS 未完成环境变量配置` 时必须核对键名是否精确为 `ALIYUN_OSS_ACCESS_KEY_SECRET`。常见误写是把 `OSS` 的首字母 `O` 写成数字 `0`,例如 `ALIYUN_0SS_ACCESS_KEY_SECRET`;该键不会被 `api-server` 读取。
@@ -1,8 +1,8 @@
# 资产操作光点消耗接入方案
# 资产操作泥点消耗接入方案
## 背景
当前光点钱包余额、充值流水与邀请奖励已经收口到 `server-rs/crates/spacetime-module/src/runtime/profile.rs`。资产图片生成和作品发布由 Axum API 调用外部模型或写入业务状态,SpacetimeDB reducer/procedure 不能直接执行外部网络生成,因此计费需要拆成两层:
当前泥点钱包余额、充值流水与邀请奖励已经收口到 `server-rs/crates/spacetime-module/src/runtime/profile.rs`。资产图片生成和作品发布由 Axum API 调用外部模型或写入业务状态,SpacetimeDB reducer/procedure 不能直接执行外部网络生成,因此计费需要拆成两层:
- SpacetimeDB 负责钱包余额和流水的原子变更。
- Axum 资产操作服务负责在执行业务资产操作前扣费,并在生成、持久化或发布失败时补偿退款。
@@ -26,17 +26,17 @@
暂不接入以下入口:
- 旧资产工坊角色主形象/动作生成接口:当前仍使用 `asset-tool` 作为兼容归属,无法确认真实用户。
- 手动上传封面:不调用外部生成模型,不消耗光点。
- 手动上传封面:不调用外部生成模型,不消耗泥点。
- 自定义世界草稿自动补图链路:属于后台补全流程,避免一次用户操作触发多笔不可预期扣费。
- 文本实体、NPC 生成:本次需求聚焦图片资产和发布资产操作,首期只覆盖可明确归属的入口。
## 计费规则
- 每次可计费资产操作消耗 `1` 枚光点。
- 例外:Match3D / 抓大鹅草稿生成是一次完整草稿外部生成动作,固定消耗 `10` 枚光点;流水仍复用 `asset_operation_consume` / `asset_operation_refund`,`asset_kind = match3d_draft_generation`。
- 例外:拼图 / 抓大鹅背景音乐生成固定消耗 `5` 枚光点;物品点击音效仍按单个音效任务消耗 `10` 枚光点。
- 例外:拼图 / 抓大鹅 UI 背景重新生成固定消耗 `2` 枚光点。
- 例外:抓大鹅结果页批量新增物品素材按实际可新增物品名计费,每 `5` 个消耗 `2` 枚光点,不足 `5` 个向上按 `5` 个计。重复名称、作品中已有名称和超过容量上限的名称不进入计费数量。
- 每次可计费资产操作消耗 `1` 枚泥点。
- 例外:Match3D / 抓大鹅草稿生成是一次完整草稿外部生成动作,固定消耗 `10` 枚泥点;流水仍复用 `asset_operation_consume` / `asset_operation_refund`,`asset_kind = match3d_draft_generation`。
- 例外:拼图 / 抓大鹅背景音乐生成固定消耗 `5` 枚泥点;物品点击音效仍按单个音效任务消耗 `10` 枚泥点。
- 例外:拼图 / 抓大鹅 UI 背景重新生成固定消耗 `2` 枚泥点。
- 例外:抓大鹅结果页批量新增物品素材按实际可新增物品名计费,每 `5` 个消耗 `2` 枚泥点,不足 `5` 个向上按 `5` 个计。重复名称、作品中已有名称和超过容量上限的名称不进入计费数量。
- 图片生成和作品发布都按资产操作计费;余额不足时禁止继续执行。
- 在调用外部图片生成或发布 mutation 前预扣,余额不足时直接返回业务错误,不继续调用后续资产操作。
- 如果图片生成、远程下载、OSS 写入、资产记录确认或发布 mutation 失败,资产操作服务自动发起同额退款。
@@ -44,7 +44,7 @@
## 钱包流水
公开两个流水来源类型,统一覆盖“资产生成”和“资产发布”这两类资产操作。流水金额由具体资产操作成本决定,不再假定所有资产操作都是 `1` 枚光点:
公开两个流水来源类型,统一覆盖“资产生成”和“资产发布”这两类资产操作。流水金额由具体资产操作成本决定,不再假定所有资产操作都是 `1` 枚泥点:
- `asset_operation_consume`:资产操作预扣,`amount_delta = -points_cost`。
- `asset_operation_refund`:资产操作失败退款,`amount_delta = +points_cost`。
@@ -34,7 +34,7 @@ Stage 1 已把 Rust 鉴权快照同步到 SpacetimeDB 的 `auth_store_snapshot`
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `user_id` | `String` | 主键。 |
| `public_user_code` | `String` | 公开百梦号。 |
| `public_user_code` | `String` | 公开陶泥号。 |
| `username` | `String` | 当前账号用户名。 |
| `display_name` | `String` | 展示名。 |
| `phone_number_masked` | `Option<String>` | 脱敏手机号。 |
@@ -44,5 +44,6 @@
2. 草稿 / 已发布筛选计数统一从 `CreationWorkShelfItem.status` 读取。
3. 卡片渲染不再直接判断 `publicationStatus` 或不同 works schema 的标题字段。
4. 统一货架按 `updatedAt` 倒序排序,兼容 ISO 字符串和 `seconds.microsZ` 后端时间文本。
5. 作品卡片以 `coverImageSrc` 作为整卡背景;卡片不展示最后修改时间,`updatedAt` 只参与排序。
6. 现有创作中心交互测试通过。
5. 作品卡片以 `coverImageSrc` 作为整卡背景;若 `coverImageSrc` 为空,允许从同一作品已有的关卡图、背景图或素材图兜底,避免草稿页退回普通面板视觉。
6. 卡片不展示最后修改时间,`updatedAt` 只参与排序。
7. 现有创作中心交互测试通过。
@@ -582,7 +582,7 @@ puzzle_creative_level_generation_plan
- Agent 选择理由
- 支持单关卡、多关卡或二者皆可
- 计划关卡数
- 预计积分范围,例如 `预计消耗 8 到 18 光点`
- 预计积分范围,例如 `预计消耗 8 到 18 泥点`
积分范围来自拼图模板协议:
@@ -1,4 +1,4 @@
# 自定义世界草稿场景幕事件与任务字段落地设计(2026-04-25)
# 自定义世界草稿场景幕事件与任务字段落地设计(2026-04-25)
## 背景
@@ -37,7 +37,7 @@
- 当前场景的核心任务描述。
- 文本会作为游戏中首次进入某个场景生成章节任务的关键上下文。
- 必须结合场景描述、场景入口钩子、出场角色与 3 幕事件,说明玩家首次进入该场景时要完成什么。
- 世界档案的场景详情页必须直接展示该字段,便于百梦主确认每个场景的默认章节任务。
- 世界档案的场景详情页必须直接展示该字段,便于陶泥儿主确认每个场景的默认章节任务。
### Landmark 生成源字段
@@ -408,7 +408,7 @@ Node 侧入口位于:
## 10.2 2026-05-01 新用户注册赠送修正
新注册用户默认获得 `10` 个光点,注册链路通过 SpacetimeDB procedure 写入 `profile_dashboard_state.wallet_balance` 与 `profile_wallet_ledger`。流水来源为 `new_user_registration_reward`,流水 ID 固定为 `new-user-registration:{user_id}`,重复调用不重复发放。
新注册用户默认获得 `10` 个泥点,注册链路通过 SpacetimeDB procedure 写入 `profile_dashboard_state.wallet_balance` 与 `profile_wallet_ledger`。流水来源为 `new_user_registration_reward`,流水 ID 固定为 `new-user-registration:{user_id}`,重复调用不重复发放。
注册赠送、邀请码奖励、充值、兑换码、资产扣费等都属于真实平台钱包流水。用户只要已经存在非 `snapshot_sync` 钱包流水,后续 `runtime_snapshot.game_state.playerCurrency` 不再覆盖 `wallet_balance`,只继续刷新游玩时长和玩过世界,避免首次保存旧运行态货币字段时把注册赠送覆盖成 `0`。
@@ -34,17 +34,17 @@
`match3d_compile_draft` action 的后端顺序为:
1. 读取 session config。
2. 对本次 `match3d_compile_draft` 生成动作按 `sessionId + profileId + action 时间戳` 构造幂等流水并预扣 `10` 光点。余额不足时不继续创建草稿;后续任一步失败时自动按同额退款。
2. 对本次 `match3d_compile_draft` 生成动作按 `sessionId + profileId + action 时间戳` 构造幂等流水并预扣 `10` 泥点。余额不足时不继续创建草稿;后续任一步失败时自动按同额退款。
3. 草稿编译先创建可恢复 profile;素材生成数量由入口页难度派生的物品种类决定:轻松 `3` 种、标准 `9` 种、进阶 `15` 种、硬核 `21` 种。
4. 先调用 SpacetimeDB compile procedure 写入草稿。首次执行使用新 `profileId`;重试时复用 session draft / work profile 中已有 `profileId`。这一步不能等待 LLM、图片、音频或 OSS 成功后才执行。
5. 基于入口页题材设定文本调用文本模型生成作品生成计划。模型固定请求 `gpt-4o`,只返回 JSON,其中 `gameName` 为 4 到 12 个中文字符的游戏名称,`summary` 为 18 到 48 个中文字符的作品描述。生成计划还必须包含 `tags`、`backgroundMusic.title`、`backgroundMusic.style`、`backgroundMusic.prompt`、`backgroundPrompt`,以及 `items[]` 中每个物品的 `name` 与 `soundPrompt`。`backgroundMusic.title` 是背景音乐名称,`backgroundMusic.prompt` 固定为空字符串,用于后续 Suno 纯音乐生成;`backgroundPrompt` 用于生成局内竖屏纯背景图,只描述题材氛围、色彩和环境,不得描述锅、圆盘、托盘、拼图槽、物品槽、HUD、UI、文字、按钮、倒计时、分数或物品。文本模型不可用时保留第 4 步的本地兜底,不阻断草稿。
6. 后端把生成计划中的 `gameName` 和 `summary` 写入 `match3d_work_profile` 作品信息后,自动调用作品标签生成器。标签生成器使用题材、作品名称和作品描述生成 3 到 6 个中文短标签;若调用失败或返回不足,则使用生成计划 tags 和本地兜底标签补齐。结果页手动 `AI生成作品标签` 也使用同一接口,并传入当前作品描述。
7. 后端从同一份作品生成计划读取当前难度所需数量的短物品名称和音效提示词;不得再只生成物品名称而丢失后续音效生成上下文。
8. 调用项目当前图片链路 VectorEngine `gpt-image-2-all` 生成 `1:1`、`1024x1024` 素材图,提示词必须合入入口页选择的 `assetStylePrompt`,并强制每格使用统一纯绿色绿幕背景,避免白底或纹理背景进入运行态素材。历史 `nanobanana2` 图片选项当前按项目统一决策回落到 VectorEngine,不重新接入 APIMart 图片网关。
8. 调用 APIMart `nanobanana2` / Gemini 图片模型生成 `1:1`、`1K` 素材图,请求模型固定为 `gemini-3.1-flash-image-preview`,走 `POST {APIMART_BASE_URL}/images/generations`,并携带 `official_fallback = true`。提示词必须合入入口页选择的 `assetStylePrompt`,并强制每格使用统一纯绿色绿幕背景,避免白底或纹理背景进入运行态素材。该调整只作用于抓大鹅物品素材 sheet;封面、9:16 纯背景图和 1:1 容器 UI 图仍继续使用项目现有 VectorEngine `gpt-image-2-all` 链路。
9. 每个物品固定需要 `5` 个不同视角。单张素材图固定为 `5*5 = 25` 格,因此单张图承载 `5` 个物品。若用户要求或难度派生的物品种类不是 `5` 的倍数,后端必须向上补齐物品名称和对应图片到最近的 `5` 的倍数;例如标准难度需要 `9` 种玩法物品,实际生成 `10` 个物品名称和对应五视角图片。若草稿物品数超过 `5`,后端按每批 `5` 个物品自动分批,多张素材图并行生成。
10. 将每张素材图按固定 `5 行 * 5 列` 切割成独立图片,并按物品顺序连续分配 `5` 张视角图。素材图提示词必须要求 `5*5` 严格均匀排布、每格主体完整居中、统一纯绿色绿幕背景、相邻物体主体至少保留 `1/4` 单格宽度空白间距、不得跨格、贴边或越界,避免裁剪后相邻格内容污染。切割前必须先在整张素材图上把绿幕背景处理为透明 alpha,再在每个理论格子内按透明背景/前景像素做内容边界校准,并带少量安全留白导出;不能做固定内缩裁剪,避免贴近格线但未跨格的樱桃、叶片、把手等主体边缘被切掉。每个物品 JSON 写入 `imageViews[]`,同时把第一个视角兼容写入 `imageSrc/imageObjectKey`。
11. 将素材图和每张独立视角图片上传到 OSS。每次获得可恢复的图片资产后,都要回写 `match3d_work_profile.generated_item_assets_json`。成功素材状态为 `image_ready`;失败素材保留已成功图片引用并记录 `error`。每个素材 JSON 同步保存 `soundPrompt`,首个素材 JSON 同步保存 `backgroundMusicTitle` 与 `backgroundMusicStyle`,`backgroundMusicPrompt` 保存为空字符串作为兼容字段。
12. 后端在图片素材生成后使用 `backgroundMusic.title` 提交 Suno 背景音乐任务,`prompt` 为空,`tags` 来自 `backgroundMusic.style`,并固定走纯音乐生成。轮询完成后通过通用创作音频资产链路转存 OSS、确认 `asset_object`、绑定到 `match3d_work/background_music`,再写回首个素材的 `backgroundMusic`。音乐生成失败只记录 warning,不阻断草稿页进入,用户可在结果页 `素材配置 > 背景音乐` 重试。
12. 后端在图片素材生成后使用 `backgroundMusic.title` 提交 Suno 背景音乐任务,`prompt` 为空,`tags` 来自 `backgroundMusic.style`,并固定走纯音乐生成。轮询完成后通过通用创作音频资产链路转存 OSS、确认 `asset_object`、绑定到 `match3d_work/background_music`,再写回首个素材的 `backgroundMusic`。自动草稿阶段必须拿到非空 `backgroundMusic.audioSrc` 才能返回成功;曲名为空、Suno 提交/轮询失败、音频下载失败、OSS 转存失败或资产绑定失败时,本次 `match3d_compile_draft` 返回失败并停留在生成页,不能进入结果页后显示“暂无音乐”。
13. 草稿生成阶段不生成点击音效,只保存 `generatedItemAssets[].soundPrompt`;点击音效由结果页 `素材配置 > 物品` 详情面板手动生成并写回对应素材。
14. UI 背景生成由 `api-server` 调用 VectorEngine `gpt-image-2-all` 分成两张资产:第一张是 `9:16` 纯背景图,不传锅参考图,且必须禁止锅、圆盘、托盘、拼图槽、物品槽、HUD、文字、按钮、倒计时、分数和物品;第二张是 `1:1` 题材容器 UI 图,固定传入 `public/match3d-background-references/pot-fused-reference.png` 作为参考图,只生成一个贴合题材设定的圆形或浅盘状竞技容器,不生成整页背景、文字、按钮或物品。容器图必须沿用参考图的大尺寸轻俯视构图:外轮廓接近画布四边,宽度约占 `86%-92%`、高度约占 `82%-90%`,内口为横向椭圆,禁止生成小容器、正俯视圆盘、侧视碗、餐盘或小托盘。纯背景上传到 `generated-match3d-assets/{sessionId}/{profileId}/background/{taskId}/background.png`,容器 UI 图上传到 `generated-match3d-assets/{sessionId}/{profileId}/ui-container/{taskId}/container.png`,两者都作为 `backgroundAsset` 挂在首个 `generatedItemAssets[]` JSON 上;HTTP DTO 同时顶层输出兼容的 `backgroundPrompt`、`backgroundImageSrc`、`backgroundImageObjectKey` 与 `generatedBackgroundAsset`,容器图通过 `generatedBackgroundAsset.containerImageSrc/containerImageObjectKey` 返回。若作品尚无用户自定义封面,草稿生成完成后默认把容器 UI 图写入 `coverImageSrc`,作为草稿架和作品信息的默认封面。
15. 在 HTTP 返回的 draft/profile DTO 中附带本次生成的素材资产预览信息、背景音乐资产信息、背景资产信息和默认封面;后续重进草稿页时从 work profile 的持久化 `generatedItemAssets` 与 `coverImageSrc` 恢复同一批素材、音乐、UI 与封面。
@@ -204,7 +204,7 @@ Match3DWorkProfile / PlatformMatch3DGalleryCard
详情页不再展示参考图、用途、模型提示词、文生/图生切换、状态查询、下载列表、taskUuid 或 subscriptionKey。
`物品素材` 列表项点击必须弹出独立预览面板,不允许在列表右侧或列表下方内联展示。列表本身使用移动端至少两列的多列卡片布局;每个列表项只展示图片预览、物品名称和垃圾箱删除图标,不展示用途、状态胶囊、视角数量或 `2D素材` 标记。预览面板只承担查看五视角图片、编辑素材名称、编辑点击音效提示词和生成点击音效;不再展示 `重新生成` 按钮。列表项自身支持单项删除,删除后立即把剩余 `generatedItemAssets` 写回作品 profile。批量新增通过列表顶部按钮打开独立面板,面板内每个输入框只输入一个物品名称,`新增物品名称` 按钮追加一个输入框;提交后按输入框顺序清洗、去重并调用 Match3D 作品批量生图接口。生成进度同时显示在批量新增面板和 `素材配置 > 物品` 列表顶部,面板可关闭,后台生成继续推进,不阻塞封面、音频等其他生成操作。后端复用草稿生成的素材图、切图、OSS 上传和可选点击音效流程,但仅按实际可新增名称持久化,不重新生成已有物品,不新增 SpacetimeDB 表,最终仍写回同一份 `generated_item_assets_json`。批量新增先补齐到 `5` 个参与整图生成,随后丢弃补齐用临时物品,只对真实新增物品抠背景、切割和上传。批量新增计费按实际可新增名称每 `5` 个消耗 `2` 光点,不足 `5` 个向上取整;重复名称、已有名称和超过容量上限的名称不计费。
`物品素材` 列表项点击必须弹出独立预览面板,不允许在列表右侧或列表下方内联展示。列表本身使用移动端至少两列的多列卡片布局;每个列表项只展示图片预览、物品名称和垃圾箱删除图标,不展示用途、状态胶囊、视角数量或 `2D素材` 标记。预览面板只承担查看五视角图片、编辑素材名称、编辑点击音效提示词和生成点击音效;不再展示 `重新生成` 按钮。列表项自身支持单项删除,删除后立即把剩余 `generatedItemAssets` 写回作品 profile。批量新增通过列表顶部按钮打开独立面板,面板内每个输入框只输入一个物品名称,`新增物品名称` 按钮追加一个输入框;提交后按输入框顺序清洗、去重并调用 Match3D 作品批量生图接口。生成进度同时显示在批量新增面板和 `素材配置 > 物品` 列表顶部,面板可关闭,后台生成继续推进,不阻塞封面、音频等其他生成操作。后端复用草稿生成的素材图、切图、OSS 上传和可选点击音效流程,但仅按实际可新增名称持久化,不重新生成已有物品,不新增 SpacetimeDB 表,最终仍写回同一份 `generated_item_assets_json`。批量新增先补齐到 `5` 个参与整图生成,随后丢弃补齐用临时物品,只对真实新增物品抠背景、切割和上传。批量新增计费按实际可新增名称每 `5` 个消耗 `2` 泥点,不足 `5` 个向上取整;重复名称、已有名称和超过容量上限的名称不计费。
## 6.1 音频生成与扣费
@@ -214,9 +214,9 @@ Match3DWorkProfile / PlatformMatch3DGalleryCard
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 + 资产槽位` 幂等预扣;背景音乐扣 `5` 光点,物品点击音效扣 `10` 光点。任务仍在处理中时不扣费。资产下载、OSS 转存或资产绑定失败时后端自动退款。前端只展示生成按钮和进度,不自行计算或写入钱包。
5. `POST /api/creation/audio/background-music/{task_id}/asset` 和 `POST /api/creation/audio/sound-effect/{task_id}/asset` 在真正拿到音频并转存资产前,由后端按 `taskId + 资产槽位` 幂等预扣;背景音乐扣 `5` 泥点,物品点击音效扣 `10` 泥点。任务仍在处理中时不扣费。资产下载、OSS 转存或资产绑定失败时后端自动退款。前端只展示生成按钮和进度,不自行计算或写入钱包。
创作入口不展示 `生成音效` Toggle。草稿生成阶段不产生物品点击音效任务,也不产生点击音效相关扣费;入口只产生一次固定 `10` 光点的草稿生成扣费。结果页 `素材配置 > UI` 重新生成背景固定扣 `2` 光点。物品点击音效由结果页 `素材配置 > 物品` 详情面板手动触发,每个音效按单独任务和单独 `match3d_click_sound` 资产槽位扣费。音效生成失败不影响草稿,失败素材保留 `soundPrompt`,用户可在结果页物品详情面板手动重试。
创作入口不展示 `生成音效` Toggle。草稿生成阶段不产生物品点击音效任务,也不产生点击音效相关扣费;入口只产生一次固定 `10` 泥点的草稿生成扣费。结果页 `素材配置 > UI` 重新生成背景固定扣 `2` 泥点。物品点击音效由结果页 `素材配置 > 物品` 详情面板手动触发,每个音效按单独任务和单独 `match3d_click_sound` 资产槽位扣费。音效生成失败不影响草稿,失败素材保留 `soundPrompt`,用户可在结果页物品详情面板手动重试。
## 7. 验收
@@ -238,4 +238,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_BASE_URL` / `VECTOR_ENGINE_API_KEY`,以及完整 `ALIYUN_OSS_BUCKET`、`ALIYUN_OSS_ENDPOINT`、`ALIYUN_OSS_ACCESS_KEY_ID`、`ALIYUN_OSS_ACCESS_KEY_SECRET`。如果只配置 bucket 和 endpoint,抓大鹅素材、封面或背景生成会在调用 VectorEngine 前返回 `OSS 未完成环境变量配置`,`details.missingEnv` 会列出缺少的 AccessKey 项;不要回退到 Rodin/GLB 或伪造本地上传成功。开启音频生成还需要对应音频上游配置。后端改动后使用 `npm run api-server` 启动,并检查 `/healthz`。
真实草稿生成需要本地私密环境配置 `APIMART_BASE_URL` / `APIMART_API_KEY` / `APIMART_IMAGE_REQUEST_TIMEOUT_MS` 用于物品素材 sheet,配置 `VECTOR_ENGINE_BASE_URL` / `VECTOR_ENGINE_API_KEY` 用于封面、背景和容器 UI,并补齐完整 `ALIYUN_OSS_BUCKET`、`ALIYUN_OSS_ENDPOINT`、`ALIYUN_OSS_ACCESS_KEY_ID`、`ALIYUN_OSS_ACCESS_KEY_SECRET`。如果只配置 bucket 和 endpoint,抓大鹅素材、封面或背景生成会在调用外部生图前返回 `OSS 未完成环境变量配置`,`details.missingEnv` 会列出缺少的 AccessKey 项;不要回退到 Rodin/GLB 或伪造本地上传成功。开启音频生成还需要对应音频上游配置。后端改动后使用 `npm run api-server` 启动,并检查 `/healthz`。
@@ -8,7 +8,7 @@
>
> 2026-05-13 补充:草稿素材实际生成数量按 `5` 的倍数向上补齐,补齐物品同样需要生成名称和五视角图片。素材图提示词固定要求 `5*5` 严格均匀排布,禁止主体跨格、贴边或越界影响裁剪效果。
>
> 2026-05-13 补充:创作页隐藏抓大鹅 `生成音效` Toggle;草稿生成固定预扣 `10` 光点,按钮展示 `消耗10光点`。点击音效生成只保留在结果页 `素材配置 > 物品` 详情面板中手动触发。
> 2026-05-13 补充:创作页隐藏抓大鹅 `生成音效` Toggle;草稿生成固定预扣 `10` 泥点,按钮展示 `消耗10泥点`。点击音效生成只保留在结果页 `素材配置 > 物品` 详情面板中手动触发。
## 1. 阶段边界
@@ -69,7 +69,7 @@ badge: 可创建
自定义风格必须在弹出面板中填写描述后才能应用。入口表单必须在移动端创作页可视区内完成题材、风格、难度和生成按钮的展示,页面自身不产生纵向滚动;风格卡只允许横向滑动。
生成按钮文案为 `生成抓大鹅草稿`,按钮内必须同时展示 `消耗10光点`。UI 中不默认展示玩法规则长文,也不展示隐藏派生数值的摘要框。
生成按钮文案为 `生成抓大鹅草稿`,按钮内必须同时展示 `消耗10泥点`。UI 中不默认展示玩法规则长文,也不展示隐藏派生数值的摘要框。
## 5. mock client
@@ -115,7 +115,7 @@ POST /api/creation/match3d/sessions/:sessionId/compile
2. 切换到 `抓大鹅` Tab 后,页面内直接显示抓大鹅入口表单,不提前创建会话。
3. 表单不展示参考图、`需要消除次数`、`难度数值`、`题材`、`物品`、`难度`摘要框。
4. 输入题材、选择风格和难度后,提交 payload 包含派生后的 `clearCount` 与 `difficulty`,`referenceImageSrc` 为 `null`,并包含 `assetStyleId`、`assetStyleLabel` 与 `assetStylePrompt`。
5. 生成按钮展示 `消耗10光点`,创作页不展示 `生成音效` Toggle。
5. 生成按钮展示 `消耗10泥点`,创作页不展示 `生成音效` Toggle。
6. 点击 `自定义` 风格弹出独立面板,填写后应用到提交 payload;未填写时不能应用空自定义风格。
7. 移动端创作页内抓大鹅入口内容不产生纵向滚动,风格卡横向滑动。
8. 点击生成后创建会话并进入草稿生成/结果页链路。
@@ -6,33 +6,33 @@
本轮在“我的”页面的“会员充值”入口落地账户充值弹窗,包含两个页签:
1. `光点充值`
1. `泥点充值`
2. `会员卡充值`
前端只负责展示与发起购买,套餐、价格、赠送规则、会员权益、生效时间、钱包余额与交易流水统一由 `server-rs` 后端返回。普通 H5 / 本地联调继续使用 `mock` 渠道:创建订单后立即写入余额或会员状态,并返回最新账户中心快照。微信小程序 web-view 使用 `wechat_mp` 渠道:创建订单时只写入 `pending` 订单并返回小程序 `wx.requestPayment` 参数,真实到账以后端微信支付通知为准。
## 2. 产品规则
### 2.1 光点充值套餐
### 2.1 泥点充值套餐
| productId | 光点 | 金额分 | 徽标 | 说明 |
| productId | 泥点 | 金额分 | 徽标 | 说明 |
| ------------- | ---: | -----: | -------- | -------------- |
| `points_60` | 60 | 600 | 首充双倍 | 首充送60光点 |
| `points_180` | 180 | 1800 | 首充双倍 | 首充送180光点 |
| `points_300` | 300 | 3000 | 首充双倍 | 首充送300光点 |
| `points_680` | 680 | 6800 | 首充双倍 | 首充送680光点 |
| `points_1280` | 1280 | 12800 | 首充双倍 | 首充送1280光点 |
| `points_3280` | 3280 | 32800 | 首充双倍 | 首充送3280光点 |
| `points_60` | 60 | 600 | 首充双倍 | 首充送60泥点 |
| `points_180` | 180 | 1800 | 首充双倍 | 首充送180泥点 |
| `points_300` | 300 | 3000 | 首充双倍 | 首充送300泥点 |
| `points_680` | 680 | 6800 | 首充双倍 | 首充送680泥点 |
| `points_1280` | 1280 | 12800 | 首充双倍 | 首充送1280泥点 |
| `points_3280` | 3280 | 32800 | 首充双倍 | 首充送3280泥点 |
光点充值固定为 `¥6 / ¥18 / ¥30 / ¥68 / ¥128 / ¥328` 六个档位。全部档位参与首充双倍:用户历史上没有 `points_recharge` 流水时,本次购买到账光点为基础光点与等额赠送光点之和;已有充值流水后只到账基础光点。实际到账光点写入交易流水,余额以 SpacetimeDB projection 为准。
泥点充值固定为 `¥6 / ¥18 / ¥30 / ¥68 / ¥128 / ¥328` 六个档位。全部档位参与首充双倍:用户历史上没有 `points_recharge` 流水时,本次购买到账泥点为基础泥点与等额赠送泥点之和;已有充值流水后只到账基础泥点。实际到账泥点写入交易流水,余额以 SpacetimeDB projection 为准。
### 2.2 会员卡套餐
| productId | 类型 | 天数 | 金额分 | 权益 |
| --------------- | ---- | ---: | -----: | --------------------------------- |
| `member_month` | 月卡 | 30 | 2800 | 免光点回合数100,每日签到加成0% |
| `member_season` | 季卡 | 90 | 7800 | 免光点回合数100,每日签到加成100% |
| `member_year` | 年卡 | 365 | 24800 | 免光点回合数100,每日签到加成210% |
| `member_month` | 月卡 | 30 | 2800 | 免泥点回合数100,每日签到加成0% |
| `member_season` | 季卡 | 90 | 7800 | 免泥点回合数100,每日签到加成100% |
| `member_year` | 年卡 | 365 | 24800 | 免泥点回合数100,每日签到加成210% |
购买会员时,如果当前会员仍有效,则从当前到期时间顺延;如果已过期或从未购买,则从当前服务端时间开始计算。状态只区分 `普通` 与已生效会员,前端不自行推断。
@@ -42,8 +42,8 @@
需要 Bearer JWT。返回:
1. 当前光点余额、会员状态、到期时间
2. 光点套餐与会员套餐
1. 当前泥点余额、会员状态、到期时间
2. 泥点套餐与会员套餐
3. 会员权益表
4. 最近订单摘要
@@ -65,8 +65,8 @@
1. 校验 `productId`
2. `paymentChannel = "mock"` 时后端创建已支付订单
3. `paymentChannel = "wechat_mp"` 时后端创建待支付订单,并调用微信支付 JSAPI 下单生成小程序支付参数
4. mock 光点套餐立即写入钱包余额与流水,mock 会员套餐立即写入会员状态
5. wechat_mp 订单不提前发光点或会员,只返回待支付订单、账户中心快照与 `wechatMiniProgramPayParams`
4. mock 泥点套餐立即写入钱包余额与流水,mock 会员套餐立即写入会员状态
5. wechat_mp 订单不提前发泥点或会员,只返回待支付订单、账户中心快照与 `wechatMiniProgramPayParams`
兼容路径:`POST /api/runtime/profile/recharge/orders`
@@ -113,15 +113,15 @@
1. “我的”页会员充值按钮打开独立弹窗,不在当前面板下方展开。
2. 弹窗顶部标题为 `账户充值`,右上角关闭。
3. 默认打开 `光点充值`,可切换到 `会员卡充值`。
3. 默认打开 `泥点充值`,可切换到 `会员卡充值`。
4. 点击套餐后调用下单接口,按钮进入处理中状态;小程序环境走 native 支付页拉起 `wx.requestPayment`,支付页返回后刷新 `profileDashboard`。
5. 弹窗内不写大段说明文案,只保留必要金额、光点、会员权益和状态反馈。
5. 弹窗内不写大段说明文案,只保留必要金额、泥点、会员权益和状态反馈。
6. 会员卡充值区以套餐卡片优先展示周期、价格和处理状态;移动端单列,桌面端三列,权益表允许横向滚动,避免小屏挤压。
## 5. 验收
1. 普通用户打开弹窗能看到光点与会员套餐。
2. 光点购买后余额增加,流水来源为 `points_recharge`。
3. 首充赠送只在首次光点充值时生效。
1. 普通用户打开弹窗能看到泥点与会员套餐。
2. 泥点购买后余额增加,流水来源为 `points_recharge`。
3. 首充赠送只在首次泥点充值时生效。
4. 会员购买后会员状态与到期时间立即更新。
5. 移动端弹窗单列可滚动,桌面端接近参考图卡片网格。
@@ -13,9 +13,9 @@
## 2. 前端交互
### 2.1 百梦号复制
### 2.1 陶泥号复制
1. 点击“我的”页百梦号后的复制按钮后,按钮文案临时切换为 `已复制`。
1. 点击“我的”页陶泥号后的复制按钮后,按钮文案临时切换为 `已复制`。
2. 复制失败时临时切换为 `复制失败`。
3. 状态自动恢复为 `复制`。
@@ -84,7 +84,7 @@ SpacetimeDB 正式表 `user_account` 需要增加 `avatar_url: Option<String>`
## 5. 验收
1. 创作页已发布作品分享按钮点击后显示 `已复制`。
2. “我的”页百梦号复制按钮点击后显示 `已复制`。
2. “我的”页陶泥号复制按钮点击后显示 `已复制`。
3. “我的”页不展示 `手机号` 与 `正常` 标签。
4. 昵称编辑成功后,资料卡与顶部账号入口同步新昵称。
5. 昵称与头像裁剪弹窗面板不透明,不能露出底层页面内容。
@@ -7,14 +7,14 @@
在现有“我的”Tab 功能入口区(常用功能)落地三个轻量入口,入口顺序固定为 `邀请好友`、`填邀请码`、`玩家社区`:
1. `邀请好友`:弹出面板展示当前账号绑定的邀请码、邀请奖励规则和成功邀请用户列表。
2. `填邀请码`:弹出面板填写邀请码,成功后邀请者与被邀请者各获得 `30` 光点。
2. `填邀请码`:弹出面板填写邀请码,成功后邀请者与被邀请者各获得 `30` 泥点。
3. `玩家社区`:弹出面板展示微信群与 QQ 群正式二维码图片。
## 后端边界
- 邀请码、邀请关系与奖励发放全部存入 `server-rs/crates/spacetime-module`。
- Axum 只做鉴权、参数转发与响应映射,不在 API 层自行计算奖励。
- 前端只读取后端状态与调用提交接口,不做本地加光点。
- 前端只读取后端状态与调用提交接口,不做本地加泥点。
- 钱包余额继续复用 `profile_dashboard_state.wallet_balance`。
- 奖励流水继续复用 `profile_wallet_ledger`,新增来源类型:
- `invite_inviter_reward`
@@ -43,7 +43,7 @@
- 每个用户拥有一个稳定邀请码,首次进入邀请中心时自动生成。
- 用户不能填写自己的邀请码。
- 用户最多填写一个邀请码,成功后不可修改。
- 被邀请者绑定成功后获得 `30` 光点。
- 被邀请者绑定成功后获得 `30` 泥点。
- 邀请者每天最多获得 `10` 次邀请奖励,超过后关系仍可绑定,被邀请者仍获得奖励,邀请者当次不再加分。
- 每次奖励都写入钱包流水,钱包余额以后端返回为准。
@@ -60,7 +60,7 @@
"invitedUsers": [
{
"userId": "user_001",
"displayName": "百梦玩家",
"displayName": "陶泥儿玩家",
"avatarUrl": null,
"boundAt": "2026-05-01T08:00:00Z"
}
@@ -89,10 +89,10 @@
- `server-rs/crates/spacetime-module` 已新增邀请码与邀请关系表,邀请中心读取和填码绑定均通过 SpacetimeDB procedure 执行。
- `server-rs/crates/api-server` 已挂接 `/api/runtime/profile/referrals/*` 与 `/api/profile/referrals/*` 两组路由。
- 前端“我的”Tab 三个功能入口均打开独立弹窗,玩家社区使用 `media/social-media-group/wechat.png` 与 `media/social-media-group/qq.png` 两张正式二维码图片。
- 复制邀请会复制邀请码和邀请链接;填码成功后刷新个人看板光点。
- 邀请好友弹窗展示 `邀请一个用户注册,双方都可获得 30 光点。每日最多获得十次邀请奖励。`,不再展示“邀请 / 已奖 / 今日”三项统计。
- 复制邀请会复制邀请码和邀请链接;填码成功后刷新个人看板泥点。
- 邀请好友弹窗展示 `邀请一个用户注册,双方都可获得 30 泥点。每日最多获得十次邀请奖励。`,不再展示“邀请 / 已奖 / 今日”三项统计。
- 邀请好友弹窗底部展示成功邀请用户头像和昵称列表;没有成功邀请时展示短空状态。
- “我的”页 `邀请好友` 按钮副标题展示 `双方得30(光点icon)`;`玩家社区` 按钮副标题展示 `每日领福利`。
- “我的”页 `邀请好友` 按钮副标题展示 `双方得30(泥点icon)`;`玩家社区` 按钮副标题展示 `每日领福利`。
- “我的”页功能入口区不展示 `常用功能` 标题和 `快捷入口` 副标题,避免首屏重复说明类文案。
## 前端交互
@@ -36,5 +36,5 @@
3. 未开放玩法点击态保持禁用,不应进入鉴权或创建会话链路。
4. 已开放玩法点击后必须进入对应创建链路;若用户未登录,先走登录保护。
5. 创作 Tab 首屏应显示“10分钟创作一个精品互动玩法”,并默认展示拼图创作表单。
6. 智能创作入口隐藏后,不应出现“Hi, 朋友”“问一问百梦”或“一句话生成闪应用”等旧首页入口。
6. 智能创作入口隐藏后,不应出现“Hi, 朋友”“问一问陶泥儿”或“一句话生成闪应用”等旧首页入口。
7. 方洞挑战入口隐藏后,不应出现在创作 Tab 模板入口、创作中心顶部卡带、平台创作类型弹层和创作页作品架中;既有 `SH-` 作品号、广场详情和试玩 runtime 链路不因此删除。
@@ -1,6 +1,6 @@
# 密码登录入口历史落地设计
> 2026-04-25 更新:当前产品策略已调整为“不开放密码注册”。新用户必须通过手机号验证码注册/登录,密码登录只面向已经登录后设置过密码的手机号账号。`POST /api/auth/entry` 只接受 `phone + password`,不支持邮箱、用户名或百梦号登录,也不承担自动建号能力。本文原有“密码自动建号”内容仅作为历史背景保留,当前落地以本更新和 [PASSWORD_LOGIN_CHANGE_RESET_DESIGN_2026-04-24.md](./PASSWORD_LOGIN_CHANGE_RESET_DESIGN_2026-04-24.md) 为准。
> 2026-04-25 更新:当前产品策略已调整为“不开放密码注册”。新用户必须通过手机号验证码注册/登录,密码登录只面向已经登录后设置过密码的手机号账号。`POST /api/auth/entry` 只接受 `phone + password`,不支持邮箱、用户名或陶泥号登录,也不承担自动建号能力。本文原有“密码自动建号”内容仅作为历史背景保留,当前落地以本更新和 [PASSWORD_LOGIN_CHANGE_RESET_DESIGN_2026-04-24.md](./PASSWORD_LOGIN_CHANGE_RESET_DESIGN_2026-04-24.md) 为准。
>
> 2026-04-28 更新:为开发期本地/测试服联调新增服务端环境变量 `GENARRATIVE_DEV_PASSWORD_ENTRY_AUTO_REGISTER_ENABLED`,默认 `false`。仅当该变量显式为 `true` 时,`POST /api/auth/entry` 可对未知手机号用本次密码直接创建账号并登录;默认关闭时仍严格保持未知手机号返回 `401` 的生产语义。该开关不得用于生产环境,也不新增任何前端规则说明文案。
@@ -17,7 +17,7 @@
1. `api-server` 对外只暴露 `phone + password` 的最小接口。
2. `module-auth` 只负责已存在手机号账号的密码校验。
3. 密码入口不创建账号,不接收邮箱、用户名或百梦号。
3. 密码入口不创建账号,不接收邮箱、用户名或陶泥号。
4. 登录成功后与 JWT、refresh cookie 的衔接方式。
## 1.1 当前冻结结论
@@ -239,7 +239,7 @@
1. 未知手机号密码登录返回 `401`,且不创建账号。
2. 已登录手机号账号设置密码后可用 `phone + password` 登录。
3. 同手机号错误密码返回 `401`。
4. 邮箱、用户名或百梦号作为密码登录标识返回 `400`。
4. 邮箱、用户名或陶泥号作为密码登录标识返回 `400`。
5. 登录成功时返回 access token。
6. 登录成功时写回 refresh cookie。
7. `GENARRATIVE_DEV_PASSWORD_ENTRY_AUTO_REGISTER_ENABLED` 默认关闭时行为不变。
@@ -19,7 +19,7 @@
沿用现有 `POST /api/auth/entry`:
1. 请求字段固定为 `phone`、`password`,前端只提交手机号。
2. 后端只按标准手机号归一化后查找账号,不兼容邮箱、用户名、百梦号或历史开发游客标识。
2. 后端只按标准手机号归一化后查找账号,不兼容邮箱、用户名、陶泥号或历史开发游客标识。
3. 手机号不存在时返回 `401`,不创建账号。
4. 手机号存在但未设置密码时返回 `401`。
5. 校验成功后签发 access token,并写入 refresh cookie。
@@ -15,7 +15,7 @@
3. 匹配忽略大小写,允许用户输入去掉空格、连字符或下划线后的连续片段,例如 `PZEPUBLIC1` 命中 `PZ-EPUBLIC1`。
4. 输入完整公开作品号并本地命中时,保留既有作品号直达行为。
5. 输入模糊片段命中公开作品时,在首页直接展示搜索结果列表,点击结果打开对应作品详情。
6. 当前公开作品列表无命中时,保留既有公开编号直达兜底,继续支持远端按作品号或百梦号查找。
6. 当前公开作品列表无命中时,保留既有公开编号直达兜底,继续支持远端按作品号或陶泥号查找。
## 验收标准
@@ -1,24 +1,24 @@
# 百梦产品命名规范落地说明
# 陶泥儿产品命名规范落地说明
## 背景
平台对外中文命名统一使用以下称谓:
- 产品中文展示名:`百梦`
- 平台内消费单位:`光点`
- 公开账号标识:`百梦号`
- 创作侧面向创作者称谓:`百梦主`
- 产品中文展示名:`陶泥儿`
- 平台内消费单位:`泥点`
- 公开账号标识:`陶泥号`
- 创作侧面向创作者称谓:`陶泥儿主`
## 落地边界
1. 前端页面、弹窗、测试断言和后端返回给用户的中文错误文案统一使用新称谓。
2. SpacetimeDB 表字段、Rust/TypeScript contract 字段、流水来源枚举、`points_*` 商品 ID、`public_user_code` 字段名继续保持不变,避免引入数据库迁移和历史数据兼容风险。
3. 公开编号现有 `SY-XXXXXXXX` 格式本轮不迁移,只调整用户可见标签为“百梦号”;编号格式如需改为新前缀,应另起迁移方案并同步老用户兼容策略。
3. 公开编号现有 `SY-XXXXXXXX` 格式本轮不迁移,只调整用户可见标签为“陶泥号”;编号格式如需改为新前缀,应另起迁移方案并同步老用户兼容策略。
4. 历史日志、构建产物、第三方依赖和生成绑定不参与本轮文本替换。
## 验收点
1. 首页、登录绑定页、我的页和搜索结果不再展示旧产品名。
2. 钱包、充值、邀请、兑换码、资产计费和拼图道具确认文案统一展示“光点”。
3. 账号公开标识相关错误和搜索空状态统一展示“百梦号”。
4. 创作相关可见默认称谓使用“百梦主”。
2. 钱包、充值、邀请、兑换码、资产计费和拼图道具确认文案统一展示“泥点”。
3. 账号公开标识相关错误和搜索空状态统一展示“陶泥号”。
4. 创作相关可见默认称谓使用“陶泥儿主”。
@@ -1,20 +1,20 @@
# 百梦产品命名替换落地说明
# 陶泥儿产品命名替换落地说明
## 1. 本轮目标
本轮统一平台对外中文命名,当前生效称谓如下:
- 产品中文展示名:`百梦`
- 平台内消费单位:`光点`
- 公开账号标识:`百梦号`
- 创作侧面向创作者称谓:`百梦主`
- 产品中文展示名:`陶泥儿`
- 平台内消费单位:`泥点`
- 公开账号标识:`陶泥号`
- 创作侧面向创作者称谓:`陶泥儿主`
## 2. 落地范围
1. 前端网页、管理后台、HTML 标题、metadata 与品牌标识统一展示“百梦”。
2. 钱包、充值、邀请、兑换码、资产计费、拼图道具与作者激励统一展示“光点”。
3. 公开账号标识、搜索兜底、登录限制与错误信息统一展示“百梦号”。
4. 创作侧面向创作者的称谓统一展示“百梦主”。
1. 前端网页、管理后台、HTML 标题、metadata 与品牌标识统一展示“陶泥儿”。
2. 钱包、充值、邀请、兑换码、资产计费、拼图道具与作者激励统一展示“泥点”。
3. 公开账号标识、搜索兜底、登录限制与错误信息统一展示“陶泥号”。
4. 创作侧面向创作者的称谓统一展示“陶泥儿主”。
5. 后端错误信息、默认商品文案、测试断言与文档说明同步更新。
## 3. 非目标
@@ -49,7 +49,7 @@ admin:{管理员用户名}:{邀请码}
## 验收标准
1. 未登录用户访问 `/?inviteCode=ABC123` 自动打开注册弹窗并预填 `ABC123`。
2. 有效邀请码注册成功后,被邀请人获得光点奖励,邀请关系落库。
2. 有效邀请码注册成功后,被邀请人获得泥点奖励,邀请关系落库。
3. 无效邀请码注册成功但不绑定,并返回短提示。
4. 管理员可添加邀请码并写入 metadata,重复提交同管理员同码更新 metadata。
5. 管理员邀请码被使用时不产生 `admin:*` 虚拟主体的钱包流水。
@@ -1,8 +1,8 @@
# 新用户注册默认光点落地说明
# 新用户注册默认泥点落地说明
## 目标
每个新注册用户默认获得 `10` 个光点。赠送必须由后端统一落账,前端只展示余额和流水,不在本地补发或推算。
每个新注册用户默认获得 `10` 个泥点。赠送必须由后端统一落账,前端只展示余额和流水,不在本地补发或推算。
## 落账规则
@@ -18,7 +18,7 @@
`runtime_snapshot.game_state.playerCurrency` 是运行态内的旧货币字段,不允许覆盖已经存在真实钱包业务流水的账户余额。只要用户已有非 `snapshot_sync` 的钱包流水,后续存档同步只能累计游玩时长和玩过世界,不再用 `playerCurrency` 回写 `wallet_balance`。
这样可以避免新用户注册赠送的 `10` 个光点,在首次保存 `playerCurrency = 0` 的运行态快照时被覆盖成 `0`。
这样可以避免新用户注册赠送的 `10` 个泥点,在首次保存 `playerCurrency = 0` 的运行态快照时被覆盖成 `0`。
## 影响文件
@@ -2,9 +2,9 @@
## 1. 目标
本轮在现有“我的”资料与钱包 projection 上新增兑换码能力。用户兑换成功后直接增加光点余额,写入 `profile_wallet_ledger`,并同步刷新 `profile_dashboard_state.wallet_balance`。
本轮在现有“我的”资料与钱包 projection 上新增兑换码能力。用户兑换成功后直接增加泥点余额,写入 `profile_wallet_ledger`,并同步刷新 `profile_dashboard_state.wallet_balance`。
管理侧本轮只提供后端 API,不新增管理后台页面。私有兑换码创建时支持内部 `userId` 与公开百梦号两类输入,后端创建阶段统一解析成内部 `userId` 存储。
管理侧本轮只提供后端 API,不新增管理后台页面。私有兑换码创建时支持内部 `userId` 与公开陶泥号两类输入,后端创建阶段统一解析成内部 `userId` 存储。
## 2. 兑换码类型
@@ -26,7 +26,7 @@
| --- | --- | --- |
| `code` | `String` | 主键,标准化后的兑换码。 |
| `mode` | `RuntimeProfileRedeemCodeMode` | 兑换码模式。 |
| `reward_points` | `u64` | 单次到账光点。 |
| `reward_points` | `u64` | 单次到账泥点。 |
| `max_uses` | `u32` | 公共码为单用户上限,唯一码/私有码为全局上限。 |
| `global_used_count` | `u32` | 全局已使用次数。公共码也记录总使用次数,但不参与公共码上限判断。 |
| `enabled` | `bool` | 是否启用。 |
@@ -42,7 +42,7 @@
| `usage_id` | `String` | 主键,格式 `redeem:{code}:{user_id}:{micros}:{sequence}`。 |
| `code` | `String` | 兑换码。 |
| `user_id` | `String` | 兑换用户。 |
| `amount_granted` | `u64` | 到账光点。 |
| `amount_granted` | `u64` | 到账泥点。 |
| `created_at` | `Timestamp` | 兑换时间。 |
索引:`code`、`user_id`、`(code, user_id)`。
@@ -121,7 +121,7 @@
“我的”页头像右侧入口由 `会员充值` 改为 `兑换码`。点击打开独立模态窗口,窗口内只保留输入框、兑换按钮和后端返回提示,不展示兑换规则说明。
成功后展示 `已到账 X 光点`,并刷新 profile dashboard。失败后直接展示后端 `message`。
成功后展示 `已到账 X 泥点`,并刷新 profile dashboard。失败后直接展示后端 `message`。
## 8. 测试矩阵
@@ -4,7 +4,7 @@
## 1. 目标
本轮新增一套可配置的个人任务系统,并补齐任务依赖的埋点统计能力。首个任务为“每日登录”,奖励 `10` 光点,入口放在“我的”页签;后台可修改任务配置。
本轮新增一套可配置的个人任务系统,并补齐任务依赖的埋点统计能力。首个任务为“每日登录”,奖励 `10` 泥点,入口放在“我的”页签;后台可修改任务配置。
## 2. 核心边界
@@ -13,7 +13,7 @@
- 任务配置写入 `profile_task_config`,默认配置包含 `daily_login`,后台修改后不得被默认初始化覆盖。
- 任务进度写入 `profile_task_progress`,用于任务中心快速读取状态。
- 领奖记录写入 `profile_task_reward_claim`,与钱包流水 `profile_wallet_ledger` 同事务写入。
- “星光”奖励复用现有“光点”钱包,不新增第二种货币。
- “星光”奖励复用现有“泥点”钱包,不新增第二种货币。
## 3. 埋点分层
@@ -77,7 +77,7 @@
## 9. 验收
1. `profile_task_config` 默认存在 `daily_login`,后台可修改奖励、阈值、标题和启用状态。
2. “我的”页可以打开每日任务面板,登录后任务可领取 `10` 光点。
2. “我的”页可以打开每日任务面板,登录后任务可领取 `10` 泥点。
3. 登录成功会幂等记录 `daily_login`;重复打开任务中心只记录 `task_center_view`,不会重复增加领取资格。
4. 重复领奖不会重复发放。
5. 表目录、迁移白名单、Rust/TypeScript 契约和前端入口同步更新。
@@ -2,7 +2,7 @@
## 1. 背景
当前前端展示的“百梦号”由前端基于 `AuthUser.id` 临时拼装:
当前前端展示的“陶泥号”由前端基于 `AuthUser.id` 临时拼装:
- 前缀固定为 `SY-`
- 取 `user.id` 或 `username` 去除非字母数字字符后的末 8 位
@@ -174,7 +174,7 @@
1. `id` 返回内部 ID 仅供当前工程内部跳转与资源读取使用,不在 UI 上直接暴露为文案
2. 不返回手机号、登录方式、绑定状态、tokenVersion 等敏感字段
3. 未命中返回 `404`
4. `by-id` 仅接受内部 `user_XXXXXXXX` 这类用户 ID,用于工程内跳转、运营排查或已有资源引用,不替代公开百梦号主搜索语义
4. `by-id` 仅接受内部 `user_XXXXXXXX` 这类用户 ID,用于工程内跳转、运营排查或已有资源引用,不替代公开陶泥号主搜索语义
## 5.2 广场作品公开编号搜索
@@ -251,7 +251,7 @@
## 7.1 账号展示
当前首页资料卡和桌面顶部都展示前端拼装百梦号,改为:
当前首页资料卡和桌面顶部都展示前端拼装陶泥号,改为:
1. 直接展示 `authUi.user.publicUserCode`
2. 复制按钮复制后端返回值
@@ -262,7 +262,7 @@
广场作品卡和详情页增加:
1. 作品号 `CW-XXXXXXXX`
2. 作者百梦号 `SY-XXXXXXXX`
2. 作者陶泥号 `SY-XXXXXXXX`
展示要求:
@@ -284,7 +284,7 @@
用户搜索命中后的最小行为:
1. 打开独立用户搜索结果面板或对话框
2. 展示头像字母、显示名、百梦号
2. 展示头像字母、显示名、陶泥号
3. 提供“查看该作者作品”入口
作品搜索命中后的行为:
@@ -325,7 +325,7 @@
## 11. 当前落地说明
1. 首页百梦号展示已优先读取后端 `publicUserCode`,原本基于 `AuthUser.id/username` 的前端拼装仅保留为兼容兜底,避免老会话未刷新时界面直接空白。
1. 首页陶泥号展示已优先读取后端 `publicUserCode`,原本基于 `AuthUser.id/username` 的前端拼装仅保留为兼容兜底,避免老会话未刷新时界面直接空白。
2. 用户公开搜索与广场作品公开搜索均已改为调用后端匿名接口,前端只负责输入、展示与跳转,不再自行决定最终编号格式。
3. 自定义世界发布链路已改为从认证服务读取真实 `public_user_code` 写入作品真相与广场读模型,不再从内部 `user_id` 临时反推 `SY-XXXXXXXX`。
4. 当前作品号 `public_work_code` 仍采用基于 `profile_id` 的稳定 fallback 方案生成 `CW-XXXXXXXX`;若后续补独立计数表,需要在不改变读写接口的前提下替换生成来源。

Some files were not shown because too many files have changed in this diff Show More