追加体位Modal改造.md 5.4 KB

追加体位 Modal 改造总结

改造目标

AppendViewModal 从简单的体位列表展示改造为类似 register 页面的完整体位选择界面,包含过滤区域、体型结构交互、待选择区域和已选择区域。

架构设计

布局结构

┌─────────────────────────────────────────────────┐
│  Modal Header: "追加体位"                        │
├──────────────┬──────────────┬───────────────────┤
│              │              │                    │
│  过滤区域    │  体型结构    │  待选择区域         │
│  (6 cols)    │  (6 cols)    │  (12 cols)         │
│              │              │                    │
│              │              ├───────────────────┤
│              │              │  已选择区域         │
│              │              │                    │
└──────────────┴──────────────┴───────────────────┘
│  Modal Footer: 取消 / 确认追加 (n)              │
└─────────────────────────────────────────────────┘

组件层次

AppendViewModal (主容器)
├── AppendViewFilterBar (过滤条)
│   └── Segmented (协议/体位切换)
├── AppendBodyFilter (体型结构)
│   ├── HumanBody (人体)
│   └── AnimalBody (动物体)
├── AppendAvailableList (待选择列表)
│   └── AppendViewCard[] (体位卡片)
└── AppendSelectedList (已选择列表)
    └── Card[] (已选体位卡片)

修改/新增文件

1. 状态管理层

src/states/exam/appendViewSlice.ts (修改)

新增状态:

  • currentSelectionType: 'protocol' | 'view' - 当前选择类型
  • currentBodyPartId: string | null - 当前身体部位ID

新增 actions:

  • setSelectionType: 切换协议/体位选择
  • setCurrentBodyPart: 设置当前身体部位

2. 组件层

src/pages/exam/components/AppendViewFilterBar.tsx (新建)

功能:

  • 提供协议/体位切换 (Segmented)
  • 切换时自动重新获取数据
  • 与 appendView slice 集成

src/pages/exam/components/AppendBodyFilter.tsx (新建)

功能:

  • 显示 HumanBody 或 AnimalBody (根据产品类型)
  • 点击身体部位触发体位数据加载
  • 高亮当前选中的身体部位
  • 与 appendView slice 集成

src/pages/exam/components/AppendAvailableList.tsx (新建)

功能:

  • 显示可选择的体位列表
  • 点击体位卡片添加到已选择列表
  • 显示加载状态和空状态
  • 复用 AppendViewCard 组件

src/pages/exam/components/AppendSelectedList.tsx (新建)

功能:

  • 显示已选择的体位列表
  • 支持移除操作 (点击删除按钮)
  • 显示已选择数量
  • 空状态提示

src/pages/exam/components/AppendViewModal.tsx (重构)

主要改动:

  • 采用三列布局 (6-6-12 分栏)
  • 右侧分为上下两部分 (待选择/已选择)
  • 移除旧的列表渲染逻辑
  • 集成新的四个子组件
  • Modal 宽度调整为 90%
  • 高度设置为 70vh

数据流

初始化流程

  1. Modal 打开 → open prop 变为 true
  2. useEffect 检测到打开 → 初始化 currentBodyPartId 为当前检查的身体部位
  3. AppendBodyFilter 根据 currentBodyPartId 高亮对应部位
  4. 用户可以点击其他身体部位切换

体位选择流程

  1. 用户点击身体部位 → setCurrentBodyPart(bodyPartId)
  2. 触发 fetchAvailableViewsThunk 获取该部位的体位
  3. AppendAvailableList 显示可用体位列表
  4. 用户点击体位卡片 → toggleViewSelection(view)
  5. 体位添加到 selectedViews
  6. AppendSelectedList 显示已选择的体位
  7. 点击确认 → appendViewsThunk 追加体位到 Study

协议/体位切换流程

  1. 用户切换 Segmented → setSelectionType(type)
  2. 如果已选择身体部位 → 重新获取数据
  3. 列表更新为对应类型的数据

关键设计决策

1. 状态管理分离

  • appendView slice 专门管理追加体位相关的状态
  • 不复用 register 页面的 viewSelection slice
  • 避免状态冲突和耦合

2. 组件复用策略

  • 新建组件而非直接复用 register 组件
  • 保持组件职责清晰
  • 便于独立维护和测试

3. 用户体验优化

  • 默认加载当前检查的身体部位
  • 支持切换身体部位查看其他体位
  • 已选择区域实时反馈
  • 清晰的数量提示

后续优化建议

  1. 协议支持:目前只实现了体位选择,协议选择功能可以后续添加
  2. 搜索功能:可在过滤区域添加搜索框
  3. 批量操作:支持全选/清空等批量操作
  4. 响应式布局:针对不同屏幕尺寸优化布局
  5. 加载优化:可以缓存已加载的身体部位数据

测试要点

  • Modal 打开时正确初始化身体部位
  • 点击身体部位能正确加载体位列表
  • 协议/体位切换功能正常
  • 体位选择和移除功能正常
  • 确认追加成功后正确更新 bodyPositionList
  • 取消操作正确清空选择状态
  • 错误提示正常显示
  • 加载状态正常显示