# H5 体验接入方案
> 文档版本：v1.0
> 最后更新：2026-04-02 08:28:05


本文档用于定义当前项目中 **原生小程序 + H5 定制内容** 的混合接入方案。

目标：

- 保留原生地图与实时游戏主流程
- 把高频变化、强定制的内容页交给 H5
- 保证 H5 失败时，原生仍可完整兜底
- 为后续客户定制、品牌包装、互动任务扩展留出稳定接口

---

## 1. 结论

当前最合适的方向不是“所有定制都 H5 化”，而是：

**原生负责核心游戏层，H5 负责定制体验层。**

也就是：

- 地图、打点、GPS、指北针、HUD、规则状态机继续原生
- 结算页、文创详情、拍照任务、语音留言、小游戏、品牌包装页交给 H5

---

## 2. 适合 H5 化的内容

当前最适合 H5 承接的是：

- 结算页
- 打点后的定制**详情页/互动页**
- 文创详情页
- 活动品牌页
- 富图文任务页
- 拍照上传 / 语音留言 / 小游戏类互动页
- 表单、问卷、抽奖、作品提交页

不建议 H5 化的部分：

- 地图主界面
- 打点逻辑
- 自动转图
- 指北针
- HUD
- GPS / 心率等实时能力主链
- 需要强实时状态同步的高频游戏弹层
- 游戏中的即时原生内容弹窗

一句话：

**核心实时游戏层保留原生，变化快的定制内容层交给 H5。**

---

## 2.1 当前阶段的定案

经过真机验证，当前项目已经明确：

- 小程序 `web-view` 在企业主体环境下可以正常打开
- 但它不适合作为“原生弹窗里的局部 H5 内容区”使用
- 真机上更接近整页原生容器，局部裁切、壳子覆盖、原生关闭按钮都不稳定

因此当前正式定案为：

- **打点后的即时内容：原生内容卡**
- **H5：只作为详情页 / 互动任务页 / 全屏结果页**

也就是说：

- `content popup` 继续原生
- 原生内容卡上提供 `查看详情`
- 点 `查看详情` 后再进入 H5
- H5 打不开时，原生内容卡继续兜底

---

## 3. 总体架构

推荐分成三层：

### 3.1 原生层

职责：

- 地图与渲染
- GPS / 指北针 / 自动转图
- 打点状态机
- HUD
- 心率 / telemetry
- 原生内容卡兜底
- 原生结果页兜底
- 核心状态与本地缓存

### 3.2 H5 体验层

职责：

- 定制内容展示
- 品牌包装
- 富交互任务
- 定制结算页
- 富图文与媒体内容

### 3.3 Bridge 层

职责：

- 原生向 H5 注入上下文
- H5 向原生请求能力
- H5 把结果回传原生

---

## 4. 两种 H5 页面类型

### 4.1 Content Experience Page

用于游戏中途的**详情体验页**或**互动任务页**。

典型场景：

- 控制点打卡后点击 `查看详情`
- 控制点点击后进入图文详情页
- 拍照上传任务
- 语音留言任务
- 小游戏互动页
- 问答/表单类互动页

### 4.2 Result Experience Page

用于游戏结束后的定制结算页。

典型场景：

- 活动定制结算
- 奖章 / 解锁内容
- 排名 / 分享
- 作品提交
- 品牌化结束页

---

## 5. 原生兜底原则

这是最重要的约束。

### 原则 1：核心流程先在原生完成

例如：

- 打点成功必须先由原生确认
- 比赛结束必须先由原生确认
- H5 只是附加体验，不拥有核心状态
- 原生内容卡必须先可独立工作

### 原则 2：H5 打不开时回退原生

如果：

- 网络失败
- H5 地址失效
- 加载超时
- Bridge 初始化失败

则直接回退：

- 原生内容卡
- 原生结果页

### 原则 3：H5 不控制比赛状态

H5 可以展示、收集信息、提交任务结果。
但不能决定：

- 是否打卡成功
- 是否比赛完成
- 是否跳点成功

这些只能由原生控制。

### 原则 4：H5 是可选增强，不是主流程依赖

即使 H5 没有打开：

