Files
hms/docs/discussions/2026-05-23-account-registration-login-flow.md
iven f11dd59382 feat(auth,mp): 患者登录流程优化 — 智能合并 + 角色冻结 + 页面冻结
- 智能合并:微信注册时用手机号盲索引匹配已有患者档案,避免重复建
  档(AuthState 添加 PiiCrypto + ensure_patient_record 增加盲索引查询)
- 角色冻结:小程序仅允许患者角色登录,医护角色被拦截
  (auth_service.rs 添加反向拦截 + 登录页移除 credential login 表单)
- 页面冻结:10 个非核心页面替换为 FrozenPage 占位组件(用药/知情同意
  /透析/家属/诊断/事件),移除 profile 导航入口,移除医生端预加载
- 医生端代码保留,仅隐藏入口,后续可零成本恢复

讨论记录:docs/discussions/2026-05-23-account-registration-login-flow.md
2026-05-23 12:27:14 +08:00

8.2 KiB
Raw Blame History

账号注册与登录流程讨论

日期: 2026-05-23 | 参与者: iven, Claude

背景

系统有 5 个角色admin/doctor/nurse/patient/operator和 2 个终端Web/小程序)。需要明确患者账号的创建路径、权限分配和业务流程边界。

现状梳理

患者账号创建路径

  • 路径 A — 小程序自注册:微信登录 → 手机号授权 → 自动在 users 表建账号 + 分配 patient 角色 + 在 patient 表建档(wechat_service.rs
  • 路径 B — Web 后台建档:管理员/医护在 Web 端手动或 CSV 批量创建,patient.user_id = None
  • 路径 C — 自助绑定:患者小程序注册后通过 bind-by-phone 盲索引匹配关联已有档案

权限模型

  • patient 角色自动分配data_scope=self
  • 纯 patient 角色被 Web 端拦截auth_service 中 is_pure_patient && !is_miniprogram → 拒绝
  • 权限码 18 个 .list + 15 个 .manage,覆盖健康数据、预约、随访、咨询、积分等

患者相关业务流程26 个)

  • 注册绑定4: 微信登录、账号密码登录、自助绑定、后台建档
  • 健康互动6: 数据查看、体征录入、设备同步、AI 分析、AI 对话、用药管理
  • 医疗服务4: 在线预约、在线咨询、随访任务、关怀计划
  • 内容积分5: 文章阅读、轮播图、签到、积分查询、积分兑换
  • 隐私授权3: 知情同意、家属代理、资料编辑
  • 消息通知2: 消息通知、告警接收
  • 透析专属2: 透析记录、透析排班

讨论要点与决策

要点 1患者注册路径的合并策略

问题: 同一人可能先被管理员建档,后来自注册产生两条记录。

决策:需要智能合并策略。 小程序注册时应检测已有档案并主动引导关联,避免重复。

要点 2混合角色支持

问题: 一个用户是否可以同时拥有 patient + nurse 等多角色?

决策:不支持混合角色。 保持角色单一、清晰,一个人只属于一个角色。如果一个医护也是患者,需要独立的 patient 账号。

要点 3小程序多角色支持

问题: 小程序是否需要支持 doctor/nurse/admin/operator 登录?

决策:当前阶段小程序仅支持患者端。 其他角色doctor/nurse/admin/operator/health_manager在小程序端冻结后续按需开放。现有 credential login 的医疗角色入口需要屏蔽或隐藏。

要点 4功能复杂度控制

问题: 患者登录后的功能是否一步到位?

决策:先出一版稳定可用的给甲方测试。 聚焦核心流程(登录、健康数据查看、预约、消息),不追求功能全覆盖,优先保证稳定性和基本体验。

T1智能合并策略已决议

现状缺口

wechat_service.rsensure_patient_record 只按 user_id 检查,不按手机号查重。管理员先建档 → 患者后自注册 → 产生两条 patient 记录。

决策

决策
匹配字段 使用现有 emergency_contact_phone 盲索引做近似匹配
多匹配处理 一个手机号只允许关联一条 patient 记录(严格去重)
冲突处理 以管理员建档数据为准,信息不一致由护士在 Web 端修改

实现思路

微信绑定手机号 → 解密 phone
  → 计算 HMAC(phone) → 查 blind_index(emergency_contact_phone)
  → 找到未绑定的 patient → 关联 user_id不新建
  → 未找到 → 创建新 patient 记录

