# 手术图文病历报告系统 — 工程整体分析 > 版本: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)三层嵌套**: ```html 标签: ​ ``` - 外层 `contenteditable="false"` 保护标签不被逐字删除 - 输入层 `data-bind` 实现与右侧表单双向绑定 - 末尾追加 `​`(零宽空格)防止排版换行异常 - **图片占位符**:``,支持 `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 ``,确保 PDF 默认文件名正确 ### 5.4 角色权限(RBAC) | 角色 | 权限 | |------|------| | `super` | 全部页面、全部数据 | | `admin` | 仅管理本科室用户;可管理模板;不能看系统设置中的 AI 配置 | | `user` | 仅创建/查看/编辑自己的报告;可见被分配模板 | --- ## 六、高风险修改区域 以下模块**牵一发而动全身**,修改时必须同步检索所有相关文件: 1. **智能字段结构** → `types.ts`、`defaultContent.ts`、`ReportEditor.tsx`、`TemplateManage.tsx`、`index.css`、`print.ts` 2. **图片占位符(创建/填充/删除恢复)** → `defaultContent.ts`、`ReportEditor.tsx`、`TemplateManage.tsx` 3. **打印样式** → `print.ts`、`index.css`(`@media print`) 4. **时间/日期格式** → `types.ts`、`ReportEditor.tsx`、`TemplateManage.tsx` 5. **数据初始化/默认值** → `Login.tsx`、`SystemSettings.tsx` 6. **自动保存/草稿** → `ReportEditor.tsx` 中的 `saveDraftToStorage`、`stateRef`、`contentRef` --- ## 七、构建与部署 ```bash # 开发 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` 在本机运行。 --- ## 八、安全与限制 1. **密码明文存储**:`localStorage` 中 `users` 数组明文保存密码,纯前端架构固有限制 2. **XSS 风险**:报告/模板内容直接以 HTML 字符串存储并在 `innerHTML` 中渲染 3. **Gemini API Key**:通过 Vite `define` 注入客户端,构建后 key 暴露在静态 JS 中(当前源码未实际调用) 4. **无 HTTPS 强制**:Docker 部署默认 HTTP 80 端口 --- ## 九、默认账号 | 账号 | 密码 | 角色 | |------|------|------| | admin | 123456 | super | | manager | 123456 | admin | | doctor / 0001 | 123456 | user |