LIJU 5 dias atrás
pai
commit
8ad6cfdef9

+ 32 - 121
src/main/java/cn/hnthyy/thmz/controller/mz/MzPharmacyController.java

@@ -322,52 +322,15 @@ public class MzPharmacyController {
             }
             resultMap = mzPharmacyService.refundMedicineProcessing(mzRefundMedicineVos, tokenUser.getUserIdCode());
 
-            // ================= 新增:根据药品类型区分处理追溯码转移 =================
-            // 目的:拆零药品追溯码转移失败不报错,不拆零药品追溯码转移失败正常报错
+            // ================= 修改:追溯码转移逻辑已优化 =================
+            // 目的:在Service层进行追溯码存在性检查,避免重复插入
             // 判断逻辑:serial="01"为拆零药品,serial="99"为不拆零药品
             
-            // 按药品类型分组处理
-            List<MzRefundMedicineVo> splitDrugList = new ArrayList<>(); // 拆零药品
-            List<MzRefundMedicineVo> nonSplitDrugList = new ArrayList<>(); // 不拆零药品
-            
-            for (MzRefundMedicineVo refundVo : mzRefundMedicineVos) {
-                if ("01".equals(refundVo.getSerial())) {
-                    // 拆零药品
-                    splitDrugList.add(refundVo);
-                } else {
-                    // 不拆零药品
-                    nonSplitDrugList.add(refundVo);
-                }
-            }
-            
-            // 处理拆零药品(容错处理)
-            if (!splitDrugList.isEmpty()) {
-                try {
-                    mzDrugTracCodgService.changeDrugCodgDataToTy(splitDrugList);
-                    log.info("拆零药品追溯码转移成功,退药处理完成 - 拆零药品数量: {}, 操作人: {}", 
-                            splitDrugList.size(), tokenUser.getUserIdCode());
-                } catch (Exception e) {
-                    // 拆零药品追溯码转移失败,记录详细错误信息,但不影响退药主流程
-                    StringBuilder refundInfo = new StringBuilder();
-                    for (MzRefundMedicineVo refundVo : splitDrugList) {
-                        refundInfo.append("病人ID:").append(refundVo.getPatientId())
-                                 .append(",处方号:").append(refundVo.getOrderNo())
-                                 .append(",药品编码:").append(refundVo.getChargeCode())
-                                 .append(";");
-                    }
-                    
-                    log.error("拆零药品追溯码转移失败,但不影响退药主流程 - 拆零药品: {}, 错误信息: {}, 操作人: {}", 
-                            refundInfo.toString(), e.getMessage(), tokenUser.getUserIdCode(), e);
-                }
-            }
-            
-            // 处理不拆零药品(原有逻辑,正常报错)
-            if (!nonSplitDrugList.isEmpty()) {
-                mzDrugTracCodgService.changeDrugCodgDataToTy(nonSplitDrugList);
-                log.info("不拆零药品追溯码转移成功,退药处理完成 - 不拆零药品数量: {}, 操作人: {}", 
-                        nonSplitDrugList.size(), tokenUser.getUserIdCode());
-            }
-            // ================= 新增结束 =================
+            // 将药品追溯码数据转移到退药表(Service层已处理重复检查)
+            mzDrugTracCodgService.changeDrugCodgDataToTy(mzRefundMedicineVos);
+            log.info("追溯码转移成功,退药处理完成 - 退药记录数量: {}, 操作人: {}", 
+                    mzRefundMedicineVos.size(), tokenUser.getUserIdCode());
+            // ================= 修改结束 =================
 
             // ================= 原方案3代码(已隐藏,可能复用) =================
             /*
@@ -461,42 +424,26 @@ public class MzPharmacyController {
                 resultMap.put("message", "撤销退药记录状态成功");
             }
 
-            // ================= 新增:根据药品类型区分处理撤销退药追溯码转移 =================
-            // 目的:拆零药品追溯码转移失败不报错,不拆零药品追溯码转移失败正常报错
+            // ================= 修改:撤销退药追溯码转移逻辑已优化 =================
+            // 目的:在Service层进行追溯码存在性检查,避免重复插入
             // 判断逻辑:serial="01"为拆零药品,serial="99"为不拆零药品
             
-            // 注意:撤销退药时,需要先查询退药表中的追溯码数据,然后根据药品类型分别处理
-            // 由于撤销退药是单个操作,这里使用容错处理,但记录详细的药品类型信息
+            //将药品追溯码退药表数据转移到正式表中(Service层已处理重复检查)
+            MzDrugTracCodg codg = new MzDrugTracCodg();
+            codg.setPatientId(patientId);
+            codg.setTimes(times);
+            //退费处方需要将发票号转正
+            codg.setReceiptNo(Math.abs(receiptNo));
+            codg.setRealNo(realNo);
+            codg.setOrderNo(orderNo);
+            codg.setGroupNo(groupNo);
             
-            try {
-                //将药品追溯码退药表数据转移到正式表中
-                MzDrugTracCodg codg = new MzDrugTracCodg();
-                codg.setPatientId(patientId);
-                codg.setTimes(times);
-                //退费处方需要将发票号转正
-                codg.setReceiptNo(Math.abs(receiptNo));
-                codg.setRealNo(realNo);
-                codg.setOrderNo(orderNo);
-                codg.setGroupNo(groupNo);
-                
-                // 使用service方法进行追溯码转移
-                mzDrugTracCodgService.changeDrugCodgDataFormTy(codg);
-                
-                log.info("撤销退药追溯码转移成功 - 病人ID: {}, 处方号: {}, 流水号: {}, 发票号: {}, 操作人: {}", 
-                        patientId, orderNo, realNo, receiptNo, tokenUser.getUserIdCode());
-                
-            } catch (Exception e) {
-                // 撤销退药追溯码转移失败,记录详细错误信息,但不影响撤销退药主流程
-                log.error("撤销退药追溯码转移失败,但不影响主流程 - 病人ID: {}, 处方号: {}, 流水号: {}, 发票号: {}, 错误信息: {}, 操作人: {}", 
-                        patientId, orderNo, realNo, receiptNo, e.getMessage(), tokenUser.getUserIdCode(), e);
-                
-                // 注意:这里不抛出异常,确保撤销退药主流程继续执行
-                // 但会导致后续问题:
-                // 1. 医保接口调用时,追溯码查询可能返回空
-                // 2. 医保接口可能报"追溯码不能为空"错误
-                // 3. 需要在前端或医保接口层面做额外处理
-            }
-            // ================= 新增结束 =================
+            // 使用service方法进行追溯码转移
+            mzDrugTracCodgService.changeDrugCodgDataFormTy(codg);
+            
+            log.info("撤销退药追溯码转移成功 - 病人ID: {}, 处方号: {}, 流水号: {}, 发票号: {}, 操作人: {}", 
+                    patientId, orderNo, realNo, receiptNo, tokenUser.getUserIdCode());
+            // ================= 修改结束 =================
 
             // ================= 原方案3代码(已隐藏,可能复用) =================
             /*
@@ -1207,52 +1154,16 @@ public class MzPharmacyController {
                 return resultMap;
             }
 
-            // ================= 新增:根据药品类型区分处理追溯码 =================
-            // 目的:拆零药品追溯码重复不报错,不拆零药品追溯码重复正常报错
+            // ================= 修改:追溯码保存逻辑已优化 =================
+            // 目的:在Service层进行追溯码存在性检查,避免重复插入
             // 判断逻辑:serial="01"为拆零药品,serial="99"为不拆零药品
             
-            // 按药品类型分组处理
-            List<MzDrugTracCodg> splitDrugList = new ArrayList<>(); // 拆零药品
-            List<MzDrugTracCodg> nonSplitDrugList = new ArrayList<>(); // 不拆零药品
-            
-            for (MzDrugTracCodg tracCodg : list) {
-                if ("01".equals(tracCodg.getSerial())) {
-                    // 拆零药品
-                    splitDrugList.add(tracCodg);
-                } else {
-                    // 不拆零药品
-                    nonSplitDrugList.add(tracCodg);
-                }
-            }
-            
-            // 处理拆零药品(容错处理)
-            if (!splitDrugList.isEmpty()) {
-                try {
-                    mzDrugTracCodgService.saveMzDrugTracCodgData(splitDrugList, tokenUser);
-                    log.info("配药拆零药品追溯码保存成功 - 病人ID: {}, 处方号: {}, 次数: {}, 追溯码数量: {}, 操作人: {}", 
-                            list.get(0).getPatientId(), list.get(0).getOrderNo(), list.get(0).getTimes(), 
-                            splitDrugList.size(), tokenUser.getUserIdCode());
-                } catch (Exception e) {
-                    // 拆零药品追溯码保存失败,记录详细错误信息,但不影响配药主流程
-                    StringBuilder tracCodgInfo = new StringBuilder();
-                    for (MzDrugTracCodg tracCodg : splitDrugList) {
-                        tracCodgInfo.append(tracCodg.getDrugTracCodg()).append(",");
-                    }
-                    
-                    log.error("配药拆零药品追溯码保存失败,但不影响主流程 - 病人ID: {}, 处方号: {}, 次数: {}, 追溯码: {}, 错误信息: {}, 操作人: {}", 
-                            list.get(0).getPatientId(), list.get(0).getOrderNo(), list.get(0).getTimes(),
-                            tracCodgInfo.toString(), e.getMessage(), tokenUser.getUserIdCode(), e);
-                }
-            }
-            
-            // 处理不拆零药品(原有逻辑,正常报错)
-            if (!nonSplitDrugList.isEmpty()) {
-                mzDrugTracCodgService.saveMzDrugTracCodgData(nonSplitDrugList, tokenUser);
-                log.info("配药不拆零药品追溯码保存成功 - 病人ID: {}, 处方号: {}, 次数: {}, 追溯码数量: {}, 操作人: {}", 
-                        list.get(0).getPatientId(), list.get(0).getOrderNo(), list.get(0).getTimes(), 
-                        nonSplitDrugList.size(), tokenUser.getUserIdCode());
-            }
-            // ================= 新增结束 =================
+            // 保存药品追溯码(Service层已处理重复检查)
+            mzDrugTracCodgService.saveMzDrugTracCodgData(list, tokenUser);
+            log.info("配药追溯码保存成功 - 病人ID: {}, 处方号: {}, 次数: {}, 追溯码数量: {}, 操作人: {}", 
+                    list.get(0).getPatientId(), list.get(0).getOrderNo(), list.get(0).getTimes(), 
+                    list.size(), tokenUser.getUserIdCode());
+            // ================= 修改结束 =================
 
             // ================= 原方案3代码(已隐藏,可能复用) =================
             /*

+ 119 - 1
src/main/java/cn/hnthyy/thmz/service/impl/his/mz/MzDrugTracCodgServiceImpl.java

@@ -67,6 +67,41 @@ public class MzDrugTracCodgServiceImpl implements MzDrugTracCodgService {
                 for(String sym : ds){
                     log.info("检查追溯码片段:'{}'", sym);
                     if(StringUtils.isNotBlank(sym)){
+                        // ================= 新增:检查追溯码是否已存在 =================
+                        // 目的:拆零药品追溯码已存在时跳过插入,不拆零药品保持原有行为
+                        // 判断逻辑:serial="01"为拆零药品,serial="99"为不拆零药品
+                        
+                        boolean shouldSkip = false;
+                        if ("01".equals(mzDrugTracCodg.getSerial())) {
+                            // 拆零药品:检查追溯码是否已存在
+                            MzDrugTracCodg existingCodg = mzDrugTracCodgMapper.selectMzDrugTracCodgByCode(sym);
+                            if (existingCodg != null) {
+                                log.info("拆零药品追溯码已存在,跳过插入 - 追溯码: {}, 药品编码: {}, 序列号: {}", 
+                                        sym, mzDrugTracCodg.getChargeItemCode(), mzDrugTracCodg.getSerial());
+                                shouldSkip = true;
+                            }
+                        }
+                        // 不拆零药品:不检查,保持原有行为(如果重复会报错)
+                        
+                        if (!shouldSkip) {
+                            MzDrugTracCodg drug = new MzDrugTracCodg();
+                            BeanUtils.copyProperties(mzDrugTracCodg, drug);
+                            drug.setDrugTracCodg(sym);
+                            drug.setFlag("0");
+                            drug.setConfirmTime(new Date());
+                            drug.setConfirmId(user.getUserIdCode());
+                            drug.setConfirmName(user.getUserName());
+                            l.add(drug);
+                            log.info("添加有效追溯码:{}", sym);
+                        }
+                        
+                        // ================= 原代码(已隐藏,可能复用) =================
+                        /*
+                        // ================= 原逻辑:直接添加所有追溯码 =================
+                        // 目的:原来的逻辑是直接添加所有追溯码,不进行重复检查
+                        // 问题:如果追溯码重复,会导致数据库主键冲突错误
+                        // 解决方案:已改为预检查逻辑,避免重复插入
+                        
                         MzDrugTracCodg drug = new MzDrugTracCodg();
                         BeanUtils.copyProperties(mzDrugTracCodg, drug);
                         drug.setDrugTracCodg(sym);
@@ -75,7 +110,9 @@ public class MzDrugTracCodgServiceImpl implements MzDrugTracCodgService {
                         drug.setConfirmId(user.getUserIdCode());
                         drug.setConfirmName(user.getUserName());
                         l.add(drug);
-                        log.info("添加有效追溯码:{}", sym);
+                        log.info("添加追溯码:{}", sym);
+                        */
+                        // ================= 原代码结束 =================
                     }
                 }
             }
