Nonmotor 开发手册
NONMOTOR / ENGINEERING GUIDE
面向后端工程师 · 从需求到交付更新于 2026.10.10

Nonmotor 前端开发指南:从需求到交付#

这份指南面向准备接手 Nonmotor 前端需求的后端工程师。以一个投保信息页需求为主线,说明项目为什么这样组织、如何跑起页面、怎样选择配置或代码实现,以及如何联调和交付。

读完并完成练习后,应能独立做到:从业务 URL 找到代码,判断需求改动范围,追踪字段到后端请求,并提交有验证证据的 MR。

阅读路线与分享安排#

阶段 章节 要回答的问题 阶段产出
认识项目 1. 项目与业务边界 Motor 与 Nonmotor 有何区别?为什么采用不同的页面组织方式? 能说明目标产品的页面链路和复用边界
跑通环境 2. 本地环境与启动;3. 调试方式 怎样用本地代码打开真实业务页面?怎样检查 App 内行为? 可访问的本地页面、正确的接口环境与调试工具
定位实现 4. 从 URL 到代码;5. 需求分析与方案 入口在哪里?改配置、改组件,还是改接口? 影响清单、实现方案与验收场景
完成开发 6. Journey 与数据流;7. 开发约定;8. 贯穿案例 页面怎样生成?一个字段怎样到达后端? 配置/代码改动、完整字段数据流
验证与交付 9. 联调自测;10. MR 与发布;12. 完成标准 如何证明行为正确?交付包含哪些物料? 自测记录、MR、发布与回退说明
持续上手 11. 工具与 AI;13. 后续专题 如何提高效率、进一步掌握差异化与上线控制? 下一步练习和专题学习计划

第一次阅读按第 1—10 章走完整流程;实际开发时用第 12 章检查完成度。分享现场的讲解顺序、演示和时间安排见分享提纲。安装细节和附录用于课后查阅,无需在现场逐条朗读。

本文依据 2026-10-09 至 2026-10-10 核对的工作区源码、团队提供的截图和已确认操作约定整理。业务项目的新环境安装、真实产品端到端流程及部署尚未在本次文档整理中实测;登录、权限和负责人等待补信息统一列在附录 A。源码依据见附录 B,市场代理规则见附录 C,Motor 各市场流程详解见附录 D。

1. 项目介绍:先认识业务与复用边界#

本章先建立项目认知:用户经过哪些页面、Motor 与 Nonmotor 为什么分开组织、哪些能力可以复用。入口注册和模板内部实现分别在第 4、6 章展开。

1.1 Motor 与 Nonmotor 的区别#

Motor 主要承载车险,Nonmotor 承载非车险。两者都会经过产品选择、信息填写、报价/确认和支付,但 Checkout 之前的页面组织方式不同:Motor 以市场专属页面为主,Nonmotor 的产品工厂主流程以共享模板和 Journey 配置为主。

对后端同学来说,可以先这样理解:Motor 由各市场的页面代码编排本地业务;Nonmotor 把高度一致的页面骨架、表单和交互做成可复用能力,再由产品工厂描述某个产品应该使用哪些能力。

对比项 Motor:车险 Nonmotor:非车险产品工厂流程
业务关注点 车辆、车主/驾驶人、历史保单、报价、附加保障,以及市场专属材料和步骤 产品保障、Plan、保障期间、投保人/被保人信息,以及产品所需的扩展字段
Checkout 前的页面组织 按市场维护页面,例如 src/pages/my/、sg/、id/motor/ 多个市场复用 src/pages/factory/、factoryV2/ 下的模板与组件
页面结构与流程 React 页面、市场组件及业务条件共同编排 模板执行 Journey 中的页面、区块、字段、步骤和路由配置
差异主要放在哪里 市场页面、model/service、组件、状态与导航处理 Journey、产品数据、翻译,以及必要的产品/市场扩展代码
复用特点 完整业务页面和专属组件跨市场复用较少;UI、表单、请求等基础能力仍能共用 产品间、市场间的页面和功能组件高度一致,适合共享模板与配置复用
拿到需求先查什么 哪个市场、哪条 Motor 流程、哪个页面或业务组件 哪个产品、哪份 Journey、哪个模板/区块/字段,已有能力能否表达

Motor 与 Nonmotor 的页面组织对比:市场专属页面与共享模板

图 1:两种组织方式的核心差异在 Checkout 之前。图中是源码结构示意,不是真实产品 UI 截图;可点击放大。

业务分类、应用配置、源码目录和维护仓库需要分别确认,具体定位方法见第 4 章。

1.2 为什么采用不同的页面组织方式#

按照团队当前的业务划分,Motor 页面相对复杂,很多业务组件与市场流程强相关,跨市场难以直接复用;Nonmotor 不同市场、产品的页面结构和功能组件高度一致,复用收益更高。源码中的“市场目录”与“共享 Factory 模板”体现了这一设计取向。

设计判断 代码中的具体表现 对开发的意义
Motor 的流程差异较大 ID 有车辆配件/附加保障编辑分支;MY 有报价卡片和车辆信息编辑;SG 按保障决定是否经过 Add-ons 先理解目标市场的页面状态、缓存和导航条件,再修改业务逻辑
Nonmotor 的主结构一致 多市场的 PDP6、Purchase5 等入口指向同一份 Factory 源码 同一种字段、区块、校验能力可以服务多个产品,避免逐产品复制页面
Nonmotor 的差异通常可以参数化 Journey 的 blocks、entries、props、dependencies、constraints、stepItems 等参与页面生成 已有能力范围内,优先调整配置、翻译和数据;新行为再扩展代码能力
共用代码会扩大影响面 修改共享 FillInfo 或解析器,会影响使用它的其他产品/市场 回归范围应按“谁消费这项能力”确定,不能只验证当前产品

这不是绝对隔离。Motor 也会复用 MoneeDesign、InsEntry、Bridge、请求、缓存和部分业务组件;Nonmotor 也保留市场适配,例如 purchase5/config/{region}、PDP 的市场插入规则,以及 PHApplicant 等专属区块。应复用稳定共性,同时保留明确的市场/产品扩展点。

1.3 用户实际经过哪些页面#

两类业务的共同目标都是让用户了解保障、提供投保信息、确认方案并支付。差别在于 Checkout 之前如何拆页、组织交互和复用实现。

Motor 与 Nonmotor 典型页面流程:ID、MY、SG 与产品工厂主流程

图示根据源码导航与配置整理,表示典型路径;产品、续保和可选分支可能改变实际顺序。

业务 典型链路与主要差异
ID Motor 车辆信息/PDP → 报价 → 个人信息确认 → Checkout;报价页可打开配件与附加保障编辑
MY Motor PDP → 报价列表 → 报价详情 → Checkout;摩托车和历史版本有不同分支
SG Motor PDP → 报价列表 → 报价详情 → 可选 Add-ons → 投保表单 → Checkout
Nonmotor 产品工厂 PDP → Purchase → Confirmation → Checkout;由具体产品配置决定步骤,部分页面可以合并或跳过

Motor 按市场查页面,完整目录截图、页面文件名和源码依据见附录 D。Nonmotor 在多个市场复用 Factory 模板,当前 MY、ID、SG、TH 注册了同一组 PDP6、Purchase5、Confirmation 入口,但其他市场的页面集合并不完全相同。

Checkout 的边界#

Nonmotor 的“模板引擎 + 产品工厂”主要描述 Checkout 之前的产品工厂页面。收银台采用独立的 checkoutV2 实现,处理金额、优惠、支付选项及创单衔接,并保留市场适配。Motor 与 Nonmotor 可以共用收银台源码,传入的数据、应用与市场构建仍然不同。

前端负责交互、展示和及时校验;金额、资格、报价和创单结果应以对应后端契约为准。一个浏览器页面能打开,不等于 App 内完整下单流程已经通过。

1.4 页面最终由什么决定#

实际页面来自几个部分的组合:前端代码、产品 Journey、接口数据、翻译、PFC 配置以及运行环境。

因此,“页面不对”不一定意味着要修改 React 代码。某个字段没有出现,可能是 Journey 没有配置、显隐条件未命中、组件名未匹配,也可能是当前产品或市场选错。

还要区分两个常见概念:

1.5 后端工程师需要建立的前端认知#

当前工程主要使用 React 18、TypeScript、Webpack 5、SCSS,采用多入口多页面架构。每个页面有自己的入口和 HTML,构建时按应用与市场选择页面集合。

页面可以运行在浏览器或 App WebView 中。项目通过 Bridge 封装页面跳转、返回和其他宿主能力。浏览器能打开页面,并不代表 App 中的返回、登录和支付链路已经验证完成。

后端熟悉的概念 在本项目前端中如何理解
服务启动入口 index.tsx 挂载页面,并进行页面级初始化
业务用例编排 App、业务组件和 Hook 组织数据、交互与页面状态
下游接口客户端 service/model 调用统一 request,封装接口协议
请求上下文 props、state、Context 和持久化缓存有不同生命周期
配置驱动 Journey 决定部分页面结构;PFC 提供命中条件下的配置
日志与调用链 Network、Console、IDAP 与后端日志结合排查

前端组件会随状态变化重复渲染,不能把组件函数当作“只执行一次的服务初始化”。跨页面跳转后,组件状态也不能自然保留,需要明确缓存与参数传递方式。

2. 本地环境:从安装到打开业务页面#

本章按实际准备顺序操作:拿到有效入口与权限 → 安装依赖 → 选择环境并启动 → 配置浏览器代理与 HTTPS → 验证业务域名、接口和登录态。默认先跑通浏览器,模拟器与真机准备放在第 3 章。

2.1 准备入口、账号与权限#

先拿到仓库访问权限,以及一个可以复现的非生产产品入口。开发样例至少要包含:市场、环境、产品、页面 URL、测试账号获取方式,必要时还包括后端 PFB。

需要访问的能力包括公司 npm 源、项目启动所需的 KMS、产品工厂配置、翻译平台,以及联调使用的后端环境。具体权限申请入口由团队维护人提供。

本文示例从已拉取的 nonmotor_h5 仓库根目录执行。开发者可使用自己的 IDE,但终端工作目录必须正确。

