This commit is contained in:
Administrator
2026-04-18 16:31:09 +08:00
commit 4e24ee15a2
30 changed files with 11182 additions and 0 deletions

209
AGENTS.md Normal file
View File

@@ -0,0 +1,209 @@
# 手术图文病历报告系统 —— Agent 开发指南
> 本文件面向 AI 编程助手。修改项目结构、构建流程或关键配置后,请同步更新本文档。
---
## 项目概览
这是一个面向医院场景的**纯前端单页应用SPA**,用于手术记录图文报告的撰写、视频关键帧抽取、模板管理以及基于角色的用户权限控制。
- **名称**:手术图文病历报告生成终端 / 智能图文报告管理系统
- **架构**:纯前端应用,无后端服务。所有数据(用户、报告、模板、设置、图片资源)均持久化在浏览器 `localStorage` / `sessionStorage` 中。
- **技术栈**React 19 + TypeScript 5.8 + Vite 6 + Tailwind CSS 4 + React Router DOM 7 + Lucide React图标
- **语言**:项目界面、注释、文档均为中文。
- **运行环境**:现代浏览器(依赖 `localStorage``URL.createObjectURL``contenteditable``MutationObserver` 等 Web API
---
## 项目结构
```
.
├── docker-compose.yaml # Docker Compose 配置(端口 4002:80
├── Dockerfile # 多阶段构建node:20-alpine 构建 → nginx:alpine 运行
├── nginx.conf # Nginx SPA 路由回退配置try_files
├── package.json # 项目依赖与脚本
├── vite.config.ts # Vite 配置(含 Tailwind CSS 插件、路径别名 @
├── tsconfig.json # TypeScript 配置ES2022、react-jsx、paths: {"@/*": ["./*"] }
├── index.html # Vite 入口 HTML
├── public/ # 静态资源logo_square.png、favicon.ico
└── src/
├── main.tsx # 应用入口React StrictMode + createRoot
├── App.tsx # 根组件定义所有路由BrowserRouter
├── index.css # 全局样式、Tailwind 主题变量、编辑器/打印专用样式
├── types.ts # TypeScript 类型定义与常量User、Report、Template、SystemSettings、FormField 等)
├── components/
│ └── Sidebar.tsx # 侧边导航栏(角色过滤、折叠逻辑、退出登录)
├── pages/
│ ├── Login.tsx # 登录页 + 默认数据初始化(用户、模板、表单字段、系统设置)
│ ├── Dashboard.tsx # 工作台概览统计卡片、7 天趋势 SVG 图表、快捷入口)
│ ├── ReportEditor.tsx # 图文报告编辑器最核心、最复杂页面2000+ 行)
│ ├── ReportManage.tsx # 报告管理(搜索、筛选、查看、编辑、删除、历史、导出)
│ ├── ReportView.tsx # 报告只读查看 + 打印
│ ├── TemplateManage.tsx # 模板管理(富文本编辑器、字段库管理、图片占位符)
│ ├── UserManage.tsx # 用户管理CRUD、签名上传、角色/模板权限分配)
│ └── SystemSettings.tsx # 系统设置视频抽帧参数、API 地址、默认模板)
└── utils/
├── storage.ts # localStorage / sessionStorage 封装JSON 自动序列化)
├── print.ts # 打印工具:通过隐藏 iframe 渲染 A4 内容并调用 window.print()
└── defaultContent.ts # 默认报告模板 HTML含智能字段绑定语法与图片占位符
```
---
## 构建与运行命令
```bash
# 安装依赖
npm install
# 本地开发(端口 3000监听 0.0.0.0
npm run dev
# 生产构建(输出到 dist/
npm run build
# 预览生产构建
npm run preview
# 类型检查(不输出文件)
npm run lint
# 清理构建产物
npm run clean
```
### Docker 部署
```bash
# 构建并运行(访问 http://localhost:4002
docker-compose up -d --build
# 停止
docker-compose down
```
构建流程:
1. **构建阶段**`node:20-alpine` 执行 `npm ci` + `npm run build`
2. **运行阶段**`nginx:alpine` 托管 `dist/` 静态文件,端口 80
3. `nginx.conf` 已配置 `try_files` 回退,支持 SPA 前端路由刷新不 404。
---
## 代码组织与模块划分
### 路由结构(`src/App.tsx`
| 路径 | 页面 | 角色权限 |
|------|------|----------|
| `/` | Login | 公开 |
| `/dashboard` | Dashboard | super / admin / user |
| `/report-editor` | ReportEditor | super / admin / user |
| `/report-manage` | ReportManage | super / admin / user |
| `/report-view/:id` | ReportView | super / admin / useruser 只能看自己的) |
| `/template-manage` | TemplateManage | super / admin |
| `/user-manage` | UserManage | super / admin |
| `/system-settings` | SystemSettings | super / admin / user |
### 核心数据模型(`src/types.ts`
- `User`:用户(`role: 'super' | 'admin' | 'user'`
- `Report`:报告(含患者信息、手术信息、富文本 `content`、视频数组、抽帧数组 `capturedFrames`、历史记录 `history`
- `Template`:模板(名称、描述、富文本 `content`
- `SystemSettings`:系统设置(抽帧数量/位置、API 端点、默认模板、自动插帧配置)
- `FormField` / `FieldType`:表单字段配置(支持文本、单选、多选、时间、日期、签名、图片)
- `CapturedFrame`视频关键帧含视频索引、时间戳、DataURL
### 存储层(`src/utils/storage.ts`
所有业务数据通过 `storage.get<T>(key, fallback)` / `storage.set<T>(key, value)` 读写 `localStorage`(或 `sessionStorage`)。**不存在任何后端 API 调用**。
关键存储键:
- `users` — 用户列表
- `currentUser` — 当前登录用户
- `reports` — 报告列表
- `templates` — 模板列表
- `systemSettings` — 系统设置
- `formFieldsConfig` — 表单字段配置
- `multiSelectOptions` / `anesthesiaOptions` — 下拉选项缓存
- `imageAssets` — 图片资源库DataURL
- `reportEditorDraft_${username}` — 报告编辑器自动草稿
- `restore_${reportId}` — 报告恢复临时内容sessionStorage
---
## 核心功能实现细节
### 1. 图文报告编辑器(`ReportEditor.tsx`
- **富文本实现**:基于原生 `contenteditable` div通过 `document.execCommand` 实现加粗、斜体、下划线、对齐、插入表格等。
- **A4 纸模拟**:编辑器内容区固定宽度 `210mm`,最小高度 `297mm`,通过 `MutationObserver` 动态扩展为多页。
- **图片占位符**`.image-placeholder` 元素,支持点击上传、拖入视频关键帧、或自动插入抽帧结果。占位符分为 `data-mode="frame"`(可拖入关键帧)和 `data-mode="manual"`(仅手动上传,如 Logo、签名
- **智能字段绑定**:模板中可插入 `<span class="smart-field-wrapper" data-bind="key">`,在报告编辑器左侧表单填写后,通过 DOM 查询同步更新编辑器内对应字段值。
- **视频抽帧**:支持上传本地视频(`URL.createObjectURL`),可手动截图或按百分比位置自动均匀抽帧(`autoCaptureFrames`)。抽帧结果支持拖入编辑器占位符。
- **自动草稿**:在 `beforeunload` / `visibilitychange` / 状态变更时自动保存草稿到 `localStorage`
- **打印**:调用 `printDocument()` 将编辑器 HTML 注入隐藏 iframe 并触发打印;`@media print` 样式隐藏所有非打印元素。
### 2. 模板管理(`TemplateManage.tsx`
- 与报告编辑器共享相似的 `contenteditable` 编辑体验。
- 额外支持**字段库管理**:可插入/编辑/删除表单字段,字段变更会同步到 `formFieldsConfig`
- 模板内容即为 HTML 字符串,存储在 `templates` localStorage 键中。
### 3. 用户与权限(`Login.tsx`、`UserManage.tsx`、`Sidebar.tsx`
- **角色体系**
- `super`(超级管理员):拥有所有权限,可管理所有用户。
- `admin`(管理员):可管理同科室的 `user` 角色用户。
- `user`(医生):只能查看/编辑自己创建的报告。
- **权限控制**:路由跳转前检查 `currentUser.role`Sidebar 根据角色过滤导航项;页面内根据角色隐藏按钮或重定向。
- **默认账号**(首次登录或数据缺失时自动初始化):
- `admin` / `123456` — 超级管理员
- `manager` / `123456` — 管理员
- `0001` / `123456` — 医生
---
## 代码风格指南
- **语言**TypeScript严格模式未开启`noEmit: true`),但代码中广泛使用显式类型注解。
- **组件风格**:函数组件 + React Hooks所有页面组件默认导出。
- **CSS**Tailwind CSS 工具类为主,复杂样式(如 `contenteditable` 内部元素、打印样式)写在 `src/index.css``@layer components` 中。
- **路径别名**`@/` 指向项目根目录(`vite.config.ts``tsconfig.json` 均已配置)。
- **图标**:统一使用 `lucide-react`
- **事件处理**:原生 DOM 事件与 React 事件混用(编辑器内大量直接使用 `document.execCommand``addEventListener`)。
- **状态管理**:无 Redux/Zustand所有状态以 React `useState` + `useRef` + `useEffect` 管理,复杂页面(如 ReportEditor使用 `useRef` 保存最新状态快照以绕过闭包问题。
---
## 测试说明
**本项目目前未配置任何测试框架**,没有单元测试、集成测试或 E2E 测试。
如需添加测试,建议:
- 单元测试Vitest与 Vite 生态一致)
- 组件测试React Testing Library
- E2E 测试Playwright测试 `localStorage` 持久化、文件上传、打印流程等)
---
## 安全注意事项
> ⚠️ **关键警告**:本应用为纯前端实现,所有认证与授权逻辑均在客户端执行。
- 用户密码以**明文**形式存储在浏览器 `localStorage` 中,无任何哈希或加密处理。
- 权限控制依赖客户端路由守卫和 UI 隐藏,可被技术手段绕过。
- 所有报告数据、视频对象 URL、图片 DataURL 均保存在用户本地浏览器中,无云端备份。
- **生产环境部署建议**:仅限内网或受信任环境使用,不要直接暴露于公网。
- 环境变量 `.env.local` 中的 `GEMINI_API_KEY` 仅用于预留的 AI 功能,当前主业务逻辑未实际调用 Gemini API。
---
## 常见开发注意事项
1. **编辑器内容初始化**`ReportEditor.tsx` 中编辑器 `innerHTML` 的初始化逻辑分散在 `useEffect`(基于 reportId / draft`useLayoutEffect`(安全兜底)中,修改时需注意两者优先级,避免内容被覆盖。
2. **视频对象 URL 生命周期**:通过 `URL.createObjectURL()` 创建的视频 URL 仅在当前会话有效,刷新页面后视频需重新上传。报告保存时仅保留视频元数据(名称、时长),不保存视频文件本身。
3. **打印样式**`@media print` 规则定义在 `src/index.css` 中,修改编辑器内元素类名时,需同步检查打印样式是否失效。
4. **Tailwind CSS v4**:本项目使用 Tailwind CSS 4`@import "tailwindcss"` + `@theme`),与 v3 的 `tailwind.config.js` 方式不兼容,请勿混用旧版配置。
5. **HMR 特殊处理**`vite.config.ts` 中根据 `DISABLE_HMR` 环境变量控制 HMR 开关,该变量由 AI Studio 运行时注入,通常无需手动修改。