|
|
@@ -0,0 +1,1142 @@
|
|
|
+# 诊断报告模板编辑功能设计文档
|
|
|
+
|
|
|
+## 📋 功能概述
|
|
|
+
|
|
|
+实现诊断报告模板的完整管理功能,包括诊断报告模板的创建、编辑、删除、应用等操作。用户可以通过诊断报告模板快速填充报告内容,提高工作效率。
|
|
|
+
|
|
|
+## 🎯 详细需求
|
|
|
+
|
|
|
+### 1. 功能需求
|
|
|
+
|
|
|
+#### 1.1 诊断报告模板列表展示(TemplatePanel)
|
|
|
+- **FR-1.1.1** 在侧边栏的"诊断报告模板"卡片中展示诊断报告模板列表
|
|
|
+- **FR-1.1.2** 筛选条功能
|
|
|
+ - `[常用]` 按钮:只显示常用诊断报告模板
|
|
|
+ - `[全部]` 按钮:显示所有诊断报告模板
|
|
|
+ - `[管理]` 按钮:打开诊断报告模板管理对话框
|
|
|
+- **FR-1.1.3** 搜索功能:支持按诊断报告模板名称搜索
|
|
|
+- **FR-1.1.4** 显示常用诊断报告模板标记(星标)
|
|
|
+- **FR-1.1.5** 点击诊断报告模板可以应用到当前报告
|
|
|
+
|
|
|
+#### 1.2 诊断报告模板管理对话框
|
|
|
+- **FR-1.2.1** 显示所有诊断报告模板的列表(表格形式)
|
|
|
+- **FR-1.2.2** 支持创建新的诊断报告模板
|
|
|
+- **FR-1.2.3** 支持编辑现有诊断报告模板
|
|
|
+- **FR-1.2.4** 支持删除诊断报告模板(带确认)
|
|
|
+- **FR-1.2.5** 支持复制现有诊断报告模板(自动添加"- 副本"后缀)
|
|
|
+- **FR-1.2.6** 支持切换常用诊断报告模板状态
|
|
|
+- **FR-1.2.7** 支持按标签过滤诊断报告模板
|
|
|
+
|
|
|
+#### 1.3 诊断报告模板编辑功能
|
|
|
+- **FR-1.3.1** 输入诊断报告模板名称(必填)
|
|
|
+- **FR-1.3.2** 输入影像所见内容(必填)
|
|
|
+- **FR-1.3.3** 输入诊断意见内容(必填)
|
|
|
+- **FR-1.3.4** 输入标签(可选)
|
|
|
+- **FR-1.3.5** 设置是否为常用诊断报告模板(复选框)
|
|
|
+- **FR-1.3.6** 表单验证
|
|
|
+
|
|
|
+#### 1.4 "另存为诊断报告模板"功能
|
|
|
+- **FR-1.4.1** 从"影像所见"区域点击"另存为诊断报告模板"按钮
|
|
|
+- **FR-1.4.2** 自动填充当前的影像所见和诊断意见内容
|
|
|
+- **FR-1.4.3** 打开诊断报告模板编辑区域,用户补充诊断报告模板名称等信息
|
|
|
+
|
|
|
+#### 1.5 应用诊断报告模板功能
|
|
|
+- **FR-1.5.1** 点击诊断报告模板列表中的诊断报告模板
|
|
|
+- **FR-1.5.2** 将诊断报告模板的影像所见和诊断意见内容填充到对应的输入框
|
|
|
+- **FR-1.5.3** 提供确认提示(如果当前已有内容)
|
|
|
+
|
|
|
+### 2. 非功能需求
|
|
|
+
|
|
|
+- **NFR-2.1** 响应时间:所有操作响应时间 < 500ms
|
|
|
+- **NFR-2.2** 用户体验:操作流畅,提示清晰
|
|
|
+- **NFR-2.3** 数据安全:删除操作需要二次确认
|
|
|
+- **NFR-2.4** 错误处理:网络错误、API错误需要友好提示
|
|
|
+
|
|
|
+## 🎨 UI结构设计
|
|
|
+
|
|
|
+### 1. 诊断报告页面-和诊断报告模板相关
|
|
|
+
|
|
|
+```
|
|
|
+DiagnosticReport 页面
|
|
|
+├── ReportHeader(报告头部)
|
|
|
+├── ReportMain(报告主体)
|
|
|
+│ ├── MainContent(左侧,16列)
|
|
|
+│ │ ├── 基本信息卡片
|
|
|
+│ │ ├── 图像卡片
|
|
|
+│ │ ├── 影像所见卡片
|
|
|
+│ │ │ ├── 标题:"影像所见"
|
|
|
+│ │ │ ├── **【"另存为诊断报告模板"按钮】** ← 🎯 入口1
|
|
|
+│ │ │ └── 文本输入框
|
|
|
+│ │ └── 诊断意见卡片
|
|
|
+│ │ ├── 标题:"影像诊断"
|
|
|
+│ │ └── 文本输入框
|
|
|
+│ └── SidePanel(右侧,8列)
|
|
|
+│ ├── 检查过滤卡片
|
|
|
+│ └── **【诊断报告模板卡片】** ← 🎯 主要功能区域
|
|
|
+│ ├── 筛选条:[常用] [全部] [管理] ← 🎯 入口2(管理按钮)
|
|
|
+│ ├── 搜索框
|
|
|
+│ └── 诊断报告模板列表
|
|
|
+│ └── 诊断报告模板项(可点击应用)
|
|
|
+└── ReportFooter(报告底部)
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 诊断报告模板管理对话框(TemplateManagementModal)
|
|
|
+
|
|
|
+```
|
|
|
+┌─────────────────────────────────────────────────────────────────────────┐
|
|
|
+│ 诊断报告模板管理 [X] │
|
|
|
+├─────────────────────────────────────────────────────────────────────────┤
|
|
|
+│ │
|
|
|
+│ 左侧:诊断报告模板列表 │ 右侧:编辑区域 │
|
|
|
+│ ┌─────────────────────────────┐ │ ┌─────────────────────────────┐ │
|
|
|
+│ │ [+ 新建诊断报告模板] │ │ │ 诊断报告模板名称 * │ │
|
|
|
+│ │ [标签过滤: 全部 ▼] │ │ │ ┌─────────────────────────┐ │ │
|
|
|
+│ │ │ │ │ │ │ │ │
|
|
|
+│ │ ┌─────────────────────────┐ │ │ │ └─────────────────────────┘ │ │
|
|
|
+│ │ │ 名称 │ 标签 │ 常用 │ │ │ │ │ │
|
|
|
+│ │ ├─────────────────────────┤ │ │ │ 影像所见 * │ │
|
|
|
+│ │ │ 模板1 │ 胸部 │ ⭐ │ │ │ │ ┌─────────────────────────┐ │ │
|
|
|
+│ │ │ 模板2 │ 腹部 │ │ │ │ │ │ │ │ │
|
|
|
+│ │ │ ... │ ... │ ... │ │ │ │ │ │ │ │
|
|
|
+│ │ └─────────────────────────┘ │ │ │ └─────────────────────────┘ │ │
|
|
|
+│ │ │ │ │ │ │
|
|
|
+│ │ │ │ │ 诊断意见 * │ │
|
|
|
+│ │ │ │ │ ┌─────────────────────────┐ │ │
|
|
|
+│ │ │ │ │ │ │ │ │
|
|
|
+│ │ │ │ │ │ │ │ │
|
|
|
+│ │ │ │ │ └─────────────────────────┘ │ │
|
|
|
+│ │ │ │ │ │ │
|
|
|
+│ │ │ │ │ 标签 │ │
|
|
|
+│ │ │ │ │ ┌─────────────────────────┐ │ │
|
|
|
+│ │ │ │ │ │ │ │ │
|
|
|
+│ │ │ │ │ └─────────────────────────┘ │ │
|
|
|
+│ │ │ │ │ │ │
|
|
|
+│ │ │ │ │ ☐ 设为常用模板 │ │
|
|
|
+│ │ │ │ │ │ │
|
|
|
+│ └─────────────────────────────┘ │ │ [删除] [保存] │ │
|
|
|
+│ │ └─────────────────────────────┘ │
|
|
|
+│ │
|
|
|
+│ [关闭] │
|
|
|
+└─────────────────────────────────────────────────────────────────────────┘
|
|
|
+```
|
|
|
+
|
|
|
+**说明:**
|
|
|
+- **左侧诊断报告模板列表**:
|
|
|
+ - 操作按钮组(根据选中状态动态显示):
|
|
|
+ - `[新建]` 按钮:始终显示,点击后右侧显示空白编辑表单
|
|
|
+ - `[复制]` 按钮:仅在选中模板时显示,点击后复制当前模板(名称自动添加"- 副本"后缀)
|
|
|
+ - `[删除]` 按钮(红色危险按钮):仅在选中模板时显示,点击后删除当前选中的诊断报告模板
|
|
|
+ - 标签搜索框(用于按标签过滤表格中的诊断报告模板,支持手动输入)
|
|
|
+ - 诊断报告模板列表(表格形式):点击某行可在右侧编辑该诊断报告模板
|
|
|
+- **右侧编辑区域**:
|
|
|
+ - 诊断报告模板名称输入框(必填)
|
|
|
+ - 影像所见文本域(必填)
|
|
|
+ - 诊断意见文本域(必填)
|
|
|
+ - 标签输入框(可选)
|
|
|
+ - 常用诊断报告模板复选框
|
|
|
+ - `[删除]` 按钮:仅在编辑现有模板时显示,删除当前选中的诊断报告模板
|
|
|
+ - `[保存]` 按钮:保存编辑内容
|
|
|
+
|
|
|
+### 3. 诊断报告模板面板(TemplatePanel)
|
|
|
+
|
|
|
+```
|
|
|
+┌─────────────────────────────────────┐
|
|
|
+│ 诊断报告模板 [X] │
|
|
|
+├─────────────────────────────────────┤
|
|
|
+│ 筛选条: │
|
|
|
+│ [常用] [全部] [管理] │
|
|
|
+│ │
|
|
|
+│ 搜索: │
|
|
|
+│ ┌─────────────────────────────────┐ │
|
|
|
+│ │ 🔍 搜索诊断报告模板... │ │
|
|
|
+│ └─────────────────────────────────┘ │
|
|
|
+│ │
|
|
|
+│ 诊断报告模板列表: │
|
|
|
+│ ┌─────────────────────────────────┐ │
|
|
|
+│ │ ⭐ 胸部正位诊断报告模板 │ │
|
|
|
+│ │ 标签: 胸部 │ │
|
|
|
+│ ├─────────────────────────────────┤ │
|
|
|
+│ │ 腹部平扫诊断报告模板 │ │
|
|
|
+│ │ 标签: 腹部 │ │
|
|
|
+│ ├─────────────────────────────────┤ │
|
|
|
+│ │ ... │ │
|
|
|
+│ └─────────────────────────────────┘ │
|
|
|
+└─────────────────────────────────────┘
|
|
|
+```
|
|
|
+
|
|
|
+**说明:**
|
|
|
+- **筛选条**:包含三个按钮
|
|
|
+ - `[常用]` - 只显示常用诊断报告模板
|
|
|
+ - `[全部]` - 显示所有诊断报告模板
|
|
|
+ - `[管理]` - 打开诊断报告模板管理对话框
|
|
|
+- **搜索条**:输入框,支持按诊断报告模板名称搜索
|
|
|
+- **诊断报告模板列表**:显示过滤后的诊断报告模板列表,可点击应用
|
|
|
+
|
|
|
+## 👥 参与者列表
|
|
|
+
|
|
|
+### 1. 组件层(Components)
|
|
|
+
|
|
|
+#### 1.1 新建组件
|
|
|
+- **TemplateManagementModal** - 诊断报告模板管理对话框(左右分栏布局)
|
|
|
+ - **左侧:诊断报告模板列表**
|
|
|
+ - "新建诊断报告模板"按钮
|
|
|
+ - 标签搜索框(用于按标签过滤表格,支持手动输入)
|
|
|
+ - 诊断报告模板列表(表格形式)
|
|
|
+ - 点击某行可在右侧编辑
|
|
|
+ - **右侧:编辑区域**
|
|
|
+ - 表单输入(名称、影像所见、诊断意见、标签、常用标记)
|
|
|
+ - 表单验证
|
|
|
+ - 删除/保存按钮
|
|
|
+
|
|
|
+- **TemplateListItem** - 诊断报告模板列表项组件
|
|
|
+ - 显示诊断报告模板名称、标签、常用标记
|
|
|
+ - 点击应用诊断报告模板
|
|
|
+ - 悬停显示预览
|
|
|
+
|
|
|
+#### 1.2 修改组件
|
|
|
+- **TemplatePanel** - 诊断报告模板面板(需要完整实现)
|
|
|
+ - 筛选条:三个按钮([常用] [全部] [管理])
|
|
|
+ - 搜索框(按诊断报告模板名称搜索)
|
|
|
+ - 诊断报告模板列表展示
|
|
|
+ - 应用诊断报告模板功能
|
|
|
+ - 常用诊断报告模板标记显示
|
|
|
+
|
|
|
+- **FindingsSection** - 影像所见区域(需要修改)
|
|
|
+ - "另存为诊断报告模板"按钮功能实现
|
|
|
+
|
|
|
+### 2. 状态管理层(Redux Slices)
|
|
|
+
|
|
|
+#### 2.1 新建/修改 Slices
|
|
|
+- **templateSlice** - 诊断报告模板状态管理(需要完整实现)
|
|
|
+ - State:
|
|
|
+ - `templates: ReportTemplate[]` - 诊断报告模板列表
|
|
|
+ - `loading: boolean` - 加载状态
|
|
|
+ - `error: string | null` - 错误信息
|
|
|
+ - `filterMode: 'all' | 'staple'` - 筛选模式(全部/常用)
|
|
|
+ - `searchKeyword: string` - 搜索关键词
|
|
|
+ - Actions:
|
|
|
+ - `fetchTemplates()` - 获取诊断报告模板列表
|
|
|
+ - `createTemplate(template)` - 创建诊断报告模板
|
|
|
+ - `updateTemplate(id, template)` - 更新诊断报告模板
|
|
|
+ - `deleteTemplate(id)` - 删除诊断报告模板
|
|
|
+ - `setFilterMode(mode)` - 设置筛选模式
|
|
|
+ - `setSearchKeyword(keyword)` - 设置搜索关键词
|
|
|
+ - Thunks:
|
|
|
+ - `fetchTemplatesThunk()` - 异步获取诊断报告模板
|
|
|
+ - `createTemplateThunk(template)` - 异步创建诊断报告模板
|
|
|
+ - `updateTemplateThunk(id, template)` - 异步更新诊断报告模板
|
|
|
+ - `deleteTemplateThunk(id)` - 异步删除诊断报告模板
|
|
|
+
|
|
|
+- **findingsSlice** - 影像所见状态(需要修改)
|
|
|
+ - 实现 `saveTemplate()` action(保存为诊断报告模板)
|
|
|
+
|
|
|
+### 3. API层(已存在)
|
|
|
+
|
|
|
+- **ReportTemplateActions.ts**
|
|
|
+ - `getReportTemplateList(params?)` - 获取诊断报告模板列表
|
|
|
+ - `createReportTemplate(template)` - 创建诊断报告模板
|
|
|
+ - `updateReportTemplate(templateId, template)` - 更新诊断报告模板
|
|
|
+ - `deleteReportTemplate(templateId)` - 删除诊断报告模板
|
|
|
+
|
|
|
+### 4. 类型定义(Types)
|
|
|
+
|
|
|
+- **ReportTemplate** - 诊断报告模板数据结构(已存在)
|
|
|
+ ```typescript
|
|
|
+ interface ReportTemplate {
|
|
|
+ id?: string;
|
|
|
+ name: string;
|
|
|
+ findings: string;
|
|
|
+ impression: string;
|
|
|
+ tag: string;
|
|
|
+ staple: boolean;
|
|
|
+ }
|
|
|
+ ```
|
|
|
+
|
|
|
+## 📝 实现TodoList
|
|
|
+
|
|
|
+### Phase 1: Redux状态管理
|
|
|
+- [ ] 实现诊断报告模板状态管理 `templateSlice.ts`
|
|
|
+ - [ ] 定义 state 结构(诊断报告模板列表、加载状态等)
|
|
|
+ - [ ] 实现同步 actions(设置筛选、搜索等)
|
|
|
+ - [ ] 实现异步 thunks(CRUD操作诊断报告模板)
|
|
|
+ - [ ] 添加到 store
|
|
|
+
|
|
|
+### Phase 2: 核心组件开发
|
|
|
+- [ ] 实现诊断报告模板管理对话框 `TemplateManagementModal` 组件
|
|
|
+ - [ ] 创建组件文件
|
|
|
+ - [ ] 实现左右分栏布局
|
|
|
+ - [ ] 实现左侧诊断报告模板列表(表格)
|
|
|
+ - [ ] 实现右侧编辑表单
|
|
|
+ - [ ] 实现标签过滤
|
|
|
+ - [ ] 实现新建/编辑/删除诊断报告模板操作
|
|
|
+ - [ ] 实现表单验证
|
|
|
+ - [ ] 连接 Redux
|
|
|
+
|
|
|
+- [ ] 实现诊断报告模板列表项 `TemplateListItem` 组件
|
|
|
+ - [ ] 创建组件文件
|
|
|
+ - [ ] 实现列表项布局
|
|
|
+ - [ ] 实现点击应用诊断报告模板功能
|
|
|
+ - [ ] 实现悬停预览
|
|
|
+
|
|
|
+### Phase 3: 集成现有组件
|
|
|
+- [ ] 完善诊断报告模板面板 `TemplatePanel` 组件
|
|
|
+ - [ ] 实现诊断报告模板列表展示
|
|
|
+ - [ ] 添加"管理诊断报告模板"按钮
|
|
|
+ - [ ] 实现标签过滤
|
|
|
+ - [ ] 连接 Redux
|
|
|
+ - [ ] 实现应用诊断报告模板功能
|
|
|
+
|
|
|
+- [ ] 修改影像所见区域 `FindingsSection` 组件
|
|
|
+ - [ ] 实现"另存为诊断报告模板"功能
|
|
|
+ - [ ] 连接诊断报告模板编辑对话框
|
|
|
+
|
|
|
+### Phase 4: 功能完善
|
|
|
+- [ ] 实现应用诊断报告模板确认提示
|
|
|
+- [ ] 实现删除诊断报告模板确认提示
|
|
|
+- [ ] 实现错误处理和提示
|
|
|
+- [ ] 实现加载状态显示
|
|
|
+
|
|
|
+### Phase 5: 测试和优化
|
|
|
+- [ ] 单元测试
|
|
|
+- [ ] 集成测试
|
|
|
+- [ ] 用户体验优化
|
|
|
+- [ ] 性能优化
|
|
|
+
|
|
|
+## 🔄 交互流程(泳道图)
|
|
|
+
|
|
|
+```mermaid
|
|
|
+sequenceDiagram
|
|
|
+ participant U as 用户
|
|
|
+ participant TP as TemplatePanel
|
|
|
+ participant TMM as TemplateManagementModal
|
|
|
+ participant Redux as Redux Store
|
|
|
+ participant API as Backend API
|
|
|
+
|
|
|
+ Note over U,API: 场景1: 查看和应用模板
|
|
|
+ U->>TP: 打开诊断报告页面
|
|
|
+ TP->>Redux: dispatch(fetchTemplatesThunk())
|
|
|
+ Redux->>API: getReportTemplateList()
|
|
|
+ API-->>Redux: 返回模板列表
|
|
|
+ Redux-->>TP: 更新模板列表
|
|
|
+ TP->>U: 显示模板列表
|
|
|
+ U->>TP: 点击某个模板
|
|
|
+ TP->>Redux: 获取模板内容
|
|
|
+ TP->>U: 确认是否应用模板?
|
|
|
+ U->>TP: 确认
|
|
|
+ TP->>Redux: dispatch(updateInputValue(findings))
|
|
|
+ TP->>Redux: dispatch(setDiagnosisDescription(impression))
|
|
|
+ Redux-->>U: 更新报告内容
|
|
|
+
|
|
|
+ Note over U,API: 场景2: 管理模板(新建)
|
|
|
+ U->>TP: 点击"编辑"按钮
|
|
|
+ TP->>TMM: 打开模板管理对话框
|
|
|
+ TMM->>U: 显示左侧模板列表
|
|
|
+ U->>TMM: 点击"新建模板"
|
|
|
+ TMM->>TMM: 右侧显示空白编辑表单
|
|
|
+ U->>TMM: 在右侧填写模板信息
|
|
|
+ U->>TMM: 点击"保存"
|
|
|
+ TMM->>TMM: 表单验证
|
|
|
+ TMM->>Redux: dispatch(createTemplateThunk(template))
|
|
|
+ Redux->>API: createReportTemplate(template)
|
|
|
+ API-->>Redux: 返回创建结果
|
|
|
+ Redux-->>TMM: 更新状态
|
|
|
+ TMM->>U: 显示成功提示
|
|
|
+ TMM->>Redux: 刷新左侧模板列表
|
|
|
+ TMM->>U: 更新显示
|
|
|
+
|
|
|
+ Note over U,API: 场景3: 编辑模板
|
|
|
+ U->>TMM: 点击左侧列表中的某个模板
|
|
|
+ TMM->>Redux: 获取模板数据
|
|
|
+ TMM->>TMM: 右侧显示预填充表单
|
|
|
+ TMM->>U: 显示模板详情
|
|
|
+ U->>TMM: 在右侧修改模板信息
|
|
|
+ U->>TMM: 点击"保存"
|
|
|
+ TMM->>Redux: dispatch(updateTemplateThunk(id, template))
|
|
|
+ Redux->>API: updateReportTemplate(id, template)
|
|
|
+ API-->>Redux: 返回更新结果
|
|
|
+ Redux-->>TMM: 更新状态
|
|
|
+ TMM->>U: 显示成功提示
|
|
|
+ TMM->>U: 刷新左侧列表
|
|
|
+
|
|
|
+ Note over U,API: 场景4: 删除模板
|
|
|
+ U->>TMM: 在右侧点击"删除"按钮
|
|
|
+ TMM->>U: 显示确认对话框
|
|
|
+ U->>TMM: 确认删除
|
|
|
+ TMM->>Redux: dispatch(deleteTemplateThunk(id))
|
|
|
+ Redux->>API: deleteReportTemplate(id)
|
|
|
+ API-->>Redux: 返回删除结果
|
|
|
+ Redux-->>TMM: 更新状态
|
|
|
+ TMM->>U: 显示成功提示并刷新列表
|
|
|
+ TMM->>TMM: 右侧清空编辑区域
|
|
|
+
|
|
|
+ Note over U,API: 场景5: 另存为模板
|
|
|
+ U->>U: 填写影像所见和诊断意见
|
|
|
+ U->>TP: 点击"另存为模板"按钮
|
|
|
+ TP->>TMM: 打开模板管理对话框
|
|
|
+ TMM->>Redux: 获取当前报告内容
|
|
|
+ TMM->>TMM: 右侧显示预填充表单
|
|
|
+ TMM->>U: 显示预填充的findings和impression
|
|
|
+ U->>TMM: 补充模板名称等信息
|
|
|
+ U->>TMM: 点击"保存"
|
|
|
+ TMM->>Redux: dispatch(createTemplateThunk(template))
|
|
|
+ Redux->>API: createReportTemplate(template)
|
|
|
+ API-->>Redux: 返回创建结果
|
|
|
+ Redux-->>TMM: 更新状态
|
|
|
+ TMM->>U: 显示成功提示
|
|
|
+ TMM->>U: 刷新左侧模板列表
|
|
|
+```
|
|
|
+
|
|
|
+## 📊 数据流设计
|
|
|
+
|
|
|
+### 1. 数据流向图
|
|
|
+
|
|
|
+```mermaid
|
|
|
+graph TB
|
|
|
+ subgraph "用户界面层"
|
|
|
+ TP[TemplatePanel]
|
|
|
+ TMM[TemplateManagementModal<br/>左侧:列表 右侧:编辑区]
|
|
|
+ FS[FindingsSection]
|
|
|
+ DS[DiagnosisSection]
|
|
|
+ end
|
|
|
+
|
|
|
+ subgraph "状态管理层"
|
|
|
+ TS[templateSlice]
|
|
|
+ FiS[findingsSlice]
|
|
|
+ DiS[diagnosisSlice]
|
|
|
+ Store[Redux Store]
|
|
|
+ end
|
|
|
+
|
|
|
+ subgraph "API层"
|
|
|
+ API[ReportTemplateActions]
|
|
|
+ end
|
|
|
+
|
|
|
+ subgraph "后端"
|
|
|
+ Backend[Backend Server]
|
|
|
+ end
|
|
|
+
|
|
|
+ %% 查询流程
|
|
|
+ TP -->|dispatch fetchTemplatesThunk| TS
|
|
|
+ TMM -->|dispatch fetchTemplatesThunk| TS
|
|
|
+ TS -->|调用| API
|
|
|
+ API -->|HTTP GET| Backend
|
|
|
+ Backend -->|返回数据| API
|
|
|
+ API -->|返回| TS
|
|
|
+ TS -->|更新state| Store
|
|
|
+ Store -->|订阅更新| TP
|
|
|
+ Store -->|订阅更新| TMM
|
|
|
+
|
|
|
+ %% 创建/更新流程
|
|
|
+ TMM -->|dispatch createTemplateThunk| TS
|
|
|
+ TMM -->|dispatch updateTemplateThunk| TS
|
|
|
+ TS -->|调用| API
|
|
|
+ API -->|HTTP POST/PUT| Backend
|
|
|
+ Backend -->|返回结果| API
|
|
|
+ API -->|返回| TS
|
|
|
+ TS -->|更新state| Store
|
|
|
+
|
|
|
+ %% 删除流程
|
|
|
+ TMM -->|dispatch deleteTemplateThunk| TS
|
|
|
+ TS -->|调用| API
|
|
|
+ API -->|HTTP DELETE| Backend
|
|
|
+ Backend -->|返回结果| API
|
|
|
+ API -->|返回| TS
|
|
|
+
|
|
|
+ %% 应用模板流程
|
|
|
+ TP -->|应用模板| FiS
|
|
|
+ TP -->|应用模板| DiS
|
|
|
+ FiS -->|更新| Store
|
|
|
+ DiS -->|更新| Store
|
|
|
+ Store -->|订阅更新| FS
|
|
|
+ Store -->|订阅更新| DS
|
|
|
+
|
|
|
+ %% 另存为模板流程
|
|
|
+ FS -->|获取当前内容| FiS
|
|
|
+ FS -->|获取当前内容| DiS
|
|
|
+ FS -->|打开对话框| TMM
|
|
|
+```
|
|
|
+
|
|
|
+### 2. Redux State 结构
|
|
|
+
|
|
|
+```typescript
|
|
|
+// Redux Store 结构
|
|
|
+{
|
|
|
+ // ... 其他 slices
|
|
|
+ template: {
|
|
|
+ templates: ReportTemplate[], // 模板列表
|
|
|
+ loading: boolean, // 加载状态
|
|
|
+ error: string | null, // 错误信息
|
|
|
+ selectedTag: string, // 选中的标签过滤
|
|
|
+ },
|
|
|
+ findings: {
|
|
|
+ diagnosticDescriptionFromImage: string, // 影像所见内容
|
|
|
+ },
|
|
|
+ diagnosis: {
|
|
|
+ diagnosisDescription: string, // 诊断意见内容
|
|
|
+ },
|
|
|
+ // ... 其他 slices
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 🗂️ 数据结构定义
|
|
|
+
|
|
|
+### 1. 核心数据结构
|
|
|
+
|
|
|
+```typescript
|
|
|
+// 报告模板
|
|
|
+export interface ReportTemplate {
|
|
|
+ id?: string; // 模板ID(可选,创建时不需要)
|
|
|
+ name: string; // 模板名称
|
|
|
+ findings: string; // 影像所见内容
|
|
|
+ impression: string; // 诊断意见内容
|
|
|
+ tag: string; // 标签(用于分类)
|
|
|
+ staple: boolean; // 是否为常用模板
|
|
|
+}
|
|
|
+
|
|
|
+// 模板查询参数
|
|
|
+export interface ReportTemplateQueryParams {
|
|
|
+ tag?: string; // 按标签过滤
|
|
|
+ is_staple?: boolean; // 是否只查询常用模板
|
|
|
+ is_pre_install?: boolean; // 是否只查询预装模板
|
|
|
+}
|
|
|
+
|
|
|
+// API响应结构
|
|
|
+export interface ReportTemplateResponse {
|
|
|
+ code: string;
|
|
|
+ description: string;
|
|
|
+ solution: string;
|
|
|
+ data: any;
|
|
|
+}
|
|
|
+
|
|
|
+export interface ReportTemplateListResponse {
|
|
|
+ code: string;
|
|
|
+ description: string;
|
|
|
+ solution: string;
|
|
|
+ data: {
|
|
|
+ templates: ReportTemplate[];
|
|
|
+ count?: number;
|
|
|
+ };
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 2. Redux State 类型
|
|
|
+
|
|
|
+```typescript
|
|
|
+// templateSlice state
|
|
|
+export interface TemplateState {
|
|
|
+ templates: ReportTemplate[];
|
|
|
+ loading: boolean;
|
|
|
+ error: string | null;
|
|
|
+ selectedTag: string;
|
|
|
+}
|
|
|
+
|
|
|
+// findingsSlice state
|
|
|
+export interface FindingsState {
|
|
|
+ diagnosticDescriptionFromImage: string;
|
|
|
+}
|
|
|
+
|
|
|
+// diagnosisSlice state
|
|
|
+export interface DiagnosisState {
|
|
|
+ diagnosisDescription: string;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 3. 组件 Props 类型
|
|
|
+
|
|
|
+```typescript
|
|
|
+// TemplateEditModal Props
|
|
|
+export interface TemplateEditModalProps {
|
|
|
+ visible: boolean;
|
|
|
+ template?: ReportTemplate; // 编辑时传入,新建时为undefined
|
|
|
+ onSave: (template: ReportTemplate) => void;
|
|
|
+ onCancel: () => void;
|
|
|
+}
|
|
|
+
|
|
|
+// TemplateManagementModal Props
|
|
|
+export interface TemplateManagementModalProps {
|
|
|
+ visible: boolean;
|
|
|
+ onClose: () => void;
|
|
|
+}
|
|
|
+
|
|
|
+// TemplateListItem Props
|
|
|
+export interface TemplateListItemProps {
|
|
|
+ template: ReportTemplate;
|
|
|
+ onClick: (template: ReportTemplate) => void;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 🚀 执行流程
|
|
|
+
|
|
|
+### 1. 功能起点
|
|
|
+
|
|
|
+#### 起点1: 用户打开诊断报告页面
|
|
|
+```
|
|
|
+用户操作: 从患者列表或其他入口进入诊断报告页面
|
|
|
+↓
|
|
|
+触发: DiagnosticReport 组件挂载
|
|
|
+↓
|
|
|
+执行: useEffect 初始化报告数据
|
|
|
+↓
|
|
|
+执行: TemplatePanel 组件挂载
|
|
|
+↓
|
|
|
+触发: dispatch(fetchTemplatesThunk())
|
|
|
+↓
|
|
|
+执行: 调用 API 获取模板列表
|
|
|
+↓
|
|
|
+结果: 模板列表显示在侧边栏
|
|
|
+```
|
|
|
+
|
|
|
+#### 起点2: 用户点击"管理模板"按钮
|
|
|
+```
|
|
|
+用户操作: 点击 TemplatePanel 中的"管理模板"按钮
|
|
|
+↓
|
|
|
+触发: 打开 TemplateManagementModal
|
|
|
+↓
|
|
|
+执行: 显示模板列表(表格形式)
|
|
|
+↓
|
|
|
+用户可以: 新建/编辑/删除模板
|
|
|
+```
|
|
|
+
|
|
|
+#### 起点3: 用户点击"另存为模板"按钮
|
|
|
+```
|
|
|
+用户操作: 在 FindingsSection 中点击"另存为模板"按钮
|
|
|
+↓
|
|
|
+触发: 获取当前报告内容(findings + impression)
|
|
|
+↓
|
|
|
+触发: 打开 TemplateEditModal
|
|
|
+↓
|
|
|
+执行: 预填充表单(findings 和 impression)
|
|
|
+↓
|
|
|
+用户操作: 补充模板名称等信息并保存
|
|
|
+```
|
|
|
+
|
|
|
+#### 起点4: 用户点击模板列表中的模板
|
|
|
+```
|
|
|
+用户操作: 在 TemplatePanel 中点击某个模板
|
|
|
+↓
|
|
|
+触发: 检查当前报告是否有内容
|
|
|
+↓
|
|
|
+如果有内容: 显示确认对话框
|
|
|
+↓
|
|
|
+用户确认: 应用模板
|
|
|
+↓
|
|
|
+执行: dispatch(updateInputValue(template.findings))
|
|
|
+执行: dispatch(setDiagnosisDescription(template.impression))
|
|
|
+↓
|
|
|
+结果: 报告内容被模板内容替换
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 详细执行流程图
|
|
|
+
|
|
|
+```mermaid
|
|
|
+flowchart TD
|
|
|
+ Start([用户进入诊断报告页面]) --> Init[DiagnosticReport组件初始化]
|
|
|
+ Init --> LoadTemplates[TemplatePanel加载模板列表]
|
|
|
+ LoadTemplates --> FetchAPI[调用fetchTemplatesThunk]
|
|
|
+ FetchAPI --> DisplayList[显示模板列表]
|
|
|
+
|
|
|
+ DisplayList --> UserAction{用户操作}
|
|
|
+
|
|
|
+ UserAction -->|点击管理模板| OpenManagement[打开TemplateManagementModal]
|
|
|
+ UserAction -->|点击模板项| ApplyTemplate[应用模板流程]
|
|
|
+ UserAction -->|点击另存为模板| SaveAsTemplate[另存为模板流程]
|
|
|
+
|
|
|
+ OpenManagement --> ManagementActions{管理操作}
|
|
|
+ ManagementActions -->|新建| CreateNew[打开TemplateEditModal<br/>空表单]
|
|
|
+ ManagementActions -->|编辑| EditExisting[打开TemplateEditModal<br/>预填充数据]
|
|
|
+ ManagementActions -->|删除| DeleteConfirm[显示删除确认]
|
|
|
+
|
|
|
+ CreateNew --> FillForm[用户填写表单]
|
|
|
+ EditExisting --> FillForm
|
|
|
+ FillForm --> Validate{表单验证}
|
|
|
+ Validate -->|失败| ShowError[显示错误提示]
|
|
|
+ ShowError --> FillForm
|
|
|
+ Validate -->|成功| SaveAPI[调用API保存]
|
|
|
+ SaveAPI --> RefreshList[刷新模板列表]
|
|
|
+ RefreshList --> DisplayList
|
|
|
+
|
|
|
+ DeleteConfirm --> ConfirmDelete{用户确认?}
|
|
|
+ ConfirmDelete -->|是| CallDeleteAPI[调用deleteTemplateThunk]
|
|
|
+ ConfirmDelete -->|否| DisplayList
|
|
|
+ CallDeleteAPI --> RefreshList
|
|
|
+
|
|
|
+ ApplyTemplate --> CheckContent{当前有内容?}
|
|
|
+ CheckContent -->|是| ConfirmApply[显示确认对话框]
|
|
|
+ CheckContent -->|否| ApplyDirectly[直接应用]
|
|
|
+ ConfirmApply --> UserConfirm{用户确认?}
|
|
|
+ UserConfirm -->|是| ApplyDirectly
|
|
|
+ UserConfirm -->|否| DisplayList
|
|
|
+ ApplyDirectly --> UpdateFindings[更新影像所见]
|
|
|
+ UpdateFindings --> UpdateDiagnosis[更新诊断意见]
|
|
|
+ UpdateDiagnosis --> DisplayList
|
|
|
+
|
|
|
+ SaveAsTemplate --> GetCurrentContent[获取当前报告内容]
|
|
|
+ GetCurrentContent --> OpenEditModal[打开TemplateEditModal<br/>预填充findings和impression]
|
|
|
+ OpenEditModal --> FillForm
|
|
|
+```
|
|
|
+
|
|
|
+## 🧪 测试方案
|
|
|
+
|
|
|
+### 1. 功能测试场景
|
|
|
+
|
|
|
+#### 场景1: 模板列表加载
|
|
|
+**测试步骤:**
|
|
|
+1. 打开诊断报告页面
|
|
|
+2. 观察右侧模板面板
|
|
|
+
|
|
|
+**预期结果:**
|
|
|
+- 模板列表正确显示
|
|
|
+- 常用模板显示星标
|
|
|
+- 标签正确显示
|
|
|
+- 加载状态正确显示
|
|
|
+
|
|
|
+**测试数据:**
|
|
|
+- 至少3个不同标签的模板
|
|
|
+- 至少1个常用模板
|
|
|
+
|
|
|
+#### 场景2: 应用模板(无内容)
|
|
|
+**测试步骤:**
|
|
|
+1. 打开诊断报告页面(空白报告)
|
|
|
+2. 点击模板列表中的某个模板
|
|
|
+
|
|
|
+**预期结果:**
|
|
|
+- 影像所见输入框填充模板的findings内容
|
|
|
+- 诊断意见输入框填充模板的impression内容
|
|
|
+- 无确认对话框
|
|
|
+
|
|
|
+#### 场景3: 应用模板(有内容)
|
|
|
+**测试步骤:**
|
|
|
+1. 打开诊断报告页面
|
|
|
+2. 在影像所见和诊断意见中输入一些内容
|
|
|
+3. 点击模板列表中的某个模板
|
|
|
+
|
|
|
+**预期结果:**
|
|
|
+- 显示确认对话框:"当前报告已有内容,是否替换为模板内容?"
|
|
|
+- 点击确认后,内容被替换
|
|
|
+- 点击取消后,内容保持不变
|
|
|
+
|
|
|
+#### 场景4: 创建新模板
|
|
|
+**测试步骤:**
|
|
|
+1. 点击"管理模板"按钮
|
|
|
+2. 点击"新建模板"按钮
|
|
|
+3. 填写表单:
|
|
|
+ - 模板名称:测试模板
|
|
|
+ - 影像所见:测试所见内容
|
|
|
+ - 诊断意见:测试诊断内容
|
|
|
+ - 标签:测试
|
|
|
+ - 勾选"设为常用模板"
|
|
|
+4. 点击"保存"
|
|
|
+
|
|
|
+**预期结果:**
|
|
|
+- 表单验证通过
|
|
|
+- API调用成功
|
|
|
+- 显示成功提示
|
|
|
+- 模板列表刷新,新模板出现
|
|
|
+- 新模板显示星标(常用)
|
|
|
+
|
|
|
+#### 场景5: 编辑模板
|
|
|
+**测试步骤:**
|
|
|
+1. 点击"管理模板"按钮
|
|
|
+2. 点击某个模板的"编辑"按钮
|
|
|
+3. 修改模板名称
|
|
|
+4. 点击"保存"
|
|
|
+
|
|
|
+**预期结果:**
|
|
|
+- 表单预填充原有数据
|
|
|
+- 修改后保存成功
|
|
|
+- 模板列表刷新,显示修改后的名称
|
|
|
+
|
|
|
+#### 场景6: 删除模板
|
|
|
+**测试步骤:**
|
|
|
+1. 点击"管理模板"按钮
|
|
|
+2. 点击某个模板的"删除"按钮
|
|
|
+3. 在确认对话框中点击"确认"
|
|
|
+
|
|
|
+**预期结果:**
|
|
|
+- 显示确认对话框:"确定要删除此模板吗?"
|
|
|
+- 点击确认后,模板被删除
|
|
|
+- 模板列表刷新,该模板消失
|
|
|
+- 显示成功提示
|
|
|
+
|
|
|
+#### 场景7: 另存为模板
|
|
|
+**测试步骤:**
|
|
|
+1. 在影像所见中输入:"胸部正位片显示..."
|
|
|
+2. 在诊断意见中输入:"未见明显异常"
|
|
|
+3. 点击"另存为模板"按钮
|
|
|
+4. 在弹出的对话框中:
|
|
|
+ - 输入模板名称:"胸部正常模板"
|
|
|
+ - 输入标签:"胸部"
|
|
|
+ - 勾选"设为常用模板"
|
|
|
+5. 点击"保存"
|
|
|
+
|
|
|
+**预期结果:**
|
|
|
+- 对话框自动填充影像所见和诊断意见
|
|
|
+- 保存成功
|
|
|
+- 模板列表刷新,新模板出现
|
|
|
+
|
|
|
+#### 场景8: 标签过滤
|
|
|
+**测试步骤:**
|
|
|
+1. 在模板面板中选择标签过滤:"胸部"
|
|
|
+2. 观察模板列表
|
|
|
+
|
|
|
+**预期结果:**
|
|
|
+- 只显示标签为"胸部"的模板
|
|
|
+- 其他标签的模板被隐藏
|
|
|
+
|
|
|
+#### 场景9: 复制诊断报告模板
|
|
|
+**测试步骤:**
|
|
|
+1. 点击"管理诊断报告模板"按钮
|
|
|
+2. 点击选择一个已有的诊断报告模板
|
|
|
+3. 点击"复制"按钮
|
|
|
+4. 修改模板名称(自动添加"- 副本"后缀)
|
|
|
+5. 点击"保存"
|
|
|
+
|
|
|
+**预期结果:**
|
|
|
+- 复制按钮仅在选中模板时显示
|
|
|
+- 右侧表单预填充选中模板的所有内容
|
|
|
+- 模板名称自动添加"- 副本"后缀
|
|
|
+- 保存成功后,列表中出现新的复制模板
|
|
|
+- 原模板不受影响
|
|
|
+
|
|
|
+#### 场景10: 表单验证
|
|
|
+**测试步骤:**
|
|
|
+1. 点击"管理模板"→"新建模板"
|
|
|
+2. 不填写任何内容,直接点击"保存"
|
|
|
+
|
|
|
+**预期结果:**
|
|
|
+- 显示验证错误提示
|
|
|
+- 必填字段标红
|
|
|
+- 无法保存
|
|
|
+
|
|
|
+### 2. 边界情况测试
|
|
|
+
|
|
|
+#### 测试用例1: 空模板列表
|
|
|
+**场景:** 后端返回空模板列表
|
|
|
+**预期:** 显示"暂无模板"提示
|
|
|
+
|
|
|
+#### 测试用例2: API错误
|
|
|
+**场景:** 网络错误或API返回错误
|
|
|
+**预期:** 显示友好的错误提示,不影响其他功能
|
|
|
+
|
|
|
+#### 测试用例3: 长文本内容
|
|
|
+**场景:** 模板内容超过1000字
|
|
|
+**预期:** 正确保存和显示,文本框支持滚动
|
|
|
+
|
|
|
+#### 测试用例4: 特殊字符
|
|
|
+**场景:** 模板名称包含特殊字符(如:<>、&、")
|
|
|
+**预期:** 正确转义和显示
|
|
|
+
|
|
|
+#### 测试用例5: 并发操作
|
|
|
+**场景:** 快速连续点击保存按钮
|
|
|
+**预期:** 防抖处理,只发送一次请求
|
|
|
+
|
|
|
+### 3. 性能测试
|
|
|
+
|
|
|
+#### 测试用例1: 大量模板
|
|
|
+**场景:** 模板列表包含100+个模板
|
|
|
+**预期:**
|
|
|
+- 列表渲染流畅
|
|
|
+- 滚动无卡顿
|
|
|
+- 考虑虚拟滚动优化
|
|
|
+
|
|
|
+#### 测试用例2: 响应时间
|
|
|
+**场景:** 所有操作
|
|
|
+**预期:** 响应时间 < 500ms
|
|
|
+
|
|
|
+### 4. 用户体验测试
|
|
|
+
|
|
|
+#### 测试用例1: 加载状态
|
|
|
+**场景:** API调用期间
|
|
|
+**预期:** 显示加载指示器(Spin)
|
|
|
+
|
|
|
+#### 测试用例2: 成功提示
|
|
|
+**场景:** 创建/编辑/删除成功
|
|
|
+**预期:** 显示Toast提示,3秒后自动消失
|
|
|
+
|
|
|
+#### 测试用例3: 错误提示
|
|
|
+**场景:** 操作失败
|
|
|
+**预期:** 显示清晰的错误信息和解决建议
|
|
|
+
|
|
|
+## 🐛 潜在问题分析
|
|
|
+
|
|
|
+### 1. 数据一致性问题
|
|
|
+
|
|
|
+**问题:** 多个用户同时编辑同一个模板
|
|
|
+**影响:** 数据覆盖,后保存的覆盖先保存的
|
|
|
+**解决方案:**
|
|
|
+- 实现乐观锁机制(版本号)
|
|
|
+- 保存前检查版本号
|
|
|
+- 如果版本号不匹配,提示用户刷新后再编辑
|
|
|
+
|
|
|
+### 2. 网络错误处理
|
|
|
+
|
|
|
+**问题:** API调用失败(网络断开、超时等)
|
|
|
+**影响:** 用户操作失败,体验差
|
|
|
+**解决方案:**
|
|
|
+- 实现重试机制(最多3次)
|
|
|
+- 显示友好的错误提示
|
|
|
+- 提供手动重试按钮
|
|
|
+- 离线状态检测
|
|
|
+
|
|
|
+### 3. 内存泄漏
|
|
|
+
|
|
|
+**问题:** 组件卸载时未清理订阅
|
|
|
+**影响:** 内存占用增加,性能下降
|
|
|
+**解决方案:**
|
|
|
+- 使用useEffect清理函数
|
|
|
+- 取消未完成的API请求
|
|
|
+- 清理事件监听器
|
|
|
+
|
|
|
+### 4. 表单状态管理
|
|
|
+
|
|
|
+**问题:** 表单数据与Redux状态不同步
|
|
|
+**影响:** 数据不一致,保存失败
|
|
|
+**解决方案:**
|
|
|
+- 使用受控组件
|
|
|
+- 统一状态管理
|
|
|
+- 表单验证在提交前进行
|
|
|
+
|
|
|
+### 5. 性能问题
|
|
|
+
|
|
|
+**问题:** 大量模板导致列表渲染慢
|
|
|
+**影响:** 页面卡顿,用户体验差
|
|
|
+**解决方案:**
|
|
|
+- 实现虚拟滚动(react-window)
|
|
|
+- 分页加载
|
|
|
+- 懒加载
|
|
|
+- 防抖和节流
|
|
|
+
|
|
|
+### 6. 并发问题
|
|
|
+
|
|
|
+**问题:** 用户快速连续点击保存按钮
|
|
|
+**影响:** 发送多次重复请求
|
|
|
+**解决方案:**
|
|
|
+- 按钮防抖处理
|
|
|
+- 保存期间禁用按钮
|
|
|
+- 显示加载状态
|
|
|
+
|
|
|
+### 7. 数据验证
|
|
|
+
|
|
|
+**问题:** 前端验证不足,后端返回错误
|
|
|
+**影响:** 用户体验差
|
|
|
+**解决方案:**
|
|
|
+- 完善前端验证规则
|
|
|
+- 与后端验证规则保持一致
|
|
|
+- 显示清晰的错误提示
|
|
|
+
|
|
|
+### 8. 浏览器兼容性
|
|
|
+
|
|
|
+**问题:** 某些浏览器不支持特定API
|
|
|
+**影响:** 功能异常
|
|
|
+**解决方案:**
|
|
|
+- 使用Polyfill
|
|
|
+- 特性检测
|
|
|
+- 降级方案
|
|
|
+
|
|
|
+## 📐 组件架构图
|
|
|
+
|
|
|
+```mermaid
|
|
|
+graph TB
|
|
|
+ subgraph "DiagnosticReport Page"
|
|
|
+ DR[DiagnosticReport]
|
|
|
+ RH[ReportHeader]
|
|
|
+ RM[ReportMain]
|
|
|
+ RF[ReportFooter]
|
|
|
+ end
|
|
|
+
|
|
|
+ subgraph "ReportMain"
|
|
|
+ MC[MainContent]
|
|
|
+ SP[SidePanel]
|
|
|
+ end
|
|
|
+
|
|
|
+ subgraph "MainContent"
|
|
|
+ BI[BaseInfo]
|
|
|
+ IL[ImageList]
|
|
|
+ FS[FindingsSection]
|
|
|
+ DS[DiagnosisSection]
|
|
|
+ end
|
|
|
+
|
|
|
+ subgraph "SidePanel"
|
|
|
+ SF[StudyFilter]
|
|
|
+ TP[TemplatePanel]
|
|
|
+ end
|
|
|
+
|
|
|
+ subgraph "TemplatePanel"
|
|
|
+ TPList[模板列表]
|
|
|
+ TPFilter[标签过滤]
|
|
|
+ TPManage[管理模板按钮]
|
|
|
+ end
|
|
|
+
|
|
|
+ subgraph "Modals"
|
|
|
+ TMM[TemplateManagementModal<br/>左:列表 右:编辑]
|
|
|
+ end
|
|
|
+
|
|
|
+ DR --> RH
|
|
|
+ DR --> RM
|
|
|
+ DR --> RF
|
|
|
+ RM --> MC
|
|
|
+ RM --> SP
|
|
|
+ MC --> BI
|
|
|
+ MC --> IL
|
|
|
+ MC --> FS
|
|
|
+ MC --> DS
|
|
|
+ SP --> SF
|
|
|
+ SP --> TP
|
|
|
+ TP --> TPList
|
|
|
+ TP --> TPFilter
|
|
|
+ TP --> TPManage
|
|
|
+ TPManage -.打开.-> TMM
|
|
|
+ FS -.打开.-> TMM
|
|
|
+ TPList -.应用模板.-> FS
|
|
|
+ TPList -.应用模板.-> DS
|
|
|
+```
|
|
|
+
|
|
|
+## 🔧 技术实现细节
|
|
|
+
|
|
|
+### 1. Redux Thunk 实现示例
|
|
|
+
|
|
|
+```typescript
|
|
|
+// templateSlice.ts
|
|
|
+export const fetchTemplatesThunk = createAsyncThunk(
|
|
|
+ 'template/fetchTemplates',
|
|
|
+ async (params?: ReportTemplateQueryParams, { rejectWithValue }) => {
|
|
|
+ try {
|
|
|
+ const response = await getReportTemplateList(params);
|
|
|
+ return response.data.templates;
|
|
|
+ } catch (error: any) {
|
|
|
+ return rejectWithValue(error.message);
|
|
|
+ }
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+export const createTemplateThunk = createAsyncThunk(
|
|
|
+ 'template/createTemplate',
|
|
|
+ async (template: ReportTemplate, { rejectWithValue }) => {
|
|
|
+ try {
|
|
|
+ const response = await createReportTemplate(template);
|
|
|
+ return response.data;
|
|
|
+ } catch (error: any) {
|
|
|
+ return rejectWithValue(error.message);
|
|
|
+ }
|
|
|
+ }
|
|
|
+);
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 表单验证规则
|
|
|
+
|
|
|
+```typescript
|
|
|
+const validateTemplate = (template: ReportTemplate): string[] => {
|
|
|
+ const errors: string[] = [];
|
|
|
+
|
|
|
+ if (!template.name || template.name.trim() === '') {
|
|
|
+ errors.push('模板名称不能为空');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (template.name && template.name.length > 50) {
|
|
|
+ errors.push('模板名称不能超过50个字符');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!template.findings || template.findings.trim() === '') {
|
|
|
+ errors.push('影像所见不能为空');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!template.impression || template.impression.trim() === '') {
|
|
|
+ errors.push('诊断意见不能为空');
|
|
|
+ }
|
|
|
+
|
|
|
+ return errors;
|
|
|
+};
|
|
|
+```
|
|
|
+
|
|
|
+### 3. 应用模板确认逻辑
|
|
|
+
|
|
|
+```typescript
|
|
|
+const handleApplyTemplate = (template: ReportTemplate) => {
|
|
|
+ const hasContent =
|
|
|
+ findings.diagnosticDescriptionFromImage.trim() !== '' ||
|
|
|
+ diagnosis.diagnosisDescription.trim() !== '';
|
|
|
+
|
|
|
+ if (hasContent) {
|
|
|
+ Modal.confirm({
|
|
|
+ title: '确认应用模板',
|
|
|
+ content: '当前报告已有内容,是否替换为模板内容?',
|
|
|
+ onOk: () => {
|
|
|
+ dispatch(updateInputValue(template.findings));
|
|
|
+ dispatch(setDiagnosisDescription(template.impression));
|
|
|
+ message.success('模板已应用');
|
|
|
+ },
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ dispatch(updateInputValue(template.findings));
|
|
|
+ dispatch(setDiagnosisDescription(template.impression));
|
|
|
+ message.success('模板已应用');
|
|
|
+ }
|
|
|
+};
|
|
|
+```
|
|
|
+
|
|
|
+## 📱 响应式设计考虑
|
|
|
+
|
|
|
+虽然当前主要针对桌面端,但需要考虑:
|
|
|
+
|
|
|
+1. **对话框尺寸**
|
|
|
+ - 大屏:宽度800px
|
|
|
+ - 中屏:宽度90%
|
|
|
+ - 小屏:全屏显示
|
|
|
+
|
|
|
+2. **模板列表**
|
|
|
+ - 大屏:显示完整信息
|
|
|
+ - 小屏:简化显示,点击展开详情
|
|
|
+
|
|
|
+3. **表单布局**
|
|
|
+ - 大屏:两列布局
|
|
|
+ - 小屏:单列布局
|
|
|
+
|
|
|
+## 🎯 实现优先级
|
|
|
+
|
|
|
+### P0 - 核心功能(必须实现)
|
|
|
+1. ✅ Redux templateSlice 实现
|
|
|
+2. ✅ TemplateEditModal 组件
|
|
|
+3. ✅ TemplatePanel 基本功能
|
|
|
+4. ✅ 应用模板功能
|
|
|
+5. ✅ 创建/编辑/删除模板
|
|
|
+
|
|
|
+### P1 - 重要功能(应该实现)
|
|
|
+1. TemplateManagementModal 组件
|
|
|
+2. 标签过滤功能
|
|
|
+3. 常用模板标记
|
|
|
+4. 另存为模板功能
|
|
|
+5. 确认对话框
|
|
|
+
|
|
|
+### P2 - 增强功能(可以实现)
|
|
|
+1. 模板预览
|
|
|
+2. 模板搜索
|
|
|
+3. 模板排序
|
|
|
+4. 批量操作
|
|
|
+5. 模板导入/导出
|
|
|
+
|
|
|
+## 📚 参考文档
|
|
|
+
|
|
|
+- [Ant Design Modal](https://ant.design/components/modal-cn/)
|
|
|
+- [Ant Design Form](https://ant.design/components/form-cn/)
|
|
|
+- [Ant Design Table](https://ant.design/components/table-cn/)
|
|
|
+- [Redux Toolkit Async Thunks](https://redux-toolkit.js.org/api/createAsyncThunk)
|
|
|
+- [React Hooks](https://react.dev/reference/react)
|
|
|
+
|
|
|
+## 📝 总结
|
|
|
+
|
|
|
+本文档详细描述了诊断报告模板编辑功能的完整设计方案,包括:
|
|
|
+
|
|
|
+1. **需求分析** - 明确了功能需求和非功能需求
|
|
|
+2. **UI设计** - 提供了详细的界面布局和交互设计
|
|
|
+3. **架构设计** - 定义了组件结构、状态管理和数据流
|
|
|
+4. **实现计划** - 制定了分阶段的实现TodoList
|
|
|
+5. **测试方案** - 覆盖了功能测试、边界测试和性能测试
|
|
|
+6. **风险分析** - 识别了潜在问题并提供了解决方案
|
|
|
+
|
|
|
+通过本文档,开发团队可以清晰地了解功能的全貌,按照计划有序地实现各个模块,确保功能的质量和用户体验。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+**文档版本:** v1.0
|
|
|
+**创建日期:** 2025-12-25
|
|
|
+**最后更新:** 2025-12-25
|
|
|
+**作者:** Cline AI Assistant
|