根因:主包 2MB 全量组件注入导致 DevTools 渲染引擎内存渐增, 叠加离线时固定 3s 抑制期后的请求洪泛。 修复: - app.config.ts 添加 lazyCodeLoading: requiredComponents 主包 2.0MB→766KB,taro.js 526→131KB,vendors.js 230→28KB - request.ts 离线抑制改为指数退避(3s→6s→12s→30s cap) 后端不可达时自动延长抑制,防止请求风暴 - SegmentTabs Tab 接口改为 readonly,修复 TS 编译错误 - AbortController polyfill 补齐小程序运行时缺失 - 健康首页/设备同步/健康档案/报告/设置页 UI 重构 - 文章页公开端点适配游客访问 - 健康首页 Swiper 间隔优化 4s→5s,动画 500→300ms
5.5 KiB
5.5 KiB
前端代码静态分析报告
分析范围: apps/web/src/ (316 TS/TSX) + apps/miniprogram/src/ (167 TS/TSX) 分析工具: Grep/Read/Bash
1. TypeScript 类型安全 — MEDIUM
Web 前端
生产代码仅 1 处 any:
| 文件 | 行号 | 问题 |
|---|---|---|
hooks/usePaginatedData.ts |
39 | fetchFn: (...args: any[]) => — 建议用泛型 A extends unknown[] |
测试文件中 17 处 as any(mock 场景),影响低。
小程序 — 10 处 as any
| 文件 | 行号 | 问题 | 严重性 |
|---|---|---|---|
app.tsx |
24, 29 | (globalThis as any).__hms |
LOW — 调试辅助 |
pages/login/index.tsx |
9 | (__wxConfig as any).envVersion |
MEDIUM |
services/request.ts |
250 | method: method as any |
MEDIUM |
pages/pkg-health/device-sync/index.tsx |
69 | (bleManager as any).dataBuffer |
HIGH |
pages/appointment/create/index.tsx |
132 | (Taro.requestSubscribeMessage as any) |
MEDIUM |
修复建议: 创建 types/global.d.ts 和 types/taro.d.ts 补全缺失类型。
2. 错误处理 — HIGH
Web 前端静默吞错 (10+ 处)
| 文件 | 行号 | 模式 |
|---|---|---|
pages/Home.tsx |
224, 232, 238 | 个人统计加载失败被吞 |
pages/Roles.tsx |
46 | 权限列表加载失败被吞 |
pages/health/ArticleManageList.tsx |
119 | 文章列表加载失败被吞 |
pages/health/DialysisManageList.tsx |
49 | 透析列表加载失败被吞 |
pages/health/components/DoctorSelect.tsx |
28 | 医生列表加载失败被吞 |
pages/health/components/workbench/OperatorWorkbench.tsx |
35 | 工作台数据加载失败被吞 |
另有 10 处 catch { }(ChatPage 4 处 / useAlertSSE 2 处 / MainLayout 1 处 / usePaginatedData 1 处 / NotificationPanel 1 处 / App.tsx 1 处)。
修复: .catch(() => {}) → .catch((err) => console.warn('[context] 操作失败:', err)),或设置错误状态。
小程序
仅 1 处静默 catch(followups/detail/index.tsx:58),有注释解释,属合理模式。
3. 安全问题 — HIGH (1 处)
dangerouslySetInnerHTML 无消毒
pages/health/articleEditor/ArticlePhonePreview.tsx:243:
<div dangerouslySetInnerHTML={{ __html: content }} />
content来自 wangEditor 富文本输出- 后台管理预览组件,内容由管理员创建(非 UGC)
- 仍建议引入 DOMPurify 做客户端消毒
- 预计工时: 30min
硬编码 URL — LOW
| 文件 | 内容 | 评估 |
|---|---|---|
AiConfigPage.tsx:340,402 |
http://localhost:11434 |
Ollama 默认 URL,仅作 placeholder |
miniprogram/services/request.ts:4 |
localhost:3000 fallback |
开发环境 fallback,生产需运行时校验 |
无硬编码密钥或密码。 ✅
4. 可访问性 — LOW
- 未发现缺少
alt的<img>— Web 前端全用 Ant Design 组件 - 3 处
onClick在非 button 元素上使用(MainLayout 侧边栏 logo/折叠按钮 + ActionThreadDrawer 事件链接) - 修复: 添加
role="button"+tabIndex={0}+onKeyDown
5. 大文件 — MEDIUM
Web 前端 (500+ 行)
| 文件 | 行数 | 建议 |
|---|---|---|
AdminDashboard.tsx |
734 | 拆分统计卡片、图表、表格 |
ArticleManageList.tsx |
654 | 拆分筛选栏、表格、详情抽屉 |
FollowUpTaskList.tsx |
543 | 拆分筛选、列表、详情 |
ConsultationDetail.tsx |
542 | 拆分消息区、信息栏 |
BannerManage.tsx |
526 | 拆分表格和表单 |
AppointmentList.tsx |
520 | 拆分筛选和表格 |
AiKnowledgePage.tsx |
508 | 拆分列表和编辑 |
所有文件在 800 行限制内(CLAUDE.md 规范),但建议拆分提升可维护性。
小程序 (300+ 行)
| 文件 | 行数 |
|---|---|
daily-monitoring/index.tsx |
449 |
health/index.tsx |
376 |
index/index.tsx |
371 |
小程序文件总体控制得更好。
6. 国际化 — MEDIUM (不阻塞)
- Web 前端: 97 个文件 / 375 处硬编码中文文本
- 高频文件: DashboardWidgets (47) / DoctorWorkbench (19) / OperatorWorkbench (18)
- 影响: 当前定位国内单语平台,短期不影响
- 建议: 新代码使用 i18n key,旧代码逐步迁移
7. 内联样式 — LOW
- 1,548 处
style={{}}分布在 129 个文件 - 高频: DoctorWorkbench (68) / AdminDashboard (54) / OperatorWorkbench (49) / DashboardWidgets (47)
- 部分动态计算(width/height)不可避免,静态样式应迁移到 CSS
8. 值得肯定的方面
- TypeScript 类型安全整体优秀 — 生产代码仅 1 处
any - 小程序已完全消除 Web API 依赖 — 无
localStorage/btoa/atob - 无硬编码密钥或密码 — 敏感值全走环境变量
- eslint-disable 使用规范 — 每处有注释解释
- 所有文件在 800 行限制内
- 小程序 console 日志格式统一 —
[模块名] 描述: error
9. 问题汇总
| 严重性 | 问题 | 文件数 | 修复工作量 |
|---|---|---|---|
| HIGH | 静默吞错 .catch(() => {}) |
10+ | 小 — 改为 warn 日志 |
| HIGH | dangerouslySetInnerHTML 无消毒 | 1 | 小 — 引入 DOMPurify |
| MEDIUM | 小程序 as any 类型断言 |
10 | 中 — 补全类型声明 |
| MEDIUM | 硬编码中文 (i18n) | 97 | 大 — 渐进迁移 |
| MEDIUM | 500+ 行大文件 | 7 | 中 — 拆分子组件 |
| LOW | 内联样式过多 | 129 | 大 — 渐进迁移 |
| LOW | localhost fallback URL | 2 | 小 — 运行时校验 |
| LOW | 非交互元素 onClick 缺 a11y | 3 | 小 |