Files
Mdeical_Sur_Report/docs/component-structure.md
admin 44decaa396 Include field library metadata in template exports
- Add fieldLibrary metadata to HTML template packages, including form fields, custom time formats, multi-select options, and anesthesia options.

- Restore imported template field metadata into local compatibility caches and the backend field library API when available.

- Preserve legacy JSON template import compatibility while keeping user-facing exports on HTML packages.

- Prevent template field saves from overwriting stored multi-select and anesthesia options with empty values.

- Update README, AGENTS, feature, requirement, design, module, progress, component, and testing docs for complete template export behavior.

- Extend template export tests to cover field library metadata round-tripping.
2026-05-02 04:27:08 +08:00

12 KiB
Raw Blame History

前端组件结构

本文档描述当前 React 前端的实际组织方式、页面组件边界、API/Auth/Utils 分层,以及后续拆分建议。它不把未来计划当作已实现事实;当前系统仍以页面级组件为主,只有少量公共组件。

总体结构

src/
├── App.tsx                  # AuthProvider、Router 和路由守卫
├── main.tsx                 # React 挂载入口
├── index.css                # Tailwind 主题、全局样式和组件类
├── types.ts                 # 核心前端类型和默认配置
├── api/                     # 前端 API client 和各业务 API 封装
├── auth/                    # 登录态 Context 和后端用户 DTO 映射
├── components/              # 跨页面公共组件
├── config/                  # 运行时开关
├── pages/                   # 页面级组件,当前主要业务 UI 都在这里
├── test/                    # Vitest/jsdom 全局测试设置
└── utils/                   # 存储、权限、默认模板、打印等通用工具

当前组件层级大致为:

