feat: add child motion entry and fix auth env
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-05-10 18:27:51 +08:00
parent 86fc382413
commit 46a254f142
22 changed files with 2868 additions and 58 deletions

View File

@@ -16,6 +16,8 @@
后续生产的该内容线模板和游戏关卡,都放置在“寓教于乐”独立标签下。
该内容线当前只覆盖儿童动作识别 Demo 内容。后续创作环节需要继续对该板块内容做区分和独立管理,不把普通公开作品仅凭近似教育题材自动归入本板块。
## 2. 展示边界
寓教于乐内容不直接展示在以下位置:
@@ -29,6 +31,8 @@
寓教于乐内容只在“发现 / 寓教于乐”标签下展示。
“寓教于乐”标签在发现页频道列表中放在最后,桌面端和移动端都显示。移动端访问该内容线的动作识别 Demo 时,需要提示横屏体验。
## 3. 开关规则
该入口需要支持灵活开关。
@@ -43,13 +47,14 @@
1. 发现页隐藏“寓教于乐”标签;
2. 隐藏“寓教于乐”标签下内容;
3. 该内容线内容不进入推荐、今日、分类、排行和搜索结果
3. 该内容线内容不进入推荐、今日、分类、排行和搜索结果
4. 该内容线内容完全不可见,公开作品搜索、作品号搜索直达、公开详情深链、浏览历史入口等平台公开入口都不能打开该内容。
## 4. 内容识别规则
临时阶段使用作品标签识别寓教于乐内容。
当公开作品标签中包含
当公开作品标签中存在一个精确等于以下文本的标签
```text
寓教于乐
@@ -57,6 +62,10 @@
则该作品归入寓教于乐内容线。
识别规则为精确匹配,不做包含匹配,不兼容空格、大小写变体或同义标签,例如“教育”“儿童教育”“动作教育”都不视为寓教于乐内容。
关闭开关时,即使作品具备精确的“寓教于乐”标签,也不允许通过任何平台公开展示入口或搜索入口访问。
## 5. 技术落地边界
本次只做前端入口和前端展示过滤,不新增后端接口。
@@ -87,3 +96,22 @@ no
3. 带有“寓教于乐”标签的公开作品不进入推荐页。
4. 带有“寓教于乐”标签的公开作品不进入发现页推荐、今日、分类、排行和搜索结果。
5. 带有“寓教于乐”标签的公开作品只在“发现 / 寓教于乐”标签下展示。
6. “寓教于乐”标签位于发现页频道列表最后,桌面端和移动端均可见。
7. 开关关闭后,带有“寓教于乐”标签的公开作品不可通过作品号搜索、公开详情深链或浏览历史入口打开。
8. 标签识别只接受精确等于“寓教于乐”的作品标签,近似标签不归入该内容线。
## 7. 待补充事项
“寓教于乐”标签下暂无内容时的空状态文案待定。落地时可先复用平台现有空状态组件,但不新增功能说明类长文案。
## 8. 第 1-2 项工程落地状态
第 1 项“发现页入口与过滤”和第 2 项“搜索 / 深链 / 历史入口拦截”已进入前端落地阶段,当前实现口径如下:
1. 入口开关由 `VITE_ENABLE_EDUTAINMENT_ENTRY` 控制,默认开启,显式配置 `false``0``off``no` 时关闭。
2. 内容识别集中在 `src/components/platform-entry/platformEdutainmentVisibility.ts`,只读取公开作品原始 `themeTags`,且只接受精确等于“寓教于乐”的标签。
3. `src/components/rpg-entry/RpgEntryHomeView.tsx` 已在发现页频道末尾追加“寓教于乐”频道,并将该类作品从推荐、今日、分类、排行、搜索、本地搜索兜底和桌面推荐模块中过滤。
4. `src/components/platform-entry/PlatformEntryFlowShellImpl.tsx` 已复用同一过滤 helper避免推荐运行态自动启动寓教于乐作品并在公开详情、作品号直达和公开详情深链等公开入口保留不可见保护。
5. 浏览历史入口会优先按当前公开作品集合匹配作品标签;匹配到“寓教于乐”作品且开关关闭时不再展示历史入口。
6. `/child-motion-demo` 本地动作 Demo 直达路由也复用同一开关;开关关闭时不匹配独立 Demo 应用,回落到主站入口。
7. 定向回归覆盖在 `src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx``src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx``src/components/platform-entry/platformEdutainmentVisibility.test.ts``src/routing/appRoutes.test.ts`包含频道顺序、开关关闭、普通列表过滤、搜索过滤、作品号直达拦截、Demo 直达路由拦截和精确标签识别。

View File

@@ -137,3 +137,19 @@
4. `npm run dev` / `npm run dev:rust` 完整栈默认由脚本计算 API 端口;加载 `.env.local` 给后端使用后,脚本必须重新固定 `RUST_SERVER_TARGET`,避免 `.env.local` 中的旧代理目标覆盖本次启动的实际 API 端口。
5. `npm run dev:web` 只启动前端,不会自动拉起 Rust API如果 `.env.local` / 当前环境已经显式声明 `GENARRATIVE_RUNTIME_SERVER_TARGET``RUST_SERVER_TARGET``GENARRATIVE_API_TARGET``GENARRATIVE_API_PORT`,脚本必须固定使用该目标。目标当下不可用时只打印警告,不自动切到另一个端口,避免前端进程长时间绑定到随后会停掉的临时 API。
6. 如果 `3000` 仍然返回 `500`,先确认浏览器是不是还开着旧的前端进程。当前脚本如果因为端口占用漂移到 `3001` / `3002`,应直接关掉旧进程后重启,而不是继续用旧的 3000 页面判断登录入口状态。
## 11. 2026-05-10 `npm run api-server` 环境加载与短信 provider 排查记录
本地单独启动 `api-server` 时,环境变量合并顺序固定为:
```text
外层 shell > .env > .env.local > .env.secrets.local
```
这保证 `.env.local` 能覆盖 `.env.example` 派生出的默认值,`.env.secrets.local` 能继续覆盖本地私密密钥配置。`scripts/api-server-dev.mjs` 不得让 `.env` 后加载并覆盖 `.env.local`,否则 `SMS_AUTH_ENABLED``SMS_AUTH_PROVIDER` 可能被压回错误值。
排查“点击获取验证码但手机收不到短信”时,除了确认 `availableLoginMethods` 包含 `phone`,还必须确认当前进程实际使用的 provider
1. `SMS_AUTH_PROVIDER="mock"` 只用于本地 UI / 账号链路联调,不会向手机发送真实短信;此时应使用 `SMS_AUTH_MOCK_VERIFY_CODE`,默认 `123456`
2. 真实短信链路必须使用 `SMS_AUTH_PROVIDER="aliyun"`,并在修改 `.env.local` 后重启 `api-server`,运行中的进程不会自动切换 provider。
3. 真实 provider 是否被使用,以 `api-server` 日志中的 `provider=aliyun``provider_request_id``provider_out_id` 为准。

View File

@@ -21,6 +21,8 @@
9. 后续关卡使用热身记录的边界进行安全提醒和暂停恢复。
10. 热身结束后进入关卡选择。
当前阶段先落浏览器本地 Demo。浏览器摄像头视频流已接入舞台背景摄像头硬件动作识别 SDK、正式动作识别接口和正式语音播报接口继续预留适配层不阻塞前端热身流程、调试输入和页面表现骨架落地。
## 2. 非目标范围
热身关当前不包含以下内容:
@@ -33,6 +35,7 @@
6. 不做特定用户识别。
7. 不跨会话保存左右空间边界、手臂挥动空间和跳跃空间。
8. 不对手部细节进行识别,只对肢体进行区分。
9. 本阶段不处理无硬件、拒绝摄像头、多人入镜、识别丢失等异常流程;这些问题记录为待决策事项,后续硬件与摄像头方案稳定后再重新设计。
## 3. 运行入口与流向
@@ -44,6 +47,8 @@
用户完成热身关所有步骤后,进入关卡选择。
当前后续游戏仍在设计中。热身结束后可先展示“开始游戏”按钮作为关卡选择占位,用户点击后进入下一关占位界面。
### 3.3 固定流程顺序
热身关必须按照以下顺序执行:
@@ -166,6 +171,20 @@
4. 动作类状态没有最长等待时间。
5. 动作类状态等待 3 秒后可以播放对应引导动画。
### 6.3 开发者调试输入
本地 Demo 需要支持开发者调试模式,用于无摄像头和自动化验证场景。
调试映射如下:
1. `A` 键映射用户向左移动。
2. `D` 键映射用户向右移动。
3. 鼠标左键按下并拖动映射左手轨迹。
4. 鼠标右键按下并拖动映射右手轨迹。
5. 空格键映射原地跳跃。
调试输入只作为本地 Demo 与测试辅助,不代表正式动作识别硬件口径。正式摄像头接入后,位置、手势和跳跃判断需要按摄像头硬件调教结果重新校准。
## 7. 分步骤开发规格
### 7.1 进入热身关
@@ -438,6 +457,12 @@
4. 右手挥动空间。
5. 跳跃空间。
当前 Demo 体验会话数据需要满足:
1. 用户刷新产品或退出产品后失效。
2. 用户只关闭当前游戏关卡并重新进入时,可以直接来到开始游戏界面,不强制重复热身。
3. 首版可使用前端运行时内存或同等生命周期容器保存;不得跨产品刷新持久化保存。
### 8.2 当前 Demo 体验会话定义
“当前 Demo 体验会话”指用户本次打开并体验 Demo 的过程。
@@ -523,10 +548,14 @@
18. 关卡暂停时屏幕中央地面绿色圆圈。
19. 关卡暂停提示文案。
角色剪影、绿色圆环、虚影提醒、圆圈消失特效、手势引导动画和热身结束特效的正式视觉资源将通过 gpt-image-2 设计和生成。本地 Demo 阶段可以先使用 CSS、Canvas 或临时占位资源实现相同交互位置与状态,不把占位资源写死为正式资产。
## 12. 固定文案与语音清单
以下文案需要作为屏幕中上方浮现文字,并同步语音播报。
正式语音播报后续接入语音播报功能接口。本地 Demo 阶段保留播报适配层与调用点,可先只展示文字,不强制生成或播放正式语音资产。
```text
欢迎你,小朋友,见到你真开心
请你来到圆圈这里和我打个招呼吧
@@ -593,10 +622,49 @@
当前需求已明确本文所需的热身关开发规格。
以下内容未在当前文档中强行定义,后续如进入工程实现阶段,可再补充对应技术细节
以下内容作为待决策事项保留,后续硬件、摄像头和正式关卡设计稳定后再补充
1. 具体接入的动作识别 SDK 或硬件接口。
2. 角色剪影、圆环、虚影提醒、特效、手势引导动画的具体资源文件命名
3. 当前 Demo 体验会话数据在前端状态、运行时上下文或其他容器中的具体存放位置
4. 绿色圆环、角色剪影、安全边界在线性空间或屏幕坐标中的具体计算公式。
5. 关卡选择页的具体页面结构。
1. 具体接入的动作识别 SDK、硬件接口和摄像头接口。
2. 无硬件、摄像头拒绝授权、多人入镜、识别不到用户、跟踪丢失等异常流程
3. 角色剪影、圆环、虚影提醒、特效、手势引导动画的正式资源文件命名
4. 绿色圆环、角色剪影、安全边界在线性空间或屏幕坐标中的正式计算公式。
5. 正式关卡选择页与后续游戏关卡的具体页面结构。
## 15. 第 3 项本地 Demo 落地记录
本地浏览器 Demo 入口已落在:
```text
/child-motion-demo
```
当前实现范围:
1. `src/ChildMotionDemoApp.tsx` 挂载独立 Demo 应用壳。
2. `src/components/child-motion-demo/childMotionWarmupModel.ts` 维护热身步骤、圆环目标、2 秒保持判定、热身校准记录和当前运行时会话完成标记。
3. `src/components/child-motion-demo/ChildMotionWarmupDemo.tsx` 实现横屏舞台、背景虚化占位层、角色剪影、绿色圆环、手势引导、热身记录面板、热身完成后的“开始游戏”按钮和下一关占位界面。
4. `src/services/child-motion-demo/childMotionDebugInput.ts` 保留开发者调试输入适配层,后续可被正式动作识别 SDK 适配层替换或并行接入。
5. `src/routing/appRoutes.tsx` 新增 `/child-motion-demo` 独立路由,并复用 `VITE_ENABLE_EDUTAINMENT_ENTRY` 开关;开关关闭时不允许通过该直达路径进入 Demo。
当前调试输入:
1. `A` 键映射用户向左移动,松开后回到中心。
2. `D` 键映射用户向右移动,松开后回到中心。
3. 鼠标左键按下并拖动映射左手轨迹。
4. 鼠标右键按下并拖动映射右手轨迹。
5. 空格键映射原地跳跃。
当前未接入但已保留边界:
1. 浏览器摄像头视频流已接入;硬件动作识别 SDK 和正式动作识别接口暂不接入,后续通过动作输入适配层替换或并行接入调试输入。
2. 正式语音播报接口暂不接入,当前先展示热身文案。
3. 正式 gpt-image-2 视觉资源暂不接入,当前使用 CSS 占位表达相同位置和状态。
4. 后续关卡安全边界暂停逻辑暂未落地,当前只完成热身记录和下一关按钮占位。
已执行的定向验证命令:
```bash
npx eslint src/components/child-motion-demo/ChildMotionWarmupDemo.tsx src/components/child-motion-demo/childMotionWarmupModel.ts src/components/child-motion-demo/ChildMotionWarmupDemo.test.tsx src/components/child-motion-demo/childMotionWarmupModel.test.ts src/services/child-motion-demo/childMotionDebugInput.ts src/services/child-motion-demo/childMotionDebugInput.test.ts src/services/child-motion-demo/index.ts src/ChildMotionDemoApp.tsx src/routing/appRoutes.tsx src/routing/appRoutes.test.ts --ext .ts,.tsx --max-warnings 0
npx vitest run src/components/child-motion-demo/childMotionWarmupModel.test.ts src/components/child-motion-demo/ChildMotionWarmupDemo.test.tsx src/services/child-motion-demo/childMotionDebugInput.test.ts src/routing/appRoutes.test.ts
npm run check:encoding
```