design.md 7.1 KB

Design: DIP 分组分值查询弹框(ScorePopup)

1. 背景与目标

为 DRG/DIP 一体化平台新增 DIP 业务的 HIS 弹框。复用 02010007 取分组入参 → 调 02010008 取 DIP 分组分值 → 渲染并支持模拟分析。

2. 路由与菜单设计

项 值
路由(hash) #/dip/score-popup
menu key dip-score-popup
菜单项名称 DIP 分组分值查询
父菜单 DIP 业务子菜单
菜单文件 frontend/src/api/menu.ts 等(按现有约定)
弹框路径参数 mode=popup&hisAdmId=...&fixmedinsCode=...&sessionId=...&userId=...&userName=...

3. 数据流

HIS URL(mode=popup)
  ↓
App.tsx 路由判断:mode=popup → 渲染 <ScorePopup/>(免登录)
  ↓
ScorePopup mount
  ↓
① 01050103 queryHospitals(fixmedinsCode)
   ├─ policyTypeDesc === 'DIP' → 继续
   └─ 其他 → Result「该机构为 DRG 业务,请使用 DRG 分组弹框」,结束
  ↓
② 02010007 queryGroupInput(hisAdmId)  (与 DRG 弹框共用)
   → 取得分组入参(小驼峰 result)
  ↓
③ 02010008 dipGroupByInput(input)  ← 新增接口封装
   → 取得 DIP 分组分值结果
  ↓
④ 渲染结果(基线展示完成)

4. 接口封装设计

4.1 新增 dipGroupByInput

// frontend/src/api/dip.ts
import { invoke, type SessionInfo } from './request';

/**
 * DIP 分组分值查询(02010008):依据 02010007 返回的分组入参,
 * 返回 DIP 编码、基准分值、调节系数、平均费用等。
 * @param input 02010007 返回的 result(小驼峰结构)
 * @param session Session 信息(可选)
 */
export const dipGroupByInput = (input: any, session?: SessionInfo) => {
  return invoke('02010008', [input], session);
};

4.2 DIP 结果类型定义

// frontend/src/api/dip.ts
export interface DIPGroupInfoItem {
  id: string;
  dipCode: string;                     // DIP 编码
  dipDesc: string;                     // DIP 名称
  principalDiagnosis: string;          // 主要诊断代码
  principalDiagnosisName: string;      // 主要诊断名称
  majorProcedure: string;              // 主要手术/操作代码
  majorProcedureName: string;          // 主要手术/操作名称
  secondaryProcedure: string;
  secondaryProcedureName: string;
  provinceID: number;
  provinceDesc: string;
  cityID: number;
  cityDesc: string;
  mdtrtArea: string;
  medinsLv: string;
  scoreValue: string;                  // 基准分值
  adjustCoefficient: string;
  primaryAdjustCoefficient: string;    // 一级调节系数
  secondaryAdjustCoefficient: string;  // 二级调节系数
  thirdAdjustCoefficient: string;      // 三级调节系数
  averageCost: string;                 // 平均费用
  groupPlanYear: number;
  checkTime: string;
}

export interface DIPGroupResult {
  dipCode: string;
  dipDesc: string;
  checkTime: string;
  dipInfo: DIPGroupInfoItem[];
}

5. 弹框组件设计

5.1 ScorePopup 组件结构(与 GroupPopup 对称)

<ScorePopup>
├── 顶部患者信息 Hero(姓名/性别/年龄/科室/医生/入院诊断/出院诊断)
├── 主操作区 Card
│   ├── 诊断列表(可编辑:增加/删除/查询 ICD;可设主诊断)
│   ├── 手术列表(可编辑:增加/删除/查询 ICD;可设主手术)
│   ├── 「模拟分组分值查询」按钮 → 触发 02010008
│   ├── 「重置」按钮 → 恢复 02010007 原值
│   └── 模拟结果展示卡(若有)
├── DIP 分组结果 Card(基线 + 模拟对比)
│   ├── DIP 编码 + 名称 + 分组时间
│   ├── 基准分值(高亮)
│   ├── 调节系数(三级)
│   ├── 平均费用
│   ├── 省/市/就医地区划代码
│   └── 医疗机构等级
└── 调试模式输入(仅非 popup 可见):AdmID 输入框 + 查询按钮

