You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
311 lines
15 KiB
311 lines
15 KiB
|
2 weeks ago
|
# IGG4 小程序埋点实施计划
|
||
|
|
|
||
|
|
## 概要
|
||
|
|
|
||
|
|
基于 `doc/track.md` 文档和信达项目的成熟埋点模式,为 IGG4 项目实施页面级 PV 埋点和点击级事件埋点。采用信达项目已验证的 `PG_` / `BTN_` 双层命名体系,复用现有 `app.mpBehavior()` 基础设施。
|
||
|
|
|
||
|
|
## 现状分析
|
||
|
|
|
||
|
|
| 维度 | 现状 |
|
||
|
|
|------|------|
|
||
|
|
| 埋点函数 | `app.mpBehavior({ PageName, doctor? })` — 仅 1 处调用 (`MINI_PROGRAM_VISIT`) |
|
||
|
|
| API 接口 | 患者端 `?r=igg4/mp-behavior/add`,医生端 `?r=igg4/doctor/mp-behavior/add` |
|
||
|
|
| 类型签名 | `{ PageName: string; doctor?: boolean }` — 需扩展以支持 `detailId` 等可选参数 |
|
||
|
|
| 页面级埋点 | 完全未实现(track.md 中 25+ 页面均未添加调用) |
|
||
|
|
| 点击级埋点 | 完全未实现 |
|
||
|
|
| 命名规范 | 无(信达项目使用 `PG_`/`BTN_` 前缀命名体系) |
|
||
|
|
|
||
|
|
## 命名规范(参照信达项目)
|
||
|
|
|
||
|
|
| 类别 | 前缀 | 格式 | 示例 |
|
||
|
|
|------|------|------|------|
|
||
|
|
| 页面浏览(患者端) | `PG_` | `PG_Patient{功能名}` | `PG_PatientHome`、`PG_PatientRepository` |
|
||
|
|
| 页面浏览(医生端) | `PG_` | `PG_Doctor{功能名}` | `PG_DoctorHome`、`PG_DoctorPatient` |
|
||
|
|
| 点击事件(患者端) | `BTN_` | `BTN_Patient{功能名}{操作}` | `BTN_PatientHomeDoctorCard`、`BTN_PatientMyVip` |
|
||
|
|
| 点击事件(医生端) | `BTN_` | `BTN_Doctor{功能名}{操作}` | `BTN_DoctorHomeInvite`、`BTN_DoctorPatientDetail` |
|
||
|
|
|
||
|
|
### PageName 与 track.md 页面对照表
|
||
|
|
|
||
|
|
**患者端页面级埋点(PG_):**
|
||
|
|
|
||
|
|
| track.md 页面路径 | PageName |
|
||
|
|
|-------------------|----------|
|
||
|
|
| pages/index/index | `PG_PatientHome` |
|
||
|
|
| gift/pages/recordList/index | `PG_PatientRecordList` |
|
||
|
|
| gift/pages/record/index | `PG_PatientRecordAdd` |
|
||
|
|
| gift/pages/recordDetail/index | `PG_PatientRecordDetail` |
|
||
|
|
| pages/interactivePatient/index | `PG_PatientInteractive` |
|
||
|
|
| pages/doctorDetail/index | `PG_PatientDoctorDetail` |
|
||
|
|
| pages/repository/index | `PG_PatientRepository` |
|
||
|
|
| pages/repositoryDetail/index | `PG_PatientRepositoryDetail` |
|
||
|
|
| pages/my/index | `PG_PatientMy` |
|
||
|
|
| pages/qaFormDetail/index | `PG_PatientQaFormDetail` |
|
||
|
|
| pages/qaForm/index | `PG_PatientQaForm` |
|
||
|
|
| pages/caseReport/index | `PG_PatientCaseReport` |
|
||
|
|
| pages/personalInformation/index | `PG_PatientPersonalInfo` |
|
||
|
|
| pages/cancellation/index | `PG_PatientCancellation` |
|
||
|
|
| pages/mySave/index | `PG_PatientMySave` |
|
||
|
|
| pages/feedback/index | `PG_PatientFeedback` |
|
||
|
|
|
||
|
|
**医生端页面级埋点(PG_):**
|
||
|
|
|
||
|
|
| track.md 页面路径 | PageName |
|
||
|
|
|-------------------|----------|
|
||
|
|
| doctor/pages/d_home/index | `PG_DoctorHome` |
|
||
|
|
| doctor/pages/d_invite/index | `PG_DoctorInvite` |
|
||
|
|
| doctor/pages/d_patient/index | `PG_DoctorPatient` |
|
||
|
|
| doctor/pages/d_patientDetail/index | `PG_DoctorPatientDetail` |
|
||
|
|
| doctor/pages/d_taskList/index | `PG_DoctorTaskList` |
|
||
|
|
| doctor/pages/d_taskDetail/index | `PG_DoctorTaskDetail` |
|
||
|
|
| doctor/pages/d_createTask/index | `PG_DoctorCreateTask` |
|
||
|
|
| doctor/pages/d_interactive/index | `PG_DoctorInteractive` |
|
||
|
|
| doctor/pages/d_interactiveDoctor/index | `PG_DoctorInteractiveDoctor` |
|
||
|
|
| doctor/pages/d_my/index | `PG_DoctorMy` |
|
||
|
|
| doctor/pages/d_userInfo/index | `PG_DoctorUserInfo` |
|
||
|
|
| doctor/pages/d_changeDoctor/index | `PG_DoctorChangeDoctor` |
|
||
|
|
|
||
|
|
## 实施步骤
|
||
|
|
|
||
|
|
### 第 1 步:扩展 mpBehavior 类型签名
|
||
|
|
|
||
|
|
**文件**: `src/app.ts` + `typings/index.d.ts`
|
||
|
|
|
||
|
|
扩展 `mpBehavior` 方法签名,支持可选的 `detailId` 参数(用于详情页等场景):
|
||
|
|
|
||
|
|
```ts
|
||
|
|
// typings/index.d.ts
|
||
|
|
mpBehavior: (data: { PageName: string; doctor?: boolean; detailId?: string }) => void
|
||
|
|
|
||
|
|
// src/app.ts — 实现签名同步更新
|
||
|
|
mpBehavior(data: { PageName: string; doctor?: boolean; detailId?: string }) {
|
||
|
|
// ... 现有逻辑不变,detailId 会随 data 对象一起 POST 到后端
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
> 说明:与信达项目一致,`detailId` 等额外字段作为 POST data 的一部分直接发送给后端,无需在 `mpBehavior` 函数内做特殊处理。
|
||
|
|
|
||
|
|
### 第 2 步:实施患者端页面级埋点(16 个页面)
|
||
|
|
|
||
|
|
在每个页面的 `onShow` 中(有 `waitLogin` 的在 `waitLogin().then()` 内),调用 `app.mpBehavior()`。
|
||
|
|
|
||
|
|
**通用模式:**
|
||
|
|
|
||
|
|
```ts
|
||
|
|
// 患者端页面(无 waitLogin)
|
||
|
|
onShow() {
|
||
|
|
app.mpBehavior({ PageName: 'PG_PatientXxx' })
|
||
|
|
}
|
||
|
|
|
||
|
|
// 患者端页面(有 waitLogin)
|
||
|
|
onShow() {
|
||
|
|
app.waitLogin().then(() => {
|
||
|
|
app.mpBehavior({ PageName: 'PG_PatientXxx' })
|
||
|
|
// ... 原有业务逻辑
|
||
|
|
})
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**修改文件清单:**
|
||
|
|
|
||
|
|
| # | 文件路径 | PageName | 嵌入位置 |
|
||
|
|
|---|---------|----------|---------|
|
||
|
|
| 1 | `src/pages/index/index.ts` | `PG_PatientHome` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 2 | `src/gift/pages/recordList/index.ts` | `PG_PatientRecordList` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 3 | `src/gift/pages/record/index.ts` | `PG_PatientRecordAdd` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 4 | `src/gift/pages/recordDetail/index.ts` | `PG_PatientRecordDetail` | `onShow` → `waitLogin().then()` 内首行,带 `detailId` |
|
||
|
|
| 5 | `src/pages/interactivePatient/index.ts` | `PG_PatientInteractive` | `onLoad` → `waitLogin().then()` 内首行 |
|
||
|
|
| 6 | `src/pages/doctorDetail/index.ts` | `PG_PatientDoctorDetail` | `onShow` → `waitLogin().then()` 内首行,带 `detailId` |
|
||
|
|
| 7 | `src/pages/repository/index.ts` | `PG_PatientRepository` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 8 | `src/pages/repositoryDetail/index.ts` | `PG_PatientRepositoryDetail` | `onShow` → `waitLogin().then()` 内首行,带 `detailId` |
|
||
|
|
| 9 | `src/pages/my/index.ts` | `PG_PatientMy` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 10 | `src/pages/qaFormDetail/index.ts` | `PG_PatientQaFormDetail` | `onShow` → `waitLogin().then()` 内首行,带 `detailId` |
|
||
|
|
| 11 | `src/pages/qaForm/index.ts` | `PG_PatientQaForm` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 12 | `src/pages/caseReport/index.ts` | `PG_PatientCaseReport` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 13 | `src/pages/personalInformation/index.ts` | `PG_PatientPersonalInfo` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 14 | `src/pages/cancellation/index.ts` | `PG_PatientCancellation` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 15 | `src/pages/mySave/index.ts` | `PG_PatientMySave` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 16 | `src/pages/feedback/index.ts` | `PG_PatientFeedback` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
|
||
|
|
### 第 3 步:实施医生端页面级埋点(12 个页面)
|
||
|
|
|
||
|
|
医生端埋点需传入 `doctor: true`,API 路径切换为 `?r=igg4/doctor/mp-behavior/add`。
|
||
|
|
|
||
|
|
**通用模式:**
|
||
|
|
|
||
|
|
```ts
|
||
|
|
// 医生端页面
|
||
|
|
onShow() {
|
||
|
|
app.waitLogin().then(() => {
|
||
|
|
app.mpBehavior({ doctor: true, PageName: 'PG_DoctorXxx' })
|
||
|
|
// ... 原有业务逻辑
|
||
|
|
})
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**修改文件清单:**
|
||
|
|
|
||
|
|
| # | 文件路径 | PageName | 嵌入位置 |
|
||
|
|
|---|---------|----------|---------|
|
||
|
|
| 1 | `src/doctor/pages/d_home/index.ts` | `PG_DoctorHome` | `onLoad` → `waitLogin().then()` 内首行 |
|
||
|
|
| 2 | `src/doctor/pages/d_invite/index.ts` | `PG_DoctorInvite` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 3 | `src/doctor/pages/d_patient/index.ts` | `PG_DoctorPatient` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 4 | `src/doctor/pages/d_patientDetail/index.ts` | `PG_DoctorPatientDetail` | `onShow` → `waitLogin().then()` 内首行,带 `detailId` |
|
||
|
|
| 5 | `src/doctor/pages/d_taskList/index.ts` | `PG_DoctorTaskList` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 6 | `src/doctor/pages/d_taskDetail/index.ts` | `PG_DoctorTaskDetail` | `onShow` → `waitLogin().then()` 内首行,带 `detailId` |
|
||
|
|
| 7 | `src/doctor/pages/d_createTask/index.ts` | `PG_DoctorCreateTask` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 8 | `src/doctor/pages/d_interactive/index.ts` | `PG_DoctorInteractive` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 9 | `src/doctor/pages/d_interactiveDoctor/index.ts` | `PG_DoctorInteractiveDoctor` | `onShow` → `waitLogin().then()` 内首行,带 `detailId` |
|
||
|
|
| 10 | `src/doctor/pages/d_my/index.ts` | `PG_DoctorMy` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 11 | `src/doctor/pages/d_userInfo/index.ts` | `PG_DoctorUserInfo` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
| 12 | `src/doctor/pages/d_changeDoctor/index.ts` | `PG_DoctorChangeDoctor` | `onShow` → `waitLogin().then()` 内首行 |
|
||
|
|
|
||
|
|
### 第 4 步:实施点击级埋点(BTN_)
|
||
|
|
|
||
|
|
在关键交互的事件处理函数首行,插入 `app.mpBehavior()` 调用。
|
||
|
|
|
||
|
|
#### 患者端点击埋点
|
||
|
|
|
||
|
|
**首页 — `src/pages/index/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| `routerTo(e)` 中 doctor 类卡片 | `BTN_PatientHomeDoctorCard` | 迷你医生卡片点击 |
|
||
|
|
| `routerTo(e)` 中功能入口 | `BTN_PatientHomeFunctionCard` | 功能卡片跳转 |
|
||
|
|
| `handleNextVisit()` | `BTN_PatientHomeNextVisit` | 下次复诊入口 |
|
||
|
|
| `handleArticleView(e)` | `BTN_PatientHomeArticle` | 文章点击 |
|
||
|
|
| `handleArticleSave(e)` | `BTN_PatientHomeArticleSave` | 文章收藏 |
|
||
|
|
| `handleToastOk()`(绑定医生确认) | `BTN_PatientHomeBindDoctor` | 绑定医生弹窗确认 |
|
||
|
|
| `handlePublic()` | `BTN_PatientHomeFollowPublic` | 关注公众号 |
|
||
|
|
|
||
|
|
**我的页面 — `src/pages/my/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| `routerVipTo()` | `BTN_PatientMyVip` | VIP 认证入口 |
|
||
|
|
| `handleMyHealthRecord(e)` | `BTN_PatientMyHealthRecord` | 健康档案 |
|
||
|
|
| `handleQaForm()` | `BTN_PatientMyQaForm` | 健康问卷 |
|
||
|
|
| `routerTo(e)` 中 mySave | `BTN_PatientMySave` | 我的收藏 |
|
||
|
|
| `routerTo(e)` 中 personalInfo | `BTN_PatientMyPersonalInfo` | 个人信息 |
|
||
|
|
| `routerTo(e)` 中 feedback | `BTN_PatientMyFeedback` | 问题反馈 |
|
||
|
|
| `handleMiniDoctor()` | `BTN_PatientMyMiniDoctor` | 迷你医生 |
|
||
|
|
|
||
|
|
**医患互动 — `src/pages/interactivePatient/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| `handleHot(e)` | `BTN_PatientInteractiveHotQuestion` | 热门问题点击 |
|
||
|
|
| `handleQuestion(e)` | `BTN_PatientInteractiveQuestion` | 快捷问题点击 |
|
||
|
|
| `handleConfirm()` | `BTN_PatientInteractiveSend` | 发送消息 |
|
||
|
|
| `handleAdl()` | `BTN_PatientInteractiveAdl` | ADL 评估入口 |
|
||
|
|
| `handleQol()` | `BTN_PatientInteractiveQol` | QoL 入口 |
|
||
|
|
| `handleDoctorDetail()` | `BTN_PatientInteractiveDoctorDetail` | 查看医生详情 |
|
||
|
|
|
||
|
|
**知识库 — `src/pages/repository/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| `tabChange(e)` | `BTN_PatientRepositoryTab` | Tab 切换 |
|
||
|
|
| `handleSearch()` | `BTN_PatientRepositorySearch` | 搜索 |
|
||
|
|
| `handleCate(e)` | `BTN_PatientRepositoryCategory` | 分类筛选 |
|
||
|
|
| `handleDetail(e)` | `BTN_PatientRepositoryArticle` | 文章详情 |
|
||
|
|
| `handleStar(e)` | `BTN_PatientRepositoryStar` | 点赞 |
|
||
|
|
| `handleToggleSave(e)` | `BTN_PatientRepositorySave` | 收藏 |
|
||
|
|
|
||
|
|
**就诊记录列表 — `src/gift/pages/recordList/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| 新增就诊记录入口 | `BTN_PatientRecordListAdd` | 新增记录按钮 |
|
||
|
|
| 点击记录项 | `BTN_PatientRecordListItem` | 记录列表项点击 |
|
||
|
|
|
||
|
|
**就诊记录新增 — `src/gift/pages/record/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| 提交/保存按钮 | `BTN_PatientRecordAddSubmit` | 保存记录 |
|
||
|
|
|
||
|
|
**医生详情 — `src/pages/doctorDetail/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| 查看互动 | `BTN_PatientDoctorDetailInteractive` | 进入互动页 |
|
||
|
|
|
||
|
|
#### 医生端点击埋点
|
||
|
|
|
||
|
|
**医生首页 — `src/doctor/pages/d_home/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| `handlePatient(e)` | `BTN_DoctorHomePatient` | 患者列表入口 |
|
||
|
|
| `handleInvite()` | `BTN_DoctorHomeInvite` | 邀约按钮 |
|
||
|
|
| `handleSelectYear1()` | `BTN_DoctorHomeSelectYear` | 年份筛选 |
|
||
|
|
|
||
|
|
**邀约患者 — `src/doctor/pages/d_invite/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| 发送邀约按钮 | `BTN_DoctorInviteSend` | 发送邀约 |
|
||
|
|
|
||
|
|
**患者列表 — `src/doctor/pages/d_patient/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| 搜索 | `BTN_DoctorPatientSearch` | 搜索患者 |
|
||
|
|
| 点击患者项 | `BTN_DoctorPatientItem` | 患者列表项 |
|
||
|
|
|
||
|
|
**互动列表 — `src/doctor/pages/d_interactive/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| 搜索 | `BTN_DoctorInteractiveSearch` | 搜索互动 |
|
||
|
|
| 点击互动项 | `BTN_DoctorInteractiveItem` | 互动列表项 |
|
||
|
|
|
||
|
|
**互动页 — `src/doctor/pages/d_interactiveDoctor/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| 发送消息 | `BTN_DoctorInteractiveSend` | 发送消息 |
|
||
|
|
|
||
|
|
**群发列表 — `src/doctor/pages/d_taskList/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| 新增群发 | `BTN_DoctorTaskListAdd` | 新增群发入口 |
|
||
|
|
| 点击群发项 | `BTN_DoctorTaskListItem` | 群发列表项 |
|
||
|
|
|
||
|
|
**群发新增 — `src/doctor/pages/d_createTask/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| 提交群发 | `BTN_DoctorCreateTaskSubmit` | 创建群发 |
|
||
|
|
|
||
|
|
**切换医生 — `src/doctor/pages/d_changeDoctor/index.ts`**
|
||
|
|
|
||
|
|
| 方法 | PageName | 说明 |
|
||
|
|
|------|----------|------|
|
||
|
|
| 选择医生 | `BTN_DoctorChangeDoctorSelect` | 切换医生选择 |
|
||
|
|
|
||
|
|
> **注意**:以上点击埋点 PageName 是基于代码探索的预定义清单。实施时需逐页确认实际的方法名和交互行为,如有差异需现场调整。
|
||
|
|
|
||
|
|
### 第 5 步:更新 doc/track.md 文档
|
||
|
|
|
||
|
|
将完整的 PageName 对照表(页面级 + 点击级)更新到 `doc/track.md`,作为埋点实施的参考文档。
|
||
|
|
|
||
|
|
## 假设与决策
|
||
|
|
|
||
|
|
1. **命名规范**:采用信达项目的 `PG_/BTN_` 前缀体系,患者端用 `Patient` 前缀,医生端用 `Doctor` 前缀。这样命名清晰且便于后端区分数据来源。
|
||
|
|
2. **detailId 参数**:扩展 `mpBehavior` 类型签名以支持可选 `detailId`,用于详情页场景。实际在 JS 层该字段会随 data 对象一起 POST,无需函数内额外处理。
|
||
|
|
3. **页面级埋点位置**:有 `waitLogin` 的页面在 `.then()` 内首行调用;无 `waitLogin` 的在 `onShow` 首行调用。确保用户登录后才上报,避免无效数据。
|
||
|
|
4. **点击级埋点位置**:在事件处理函数首行调用 `mpBehavior`,先上报再执行业务逻辑(与信达项目一致)。
|
||
|
|
5. **医生端 `doctor: true`**:所有医生端埋点均传入 `doctor: true`,确保 API 路径正确切换。
|
||
|
|
6. **MINI_PROGRAM_VISIT 保留**:`app.ts` 中现有的 `MINI_PROGRAM_VISIT` 埋点保留不变,它记录小程序整体打开事件,与页面级 PV 埋点互不冲突。
|
||
|
|
7. **无集中常量文件**:PageName 采用硬编码字符串(与信达项目一致),不创建额外的常量/枚举文件,避免增加维护成本。
|
||
|
|
|
||
|
|
## 验证步骤
|
||
|
|
|
||
|
|
1. 编译检查:确保 `pnpm run lint:fix` 无新增错误
|
||
|
|
2. 逐页验证:在微信开发者工具中打开每个页面,检查 console 中 mpBehavior POST 请求是否正常发出
|
||
|
|
3. 参数验证:确认患者端请求路径为 `?r=igg4/mp-behavior/add`,医生端为 `?r=igg4/doctor/mp-behavior/add`
|
||
|
|
4. doctor 参数验证:确认 `doctor` 字段在发送前被正确删除(不出现在 POST body 中)
|
||
|
|
5. detailId 验证:确认详情页的 `detailId` 正确传入 POST body
|