Files
hms/wiki/miniprogram.md
iven 28bcdc4208
Some checks failed
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
docs: 更新 wiki — Design Token 全面接入记录
- index.md: 更新关键数字(716 提交)、新增 Design Token 指标行
- miniprogram.md: 新增 §1.1 Design Token 系统完整文档(10 级字号表、
  4 结构 token、使用规则、关怀模式说明)、更新变更记录
2026-05-09 23:58:09 +08:00

33 KiB
Raw Blame History

title, updated, status, tags
title updated status tags
微信小程序(患者端) 2026-05-08 active
miniprogram
taro
wechat
patient

微信小程序(患者端)

index 导航。关联: infrastructure erp-server erp-health

1. 设计决策

  • Taro 4.2 + React 18 — 跨平台小程序框架React 生态
  • Zustand 状态管理 — 与 Web 前端一致的 store 模式
  • 微信登录流程Taro.login() → code → 后端 jscode2session → openid → JWT
  • build 时注入环境变量process.env 在小程序运行时不存在,必须通过 defineConstants 编译时替换
  • 不使用浏览器 Web APIbtoa/atob 等在小程序中不可用,用 Taro 原生 API 替代
  • Zod 输入验证 — 健康数据录入使用 Zod schema 验证

版本

Taro 4.2 / React 18 / TypeScript / Zustand 5 / Sass / Zod / ECharts 6按需引入

依赖统一2026-04-27 移除 echarts-taro3-react(内嵌 Taro 3.0.8 + React 16导致 webpack 模块 ID 不一致 → Cannot read property 'call' of undefined)。改为自定义 EcCanvas 组件 + echarts/core 按需引入。taro.js chunk 从 152KB 降至 133KB。

1.1 设计系统:温润东方风

自 2026-04-27 起采用。所有新增/修改页面必须遵循此设计系统,保持视觉一致性。

设计系统源文件:apps/miniprogram/src/styles/variables.scss + mixins.scss + tokens.scss

设计哲学Kenya Hara 式东方极简。温润米底 + 单一赤土橙贯穿全场,留白呼吸感优先。

色彩

角色 变量名 色值 用途
强调色 $pri #C4623A 按钮、链接、活跃 tab、品牌色
强调浅 $pri-l #F0DDD4 图标底色、高亮背景
强调深 $pri-d #8B3E1F 渐变终点、暗色变体
背景 $bg #F5F0EB 页面底色warm cream
卡片 $card #FFFFFF 白色卡片
辅助底 $surface-alt #EDE8E2 次级表面、分隔
主文字 $tx #2D2A26 warm black标题和正文
次文字 $tx2 #7A756E 辅助说明、标签
淡文字 $tx3 #A8A29E 占位、时间戳、箭头
边框 $bd / $bd-l #E8E2DC / #F0EBE5 分隔线、卡片边框
成功 $acc / $acc-l #5B7A5E / #E8F0E8 sage green 正常状态
警告 $wrn / $wrn-l #C4873A / #FFF3E0 warm amber 偏高/待确认
危险 $dan / $dan-l #B54A4A / #FDEAEA muted red 异常/删除

字体

用途 字体栈 说明
标题 / 数据数字 Georgia, Times New Roman, serif 衬线体,传递专业与温度。用 @include serif-number
正文 / 辅助 -apple-system, PingFang SC, sans-serif 系统无衬线,清晰可读
章节标题 @include section-title 30rpx / bold / serif统一样式

圆角 / 阴影 / 间距

元素 圆角 阴影
卡片 $r 12px $shadow-md (0 2px 12px rgba(45,42,38,0.08))
小元素(标签、输入框) $r-sm 8px $shadow-sm (0 1px 4px rgba(45,42,38,0.04))
浮层、弹窗 $r-lg 16px $shadow-lg (0 8px 32px rgba(45,42,38,0.12))
水平间距 页面两侧 24rpx卡片内 24-28rpx
垂直间距 区块间 24rpx卡片内标题与内容 20rpx

组件规范

按钮:主按钮 $pri 实色 + 白字 + 圆角 12px + 阴影。次按钮 $pri 边框透明底。禁用 $surface-alt 底 + $tx3 字。

