- 智能合并:微信注册时用手机号盲索引匹配已有患者档案,避免重复建 档(AuthState 添加 PiiCrypto + ensure_patient_record 增加盲索引查询) - 角色冻结:小程序仅允许患者角色登录,医护角色被拦截 (auth_service.rs 添加反向拦截 + 登录页移除 credential login 表单) - 页面冻结:10 个非核心页面替换为 FrozenPage 占位组件(用药/知情同意 /透析/家属/诊断/事件),移除 profile 导航入口,移除医生端预加载 - 医生端代码保留,仅隐藏入口,后续可零成本恢复 讨论记录:docs/discussions/2026-05-23-account-registration-login-flow.md
8.2 KiB
8.2 KiB
账号注册与登录流程讨论
日期: 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.rs 的 ensure_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.rs—ensure_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 条件渲染 |
零影响 |
| 内存 | 未加载的分包代码不占用运行内存 | 零影响 |
决策:保留代码,隐藏入口
保留全部医生端代码,仅做以下调整:
- 后端拦截 —
auth_service.rs中拒绝非 patient 角色登录小程序(仅保留client_type=miniprogram + patient组合) - 前端隐藏入口 — 小程序登录页移除账号密码登录入口(仅保留微信一键登录)
- 移除预加载 —
app.config.ts的 preloadRule 中移除pkg-doctor-core - 保留但不触发 — 角色分流逻辑(isMedicalStaff/DoctorTabBar)保留在代码中,但不会被触发
后续恢复路径
需要重新开放医生端时:
- 恢复 credential login 入口
- 后端放开角色限制
- preloadRule 加回预加载
- 零代码修改,纯配置变更
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 页 |
裁剪实施方式
冻结页面的代码保留在仓库中,通过以下方式隐藏:
- 移除导航入口 — profile 页面中移除冻结模块的菜单项
- 保留路由注册 — app.config.ts 中的页面注册保留(避免深度链接崩溃)
- 直接访问容错 — 被冻结页面若被直接访问,显示"功能即将上线"占位
全部决策汇总
| # | 决策 | 影响范围 | 优先级 |
|---|---|---|---|
| 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 页菜单 + 页面容错 | 中 |