diff --git a/src/main/java/com/glxp/api/controller/inout/IoCodeTempController.java b/src/main/java/com/glxp/api/controller/inout/IoCodeTempController.java index 5f6e28106..ef50d873c 100644 --- a/src/main/java/com/glxp/api/controller/inout/IoCodeTempController.java +++ b/src/main/java/com/glxp/api/controller/inout/IoCodeTempController.java @@ -419,7 +419,7 @@ public class IoCodeTempController extends BaseController { @RepeatSubmit() @AuthRuleAnnotation("") @PostMapping("warehouse/inout/batchAddCode") - @CusRedissonAnnotation(cacheName = RedissonCacheKey.WEB_ADD_CODE, key = {"#addOrderCodeRequest.corpOrderId", "#addOrderCodeRequest.codeList","#addOrderCodeRequest.code"}, timeOutMsg = "系统正在处理,请勿重复提交") + @CusRedissonAnnotation(cacheName = RedissonCacheKey.WEB_ADD_CODE, key = {"#addOrderCodeRequest.corpOrderId", "#addOrderCodeRequest.codeList", "#addOrderCodeRequest.code"}, timeOutMsg = "重复扫码") @Log(title = "单据管理", businessType = BusinessType.INSERT) public BaseResponse batchAddCode(@RequestBody AddOrderCodeRequest addOrderCodeRequest, BindingResult bindingResult) { @@ -437,17 +437,15 @@ public class IoCodeTempController extends BaseController { codeList.add(addOrderCodeRequest.getCode()); addOrderCodeRequest.setCodeList(codeList); } + // 获取第一个码判断类型,如果是药品类型则使用批量处理方法 - if (!codeList.isEmpty()) { + if (!codeList.isEmpty() && IntUtil.value(addOrderCodeRequest.getProductType()) == 2) { String firstCode = codeList.get(0); if (firstCode.endsWith("\u001D")) { firstCode = firstCode.replace("\u001D", ""); } - UdiEntity firstUdiEntity = FilterUdiUtils.getUdi(firstCode); - if (firstUdiEntity != null && IntUtil.value(firstUdiEntity.getProductType()) == 2) { - // 药品类型,使用批量处理方法 - return addCoodeService.batchProcessDrugCodes(addOrderCodeRequest, authAdmin); - } + // 药品类型,使用批量处理方法 + return addCoodeService.batchProcessDrugCodes(addOrderCodeRequest, authAdmin); } // 原有处理逻辑,处理非药品或空列表情况 diff --git a/src/main/java/com/glxp/api/req/inout/AddOrderCodeRequest.java b/src/main/java/com/glxp/api/req/inout/AddOrderCodeRequest.java index d6e5b4201..acc20bf5a 100644 --- a/src/main/java/com/glxp/api/req/inout/AddOrderCodeRequest.java +++ b/src/main/java/com/glxp/api/req/inout/AddOrderCodeRequest.java @@ -66,4 +66,6 @@ public class AddOrderCodeRequest { private Integer fromType; + private Integer productType; + } diff --git a/src/main/java/com/glxp/api/service/inout/AddCoodeService.java b/src/main/java/com/glxp/api/service/inout/AddCoodeService.java index e28c705e0..a1db3d57a 100644 --- a/src/main/java/com/glxp/api/service/inout/AddCoodeService.java +++ b/src/main/java/com/glxp/api/service/inout/AddCoodeService.java @@ -175,7 +175,7 @@ public class AddCoodeService { for (String code : processedCodes) { UdiEntity udiEntity = FilterUdiUtils.getUdi(code); - if (udiEntity != null) { + if (udiEntity != null && StrUtil.isNotEmpty(udiEntity.getUdi())) { udiEntityMap.put(code, udiEntity); nameCodes.put(udiEntity.getUdi(), code); } else { @@ -189,6 +189,7 @@ public class AddCoodeService { if (udiEntityMap.isEmpty()) { addCodeResult.setVailCodeResultResponses(vailCodeResultResponses); + addCodeResult.setOrderId(addOrderCodeRequest.getBillNo()); return ResultVOUtils.success(addCodeResult); } @@ -819,60 +820,72 @@ public class AddCoodeService { return Collections.emptyList(); } - // 获取当前订单的所有明细码 - List ioOrderDetailCodeEntities = orderDetailCodeDao.selectList(new QueryWrapper().select("id", "count", "reCount", "bindRlFk", "batchNo", "price").eq("orderIdFk", orderEntity.getBillNo())); - // 按照关联ID和批次号分组码实体 - Map> groupedTempEntities = codeTempEntities.stream().collect(Collectors.groupingBy(entity -> entity.getRelId() + ":" + StrUtil.trimToEmpty(entity.getBatchNo()))); + Map> groupedTempEntities = codeTempEntities.stream() + .collect(Collectors.groupingBy(entity -> entity.getRelId() + ":" + StrUtil.trimToEmpty(entity.getBatchNo()))); + + // 使用synchronized块来保护关键部分 + synchronized (orderEntity.getBillNo().intern()) { + // 获取当前订单的所有明细码 + // 处理每个分组 + for (Map.Entry> entry : groupedTempEntities.entrySet()) { + List group = entry.getValue(); + if (CollUtil.isEmpty(group)) { + continue; + } - // 处理每个分组 - for (Map.Entry> entry : groupedTempEntities.entrySet()) { - List group = entry.getValue(); - if (CollUtil.isEmpty(group)) { - continue; - } - IoCodeTempEntity representative = group.get(0); - UdiRelevanceResponse udiRelevanceResponse = udiRelevanceService.selectSupGroupById(representative.getRelId(), representative.getSupId()); - - // 计算该组的总数量 - int totalCount = group.stream().mapToInt(IoCodeTempEntity::getMyCount).sum(); - int totalReCount = group.stream().mapToInt(IoCodeTempEntity::getMyReCount).sum(); - // 如果没有现有明细码或未找到匹配的明细码,则创建新的 - boolean isUpdate = false; - IoOrderDetailCodeEntity resultDetailEntity = null; - if (CollUtil.isNotEmpty(ioOrderDetailCodeEntities)) { - for (IoOrderDetailCodeEntity orderDetailCodeEntity : ioOrderDetailCodeEntities) { - if (orderDetailCodeEntity.getBindRlFk().longValue() == representative.getRelId().longValue() && StrUtil.trimToEmpty(orderDetailCodeEntity.getBatchNo()).equals(StrUtil.trimToEmpty(representative.getBatchNo()))) { - // 更新现有明细码的数量 - orderDetailCodeEntity.setCount(orderDetailCodeEntity.getCount() + totalCount); - orderDetailCodeEntity.setReCount(orderDetailCodeEntity.getReCount() + totalReCount); - orderDetailCodeEntity.setUpdateTime(new Date()); - orderDetailCodeDao.updateCount(orderDetailCodeEntity); - isUpdate = true; - resultDetailEntity = orderDetailCodeEntity; - break; + IoCodeTempEntity representative = group.get(0); + UdiRelevanceResponse udiRelevanceResponse = udiRelevanceService.selectSupGroupById( + representative.getRelId(), + representative.getSupId()); + + // 计算该组的总数量 + int totalCount = group.stream().mapToInt(IoCodeTempEntity::getMyCount).sum(); + int totalReCount = group.stream().mapToInt(IoCodeTempEntity::getMyReCount).sum(); + + // 在数据库层面使用悲观锁或乐观锁查询现有记录 + IoOrderDetailCodeEntity existingEntity = orderDetailCodeDao.selectOne( + new QueryWrapper() + .eq("orderIdFk", orderEntity.getBillNo()) + .eq("bindRlFk", representative.getRelId()) + .eq(StrUtil.isNotEmpty(representative.getBatchNo()), "batchNo", representative.getBatchNo()) + .last("limit 1 FOR UPDATE")); // 添加行级锁 + + IoOrderDetailCodeEntity resultDetailEntity; + if (existingEntity != null) { + // 更新现有明细码的数量 + existingEntity.setCount(existingEntity.getCount() + totalCount); + existingEntity.setReCount(existingEntity.getReCount() + totalReCount); + existingEntity.setUpdateTime(new Date()); + orderDetailCodeDao.updateCount(existingEntity); + resultDetailEntity = existingEntity; + } else { + // 创建新记录 + resultDetailEntity = buildEntity(orderEntity, representative, udiRelevanceResponse, totalCount, totalReCount); + orderDetailCodeDao.insert(resultDetailEntity); + } + // 批量更新价格信息 + List updateBatch = new ArrayList<>(); + for (IoCodeTempEntity entity : group) { + if (entity.getPrice() == null && udiRelevanceResponse != null && udiRelevanceResponse.getPrice() != null) { + entity.setPrice(udiRelevanceResponse.getPrice()); } + entity.setBizId(resultDetailEntity.getId()); + updateBatch.add(entity); } - } - // 如果没有更新现有记录,则创建新记录 - if (!isUpdate) { - resultDetailEntity = buildEntity(orderEntity, representative, udiRelevanceResponse, totalCount, totalReCount); - orderDetailCodeDao.insert(resultDetailEntity); - } - // 更新价格信息 - for (IoCodeTempEntity entity : group) { - if (entity.getPrice() == null && udiRelevanceResponse != null && udiRelevanceResponse.getPrice() != null) { - entity.setPrice(udiRelevanceResponse.getPrice()); + // 批量更新以提高性能 + if (!updateBatch.isEmpty()) { + codeTempService.batchUpdate(updateBatch); } - entity.setBizId(resultDetailEntity.getId()); - codeTempService.updateById(entity); } + // 返回最新的明细码列表 + return orderDetailCodeDao.selectList( + new QueryWrapper() + .select("id", "count", "reCount", "bindRlFk", "batchNo", "price") + .eq("orderIdFk", orderEntity.getBillNo())); } - - // 返回最新的明细码列表 - return orderDetailCodeDao.selectList(new QueryWrapper().select("id", "count", "reCount", "bindRlFk", "batchNo", "price").eq("orderIdFk", orderEntity.getBillNo())); } public Integer getMaxGroupNumber() {