BeeX H5 离线包双渠道技术设计

当前事实版 · INTERNAL / RELEASE 双渠道 · 更新于 2026-07-23

1. 核心决策

BeeX 不再按“测试环境包 / 正式环境包”构建 H5。一次流水线从同一个 commit 同时产出 INTERNALRELEASE 两个包渠道。Native 版本只决定包渠道; 只有 INTERNAL 包才读取 Native 当前选择的业务环境。
一句话真值:88.88.88 → INTERNAL;其他 Native 版本 → RELEASE。请求来自哪个 API Host、Query 里的 envCode 是什么, 都不能改变这个结论。

2. 两个独立维度

维度可选值决定什么不能决定什么
包渠道 INTERNAL / RELEASE 包内是否包含测试配置、中文、调试工具和环境切换能力。 不代表当前正在调用测试 API 还是生产 API。
业务环境 production / id-test INTERNAL 包本次运行使用哪组 API、WhatsApp 和业务配置。 不能让非 88 Native 获得 INTERNAL 包。

env_code=id-testenv_code=id 在 H5 包表中保留为渠道分区兼容字段: 前者存 INTERNAL,后者存 RELEASE。它不再表达客户端当前业务环境。

3. 唯一判定表

Native 版本请求的业务 API服务端返回渠道H5 最终业务配置
88.88.88生产 APIINTERNAL默认生产;Native 当前为生产时使用生产配置。
88.88.88测试 APIINTERNALNative 当前为 id-test 时使用 id-test 配置。
任意非 88.88.88生产 APIRELEASE只存在生产配置。
任意非 88.88.88测试 APIRELEASE仍只存在生产配置;请求 Host 不能提升渠道。
禁止的实现:不能用 API Host、envCode、管理后台当前切换环境或 CDN 域名决定 INTERNAL / RELEASE。否则正式 App 误连测试 API 时可能拿到内部包。

4. 一次构建两个产物

统一流水线:同版本、同 commit、两个独立 ZIP
flowchart LR
  G["Git commit"] --> P["云效统一 H5 流水线 4987658"]
  P --> I["INTERNAL ZIP\n生产+id-test 配置\n仅 88.88.88"]
  P --> R["RELEASE ZIP\n仅生产配置\n非 88"]
  I --> IT["INTERNAL manifest\nmin=max=88.88.88"]
  R --> RT["RELEASE manifest\n无 Native 范围"]
  IT --> REG1["登记到 INTERNAL 分区"]
  RT --> REG2["登记到 RELEASE 分区"]
        
内容INTERNALRELEASE
包渠道INTERNALRELEASE
Native 适用范围min=max=88.88.88无范围字段,由服务端按“非 88”选择
业务配置生产 + id-test,默认生产仅生产/default
中文及调试能力包含不包含
环境切换允许生产 / id-test不提供入口,也没有测试配置
版本与 commit必须完全相同;SHA256 必须分别计算且通常不同。

5. Native 与 H5 启动

INTERNAL 包启动时选择业务环境;RELEASE 不执行环境选择
sequenceDiagram
  participant App as "Native"
  participant Store as "Native 环境存储"
  participant H5 as "本地 H5"
  participant API as "BeeX API"
  App->>Store: "启动前读取当前环境"
  alt "Native = 88.88.88"
    Store-->>App: "production 或 id-test,缺省 production"
    App->>H5: "注入 packageChannel=INTERNAL + environmentId"
    H5->>H5: "从包内两组配置选择对应配置"
  else "Native != 88.88.88"
    Store-->>App: "强制 production,并清理内部环境状态"
    App->>H5: "注入 packageChannel=RELEASE"
    H5->>H5: "使用唯一 production/default 配置"
  end
  H5->>API: "按已确定配置发起请求"
        
  1. Native 在创建 WebView 之前读取当前环境。
  2. 非 88 版本会清除历史测试环境、调试 H5、语言覆盖和内部开关,强制生产。
  3. Native 向 H5 注入不可变的 h5PackageChannel 与当前 environmentId
  4. INTERNAL 读取 environmentId 选择包内配置;缺失或非法值回退生产。
  5. RELEASE 忽略环境输入,因为包内根本不存在测试配置。

6. 服务端下发规则

业务 API Host 与包渠道解耦
flowchart TD
  Q["GET /api/v1/app/h5-package/latest"] --> V{"nativeVersion == 88.88.88?"}
  V -- "是" --> IC["查询 INTERNAL 分区\n兼容 env_code=id-test"]
  V -- "否" --> RC["查询 RELEASE 分区\n兼容 env_code=id"]
  IC --> G["按状态、灰度目标、当前版本选择候选"]
  RC --> G
  G --> O["返回 packageUrl / sha256 / releaseNotes"]
        

服务端必须忽略请求中的 envCode 来选择渠道。它只信任已安装 Native 的 nativeVersion:精确等于 88.88.88 查询 INTERNAL,其余查询 RELEASE。

同一统一流水线会把两个渠道登记到测试与生产管理服务,使 88 从任一业务 API 查询时都能找到 INTERNAL, 非 88 从任一业务 API 查询时都只能找到 RELEASE。

发布状态仍由渠道权威版本池维护:INTERNAL 以内部版本池为准,RELEASE 以线上版本池为准。 请求落在非权威 API 时,业务服务携带内部路由标记与 X-ADMIN-TOKEN 查询权威版本池; 权威服务失败时返回 hasUpdate=false,绝不改查另一个渠道。内部路由标记不能由公网请求单独伪造。

7. 安全与防误发

风险门禁
正式 App 获得测试配置RELEASE 构建阶段不写入任何测试 API、测试 WhatsApp 或内部工具;服务端非 88 永不查询 INTERNAL。
88 测试线上时拿到 RELEASE服务端按 Native 版本强制选择 INTERNAL,不看 API Host 和请求 envCode。
转线上重新构建导致漂移生产晋级只复用同版本、同 commit 的预构建 RELEASE;候选不存在则失败并要求重跑统一流水线。
旧测试状态污染正式 App非 88 启动时主动清除本地环境切换、调试 H5、语言覆盖与内部开关。
两个渠道内容相同或配错流水线校验 manifest、Native 范围、内嵌 Host、测试号码与两个 ZIP 的独立 SHA256。
公网伪造内部路由身份内部转发同时校验路由标记和共享管理令牌;缺失或不匹配时拒绝,不信任转发的用户与联盟码。
权威版本池不可用返回无更新并继续使用本地离线包;禁止为了“有包可下”而跨渠道降级。

8. 后续演进原则

  • 新增国家时仍按国家数据中心独立发布,但包渠道规则保持 INTERNAL / RELEASE 两类。
  • 新增内部工具只进入 INTERNAL,不通过运行时远程开关塞进 RELEASE。
  • 新增生产配置应进入 RELEASE 的 default 配置,同时进入 INTERNAL 的 production 配置。
  • 任何需要修改“渠道判定”的需求必须同时更新 Native、业务服务、管理后台、流水线校验和本文档。