自动化立体仓库 - WMS系统
zwl
2 天以前 18c48be67ec6b0b02e954203d0b2bd3f41b1fd0b
src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java
@@ -23,12 +23,15 @@
import com.zy.common.model.StartupDto;
import com.zy.common.service.CommonService;
import com.zy.common.utils.HttpHandler;
import com.zy.common.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import java.io.IOException;
import java.math.BigDecimal;
@@ -48,6 +51,8 @@
    /** 三方接口统计:本系统调用 WCS 的 namespace 约定 */
    private static final String NS_WMS_TO_WCS = "本系统请求WCS";
    private static final String REASSIGN_CRN_LOCK_KEY_PREFIX = "wcs:reassign:inbound:crn:";
    private static final long REASSIGN_CRN_LOCK_SECONDS = 180L;
    @Autowired
    private LocMastService locMastService;
@@ -96,6 +101,8 @@
    private ApiLogService apiLogService;
    @Autowired
    private RowLastnoService rowLastnoService;
    @Autowired
    private RedisUtil redisUtil;
    /**
@@ -663,6 +670,7 @@
        updateReassignTargetLoc(targetLoc, wrkMast, currentLoc, now);
        updateReassignWorkMast(wrkMast, startupDto, now);
        releaseOldReservedLocIfNeeded(currentLoc, targetLoc.getLocNo(), now);
        lockReassignedCrnAfterCommit(preferredArea, targetLoc.getCrnNo(), wrkMast.getWrkNo());
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("locNo", Utils.WMSLocToWCSLoc(targetLoc.getLocNo()));
@@ -779,12 +787,21 @@
        }
        List<Integer> candidateCrnNos = new ArrayList<>();
        for (int crnNo = currentCrnNo - 1; crnNo >= startCrnNo; crnNo--) {
            candidateCrnNos.add(crnNo);
            addUnlockedReassignCandidate(candidateCrnNos, area, crnNo);
        }
        for (int crnNo = endCrnNo; crnNo > currentCrnNo; crnNo--) {
            candidateCrnNos.add(crnNo);
            addUnlockedReassignCandidate(candidateCrnNos, area, crnNo);
        }
        return candidateCrnNos;
    }
    private void addUnlockedReassignCandidate(List<Integer> candidateCrnNos, Integer area, int crnNo) {
        if (isReassignCrnLocked(area, crnNo)) {
            log.info("skip locked reassign crane. area={}, crnNo={}, ttl={}s",
                    area, crnNo, redisUtil.getExpire(buildReassignCrnLockKey(area, crnNo)));
            return;
        }
        candidateCrnNos.add(crnNo);
    }
    private int resolveAreaStartCrnNo(RowLastno areaRowLastno) {
@@ -871,6 +888,43 @@
        }
    }
    private boolean isReassignCrnLocked(Integer area, Integer crnNo) {
        if (area == null || crnNo == null) {
            return false;
        }
        return redisUtil.hasKey(buildReassignCrnLockKey(area, crnNo));
    }
    private String buildReassignCrnLockKey(Integer area, Integer crnNo) {
        return REASSIGN_CRN_LOCK_KEY_PREFIX + area + ":" + crnNo;
    }
    private void lockReassignedCrnAfterCommit(Integer area, Integer crnNo, Integer wrkNo) {
        if (area == null || crnNo == null) {
            return;
        }
        Runnable action = () -> {
            String key = buildReassignCrnLockKey(area, crnNo);
            boolean locked = redisUtil.set(key, String.valueOf(wrkNo), REASSIGN_CRN_LOCK_SECONDS);
            if (!locked) {
                log.warn("failed to lock reassigned crane in redis. area={}, crnNo={}, wrkNo={}", area, crnNo, wrkNo);
                return;
            }
            log.info("locked reassigned crane in redis. area={}, crnNo={}, wrkNo={}, ttl={}s",
                    area, crnNo, wrkNo, REASSIGN_CRN_LOCK_SECONDS);
        };
        if (TransactionSynchronizationManager.isActualTransactionActive()) {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
                @Override
                public void afterCommit() {
                    action.run();
                }
            });
            return;
        }
        action.run();
    }
    /**
     * 按任务类型选择 WCS 接口地址。
     * in -> 入库接口