影响范围

  • crates/erp-auth/src/service/wechat_service.rsensure_patient_record 增加盲索引查询
  • crates/erp-health/src/entity/blind_index.rs — 可能需要从 erp-auth 跨 crate 查询(或用 raw SQL

T2医生端独立分包处理已决议

现状

分包 页面 代码量 类型
pkg-doctor-core 8 页 104 KB independent 分包
pkg-doctor-clinical 10 页 124 KB independent 分包
DoctorTabBar 组件 8 KB 条件渲染
角色分流逻辑 ~18 个文件引用 散布各处

性能影响分析

维度 影响 程度
包体积(提交) 注册在 app.config.ts 中的页面增加总包体积 ~236 KB 微小(微信主包限制 2MB当前远未触及
运行时加载 independent: true 分包只在用户主动跳转时下载,不跳转 = 不加载 零影响
预加载 首页 preloadRule 包含 pkg-doctor-core,会触发提前下载 需移除预加载项
首屏渲染 auth.ts 中 isMedicalStaff() 是纯数组比较DoctorTabBar 条件渲染 零影响
内存 未加载的分包代码不占用运行内存 零影响

决策:保留代码,隐藏入口

保留全部医生端代码,仅做以下调整:

  1. 后端拦截auth_service.rs 中拒绝非 patient 角色登录小程序(仅保留 client_type=miniprogram + patient 组合)
  2. 前端隐藏入口 — 小程序登录页移除账号密码登录入口(仅保留微信一键登录)
  3. 移除预加载app.config.ts 的 preloadRule 中移除 pkg-doctor-core
  4. 保留但不触发 — 角色分流逻辑isMedicalStaff/DoctorTabBar保留在代码中但不会被触发

后续恢复路径

需要重新开放医生端时:

  1. 恢复 credential login 入口
  2. 后端放开角色限制
  3. preloadRule 加回预加载
  4. 零代码修改,纯配置变更

T3甲方测试版功能裁剪已决议

冻结页面清单

模块 页面 页面数 冻结方式
医生端pkg-doctor-core 工作台/患者/咨询/随访/行动收件箱 8 隐藏入口 + 移除预加载
医生端pkg-doctor-clinical 透析/处方/报告/告警 10 隐藏入口
透析相关 pkg-profile/dialysis-records + dialysis-prescriptions (各 list+detail) 4 移除导航入口
家属管理 pkg-profile/family + family-add 2 移除导航入口
用药管理 pkg-profile/medication 1 移除导航入口
知情同意 pkg-profile/consents 1 移除导航入口
诊断记录 pkg-profile/diagnoses 1 移除导航入口
事件日志 pkg-profile/events 1 移除导航入口
小计冻结 28 页

保留页面清单(甲方测试版)

模块 页面 页面数 说明
主包 login / index / health / messages / consultation / create / mall / profile / legal×2 10 TabBar 全部保留
pkg-health trend / input / daily-monitoring / alerts / device-sync 5 健康核心
pkg-mall exchange / orders / detail / product 4 商城
pkg-profile reports / reports-detail / followups / followups-detail / settings / health-records / elder-mode / notifications 8 档案+设置
ai-report list / detail 2 AI 报告
article index / detail 2 文章
appointment index / create / detail 3 预约
pkg-consultation detail 1 咨询详情
小计保留 35 页

裁剪实施方式

冻结页面的代码保留在仓库中,通过以下方式隐藏:

  1. 移除导航入口 — profile 页面中移除冻结模块的菜单项
  2. 保留路由注册 — app.config.ts 中的页面注册保留(避免深度链接崩溃)
  3. 直接访问容错 — 被冻结页面若被直接访问,显示"功能即将上线"占位

全部决策汇总

# 决策 影响范围 优先级
D1 智能合并 — 用 emergency_contact_phone 盲索引匹配 wechat_service.rs
D2 不支持混合角色 auth 模块 已实现
D3 小程序仅患者端,冻结其他角色 auth_service.rs + 登录页
D4 功能精简,先稳定再迭代 小程序全局
D5 医生端保留代码隐藏入口,移除预加载 app.config.ts + auth_service.rs
D6 冻结 28 页透析×4 + 家属×2 + 用药 + 知情同意 + 诊断 + 事件 + 医生端×18 profile 页菜单 + 页面容错