@@ -154,12 +191,53 @@ public class MzDrugTracCodgServiceImpl implements MzDrugTracCodgService {
             list.addAll(l);
         }
         if(!list.isEmpty()){
+            // ================= 新增:检查退药追溯码是否已存在 =================
+            // 目的:拆零药品追溯码已存在时跳过插入,不拆零药品保持原有行为
+            // 判断逻辑:serial="01"为拆零药品,serial="99"为不拆零药品
+            
+            List<MzDrugTracCodg> filteredList = new ArrayList<>();
+            for (MzDrugTracCodg codg : list) {
+                boolean shouldSkip = false;
+                if ("01".equals(codg.getSerial())) {
+                    // 拆零药品:检查追溯码是否已在退药表中存在
+                    List<MzDrugTracCodg> existingCodgList = mzDrugTracCodgMapper.selectMzDrugTracCodgTyData(codg);
+                    if (existingCodgList != null && !existingCodgList.isEmpty()) {
+                        log.info("拆零药品退药追溯码已存在,跳过插入 - 追溯码: {}, 药品编码: {}, 序列号: {}", 
+                                codg.getDrugTracCodg(), codg.getChargeItemCode(), codg.getSerial());
+                        shouldSkip = true;
+                    }
+                }
+                // 不拆零药品:不检查,保持原有行为(如果重复会报错)
+                
+                if (!shouldSkip) {
+                    filteredList.add(codg);
+                }
+            }
+            
+            if (!filteredList.isEmpty()) {
+                //保存到退药信息表
+                mzDrugTracCodgMapper.insertDrugTracCodgTyData(filteredList);
+                //删除追溯码信息表
+                for(MzDrugTracCodg c : filteredList){
+                    mzDrugTracCodgMapper.deleteMzDrugTracCodgByCode(c.getDrugTracCodg());
+                }
+            }
+            
+            // ================= 原代码(已隐藏,可能复用) =================
+            /*
+            // ================= 原逻辑:直接转移所有追溯码 =================
+            // 目的:原来的逻辑是直接转移所有追溯码,不进行重复检查
+            // 问题:如果追溯码重复,会导致数据库主键冲突错误
+            // 解决方案:已改为预检查逻辑,避免重复插入
+            
             //保存到退药信息表
             mzDrugTracCodgMapper.insertDrugTracCodgTyData(list);
             //删除追溯码信息表
             for(MzDrugTracCodg c : list){
                 mzDrugTracCodgMapper.deleteMzDrugTracCodgByCode(c.getDrugTracCodg());
             }
+            */
+            // ================= 原代码结束 =================
         }
 
     }
