6.9 KiB
6.9 KiB
手术图文病历报告系统 — 工程整体分析
版本:V1.3 最后更新:2026-04-19 分析维度:架构、数据流、核心模块、风险点、扩展方向
一、项目定位
手术图文病历报告系统 是一款面向医院手术室场景的纯前端单页应用(SPA),核心能力包括:
- 富文本编辑器撰写结构化手术图文报告
- 手术视频上传 + 自动/手动关键帧抽取,拖拽插入报告
- 报告模板管理、用户权限(RBAC)、系统设置
- 导出 PDF / JSON 格式报告与模板
关键约束:无后端服务器,所有数据持久化在浏览器 localStorage(约 5MB 容量上限)。
二、技术栈
| 层级 | 技术 |
|---|---|
| 框架 | React 19 + TypeScript 5.8 |
| 构建 | Vite 6 |
| 样式 | Tailwind CSS v4(@theme / @import "tailwindcss" 新语法) |
| 路由 | React Router DOM v7 |
| 图标 | lucide-react |
| 动画 | motion |
| AI SDK | @google/genai(已安装,业务代码中未实际调用) |
无 ESLint、无 Prettier、无单元测试框架,唯一类型检查为 tsc --noEmit。
三、项目结构
src/
├── components/
│ └── Sidebar.tsx # 左侧导航(角色过滤、自动折叠)
├── pages/
│ ├── Login.tsx # 登录页 + 全局 initData(默认用户/模板/字段/素材)
│ ├── Dashboard.tsx # 工作台(统计卡片、SVG 趋势图)
│ ├── ReportEditor.tsx # 核心:报告编辑器(2,200+ 行,最大文件)
│ ├── ReportManage.tsx # 报告列表(搜索、筛选、批量操作、历史回溯)
│ ├── ReportView.tsx # 报告只读查看 + 打印
│ ├── TemplateManage.tsx # 模板编辑器(1,600+ 行,自定义 Undo/Redo)
│ ├── UserManage.tsx # 用户管理(RBAC、签名上传、模板权限)
│ └── SystemSettings.tsx # 系统设置(抽帧配置、AI API、默认模板)
├── utils/
│ ├── storage.ts # localStorage / sessionStorage 封装
│ ├── print.ts # iframe 打印工具(A4 样式、@page 边距)
│ └── defaultContent.ts # 默认模板 HTML(腹腔镜胆囊切除术报告)
├── App.tsx # BrowserRouter + 路由表
├── main.tsx # React 根挂载(StrictMode)
├── types.ts # 核心 TypeScript 类型
└── index.css # Tailwind 入口 + @theme 变量 + 打印媒体查询
四、数据持久化架构
无全局状态库(无 Redux/Zustand/Context)。每个页面独立通过 useState + useEffect 管理状态,localStorage 即数据库。
| localStorage Key | 说明 |
|---|---|
users |
用户列表 |
currentUser |
当前登录用户 |
reports |
报告列表 |
templates |
模板列表 |
systemSettings |
系统设置 |
formFieldsConfig |
动态字段配置 |
imageAssets |
系统素材库(Base64 图片) |
reportEditorDraft_${username} |
每用户报告草稿 |
customTimeFormats |
用户自定义时间格式缓存 |
容量风险:关键帧采用 Canvas 压缩(最大宽度 800px、JPEG 质量 0.6)以控制体积。storage.ts 异常已改为 console.error 输出,不再静默吞掉。
五、核心模块深度分析
5.1 富文本编辑器(ReportEditor / TemplateManage)
- 底层:原生
contentEditable+document.execCommand - 智能字段(Smart Field)三层嵌套:
<span class="smart-field-wrapper" contenteditable="false"> <span class="field-label">标签:</span> <span class="field-value" contenteditable="true" data-bind="key"></span> </span>​- 外层
contenteditable="false"保护标签不被逐字删除 - 输入层
data-bind实现与右侧表单双向绑定 - 末尾追加
​(零宽空格)防止排版换行异常
- 外层
- 图片占位符:
<span class="image-placeholder">,支持data-mode="frame|manual"分类隔离 - 自定义 Undo/Redo(TemplateManage):基于 HTML 字符串快照的
undoStack/redoStack,完全接管撤销逻辑
5.2 视频分析(ReportEditor)
- 上传本地视频 → 生成 object URL
- 自动抽帧:按
systemSettings.framePositions百分比位置逐帧截图 - 手动截图:点击按钮从当前播放时间捕获
- 图片压缩:Canvas 等比缩放至最大 800px 宽,JPEG 质量 0.6
- 非阻塞
setTimeout队列式自动帧插入,避免阻塞抽帧循环
5.3 打印系统(utils/print.ts)
- 创建隐藏 iframe,写入带 A4 打印样式的 HTML
@page { margin: 15mm 10mm; }为每一页纸张独立分配边距body { padding: 0 }— 不可用 body padding 代替 @page margin- 打印前临时设置
document.title并注入 iframe<title>,确保 PDF 默认文件名正确
5.4 角色权限(RBAC)
| 角色 | 权限 |
|---|---|
super |
全部页面、全部数据 |
admin |
仅管理本科室用户;可管理模板;不能看系统设置中的 AI 配置 |
user |
仅创建/查看/编辑自己的报告;可见被分配模板 |
六、高风险修改区域
以下模块牵一发而动全身,修改时必须同步检索所有相关文件:
- 智能字段结构 →
types.ts、defaultContent.ts、ReportEditor.tsx、TemplateManage.tsx、index.css、print.ts - 图片占位符(创建/填充/删除恢复) →
defaultContent.ts、ReportEditor.tsx、TemplateManage.tsx - 打印样式 →
print.ts、index.css(@media print) - 时间/日期格式 →
types.ts、ReportEditor.tsx、TemplateManage.tsx - 数据初始化/默认值 →
Login.tsx、SystemSettings.tsx - 自动保存/草稿 →
ReportEditor.tsx中的saveDraftToStorage、stateRef、contentRef
七、构建与部署
# 开发
npm run dev # vite --port=3000 --host=0.0.0.0
# 生产构建
npm run build # vite build → dist/
npm run preview # vite preview(默认端口 4173)
# 类型检查
npm run lint # tsc --noEmit
当前部署状态:通过 npm run build && npm run preview -- --host 在本机运行。
八、安全与限制
- 密码明文存储:
localStorage中users数组明文保存密码,纯前端架构固有限制 - XSS 风险:报告/模板内容直接以 HTML 字符串存储并在
innerHTML中渲染 - Gemini API Key:通过 Vite
define注入客户端,构建后 key 暴露在静态 JS 中(当前源码未实际调用) - 无 HTTPS 强制:Docker 部署默认 HTTP 80 端口
九、默认账号
| 账号 | 密码 | 角色 |
|---|---|---|
| admin | 123456 | super |
| manager | 123456 | admin |
| doctor / 0001 | 123456 | user |