2.2 安装 Node 与项目依赖#

仓库 .nvmrc 当前声明 v20。已安装 nvm 的同学可以执行:

bash
nvm install
nvm use
node -v
npm -v

使用其他 Node 版本管理器时,同样以项目版本文件为依据。package.json 中较宽泛的最低版本声明,不代表所有更低版本都已验证可用。

部署安装脚本使用以下依赖安装方式,本地可以据此准备依赖:

bash
npm install --registry https://npm.shopee.io --legacy-peer-deps

安装失败时,先根据错误区分 npm 源访问、权限、Node 版本和原生依赖编译问题。不要通过随意升级依赖或删除锁文件来跳过原因分析。安装后检查 package-lock.json 差异,确认是否属于本次需求。

2.3 选择环境并启动本地服务#

配置 作用 需要注意
APP_NAME 选择应用及入口配置 本项目目标服务选择 nonmotor
REGION 选择市场入口和区域实现 使用目标市场,例如 my、id;并非每个应用都支持菜单中的全部市场
ENV 选择开发/构建环境 对应 mock、dev、test、uat、live 等;日常联调选已约定的非生产环境
BUILD_ENV 选择构建环境与相关运行配置 按目标业务选择 spin 或 spic
BROKER_NAME 部分 spic 场景的主体配置 仅按实际业务选择
TRANSIFY_REPORT 本地翻译使用上报开关 启动菜单可选择,默认 off
后端 PFB 指定联调的后端分支环境 不等于前端 ENV;必须结合实际请求验证

npm run dev 的交互脚本会把所选配置保存到仓库根目录 .env。新任务开始时应核对配置,不要无意复用上一次开发的市场和应用。

npm run start 和 npm run build 都会先执行 scripts/kms.js。KMS 访问失败属于启动前置条件问题,应按团队约定准备对应凭证和网络;凭证不要写进源码、MR 或共享排障日志。

使用交互入口启动#

bash
npm run dev

依次选择“开发”、目标环境、Transify 上报设置、目标市场、服务 nonmotor、构建环境;需要时再选择主体。首次启动应显式选择,确认无误后才使用“使用上一个命令”。

脚本随后调用 npm run start。默认端口为 3000,端口变更时以终端输出为准。

2.4 建立浏览器到本地服务的代理链路#

本地联调使用 ZeroOmega 浏览器代理插件 + Whistle 代理服务 + 本地开发服务。三者职责如下:

工具 职责 本文使用的地址
Proxy SwitchyOmega 3(ZeroOmega) 控制 Chrome 请求是否经过指定代理 指向 127.0.0.1:8899
Whistle 抓包、匹配规则、转发或替换请求响应 默认代理端口 8899,管理后台为 http://127.0.0.1:8899
nonmotor 开发服务 返回本地 HTML、JS/CSS,并通过开发代理处理 /api 默认 localhost:3000

Whistle 是基于 Node.js 的跨平台网络代理与调试工具,支持 macOS、Windows、Linux。日常使用它查看请求、代理页面和接口、mock 响应、模拟弱网以及调试移动端 H5。ZeroOmega 只负责代理选择,安装插件后还需要运行 Whistle。Whistle 项目说明

以 MY Test 的整站代理规则为例:

流程示意
  1. Chrome 访问 MY Test 域名
    1. ZeroOmega
      1. Whistle 8899
        1. 本地开发服务 3000
          1. 返回本地页面与资源
          2. API 经开发代理发往后端

浏览器地址栏仍是业务域名,本地代码通过代理返回。页面 Cookie 和存储仍按浏览器中的域名使用;代理本身不会创建登录态。

安装 ZeroOmega 插件#

在 Chrome 中打开 Proxy SwitchyOmega 3(ZeroOmega)安装页,安装后进入插件设置,新建一个代理情景模式,例如命名为 Whistle。

设置项 值
代理协议 HTTP
代理服务器 127.0.0.1
端口 8899

将该 HTTP 代理设为默认代理,使目标 HTTP/HTTPS 请求都经过它;若界面分别配置 HTTP、HTTPS 请求代理,两者均指向上述代理服务。这里选择的 HTTP 是浏览器连接代理的方式,不代表目标业务页面必须使用 HTTP。

保存/应用设置。等 Whistle 启动后,再通过插件图标切换到 Whistle 模式。也可以在自动切换模式中仅让目标业务域名走此代理。

安装并启动 Whistle#

完成 Node 环境准备后,在终端执行:

bash
# 安装命令行版
npm i -g whistle

# 启动并查看状态
w2 start
w2 status

打开 Whistle 本地管理后台。主要使用 Network 查看流量,使用 Rules 编辑代理规则。命令行版的常用管理命令如下:官方命令行文档

bash
# 重启
w2 restart

# 停止
w2 stop

Whistle 也提供桌面客户端,可从官方安装说明进入;本指南统一以命令行版为例。同一套环境选择一种运行方式,避免两个实例竞争端口或误用另一套规则。

安装证书并开启 HTTPS 抓包#

业务页面使用 HTTPS 时,需要让 Whistle 解密请求,才能按页面路径代理并查看明文请求响应。完成以下设置:

  1. 在 Whistle 管理界面打开 HTTPS,通过 Download RootCA 下载本机 Whistle 根证书。
  2. 在操作系统中安装并信任该证书。macOS 可在“钥匙串访问”中导入并设置证书信任;也可使用下面的官方命令完成安装,按系统提示确认。
  3. 在 Whistle HTTPS 设置中开启 Enable HTTPS (Capture Tunnel Traffic)。
  4. 重新加载目标 HTTPS 页面,检查是否能看到具体 URL、请求头和响应内容。
bash
w2 ca

证书安装与 HTTPS 解密开关需要同时完成。若只看到 Tunnel to 而无法查看目标请求内容,先检查解密开关、证书信任以及请求是否经过当前 Whistle 实例。HTTPS 设置说明、证书安装命令

配置目标市场的代理规则#

在 Whistle 的 Rules 中按市场与环境建立规则组,例如 nonmotor-my-test,粘贴规则、保存并启用。本地 3000 端口一次运行的是当前选择的应用/市场/环境;日常只启用本次需要的规则组。

以 MY Test 为例,团队材料使用整站转发,本指南整理为显式指定 HTTP 目标的写法:

text
# MY Test:保留请求路径,整站转发到本地开发服务
protection.test.shopee.com.my http://localhost:3000

它会将 /nonmotor/purchase5.html?... 转发到本地相同路径。已有整站规则时,指向相同服务、保留相同路径的 /ins、/nonmotor、/common、/ec、/static 规则可合并,避免重复维护。使用 http:// 明确目标是本地 HTTP 开发服务,URL 路径按规则自动拼接。Whistle HTTP 转发规则

整站转发也包含 /api,接口随后由 scripts/start.js 的开发代理决定最终后端目标。因此需要核对浏览器访问环境、Whistle 规则和本地启动环境。它不是只替换 HTML 的规则。

如果只想代理某个页面目录,可以使用下列规则替代整站规则;资源和其他请求的去向需要另外核对,不要与整站规则一起启用后误以为范围已缩小:

text
# 可选:仅把 nonmotor 路径转发到本地
protection.test.shopee.com.my/nonmotor http://localhost:3000/nonmotor

各市场的整站规则见附录 C。代理规则不会自动启动项目,也不会让未构建的应用页面出现:APP_NAME=nonmotor 时,其他应用入口是否可用仍取决于本地构建内容。

2.5 使用有效业务 URL 与登录态#

开发环境生成的 HTML 路径带应用前缀。例如,MY 的 purchase5 在默认端口下对应:

text
http://localhost:3000/nonmotor/purchase5.html?product_id=<目标产品ID>

这是路径示意,<目标产品ID> 必须替换成实际值,其他必要参数应从有效业务入口保留。该页依赖产品配置、登录态和前序流程数据时,应从产品详情进入;直接打开中间页不能替代完整链路验证。

完成第 2 章代理配置后,日常联调在浏览器打开对应环境的原始业务地址,例如 MY Test:

text
https://protection.test.shopee.com.my/nonmotor/purchase5.html?product_id=<目标产品ID>

浏览器通过 Whistle 获取本地页面,地址栏保持 MY Test 域名。直接访问 localhost 可用于检查本地页面服务,但两者的 Cookie/存储域不同,不能把 localhost 能打开视为业务域名登录已完成。

仓库旧 README 中的 /ins/ 和根路径示例不能直接套用到 nonmotor。开发路径依据 config/webpack.config.js,页面名单依据 config/nonmotor/{region}.json。

2.6 核对 API 环境与 PFB#

scripts/start.js 已包含开发代理:非 mock 环境根据 BUILD_ENV、REGION、ENV 等选择后端域名,并代理 /api 请求;mock 环境将 /api 指向本地 3001 端口。

启动后先查看终端输出的请求转发域名,再在浏览器 Network 面板核对具体请求。页面加载成功、代理目标正确、登录成功是三个不同检查点。

使用第 2 章的整站规则时,请求链路是“浏览器 → Whistle → 本地开发服务 → 开发 API 代理”。登录 Cookie 的域、环境和账号必须匹配当前打开的页面;后端使用 PFB 时,验证实际链路是否命中目标 PFB。

用户提供的浏览器域名与当前 scripts/start.js 的部分 API 目标存在差异:

市场/环境 材料中的浏览器域名 当前 spin 开发代理目标
TH Test protection.test.shopee.co.th protection.test.moneeinsurebroker.co.th
TH UAT protection.uat.seainsurebroker.co.th protection.uat.moneeinsurebroker.co.th
SG Test / UAT test.moneeinsureagency.sg / uat.moneeinsureagency.sg test.seainagency.sg / uat.seainagency.sg
PH Test / UAT protection.test.moneeinsurebroker.com.ph / protection.uat.moneeinsurebroker.com.ph protection.test.seainsureagency.com.ph / protection.uat.seainsureagency.com.ph

此表记录材料和源码的差异,不据此认定域名不可用或需要替换。目标环境是否通过别名或迁移实现兼容,需要实际联调确认。浏览器域名正确仍不足以证明 API 目标正确,本次文档整理未修改代理源码。