状态标签:用 @include tag(背景色, 文字色) 生成。不用粗边框、不用 emoji 状态图标。颜色映射:正常 → $acc/$acc-l,偏高 → $wrn/$wrn-l,异常 → $dan/$dan-l,默认 → $tx2/$bd-l

健康数据卡片2×2 网格,衬线大数字居中,小标签 + 状态标签在底部。数据用 @include serif-number 等宽数字。

列表项:白色卡片容器,每行 14-24rpx padding$bd-l 底部分隔。右侧箭头用 字符。无左侧彩色 border accent。

图标:禁止用 emoji 作图标。用线性 SVG 或首字衬线体作为图标占位。图标底色用 $pri-l

禁止事项:紫色渐变 / emoji 作图标 / 圆角卡片+左彩色 border / 无意义渐变背景 / 装饰性 icon 遍地配。

Design Token 系统

自 2026-05-09 起全面接入。68 个 SCSS 文件59 页面 + 9 组件)全部使用 var(--tk-*) 引用字号和结构值。

源文件:apps/miniprogram/src/styles/tokens.scss

架构原理:通过 CSS 自定义属性Custom Properties实现单一真相源。page {} 定义正常值,.elder-mode {} 覆写关怀值,所有页面通过 var(--tk-*) 引用,关怀模式自动级联生效,无需逐页维护覆写。

Taro 兼容性Taro 编译器正确处理 CSS 自定义属性中的 px→rpx 转换(如 --tk-font-h1: 26px--tk-font-h1: 52rpx)。

字号 Token10 级)
Token 正常值 关怀值 倍率 语义 覆盖场景
--tk-font-hero 48px 56px ×1.17 装饰图标、空状态字符 大型装饰元素
--tk-font-h1 26px 30px ×1.15 页面/区块标题 99 处
--tk-font-h2 24px 28px ×1.17 副标题、日期 86 处
--tk-font-body-lg 28px 34px ×1.21 大正文、按钮 110 处
--tk-font-body 22px 30px ×1.36 正文、标签 92 处
--tk-font-body-sm 16px 22px ×1.38 中等正文、列表项 26 处
--tk-font-num 30px 34px ×1.13 数值显示 56 处
--tk-font-num-lg 34px 40px ×1.18 大数值、统计 21 处
--tk-font-cap 13px 18px ×1.38 说明文字、时间戳 54 处
--tk-font-micro 11px 17px ×1.55 角标、标签 22 处
结构 Token
Token 正常值 关怀值 语义
--tk-line-height 1.5 1.7 行高
--tk-touch-min 48px 56px 最小触控区域
--tk-btn-primary-h 56px 64px 主按钮高度
--tk-text-secondary #78716C #5A554F 辅助文字颜色(关怀模式提升对比度)
使用规则

新增页面必须使用 token,禁止硬编码 font-size: Npx

// 正确
.title { font-size: var(--tk-font-h1); }
.desc { font-size: var(--tk-font-cap); color: var(--tk-text-secondary); }
.number { font-size: var(--tk-font-num); @include serif-number; }

// 错误
.title { font-size: 26px; }  // 禁止

特殊值例外(仅允许以下场景硬编码):

  • 72px — 积分余额大数字(装饰性,不走 token
  • 80px — 错误状态图标(组件内部装饰)
  • 21px — 长辈模式预览页(特殊 UI
关怀模式Elder Mode

通过 Zustand store (stores/ui.ts) 的 DisplayMode 控制。useElderClass() hook 在根 View 添加 .elder-mode class触发所有 token 的关怀值级联。

elder-mode.scss~120 行仅保留结构布局覆写grid 列数、padding、gap所有字号/颜色覆写已通过 token 级联自动处理。

2. 关键文件 + 数据流

核心文件

文件 职责
apps/miniprogram/config/index.ts Taro 构建配置defineConstants 注入环境变量)
apps/miniprogram/src/services/request.ts HTTP 请求封装401 自动刷新、错误处理)
apps/miniprogram/src/services/auth.ts 微信登录/绑定手机号 API
apps/miniprogram/src/stores/auth.ts 认证状态login/bindPhone/restore
apps/miniprogram/src/utils/secure-storage.ts token 安全存储XOR + Base64 混淆)
apps/miniprogram/project.config.json 微信开发者工具配置AppID、urlCheck

微信登录流程

用户点击"微信一键登录"
    ↓
