# 诊断报告模板编辑功能设计文档 ## 📋 功能概述 实现诊断报告模板的完整管理功能,包括诊断报告模板的创建、编辑、删除、应用等操作。用户可以通过诊断报告模板快速填充报告内容,提高工作效率。 ## 🎯 详细需求 ### 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
左侧:列表 右侧:编辑区] 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
空表单] ManagementActions -->|编辑| EditExisting[打开TemplateEditModal
预填充数据] 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
预填充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
左:列表 右:编辑] 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