2.7 首次启动的验收清单#

首次开发不以“终端没有报错”为结束,应完成以下检查:

  1. Webpack 编译完成,目标 /nonmotor/*.html 可以打开。
  2. 当前应用、市场、环境和产品与需求一致。
  3. 页面能获取正确 Journey 或业务数据,接口没有登录失败。
  4. 修改一处目标页面代码后,能够确认浏览器运行的是本地版本。
  5. 至少完成目标产品的一段真实交互,核对请求和页面结果。

代理链路还应检查:

若 Whistle 看不到请求,先查插件模式和代理端口;能看到请求但页面未替换,查规则命中、缓存和本地路径;接口报登录错误则继续核对账号、Cookie 域和 API 目标,代理工具不会代替登录步骤。

3. 调试方式:浏览器、模拟器与真机#

本章解决“在哪里验证、用什么工具看问题”。第 2 章先跑通请求链路,本章再区分浏览器局部调试、App 内 H5 调试和完整业务自测。

3.1 按任务选择调试环境#

日常开发可以先在浏览器快速调试,再用模拟器检查 App 内行为,提测前优先在真机完成主流程自测。三种方式共享同一套业务代码,但运行环境和可验证的能力不同。

方式 优势 主要限制 适合做什么
iOS 模拟器 在电脑上运行 Shopee App,可配合 Safari 调试 App 内 H5 占用电脑内存,依赖 Simulator App 构建;不能完全替代真实设备 H5 与 App 的交互、Bridge 跳转与返回、iOS WebView 问题定位
浏览器 轻量,不用启动模拟器;有有效 URL 和所需登录态即可访问,调试工具使用方便 缺少 App 宿主能力,无法走完依赖原生页面的完整下单流程 页面布局、DOM、字段校验、接口数据、异常状态和快速修改验证
真机 最接近用户实际的触摸、输入、滚动和 App 使用体验 需要目标设备、App、测试账号及网络环境 业务主流程自测首选,尤其是支付、OTP、地址选择和跨页面返回

3.2 浏览器:日常开发与局部验证#

浏览器调试最轻量。完成代理和登录准备后,直接打开目标业务 URL,使用 Chrome DevTools 的 Elements、Console、Network、Sources、Application 等面板即可调试,不必同时运行模拟器。

浏览器通过业务 URL 打开 H5,使用 Chrome DevTools 查看日志、请求与页面存储

图示:完成登录鉴权后,通过有效的业务 URL 打开 H5 页面;Console 查看日志,Network 查看请求,Elements 检查 DOM 与样式,Application 查看当前域名的 Local Storage、Session Storage 和 Cookie。截图中的 URL 和参数仅用于说明入口位置,实际调试请使用本次产品的有效入口。点击图片可放大查看。

适合先完成布局调整、文案检查、字段校验、接口响应处理等工作。浏览器的设备模拟模式可以辅助检查移动端尺寸,但页面仍运行在浏览器环境中,不会因此获得 Shopee App 的 Bridge、RN 或原生能力。

当前项目涉及 App 能力的完整下单流程,不能只在普通浏览器中验收。 按团队提供的场景,支付页面、OTP 验证页面、SP 统一的 address select 页面等需要跳转到 App 内的 RN/原生页面,浏览器无法复现这些跳转及返回链路。具体页面承载方式以目标市场和 App 版本为准。

遇到这些边界时,转到模拟器或真机继续验证。即使使用 mock 或模拟 Bridge 返回值,也只说明 H5 在指定返回数据下的处理正常,不能证明真实 App 跳转、回调和下单流程通过。

3.3 模拟器:安装 App 并配置代理#

本节适用于 macOS + Xcode 的 iOS 模拟器,用于验证 Shopee App 内的 H5 展示、返回与 Bridge 交互。安装入口和内部 App 下载方式来自团队提供的截图;截图中的设备、iOS 和 App 版本只是示例,选择时以当前测试要求和兼容性为准。

第一步:安装 Xcode 并启动模拟器#

  1. 从团队材料中的 Xcode 下载目录获取适配当前 Mac 的 Xcode,完成安装及首次启动要求的组件安装。
  2. 在 Xcode 中确认已安装目标 iOS Simulator runtime。如果没有可选的 iOS 设备,先在 Xcode 设置的运行时/组件管理界面下载所需版本;不同 Xcode 版本的菜单名称可能不同。Apple 运行时安装说明
  3. 搜索并打开 Simulator.app,或通过 Xcode 的 Open Developer Tool → Simulator 打开。
  4. 选择并启动一个目标 iPhone 模拟设备,等待进入 iOS 主屏幕。

Simulator 是 Xcode 自带的开发工具。仅有命令行工具不等于已经准备好完整的模拟器环境。Apple Simulator 说明

第二步:下载对应市场的 Simulator App 包#

进入团队 App 平台 app.sea.com,选择需要调试的 Shopee 市场 App。截图给出的示例为 Shopee ID App 页面,其他市场选择各自对应的 App。

在 iOS 版本列表中搜索 simula 或 simulator,找到团队要求的模拟器构建版本并下载。不要把截图中的历史版本号作为统一安装要求;也不要仅凭市场一致就选择任意 Native Feature Build,应使用本次测试约定的构建。

安装包需要明确支持 iOS Simulator,并与当前 Mac 架构及模拟器运行时兼容。普通真机安装包不能通过改扩展名变成 Simulator 包。

第三步:解压并安装 App#

  1. 若下载的是可直接使用的 .app 应用包,直接进入安装步骤。
  2. 若是压缩包,先解压。团队材料中的“改后缀为 .zip”适用于内容本身为 ZIP 归档、但下载扩展名不便解压的包;已经是 .zip 的文件直接解压即可。
  3. 在解压目录中找到 .app 应用包,将它拖到已经启动的 Simulator 设备窗口中安装。
  4. 等待主屏幕出现 App 图标,打开并检查能否正常启动。

如果安装失败,先核对是否误下真机包、市场/构建是否正确、Mac 架构及 runtime 是否兼容。App 安装完成后,再按团队测试账号流程登录;账号获取和登录操作另行补充。

第四步:为模拟器开启系统代理#

第 2.4 节的 ZeroOmega 控制 Chrome 请求,不能代替模拟器 App 的代理设置。按团队材料,模拟器联调通过 Whistle 设置 Mac 系统代理:

bash
# 启动 Whistle
w2 start

# 设置 Mac 系统代理,指向运行中的 Whistle
w2 proxy

默认 Whistle 使用 127.0.0.1:8899。开启系统代理会影响使用该系统代理的其他应用,操作前保留原代理配置,结束后恢复。Whistle 系统代理命令

同时完成以下配置:

浏览器 ZeroOmega、Mac 系统代理和实体手机 Wi-Fi 代理是不同的流量入口,按调试设备选择;三者可以指向同一个 Whistle 服务。

第五步:验证并结束调试#

在 Whistle Network 中观察请求,并核对:

检查项 通过标准
模拟设备 能进入 iOS 主屏幕,目标 App 能正常启动
代理 模拟器访问目标页面时,Whistle 能捕获对应请求
HTTPS 能查看具体请求与响应内容,无证书信任错误
页面版本 目标业务域名返回本地修改后的页面
业务链路 登录、接口环境、页面返回与相关 Bridge 行为符合本次需求

若 Safari 请求可抓取、但目标 App 请求不可抓取,应继续检查 App 的网络及证书策略,不把浏览器验证结果当作 App 已通过。模拟器用于日常开发验证,依赖真实设备能力的场景仍需按验收要求在真机验证。

调试结束,或其他软件因系统代理出现网络问题时,关闭本次启用的系统代理:

bash
w2 proxy 0

# 不再需要 Whistle 时再停止服务
w2 stop

截图使用 w2 proxy off,本文统一采用官方当前文档列出的 w2 proxy 0。若原来已有公司代理或其他网络工具,应恢复原设置;Chrome 的 ZeroOmega 若仍选着 Whistle 模式,也需要切回正常模式。Whistle 命令说明

团队安装材料截图#

团队提供的 Xcode、Shopee Simulator App 安装与模拟器代理步骤

截图中的内部下载地址作为团队提供的安装入口保留,本次未登录这些平台确认可下载版本,也未实际安装 Xcode、App、证书或修改系统代理。

3.4 Safari:检查 App 内的 H5#

模拟器负责运行 App,Mac 上的 Safari Web Inspector 负责查看和调试其中的 H5。可以把它理解为“给模拟器里的网页打开 F12”。

  1. 打开 Mac 上的 Safari → Settings(设置)→ Advanced(高级),勾选 Show features for web developers(显示网页开发者功能)。旧版 Safari 的文案可能为“在菜单栏中显示开发菜单”。
  2. 启动 iOS 模拟器,在 Shopee App 中进入要调试的 H5 页面,保持页面打开。
  3. 在 Mac Safari 的 Develop(开发) 菜单中,找到正在运行的模拟设备,再选择对应 App 下的目标 H5 标题或 URL,打开 Web Inspector。
  4. 在模拟器中操作页面,同时在 Mac 上查看日志、请求、DOM 与样式。页面跳到新 WebView 后,必要时重新选择当前页面。

Safari Develop 选择模拟器或真机中的 H5 页面并打开 Web Inspector

图示:Safari → Develop → 当前模拟器或真机 → Shopee → 目标 H5 页面。截图中选中的是已连接的真机,模拟器入口位于同一菜单;选择页面后会打开下方的 Web Inspector。点击图片可放大查看。

模拟器的远程检查能力默认开启,无需照搬真机的 Web Inspector 开关步骤。菜单中能否出现具体 App 页面,还取决于该 App 构建是否允许检查 WebView。WebKit 启用 Web Inspector 说明

想查什么 使用的面板/能力 Nonmotor 中的例子
打印的 Log、JS 错误 Console 查看初始化异常、字段联动日志和 Bridge 调用前后的输出
请求及响应 Network 核对接口参数、业务码、响应内容与耗时
DOM 节点和样式 Elements / Styles 找到实际渲染的节点,检查显隐、间距、遮挡和滚动布局
登录及页面存储 Storage / Cookies 等相关面板 核对当前域名的 Cookie、localStorage、sessionStorage;排查回退后旧数据或字段丢失
JS 执行过程 Sources / Debugger 设置断点,检查用户输入如何进入缓存和请求参数

这里的“缓存”需要分清:表单数据可能在页面存储中,JS/CSS 等资源还可能命中 HTTP 缓存。先核对当前页面和数据来源,再决定清理哪一项;清理存储可能同时清掉登录态或前序投保信息。

如果 Develop 中没有目标页面,先确认 App 已打开 H5、选对设备和页面,再核对测试包是否开放 WebView 检查。能检查模拟器 Safari 中的网页,不代表一定能检查 Shopee App 内的 WebView;需要时由客户端同学确认构建配置。WebKit App 内容检查说明

Safari Web Inspector 主要检查选中的 H5 页面;Whistle 用于观察经过代理的网络流量和执行转发规则。两者配合使用。Safari 的 DOM/样式面板不能直接检查 App 的 RN 或原生页面内部实现。

3.5 真机:验证完整用户交互#

可以直观理解为“把电脑里的模拟设备换成手里的真实手机”。真机能更接近用户实际操作,尤其适合检查触摸、键盘遮挡、滚动、返回手势和 App 页面切换。提测前优先使用真机完成本次需求的主流程自测。

使用目标市场、环境和测试版本的 Shopee App,从实际业务入口进入页面。调试本地代码时,按第 3.6 节配置手机代理及证书,并确认手机请求确实经过电脑上的 Whistle。

需要检查 iPhone 内的 H5 时,在 iPhone 设置中找到 Safari → Advanced(高级)→ Web Inspector(网页检查器),开启后连接 Mac 并完成设备信任,再从 Mac Safari 的 Develop 菜单选择该设备与可检查的 H5;较新 iOS 的 Safari 设置可能位于“设置 → App”内。此方式同样要求 App 开放对应 WebView 检查。iOS 远程检查说明

自测重点包括:

给 QA 的自测记录应写清设备/系统、App 版本、市场、环境、入口、执行场景和结果,区分浏览器验证、模拟器验证与真机验证。

3.6 Whistle 联调能力与代理收尾#

场景 用法
查看接口 在 Network 中查看 URL、请求/响应头、响应体和耗时
临时 mock 用限定范围的规则替换目标接口响应,模拟特定数据和错误
弱网验证 用延迟、限速规则检查 loading、超时与重试表现
页面远程调试 按需使用 Whistle 内置 Weinre、Console 能力

这些能力可以在不修改业务代码的情况下调整网络行为,规则使用后应关闭,避免影响下一轮真实接口验证。Whistle 快速上手

手机代理与证书#

手机调试时,手机与电脑需网络互通;将手机 Wi-Fi 的手动代理设为电脑的局域网 IP + 8899,不能填写手机自己的 127.0.0.1。手机也需要安装并信任该 Whistle 根证书,iOS 安装描述文件后还需开启完全信任。部分 App 的证书策略可能限制抓包,应以实际运行结果为准。移动端抓包说明

结束调试时,先将 ZeroOmega 切回原先的正常模式,再按需执行 w2 stop;手机或系统若设置了手动代理,也应恢复原配置。本文浏览器方案不要求同时开启系统代理,只有配置过的代理入口才需要恢复。

4. 代码定位:从业务 URL 找到实现#

本章的目标是找到“当前产品真正执行的代码”。按应用与市场确认入口,再沿 index.tsx → App.tsx → model/组件/Hook 阅读;找到同名文件还不足以证明定位正确。

4.1 常用目录#

目录或文件 主要职责
config/nonmotor/{region}.json nonmotor 各市场的 entry 和 HTML 配置
config/bizConfig.js 根据 APP_NAME、REGION 读取并组装入口配置
src/pages/ 页面实现,包含历史页面、市场页面和工厂页面
src/pages/factory/、src/pages/factoryV2/ 产品工厂页面、组件、解析和业务实现
src/pages/checkoutV2/ 收银台页面及相关业务代码
src/service/ 按领域组织的接口封装
页面内的 model/、service/ 部分既有页面的请求与数据处理,阅读时沿实际 import 查找
src/common/request.ts 请求、登录检测、签名等公共行为
src/InsEntry/ 动态表单、字段组件和校验能力
src/MoneeDesign/ 基础 UI 控件、图标及样式能力
src/components/ 共享组件和业务组件
src/module/ URL、存储、日期、Cookie 等公共工具
src/bridge/ App 宿主交互封装
src/locales/ 文案格式化与翻译读取
runbooks/、docs/automation/ 回归用例与 UI 自动化规范
deploy/ 安装、构建和部署配置

仓库保留了 ins_h5 的名称、工具和其他业务源码。判断一个页面是否属于当前 nonmotor 构建,要查入口配置,不能仅靠目录名或文件是否存在。

先分清应用配置、市场和维护仓库#

第 4.2 节截图左侧的目录按应用划分页面注册,目录内的 my.json、sg.json 等再按市场划分。拿到需求后,先确认应用与市场,再查页面文件名。 对后端同学而言,可以把这些 JSON 理解为构建时的“页面入口清单”:它决定本次构建包含哪些页面及其源码入口,业务内容仍由页面代码、接口和配置决定。

配置目录 对应应用与页面路径 页面范围与查找方式
config/nonmotor/{region}.json APP_NAME=nonmotor,/nonmotor/*.html 当前非车险应用的入口清单,本指南主要在这里定位页面
config/bizConfig/{region}.json APP_NAME=ins,/ins/*.html 截图标注的 motor 页面所在配置;当前仍保留部分历史工厂/非车险入口,不能将其理解为“只含 motor”
config/common/{region}.json APP_NAME=common,/common/*.html 公共应用页面;例如 MY 配置中的 home.html、product-list.html、policy-list.html
config/ec/{region}.json APP_NAME=ec,/ec/*.html EC 应用页面;例如 MY 配置中的 ec-pdp.html,按目标页面继续查注册

按团队截图中的维护约定,common 应用页面的需求在 ins_h5 仓库修改;nonmotor 应用页面在 nonmotor_h5 仓库处理。 两个仓库中都可能保留相似目录,不能因为当前仓库里搜到了文件,就认为应该在这里提交需求。

还要区分两种 common:config/common/ 表示 common 应用的页面清单,src/pages/common/ 只是源码目录。例如 MY nonmotor 的 area-selector.html 指向 src/pages/common/areaSelector/index.tsx,它仍是注册在 nonmotor 应用下的页面。源码路径、构建归属和维护仓库需要分别确认。

4.2 页面介绍:从 URL 找到入口和实现#

页面注册配置:应用目录、entry 打包入口、源码路径与 htmlPlugin 页面文件名的对应关系

图示以 config/nonmotor/my.json 的 factory-pdp6 为例:左侧是应用与市场配置,中间的 entry 关联入口名和源码,右侧的 htmlPlugin 将 HTML 文件与入口关联。点击图片可放大查看。

读懂 entry、chunks 与 filename#

下面摘取当前配置中的 PDP6 注册项,省略同文件中的其他页面:

json
{
  "entry": {
    "factory-pdp6": "factoryV2/pdp/index.tsx"
  },
  "htmlPlugin": [
    {
      "inject": true,
      "templateKey": "appHtml",
      "chunks": ["factory-pdp6"],
      "filename": "factory-pdp6.html"
    }
  ]
}
配置项 在本例中的含义 开发时怎么用
entry 的 key:factory-pdp6 页面打包入口名,与截图中的 chunk 名对应 用它关联 htmlPlugin.chunks,不是直接访问的 URL
entry 的 value:factoryV2/pdp/index.tsx 相对于 src/pages/ 的入口源码路径 实际打开 src/pages/factoryV2/pdp/index.tsx
chunks: ["factory-pdp6"] 该 HTML 关联的入口 必须能在 entry 中找到对应 key
filename: "factory-pdp6.html" 生成的页面文件名 用浏览器 URL 中的 HTML 文件名反查它
templateKey: "appHtml" HTML 模板标识 config/paths.js 将它映射到 public/index.html,并非业务 React 页面
inject: true 让 HTML 插件注入构建资源 不需要手工把每个打包脚本写进页面模板

这里区分的是入口名、源码路径、页面文件名三个概念,它们不必同名。例如 confirm-info3.html 对应的 chunk 是 factoryV2ConfirmInfo,源码位于 factoryV2/confirmInfo/index.tsx。构建还有公共依赖拆分,不能据此推断一个 HTML 只加载一个 JS 文件。

用截图中的 PDP6 走一遍定位过程#

假设已经确认目标是 MY 市场、nonmotor 应用,页面路径为 /nonmotor/factory-pdp6.html:

text
目标市场 MY + /nonmotor/factory-pdp6.html
  → config/nonmotor/my.json
  → htmlPlugin.filename: factory-pdp6.html
  → htmlPlugin.chunks: factory-pdp6
  → entry["factory-pdp6"]: factoryV2/pdp/index.tsx
  → src/pages/factoryV2/pdp/index.tsx
  → 同目录 App.tsx
  → Journey 请求、区块组件、表单与业务逻辑

市场不能只靠 /nonmotor/ 判断,要结合业务域名、需求和启动配置。前面浏览器截图使用的是 SG 域名,实际定位该页面时应查 config/nonmotor/sg.json;当前 SG 的 PDP6 也指向同一源码,但不能因此假定所有页面在每个市场都已注册。

继续阅读源码时,按职责分层:

  1. 页面启动:src/pages/factoryV2/pdp/index.tsx。 创建 React 根节点,执行 JS_START、trackAutoExpo('insurance_product') 等初始化,通过 BaseComponent 挂载 App,并声明必需参数 product_id。
  2. 页面编排:同目录 App.tsx。 创建 Form 和页面状态;普通业务入口默认调用 queryFactoryProductDetail('pdp') 获取页面数据。源码也支持 queryPageData 的定制分支和 Admin 预览,阅读具体产品时继续核对实际分支。
  3. 请求与解析:src/pages/factoryV2/model/queryProductFactoryJourney.ts。 默认请求封装读取 URL 中的 product_id,调用 Journey 接口,再通过 parseFactoryProductDetail 选择 pdp 页面并解析配置。源码请求路径还可能被公共请求层按迁移配置改写,最终以 Network 为准。
  4. 区块与交互:pdp/syncComponents/、factoryV2/hooks/useGenerateComponents 及相关业务组件。 App.tsx 将解析后的页面数据交给组件生成逻辑;样式、表单、试算、底部购买按钮等继续沿对应组件与 Hook 查找。

同一个 factory-pdp6.html 可以承载不同产品。HTML 文件名帮助定位页面模板,product_id、Journey 和接口数据决定当前展示的具体业务。因此,定位到 App.tsx 只是找到入口,还要确认当前产品实际加载的区块和字段。

常见页面的注册对照#

以下映射均来自当前 config/nonmotor/my.json。源码列统一相对于 src/pages/,具体产品不一定经过全部页面,也不保证按表格顺序跳转。

页面文件名 主要用途 chunk / entry key 入口源码
factory-pdp6.html 产品详情、方案与报价展示、投保入口 factory-pdp6 factoryV2/pdp/index.tsx
purchase5.html 投保信息录入与步骤处理 purchase5 factoryV2/purchase5/index.tsx
confirm-info3.html 投保信息确认 factoryV2ConfirmInfo factoryV2/confirmInfo/index.tsx
checkout.html 收银台及后续支付衔接 checkout checkoutV2/index.tsx
area-selector.html 地区选择辅助页 areaSelector common/areaSelector/index.tsx

用同样的方法可以定位 MY 投保信息页:purchase5.html → purchase5 → src/pages/factoryV2/purchase5/index.tsx → App.tsx。该页调用 queryFactoryProductDetail('purchase', true),但其 import 指向 src/pages/factory/model/queryProductFactoryJourney.ts,与上述 PDP6 使用的 factoryV2/model 不同。跟随当前文件的实际 import,不凭相似目录名选择实现。

常用搜索命令:

bash
# 先在目标市场的入口配置中查页面文件名
rg -n 'factory-pdp6.html|factory-pdp6|purchase5' config/nonmotor/my.json

# 再追踪页面请求与组件生成逻辑
rg -n 'queryFactoryProductDetail|useGenerateComponents' src/pages/factoryV2/pdp
rg -n 'query_product_factory_journey' src/pages/factoryV2/model/queryProductFactoryJourney.ts

# 修改共享源码前,检查哪些应用、市场还引用它
rg -n 'factoryV2/pdp/index.tsx' config

配置如何变成可访问页面#

config/bizConfig.js 根据 APP_NAME 和 REGION 选择 JSON,将 entry 中的相对路径解析到 src/pages/,并解析 HTML 模板。config/webpack.config.js 为各项创建 HTML 插件,本地开发时加上应用前缀,例如 /nonmotor/factory-pdp6.html;生产构建的输出目录由 config/paths.js 决定,nonmotor 对应 dist/nonmotor。

这解释了三个常见问题:只有源码文件、没有入口注册,页面不会自动进入该市场构建;注册了 MY 页面,不代表 SG 页面同时可用;修改入口配置后,需要重启开发服务让新的入口清单生效。对已存在的共享页面做改动,还要检查其他应用、市场和产品的影响范围。

4.3 阅读旧代码与编写新代码的区别#

历史页面可能存在不同目录布局、旧接口封装或宽泛类型。阅读时跟随真实调用链;新增代码时遵守当前项目规范,复用既有工具,并保持本次改动范围清晰。

例如,公共 API 通常放在 src/service/{domain};维护一个已有页面时,不应仅为统一目录把整页 model 全部搬迁。

5. 需求分析:确定改动范围与实现方案#

开发按以下顺序推进,每一步都留下一份可检查的结果。

阶段 要做的事 产出/阅读位置
接需求 对齐业务场景、页面、状态和接口 本章:影响清单与配置/代码判断
定方案 确认复用能力、字段数据流和跨市场影响 本章与第 6—7 章:简明方案或 TD
实现 修改配置/代码,闭合输入到请求的数据流 第 8 章:贯穿练习
验证 联调、异常与返回路径、受影响范围回归 第 9 章:验证记录
交付 Review、MR、提测、发布物料与部署验收 第 10、12 章:交付清单

5.1 第一步:把业务需求变成前端影响清单#

编码前,先确认以下信息:

维度 要明确的问题
范围 哪个市场、产品、渠道、App/浏览器场景?哪些不受影响?
页面 从哪里进入?经过哪些页面?返回、刷新、重新进入如何表现?
设计 默认、加载、空数据、错误、禁用状态如何展示?
数据 来源是接口、Journey、PFC、缓存还是用户输入?
契约 字段类型、枚举、空值、业务码、时间和金额口径是什么?
配置 是否修改 Journey、翻译、图片、开关或准入配置?
验收 正常路径、异常路径、埋点和关联产品如何验证?

接口有某个字段,并不意味着前端该直接展示或提交它。要同时确定展示规则、交互规则和业务含义。

5.2 第二步:判断修改配置还是代码#

需求情况 优先处理方式
已有字段的文案、显隐、支持范围内的校验调整 核对 Journey/i18n 和组件能力,优先配置
现有组件已有能力,但当前产品尚未启用 配置接入并验证数据契约
现有组件缺少交互或展示能力 评估扩展现有组件,列出其他调用方
独立业务区块 复用基础控件,新增或调整业务组件及配置接入
新页面或流程步骤 先评估现有模板,再处理入口、导航、缓存和埋点
接口新增或变更字段 对齐类型、请求映射、响应处理和全部消费方

如果需求只涉及 Journey,也要验证运行时页面和接口行为;如果修改公共组件,回归范围要覆盖复用方。

5.3 第三步:形成方案并开始开发#

小需求可以用一份简明方案说明目标页面、字段映射、改动文件和验收场景。复杂需求需要 TD,把页面、组件、接口、配置、缓存和发布依赖拆清楚。

开发顺序建议为:确认契约 → 获取当前配置 → 选择复用能力 → 实现页面与数据流 → 联调 → 自测 → Review → 提测。接口尚未就绪时,可以用明确契约的 mock 并行开发,真实接口就绪后补齐联调。

5.4 在对应迭代分支开展工作#

团队在 Casement 中建立迭代,迭代分支命名为 release-v1.x.xxx;本地开发分支命名为 dev-v1.x.xxx,版本号与目标迭代保持一致。例如,release-v1.3.318 对应 dev-v1.3.318。

分支 用途 代码流向
dev-v1.x.xxx 开发者本地开发、提交 commit 和自测 自测完成后发起 MR,合入对应 release 分支
release-v1.x.xxx 汇集当前迭代的改动,供版本发布与部署使用 合入并发布后,在 Casement 部署对应版本

完整流程如下:

流程示意
  1. Casement 建立 release 迭代
    1. dev 分支开发与提交 commit
      1. 本地自测完成
        1. 提交 MR:dev → release
          1. MR 合入 release 并发布
            1. Casement 部署对应版本
              1. 检查部署结果与页面行为

开始修改前检查工作区和当前分支,确认本次需求所属的迭代:

bash
git status --short
git branch --show-current

在对应的 dev-v1.x.xxx 分支完成开发和 commit,本地开发、自测完成后推送分支并提交 MR。MR 的 source 选择 dev-v1.x.xxx,target 选择同版本的 release-v1.x.xxx。

提交 MR 前同步目标分支并处理冲突,不把无关工作区变更混入本次需求。确认 MR 已成功合入 release 并完成发布后,再进入 Casement 部署;只有本地 commit 或 MR 尚未合入时,release 版本还不包含本次改动。

Reviewer、审批要求及多人同时使用开发分支时的远端协作约定,按团队安排执行,具体规则待补充。

6. 核心机制:Journey、模板与字段数据流#

本章解释配置如何成为页面,以及页面字段怎样成为后端请求。判断“只改配置是否足够”时,要同时核对组件能力和字段消费链路。

6.1 Journey 的三层结构#

层次 含义 阅读重点
page 一个页面或配置中的页面节点 页面名、步骤、页面属性
block 页面中的业务区块 组件名、所在步骤、区块属性和字段集合
entry 区块中的字段或渲染元素 component_name、field_name、props、依赖和约束

可以将其理解为“配置描述界面需要什么,代码提供可执行的组件能力”。配置写入了某个 component_name,还需要确认目标页面能够解析并加载该组件。

6.2 模板如何解析并渲染 Journey#

这里说的是前端把 Journey 结构解析并映射成 React 组件的运行机制。它包括页面容器、Journey 解析、区块组件注册、动态表单、步骤与路由处理;与 Webpack 生成 HTML 使用的 templateKey: appHtml 分属不同层次。

Nonmotor 模板渲染与数据流:Journey、React 区块、表单和 Checkout

图 3:产品工厂描述页面需要什么,前端代码实现这些能力,接口提供业务数据与校验结果。不同模板版本的实现路径略有不同。

用 PDP6 和 Purchase5 可以看到完整机制:

  1. 确认产品和页面。 URL 中的 product_id 标识产品;PDP6 默认调用 queryFactoryProductDetail('pdp') 获取对应 Journey,Purchase5 调用 queryFactoryProductDetail('purchase', true)。同一个 HTML 可以服务不同产品。
  2. 解析页面配置。 parseFactoryProductDetail 从 pages 中取出对应页面,把页面/区块的 props、字段的 field_name、dependencies、constraints 等转换成前端消费的数据。
  3. 生成业务区块。 PDP6 的 useGenerateComponents 遍历 blocks,根据 component_name(兼容 name)查找同步注册的组件,或加载对应异步组件。例如 Header、Coverage2、FillInfo、FAQ 都是已经实现的 React 能力。
  4. 生成字段并执行交互。 FillInfo 等区块继续消费 entries,结合 InsEntry 表单能力处理输入、字段值、联动与校验。Journey 描述选用哪些字段和规则,组件代码负责执行;配置里写一个名字,并不会自动生成尚未实现的新功能。
  5. 编排步骤和下一页。 Purchase5 根据 stepItems 建立步骤,并通过区块的 forkey 归入对应步骤,由 PurchaseStepBar 控制前进和返回。next_route 等配置参与跨页面导航;一个 HTML 内也可能包含多个投保步骤。
  6. 闭合业务数据。 输入需要按实现完成校验、转换和缓存写回,供确认页与 Checkout 消费;页面能显示字段,并不代表后端已经能收到它。

PDP6 使用 factoryV2/model/queryProductFactoryJourney.ts 和 Factory V2 的生成 Hook;Purchase5、Confirmation 中仍有对 factory/model 或 factory/hooks 的引用。新旧实现共存,定位时应跟随实际 import,而不是根据文件夹名猜测。

Purchase5 在解析 Journey 时传入 true,entry 的运行时 name 使用 field_name。排查联动时应核对表单实际标识,而不只看 Admin 中的 entry 名称。

6.3 配置源与本地 mock#

当前项目约定:

修改 Journey 时要同步源配置和生成的 view。找不到当前产品的配置时,应先取得有效配置来源,不能根据页面外观拼出一份“看起来合理”的配置。

图片使用经过指定上传流程得到的 CDN 地址;不把 Figma 临时链接或本地路径当作正式 Journey 图片。产品差异优先通过配置表达,配置确实不能承接时再说明代码适配的原因与范围。

6.4 数据闭环要在当前步骤完成#

新增字段时,至少追踪:输入值 → 校验结果 → 缓存位置 → 下游读取 → 展示值 → 请求值。

每个步骤负责把自己的输出处理成下游可直接消费的结构。不要把前序步骤遗漏的字段转换、默认值和业务规则统一堆到最后创单时补救。

项目已有存储工具和 Road Cache helper。阅读具体产品时还要核对缓存 key 与产品、流程、续保等参数的关系。返回修改、切换产品和重新进入,都可能暴露只验证单次向前流程时发现不了的问题。

7. 开发约定:页面、组件、接口与公共能力#

实现前先查已有能力,开发时按职责分层。以下是入门必须遵守的边界,完整规范以仓库 AGENTS.md 和本地 Skills 为准。

7.1 页面与组件如何分工#

层次 应承担的职责
页面入口 index.tsx 挂载页面、页面级埋点及初始化
App / 页面业务层 页面数据、状态组合、业务交互与流程
业务组件 一个可独立理解的业务区块及其交互
基础控件 输入、按钮、图标、状态 UI 等通用表现
service/model 接口类型、参数映射和数据处理;新 Service 不承载 Toast、跳转或 React 逻辑

新增基础 UI 优先查 src/MoneeDesign/;新增业务能力先查已有组件。复杂页面可以使用 reducer 和 Context,局部状态尽量留在负责它的组件中,不为一个小需求引入新的全局状态库。

7.2 新建页面的入口注册#

nonmotor 新页面应注册在 config/nonmotor/{region}.json,其中 entry 路径相对 src/pages,htmlPlugin 的 chunks 必须对应 entry key。涉及多个市场时逐个核对目标市场的配置,修改入口后重启开发服务。

现有 npm run template 页面模板脚本仍向 config/bizConfig/{country}.json 写入注册。 使用它生成文件后,必须检查并调整 nonmotor 的入口归属,避免页面建好了却未进入目标构建,或把页面误加到其他应用。

7.3 接口调用#

统一使用 @/common/request,沿用项目登录、签名等公共行为,不在页面中直接另起 axios/fetch 调用业务接口。

前后端联调时逐项确认:请求 URL、HTTP 方法、字段名称与类型、业务成功码、可选字段、错误处理。HTTP 200 与业务成功是不同条件;errFirst 等封装选项也会影响调用方如何接收结果,阅读时以实际调用契约为准。

金额、日期、证件和较长 ID 的转换优先使用已有工具及协议。产品/Journey 等大整数 ID 不能随意转换为 JavaScript Number。若后续生成 API 代码,遵循项目规范中对生成目录的约束,通过生成流程更新,不手工修改生成结果;当前工作区未包含 src/api/ 目录。

7.4 文案、样式与跳转#

7.5 nonmotor 迁移相关行为#

src/common/nonmotor.ts 根据 nonmotorMigration 配置处理部分旧页面及 API 地址:pages/force_pages 控制页面迁移,apis 控制指定 standalone API 的迁移。API 改写在统一 request 中调用。

因此排查“源码里是旧地址,Network 里是新地址”时,应同时检查迁移配置。不要把所有 /ins/ 或 standalone URL 全局替换成 nonmotor,也不要假定所有旧地址都会自动迁移。

7.6 埋点和监控#

新增或改变交互时,核对页面、点击和一级业务模块曝光。页面入口负责初始化,事件名称按已确认的 TMS 定义,避免重复上报公共字段或在重复渲染时反复曝光。

性能链路按项目约定覆盖 JS_START、BEFORE_MAIN、AFTER_MAIN、RENDER。业务异常使用带稳定 unique_key 的日志,记录定位所需上下文,避免静默吞错或记录凭证、敏感表单原文。

8. 贯穿案例:给投保流程增加联系邮箱#

本节是教学需求,帮助理解实施过程,不代表某个线上产品已有该需求。真实产品 ID、字段路径、文案 key 和接口应在实施时从配置与协议确认。

练习顺序:补全需求 → 定位页面与配置 → 建立字段映射 → 实现与联调 → 验证返回和异常路径。完成后应交付配置/代码差异、字段映射表、请求证据和自测结果。

8.1 把一句需求写完整#

假设需求为:用户在投保信息页填写联系邮箱;该字段必填,格式不正确时提示;确认页展示邮箱;返回修改后保留最新值;提交时传递给后端。

先确认联系邮箱属于投保人还是其他对象,是否已有接口字段、是否自动预填、能否编辑,以及服务端错误如何反馈。如果这些含义没有确认,先不要用另一个产品的字段路径代替。

8.2 定位页面和已有能力#

从有效 URL 确定市场、产品和页面,按第 4 章定位入口;获取当前产品 Journey,找到目标步骤和字段区块。

仓库已有 src/InsEntry/validate/email.ts,可以检查现有邮箱校验的适用性。同时查看当前产品所用输入组件和约束注册方式。新增字段不等于新增一个输入框组件,也不等于必须改动公共校验。

8.3 建立字段映射表#

项目 本次必须确认的内容
展示 标签、占位文案、错误文案及对应翻译
Journey 所属 page/block、entry 标识、component_name、field_name
数据来源 用户输入,是否由已有接口或缓存预填
校验 必填、格式、长度及校验触发时机
缓存 当前步骤写入路径、读取时机、覆盖和清理策略
确认展示 下一页从哪里读取,是否需要格式化
接口 具体请求、字段路径、string 类型及空值策略

同一个字段在 Journey、表单、缓存和接口中的名字可能不同。表格中的路径必须逐项从真实配置、代码和协议核对。

8.4 实现并闭合数据流#

先通过现有 Journey 能力配置输入和约束,生成对应可读 view 和本地 mock。若确认页已有支持该字段的展示能力,同步配置;能力不足时,再扩展相应组件并评估复用产品。

接着检查提交当前步骤时是否会把字段校验、转换并写入正确缓存。进入确认页后应读到相同值;返回编辑再次前进,应读到修改后的值。最后核对真实请求体,确认字段归属和类型与后端一致。

8.5 自测案例#

场景 预期
首次进入,无预填值 展示空字段,行为符合设计
留空并继续 阻止进入下一步,显示必填提示
输入无效格式并继续 显示格式提示,不发送无效的业务提交
输入合法邮箱 校验通过,下一页展示一致
从确认页返回修改 再次前进展示新值,最终请求使用新值
接口返回业务错误 用户能理解结果并按约定重试,不无反馈卡住
重新进入或切换产品 缓存行为符合该产品约定,不出现错误串用
其他复用产品 原有字段和交互不被本次公共改动影响

这个需求的完成证据包括:配置/代码差异、页面截图、字段请求核对结果、异常与返回路径结果,以及发布时需要同步的翻译和 Journey。

9. 验证与排障:证明需求已经实现#

自测按“构建与代码检查 → 目标页面交互 → 真实接口 → App 主流程 → 复用方回归”逐步完成。检查范围由需求决定,已有证据通过后不必重复扩大测试。

记录维度 至少写清
环境 市场、产品、入口、前后端环境/PFB、前端版本
设备 浏览器/模拟器/真机、系统与 App 版本
场景 正常、无效输入、接口异常、返回修改、重新进入、受影响产品
证据 预期与实际结果、截图、请求参数/响应;注明 mock 或真实接口
未完成项 阻塞原因、尚未验证的范围与下一步

9.1 先分清在哪一层失败#

先按第 3 章选择调试环境:浏览器用于快速定位 H5 问题,模拟器配合 Safari 检查 App 内 H5,真机优先用于完整主流程自测。涉及支付、OTP 或地址选择等 App 页面时,不能以浏览器验证代替 App 链路验收。

现象 首先检查
页面 404 当前 APP_NAME、市场入口、路径前缀、是否重启开发服务
页面白屏 Console、JS 资源、初始化异常和主请求结果
修改没有生效 是否运行本地版本、代理规则、当前产品配置、缓存
请求未命中预期服务 ENV、代理目标、PFB、迁移配置和实际请求 URL
HTTP 200 但页面报错 业务码、响应结构、必需数据与调用方处理
字段不出现 Journey 数据、组件匹配、显隐依赖、当前步骤
输入正确但请求值错误 field_name、缓存路径、类型转换和下游组装
返回后信息丢失 步骤离开时写回、返回时读取、缓存 key 和清理时机
浏览器正常、App 异常 Bridge、WebView 返回行为、登录和真实运行环境
某一市场正常、其他市场异常 市场入口、条件编译、区域配置、翻译和组件依赖

先复现并确认请求、响应和状态,再决定改动层次。不要因为错误出现在页面上就直接修改组件。

9.2 Mock 与真实联调#

Mock 用于接口未完成时的并行开发,以及稳定复现空数据、异常和特定分支。响应需要遵守真实契约,并把作用范围限定到目标接口/产品。

验证记录应写清哪些结果来自 mock、哪些已经通过真实接口。Mock 成功只能证明页面在该响应下的行为;真实登录、网关、PFB、后端校验和 App 行为需要相应环境的证据。

9.3 代码检查与运行验收#

依赖安装完成后,可执行项目工具。以下代码检查命令中路径需要替换为本次真实改动文件:

bash
npx tsc --noEmit
npx eslint <本次修改的TS或TSX文件>
npx prettier --check <本次修改的文件>
git diff --check

执行 npm run dev,在菜单选择“构建”并明确选择目标环境、市场和 nonmotor,完成目标构建检查。多个市场共用的改动,按影响范围验证对应构建和页面。

命令失败时区分本次引入的问题、已有问题和环境阻塞,保留准确结论。构建通过仍需浏览器验收。前端不默认要求新增单测文件,已有相关测试按需运行,业务路径以目标环境和页面验证为依据。

9.4 使用已有自动化用例#

优先查找 runbooks/ 中已有的页面用例,确认场景、市场、环境和预期与需求一致。执行时按 runbooks/index.json 的 executionOwner 选择对应 Skill,不混用两条执行链的 session 和结果。

新增交互应补充对应验收场景;自动化报告要能定位到步骤、截图、请求或其他证据。登录失败、配置缺失等阻塞不能被记录成业务通过。

10. 交付与发布:MR、提测、Casement 与回退#

本章接续第 5 章的迭代分支流程:本地自测完成 → 提交 MR → Review 与合入 → 按团队流程提测/发布 → Casement 部署 → 检查实际页面。代码、配置与接口是同一次交付的组成部分。

10.1 准备 MR 与 QA 交接资料#

MR 描述应包含业务问题、最终行为、影响页面/产品/市场、代码与配置改动,以及验证结果。涉及公共能力时列明调用方影响,涉及协议时说明字段变化。

提交前检查:有无无关文件、临时日志、账号或凭证;新增类型与真实数据是否一致;配置与 mock 是否按约定同步;自测是否覆盖用户回退和错误路径。

给 QA 的交接资料应包含完整入口、市场/产品、环境与版本、账号获取方式、需求范围、验收场景、自测结果及已知限制。验证记录格式见第 9 章。

10.2 前端交付物不只有代码#

物料 交付时核对
前端代码包 分支、版本、APP_NAME、市场、环境
Journey 目标产品、配置版本、组件兼容性、发布状态
i18n / Transify key、目标语言、插值和实际下发
图片 正式 CDN 地址、尺寸、加载效果
PFC 下发范围、字段结构、预期命中行为
后端接口 环境、版本、字段契约和发布依赖
QA 验证资料 完整入口、场景、预期、自测证据与限制

物料范围按实际产品和市场确定,不照搬 Admin 后端所有物料全地区同步的要求。

10.3 在 Casement 部署迭代版本#

部署前先完成第 5.4 节的开发、自测、MR 合入与发布流程。然后在 Casement 中选择 nonmotor_h5 应用,进入对应 release-v1.x.xxx 迭代,部署该迭代对应的分支代码版本。

Casement 中选择 nonmotor_h5 应用、release 迭代并查看部署记录

图为用户提供的 release-v1.3.318 Test 环境示例。使用时替换为当前迭代和目标环境,不直接沿用截图中的版本、PFB 或部署状态。

操作顺序:

  1. 在 My Application 中选择 nonmotor_h5,进入本次迭代的 release 页面。
  2. 确认当前环境,并检查本次需求需要的配置、Release Note 等发布物料。
  3. 在 Deployment → Service Deployment 中找到目标服务,使用 Deploy 进入部署操作,核对本次版本和目标环境后提交。
  4. 在部署记录中核对 Region、Env 和 Parameters (Git/PFB/ImageTag),确认版本、PFB 与本次联调或验证计划一致。
  5. 观察 Status,必要时通过 Detail 查看详情。deploying 表示仍在部署,不能视为完成;部署成功后再验证目标页面及业务链路。

MR 合入、版本发布、部署成功和业务验收分别是不同检查点。部署记录中的 Git/版本、PFB 和镜像信息应与预期对应,避免代码已合入但实际验证的仍是其他版本。

部署负责人、审批要求,以及发布版本/Tag 的具体生成操作仍需按团队约定补充。截图中的 Rollback 是平台入口,实际回滚前仍需检查代码与配置的兼容关系。

10.4 构建产物与市场范围#

deploy/nonmotor.json 定义了 nonmotor 部署模块。deploy/space_build.sh 读取部署环境中的 CID 作为 REGION,并设置 APP_NAME 进行构建;产物目录为 dist/nonmotor,部署使用 /nonmotor/ 页面路径,静态资源路径也包含环境和市场信息。

这意味着发布时要核对目标市场与应用,不能仅凭某一次构建完成就认定所有市场都已覆盖。Casement 的一条部署记录可以包含多个 Region,也可以只包含一个市场;以本次选择和部署结果为准,不要求开发者机械地逐市场点击部署。

10.5 发布顺序与回退#

发布前把代码、配置和接口依赖放在一起 Review。例如,Journey 引用了新组件时,需要确保目标代码包能够加载它;接口字段变化时,需要确认前后端版本组合的兼容性。

回退方案也要覆盖配置和接口配套关系。不能只回退前端包,却保留仅新包能处理的 Journey。

上线后检查目标入口、主流程、资源加载、业务错误和关键埋点。监控与验收范围应对应本次改动的市场、产品和场景。

11. 效率工具:日常查询、AI 协作与上手练习#

11.1 按问题选择工具#

要解决的问题 工具或入口
找代码和调用方 IDE 全局搜索、rg、Git diff
看页面请求与响应 浏览器 DevTools Network
看样式、布局和运行错误 Elements、Console、断点调试
核对视觉与交互设计 Figma 及目标页面实际渲染
查询产品 Journey Admin 产品工厂及仓库配置同步 Skill
管理翻译 Transify、Journey i18n 及项目读取链路
核对埋点 TMS 定义与实际事件
排查线上表现 IDAP 与必要的后端日志
执行回归 现有 Runbook 与对应执行 Skill

具体平台 URL 和权限申请方式应从团队入口表获取,本文不把其他项目或旧环境的链接当作 nonmotor 当前入口。

11.2 给 AI 的输入要覆盖开发上下文#

可以使用下面的任务描述模板:

text
请在 nonmotor_h5 中实现以下需求。
市场、环境、构建环境:……
产品与完整页面入口:……
需求正文、设计来源:……
当前 Journey 来源:……
接口协议、字段与业务码:……
预期交互、错误和返回行为:……
影响范围与不应改动的部分:……
验收场景:……

先判断配置与代码的改动边界,列出影响文件和字段数据流,
按仓库 AGENTS.md 与本地 Skills 实现,提供验证结果和未解决项。

仓库已有需求分析、TD、代码生成、Journey 查询/更新、mock、UI 验证、Runbook 和代码 Review 等 Skills。根据任务选择相应入口,编码前仍需应用完整工程规范。AI 不能替代开发者确认字段语义、配置范围和最终运行效果。

11.3 后端同学建议的上手顺序#

第一个需求可以选择已有组件支持的文案或字段配置调整,熟悉运行环境和交付流程;随后完成本指南中类似的字段数据流;再承接需要扩展组件的小型业务模块。

学习前端基础时,优先覆盖对象/数组、可选值、Promise、TypeScript 类型、React props/state、事件、Effect、Context/reducer 和基础布局。每个概念都回到当前页面找一个真实使用点。

12. 第一个需求的完成标准#

完成第一个需求时,逐项检查以下结果;“代码写完”只是其中一部分。

13. 补充内容:后续专题#

前面的章节覆盖日常开发闭环。后续专题按“差异化开发 → 配置与上线控制 → 观测与排障”展开,每个专题配实际代码、平台操作和验证案例。以下保留为专题计划,尚未补齐的平台规则不作为已确认操作流程。

13.1 差异化开发#

专题 后续重点介绍 希望解决的问题
市场差异(条件编译) REGION 与条件编译的关系;市场代码如何进入对应构建产物;条件编译与运行时判断的区别 同一份源码如何支持不同市场?修改某市场逻辑时,怎样判断其他市场是否受影响?
产品差异 共享模板中的产品差异如何表达;Journey 配置、产品条件与专属组件的使用边界 相同页面中,不同产品为什么展示不同内容?新需求应该改配置还是扩展组件?

13.2 配置与上线控制#

专题 后续重点介绍 希望解决的问题
Transify 配置流程 文案 key 的申请/维护、多语言配置、项目接入、更新生效与页面验证流程 新增或修改文案需要经过哪些步骤?平台已修改但页面未更新时怎样排查?
灰度功能 功能开关、灰度条件与命中判断;如何验证开启/关闭两条路径,以及逐步开放和回退 为什么同一个功能对不同用户表现不同?如何确认自己命中了灰度?
产品工厂放量 产品工厂相关能力的放量入口、适用范围、命中规则、验证方式,以及扩大范围和回退流程 配置完成后如何逐步开放?怎样确认目标产品、市场与用户使用了预期版本?

13.3 观测与排障#

专题 后续重点介绍 希望解决的问题
TMS 埋点上报流程 埋点需求与事件定义、TMS 配置查询、页面/点击/曝光事件接入、参数映射,以及触发与上报验证 如何从埋点定义找到前端上报位置?怎样验证事件时机、参数及重复或漏报问题?
IDAP 日志查看与排查 查询入口与权限、市场/环境/时间范围筛选、接口与自定义日志查看,以及结合页面、产品和会话线索定位问题 页面报错或接口异常时从哪里查起?如何把前端日志、Network 请求与后端日志关联起来?

这些专题会分别说明控制对象、配置入口、代码消费位置和验证方法,尤其区分功能灰度、市场构建、产品差异与产品工厂放量,避免把不同层面的控制机制混为一谈。

TMS 专题重点说明埋点定义、接入与上报验证;IDAP 专题重点说明运行日志和异常排查。后续会分别展示实际使用的查询入口,说明各平台能看到的数据及其边界。

本节先作为后续分享目录;具体平台操作、规则和示例将在对应专题中补充。

附录 A:团队操作信息待补充#

这些信息影响实际操作,在确认前不将示例或历史约定作为当前流程:

信息 当前状态 需要补齐的内容
分支与 Review dev/release 命名和 MR 方向已确认 Reviewer、审批要求、多人开发分支的远端协作约定
本地代理 ZeroOmega、Whistle、证书和市场规则已整理 按目标环境实测;确认 TH/SG/PH 浏览器域名与 API 目标的对应关系
iOS 模拟器 Xcode、Simulator App 安装和系统代理步骤已整理 当前推荐的 App 构建、iOS runtime、Mac 架构兼容性及目标 App 业务入口
本地登录 待补充 测试账号获取、目标域名登录和登录态验证步骤
PFB 联调 需按目标环境确认 设置方式、有效性检查、后端命中验证
部署与回滚 Casement 应用、迭代入口及部署流程已确认 平台 URL、操作人、审批、版本/Tag 生成与具体回滚步骤
培训演示产品 待选定 市场、产品、完整入口、设计截图和演示数据
常用平台 能力已列出,链接待补齐 Admin、Transify、TMS、IDAP、KMS 与权限申请入口

附录 B:依据与维护范围#

主要核对文件:.nvmrc、package.json、scripts/prompt.js、scripts/start.js、scripts/create-template.js、config/bizConfig.js、config/paths.js、config/webpack.config.js、config/nonmotor/my.json、deploy/nonmotor.json、deploy/space_build.sh、deploy/space_install.sh。

页面与数据流依据:src/pages/factoryV2/purchase5/index.tsx、App.tsx、src/pages/factory/model/queryProductFactoryJourney.ts、src/common/request.ts、src/common/nonmotor.ts、src/module/storage/helper.ts、src/InsEntry/validate/email.ts。

页面入口介绍补充核对:config/nonmotor/my.json、config/nonmotor/sg.json、config/common/my.json、config/ec/my.json、config/bizConfig/my.json、src/pages/factoryV2/pdp/index.tsx、src/pages/factoryV2/pdp/App.tsx、src/pages/factoryV2/model/queryProductFactoryJourney.ts;配置组装和输出规则核对 config/bizConfig.js、config/webpack.config.js 与 config/paths.js。common 应用的仓库维护约定来自团队提供的页面注册截图。

项目介绍补充核对(2026-10-10):Motor 流程基于 ins_h5 当前工作区的 config/bizConfig/{region}.json,以及 src/pages/id/motor/carPdp/components/GetQuoteBtn/index.tsx、quote/components/QuoteAddonPanel/index.tsx、quote/components/BottomBar/index.tsx、confirmPersonalInfo/components/ConfirmBtn/index.tsx;MY 的 carPdp/components/BottomBar、quoteList/App.tsx、common/components/QuoteCard、quoteDetail2/components/BottomBar;SG 的 carPdp/components/BottomBar、quoteList/components/QuoteCard、quoteDetail/components/BottomBar、quoteAddOn/components/BottomBar、applicationForm/App.tsx。上述 MY/SG 路径分别以 src/pages/my/、src/pages/sg/ 为前缀。

Nonmotor 复用机制基于 nonmotor_h5 当前工作区的七个 config/nonmotor/{region}.json、src/pages/factoryV2/hooks/useGenerateComponents.tsx、model/queryProductFactoryJourney.ts、pdp/syncComponents/index.ts、pdp/config/pdpConfig.tsx、purchase5/App.tsx、purchase5/config/index.ts、confirmInfo/App.tsx,以及 src/pages/factory/model/queryProductFactoryJourney.ts、src/pages/checkoutV2/App.tsx 和 model/{region}。Factory V2 的缩略路径均以 src/pages/factoryV2/ 为前缀。组织方式的业务原因结合团队本次说明整理;流程图是源码导航与配置的教学示意,未冒充所有市场产品的端到端实测结果。

开发规范依据:本仓库 AGENTS.md 及 .agents/skills/ 下的工程、Journey、Service、React、样式、MoneeDesign、运行时集成与埋点规范。后续维护应以当前源码和规范为准。

文档编排参考:admin后端开发流程,内容由用户提供的 HTML 读取。代理章节结合用户材料、ZeroOmega 安装页和随文引用的 Whistle 官方说明整理。本文未执行真实产品配置修改、业务操作或发布,也未代用户安装插件、根证书或切换代理。

分支及部署流程依据:用户确认的 dev-v1.x.xxx → release-v1.x.xxx → Casement 部署 流程,以及随文保存的 Casement 截图。截图仅用作操作位置说明,不作为当前部署结果或权限状态的证明。

模拟器流程依据:用户提供的模拟器安装截图,以及随文引用的 Apple 和 Whistle 官方说明;内部下载入口来自截图正文,版本与页面可用性未独立验证。

附录 C:市场代理规则#

以下按用户提供的域名整理,保留原有整站转发意图,目标统一为本地 HTTP 3000 服务;没有实际联网验证这些业务域名。每个市场/环境单独保存为规则组,按本次开发选择启用,不要把所有环境同时指向一套本地构建后混用。

text
# BR UAT
protection.uat.shopee.com.br http://localhost:3000

# TH Test
protection.test.shopee.co.th http://localhost:3000

# TH UAT
protection.uat.seainsurebroker.co.th http://localhost:3000

# SG Test
test.moneeinsureagency.sg http://localhost:3000

# SG UAT
uat.moneeinsureagency.sg http://localhost:3000

# MY Test
protection.test.shopee.com.my http://localhost:3000

# MY UAT
protection.uat.shopee.com.my http://localhost:3000

# VN Test
insurance.test.shopee.vn http://localhost:3000

# VN UAT
insurance.uat.shopee.vn http://localhost:3000

# ID Test
insurance.test.shopee.co.id http://localhost:3000

# ID UAT
insurance.uat.shopee.co.id http://localhost:3000

# PH Test
protection.test.moneeinsurebroker.com.ph http://localhost:3000

# PH UAT
protection.uat.moneeinsurebroker.com.ph http://localhost:3000

整理时处理了以下重复与不一致:

附录 D:Motor 市场流程与目录详解#

本附录供需要对照车险页面的同学深入阅读。第 1 章讲业务差异;这里保留 ID、MY、SG 的具体链路、团队目录截图,以及七个市场的入口示例。源码中存在历史与可选分支,表格不代表所有产品的固定步骤。

ID:车辆与报价逻辑分开,附加保障作为报价页分支#

当前 id/motor/ 的主链路可以沿以下页面阅读:

car-pdp.html → quote2.html → confirm-personal-info2.html → checkout.html

页面/分支 作用与代码位置
车险 PDP id/motor/carPdp/;填写/选择车辆相关信息,GetQuoteBtn 成功后进入 quote2.html
报价页 id/motor/quote/;展示和调整报价、保障方案,BottomBar 进入个人信息确认
车辆配件、附加保障 QuoteAddonPanel 分别打开 add-car-accessories2.html、add-additional-coverage2.html;返回报价页后读取缓存、更新选项,相关处理会触发重新报价
个人信息确认 id/motor/confirmPersonalInfo/;确认车主等资料,写入 createPolicyParams、calcPremiums 后进入 Checkout

车辆品牌和地区选择也有独立入口,例如 car-information.html、region-code-selector.html。这些是用户操作触发的辅助页面,不是每次投保都要依次经过的主步骤。

MY:从车辆信息获取报价列表,再进入报价详情#

当前汽车报价路径可读作:

car-pdp.html / car-pdp2.html → quote-list.html → quote-detail2.html → checkout.html

PDP 的 my/carPdp/components/BottomBar 进行预检、请求报价卡片,并把车辆信息和报价结果写入缓存;my/quoteList/App.tsx 读取缓存并展示卡片;my/common/components/QuoteCard 进入报价详情;my/quoteDetail2/components/BottomBar 处理进入 Checkout 前的业务逻辑。

报价详情还可打开 vehicle-info.html 修改车辆信息。摩托车与部分历史路径存在分支,例如 motorcycle-quote-list.html、quote-detail.html,因此不能把汽车示例原样套到所有 MY Motor 产品。

SG:报价详情之后,按保障内容决定是否进入 Add-ons#

SG 的报价列表路径可读作:

car-pdp.html → quote-list.html → quote-detail.html → [quote-addon.html] → application-form.html → checkout.html

sg/quoteDetail/components/BottomBar 根据当前方案的可用附加保障计算 hasAddOns:有附加保障时进入 quote-addon.html,否则直接进入投保表单。PDP 还保留进入 quote.html 等路径,续保也有专属分支;上面的列表路径用于说明当前代码中的一种业务编排。

这类差异解释了为什么不能简单把某市场的 Motor 页面复制后只换翻译:页面拆分、字段、报价前提、附加保障、缓存结构与下一步条件都可能变化。

不同市场的入口目录#

Motor 页面源码目录:ID motor 子目录与 MY、PH、SG、TH、VN 市场目录

团队提供的目录截图:src/pages/id/motor/ 集中放置 ID 的车险主流程页面;其他市场在各自目录维护。截图中同时能看到 factory、factoryV2 和 checkoutV2,分别对应产品工厂模板与收银台。

以下是当前 config/bizConfig/{region}.json 已登记的代表页面,不表示它们全部属于同一条顺序流程。

市场 主要源码目录(相对 src/pages/) 已登记的页面示例
MY my/ carPdp、quoteList、quoteDetail2、vehicleInfo
ID id/motor/,以及部分 id/ 辅助页 carPdp、quote、addAdditionalCoverage、confirmPersonalInfo;carInformation
SG sg/ carPdp、quoteList、quoteDetail、quoteAddOn、applicationForm、driverInfo
TH th/ carPdp、quoteList、coverageDetail、applicationForm、confirmInfo、carPhoto
PH ph/ carPdp2、quoteList、coverageDetail、vehicleInformation2、reviewConfirm、kyc
VN vn/ carPdp、carInformation、applicationForm、confirmInfo
BR br/ carPdp、selectCoverageInsurer、quote、selectPlan、applicationForm
↑