Files
youle_app_ohos/CLAUDE.md
T

96 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 项目概述
HarmonyOS NEXTAPI 12+,目标 SDK `6.1.1(24)`runtimeOS `HarmonyOS`)上的 **TSGame 游戏大厅原生外壳**。目标:用 ArkTS / ArkUI 声明式 / Stage 模型重写原 Android WebView 外壳,使现有 H5(大厅 + 全部子游戏 + 活动/收银台等网页)**一行不改**即可运行。
当前处于 **M0 脚手架阶段**`entry/` 仍是 DevEco 默认模板(`Index.ets` 为 Hello World),尚未落地设计文档中的多模块架构。实现工作以 `docs/设计文档/` 为唯一依据推进。
**原 Android 项目位于 `../tsgame_android`**(相对本仓库根目录)——即本项目要复刻的 WebView 外壳源头。遇到契约/行为存疑时,以该 Android 工程的实际实现为准对照。
## 工作约定
- **🔴 H5 零改动是最高铁律**:H5 网页(大厅 + 全部子游戏)必须**完美适配新项目,不做任何修改**。所有适配工作只能发生在原生侧——H5 向原生注册的接口、原生向 H5 注册的接口、双向接口的调用时机/参数/数据结构,全部以《契约规范》为准、与原 Android 行为完全一致。**任何"改一下 H5 就好了"的方案都不被接受**;H5 行为存疑时改原生实现去迁就 H5,而非反过来。这是判断一切技术方案是否成立的首要判据。
- **原生内部实现自由**:在不违背上述铁律的前提下,原生侧的内部实现(分层、模块拆分、数据结构、设计模式、用何种 HarmonyOS API/SDK、性能优化手段等)可以**根据实际情况自由设计**,不必拘泥于原 Android 的内部写法或设计文档的伪代码细节。铁律只约束"对 H5 暴露的边界行为",边界以内怎么实现由开发者按 HarmonyOS 最佳实践决定。
- **及时自动提交 git**:每完成一个可独立验收的小步骤(一个 Provider、一个状态机节点、一处可编译通过的改动)后,**主动执行 git 提交**,无需等待用户要求。提交信息用中文、说明"做了什么 + 对应契约/设计条目(如 §8、T-M1-04)"。⚠️ 仓库当前尚未 `git init`,首次提交前需先初始化。
- **及时更新计划进度**:按 `docs/设计文档/Plan/` 的计划实施时,每完成一个任务(`T-M{里程碑}-{序号}`)或推进一个里程碑,**主动更新对应计划文档的进度**——在 `01_任务分解WBS.md` 标记任务状态(`☐ 未开始 / ◐ 进行中 / ☑ 完成 / ⚠ 受阻`),受阻项同步登记到 `03_风险登记册.md`(见 `00_总体规划.md` §8 进度跟踪机制)。与代码提交同节奏,无需等用户提醒。
- HarmonyOS 相关操作(构建、运行、调试、设备、日志、查文档/SDK 签名)**必须**走 `deveco-cli` skill / `devecocli`,不要手搓 `hvigorw` 命令或直连 MCP HTTP 桥。
- **禁止直接编辑 `project.godot` 类生成文件**;本项目对应的是 **不要手改 `oh-package-lock.json5`、`build/` 产物、`.hvigor/`**——它们由工具生成。
- **调试产物统一放 `docs/spike/`**:调试/排查时产生的临时文件(hilog 日志、`hdc` 截图、抓包、临时验证脚本等)一律落在 `docs/spike/` 下,**不要散在仓库根目录**;这类文件不提交(应被 `.gitignore` 忽略),排查结束后可随时清理。临时埋点代码(验证用的 `onTouch` 打点、spike 方法等)验证完必须从源码移除。
## 常用命令
构建/运行/测试统一通过 `devecocli`(见 `deveco-cli` skill):
- 构建 HAPdebug):`devecocli build`(底层 hvigor `assembleHap`,产物 `entry/build/default/...`
- 运行到设备/模拟器:`devecocli run`;设备列表 `devecocli devices`
- 真机/模拟器日志:`devecocli log`hilog
- 查 SDK API 签名 / 鸿蒙文档:`devecocli docs <关键词>`(编码前核对 `@ohos.*` / `@kit.*` 实际签名)
测试(Hypium`@ohos/hypium` + `@ohos/hamock`):
- 本地单元测试:`entry/src/test/``LocalUnit.test.ets``List.test.ets`)——纯逻辑,不依赖设备
- 设备插桩测试:`entry/src/ohosTest/``Ability.test.ets` 等)——需真机/模拟器
- 通过 `devecocli test` 触发;目标:桥引擎 / `VersionResolver` / `MessageCodec` 单测覆盖率 **≥80%**
代码检查(`code-linter.json5`,仅作用于 `**/*.ets`):
- 规则集 `@performance/recommended` + `@typescript-eslint/recommended`
- **`@security/no-unsafe-*` 一组加密规则为 `error`**:禁用不安全的 AES/Hash/MAC/DH/DSA/ECDSA/RSA/3DES,写加密代码时务必遵守
## 架构(big picture,需读多文件才能掌握)
> 真正的架构在设计文档里,代码尚未落地。三份 SSOT 文档(修改实现前必读对应章节):
> - `docs/设计文档/TSGame_原生与H5接口契约总规范.md` —— **对外不可变契约**(H5 零改动的判据:handler 名、参数、数据结构、调用时机)
> - `docs/设计文档/TSGame_HarmonyOS框架设计与开发指南.md` —— HarmonyOS 侧如何实现(分层、桥、容器、启动)
> - `docs/设计文档/Plan/` —— 落地计划:`00_总体规划` / `01_任务分解WBS`(任务 ID `T-M{里程碑}-{序号}`/ `02_测试与验收` / `03_风险登记册`
### 分层(依赖单向向下,跨层只依赖接口)
```
① 应用/编排层 EntryAbility · StartupOrchestrator · 路由 · DI 组装根(AppModule)
② 容器层 BridgeGameContainer(大厅/子游戏) │ GenericWebContainer(通用网页)
③ 桥引擎层 BridgeController · MessageCodec · HandlerRegistry · SettingsProxy
④ 能力层 每个原生能力 = 一个 CapabilityProvider 插件(share/login/location/...)
⑤ 领域服务层 ConfigManager · ResourceManager · AppDataInjector · VersionResolver
⑥ 平台服务层 HttpClient · Downloader · Unzipper · KvStore · LocalUploadServer · TaskScheduler
横切层 Logger/Tracer · ErrorCenter · EventBus · DIContainer · Contracts(TS类型 SSOT)
```
目标多模块拆分(HAR/HSP):`entry`(①②) / `feature_bridge`(③) / `feature_capabilities`(④) / `domain_resource`(⑤) / `platform`(⑥) / `contracts`(契约类型) / `common`(横切)。
### 三条不可违背的关键约束
1. **桥核心对能力零感知**`feature_bridge` 不 import 任何具体能力,只持 `HandlerRegistry`;能力启动时把自己的 handler 注册进去。新增能力 = 新增一个 `CapabilityProvider`,零侵入桥核心。`contracts` HAR 用 `enum`/`interface` 固化所有 handler 名与 DTO,是全工程唯一来源(杜绝 `finsh`/`getcameraaAddress` 等拼写漂移)。
2. **出站下发必须在 UI 线程**(§5.5):`runJavaScript` 只能在 UI 线程调用,而能力回调常在非 UI 线程。`BridgeController.dispatch` 内置 UI 线程守卫;Provider 不关心线程,任意线程 `callHandler` 最终都在 UI 线程下发。
3. **TaskPool 只搬 Sendable**(§9.1):`@Concurrent` 任务跨线程传参/返回值必须是 Sendable**不能传** callback / `WebviewController` / `UIAbilityContext`。下载/解压进度一律经 `emitter`/`AppStorage` 回 UI 线程,不要跨线程传函数。
### 桥协议核心("H5 零改动"命门,100% 复刻 lzyzsd/JsBridge
- H5→原生:`Web().onLoadIntercept` 拦截 `yy://`(含 iframe 导航);`yy://return/` 前缀走回执,其余触发 `flushMessageQueue()`
- **队列回传不靠 `runJavaScript` 返回值**`_fetchQueue()` 在 H5 内把 `iframe.src` 置为 `yy://return/_fetchQueue/<队列JSON>`,再次经 `onLoadIntercept``handleReturnData` 路由到预登记的 `_fetchQueue` 回调。务必忠实复刻此机制。
- 原生→H5`controller.runJavaScript("WebViewJavascriptBridge._handleMessageFromNative('"+json+"');")`;桥 JS 在 `onPageEnd` 注入(直接复用库原文件)。
- **必须设 `DefaultHandler`(空实现)**:未注册的 handler 名落到默认空实现而不抛错,是"H5 调用永不报错"的最后防线。
### 双容器模型
- **BridgeGameContainer**(大厅/子游戏,对应 Android `webviewActivity`):挂桥协议;`app_data.js` 必须在**加载页面之前**由 `AppDataInjector` 写入(H5 同步 `<script src>` 读取),切勿放到 `onPageEnd``setPostUrl`/`appservice` 在首次进度 100% 时下发。子游戏切换 = 同容器 `loadUrl`,不重建组件。
- **GenericWebContainer**(通用网页,对应 `openwebActivity1`):**不挂桥**,用 `javaScriptProxy` 注入 `settings` 对象(6 方法)+ `runJavaScript` 直调;回传走结果码 101 语义经 `emitter`/路由投回上层 Bridge 容器。
### 本期范围与占位桩
本期实现分享/登录/定位/音频/摇一摇/扫码/相机/震动/剪贴板/网络/设备等 Provider。**视频房(声网)与支付用占位桩**(`RoomStubProvider`/`PayStubProvider`,§6.5):仍注册 handler,但 void 型空实现、有同步返回的回安全默认值、绝不触发出站推送——保证 H5 调用不报错、不卡死。**闲聊不涉及**(无 H5 桥接口)。组装根 `buildCapabilities()` 是唯一知道"全部能力"的地方,未来换回真实 Provider 即可。
### 两个最高风险"阻塞性验证"(必须最先证伪)
- **M1**`yy://` 的 iframe 导航是否稳定触发 `onLoadIntercept`(不同 ArkWeb 版本有差异)。失败回退:`onInterceptRequest`+`WebSchemeHandler` → 或改注入 `javaScriptProxy` 同步通道(对 H5 仍透明)。
- **M2**`file://` 加载下 H5 的 XHR/fetch 取本地资源是否可用。失败启用官方跨域方案(自定义协议 / `onInterceptRequest`)。
### 生产加固红线(附录 B
- `setWebDebuggingAccess(true)` **仅 debug 包**`BuildProfile.DEBUG` 守卫),release 必关。
- 密钥(微信 `AppSecret`、支付 `API_KEY`)**不入客户端**:登录走 code、支付签名走服务端。
- 明文 HTTP 域名需在 `module.json5` 网络安全配置显式放行;`gamepaywelcome` 等外部唤起 scheme 在 `abilities.skills.uris` 声明。