gaoluyang
昨天 8c65f898ed6e5b0c7a94c792c4562f6ec831dccd
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java
@@ -20,6 +20,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockFreezeClaimMapper;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
@@ -70,6 +71,8 @@
    @Resource
    private MesWmMaterialStockMapper materialStockMapper;
    @Resource
    private MesWmMaterialStockFreezeClaimMapper freezeClaimMapper;
    @Resource
    private MesMdmItemService mdmItemService;
@@ -152,21 +155,34 @@
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMaterialStockFrozen(MesWmMaterialStockFreezeReqVO updateReqVO) {
        // 校验存在
        validateMaterialStockExists(updateReqVO.getId());
        // 更新冻结状态
        materialStockMapper.updateById(new MesWmMaterialStockDO()
                .setId(updateReqVO.getId()).setFrozen(updateReqVO.getFrozen()));
        setMaterialStockFreeze(List.of(updateReqVO.getId()), "MANUAL", 0L, updateReqVO.getFrozen());
    }
    @Override
    public void updateMaterialStockFrozen(Collection<Long> ids, boolean frozen) {
    @Transactional(rollbackFor = Exception.class)
    public void setMaterialStockFreeze(Collection<Long> ids, String sourceType, Long sourceId, boolean frozen) {
        if (CollUtil.isEmpty(ids)) {
            return;
        }
        materialStockMapper.updateByIds(ids, new MesWmMaterialStockDO().setFrozen(frozen));
        // 按 ID 固定顺序加锁,避免两个任务同时冻结相同库存时产生锁顺序反转。
        for (Long stockId : ids.stream().filter(Objects::nonNull).distinct().sorted().toList()) {
            MesWmMaterialStockDO stock = materialStockMapper.lockById(stockId);
            if (stock == null) {
                throw exception(WM_MATERIAL_STOCK_NOT_EXISTS);
            }
            if (frozen) {
                freezeClaimMapper.acquire(stockId, sourceType, sourceId);
            } else {
                freezeClaimMapper.release(stockId, sourceType, sourceId);
            }
            boolean effectiveFrozen = freezeClaimMapper.countByStockId(stockId) > 0;
            if (!Objects.equals(stock.getFrozen(), effectiveFrozen)) {
                materialStockMapper.updateById(new MesWmMaterialStockDO()
                        .setId(stockId).setFrozen(effectiveFrozen));
            }
        }
    }
    @Override