main.tsx
└── App
    └── AuthProvider
        └── BrowserRouter
            └── RequireAuth
                ├── Sidebar
                └── pages/*

RequireAuthsrc/App.tsx 中定义,负责前端路由保护和角色入口控制。真正的生产安全边界仍以后端 API 权限校验为准。

路由与页面

路由 页面组件 角色入口 主要职责
/ Login 未登录 默认数据兼容初始化、登录表单、调用 Auth Context。
/dashboard Dashboard 全部登录用户 工作台统计、趋势和快捷入口。
/report-editor ReportEditor 全部登录用户 新建/编辑报告、富文本、字段同步、视频抽帧、AI、语音、保存。
/report-manage ReportManage 全部登录用户 报告列表、搜索筛选、历史恢复、删除、导出。
/report-view/:id ReportView 全部登录用户 报告查看、受控报告读取、浏览器打印。
/template-manage TemplateManage 超级管理员、管理员 模板内容、字段库、图片资源、导入导出。
/user-manage UserManage 超级管理员、管理员 用户、部门、模板授权和签名维护。
/audit-logs AuditLogs 超级管理员、管理员 审计日志列表、筛选和展示。
/system-settings SystemSettings 全部登录用户 全局设置和个人默认模板;超级管理员可维护 AI/语音/抽帧。

页面组件普遍直接组合 UI、状态、API 调用和本地兼容缓存逻辑。新增复杂功能时应优先判断是否需要抽到 api/utils/ 或新的子组件中,避免继续扩大巨型页面。

公共组件

src/components/Sidebar.tsx

当前唯一跨页面公共组件。职责包括:

  • 根据 Auth Context 中的当前用户展示导航入口。
  • 在 Auth Context 不可用时回退读取 localStorage.currentUser
  • /report-editor/template-manage 中自动折叠。
  • 调用 auth.logout() 退出登录,并清理本地登录态。

测试:src/components/Sidebar.test.tsx 覆盖角色菜单过滤。

认证层

src/auth/AuthContext.tsx

AuthProvider 是前端登录态入口:

  • 启动时调用 /api/auth/me 恢复后端 Session。
  • login 调用 /api/auth/login
  • logout 调用 /api/auth/logout 并清理本地 currentUser
  • syncUser 把后端安全用户 DTO 转为前端 User,并同步迁移期本地缓存。

src/auth/backendUser.ts

负责后端用户模型到前端历史类型的兼容映射:

  • 后端 doctor 映射为前端 user
  • 后端 departmentName 映射为前端 department
  • 部门模板授权映射为 visibleTemplatesmanageableTemplates

新增用户字段时,应优先在后端 DTO、backendUser.tssrc/types.ts 和对应测试中一起更新。

API 层

src/api/client.ts 是唯一底层请求封装:

  • 默认请求相对路径 /api/...
  • 请求带 credentials: 'include',用于 HttpOnly Session Cookie。
  • 解包后端 { data } 响应。
  • 统一抛出 ApiError

业务 API 按资源拆分:

文件 职责
ai.ts AI 模型列表和聊天代理。
audit.ts 审计日志查询。
dashboard.ts 工作台统计。
files.ts 签名、模板图片、视频、关键帧等文件资源。
library.ts 字段库和选项库。
reports.ts 报告列表、详情、保存和删除。
settings.ts 系统设置读取、保存、重置。
speech.ts 讯飞语音 WebSocket URL 生成。
templates.ts 模板列表、详情、创建、更新、删除。
users.ts 用户、部门和部门模板授权。

页面组件不应直接拼接第三方 API 或绕过 api/client.ts 调后端。新增后端接口时,优先新增或扩展对应 src/api/*.ts,再由页面调用。

工具层

文件 职责
storage.ts localStorage/sessionStorage JSON 封装,systemSettings 做兼容混淆读取。
permissions.ts 前端角色、报告可见性和模板可见性判断。仅用于体验和开发回退。
defaultContent.ts 默认报告 HTML 模板,包含 data-bind 字段、图片占位符和 AI 区域。
print.ts iframe 打印工具。

工具层应保持无 React UI 依赖。业务规则如果已后端化,应以后端策略为准,前端工具只做展示过滤或离线回退。

页面内部结构

Login

主要职责:

  • 初始化迁移期默认数据:用户、模板、字段、图片资源、系统设置。
  • 提交登录表单到 AuthContext.login
  • 展示默认测试账号。

注意:真实账号认证已由后端处理,本地 users.password 只是旧兼容数据,不是安全边界。

Dashboard

主要职责:

  • 调用 getDashboardStats 读取后端统计。
  • 根据角色展示报告、用户、模板、近期趋势和快捷入口。
  • API 不可用且本地回退开启时,从本地报告、用户、模板构造统计。

ReportEditor

当前最大页面组件,约 3000 行。它同时承担 UI、状态、富文本编辑、媒体处理和 API 调用。

主要内部区域:

  • 顶部工具栏:返回、保存草稿、完成报告、打印等操作。
  • 基本信息表单:由字段库和 reportData 驱动。
  • 报告正文编辑区:contentEditable HTML、智能字段和图片占位符。
  • 视频分析区:视频上传、预览、自动抽帧、手动截帧。
  • 关键帧列表:点击插入、拖拽插入、后端文件上传状态。
  • AI 撰写面板:对话、区域改写和差异确认。
  • 语音输入:浏览器麦克风采集,连接 /api/speech/iat
  • 保存逻辑:优先调用 Reports API并同步 ReportMedia 所需的视频/关键帧引用。

重要状态来源:

  • reportData:报告结构化字段。
  • contentRef:报告正文 DOM。
  • videos / capturedFrames:视频和关键帧。
  • settings系统设置、抽帧策略、AI/语音开关。
  • formFields:字段库。
  • chatMessages / AI 相关状态AI 面板上下文。

后续拆分优先级:

  1. 抽出报告基本信息表单。
  2. 抽出富文本工具栏和正文编辑器适配层。
  3. 抽出视频上传/抽帧/关键帧列表。
  4. 抽出 AI 面板和 Diff 确认弹窗。
  5. 抽出报告保存 hook例如 useReportPersistence

拆分时要保持字段绑定、图片占位符、历史恢复和保存顺序兼容。

ReportManageReportView

ReportManage 负责列表型工作流:

  • 调用 Reports API 获取权限过滤后的报告。
  • 前端搜索、状态筛选和日期筛选。
  • 删除报告、历史恢复、打印/PDF 导出和批量操作。

ReportView 负责只读展示:

  • 调用 Reports API 获取详情。
  • 渲染报告 HTML。
  • 调用 printDocument 进入浏览器打印。

这两个页面与 ReportEditor 通过路由和 sessionStorage.restore_${reportId} 协作。

TemplateManage

当前第二大页面组件,约 1800 行。职责包括:

  • 模板列表、选择、新增、复制、删除。
  • 模板正文 contentEditable 编辑。
  • 富文本命令、表格、字段、图片占位符、AI 区域插入。
  • 字段库维护。
  • 模板图片资源上传和删除。
  • 模板 HTML 模板包导出和 HTML/历史 JSON 模板包导入HTML 包内嵌模板字段和字段管理设置。

后续拆分优先级:

  1. 抽出模板列表和模板元信息编辑。
  2. 抽出模板内容编辑器和工具栏。
  3. 抽出字段库管理面板。
  4. 抽出图片资源管理面板。
  5. 抽出导入导出工具。

UserManage

主要职责:

  • 调用 Users API 管理用户。
  • 调用 Departments API 读取部门和更新模板授权。
  • 管理角色、状态、密码、签名和部门模板权限。
  • 校验默认超级管理员、当前用户、管理员唯一性等 UI 规则。

后端仍会做最终权限校验;前端限制只用于减少误操作。

SystemSettings

主要职责:

  • 调用 Settings API 读取、保存和重置系统设置。
  • 超级管理员维护抽帧、自动插入、AI Provider、讯飞配置。
  • 普通用户主要维护个人默认模板。
  • 本地回退开启时API 不可用才读取或保存本地 systemSettings

AI Key 和讯飞密钥由后端代理使用,普通用户读取设置时不会拿到真实密钥。

AuditLogs

主要职责:

  • 调用 Audit API 获取审计日志。
  • 支持动作、目标类型、关键字和分页筛选。
  • 格式化元数据、动作名称和目标类型。

管理员只能看到后端允许范围内的日志,超级管理员可看全部。

数据流

常见后端化数据流:

Page Component
  └── src/api/<resource>.ts
      └── apiRequest()
          └── /api/<resource>
              └── NestJS module/service
                  └── Prisma/PostgreSQL or file storage

登录态数据流:

Login
  └── AuthContext.login()
      └── POST /api/auth/login
          └── HttpOnly Session Cookie
              └── AuthContext.refresh()
                  └── GET /api/auth/me

开发/迁移期兼容数据流:

Page Component
  ├── Try backend API first
  └── If API failed and VITE_ENABLE_LOCAL_FALLBACK=true
      └── localStorage/sessionStorage compatibility path

生产构建默认不应依赖本地回退作为主要数据来源。

新增组件约定

  • 复用业务 API 封装,不在组件中重复写 fetch('/api/...')
  • 页面级入口继续放在 src/pages;跨页面复用 UI 放在 src/components
  • 只在复杂页面拆分局部子组件时,可以先放在同目录附近;若开始跨页面复用,再移动到 src/components
  • 状态管理优先保持局部化;只有登录态使用 Auth Context。
  • 业务规则优先放后端或 src/utils,不要散落在 JSX 条件里。
  • 新增复杂组件应配套测试至少覆盖权限入口、API 错误分支或关键交互之一。
  • 修改 ReportEditorTemplateManage 这类大组件时,避免顺手重构无关区域;优先小步拆分并保留行为测试。

当前结构风险

  • ReportEditor.tsx 过大媒体、AI、语音、富文本和保存逻辑耦合高。
  • TemplateManage.tsx 同时承担编辑器、字段库、资源库和导入导出。
  • 多个页面仍保留本地兼容回退,阅读时要区分主后端路径和回退路径。
  • 前端权限工具仍存在,但不能当作生产安全边界。
  • HTML 编辑和渲染依赖 contentEditabledangerouslySetInnerHTML,拆分时必须保持清洗、打印和字段绑定一致。