refactor(mp): 架构重构 — usePageData 统一数据加载 + Store 解耦 + 大页面拆分

新增 usePageData hook(useDidShow 节流 + usePullDownRefresh + loadingRef 防重入 + enabled 条件守卫),
44/58 页面迁移接入,消灭 4 种数据加载模式并存。

- 新增 hooks/usePageData.ts — 统一页面数据加载生命周期
- 新增 stores/index.ts — resetAllStores() 解耦 auth↔health store 依赖
- 新增 pages/index/useHomeData.ts — 首页数据 hook(424→282 行)
- 新增 pages/health/useHealthData.ts — 健康页数据 hook(422→254 行)
- 44 个页面迁移到 usePageData(9 患者端 + 15 医生端 + 20 子包)
- auth store logout 不再直接导入 health store

构建通过,测试 74/75(1 个预存失败)。
This commit is contained in:
iven
2026-05-15 01:13:01 +08:00
parent 0f58af245d
commit 1fd2c7a533
52 changed files with 791 additions and 664 deletions

View File

@@ -151,7 +151,11 @@ Taro 4.2 / React 18 / TypeScript / Zustand 5 / Sass / Zod / ECharts 6按需
| `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/src/stores/index.ts` | `resetAllStores()` 统一清理(解耦 store 间依赖 |
| `apps/miniprogram/src/hooks/usePageData.ts` | **统一页面数据加载 hook**(节流 + 下拉刷新 + 防重入) |
| `apps/miniprogram/src/pages/index/useHomeData.ts` | 首页数据 hook从 424 行页面组件中提取) |
| `apps/miniprogram/src/pages/health/useHealthData.ts` | 健康页数据 hook从 422 行页面组件中提取) |
| `apps/miniprogram/src/utils/secure-storage.ts` | token 安全存储(明文存储,保留接口兼容) |
| `apps/miniprogram/project.config.json` | 微信开发者工具配置AppID、urlCheck |
### 微信登录流程
@@ -270,6 +274,18 @@ POST /auth/wechat/login { code }
| `pages/events/index` | 线下活动 |
| `pages/device-sync/index` | 设备数据同步 |
### Hook 层7 个)
| Hook | 用途 |
|------|------|
| `usePageData` | **统一页面数据加载**`useDidShow` 节流 + `usePullDownRefresh` + `loadingRef` 防重入 + `enabled` 条件守卫。44/58 页面已接入 |
| `useThrottledDidShow` | 带节流的 `useDidShow`(已迁移页面不再直接使用,保留兼容) |
| `useSafeTimeout` | 页面隐藏时自动 clearTimeout |
| `usePageRefresh` | 下拉刷新封装 |
| `usePagination` | 通用分页逻辑 |
| `useAuthRequired` | 登录态检查 |
| `useElderClass` | 长者模式 CSS class |
### 服务层10+ 个文件)
| 文件 | 覆盖 |
@@ -477,13 +493,13 @@ secret = "<通过环境变量 ERP__WECHAT__SECRET 设置>"
| `health/index` loadTrend 无并发保护 | `health/index` | **已修复:** 添加 `loadingRef` 防重入 |
| `doctor/prescription` handleSearch loading 竞态 | `doctor/prescription` | handleSearch 和 useEffect 的 loadData 可能闪烁 |
#### 架构建议
#### 架构建议(已完成标注 ✅)
1. **统一数据加载模式**:所有列表页使用 `useThrottledDidShow` + `loadingRef` 双重保护(当前 appointment/messages 遵循,但 ai-report/events 不遵循)
1. ~~**统一数据加载模式**~~ ✅ 已完成:所有列表/详情页使用 `usePageData` hook44/58 页面已接入
2. **长轮询通用化**`consultation/detail``doctor/consultation/detail` 的长轮询逻辑几乎相同,应抽取为 `useLongPolling` hook
3. **服务端过滤优先**:所有列表页的 Tab 过滤传参给后端,不在前端做客户端过滤
4. **BLE 管理器生命周期**BLE 等硬件相关管理器应通过 Context 或 hook 管理,避免模块级单例
5. **getStorageSync 出渲染路径**:组件顶层不应有同步 I/O统一通过 Zustand store 获取
3. ~~**服务端过滤优先**~~ ✅ 已完成:所有列表页的 Tab 过滤传参给后端
4. ~~**BLE 管理器生命周期**~~ ✅ 已完成:改为 `useRef` 懒初始化
5. ~~**getStorageSync 出渲染路径**~~ ✅ 已完成:通过 Zustand store 获取
### 2026-05-15 患者端登录后卡死深度审查3 专家组 × 请求链路 + 并发分析 + 端点可达性)
@@ -890,6 +906,7 @@ node scripts/audit-pages.mjs --role doctor --batch-size 8
| 日期 | 变更 |
|------|------|
| 2026-05-15 | **架构重构:统一页面数据加载 + Store 解耦 + 大页面拆分**:新增 `usePageData` hook节流+下拉刷新+防重入+条件守卫44/58 页面迁移接入;新增 `resetAllStores()` 解耦 store 间依赖auth 不再直接导入 health提取 `useHomeData`/`useHealthData` 将首页 424→282 行、健康页 422→254 行;构建通过 + 测试 74/75 |
| 2026-05-15 | **患者端登录后卡死深度审查3 专家组)**:根因 — 全局并发请求超微信 10 限制排队阻塞;端点可达性验证 33/33 全部存在Tab 切换请求链路分析(最坏 13 并发);修复 HIGH×3doRefresh 状态清理 + 401 跳转登录页 + 全局并发限制 MAX_CONCURRENT=8+ MEDIUM×3长轮询 generation counter + 首页/健康页 loadingRef 防重入 + refreshToday 去重) |
| 2026-05-15 | **全量审计修复(第二轮)**:修复 CRITICAL×1pollingRef 未定义回归,咨询详情页 loadData 引用已删除的 pollingRef → 闭会话时 ReferenceError 崩溃HIGH×3 — 401 重试递归占用双 slot 改为循环结构释放后重入、4 个医生端列表页consultation/alerts/dialysis/prescription添加 loadingRef 防重入、safeNavigateTo 页栈溢出保护栈≥9 自动 redirectTo新增 `safeNavigateTo` 工具函数(`utils/navigate.ts` |
| 2026-05-15 | **setTimeout 无清理修复**:新增 `useSafeTimeout` hook页面隐藏时自动 clearTimeout10 个页面接入 — daily-monitoring2、exchange4、family-add、health/input、prescription detail/create、dialysis detail/create、appointment detail/create所有 fire-and-forget 定时器替换为 safeSetTimeout |