Taro.login() → 临时 code
    ↓
POST /auth/wechat/login { code }
    ↓
后端调用微信 jscode2session → 获取 openid + session_key
    ↓
查询 wechat_users 表
    ├── 已绑定 → 返回 { bound: true, token: JWT } → 跳转首页
    └── 未绑定 → 返回 { bound: false, openid } → 显示"授权手机号"按钮
        ↓ 用户授权手机号
    POST /auth/wechat/bind-phone { openid, encrypted_data, iv }
        ↓
    后端解密手机号 → 创建/关联用户 → 返回 JWT → 跳转首页

页面结构59 个页面6 个主包 + 10 个子包)

TabBar 页面3 个)

页面路径 说明
pages/index/index 首页(今日健康、快捷服务)
pages/health/index 健康上报Tab 页)
pages/messages/index 消息中心Tab 页)

患者端主页面

页面路径 说明
pages/login/index 登录页(微信登录 + 协议勾选)
pages/consultation/index 咨询列表
pages/consultation/detail/index 咨询详情
pages/mall/index 积分商城
pages/profile/index 个人中心
pages/appointment/index 预约列表
pages/appointment/create/index 预约挂号
pages/appointment/detail/index 预约详情
pages/legal/user-agreement 用户服务协议
pages/legal/privacy-policy 隐私政策

健康子包pkg-health4 个)

页面路径 说明
pages/pkg-health/trend/index 健康趋势(体征数据折线图)
pages/pkg-health/input/index 健康数据录入Zod 验证)
pages/pkg-health/daily-monitoring/index 日常监测数据
pages/pkg-health/alerts/index 告警列表

医生端子包doctor16 个)

页面路径 说明
pages/doctor/index 医护首页/工作台
pages/doctor/patients/index 患者列表
pages/doctor/patients/detail/index 患者详情
pages/doctor/consultation/index 咨询管理
pages/doctor/consultation/detail/index 咨询详情
pages/doctor/followup/index 随访管理
pages/doctor/followup/detail/index 随访详情
pages/doctor/report/index 报告管理
pages/doctor/report/detail/index 报告详情
pages/doctor/alerts/index 告警管理
pages/doctor/alerts/detail/index 告警详情
pages/doctor/action-inbox/index 待办事项
pages/doctor/dialysis/index 透析管理
pages/doctor/dialysis/detail/index 透析详情
pages/doctor/dialysis/create/index 创建透析记录
pages/doctor/prescription/index 处方管理
pages/doctor/prescription/detail/index 处方详情
pages/doctor/prescription/create/index 开具处方

商城子包pkg-mall3 个)

页面路径 说明
pages/pkg-mall/exchange/index 积分兑换
pages/pkg-mall/orders/index 积分订单
pages/pkg-mall/detail/index 商品详情

个人中心子包pkg-profile12 个)

页面路径 说明
pages/pkg-profile/family/index 家庭成员管理
pages/pkg-profile/family-add/index 添加家庭成员
pages/pkg-profile/reports/index 我的报告
pages/pkg-profile/followups/index 我的随访
pages/pkg-profile/medication/index 用药记录
pages/pkg-profile/settings/index 设置
pages/pkg-profile/dialysis-records/index 透析记录
pages/pkg-profile/dialysis-records/detail/index 透析记录详情
pages/pkg-profile/dialysis-prescriptions/index 透析处方
pages/pkg-profile/dialysis-prescriptions/detail/index 透析处方详情
pages/pkg-profile/consents/index 知情同意
pages/pkg-profile/health-records/index 健康档案
pages/pkg-profile/diagnoses/index 诊断记录

其他子包9 个)

页面路径 说明
pages/ai-report/list/index AI 分析报告列表
pages/ai-report/detail/index AI 分析报告详情
pages/article/index 健康资讯列表
pages/article/detail/index 文章详情
pages/report/detail/index 健康报告详情
pages/followup/detail/index 随访详情
pages/events/index 线下活动
pages/device-sync/index 设备数据同步

服务层10+ 个文件)

文件 覆盖
request.ts HTTP 封装401 刷新、错误处理)
auth.ts 微信登录/绑定手机号
health.ts 体征数据/健康趋势
patient.ts 患者信息/家庭成员
appointment.ts 预约挂号/详情/取消
followup.ts 随访任务/详情
article.ts 健康文章
report.ts 健康报告
analytics.ts 数据分析
wechat-templates.ts 微信模板消息 ID