@@ -168,6 +246,44 @@ public class MzDrugTracCodgServiceImpl implements MzDrugTracCodgService {
     @Override
     public void changeDrugCodgDataFormTy(MzDrugTracCodg drugTracCodg) {
         List<MzDrugTracCodg> list = mzDrugTracCodgMapper.selectMzDrugTracCodgTyData(drugTracCodg);
+        List<MzDrugTracCodg> data = new ArrayList<>();
+        for(MzDrugTracCodg codg : list){
+            // ================= 新增:检查追溯码是否已存在 =================
+            // 目的:拆零药品追溯码已存在时跳过插入,不拆零药品保持原有行为
+            // 判断逻辑:serial="01"为拆零药品,serial="99"为不拆零药品
+            
+            boolean shouldSkip = false;
+            if ("01".equals(codg.getSerial())) {
+                // 拆零药品:检查追溯码是否已在发药表中存在
+                MzDrugTracCodg existingCodg = mzDrugTracCodgMapper.selectMzDrugTracCodgByCode(codg.getDrugTracCodg());
+                if (existingCodg != null) {
+                    log.info("拆零药品撤销退药追溯码已存在,跳过插入 - 追溯码: {}, 药品编码: {}, 序列号: {}", 
+                            codg.getDrugTracCodg(), codg.getChargeItemCode(), codg.getSerial());
+                    shouldSkip = true;
+                }
+            } else {
+                // 不拆零药品:保持原有逻辑,如果已存在就跳过
+                MzDrugTracCodg d = mzDrugTracCodgMapper.selectMzDrugTracCodgByCode(codg.getDrugTracCodg());
+                if(null == d){
+                    data.add(codg);
+                }
+                // 不拆零药品处理完毕,继续下一个
+                continue;
+            }
+            
+            // 拆零药品且不存在时才添加
+            if ("01".equals(codg.getSerial()) && !shouldSkip) {
+                data.add(codg);
+            }
+        }
+        
+        // ================= 原代码(已隐藏,可能复用) =================
+        /*
+        // ================= 原逻辑:简单检查后直接添加 =================
+        // 目的:原来的逻辑是简单检查追溯码是否已存在,不区分拆零和不拆零
+        // 问题:没有区分拆零和不拆零药品的不同处理逻辑
+        // 解决方案:已改为区分拆零和不拆零药品的预检查逻辑
+        
         List<MzDrugTracCodg> data = new ArrayList<>();
         for(MzDrugTracCodg codg : list){
             MzDrugTracCodg d = mzDrugTracCodgMapper.selectMzDrugTracCodgByCode(codg.getDrugTracCodg());
@@ -175,6 +291,8 @@ public class MzDrugTracCodgServiceImpl implements MzDrugTracCodgService {
                 data.add(codg);
             }
         }
+        */
+        // ================= 原代码结束 =================
         if(!data.isEmpty()){
             mzDrugTracCodgMapper.insertMzDrugTracCodgData(data);
             for (MzDrugTracCodg c : data) {