5.2 渲染的对比分析表

列 基线 模拟 差异
DIP 编码 dipCode dipCode(模拟) 文本对比
DIP 名称 dipDesc dipDesc(模拟) 文本对比
基准分值 scoreValue 模拟 数值对比(红/绿)
主要诊断 principalDiagnosis 表单值 文本
主要手术 majorProcedure 表单值 文本

6. 业务类型判断

复用 useHospitalOptions 思路,但需独立实现(因为 options 丢失 policyTypeDesc)。改为:

useEffect(() => {
  if (!isPopup) return;
  let cancelled = false;
  (async () => {
    try {
      const resp = await queryHospitals(
        { organizationCode: fixmedinsCode },
        { pageSize: 1, currentPage: 1 },
      );
      if (cancelled) return;
      const rows: HospitalItem[] = resp?.result?.rows || [];
      const policyDesc = (rows[0]?.policyTypeDesc || '').trim().toUpperCase();
      setBizType(policyDesc === 'DIP' ? 'dip' : 'drg');  // drg=展示该机构不匹配
    } catch {
      if (!cancelled) setBizType('dip');  // 异常回落 DIP(保守)
    }
  })();
  return () => { cancelled = true; };
}, [isPopup, fixmedinsCode]);

7. 调试入口

7.1 Workbench.tsx 顶部按钮

<Button onClick={() => navigate('/#/dip/score-popup?mode=preview&hisAdmId=...')}>
  打开 DIP 分组分值查询(调试)
</Button>

7.2 ScorePopup AdmID 输入框

  • 仅 !isPopup 时渲染(mode=preview 或菜单模式下显示)
  • 输入 AdmID + 点击「查询」→ 走 loadBaseline

8. 与 GroupPopup 的差异清单

维度 GroupPopup(DRG) ScorePopup(DIP)
分组接口 02010002 02010008
入口菜单 key drg-group-popup dip-score-popup
入口文件 pages/DRG/GroupPopup.tsx pages/DIP/ScorePopup.tsx
业务类型判断 policyTypeDesc=='DRG' policyTypeDesc=='DIP'
不匹配提示 暂未开发DIP分组分值查询功能 该机构为 DRG 业务,请使用 DRG 分组弹框
Hero 关键指标 drg/mdc/权重/盈亏 DIP 编码/名称/基准分值/调节系数/平均费用
对比表字段 drg/drgDesc/mdc/mdcDesc/支付标准/盈亏 dipCode/dipDesc/scoreValue/主要诊断/主要手术
模拟分组入参 groupInput 全量 + 编辑覆盖 同上(全量 result + 编辑覆盖)
模拟结果展示 DRGResult 渲染 DIPGroupResult 渲染

9. postMessage 协议(与 HIS 集成)

复用 GroupPopup 已有的协议(his-parent source):

  • init-group-input:父页注入 02010007 result
  • baseline-group-done:基线分组完成(通知父页)
  • sim-group-done:模拟分组完成(通知父页)

事件名调整:

  • baseline-score-done
  • sim-score-done

10. 容错

  • URL 未带 fixmedinsCode → 回落为 DIP(保守策略)
  • 01050103 异常 → 回落为 DIP
  • 02010007 返回空 → message.error 提示,不渲染主体
  • 02010008 返回空 → message.error 提示,渲染基线入参与提示「暂无 DIP 分组分值结果」

11. 后续工作(不在本 change 范围)

  • 后端 02010008 接口落地(用户另一分支)
  • 弹框自动保存分组分值结果到 02010035(按项目约定:HIS 端如需保存请通过 postMessage 拿结果后自行调)