From 8af06f6916be405dc5fa5172720fdbf22746d4f6 Mon Sep 17 00:00:00 2001 From: chenqi Date: Wed, 4 Mar 2026 18:32:06 +0800 Subject: [PATCH] =?UTF-8?q?perf(database):=20=E4=BC=98=E5=8C=96=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E6=9F=A5=E8=AF=A2=E6=80=A7=E8=83=BD=E5=92=8C?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E8=AF=B7=E6=B1=82=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 优化ActivityDefinitionManageMapper.xml中的分页查询,减少JOIN操作并使用索引友好的写法 - 修复purchaseinventory组件中API调用的数据传递格式问题 - 将前端请求超时时间从60秒增加到120秒以配合后端超时设置 - 在手术申请页面添加远程搜索防抖功能,避免频繁API调用 - 重构SurgeryAppServiceImpl中的名称字段填充逻辑,使用批量查询减少数据库访问次数 - 优化SurgeryMapper.xml中的分页查询,使用子查询预加载关联数据并减少不必要的JOIN --- .../impl/SurgeryAppServiceImpl.java | 124 +++++++++--------- .../mapper/clinicalmanage/SurgeryMapper.xml | 115 +++++++++++++++- .../ActivityDefinitionManageMapper.xml | 107 ++++++--------- openhis-ui-vue3/src/utils/request.js | 2 +- .../components/surgery/surgeryApplication.vue | 28 +++- .../components/purchaseinventory.js | 6 +- 6 files changed, 244 insertions(+), 138 deletions(-) diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/clinicalmanage/appservice/impl/SurgeryAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/clinicalmanage/appservice/impl/SurgeryAppServiceImpl.java index d03c8531..b6de136c 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/clinicalmanage/appservice/impl/SurgeryAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/clinicalmanage/appservice/impl/SurgeryAppServiceImpl.java @@ -533,94 +533,94 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService { /** * 填充手术记录中的名称字段 - * 根据ID反向查询用户表、机构表、手术室表、患者表、就诊表,填充对应的名称字段 + * 优化:使用批量查询减少数据库访问次数 * * @param surgery 手术实体对象 */ private void fillSurgeryNameFields(Surgery surgery) { + // 收集所有需要查询的ID + Set practitionerIds = new HashSet<>(); + Set orgIds = new HashSet<>(); + Set otherIds = new HashSet<>(); + + // 收集Practitioner IDs + if (surgery.getMainSurgeonId() != null) practitionerIds.add(surgery.getMainSurgeonId()); + if (surgery.getAnesthetistId() != null) practitionerIds.add(surgery.getAnesthetistId()); + if (surgery.getAssistant1Id() != null) practitionerIds.add(surgery.getAssistant1Id()); + if (surgery.getAssistant2Id() != null) practitionerIds.add(surgery.getAssistant2Id()); + if (surgery.getScrubNurseId() != null) practitionerIds.add(surgery.getScrubNurseId()); + if (surgery.getApplyDoctorId() != null) practitionerIds.add(surgery.getApplyDoctorId()); + + // 收集Organization IDs + if (surgery.getOrgId() != null) orgIds.add(surgery.getOrgId()); + if (surgery.getApplyDeptId() != null) orgIds.add(surgery.getApplyDeptId()); + + // 批量查询并缓存结果 + Map practitionerNameMap = new HashMap<>(); + Map orgNameMap = new HashMap<>(); + + // 批量查询Practitioner + if (!practitionerIds.isEmpty()) { + List practitioners = practitionerService.listByIds(practitionerIds); + for (com.openhis.administration.domain.Practitioner p : practitioners) { + practitionerNameMap.put(p.getId(), p.getName()); + } + } + + // 批量查询Organization + if (!orgIds.isEmpty()) { + List orgs = organizationService.listByIds(orgIds); + for (Organization o : orgs) { + orgNameMap.put(o.getId(), o.getName()); + } + } + // 填充患者姓名 - if (surgery.getPatientId() != null) { + if (surgery.getPatientId() != null && surgery.getPatientName() == null) { Patient patient = patientService.getById(surgery.getPatientId()); if (patient != null) { surgery.setPatientName(patient.getName()); } } - // 填充主刀医生姓名(使用practitionerId查询Practitioner表) - if (surgery.getMainSurgeonId() != null) { - com.openhis.administration.domain.Practitioner mainSurgeon = practitionerService.getById(surgery.getMainSurgeonId()); - if (mainSurgeon != null) { - surgery.setMainSurgeonName(mainSurgeon.getName()); - } + // 使用缓存填充名称 + if (surgery.getMainSurgeonId() != null && surgery.getMainSurgeonName() == null) { + surgery.setMainSurgeonName(practitionerNameMap.get(surgery.getMainSurgeonId())); } - - // 填充麻醉医生姓名(使用practitionerId查询Practitioner表) - if (surgery.getAnesthetistId() != null) { - com.openhis.administration.domain.Practitioner anesthetist = practitionerService.getById(surgery.getAnesthetistId()); - if (anesthetist != null) { - surgery.setAnesthetistName(anesthetist.getName()); - } + if (surgery.getAnesthetistId() != null && surgery.getAnesthetistName() == null) { + surgery.setAnesthetistName(practitionerNameMap.get(surgery.getAnesthetistId())); } - - // 填充助手1姓名(使用practitionerId查询Practitioner表) - if (surgery.getAssistant1Id() != null) { - com.openhis.administration.domain.Practitioner assistant1 = practitionerService.getById(surgery.getAssistant1Id()); - if (assistant1 != null) { - surgery.setAssistant1Name(assistant1.getName()); - } + if (surgery.getAssistant1Id() != null && surgery.getAssistant1Name() == null) { + surgery.setAssistant1Name(practitionerNameMap.get(surgery.getAssistant1Id())); } - - // 填充助手2姓名(使用practitionerId查询Practitioner表) - if (surgery.getAssistant2Id() != null) { - com.openhis.administration.domain.Practitioner assistant2 = practitionerService.getById(surgery.getAssistant2Id()); - if (assistant2 != null) { - surgery.setAssistant2Name(assistant2.getName()); - } + if (surgery.getAssistant2Id() != null && surgery.getAssistant2Name() == null) { + surgery.setAssistant2Name(practitionerNameMap.get(surgery.getAssistant2Id())); } - - // 填充巡回护士姓名(使用practitionerId查询Practitioner表) - if (surgery.getScrubNurseId() != null) { - com.openhis.administration.domain.Practitioner scrubNurse = practitionerService.getById(surgery.getScrubNurseId()); - if (scrubNurse != null) { - surgery.setScrubNurseName(scrubNurse.getName()); - } + if (surgery.getScrubNurseId() != null && surgery.getScrubNurseName() == null) { + surgery.setScrubNurseName(practitionerNameMap.get(surgery.getScrubNurseId())); + } + if (surgery.getApplyDoctorId() != null && surgery.getApplyDoctorName() == null) { + surgery.setApplyDoctorName(practitionerNameMap.get(surgery.getApplyDoctorId())); } // 填充手术室名称 - if (surgery.getOperatingRoomId() != null) { + if (surgery.getOperatingRoomId() != null && surgery.getOperatingRoomName() == null) { OperatingRoom operatingRoom = operatingRoomService.getById(surgery.getOperatingRoomId()); if (operatingRoom != null) { surgery.setOperatingRoomName(operatingRoom.getName()); } } - // 填充执行科室名称 - if (surgery.getOrgId() != null) { - Organization org = organizationService.getById(surgery.getOrgId()); - if (org != null) { - surgery.setOrgName(org.getName()); - } + // 使用缓存填充组织名称 + if (surgery.getOrgId() != null && surgery.getOrgName() == null) { + surgery.setOrgName(orgNameMap.get(surgery.getOrgId())); + } + if (surgery.getApplyDeptId() != null && surgery.getApplyDeptName() == null) { + surgery.setApplyDeptName(orgNameMap.get(surgery.getApplyDeptId())); } - // 填充申请科室名称(如果还没有设置) - if (surgery.getApplyDeptId() != null && (surgery.getApplyDeptName() == null || surgery.getApplyDeptName().isEmpty())) { - Organization applyDept = organizationService.getById(surgery.getApplyDeptId()); - if (applyDept != null) { - surgery.setApplyDeptName(applyDept.getName()); - } - } - - // 填充申请医生姓名(如果还没有设置) - 使用practitionerId查询Practitioner表 - if (surgery.getApplyDoctorId() != null && (surgery.getApplyDoctorName() == null || surgery.getApplyDoctorName().isEmpty())) { - com.openhis.administration.domain.Practitioner applyDoctor = practitionerService.getById(surgery.getApplyDoctorId()); - if (applyDoctor != null) { - surgery.setApplyDoctorName(applyDoctor.getName()); - } - } - - log.info("填充手术名称字段完成 - patientName: {}, mainSurgeonName: {}, anesthetistName: {}, assistant1Name: {}, assistant2Name: {}, scrubNurseName: {}, operatingRoomName: {}, orgName: {}", - surgery.getPatientName(), surgery.getMainSurgeonName(), surgery.getAnesthetistName(), surgery.getAssistant1Name(), - surgery.getAssistant2Name(), surgery.getScrubNurseName(), surgery.getOperatingRoomName(), surgery.getOrgName()); + log.debug("填充手术名称字段完成 - patientName: {}, mainSurgeonName: {}, orgName: {}", + surgery.getPatientName(), surgery.getMainSurgeonName(), surgery.getOrgName()); } /** diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/clinicalmanage/SurgeryMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/clinicalmanage/SurgeryMapper.xml index ad978677..fc422cb3 100644 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/clinicalmanage/SurgeryMapper.xml +++ b/openhis-server-new/openhis-application/src/main/resources/mapper/clinicalmanage/SurgeryMapper.xml @@ -189,13 +189,124 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" LEFT JOIN adm_organization apply_dept ON s.apply_dept_id = apply_dept.id + SELECT - T3.id, - T3.category_code, - T3.bus_no, - T3.name, - T3.py_str, - T3.wb_str, - T3.type_enum, - T3.permitted_unit_code, - T3.org_id, - T3.location_id, - T3.yb_flag, - T3.yb_no, - T3.yb_match_flag, - T3.status_enum, - T3.body_site_code, - T3.specimen_code, - T3.description_text, - T3.rule_id, - T3.tenant_id, - T3.item_type_code, - T3.yb_type, - T3.price_code, - T3.retail_price, - T3.maximum_retail_price, - T3.chrgitm_lv, - T3.children_json, - T3.pricing_flag, - T3.sort_order, - T3.service_range - FROM - ( - SELECT - T1.id, - T1.category_code, - T1.bus_no, - T1.name, - T1.py_str, - T1.wb_str, - T1.type_enum, - T1.permitted_unit_code, - T1.org_id, - T1.location_id, - T1.yb_flag, - T1.yb_no, - T1.yb_match_flag, - T1.status_enum, - T1.body_site_code, - T1.specimen_code, - T1.description_text, - T1.rule_id, - T1.tenant_id, - T1.chrgitm_lv, - T2.type_code as item_type_code, - T2.yb_type, - T2.price_code, - T2.price as retail_price, - T4.amount as maximum_retail_price, - T1.children_json, - T1.pricing_flag, - T1.sort_order, - T1.service_range + T1.id, + T1.category_code, + T1.bus_no, + T1.name, + T1.py_str, + T1.wb_str, + T1.type_enum, + T1.permitted_unit_code, + T1.org_id, + T1.location_id, + T1.yb_flag, + T1.yb_no, + T1.yb_match_flag, + T1.status_enum, + T1.body_site_code, + T1.specimen_code, + T1.description_text, + T1.rule_id, + T1.tenant_id, + T1.chrgitm_lv, + T1.children_json, + T1.pricing_flag, + T1.sort_order, + T1.service_range, + T2.type_code as item_type_code, + T2.yb_type, + T2.price_code, + T2.price as retail_price, + T4.amount as maximum_retail_price FROM wor_activity_definition T1 - LEFT JOIN adm_charge_item_definition T2 ON T1.id = T2.instance_id - LEFT JOIN adm_charge_item_definition T5 ON T5.instance_id = T1.id AND T5.instance_table = 'wor_activity_definition' - LEFT JOIN adm_charge_item_def_detail T4 ON T4.definition_id = T5.id AND T4.condition_code = '4' + /* 只JOIN必要的价格表,使用INNER JOIN避免笛卡尔积 */ + INNER JOIN adm_charge_item_definition T2 + ON T1.id = T2.instance_id + AND T2.instance_table = 'wor_activity_definition' + /* 最高零售价使用LEFT JOIN,因为可能不存在 */ + LEFT JOIN adm_charge_item_def_detail T4 + ON T4.definition_id = T2.id + AND T4.condition_code = '4' T1.delete_flag = '0' - AND T2.instance_table = 'wor_activity_definition' @@ -84,9 +57,7 @@ - ORDER BY T1.bus_no DESC - ) T3 - + ORDER BY T1.id DESC