# 宝贝识物创作发布实现方案 2026-05-11 ## 1. 范围 本方案对应第 2 线程:创作发布线程。 本线程落地: 1. 创作入口配置; 2. 模板表单; 3. 本地草稿生成 service; 4. 结果页; 5. 发布 payload 约束; 6. 本地 Demo 运行态; 7. 后端 image-2 / 作品持久化 / 运行态接口预留形状。 本阶段运行态先做浏览器本地 Demo,并消费现有本地 mocap 动作数据源;正式硬件接口和摄像头调教在后续接口稳定后继续接入。 ## 2. 前端接入点 新增玩法 ID: ```text baby-object-match ``` 用户展示名: ```text 宝贝识物 ``` 入口文件: 1. `src/config/newWorkEntryConfig.ts` 2. `src/components/platform-entry/platformEntryCreationTypes.ts` 3. `src/components/platform-entry/PlatformEntryCreationTypeModal.tsx` 4. `src/components/platform-entry/PlatformEntryFlowShellImpl.tsx` `baby-object-match` 必须复用 `VITE_ENABLE_EDUTAINMENT_ENTRY` 开关;开关关闭时,创作类型弹层不展示 `宝贝识物`,创作页作品架不展示本地宝贝识物草稿或已发布作品卡,公开发现、搜索、详情、作品号和浏览历史也继续完全不可见。 新增阶段: ```text baby-object-match-workspace baby-object-match-generating baby-object-match-result baby-object-match-runtime ``` ## 3. 契约 前端共享契约放在: ```text packages/shared/src/contracts/edutainmentBabyObject.ts ``` 核心字段: 1. `BabyObjectMatchDraft.templateId = "baby-object-match"`; 2. `BabyObjectMatchDraft.templateName = "宝贝识物"`; 3. `BabyObjectMatchDraft.themeTags` 必须包含精确 `寓教于乐`; 4. `BabyObjectMatchItemAsset.generationProvider` 首版允许为 `vector-engine-gpt-image-2` 或 `placeholder`; 5. `BabyObjectMatchPublishRequest.draft.themeTags` 发布前必须归一化补齐 `寓教于乐`。 ## 4. Service 边界 前端 service 放在: ```text src/services/edutainment-baby-object/babyObjectMatchClient.ts ``` 首版提供: 1. `createBabyObjectMatchDraft(payload)`; 2. `saveBabyObjectMatchDraft(draft)`; 3. `publishBabyObjectMatchWork(payload)`。 当前后端正式接口未在本线程扩表落地,因此 service 先走本地 Demo 存储,并把 asset 结果标记为 `placeholder`。后续后端接入时,应替换为: ```text POST /api/creation/edutainment/baby-object-match/drafts PUT /api/creation/edutainment/baby-object-match/drafts/{draftId} POST /api/creation/edutainment/baby-object-match/drafts/{draftId}/publish ``` 图片生成必须在后端调用 VectorEngine `gpt-image-2-all`,不得从前端直接调用外部图片接口。 ## 5. UI 边界 工作台只展示两个必填输入和生成按钮。 结果页只展示草稿核心信息、两个物品、保存草稿、发布、试玩。不在 UI 内写玩法说明长文案。 移动端优先:表单和结果页使用单列布局,桌面端自然扩展为双列。 ## 6. 运行态边界 前端运行态放在: ```text src/components/edutainment-runtime/BabyObjectMatchRuntimeShell.tsx ``` 运行态直接消费 `BabyObjectMatchDraft`,必须使用草稿中的两个物品名称和物品图。 每轮只随机当前从礼物盒跳出的物品;左右篮子不随机交换,左侧固定为草稿 `itemAssets[0]`,右侧固定为草稿 `itemAssets[1]`。 首关状态机: 1. `waiting`:礼物盒关闭,等待任意手抬起; 2. `active`:当前物品停留在屏幕中央; 3. `correct`:展示“真棒”反馈,成功次数加 1; 4. `wrong`:展示“再想一想吧”反馈,当前物品回到中央; 5. `complete`:成功次数达到 20,展示“恭喜你!小朋友!”和按钮。 动作输入: 1. 任意手完成一次 `open_palm -> grab` 抓握序列:打开礼物盒并生成当前物品; 2. 左手连续横向移动达到阈值:将当前物品送入左侧篮子; 3. 右手连续横向移动达到阈值:将当前物品送入右侧篮子。 运行态直接通过 `useMocapInput` 消费本地 mocap WebSocket `/stream`。选篮只使用明确 `leftHand` 或 `rightHand` 的连续横向轨迹阈值,不再通过 `wave_left_hand`、`wave_right_hand`、`wave` 等动作名触发;侧别为 `unknown` 的手部轨迹也不参与选篮,以避免多套判定误命中和连续误触发。当前本地 mocap 输出的 handedness 按摄像头视角标记,宝贝识物运行态必须先换算为用户身体视角:`rightHand` 轨迹映射玩家左手并进入左侧篮子,`leftHand` 轨迹映射玩家右手并进入右侧篮子。草稿试玩、发布后正式体验和热身关后的本地 Demo 都复用同一个运行态,因此三条入口都必须具备同一套动作控制能力。 开发者调试输入: 1. `F`:映射任意手抬起,打开礼物盒并生成当前物品; 2. 鼠标左键按下并拖动:映射左手轨迹,抬起后将当前物品送入左侧篮子; 3. 鼠标右键按下并拖动:映射右手轨迹,抬起后将当前物品送入右侧篮子。 运行态不得新增计时、失败次数、分数、体力或难度递增规则。 音效和语音播报当前只保留接口预留边界,正式语音接口后续接入。 ## 7. 发布约束 发布前必须执行: 1. 两个物品名非空; 2. 两个物品名对应的 asset 存在; 3. 标签补齐精确 `寓教于乐`; 4. `publicationStatus` 从 `draft` 变为 `published`。 发布后首版本地响应返回 `publicWorkCode`,用于分享弹窗;正式后端接入时 public code 生成规则需要纳入统一作品号服务。 ## 8. 热身关衔接 `/child-motion-demo` 热身完成后的“开始游戏”按钮进入同一个 `BabyObjectMatchRuntimeShell`。 热身关独立 Demo 没有创作者草稿上下文,因此使用固定本地 Demo 草稿承载两个物品,仅用于热身关后验证首关体验;正式平台体验仍必须从 `宝贝识物` 模板创作发布后进入寓教于乐板块。 ## 9. 验收命令 ```bash npm run test -- src/components/platform-entry/platformEntryCreationTypes.test.ts src/components/edutainment-creation/BabyObjectMatchWorkspace.test.tsx src/components/edutainment-result/BabyObjectMatchResultView.test.tsx src/components/edutainment-runtime/BabyObjectMatchRuntimeShell.test.tsx src/components/child-motion-demo/ChildMotionWarmupDemo.test.tsx src/services/edutainment-baby-object/babyObjectMatchClient.test.ts npx vitest run src/components/platform-entry/platformEdutainmentVisibility.test.ts src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/custom-world-home/creationWorkShelf.test.ts src/services/useMocapInput.test.ts src/services/child-motion-demo/childMotionDebugInput.test.ts src/routing/appRoutes.test.ts npx eslint src/components/platform-entry/platformEntryCreationTypes.ts src/components/platform-entry/platformEntryCreationTypes.test.ts src/components/platform-entry/PlatformEntryFlowShellImpl.tsx --ext .ts,.tsx --max-warnings 0 npm run check:encoding npm run typecheck npm run build:raw ``` 若后续接入真实 Rust API 和 SpacetimeDB 表,再补充 `npm run api-server`、`/healthz`、Rust contract / api-server / spacetime-client 定向测试和 migration 表目录更新。