Files
Mdeical_Sur_Report/AGENTS.md

16 KiB
Raw Blame History

AGENTS.md — 手术图文病历报告系统AI手术图文报告系统 V2.0

本文档面向 AI 编程助手。如果你正在阅读本文件,说明你对本项目一无所知。以下内容全部基于项目实际代码与配置,请勿假设任何未在本文中显式说明的内容。


1. 项目概述

本项目是一个纯前端的医疗图文报告管理应用,面向医院手术记录场景。核心能力包括:

  • 通过富文本编辑器撰写手术图文报告
  • 上传手术视频并自动/手动截取关键帧插入报告
  • 模板管理(创建、维护标准模板,新建报告时自动加载默认模板)
  • 基于角色的权限控制(超级管理员 / 管理员 / 普通用户)
  • AI 辅助撰写(支持 Kimi、DeepSeek、OpenAI 及自定义兼容接口)
  • 报告批量操作(删除、导出 PDF / JSON
  • 讯飞语音输入WebSocket 实时转写)

重要前提:本项目没有任何后端服务。所有数据(用户、报告、模板、视频帧、系统配置)全部持久化在浏览器 localStorage 中。认证与授权逻辑完全在客户端执行。

默认测试账号:

  • admin / 123456
  • manager / 123456
  • doctor / 123456

2. 技术栈

