Files
Mdeical_Sur_Report/AGENTS.md

209 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 手术图文病历报告系统 —— AI 代理开发指南
> 本文档面向 AI 编码代理。若你正在阅读此文件,说明你对该项目一无所知,请仔细阅读后再修改代码。
---
## 1. 项目概述
**手术图文病历报告系统**是一款基于 **React 19 + TypeScript + Vite + Tailwind CSS 4** 开发的纯前端医疗图文报告管理应用。所有数据持久化在浏览器 `localStorage` 中,无需后端服务即可独立运行。
### 核心功能
- **图文报告生成**:基于 `contentEditable` 的富文本编辑器,支持插入表格、图片占位符,可从本地或手术视频中截取关键帧插入报告。
- **报告管理**:搜索、筛选、查看、编辑、打印、删除报告;支持历史版本回溯。
- **模板管理**:创建和维护报告标准模板,新建报告时自动加载默认模板。
- **用户管理**:基于角色的权限控制(超级管理员 / 管理员 / 医生)。
- **系统设置**配置视频自动抽帧百分比、AI API 接口地址、默认模板等全局参数。
### 默认测试账号
| 账号 | 密码 | 角色 |
|---------|--------|------------|
| admin | 123456 | 超级管理员 |
| manager | 123456 | 管理员 |
| 0001 | 123456 | 医生 |
---
## 2. 技术栈与运行时架构
### 技术栈
- **框架**React 19函数组件 + Hooks
- **路由**React Router DOM 7`BrowserRouter`
- **构建工具**Vite 6
- **样式**Tailwind CSS 4使用 `@import "tailwindcss"``@theme` 语法)
- **图标**Lucide React
- **动画**Motion
- **语言**TypeScript 5.8`tsconfig.json``jsx: "react-jsx"``moduleResolution: "bundler"`
- **其他依赖**`@google/genai`(预留 AI 功能)
### 运行时架构
- **纯前端 SPA**:无后端 API所有业务逻辑在浏览器端执行。
- **数据存储**:全部使用 `localStorage`(通过 `src/utils/storage.ts` 封装)和少量 `sessionStorage`(用于版本恢复)。
- **安全模型**:客户端认证授权,密码以**明文**形式保存在 `localStorage` 中。项目设计用于内网或受信任环境,**切勿直接暴露到公网**。
---
## 3. 项目目录结构
```
.
├── 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 配置(含 GEMINI_API_KEY 注入)
├── tsconfig.json # TypeScript 配置paths: "@/*": "./*"
├── index.html # Vite 入口 HTML
├── public/ # 静态资源logo、favicon
└── src/
├── App.tsx # 根组件与路由表
├── main.tsx # 应用入口createRoot + StrictMode
├── index.css # 全局样式、Tailwind 主题、打印样式、编辑器专用样式
├── types.ts # 核心 TypeScript 类型定义
├── components/
│ └── Sidebar.tsx # 左侧导航栏(按角色过滤菜单)
├── pages/
│ ├── Login.tsx # 登录页(初始化默认数据)
│ ├── Dashboard.tsx # 工作台概览(统计图表 + 快捷入口)
│ ├── ReportEditor.tsx # 图文报告编辑器(最复杂的页面,约 1400+ 行)
│ ├── ReportManage.tsx # 报告列表管理
│ ├── ReportView.tsx # 报告查看/打印
│ ├── TemplateManage.tsx # 模板管理
│ ├── UserManage.tsx # 用户管理
│ └── SystemSettings.tsx # 系统设置
└── utils/
├── storage.ts # localStorage/sessionStorage 封装
├── print.ts # 基于 iframe 的 A4 打印实现
└── defaultContent.ts # 默认手术报告模板 HTML 字符串
```
---
## 4. 构建、运行与部署
### 本地开发
```bash
# 安装依赖
npm install
# 启动开发服务器(端口 3000监听 0.0.0.0
npm run dev
```
### 可用脚本package.json
| 脚本 | 作用 |
|-----------|-----------------------------------|
| `dev` | `vite --port=3000 --host=0.0.0.0` |
| `build` | `vite build`(输出到 `dist/` |
| `preview` | `vite preview` |
| `lint` | `tsc --noEmit`(类型检查) |
| `clean` | `rm -rf dist` |
### 环境变量
复制 `.env.example``.env.local`(或 `.env`
- `GEMINI_API_KEY`Google Gemini API 密钥(预留 AI 功能Vite 会在构建时通过 `define` 注入为 `process.env.GEMINI_API_KEY`)。
- `APP_URL`:应用部署后的访问地址。
### Docker 部署
```bash
# 构建并启动(访问 http://localhost:4002
docker-compose up -d --build
# 停止
docker-compose down
```
- **构建阶段**`node:20-alpine` 执行 `npm ci` + `npm run build`
- **运行阶段**`nginx:alpine` 托管 `dist/` 静态资源
- **SPA 支持**`nginx.conf` 已配置 `try_files $uri $uri/ /index.html;`
---
## 5. 代码组织与开发约定
### 路由结构
所有路由定义在 `src/App.tsx`
- `/` → 登录页
- `/dashboard` → 工作台
- `/report-editor` → 新建报告(`?id=xxx` 为编辑)
- `/report-view/:id` → 查看报告
- `/report-manage` → 报告管理
- `/template-manage` → 模板管理
- `/user-manage` → 用户管理
- `/system-settings` → 系统设置
### 权限模型
角色分为三种:`super`(超级管理员)、`admin`(管理员)、`user`(医生)。
- 各页面在 `useEffect` 中读取 `storage.get('currentUser')`,未登录则 `navigate('/')`
- `Sidebar.tsx``navItems``roles` 数组过滤菜单。
- `user` 角色只能查看/编辑自己创建的报告;`super`/`admin` 可查看全院报告。
- `admin` 只能管理同部门(`department`)的 `user` 角色用户,且一个部门只能有一个管理员。
- 用户对象包含 `visibleTemplates`(可视模板)和 `manageableTemplates`(可管理模板)数组,用于细粒度模板权限控制。
### 数据持久化约定
- **禁止直接调用 `localStorage`**,统一使用 `src/utils/storage.ts` 中的 `storage.get / storage.set / storage.remove`
- localStorage 中存储的 key 包括:`users``reports``templates``systemSettings``currentUser``multiSelectOptions``anesthesiaOptions``reportEditorDraft_{username}`
- sessionStorage 中存储的 key 包括:`restore_{reportId}`(用于历史版本恢复)。
- 报告编辑器会在 `beforeunload``visibilitychange` 时自动保存草稿到 `reportEditorDraft_{username}`
### 样式约定
- 全局使用 Tailwind 工具类;自定义设计变量定义在 `src/index.css``@theme` 中(如 `--color-bg``--color-accent`)。
- 通用组件类在 `index.css``@layer components` 中定义:`.btn-accent``.card-minimal``.input-minimal`
- **编辑器样式**`.editor-content``.editor-content-wrapper``.image-placeholder`)和 **打印样式**`@media print`)集中在 `index.css` 中维护。
- A4 打印尺寸为 `210mm × 297mm`,打印时通过 `visibility` 控制只显示 `.print-content` 区域。
### 编辑器实现细节
- `ReportEditor.tsx``TemplateManage.tsx` 使用原生 `contentEditable` + `document.execCommand` 实现富文本,而非第三方编辑器。
- 图片通过 `.image-placeholder` 占位符插入,支持两种填充方式:
1. 点击占位符上传本地图片Base64 存入 HTML
2. 从右侧“视频分析”面板拖拽自动抽帧的截图到占位符中。
- 视频中上传后会根据 `systemSettings.framePositions` 自动抽帧(通过 `<video>` + `<canvas>` 实现)。
- 自动抽帧支持“自动帧插入”功能:开启后,抽得的帧会按延迟顺序自动填入编辑器中的空图片占位符。
### TypeScript 类型
核心类型定义在 `src/types.ts`
- `User`:用户,角色为 `'super' | 'admin' | 'user'`,含 `visibleTemplates``manageableTemplates`
- `Report`:报告,状态为 `'draft' | 'completed'`,含 `content`HTML 字符串)、`videos``capturedFrames``history`
- `Template`:模板,结构与报告内容类似
- `SystemSettings`:系统设置,含 `frameCount``framePositions``apiEndpoint``apiKey``defaultTemplate``frameMode``autoInsertFrames``autoInsertFrameIndices``autoInsertDelay`
- `CapturedFrame`:视频抽帧结果,含 `dataUrl``isManual`
### 路径别名
- `vite.config.ts``tsconfig.json` 均配置了 `@/` 指向项目根目录(`.`)。
- 源码中导入使用相对路径(如 `../utils/storage`)或 `@/` 均可。
---
## 6. 测试策略
**当前项目没有单元测试或 E2E 测试框架。**
- 唯一可用的质量检查命令是 `npm run lint`,它执行 `tsc --noEmit` 进行全量类型检查。
- 在修改代码后,**务必运行 `npm run lint` 确保无 TypeScript 编译错误**。
- 若你引入了新依赖或修改了复杂交互逻辑,建议在本地通过 `npm run dev` 进行手工功能验证(可快速使用登录页的“快捷登录测试账号”)。
---
## 7. 安全与部署注意事项
### 安全警告(必读)
1. **无后端哈希**:用户密码以明文保存在浏览器 `localStorage` 中。
2. **客户端鉴权**:所有权限判断都在前端执行,易被绕过。
3. **因此,该应用仅适合部署在医院内网、受信任的局域网或单人使用的环境中,严禁直接暴露于公网。**
### 部署检查清单
- [ ] `nginx.conf` 中的 `try_files` 确保 SPA 刷新不 404。
- [ ] `dist/` 构建产物已包含在 Docker 镜像中。
- [ ] 若启用 AI 功能,需正确配置 `GEMINI_API_KEY` 环境变量Vite 在构建时注入,修改后需重新构建)。
- [ ] 确保最终运行环境可访问 `https://fonts.googleapis.com/css2?family=Inter`(否则页面字体会降级为系统默认字体)。
---
## 8. 给 AI 代理的快速备忘
- **不要直接操作 `localStorage`**,用 `src/utils/storage.ts`
- **不要引入重型富文本编辑器**,现有方案基于 `contentEditable` + `document.execCommand`,保持轻量。
- **打印逻辑**已封装在 `src/utils/print.ts`,需要打印 A4 报告时直接调用 `printDocument(htmlContent)`
- **修改样式时优先检查 `src/index.css`**Tailwind v4 的主题变量和打印样式都在那里。
- **添加新页面后**,记得在 `src/App.tsx` 注册路由,并在 `src/components/Sidebar.tsx``navItems` 中配置菜单和可见角色。
- **修改 Docker 端口映射时**,同步更新 `docker-compose.yaml` 和本文件中的说明。