组件10 个)

组件 用途
EcCanvas ECharts Canvas 包装Taro 4 兼容,按需引入 echarts/core
EmptyState 空状态占位
ErrorBoundary 错误边界捕获
ErrorState 错误状态展示
FamilyPicker 家庭成员选择器
HealthCard 健康数据卡片
Loading 加载状态
StepIndicator 步骤指示器
TrendChart 趋势图表(基于 EcCanvas
WeekCalendar 周日历组件

集成契约

方向 模块 接口 触发时机
调用 → erp-server POST /auth/wechat/login 微信登录
调用 → erp-server POST /auth/wechat/bind-phone 手机号绑定
调用 → erp-health /api/v1/health/* 健康数据查询
调用 → erp-server /api/v1/auth/refresh Token 刷新

3. 代码逻辑

环境变量注入(关键)

小程序运行时没有 process.env,必须在 config/index.ts 中通过 defineConstants 编译时替换:

defineConstants: {
  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
  'process.env.TARO_APP_API_URL': JSON.stringify(process.env.TARO_APP_API_URL || 'http://localhost:3000/api/v1'),
  'process.env.TARO_APP_ENCRYPTION_KEY': JSON.stringify(process.env.TARO_APP_ENCRYPTION_KEY || ''),
},

Token 安全存储

secure-storage.ts 使用 XOR 混淆 + Base64 编码存储 token

  • 不使用 btoa/atob — 小程序环境不支持
  • 使用 Taro.arrayBufferToBase64 / Taro.base64ToArrayBuffer 替代
  • 加密密钥通过 TARO_APP_ENCRYPTION_KEY 环境变量注入

请求封装request.ts

  • 401 自动尝试 refresh token失败后跳转登录页
  • 错误响应格式: { error: string, message: string }(无 success 字段)
  • 成功响应格式: { success: true, data: T }
  • 当前 URL 拼接方式构建查询参数(待重构为 params 对象)

健康数据录入验证

使用 Zod schema 验证用户输入的体征数据(血压、心率、体重、血糖),确保数据类型和范围合法。

4. 构建与调试

构建

cd apps/miniprogram && pnpm build:weapp    # 生产构建
cd apps/miniprogram && npx taro build --type weapp  # 等效

微信开发者工具配置

配置项 说明
AppID wx20f4ef9cc2ec66c5 真实微信 AppID
urlCheck false 不校验合法域名(开发模式)
miniprogramRoot dist/ 编译输出目录

后端微信配置

crates/erp-server/config/default.toml:

[wechat]
appid = "wx20f4ef9cc2ec66c5"
secret = "<通过环境变量 ERP__WECHAT__SECRET 设置>"

5. 活跃问题 + 陷阱

历史教训

问题 根因 修复
页面空白 ReferenceError: process is not defined process.env 在运行时不存在 defineConstants 编译时替换
登录成功但前端报失败 btoa is not defined secure-storage.ts 使用 Web API 改用 Taro.arrayBufferToBase64
微信登录 500 wechat_users.created_by 不存在 迁移创建的表缺少标准字段 ALTER TABLE 补列
401 循环重定向 首页未登录时 request.ts 反复 redirectTo 检查当前路径避免重复跳转
Cannot read property 'call' of undefined echarts-taro3-react 内嵌 Taro 3.0.8 + React 16与 Taro 4.2 + React 18 产生双实例webpack 模块 ID 不匹配 移除 echarts-taro3-react,改为自定义 EcCanvas + echarts/core 按需引入

待优化

问题 级别 说明
Auth token 日志输出 P0 已解决 terser drop_console 移除生产日志
Token 刷新竞态 P0 已解决 refreshPromise 单例 + GET 请求去重
ECharts 全量引入 P2 已解决 分包后 echarts 514KB 仅在趋势页按需加载
积分商城降级 UI P0 未关联患者档案时 Tab 页空白,需引导用户建档
daily-monitoring 无 Zod 验证 P1 对齐 health/input 的验证标准
文章列表返回草稿 P1 患者端应只展示 published 状态文章
URL 拼接构建查询参数 P2 request.ts 已支持 buildQuery(params) 但内部使用
生产配置 P2 urlCheck/minified 需区分环境

2026-04-30 审计发现

三端对齐差距(小程序 API 覆盖 76 个Web 235 个,后端 328 个):

发现 严重性 说明
晚间血压数据永久丢失 CRITICAL 已修复 新增 blood_pressure_evening indicator_type小程序录入页 + 日常监测页 + 后端 service + 集成测试均已覆盖
透析管理完全无入口 HIGH 已修复 医生端新增 dialysis 3 页面 + prescription 3 页面,患者端新增 dialysis-records 2 页面 + dialysis-prescriptions 2 页面
知情同意完全无入口 HIGH 已修复 患者端新增 pkg-profile/consents 页面
体温/血氧未映射 MEDIUM body_temperature/spo2 无 indicator_type
健康记录小程序无入口 MEDIUM 已修复 患者端新增 pkg-profile/health-records 页面
诊断记录小程序无入口 MEDIUM 已修复 患者端新增 pkg-profile/diagnoses 页面
小程序无自动化测试 HIGH 已建立 MCP 自动化审计流程4 角色 236 次探测通过率 96.2%

功能域完成度(小程序端):

功能域 完成度 关键差距
咨询管理 95% 无导出(预期)
预约管理 90% 基本对齐
随访管理 70% 仅列表+创建
患者管理 85% 无删除(预期)
健康数据 80% 丢失晚间血压 已修复
告警系统 80% 查看+处理+医护端管理
透析管理 70% 医护端管理+患者端查看记录/处方
知情同意 60% 患者端查看,无签署流程
健康档案 60% 患者端可查看健康档案和诊断
统计仪表盘 30% 仅医护端 3 个统计
AI 分析 30% 仅历史查看

注意事项

  • Taro.login() 的 code 一次性使用,每次调用会返回新 code
  • session_key 缓存 5 分钟TTL过期需重新登录
  • 微信开发者工具中 getPhoneNumber 需要真机调试或使用测试号
  • Redis 不可达时限流降级为 fail-open不影响登录

6. MCP 联调(微信开发者工具自动化)

通过 MCP (Model Context Protocol) 工具直接操控微信开发者工具中的小程序模拟器,实现页面导航、元素交互、数据读取等操作。

当前使用自建 MCP 服务器 @hms/weapp-mcptools/weapp-mcp/),基于 @weapp-vite/miniprogram-automator@1.1.0(社区活跃维护 fork。 原有的 @yfme/weapp-dev-mcp 在 DevTools 2.01.2510290 版本后不兼容,已弃用。

6.1 前置条件

  1. 后端运行cargo run 启动 http://localhost:3000
  2. 小程序以 dev 模式构建 — 必须使用 NODE_ENV=development 构建(详见 §6.4
    cd apps/miniprogram
    echo 'TARO_APP_API_URL=http://localhost:3000/api/v1
    

TARO_APP_ENCRYPTION_KEY=' > .env NODE_ENV=development npx taro build --type weapp

3. **微信开发者工具已登录** — 确保已扫码登录CLI 命令需要登录态)
4. **微信开发者工具打开项目** — 手动打开,加载 `apps/miniprogram/dist/`
5. **自动化端口已开启** — `project.config.json` 中 `"automationAudits": true`

> ⚠️ **为什么必须 dev 模式?** 生产构建(`pnpm build:weapp`)设置 `NODE_ENV=production``secure-storage.ts` 的 `decrypt()` 在密钥为空时会抛异常。dev 模式允许空密钥走明文存储。

### 6.2 启动调试环境

> **铁律:只允许一个 DevTools 实例运行。** 多实例会导致 App 级别自动化命令全部超时(无法恢复,必须全部关闭重开)。

#### 方式 ALauncher.launch() 自动启动(推荐)

通过 `@weapp-vite/miniprogram-automator` 的 `Launcher` 自动启动 DevTools 并开启自动化端口,无需手动操作。

```bash
# 步骤 1确认没有残留的 DevTools 进程
tasklist | findstr wechatdevtools
# 如有残留taskkill /F /IM wechatdevtools.exe

# 步骤 2MCP 的 inject_auth 或 connect 工具会自动调用 Launcher.launch()
# 或者手动测试:
cd tools/weapp-mcp
node --input-type=module -e "
import { Launcher } from '@weapp-vite/miniprogram-automator';
const mp = await new Launcher().launch({
 cliPath: 'D:/微信web开发者工具/cli.bat',
 projectPath: 'G:/hms/apps/miniprogram/dist',
});
console.log('OK:', (await mp.systemInfo()).model);
// 不要 disconnect保持连接供 MCP 使用
"
# 自动在端口 9420 开启自动化

方式 B手动启动 + CLI 开端口

# 步骤 1确认没有残留的 DevTools 进程
taskkill /F /IM wechatdevtools.exe

# 步骤 2手动打开微信开发者工具加载 apps/miniprogram/dist/
# 等待模拟器完全加载,确认无报错

# 步骤 3通过 CLI 开启自动化端口(端口 9420
"D:/微信web开发者工具/cli.bat" auto --project G:/hms/apps/miniprogram/dist --auto-port 9420
# 看到 "✔ auto" 即成功

# 步骤 4验证端口已开启
netstat -ano | findstr 9420
# 应看到 LISTENING 状态

成功后可通过 mcp__weapp-local__connect 连接。

6.3 常用 MCP 操作weapp-local 工具集)

操作 MCP 工具 说明
连接 connect 连接自动化端口,返回系统信息
断开 disconnect 断开连接
查看当前页面 current_page 返回路径、尺寸,可选包含 data
导航到页面 navigate navigateTo / switchTab / reLaunch / redirectTo / navigateBack
查找元素 get_element CSS 选择器,支持 [index=N] 语法
查找多个元素 get_elements CSS 选择器数组
点击元素 tap CSS 选择器定位后点击
输入文本 input CSS 选择器 + 值
滚动 scroll scroll-view 的 CSS 选择器 + x/y 坐标
读取页面数据 page_data 获取当前页面 data 对象(可选路径)
设置页面数据 page_data JSON data 参数 → setData
读取组件数据 element_data 组件 CSS 选择器 + 可选路径
设置组件数据 element_data CSS 选择器 + JSON data → setData
调用页面方法 page_call_method 调用当前页面上暴露的方法
执行 JS evaluate 在 AppService 上下文执行 JavaScript
调用 wx API call_wx getStorageSyncsetStorageSync
Mock wx API mock_wx Mock 一个 wx API 返回指定结果
恢复 wx API restore_wx 恢复被 mock 的 wx API
获取 WXML get_wxml 获取元素的 WXML 结构
截图 screenshot ⚠️ 当前版本超时,见 §6.6
日志 get_logs 获取 console 日志和异常
等待元素 wait_for 轮询等待选择器匹配
注入认证 inject_auth 一键获取后端 token + 注入 storage + 跳转首页
审计页面 audit_page 导航 → 检查加载 → 收集错误 → 健康报告
批量审计 audit_all 批量审计所有小程序页面

6.4 绕过微信登录

MCP 无法模拟微信 OAuthTaro.login() 返回的 code 走真实微信 jscode2session 接口DevTools 模拟器会返回 mock code 导致后端 500

方案一inject_auth 一键注入(推荐)

原理: 以 dev 模式重编译(空加密密钥),通过 MCP 的 inject_auth 工具自动完成:获取 admin token → evaluate 注入 storage → reLaunch 首页。

1. 准备:确保已按 §6.1 以 dev 模式构建,且已连接 MCPconnect

2. 调用 inject_auth 工具(默认参数即可):
   - 自动 POST /auth/login 获取 admin token
   - 通过 evaluate() 注入 access_token / refresh_token / user_data / tenant_id / patient_id
   - reLaunch 到 /pages/index/index
   - 等待 2 秒后返回当前页面路径

3. 成功后即可正常操作各页面

关键 ID默认值

  • tenant_id: 019d80da-7a2c-7820-b0a3-3d5266a3a324
  • patient_id: 019dcd34-bc4d-72c1-8c19-77ce1f4839d6

方案二:手动分步注入

# 1. 获取 admin token
curl -X POST http://localhost:3000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"Admin@2026"}'

# 2. 通过 MCP call_wx 逐个写入 storage
# 3. 通过 MCP navigate reLaunch 到首页

⚠️ 长字符串 token 通过 call_wx 传输可能截断。建议用 inject_auth 工具(内部用 evaluate 直接执行,无传输问题)。

6.5 TabBar 页面列表

以下页面是 TabBar 页面,必须用 switchTab 导航(不能用 navigateTo

  • pages/index/index — 首页
  • pages/health/index — 健康数据
  • pages/messages/index — 消息中心

注意:咨询、商城、个人中心虽然显示为 Tab 样式,但实际不是 TabBar 页面(使用 reLaunch 导航)。

6.6 已知限制

问题 原因 替代方案
screenshot 超时 App.captureScreenshot 在 DevTools 2.01.2510290 不响应 get_element + page_data 获取 UI 状态
多实例导致全挂 两个 DevTools 实例抢端口App 域命令全部超时且不可恢复 taskkill /F /IM wechatdevtools.exe 后重开
navigateTo 超出 10 页栈 小程序 webview 限制最多 10 层页面栈 批量测试用 reLaunch 逐页导航
CLI 需要登录 cli.bat auto 要求 DevTools 已扫码登录 在 DevTools 中先扫码登录
SummerCompiler 报错 project.config.json 缺少必要字段 已配置 packNpmManually/packNpmRelationList/ignoreUploadUnusedFiles/condition
require() 在 evaluate 不可用 webpack 用数字 ID 注册模块 直接用 wx.setStorageSync / wx.getStorageSync
auth 重定向 request interceptor 检测 401 后跳转 login 并清空 storage 确保 token 有效reLaunch 后等待 2-3 秒
生产构建 decrypt 抛异常 空密钥 + NODE_ENV=productiondecrypt() 直接 throw 使用 NODE_ENV=development 构建

6.7 MCP 服务器架构

tools/weapp-mcp/
├── src/
│   ├── index.ts        # MCP 服务器入口25 个工具注册
│   └── automator.ts    # 连接管理器(@weapp-vite/miniprogram-automator
├── package.json        # @hms/weapp-mcp, 依赖 @weapp-vite/miniprogram-automator@1.1.0
└── tsconfig.json

.mcp.json 配置:

{
  "weapp-local": {
    "command": "node",
    "args": ["tools/weapp-mcp/dist/index.js"],
    "env": {
      "WEAPP_WS_ENDPOINT": "ws://localhost:9420",
      "WEAPP_CLI_PATH": "D:/微信web开发者工具/cli.bat",
      "WEAPP_PROJECT_PATH": "G:/hms/apps/miniprogram/dist",
      "HMS_API_URL": "http://localhost:3000/api/v1"
    }
  }
}

修改后需 cd tools/weapp-mcp && npm run build 重新编译。

6.8 自动化审计脚本

脚本 用途 运行
tools/weapp-mcp/scripts/audit-pages.mjs 多角色分批审计(推荐) node scripts/audit-pages.mjs --role admin
apps/miniprogram/inject-auth.cjs 注入明文 tokendev 模式) node inject-auth.cjs
apps/miniprogram/e2e-final.cjs 完整 E2E 链路验证11 UI + 10 API node e2e-final.cjs

分批审计脚本用法

# 在 tools/weapp-mcp/ 目录下运行
cd tools/weapp-mcp

# 审计指定角色admin/doctor/nurse/operator
node scripts/audit-pages.mjs --role admin

# 自定义批次大小(默认 10 页/批,每批重启 DevTools 防止多实例超时)
node scripts/audit-pages.mjs --role doctor --batch-size 8

# 输出:
# - 控制台实时显示每页状态OK / LOGIN_REDIRECT / ERROR
# - JSON 报告保存到 docs/qa/role-test-results/MP-{role}-audit.json

设计要点:

  • 每批 N 页后自动 taskkill 所有 DevTools 进程并重新 Launcher.launch(),避免多实例导致 App 级命令超时
  • 通过 mp.evaluate() 注入 storagewx.setStorageSync),写入 access_token/refresh_token/user_data/user_roles/tenant_id/current_patient_id
  • 测试用户密码均为 Admin@2026(不是 Test@2026

⚠️ 旧脚本 audit-pages.cjs / audit-detail-pages.cjs 基于 miniprogram-automator(已弃用),请使用新的 audit-pages.mjs

6.9 审计结果

2026-05-08 多角色自动化审计59 页面 × 4 角色)

使用分批审计脚本对全部 59 个页面进行 4 角色全面审计236 次页面探测):

角色 OK LOGIN_REDIRECT ERROR 通过率
admin患者 57 0 2 96.6%
doctor医生 58 1 0 98.3%
nurse护士 57 0 2 96.6%
operator运营 55 0 4 93.2%
合计 227 1 8 96.2%

关键结论:

  • 8 个 ERROR 全部是 DevTools 模拟器随机 timeout非产品缺陷
  • 1 个 LOGIN_REDIRECT 是 doctor 首页首次加载时序问题
  • 所有 59 个页面在所有角色下均可正常渲染(排除测试工具因素)
  • 测试用户密码均为 Admin@2026(之前误用 Test@2026 导致大量 LOGIN_REDIRECT

报告文件:docs/qa/role-test-results/MP-{role}-audit.json

2026-04-27 初次审计40 页面,单角色)

通过 MCP 自动化工具对全部 40 个页面进行渲染审计:

类别 数量 结果
TabBar 页面 5 5/5 OK
患者端子页面 24 24/24 OK
详情页(假 ID 11 11/11 优雅降级
合计 40 40/40 全部通过

详细审计报告见 docs/discussions/2026-04-27-miniprogram-audit-report.md

7. 变更记录

日期 变更
2026-05-09 Design Token 全面接入68 SCSS 文件59 页面 + 9 组件)全面迁移 font-size: Npxvar(--tk-*);重写 tokens.scss 校准 10 级字号 + 4 结构 token 匹配实际设计值;更新 mixins.scss 4 个 mixin 引用 token清理 12 个页面的本地 mixin 重复定义;elder-mode.scss 从 530 行缩减至 ~120 行(删除所有字号/颜色覆写仅保留结构布局634 token 引用 / 3 个特殊硬编码;新增 §1.1 Design Token 系统文档
2026-05-08 多角色自动化审计4 角色admin/doctor/nurse/operator× 59 页面 = 236 次探测,综合通过率 96.2%;更新 §2 页面结构为 59 页面完整列表(含医生端 dialysis/prescription/action-inbox + 患者端 dialysis-records/prescriptions/consents/health-records/diagnoses更新 §5 审计发现(透析/知情同意/诊断/健康记录标记为已修复);更新 §6.5 TabBar 为 3 个;新增 §6.8 分批审计脚本;更新 §6.9 多角色审计结果
2026-05-08 MCP 联调全面重写:自建 MCP 服务器 @hms/weapp-mcp 替代 @yfme/weapp-dev-mcp;基于 @weapp-vite/miniprogram-automator@1.1.0;新增 §6.2 启动步骤(登录+单实例铁律);更新工具列表为 weapp-local 25 个工具;新增 inject_auth 一键注入;新增 §6.7 MCP 服务器架构说明多实例冲突、CLI 登录、SummerCompiler 等已知限制
2026-05-01 审计发现更新CRITICAL 晚间血压丢失 / HIGH 透析+知情同意完全空白 / 功能域完成度矩阵
2026-04-28 全面性能优化分包加载6 分包,主包 517KB→275KBvendors 192KB→36KBGET 请求去重+60s TTL 缓存points store 集中积分/签到状态todaySummary 60s TTL7 组件 React.memoTrendChart 双重渲染修复restoreAuth 提升 App 级别prod terser drop_consolecrypto-js 按需引入
2026-04-27 移除 echarts-taro3-react:内嵌 Taro 3 + React 16 导致 webpack 模块加载失败,改为自定义 EcCanvas 组件 + echarts/core 按需引入;更新版本说明 + 历史教训 + 组件列表
2026-04-27 MCP 联调全面更新§6.1 增加 dev 构建前置条件§6.4 重写为明文 token 注入法评估两种方案§6.6 补充 7 条已知限制,新增 §6.7 审计脚本说明 + §6.8 实测审计结果40/40 页面通过§5 补充 4 条审计发现
2026-04-27 新增 §6 MCP 联调章节连接、操作列表、绕过登录、已知限制、e2e 脚本
2026-04-26 全面更新40 页面(含 9 个医护端页面、15 目录、5 个 Tab 页、积分商城、线下活动
2026-04-25 全面更新20 页面、10 服务、9 组件、Zod 验证、加密密钥外部化说明
2026-04-24 创建小程序 wiki 页面,记录登录流程、环境配置、历史陷阱