From 2407d06bcf106e1d5ef45cb8664d1322d27dc57f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E4=BA=91?= <赵云@gentronhealth.com> Date: Wed, 13 May 2026 19:19:03 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#489:=20=E3=80=90=E5=8C=BB=E5=98=B1?= =?UTF-8?q?=E9=97=AD=E7=8E=AF=E3=80=91=E5=8C=BB=E7=94=9F=E7=AB=99=E7=AD=BE?= =?UTF-8?q?=E5=8F=91=E5=8D=95=E6=9D=A1=E9=95=BF=E6=9C=9F=E8=8D=AF=E5=93=81?= =?UTF-8?q?=E5=8C=BB=E5=98=B1=EF=BC=8C=E6=8A=A4=E5=A3=AB=E6=A0=A1=E5=AF=B9?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E7=94=9F=E6=88=90=E9=87=8D=E5=A4=8D=EF=BC=88?= =?UTF-8?q?=E4=B8=A4=E6=9D=A1=EF=BC=89=E5=BE=85=E6=A0=A1=E5=AF=B9=E8=AE=B0?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因分析: 1. SQL查询JOIN倍增:selectInpatientAdvicePage 中多个LEFT JOIN(如adm_encounter_location、 adm_encounter_participant、med_medication)可能产生重复行,外层查询无DISTINCT去重 2. 防重复逻辑缺陷:handMedication() 中仅对 DbOpType.INSERT 进行去重,若同一请求中包含 INSERT 和 UPDATE(编辑后签发的医嘱),两者uniqueKey相同但UPDATE不受去重限制, 导致 UPDATE 修改旧记录 + INSERT 创建新记录 = 两条数据 修复方案: 1. 在AdviceProcessAppMapper.xml的UNION两侧子查询中添加SELECT DISTINCT,防止JOIN倍增 2. 在AdviceManageAppServiceImpl.java中移除dbOpType限制,对所有医嘱(INSERT+UPDATE) 统一按uniqueKey去重,确保同一业务医嘱只处理一次 Co-Authored-By: Claude Opus 4.7 --- .../impl/AdviceManageAppServiceImpl.java | 16 ++++++++-------- .../AdviceProcessAppMapper.xml | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java index d18d54b66..957313188 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java @@ -341,7 +341,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService { && (DbOpType.INSERT.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType()))) .collect(Collectors.toList()); - // 防重复保存:对新增医嘱进行去重,避免签发单条长期医嘱时产生重复记录 + // 防重复保存:对所有医嘱进行去重(包括 INSERT 和 UPDATE 混合场景),避免签发单条医嘱时产生重复记录 Set longUniqueKeySet = new HashSet<>(); List longUniqueList = new ArrayList<>(); for (RegAdviceSaveDto adviceSaveDto : longInsertOrUpdateList) { @@ -351,10 +351,10 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService { + adviceSaveDto.getDose() + "_" + adviceSaveDto.getMethodCode() + "_" + adviceSaveDto.getRateCode(); - if (DbOpType.INSERT.getCode().equals(adviceSaveDto.getDbOpType()) && longUniqueKeySet.contains(uniqueKey)) { - log.warn("防重复保存:检测到重复长期医嘱,跳过保存 - patientId={}, encounterId={}, adviceDefinitionId={}, dose={}", + if (longUniqueKeySet.contains(uniqueKey)) { + log.warn("防重复保存:检测到重复长期医嘱(跨操作类型),跳过 - patientId={}, encounterId={}, adviceDefinitionId={}, dbOpType={}", adviceSaveDto.getPatientId(), adviceSaveDto.getEncounterId(), - adviceSaveDto.getAdviceDefinitionId(), adviceSaveDto.getDose()); + adviceSaveDto.getAdviceDefinitionId(), adviceSaveDto.getDbOpType()); continue; } longUniqueKeySet.add(uniqueKey); @@ -429,7 +429,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService { && (DbOpType.INSERT.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType()))) .collect(Collectors.toList()); - // 防重复保存:对新增医嘱进行去重 + // 防重复保存:对所有医嘱进行去重(包括 INSERT 和 UPDATE 混合场景),避免签发时产生重复记录 Set tempUniqueKeySet = new HashSet<>(); List tempUniqueList = new ArrayList<>(); for (RegAdviceSaveDto adviceSaveDto : tempInsertOrUpdateList) { @@ -439,10 +439,10 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService { + adviceSaveDto.getDose() + "_" + adviceSaveDto.getMethodCode() + "_" + adviceSaveDto.getRateCode(); - if (DbOpType.INSERT.getCode().equals(adviceSaveDto.getDbOpType()) && tempUniqueKeySet.contains(uniqueKey)) { - log.warn("防重复保存:检测到重复临时医嘱,跳过保存 - patientId={}, encounterId={}, adviceDefinitionId={}, dose={}", + if (tempUniqueKeySet.contains(uniqueKey)) { + log.warn("防重复保存:检测到重复临时医嘱(跨操作类型),跳过 - patientId={}, encounterId={}, adviceDefinitionId={}, dbOpType={}", adviceSaveDto.getPatientId(), adviceSaveDto.getEncounterId(), - adviceSaveDto.getAdviceDefinitionId(), adviceSaveDto.getDose()); + adviceSaveDto.getAdviceDefinitionId(), adviceSaveDto.getDbOpType()); continue; } tempUniqueKeySet.add(uniqueKey); diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/inhospitalnursestation/AdviceProcessAppMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/inhospitalnursestation/AdviceProcessAppMapper.xml index 3aa27ecbd..dbd2b1cd9 100755 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/inhospitalnursestation/AdviceProcessAppMapper.xml +++ b/openhis-server-new/openhis-application/src/main/resources/mapper/inhospitalnursestation/AdviceProcessAppMapper.xml @@ -155,7 +155,7 @@ ii.performer_check_id, ii.category_code, ii.dispense_status - FROM (( SELECT T1.encounter_id, + FROM (( SELECT DISTINCT T1.encounter_id, T1.tenant_id, #{medMedicationRequest} AS advice_table, T1.id AS request_id, @@ -293,7 +293,7 @@ T1.sort_number, T1.group_id ) UNION - ( SELECT T1.encounter_id, + ( SELECT DISTINCT T1.encounter_id, T1.tenant_id, #{worServiceRequest} AS advice_table, T1.id AS request_id,