层级 技术
框架 React 19 + TypeScript ~5.8.2
构建工具 Vite 6.2.0@vitejs/plugin-react
路由 React Router DOM v7BrowserRouter
样式 Tailwind CSS v4.1.14(通过 @tailwindcss/vite 插件引入,非 PostCSS
图标 lucide-react
动画 motionFramer Motion 继任者)
AI SDK @google/genai(依赖列表中,实际主要使用 OpenAI 兼容 API
其他关键依赖 diff(字符级差异比对)、crypto-js(讯飞 HMAC-SHA256 鉴权)

package.json 中虽然声明了 express@types/express,但源码中未见服务端代码,推测为历史遗留或未使用的依赖。


3. 项目结构

src/
├── App.tsx                 # 根组件,定义所有路由
├── main.tsx                # 应用入口React 19 + StrictMode
├── types.ts                # 全局类型定义与默认值常量
├── index.css               # Tailwind v4 引入 + 自定义编辑器/打印/A4 样式
├── components/
│   └── Sidebar.tsx         # 全局侧边导航栏(带角色过滤、自动收起)
├── pages/                  # 所有页面均为大而整的单文件组件
│   ├── Login.tsx           # 登录 + 初始数据种子写入
│   ├── Dashboard.tsx       # 统计看板、SVG 趋势图、快捷入口
│   ├── ReportEditor.tsx    # 核心编辑器(~2900 行富文本、视频、AI、Diff、表单
│   ├── ReportManage.tsx    # 报告列表、检索、批量操作、历史版本恢复
│   ├── ReportView.tsx      # 只读报告展示 + 打印触发
│   ├── TemplateManage.tsx  # 模板编辑器(~1700 行)+ 字段库侧边栏
│   ├── UserManage.tsx      # RBAC 用户 CRUD + 电子签名
│   └── SystemSettings.tsx  # 抽帧配置、AI 服务商、讯飞语音参数
└── utils/
    ├── storage.ts          # localStorage/sessionStorage 封装(含 XOR 加密)
    ├── print.ts            # iframe 静默渲染 + window.print() 实现 A4 打印
    └── defaultContent.ts   # 默认手术报告 HTML 模板(含 data-bind 占位)

架构特点

  • 无外部状态管理库,全部使用 React 原生 useState / useRef / useEffect
  • 无组件拆分策略,页面级组件体积巨大(ReportEditor.tsxTemplateManage.tsx 均超 1500 行)
  • 无懒加载,所有页面在 App.tsx 中直接静态导入
  • 共享布局仅有 Sidebar.tsx 一处

4. 构建与运行命令

# 安装依赖
npm install

# 本地开发(端口 3000监听 0.0.0.0
npm run dev

# 类型检查(无单元测试)
npm run lint        # 等价于 tsc --noEmit

# 生产构建
npm run build

# 预览生产构建(端口 4173
npm run preview

# 清理构建产物
npm run clean       # rm -rf dist

环境变量(复制 .env.example.env.local

  • GEMINI_API_KEYGemini AI API 密钥(构建时通过 Vite define 注入为 process.env.GEMINI_API_KEY
  • APP_URL:部署后的访问地址,用于自引用链接

Windows 特别注意:重新部署前若使用 npm run preview,需手动终止旧的 vite preview 进程,避免端口冲突。


5. 开发规范与代码风格

以下规范全部来自 过往经验/ 中的踩坑记录,必须遵守

5.1 contentEditable 编辑器规范

  • 插入 HTML 时,模板字符串必须为紧凑单行,禁止多行缩进/换行,否则浏览器会解析出额外文本节点破坏排版。
  • 删除特殊节点优先使用 Range.selectNode(target) + document.execCommand('delete'),而非直接 target.remove(),以保留浏览器原生撤销栈。
  • 所有工具栏/侧边栏按钮必须加 onMouseDown={(e) => e.preventDefault()},防止点击时编辑器失焦导致光标位置丢失。
  • 自定义 Undo/Redo:结构性变更(插入/删除智能字段、表格等)应基于 innerHTML 快照实现自定义历史栈(undoStack / redoStack),并在操作前执行 pushHistory()
  • 键盘事件拦截:对 contenteditable="false" 的内联控件,若处于块级边界,必须拦截 Backspace/Delete以及 Ctrl+Z/Ctrl+Y防止浏览器误删父级 <p>
  • 防换行技巧:在 inline-block / inline-flex 控件后追加 &#8203;(零宽空格)作为行内锚点。

5.2 自动保存与草稿机制(高频踩坑区)

  • 禁止单独依赖 useRef 作为自动保存的唯一数据源。React 18 StrictMode 的模拟卸载会导致 ref 仍保持初始空值,从而用空数据覆盖有效的 localStorage 草稿。
  • ReportEditor.tsx 中新增任何 useState 时,必须三问:
    1. 是否需要持久化到 draft
    2. 是否已加入 stateRef 初始化?
    3. 是否已在 saveDraftToStorage、所有恢复分支、以及 state→ref 同步 effect 中补齐?
  • contentRef.current = editorRef.current.innerHTML 必须紧跟在任何直接操作 DOM 修改编辑器内容的代码之后。

5.3 图片与视频处理

  • LocalStorage 容量预警:视频抽帧必须使用 Canvas 等比压缩(最大宽度 800pxJPEG 质量 0.6),单张控制在 30KB~80KB避免 5MB 上限静默失败。
  • 存储层异常捕获绝不应静默吞掉,至少输出 console.error
  • 占位符体系:所有 .image-placeholder 必须携带 data-mode="frame|manual" 属性。修改占位符的创建/填充/删除逻辑时,必须同步检索所有入口:fillPlaceholderSrcfillPlaceholderautoCaptureFrames、拖拽填充、TemplateManage.tsx,以及 defaultContent.ts 中的预置模板。
  • 填充图片后需将占位符外壳的固定 width/height 改为 auto,同时保留 max-width/max-height 作为硬限制。

5.4 智能字段与动态表单

  • DOM 三层结构<span class="smart-field-wrapper" contenteditable="false"><span class="field-label"><span class="field-value" contenteditable="true" data-bind="xxx">
  • 双向绑定:富文本→表单通过 handleEditorInpute.target.hasAttribute('data-bind') 实时更新;表单→富文本通过 useEffect 监听 reportData,仅在 el.innerText !== newValue 时才重写 DOM防止光标跳动。
  • 时间/日期字段显示格式与存储格式必须分离且同时实现正向格式化与反向解析12h/24h 判断使用 includes('hh') || includes('A') 等包含性判断,兼容自定义格式。

5.5 AI 功能开发规范

  • 模型兼容性:调用 OpenAI 兼容 API 时,必须根据「是否有图片附件」动态决定 content 类型(string vs array),纯文本模型发送数组会 400。
  • System Prompt 设计
    • 条件应只依赖用户意图开关(如 aiModifyEnabled),不应依赖具体 UI 状态。
    • 向大模型发送局部修改请求时,必须提供全局上下文,但同时设置严格的内容边界Fencing,明确声明"全局参考仅供理解,严禁输出"其他模块内容。
    • 对关键输出字段(如 updatedHtml)使用「绝对强制」「绝对不允许」等最强措辞,并在前端增加缺失校验兜底。
  • 降级机制:目标区域注入必须配备降级方案(如光标处 execCommand('insertHTML'));修改模式开启后应自动兜底锁定第一个可用 AI 区域。
  • DOM 结构修复:在读取 .ai-content 数据前,必须将因用户回车而溢出为兄弟节点的 <p> 重新移回容器内。
  • 样式与撤销AI 内容注入必须使用 Range.selectNodeContents + execCommand('insertHTML') 以保留撤销栈;返回的 HTML 需在后处理阶段统一注入内联字体样式(font-family: SimSun; font-size: 12pt;);注入前需清洗(去掉 <br>、段落间空白)。
  • Diff 对比:使用 diff 库做字符级差异比对,并在注入前去掉 diff 高亮标签。

5.6 数据迁移与类型安全

  • 任何涉及 localStorage 数据结构变更的重构,必须在初始化入口提供自动迁移逻辑,使用 (obj as any).oldField 安全访问旧字段,避免类型污染和配置丢失。
  • 从持久化存储读取的数组类型数据,渲染前务必做 Array.isArray 校验,防止历史脏数据导致整页崩溃。
  • 当将格式简写迁移为标准 token 时,必须全局搜索所有硬编码默认值,并在初始化时建立无效值清理机制。

5.7 UI/UX 通用规范

  • 禁用原生 prompt/confirm/alert,统一使用项目风格的自定义 Modal 组件。
  • URL 拼接:必须对基础路径做尾部斜杠移除 .replace(/\/+$/, '')
  • 打印边距:使用 @page { margin: ... } 为每一页物理纸张独立分配边距,切勿依赖 body { padding: ... }
  • 滚动容器内展开:点击展开/折叠的交互组件,应考虑增加 scrollIntoView 兜底,防止布局突变导致点击失效。
  • 表格列变更:保持 <thead><tbody> 列顺序严格一致。
  • 大文件修改策略:对于超过 1500 行的单文件组件采用「Grep 定位 → 精确读取 → 最小化替换」的三段式策略,避免盲目滚动。

6. 测试说明

本项目没有任何测试框架或测试用例

  • npm run linttsc --noEmit)是唯一的自动化质量门禁。
  • 确保 tsconfig.json 已正确 exclude 非源码目录(如 参考信息distnode_modules),否则参考文件会导致类型检查失败。
  • 由于无后端、无测试,所有功能验证依赖手动端到端测试。

7. 部署流程

7.1 Docker 部署(推荐)

docker-compose up -d --build
  • 构建阶段:node:20-alpine 执行 npm ci + npm run build
  • 运行阶段:nginx:alpine 托管静态产物,暴露容器端口 80
  • 宿主机端口映射:400280
  • 服务名:tuwen_system,重启策略:unless-stopped

7.2 无 Docker 静态部署

npm run build
npm run preview

构建产物输出到 dist/ 目录,可直接作为静态站点托管到任意 Web 服务器。

7.3 Nginx 配置要点(nginx.conf

  • SPA 路由try_files $uri $uri/ /index.html,确保客户端路由正常工作。
  • Gzip 压缩对文本、CSS、JS、XML、JSON 启用。
  • 静态资源缓存JS、CSS、图片、字体等设置 immutable 1 年缓存。

8. 安全注意事项

本项目为纯前端应用,不存在服务端安全层。以下风险必须在部署前被充分理解:

  1. 用户密码以明文形式保存在浏览器 localStorage,无后端哈希处理。
  2. API 密钥与凭证通过源码混淆存放字符码数组、XOR 加密),但仍在客户端可还原。
  3. 所有认证与授权逻辑在客户端执行,可通过开发者工具绕过。
  4. 若用于生产环境,必须部署在内网或受信任环境中,严禁直接暴露于公网。
  5. storage.ts 中对 systemSettings 使用 XOR 加密,密钥硬编码于源码,仅提供最低限度的防窥视保护。

9. 关键架构决策

决策 说明
纯前端 / 无后端 所有数据存 localStorage,零服务端依赖,开箱即用
原生 contentEditable 不使用第三方富文本库,通过 document.execCommand 和自定义 DOM 操作实现
单文件大组件 页面逻辑、状态、副作用全部内聚在同一文件中,无细粒度组件拆分
localStorage 即数据库 用户、报告、模板、配置、视频帧全部序列化后存入浏览器本地存储
iframe 打印 通过隐藏 iframe 独立渲染 A4 尺寸 HTML隔离打印样式与交互样式
OpenAI 兼容 API AI 功能不绑定特定厂商,通过统一接口支持多服务商切换

最后更新:基于当前代码库实际内容生成。若项目结构或依赖发生变更,请同步更新本文件。


10. 代码编纂工作流(强制执行)

以下工作流由项目所有者定义,所有涉及项目代码修改的需求必须严格执行,不允许跳过任何步骤。

工作流触发条件

  • 用户提出任何与项目修改相关的需求功能新增、Bug 修复、重构、优化等)
  • 用户明确说"按照工作流执行"或类似指令

工作流 7 步骤

Step 0记录开始时间

在对话开头记录时间戳:{Year}-{Mon}-{Day}-{Hour}-{Min}-{Sec}

Step 1阅读工程分析

  • 阅读 .\工程分析\ 文件夹下所有已有文档(需求分析、实现方案、测试方案、经验记录)。
  • 若文件夹为空,基于当前代码库做一次整体工程分析并写入 .\工程分析\ 留存。

Step 2整理需求

  • 将用户原始需求结构化拆解。
  • 写入 .\工程分析\需求分析-{Year}-{Mon}-{Day}-{Hour}-{Min}-{Sec}.md
  • 模板见 .\工程分析\需求分析-模板.md

Step 3制定实现方案

  • 基于需求分析和代码理解,制定详细实现方案。
  • 写入 .\工程分析\实现方案-{Year}-{Mon}-{Day}-{Hour}-{Min}-{Sec}.md
  • 模板见 .\工程分析\实现方案-模板.md
  • ⚠️ 写完后必须停止,等待用户二次人工审核确认,严禁擅自继续。

Step 4制定测试方案

  • 基于实现方案,制定可执行的测试验证方案。
  • 写入 .\工程分析\测试方案-{Year}-{Mon}-{Day}-{Hour}-{Min}-{Sec}.md
  • 模板见 .\工程分析\测试方案-模板.md
  • ⚠️ 写完后必须停止,等待用户二次人工审核确认,严禁擅自继续。

Step 5执行前检查 + 经验沉淀

  1. 执行前必读 .\工程分析\经验记录.md,避免重复踩坑。
  2. 严格按照已审核的实现方案执行代码修改。
  3. 按已审核的测试方案执行验证。
  4. 若执行过程中遇到任何问题,在 .\工程分析\经验记录.md 中以四段式追加:
    • A. 具体问题
    • B. 产生问题原因
    • C. 解决问题方案
    • D. 后续如何避免问题

Step 6Git 备份

git add .
git commit -m "{Year}-{Mon}-{Day}-{Hour}-{Min}-{Sec} - 本次修改简要描述"
git push origin main
  • 完成后向用户报告:"已完成对文档的备份 commit。"

Step 7重新部署

npm install   # 如需
npm run lint
npm run build
npm run preview   # 如需预览
  • 确保构建成功无错误,向用户报告部署完成。

不可跳过的硬性要求

要求 说明
时间戳贯穿 同一需求的所有文档使用同一时间戳
用户审核卡点 实现方案、测试方案文档写完后必须人工确认
经验沉淀 遇到问题必须写入经验记录.md四段式格式
Git 备份 每次修改完成后必须 commit + push
构建验证 必须执行 npm run build 并确保成功
规范兼容 实现方案必须自检 AGENTS.md 第 5 章规范清单