- 游戏仍应可继续
- 用户仍能完成路线
- 用户仍能看到最小内容或最小结果

---

## 6. 配置模型建议

后续建议对“内容体验”和“结果体验”都支持两种类型：

- `native`
- `h5`

### 6.1 内容体验配置示例

```json
{
  "contentExperience": {
    "type": "h5",
    "url": "https://example.com/content/control-3",
    "bridge": "content-v1",
    "fallback": "native"
  }
}
```

这个字段当前应理解为：

- `contentExperience` = 原生内容卡上的 H5 **详情/互动扩展**
- 不是直接顶替原生内容弹窗

或：

```json
{
  "contentExperience": {
    "type": "native"
  }
}
```

### 6.2 结果页配置示例

```json
{
  "resultExperience": {
    "type": "h5",
    "url": "https://example.com/result/score-o",
    "bridge": "result-v1",
    "fallback": "native"
  }
}
```

### 6.3 建议扩展字段

后续还可以逐步加入：

- `template`
- `theme`
- `timeoutMs`
- `allowClose`
- `prefetch`
- `requiresNetwork`

---

## 7. 内容页与结果页的推荐职责

### 原生最小内容卡

负责：

- 最小图文说明
- 最小点击查看
- 自动弹出兜底

### H5 内容页

负责：

- 强样式定制
- 多媒体内容
- 任务型互动
- 客户活动包装

### 原生最小结果页

负责：

- 结果一定可见
- 成绩一定可回顾
- 无网络也能展示基础结果

### H5 结果页

负责：

- 品牌化包装
- 排名/分享
- 作品提交
- 奖章、解锁、收集册

---

## 8. 性能与体验要求

H5 接入时必须注意：

- 不阻塞原生主流程
- 不把高频实时状态强行桥接到 H5
- 不在地图进行中频繁开重页面
- 低端机上优先简化交互和媒体资源

推荐策略：

- 内容详情页可以 H5
- 地图中高频反馈继续原生
- 结算增强页可以 H5
- 结果最小摘要必须原生兜底

---

## 9. 当前建议实施顺序

### 第一步

先实现：

- 原生最小兜底内容卡
- 原生最小结果页

### 第二步

新增一个通用 H5 容器页，用于承接：

- 内容页
- 结果页

### 第三步

定义 Bridge 协议，并先支持最核心动作：

- 关闭
- 获取上下文
- 拍照
- 录音
- 提交结果

### 第四步

再让配置决定：

- 当前活动走原生
- 还是走 H5

### 第五步

最后再逐步扩到：

- 上传能力
- 分享能力
- 小游戏任务
- 作品提交

---

## 10. 下一步建议

当前最适合的下一步不是直接写复杂 H5 页面，而是：

1. 先定义原生与 H5 的统一入口模型
2. 先把 Bridge 协议做小而稳
3. 先做一个通用 H5 容器页
4. 先让一个简单内容页或一个简单结果页跑通

---

## 11. 当前建议结论

最稳的方案不是“把定制内容都做成 H5”，而是：

**原生保底，H5 承接定制体验。**

这样既能支持客户高频变化需求，也不会破坏核心游戏体验。

---

## 12. 当前主体能力约束补充

最近实际排查已经确认：

- 当前最初使用的是**个人主体**小程序

在这个前提下，`web-view` 能力可能直接受到限制。  
这意味着：

- H5 页面本身可在浏览器打开
- 小程序里仍然可能无法通过 `web-view` 打开

因此当前 H5 接入方案需要增加一个现实前提：

### 12.1 个人主体下

可以先做：

- 容器页
- Bridge 协议
- 配置结构
- 原生兜底逻辑

但不要指望所有 H5 内容页都能在当前环境稳定跑通。

### 12.2 企业主体下

企业主体审核通过后，再优先回归：

- 最小 `web-view` 测试页
- 内容体验页 H5
- 结果页 H5

也就是说：

当前 H5 方案仍然成立，但在企业主体生效前，应按“预留 + 待验证”看待。

详细说明见：

- [platform-capability-notes.md](D:/dev/cmr-mini/doc/debug/平台能力说明.md)



