自动化立体仓库 - WMS系统
zwl
3 天以前 b0877a3275ed5bc96fb80f84949904e149946cf2
src/main/java/com/zy/asrs/service/impl/ExternalTaskFacadeServiceImpl.java
@@ -4,7 +4,7 @@
import com.core.common.Cools;
import com.core.common.R;
import com.zy.asrs.entity.param.MesToCombParam;
import com.zy.asrs.entity.param.OpenOrderPakoutPauseParam;
import com.zy.asrs.entity.param.OpenOrderPakoutExecuteParam;
import com.zy.asrs.entity.param.OutTaskParam;
import com.zy.asrs.service.ExternalTaskFacadeService;
import com.zy.asrs.service.LocDetlService;
@@ -14,6 +14,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Objects;
/**
@@ -65,7 +66,17 @@
    }
    /**
     * 复用现有出库建单逻辑;当 autoConfirm=true 时,继续调用原有确认接口自动放行。
     * 复用统一出库订单化逻辑。
     *
     * MQTT/IoT 入口不再绕过订单直接生成 WrkMast:
     * - autoConfirm=false:只创建 status=0 的订单,等待外部调用执行接口;
     * - autoConfirm=true:创建订单后立即走执行逻辑,生成当前批次任务并确认可下发。
     *
     * 这样做是为了让 HTTP /outOrder 和 MQTT/IoT 直调共享同一套:
     * - 订单明细保存字段;
     * - 批次键计算;
     * - 中止取消和 work_qty 回滚;
     * - pdcType 放行。
     */
    @Override
    public R createOutboundTask(OutTaskParam param, boolean autoConfirm) {
@@ -83,26 +94,45 @@
        }
        int countLoc = locDetlService.selectCount(new EntityWrapper<com.zy.asrs.entity.LocDetl>().eq("zpallet", param.getPalletId()));
        if (countLoc == 0) {
            return R.error("库存中不存在该托盘");
            return R.error("库存中不存在该托盘:" + param.getPalletId());
        }
        if (param.getSeq() == null) {
            param.setSeq(1);
            // 设备直调通常是单托盘出库,没有 ERP 顺序号;0 表示无序,和 /outOrder 的校验语义一致。
            param.setSeq(0);
        }
        if (Cools.isEmpty(param.getBatchSeq())) {
            // batchSeq 是接口原始字段,明细里会保存;实际生成任务时低站点仍按 orderId 作为批次键。
            param.setBatchSeq(param.getOrderId());
        }
        if (isHighStation(param.getStationId()) && Cools.isEmpty(param.getEntryWmsCode())) {
            // IoT 直调常见为单托盘任务,没有 ERP 进仓编号;用 orderId 作为批次键,
            // 这样既满足高站点订单明细校验,也能让执行后 WrkMast.batchSeq 保持可追溯。
            param.setEntryWmsCode(param.getOrderId());
        }
        R result = openService.outOrder(param, 1);
        if (!Objects.equals(result.get("code"), 200) || !autoConfirm) {
            return result;
        // IoT/MQTT 默认只预创建订单,status=0 不会被定时器扫描。
        // 只有 autoConfirm=true 或外部后续调用执行接口时,才会把 status 恢复为 1 并生成任务。
        R orderResult = openService.outOrderCreatePakoutOrder(Collections.singletonList(param), false);
        if (!Objects.equals(orderResult.get("code"), 200) || !autoConfirm) {
            return orderResult;
        }
        // IoT pick 约定为“收到即执行”,因此这里直接复用原有确认放行接口。
        OpenOrderPakoutPauseParam executeParam = new OpenOrderPakoutPauseParam();
        // IoT pick 约定为“收到即执行”,因此建单后直接复用公开执行接口的服务逻辑。
        OpenOrderPakoutExecuteParam executeParam = new OpenOrderPakoutExecuteParam();
        executeParam.setOrderId(param.getOrderId());
        executeParam.setExecute(1);
        R confirmResult = openService.pakoutOrderPause(executeParam);
        if (result.get("wrkNo") != null) {
            confirmResult.add(Cools.add("wrkNo", result.get("wrkNo")));
        return openService.pakoutOrderExecute(executeParam);
    }
    private boolean isHighStation(String stationId) {
        if (Cools.isEmpty(stationId)) {
            return false;
        }
        return confirmResult;
        try {
            return Integer.valueOf(stationId) > 600;
        } catch (NumberFormatException ignored) {
            return false;
        }
    }
}