diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/ComponentPackingController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/ComponentPackingController.java index dc5e789f..6f305c09 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/ComponentPackingController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/ComponentPackingController.java @@ -113,9 +113,7 @@ public class ComponentPackingController { /** * 添加零部件的打包信息 - * - * @param request - * @return + * @return {@link InventoryLockVO} */ @PostMapping("add") public ApiResult savePacking(@Valid @RequestBody ComponentPackingInputQO request) { diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutAssistanceController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutAssistanceController.java index 163d3b44..5c14ecad 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutAssistanceController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutAssistanceController.java @@ -11,7 +11,6 @@ import com.nflg.wms.admin.repository.InventoryForOutRepository; import com.nflg.wms.admin.repository.OutMaterialScanRecordRespository; import com.nflg.wms.admin.service.BasdeSerialNumberControllerService; import com.nflg.wms.admin.service.SapService; -import com.nflg.wms.admin.util.NoUtil; import com.nflg.wms.admin.util.PdfGeneratorUtil; import com.nflg.wms.admin.util.QRCodeUtil; import com.nflg.wms.admin.util.ThymeleafUtil; @@ -105,6 +104,7 @@ public class OutAssistanceController extends BaseController { /** * 保存 + * @return {@link InventoryLockVO} */ @Transactional @PostMapping("save") @@ -119,6 +119,7 @@ public class OutAssistanceController extends BaseController { VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(materialNos)) .throwMessage("以下物料的申请数量超出限制:" + StrUtil.join(",", materialNos)); Map> maps = datas.stream().collect(Collectors.groupingBy(SubcontractedOrderDTO::getKey)); + List lockVOS = new ArrayList<>(); maps.forEach((key, items) -> { WmsOutAssistance order = Convert.convert(WmsOutAssistance.class, items.get(0)); order.setNo(serialNumberControllerService.generateSerialNumber(16)); @@ -127,11 +128,35 @@ public class OutAssistanceController extends BaseController { outAssistanceService.save(order); items.forEach(item -> { WmsOutAssistanceItem data = Convert.convert(WmsOutAssistanceItem.class, item); - data.setLeft(data.getNum()); - data.setOrderId(order.getId()); - outAssistanceItemService.save(data); + RLock lock = redissonClient.getLock(StrUtil.format("lock:inventory:{}:{}:{}", order.getWerks(), order.getLgort1(), item.getMatnr1())); + try { + // 等待5秒获取锁,10秒后自动释放 + if (lock.tryLock(5, 10, TimeUnit.SECONDS)) { + if (inventoryService.getNumOne(order.getWerks(), order.getLgort1(), item.getMatnr1()).compareTo(data.getNum()) < 0) { + List itemLocks = inventoryService.getLockList(order.getWerks(), order.getLgort1(), item.getMatnr1()); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(itemLocks)).throwMessage("库存不足:" + item.getMatnr1()); + lockVOS.addAll(itemLocks); + }else { + data.setLeft(data.getNum()); + data.setOrderId(order.getId()); + outAssistanceItemService.save(data); + } + } else { + throw new NflgException(STATE.BusinessError, "获取锁失败"); + } + } catch (Exception e) { + log.error("保存单据出错", e); + throw new NflgException(STATE.BusinessError, e.getMessage()); + } finally { + if (lock.isHeldByCurrentThread()) { + lock.unlock(); + } + } }); }); + if (CollectionUtil.isNotEmpty(lockVOS)) { + throw new DataAlertException(STATE.OutOfStock, lockVOS); + } return ApiResult.success(); } @@ -230,10 +255,10 @@ public class OutAssistanceController extends BaseController { public ApiResult submit(@Valid @RequestBody OutProduceSubmitQO request) { WmsOutAssistance order = outAssistanceService.lambdaQuery().eq(WmsOutAssistance::getNo, request.getNo()).one(); VUtil.trueThrowBusinessError(Objects.isNull(order)).throwMessage("订单不存在"); - Set matnrs = request.getItems().stream().map(OutProduceSubmitItemQO::getMaterialNo).collect(Collectors.toSet()); - matnrs.removeAll(request.getRecommendBatch().stream().map(InventoryForOutVO::getMaterialNo).collect(Collectors.toSet())); - VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(matnrs)) - .throwMessage("以下物料无库存,不能出库:" + StrUtil.join(",", matnrs)); +// Set matnrs = request.getItems().stream().map(OutProduceSubmitItemQO::getMaterialNo).collect(Collectors.toSet()); +// matnrs.removeAll(request.getRecommendBatch().stream().map(InventoryForOutVO::getMaterialNo).collect(Collectors.toSet())); +// VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(matnrs)) +// .throwMessage("以下物料无库存,不能出库:" + StrUtil.join(",", matnrs)); WmsOutAssistanceTicket ticket = new WmsOutAssistanceTicket() .setId(IdUtil.getSnowflakeNextId()) .setNo(serialNumberControllerService.generateSerialNumber(17)) @@ -354,36 +379,6 @@ public class OutAssistanceController extends BaseController { }); } }); - List lockVOS = new ArrayList<>(); - records.stream() - .collect(Collectors.groupingBy(OutMaterialScanRecord::getKey10)) - .forEach((key, vs) -> { - OutMaterialScanRecord info = vs.get(0); - BigDecimal lockNum = vs.stream().map(OutMaterialScanRecord::getNum).reduce(BigDecimal.ZERO, BigDecimal::add); - RLock lock = redissonClient.getLock(StrUtil.format("lock:inventory:{}:{}:{}", info.getFactoryNo(), info.getWarehouseNo(), info.getMaterialNo())); - try { - // 等待5秒获取锁,10秒后自动释放 - if (lock.tryLock(5, 10, TimeUnit.SECONDS)) { - if (inventoryService.getNumOne(info.getFactoryNo(), info.getWarehouseNo(), info.getMaterialNo()).compareTo(lockNum) < 0) { - List itemLocks = inventoryService.getLockList(info.getFactoryNo(), info.getWarehouseNo(), info.getMaterialNo()); - VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(itemLocks)).throwMessage("库存不足:" + info.getMaterialNo()); - lockVOS.addAll(itemLocks); - } - } else { - throw new NflgException(STATE.BusinessError, "获取锁失败"); - } - } catch (Exception e) { - log.error("保存生产领料单出错", e); - throw new NflgException(STATE.BusinessError, e.getMessage()); - } finally { - if (lock.isHeldByCurrentThread()) { - lock.unlock(); - } - } - }); - if (CollectionUtil.isNotEmpty(lockVOS)) { - throw new DataAlertException(STATE.OutOfStock, lockVOS); - } outAssistanceItemService.updateBatchById(datas); outAssistanceTicketItemService.saveBatch(ticketItems); outAssistanceTicketService.save(ticket); diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutCostCenterController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutCostCenterController.java index 1dea1b9e..c49afff4 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutCostCenterController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutCostCenterController.java @@ -11,7 +11,6 @@ import com.nflg.wms.admin.repository.InventoryForOutRepository; import com.nflg.wms.admin.repository.OutMaterialScanRecordRespository; import com.nflg.wms.admin.service.BasdeSerialNumberControllerService; import com.nflg.wms.admin.service.SapService; -import com.nflg.wms.admin.util.NoUtil; import com.nflg.wms.admin.util.PdfGeneratorUtil; import com.nflg.wms.admin.util.QRCodeUtil; import com.nflg.wms.admin.util.ThymeleafUtil; @@ -108,6 +107,7 @@ public class OutCostCenterController extends BaseController { /** * 保存 + * @return {@link InventoryLockVO} */ @Transactional @PostMapping("save") @@ -121,6 +121,7 @@ public class OutCostCenterController extends BaseController { }); VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(materialNos)) .throwMessage("以下物料的申请数量超出限制:" + StrUtil.join(",", materialNos)); + List lockVOS = new ArrayList<>(); Map> maps = datas.stream().collect(Collectors.groupingBy(DepartmentMaterialRequisitionDTO::getKey1)); maps.forEach((key, items) -> { WmsOutCostcenter order = Convert.convert(WmsOutCostcenter.class, items.get(0)); @@ -130,11 +131,35 @@ public class OutCostCenterController extends BaseController { outCostcenterService.save(order); items.forEach(item -> { WmsOutCostcenterItem data = Convert.convert(WmsOutCostcenterItem.class, item); - data.setLeft(data.getNum()); - data.setOrderId(order.getId()); - outCostcenterItemService.save(data); + RLock lock = redissonClient.getLock(StrUtil.format("lock:inventory:{}:{}:{}", order.getWerks(), data.getLgort(), data.getMatnr())); + try { + // 等待5秒获取锁,10秒后自动释放 + if (lock.tryLock(5, 10, TimeUnit.SECONDS)) { + if (inventoryService.getNumOne(order.getWerks(), data.getLgort(), data.getMatnr()).compareTo(data.getNum()) < 0) { + List itemLocks = inventoryService.getLockList(order.getWerks(), data.getLgort(), data.getMatnr()); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(itemLocks)).throwMessage("库存不足:" + data.getMatnr()); + lockVOS.addAll(itemLocks); + } else { + data.setLeft(data.getNum()); + data.setOrderId(order.getId()); + outCostcenterItemService.save(data); + } + } else { + throw new NflgException(STATE.BusinessError, "获取锁失败"); + } + } catch (Exception e) { + log.error("保存单据出错", e); + throw new NflgException(STATE.BusinessError, e.getMessage()); + } finally { + if (lock.isHeldByCurrentThread()) { + lock.unlock(); + } + } }); }); + if (CollectionUtil.isNotEmpty(lockVOS)) { + throw new DataAlertException(STATE.OutOfStock, lockVOS); + } return ApiResult.success(); } @@ -232,10 +257,10 @@ public class OutCostCenterController extends BaseController { public ApiResult submit(@Valid @RequestBody OutProduceSubmitQO request) { WmsOutCostcenter order = outCostcenterService.lambdaQuery().eq(WmsOutCostcenter::getNo, request.getNo()).one(); VUtil.trueThrowBusinessError(Objects.isNull(order)).throwMessage("订单不存在"); - Set matnrs = request.getItems().stream().map(OutProduceSubmitItemQO::getMaterialNo).collect(Collectors.toSet()); - matnrs.removeAll(request.getRecommendBatch().stream().map(InventoryForOutVO::getMaterialNo).collect(Collectors.toSet())); - VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(matnrs)) - .throwMessage("以下物料无库存,不能出库:" + StrUtil.join(",", matnrs)); +// Set matnrs = request.getItems().stream().map(OutProduceSubmitItemQO::getMaterialNo).collect(Collectors.toSet()); +// matnrs.removeAll(request.getRecommendBatch().stream().map(InventoryForOutVO::getMaterialNo).collect(Collectors.toSet())); +// VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(matnrs)) +// .throwMessage("以下物料无库存,不能出库:" + StrUtil.join(",", matnrs)); WmsOutCostcenterTicket ticket = new WmsOutCostcenterTicket() .setId(IdUtil.getSnowflakeNextId()) .setNo(serialNumberControllerService.generateSerialNumber(15)) @@ -253,7 +278,9 @@ public class OutCostCenterController extends BaseController { .flatMap(Collection::stream) .map(QRCodeQO::getContent) .collect(Collectors.toSet()); - List qrCodeMasters = CollectionUtil.isEmpty(allQrCodes) ? Collections.emptyList() : qrCodeMasterService.lambdaQuery() + List qrCodeMasters = CollectionUtil.isEmpty(allQrCodes) + ? Collections.emptyList() : + qrCodeMasterService.lambdaQuery() .eq(WmsQrCodeMaster::getProcessStage, BarCodeProcessStage.InBound.getState()) .in(WmsQrCodeMaster::getBarcodeCode, allQrCodes) .list(); @@ -348,36 +375,6 @@ public class OutCostCenterController extends BaseController { }); } }); - List lockVOS = new ArrayList<>(); - records.stream() - .collect(Collectors.groupingBy(OutMaterialScanRecord::getKey10)) - .forEach((key, vs) -> { - OutMaterialScanRecord info = vs.get(0); - BigDecimal lockNum = vs.stream().map(OutMaterialScanRecord::getNum).reduce(BigDecimal.ZERO, BigDecimal::add); - RLock lock = redissonClient.getLock(StrUtil.format("lock:inventory:{}:{}:{}", info.getFactoryNo(), info.getWarehouseNo(), info.getMaterialNo())); - try { - // 等待5秒获取锁,10秒后自动释放 - if (lock.tryLock(5, 10, TimeUnit.SECONDS)) { - if (inventoryService.getNumOne(info.getFactoryNo(), info.getWarehouseNo(), info.getMaterialNo()).compareTo(lockNum) < 0) { - List itemLocks = inventoryService.getLockList(info.getFactoryNo(), info.getWarehouseNo(), info.getMaterialNo()); - VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(itemLocks)).throwMessage("库存不足:" + info.getMaterialNo()); - lockVOS.addAll(itemLocks); - } - } else { - throw new NflgException(STATE.BusinessError, "获取锁失败"); - } - } catch (Exception e) { - log.error("保存生产领料单出错", e); - throw new NflgException(STATE.BusinessError, e.getMessage()); - } finally { - if (lock.isHeldByCurrentThread()) { - lock.unlock(); - } - } - }); - if (CollectionUtil.isNotEmpty(lockVOS)) { - throw new DataAlertException(STATE.OutOfStock, lockVOS); - } outCostcenterItemService.updateBatchById(datas); outCostcenterTicketItemService.saveBatch(ticketItems); outCostcenterTicketService.save(ticket); @@ -433,17 +430,17 @@ public class OutCostCenterController extends BaseController { .setFactoryNo(list.get(0).getFactoryNo()) .setWarehouseNo(list.get(0).getWarehouseNo()) .setBinLocation(list.get(0).isQiTao() ? list.get(0).getBinNo() : qrCodeMasters.stream() - .filter(qr -> StrUtil.equals(qr.getBarcodeCode(), list.get(0).getUniqNo())) - .findFirst() - .map(WmsQrCodeMaster::getBinLocation) - .orElse("") + .filter(qr -> StrUtil.equals(qr.getBarcodeCode(), list.get(0).getUniqNo())) + .findFirst() + .map(WmsQrCodeMaster::getBinLocation) + .orElse("") ) .setNum(list.stream().map(OutMaterialScanRecord::getNum).reduce(BigDecimal.ZERO, BigDecimal::add)) ).toList() ); Map> dmaps = records.stream().collect(Collectors.groupingBy(OutMaterialScanRecord::getKey7)); OptRecordDTO optRecordDTO = new OptRecordDTO(); - optRecordDTO.setOperationType((short)1) + optRecordDTO.setOperationType((short) 1) .setOrderId(order.getNo()); optRecordService.add(optRecordDTO); C_MaterialOutboundDTO vo = sapService.ZWM00_MB115(new C_MaterialOutboundQO() diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutProduceController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutProduceController.java index f420eaf0..a5351678 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutProduceController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutProduceController.java @@ -21,7 +21,10 @@ import com.nflg.wms.common.exception.NflgException; import com.nflg.wms.common.pojo.ApiResult; import com.nflg.wms.common.pojo.PageData; import com.nflg.wms.common.pojo.document.OutMaterialScanRecord; -import com.nflg.wms.common.pojo.dto.*; +import com.nflg.wms.common.pojo.dto.InventoryForOutDTO; +import com.nflg.wms.common.pojo.dto.InventoryInDTO; +import com.nflg.wms.common.pojo.dto.InventoryOutDTO; +import com.nflg.wms.common.pojo.dto.OptRecordDTO; import com.nflg.wms.common.pojo.qo.*; import com.nflg.wms.common.pojo.vo.*; import com.nflg.wms.common.util.EecExcelUtil; @@ -46,7 +49,6 @@ import java.io.IOException; import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -384,10 +386,10 @@ public class OutProduceController extends BaseController { public ApiResult submit(@Valid @RequestBody OutProduceSubmitQO request) { WmsOutProduce order = outProduceService.lambdaQuery().eq(WmsOutProduce::getNo, request.getNo()).one(); VUtil.trueThrowBusinessError(Objects.isNull(order)).throwMessage("订单不存在"); - Set matnrs = request.getItems().stream().map(OutProduceSubmitItemQO::getMaterialNo).collect(Collectors.toSet()); - matnrs.removeAll(request.getRecommendBatch().stream().map(InventoryForOutVO::getMaterialNo).collect(Collectors.toSet())); - VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(matnrs)) - .throwMessage("以下物料无库存,不能出库:" + StrUtil.join(",", matnrs)); +// Set matnrs = request.getItems().stream().map(OutProduceSubmitItemQO::getMaterialNo).collect(Collectors.toSet()); +// matnrs.removeAll(request.getRecommendBatch().stream().map(InventoryForOutVO::getMaterialNo).collect(Collectors.toSet())); +// VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(matnrs)) +// .throwMessage("以下物料无库存,不能出库:" + StrUtil.join(",", matnrs)); WmsOutProduceTicket ticket = new WmsOutProduceTicket() .setId(IdUtil.getSnowflakeNextId()) .setNo(serialNumberControllerService.generateSerialNumber(21)) diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/TransferCompanyController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/TransferCompanyController.java index 663112ca..39beb135 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/TransferCompanyController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/TransferCompanyController.java @@ -162,7 +162,7 @@ public class TransferCompanyController extends BaseController { throw new NflgException(STATE.BusinessError, "获取锁失败"); } } catch (Exception e) { - log.error("保存生产领料单出错", e); + log.error("保存出错", e); throw new NflgException(STATE.BusinessError, e.getMessage()); } finally { if (lock.isHeldByCurrentThread()) { @@ -288,10 +288,10 @@ public class TransferCompanyController extends BaseController { public ApiResult submitForOut(@Valid @RequestBody OutProduceSubmitQO request) { WmsTransferCompany order = transferCompanyService.lambdaQuery().eq(WmsTransferCompany::getNo, request.getNo()).one(); VUtil.trueThrowBusinessError(Objects.isNull(order)).throwMessage("转储单不存在"); - Set matnrs = request.getItems().stream().map(OutProduceSubmitItemQO::getMaterialNo).collect(Collectors.toSet()); - matnrs.removeAll(request.getRecommendBatch().stream().map(InventoryForOutVO::getMaterialNo).collect(Collectors.toSet())); - VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(matnrs)) - .throwMessage("以下物料无库存,不能出库:" + StrUtil.join(",", matnrs)); +// Set matnrs = request.getItems().stream().map(OutProduceSubmitItemQO::getMaterialNo).collect(Collectors.toSet()); +// matnrs.removeAll(request.getRecommendBatch().stream().map(InventoryForOutVO::getMaterialNo).collect(Collectors.toSet())); +// VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(matnrs)) +// .throwMessage("以下物料无库存,不能出库:" + StrUtil.join(",", matnrs)); List datas = transferCompanyItemService.getList(order.getId()); List records = new ArrayList<>(); List ticketItems = new ArrayList<>(); diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/TransferFactoryController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/TransferFactoryController.java index 05265cc5..d3c97925 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/TransferFactoryController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/TransferFactoryController.java @@ -160,7 +160,7 @@ public class TransferFactoryController extends BaseController { throw new NflgException(STATE.BusinessError, "获取锁失败"); } } catch (Exception e) { - log.error("保存生产领料单出错", e); + log.error("保存出错", e); throw new NflgException(STATE.BusinessError, e.getMessage()); } finally { if (lock.isHeldByCurrentThread()) { @@ -287,10 +287,10 @@ public class TransferFactoryController extends BaseController { public ApiResult submitForOut(@Valid @RequestBody OutProduceSubmitQO request) { WmsTransferFactory order = transferFactoryService.lambdaQuery().eq(WmsTransferFactory::getNo, request.getNo()).one(); VUtil.trueThrowBusinessError(Objects.isNull(order)).throwMessage("调拨单不存在"); - Set matnrs = request.getItems().stream().map(OutProduceSubmitItemQO::getMaterialNo).collect(Collectors.toSet()); - matnrs.removeAll(request.getRecommendBatch().stream().map(InventoryForOutVO::getMaterialNo).collect(Collectors.toSet())); - VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(matnrs)) - .throwMessage("以下物料无库存,不能出库:" + StrUtil.join(",", matnrs)); +// Set matnrs = request.getItems().stream().map(OutProduceSubmitItemQO::getMaterialNo).collect(Collectors.toSet()); +// matnrs.removeAll(request.getRecommendBatch().stream().map(InventoryForOutVO::getMaterialNo).collect(Collectors.toSet())); +// VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(matnrs)) +// .throwMessage("以下物料无库存,不能出库:" + StrUtil.join(",", matnrs)); List datas = transferFactoryItemService.getList(order.getId()); List records = new ArrayList<>(); WmsTransferFactoryTicket ticket = new WmsTransferFactoryTicket() diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/ComponentPackingControllerService.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/ComponentPackingControllerService.java index 909ef495..2158b1ef 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/ComponentPackingControllerService.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/ComponentPackingControllerService.java @@ -2,27 +2,38 @@ package com.nflg.wms.admin.service; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.nflg.wms.common.constant.STATE; +import com.nflg.wms.common.exception.DataAlertException; +import com.nflg.wms.common.exception.NflgException; import com.nflg.wms.common.pojo.qo.ComponentPackingEditInputQO; import com.nflg.wms.common.pojo.qo.ComponentPackingInputQO; import com.nflg.wms.common.pojo.qo.ComponentPackingItemEditInputQO; +import com.nflg.wms.common.pojo.vo.InventoryLockVO; import com.nflg.wms.common.util.UserUtil; import com.nflg.wms.common.util.VUtil; import com.nflg.wms.repository.entity.WmsComponentPacking; import com.nflg.wms.repository.entity.WmsComponentPackingItem; import com.nflg.wms.repository.service.IWmsComponentPackingItemService; import com.nflg.wms.repository.service.IWmsComponentPackingService; +import com.nflg.wms.repository.service.IWmsInventoryService; import jakarta.annotation.Resource; import jakarta.validation.Valid; -import org.springframework.cloud.commons.util.IdUtils; +import lombok.extern.slf4j.Slf4j; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.concurrent.TimeUnit; +@Slf4j @Component public class ComponentPackingControllerService { @Resource @@ -34,6 +45,12 @@ public class ComponentPackingControllerService { @Resource private BasdeSerialNumberControllerService basdeSerialNumberControllerService; + @Resource + private RedissonClient redissonClient; + + @Resource + private IWmsInventoryService inventoryService; + @Transactional public void savePacking(@Valid ComponentPackingInputQO request) { WmsComponentPacking wmsComponentPacking = new WmsComponentPacking(); @@ -65,32 +82,57 @@ public class ComponentPackingControllerService { wmsComponentPacking.setCreateId(UserUtil.getUserId()); wmsComponentPacking.setCreateTime(LocalDateTime.now()); wmsComponentPacking.setFactoryNo(request.getFactoryNo()); - List wmsComponentPackingItems = request.getItems().stream() - .map(item -> new WmsComponentPackingItem() - .setId(IdUtil.getSnowflakeNextId()) - .setItemIndex(item.getIndex()) - .setVbeln(item.getVbeln()) - .setPosnr(item.getPosnr()) - .setIdnrk(item.getIdnrk()) - .setOjtxb(item.getOjtxb()) - .setMeins(item.getMeins()) - .setMenge(item.getMenge()) - .setAtwrt(item.getAtwrt()) - .setZatwrt(item.getZatwrt()) - .setZxiah(item.getZxiah()) - .setZtext(item.getZtext()) - .setPotx2(item.getPotx2()) - .setPmenge(item.getPmenge()) - .setLgpbe(item.getLgpbe()) - .setLgort(item.getLgort()) - .setLgobe(item.getLgobe()) - .setOutQty(new BigDecimal(0)) - .setPackingId(wmsComponentPacking.getId()) - ).toList(); - + List lockVOS = new ArrayList<>(); + request.getItems().forEach(item -> { + RLock lock = redissonClient.getLock(StrUtil.format("lock:inventory:{}:{}:{}", wmsComponentPacking.getFactoryNo(), item.getLgort(), item.getIdnrk())); + try { + // 等待5秒获取锁,10秒后自动释放 + if (lock.tryLock(5, 10, TimeUnit.SECONDS)) { + if (inventoryService.getNumOne(wmsComponentPacking.getFactoryNo(), item.getLgort(), item.getIdnrk()).compareTo(item.getMenge()) < 0) { + List itemLocks = inventoryService.getLockList(wmsComponentPacking.getFactoryNo(), item.getLgort(), item.getIdnrk()); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(itemLocks)).throwMessage("库存不足:" + item.getIdnrk()); + lockVOS.addAll(itemLocks); + } else { + wmsComponentPackingItemService.save( + new WmsComponentPackingItem() + .setId(IdUtil.getSnowflakeNextId()) + .setItemIndex(item.getIndex()) + .setVbeln(item.getVbeln()) + .setPosnr(item.getPosnr()) + .setIdnrk(item.getIdnrk()) + .setOjtxb(item.getOjtxb()) + .setMeins(item.getMeins()) + .setMenge(item.getMenge()) + .setAtwrt(item.getAtwrt()) + .setZatwrt(item.getZatwrt()) + .setZxiah(item.getZxiah()) + .setZtext(item.getZtext()) + .setPotx2(item.getPotx2()) + .setPmenge(item.getPmenge()) + .setLgpbe(item.getLgpbe()) + .setLgort(item.getLgort()) + .setLgobe(item.getLgobe()) + .setOutQty(new BigDecimal(0)) + .setPackingId(wmsComponentPacking.getId()) + ); + } + } else { + throw new NflgException(STATE.BusinessError, "获取锁失败"); + } + } catch (Exception e) { + log.error("保存单据出错", e); + throw new NflgException(STATE.BusinessError, e.getMessage()); + } finally { + if (lock.isHeldByCurrentThread()) { + lock.unlock(); + } + } + }); + if (CollectionUtil.isNotEmpty(lockVOS)) { + throw new DataAlertException(STATE.OutOfStock, lockVOS); + } // 直接保存 wmscomponentPackingService.save(wmsComponentPacking); - wmsComponentPackingItemService.saveBatch(wmsComponentPackingItems); } @Transactional diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsComponentPacking.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsComponentPacking.java index 5c6e92be..6a27a4b8 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsComponentPacking.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsComponentPacking.java @@ -3,13 +3,13 @@ package com.nflg.wms.repository.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; import lombok.ToString; import lombok.experimental.Accessors; import java.io.Serializable; -import java.time.LocalDate; import java.time.LocalDateTime; /** @@ -157,6 +157,7 @@ public class WmsComponentPacking implements Serializable { /** * 所属工厂 */ + @NotBlank private String factoryNo; /**