#
Junjie
昨天 bc25276b90cf8256bbe37126120d66d9142c9c29
#
6个文件已添加
8个文件已修改
1216 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/ConsoleController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/StationLatestDataVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/plugin/FakeProcess.java 164 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/plugin/GslProcess.java 191 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/plugin/NormalProcess.java 135 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/plugin/XiaosongProcess.java 172 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/plugin/store/AsyncInTaskResult.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/plugin/store/AsyncInTaskStatus.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/plugin/store/InTaskApplyRequest.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/plugin/store/StoreInTaskContext.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/plugin/store/StoreInTaskGenerationService.java 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/plugin/store/StoreInTaskPolicy.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/utils/WmsOperateUtils.java 197 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/components/DevpCard.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ConsoleController.java
@@ -133,6 +133,7 @@
                vo.setError(stationProtocol.getError()); // 错误码
                vo.setErrorMsg(stationProtocol.getErrorMsg()); // 报警信息
                vo.setBarcode(stationProtocol.getBarcode()); // 条码
                vo.setSystemWarning(stationProtocol.getSystemWarning()); // 系统告警/业务提示
                vo.setWeight(stationProtocol.getWeight());//重量
                vo.setTaskWriteIdx(stationProtocol.getTaskWriteIdx());//任务可写区
                String stationStatus = StationStatusType.process(stationProtocol).toString().toLowerCase().replaceAll("_", "-");
src/main/java/com/zy/asrs/domain/vo/StationLatestDataVo.java
@@ -52,6 +52,9 @@
    private String stationStatus;
    //系统告警/业务提示
    private String systemWarning;
    //重量
    private Double weight;
src/main/java/com/zy/core/plugin/FakeProcess.java
@@ -25,6 +25,9 @@
import com.zy.core.model.protocol.DualCrnProtocol;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.plugin.api.MainProcessPluginApi;
import com.zy.core.plugin.store.StoreInTaskContext;
import com.zy.core.plugin.store.StoreInTaskGenerationService;
import com.zy.core.plugin.store.StoreInTaskPolicy;
import com.zy.core.properties.SystemProperties;
import com.zy.core.thread.CrnThread;
import com.zy.core.thread.DualCrnThread;
@@ -49,7 +52,7 @@
@Slf4j
@Component
public class FakeProcess implements MainProcessPluginApi {
public class FakeProcess implements MainProcessPluginApi, StoreInTaskPolicy {
    private static final long METHOD_TIMEOUT_MS = 15000; // 15秒超时
    private static final ExecutorService timeoutExecutor = Executors.newCachedThreadPool();
@@ -86,6 +89,8 @@
    private WmsOperateUtils wmsOperateUtils;
    @Autowired
    private DualCrnOperateProcessUtils dualCrnOperateProcessUtils;
    @Autowired
    private StoreInTaskGenerationService storeInTaskGenerationService;
    /**
     * 带超时保护执行方法
@@ -425,141 +430,38 @@
     * 入库站,根据条码扫描生成入库工作档
     */
    public synchronized void generateStoreWrkFile() {
        try {
            if (fakeRealTaskRequestWms.equals("N")) {
                return;
            }
        storeInTaskGenerationService.generate(this);
    }
            Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
            if (systemConfigMapObj == null) {
                return;
            }
            HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
    @Override
    public boolean isEnabled() {
        return !"N".equals(fakeRealTaskRequestWms);
    }
            int conveyorStationTaskLimit = 30;
            String conveyorStationTaskLimitStr = systemConfigMap.get("conveyorStationTaskLimit");
            if (conveyorStationTaskLimitStr != null) {
                conveyorStationTaskLimit = Integer.parseInt(conveyorStationTaskLimitStr);
            }
            int currentStationTaskCount = stationOperateProcessUtils.getCurrentStationTaskCount();
            if (currentStationTaskCount > conveyorStationTaskLimit) {
                News.error("输送站点任务已达到上限,上限值:{},站点任务数:{}", conveyorStationTaskLimit, currentStationTaskCount);
                return;
            }
    @Override
    public boolean matchCandidate(StoreInTaskContext context) {
        StationProtocol stationProtocol = context.getStationProtocol();
        return stationProtocol.isAutoing()
                && stationProtocol.isLoading()
                && stationProtocol.getTaskNo() > 0
                && !Cools.isEmpty(stationProtocol.getBarcode());
    }
            List<BasDevp> basDevps = basDevpService.list(new QueryWrapper<>());
            for (BasDevp basDevp : basDevps) {
                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
                if (stationThread == null) {
                    continue;
                }
    @Override
    public void onRequestPermitGranted(StoreInTaskContext context) {
        redisUtil.set(getGenerateLockKey(context), "lock", 3);
    }
                Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
                List<StationObjModel> list = basDevp.getBarcodeStationList$();
                for (StationObjModel entity : list) {
                    Integer stationId = entity.getStationId();
                    if (!stationMap.containsKey(stationId)) {
                        continue;
                    }
                    StationProtocol stationProtocol = stationMap.get(stationId);
                    if (stationProtocol == null) {
                        continue;
                    }
                    // 满足自动、有物、有工作号,生成入库数据
                    if (stationProtocol.isAutoing()
                            && stationProtocol.isLoading()
                            && stationProtocol.getTaskNo() > 0) {
                        if (Cools.isEmpty(stationProtocol.getBarcode())) {
                            continue;
                        }
                        // 检测任务是否生成
                        List<WrkMast> wrkMasts = wrkMastService
                                .list(new QueryWrapper<WrkMast>()
                                        .eq("barcode", stationProtocol.getBarcode()));
                        if (!wrkMasts.isEmpty()) {
                            continue;
                        }
                        Object lock = redisUtil.get(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId);
                        if (lock != null) {
                            continue;
                        }
                        redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 3);
                        String barcode = stationProtocol.getBarcode();
                        Integer stationIdVal = stationProtocol.getStationId();
                        Integer taskNo = stationProtocol.getTaskNo();
                        // 1. 首先查询是否有已完成的异步响应
                        String response = wmsOperateUtils.queryAsyncInTaskResponse(barcode, stationIdVal, taskNo);
                        if (!Cools.isEmpty(response)) {
                            // 2. 有响应结果,处理响应
                            if (response.equals("FAILED") || response.startsWith("ERROR:")) {
                                // 请求失败,重新发起异步请求
                                News.error("WMS入库请求失败,重新发起请求,barcode={},stationId={},response={}", barcode,
                                        stationIdVal, response);
                                wmsOperateUtils.applyInTaskAsync(barcode, stationIdVal, taskNo,
                                        stationProtocol.getPalletHeight());
                                redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                                stationProtocol.setSystemWarning("请求入库失败,WMS返回=" + response);
                                continue;
                            }
                            // 解析响应
                            JSONObject jsonObject = JSON.parseObject(response);
                            if (jsonObject.getInteger("code").equals(200)) {
                                StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                                CreateInTaskParam taskParam = new CreateInTaskParam();
                                taskParam.setTaskNo(dto.getTaskNo());
                                taskParam.setLocNo(dto.getLocNo());
                                taskParam.setTaskPri(dto.getTaskPri());
                                taskParam.setBarcode(barcode);
                                WrkMast wrkMast = commonService.createInTask(taskParam);
                                StationCommand command = stationThread.getCommand(StationCommandType.WRITE_INFO,
                                        wrkMast.getWrkNo(), stationId, stationId, 0);
                                if (command == null) {
                                    News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败");
                                    continue;
                                }
                                MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command));
                                stationProtocol.setSystemWarning("");
                            } else {
                                // 接口返回非200,重新发起请求
                                News.error("WMS入库接口返回非200,重新发起请求,barcode={},stationId={},response={}", barcode,
                                        stationIdVal, response);
                                wmsOperateUtils.applyInTaskAsync(barcode, stationIdVal, taskNo,
                                        stationProtocol.getPalletHeight());
                                redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                                stationProtocol.setSystemWarning("请求入库失败,WMS返回=" + response);
                            }
                        } else {
                            // 3. 没有响应结果,检查是否有请求正在进行中
                            if (!wmsOperateUtils.isAsyncRequestInProgress(barcode, stationIdVal, taskNo)) {
                                // 没有请求进行中,发起新的异步请求
                                News.info("发起异步WMS入库请求,barcode={},stationId={}", barcode, stationIdVal);
                                wmsOperateUtils.applyInTaskAsync(barcode, stationIdVal, taskNo,
                                        stationProtocol.getPalletHeight());
                                redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                                stationProtocol.setSystemWarning("请求入库失败,WMS无返回");
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
    @Override
    public void afterTaskCreated(StoreInTaskContext context, WrkMast wrkMast) {
        Integer stationId = context.getStationObjModel().getStationId();
        StationCommand command = context.getStationThread().getCommand(StationCommandType.WRITE_INFO,
                wrkMast.getWrkNo(), stationId, stationId, 0);
        if (command == null) {
            News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败");
            return;
        }
        MessageQueue.offer(SlaveType.Devp, context.getBasDevp().getDevpNo(), new Task(2, command));
    }
    // 计算所有站点停留时间
src/main/java/com/zy/core/plugin/GslProcess.java
@@ -1,15 +1,10 @@
package com.zy.core.plugin;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.common.Cools;
import com.zy.asrs.domain.param.CreateInTaskParam;
import com.zy.asrs.entity.BasDevp;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.BasDevpService;
import com.zy.asrs.service.WrkMastService;
import com.zy.common.model.StartupDto;
import com.zy.common.service.CommonService;
import com.zy.common.utils.RedisUtil;
import com.zy.core.News;
@@ -24,21 +19,23 @@
import com.zy.core.model.command.StationCommand;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.plugin.api.MainProcessPluginApi;
import com.zy.core.plugin.store.InTaskApplyRequest;
import com.zy.core.plugin.store.StoreInTaskContext;
import com.zy.core.plugin.store.StoreInTaskGenerationService;
import com.zy.core.plugin.store.StoreInTaskPolicy;
import com.zy.core.thread.StationThread;
import com.zy.core.utils.CrnOperateProcessUtils;
import com.zy.core.utils.StationOperateProcessUtils;
import com.zy.core.utils.WmsOperateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Component
public class GslProcess implements MainProcessPluginApi {
public class GslProcess implements MainProcessPluginApi, StoreInTaskPolicy {
    @Autowired
    private CrnOperateProcessUtils crnOperateUtils;
@@ -49,11 +46,9 @@
    @Autowired
    private BasDevpService basDevpService;
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private WmsOperateUtils wmsOperateUtils;
    private StoreInTaskGenerationService storeInTaskGenerationService;
    @Override
    public void run() {
@@ -90,141 +85,51 @@
     * 入库站,根据条码扫描生成入库工作档
     */
    public synchronized void generateStoreWrkFile() {
        try {
            Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
            if (systemConfigMapObj == null) {
                return;
            }
            HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
        storeInTaskGenerationService.generate(this);
    }
            int conveyorStationTaskLimit = 30;
            String conveyorStationTaskLimitStr = systemConfigMap.get("conveyorStationTaskLimit");
            if (conveyorStationTaskLimitStr != null) {
                conveyorStationTaskLimit = Integer.parseInt(conveyorStationTaskLimitStr);
            }
            int currentStationTaskCount = stationOperateProcessUtils.getCurrentStationTaskCount();
            if (currentStationTaskCount > conveyorStationTaskLimit) {
                News.error("输送站点任务已达到上限,上限值:{},站点任务数:{}", conveyorStationTaskLimit, currentStationTaskCount);
                return;
            }
    @Override
    public boolean matchCandidate(StoreInTaskContext context) {
        StationProtocol stationProtocol = context.getStationProtocol();
        return stationProtocol.isAutoing()
                && stationProtocol.isLoading()
                && stationProtocol.isInEnable()
                && stationProtocol.getTaskNo() > 0
                && !Cools.isEmpty(stationProtocol.getBarcode());
    }
            List<BasDevp> basDevps = basDevpService.list(new QueryWrapper<>());
            for (BasDevp basDevp : basDevps) {
                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
                if (stationThread == null) {
                    continue;
                }
                Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
                List<StationObjModel> list = basDevp.getBarcodeStationList$();
                for (StationObjModel entity : list) {
                    Integer stationId = entity.getStationId();
                    if (!stationMap.containsKey(stationId)) {
                        continue;
                    }
                    StationProtocol stationProtocol = stationMap.get(stationId);
                    if (stationProtocol == null) {
                        continue;
                    }
                    // 满足自动、有物、有工作号,生成入库数据
                    if (stationProtocol.isAutoing()
                            && stationProtocol.isLoading()
                            && stationProtocol.isInEnable()
                            && stationProtocol.getTaskNo() > 0) {
                        if (Cools.isEmpty(stationProtocol.getBarcode())) {
                            continue;
                        }
                        if (stationProtocol.getError() > 0) {
                            Object lock = redisUtil.get(RedisKeyType.GENERATE_STATION_BACK_LIMIT.key + stationProtocol.getStationId());
                            if (lock != null) {
                                continue;
                            }
                            StationObjModel backStation = entity.getBackStation();
                            StationCommand command = stationThread.getCommand(StationCommandType.MOVE, commonService.getWorkNo(WrkIoType.STATION_BACK.id), stationId, backStation.getStationId(), 0);
                            if (command == null) {
                                News.taskInfo(stationProtocol.getTaskNo(), "{}工作,获取输送线命令失败", stationProtocol.getTaskNo());
                                continue;
                            }
                            MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command));
                            News.taskInfo(stationProtocol.getTaskNo(), "{}扫码异常,已退回至{}", backStation.getStationId());
                            redisUtil.set(RedisKeyType.GENERATE_STATION_BACK_LIMIT.key + stationProtocol.getStationId(), "lock", 10);
                        }
                        // 检测任务是否生成
                        List<WrkMast> wrkMasts = wrkMastService
                                .list(new QueryWrapper<WrkMast>()
                                        .eq("barcode", stationProtocol.getBarcode()));
                        if (!wrkMasts.isEmpty()) {
                            continue;
                        }
                        Object lock = redisUtil.get(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId);
                        if (lock != null) {
                            continue;
                        }
                        String barcode = stationProtocol.getBarcode();
                        Integer stationIdVal = stationProtocol.getStationId();
                        Integer taskNo = stationProtocol.getTaskNo();
                        // 1. 首先查询是否有已完成的异步响应
                        String response = wmsOperateUtils.queryAsyncInTaskResponse(barcode, stationIdVal, taskNo);
                        if (!Cools.isEmpty(response)) {
                            // 2. 有响应结果,处理响应
                            if (response.equals("FAILED") || response.startsWith("ERROR:")) {
                                // 请求失败,重新发起异步请求
                                News.error("WMS入库请求失败,重新发起请求,barcode={},stationId={},response={}", barcode,
                                        stationIdVal, response);
                                wmsOperateUtils.applyInTaskAsync(barcode, stationIdVal, taskNo,
                                        stationProtocol.getPalletHeight());
                                redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                                stationProtocol.setSystemWarning("请求入库失败,WMS返回=" + response);
                                continue;
                            }
                            // 解析响应
                            JSONObject jsonObject = JSON.parseObject(response);
                            if (jsonObject.getInteger("code").equals(200)) {
                                StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                                CreateInTaskParam taskParam = new CreateInTaskParam();
                                taskParam.setTaskNo(dto.getTaskNo());
                                taskParam.setLocNo(dto.getLocNo());
                                taskParam.setTaskPri(dto.getTaskPri());
                                taskParam.setBarcode(barcode);
                                WrkMast wrkMast = commonService.createInTask(taskParam);
                                stationProtocol.setSystemWarning("");
                            } else {
                                // 接口返回非200,重新发起请求
                                News.error("WMS入库接口返回非200,重新发起请求,barcode={},stationId={},response={}", barcode,
                                        stationIdVal, response);
                                wmsOperateUtils.applyInTaskAsync(barcode, stationIdVal, taskNo,
                                        stationProtocol.getPalletHeight());
                                redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                                stationProtocol.setSystemWarning("请求入库失败,WMS返回=" + response);
                            }
                        } else {
                            // 3. 没有响应结果,检查是否有请求正在进行中
                            if (!wmsOperateUtils.isAsyncRequestInProgress(barcode, stationIdVal, taskNo)) {
                                // 没有请求进行中,发起新的异步请求
                                News.info("发起异步WMS入库请求,barcode={},stationId={}", barcode, stationIdVal);
                                wmsOperateUtils.applyInTaskAsync(barcode, stationIdVal, taskNo,
                                        stationProtocol.getPalletHeight());
                                redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                                stationProtocol.setSystemWarning("请求入库失败,WMS无返回");
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
    @Override
    public boolean beforeApply(StoreInTaskContext context) {
        StationProtocol stationProtocol = context.getStationProtocol();
        if (stationProtocol.getError() <= 0) {
            return true;
        }
        Object lock = redisUtil.get(RedisKeyType.GENERATE_STATION_BACK_LIMIT.key + stationProtocol.getStationId());
        if (lock != null) {
            return false;
        }
        StationObjModel backStation = context.getStationObjModel().getBackStation();
        StationCommand command = context.getStationThread().getCommand(StationCommandType.MOVE,
                commonService.getWorkNo(WrkIoType.STATION_BACK.id),
                context.getStationObjModel().getStationId(),
                backStation.getStationId(), 0);
        if (command == null) {
            News.taskInfo(stationProtocol.getTaskNo(), "{}工作,获取输送线命令失败", stationProtocol.getTaskNo());
            return false;
        }
        MessageQueue.offer(SlaveType.Devp, context.getBasDevp().getDevpNo(), new Task(2, command));
        News.taskInfo(stationProtocol.getTaskNo(), "{}扫码异常,已退回至{}", backStation.getStationId());
        redisUtil.set(RedisKeyType.GENERATE_STATION_BACK_LIMIT.key + stationProtocol.getStationId(), "lock", 10);
        return true;
    }
    @Override
    public InTaskApplyRequest buildApplyRequest(StoreInTaskContext context) {
        InTaskApplyRequest request = StoreInTaskPolicy.super.buildApplyRequest(context);
        request.getExtraParams().put("weight", context.getStationProtocol().getWeight());
        return request;
    }
    //检测入库站是否有任务生成,并启动入库
src/main/java/com/zy/core/plugin/NormalProcess.java
@@ -24,6 +24,9 @@
import com.zy.core.model.command.StationCommand;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.plugin.api.MainProcessPluginApi;
import com.zy.core.plugin.store.StoreInTaskContext;
import com.zy.core.plugin.store.StoreInTaskGenerationService;
import com.zy.core.plugin.store.StoreInTaskPolicy;
import com.zy.core.thread.StationThread;
import com.zy.core.utils.CrnOperateProcessUtils;
import com.zy.core.utils.StationOperateProcessUtils;
@@ -38,7 +41,7 @@
@Slf4j
@Component
public class NormalProcess implements MainProcessPluginApi {
public class NormalProcess implements MainProcessPluginApi, StoreInTaskPolicy {
    @Autowired
    private CrnOperateProcessUtils crnOperateUtils;
@@ -54,6 +57,8 @@
    private RedisUtil redisUtil;
    @Autowired
    private WmsOperateUtils wmsOperateUtils;
    @Autowired
    private StoreInTaskGenerationService storeInTaskGenerationService;
    @Override
    public void run() {
@@ -84,125 +89,17 @@
     * 入库站,根据条码扫描生成入库工作档
     */
    public synchronized void generateStoreWrkFile() {
        try {
            Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
            if (systemConfigMapObj == null) {
                return;
            }
            HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
        storeInTaskGenerationService.generate(this);
    }
            int conveyorStationTaskLimit = 30;
            String conveyorStationTaskLimitStr = systemConfigMap.get("conveyorStationTaskLimit");
            if (conveyorStationTaskLimitStr != null) {
                conveyorStationTaskLimit = Integer.parseInt(conveyorStationTaskLimitStr);
            }
            int currentStationTaskCount = stationOperateProcessUtils.getCurrentStationTaskCount();
            if (currentStationTaskCount > conveyorStationTaskLimit) {
                News.error("输送站点任务已达到上限,上限值:{},站点任务数:{}", conveyorStationTaskLimit, currentStationTaskCount);
                return;
            }
            List<BasDevp> basDevps = basDevpService.list(new QueryWrapper<>());
            for (BasDevp basDevp : basDevps) {
                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
                if (stationThread == null) {
                    continue;
                }
                Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
                List<StationObjModel> list = basDevp.getBarcodeStationList$();
                for (StationObjModel entity : list) {
                    Integer stationId = entity.getStationId();
                    if (!stationMap.containsKey(stationId)) {
                        continue;
                    }
                    StationProtocol stationProtocol = stationMap.get(stationId);
                    if (stationProtocol == null) {
                        continue;
                    }
                    // 满足自动、有物、有工作号,生成入库数据
                    if (stationProtocol.isAutoing()
                            && stationProtocol.isLoading()
                            && stationProtocol.isInEnable()
                            && stationProtocol.getTaskNo() > 0) {
                        if (Cools.isEmpty(stationProtocol.getBarcode())) {
                            continue;
                        }
                        // 检测任务是否生成
                        List<WrkMast> wrkMasts = wrkMastService
                                .list(new QueryWrapper<WrkMast>()
                                        .eq("barcode", stationProtocol.getBarcode()));
                        if (!wrkMasts.isEmpty()) {
                            continue;
                        }
                        Object lock = redisUtil.get(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId);
                        if (lock != null) {
                            continue;
                        }
                        String barcode = stationProtocol.getBarcode();
                        Integer stationIdVal = stationProtocol.getStationId();
                        Integer taskNo = stationProtocol.getTaskNo();
                        // 1. 首先查询是否有已完成的异步响应
                        String response = wmsOperateUtils.queryAsyncInTaskResponse(barcode, stationIdVal, taskNo);
                        if (!Cools.isEmpty(response)) {
                            // 2. 有响应结果,处理响应
                            if (response.equals("FAILED") || response.startsWith("ERROR:")) {
                                // 请求失败,重新发起异步请求
                                News.error("WMS入库请求失败,重新发起请求,barcode={},stationId={},response={}", barcode,
                                        stationIdVal, response);
                                wmsOperateUtils.applyInTaskAsync(barcode, stationIdVal, taskNo,
                                        stationProtocol.getPalletHeight());
                                redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                                stationProtocol.setSystemWarning("请求入库失败,WMS返回=" + response);
                                continue;
                            }
                            // 解析响应
                            JSONObject jsonObject = JSON.parseObject(response);
                            if (jsonObject.getInteger("code").equals(200)) {
                                StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                                CreateInTaskParam taskParam = new CreateInTaskParam();
                                taskParam.setTaskNo(dto.getTaskNo());
                                taskParam.setLocNo(dto.getLocNo());
                                taskParam.setTaskPri(dto.getTaskPri());
                                taskParam.setBarcode(barcode);
                                WrkMast wrkMast = commonService.createInTask(taskParam);
                                stationProtocol.setSystemWarning("");
                            } else {
                                // 接口返回非200,重新发起请求
                                News.error("WMS入库接口返回非200,重新发起请求,barcode={},stationId={},response={}", barcode,
                                        stationIdVal, response);
                                wmsOperateUtils.applyInTaskAsync(barcode, stationIdVal, taskNo,
                                        stationProtocol.getPalletHeight());
                                redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                                stationProtocol.setSystemWarning("请求入库失败,WMS返回=" + response);
                            }
                        } else {
                            // 3. 没有响应结果,检查是否有请求正在进行中
                            if (!wmsOperateUtils.isAsyncRequestInProgress(barcode, stationIdVal, taskNo)) {
                                // 没有请求进行中,发起新的异步请求
                                News.info("发起异步WMS入库请求,barcode={},stationId={}", barcode, stationIdVal);
                                wmsOperateUtils.applyInTaskAsync(barcode, stationIdVal, taskNo,
                                        stationProtocol.getPalletHeight());
                                redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                                stationProtocol.setSystemWarning("请求入库失败,WMS无返回");
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    @Override
    public boolean matchCandidate(StoreInTaskContext context) {
        StationProtocol stationProtocol = context.getStationProtocol();
        return stationProtocol.isAutoing()
                && stationProtocol.isLoading()
                && stationProtocol.isInEnable()
                && stationProtocol.getTaskNo() > 0
                && !Cools.isEmpty(stationProtocol.getBarcode());
    }
    //检测入库站是否有任务生成,并启动入库
src/main/java/com/zy/core/plugin/XiaosongProcess.java
@@ -24,6 +24,9 @@
import com.zy.core.model.command.StationCommand;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.plugin.api.MainProcessPluginApi;
import com.zy.core.plugin.store.StoreInTaskContext;
import com.zy.core.plugin.store.StoreInTaskGenerationService;
import com.zy.core.plugin.store.StoreInTaskPolicy;
import com.zy.core.thread.StationThread;
import com.zy.core.utils.CrnOperateProcessUtils;
import com.zy.core.utils.DualCrnOperateProcessUtils;
@@ -39,7 +42,7 @@
@Slf4j
@Component
public class XiaosongProcess implements MainProcessPluginApi {
public class XiaosongProcess implements MainProcessPluginApi, StoreInTaskPolicy {
    @Autowired
    private CrnOperateProcessUtils crnOperateUtils;
@@ -57,6 +60,8 @@
    private WmsOperateUtils wmsOperateUtils;
    @Autowired
    private DualCrnOperateProcessUtils dualCrnOperateProcessUtils;
    @Autowired
    private StoreInTaskGenerationService storeInTaskGenerationService;
    @Override
    public void run() {
@@ -96,140 +101,43 @@
     * 入库站,根据条码扫描生成入库工作档
     */
    public synchronized void generateStoreWrkFile() {
        try {
            Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
            if (systemConfigMapObj == null) {
                return;
            }
            HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
        storeInTaskGenerationService.generate(this);
    }
            int conveyorStationTaskLimit = 30;
            String conveyorStationTaskLimitStr = systemConfigMap.get("conveyorStationTaskLimit");
            if (conveyorStationTaskLimitStr != null) {
                conveyorStationTaskLimit = Integer.parseInt(conveyorStationTaskLimitStr);
            }
            int currentStationTaskCount = stationOperateProcessUtils.getCurrentStationTaskCount();
            if (currentStationTaskCount > conveyorStationTaskLimit) {
                News.error("输送站点任务已达到上限,上限值:{},站点任务数:{}", conveyorStationTaskLimit, currentStationTaskCount);
                return;
            }
    @Override
    public boolean matchCandidate(StoreInTaskContext context) {
        StationProtocol stationProtocol = context.getStationProtocol();
        return stationProtocol.isAutoing()
                && stationProtocol.isLoading()
                && stationProtocol.isInEnable()
                && stationProtocol.getTaskNo() > 0
                && !Cools.isEmpty(stationProtocol.getBarcode());
    }
            List<BasDevp> basDevps = basDevpService.list(new QueryWrapper<>());
            for (BasDevp basDevp : basDevps) {
                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
                if (stationThread == null) {
                    continue;
                }
                Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
                List<StationObjModel> list = basDevp.getBarcodeStationList$();
                for (StationObjModel entity : list) {
                    Integer stationId = entity.getStationId();
                    if (!stationMap.containsKey(stationId)) {
                        continue;
                    }
                    StationProtocol stationProtocol = stationMap.get(stationId);
                    if (stationProtocol == null) {
                        continue;
                    }
                    if (stationProtocol.isAutoing()
                            && stationProtocol.isLoading()
                            && stationProtocol.isInEnable()
                            && stationProtocol.getTaskNo() > 0) {
                        if (Cools.isEmpty(stationProtocol.getBarcode())) {
                            continue;
                        }
                        if (stationProtocol.getError() > 0) {
                            Object lock = redisUtil.get(RedisKeyType.GENERATE_STATION_BACK_LIMIT.key + stationProtocol.getTaskNo());
                            if (lock != null) {
                                continue;
                            }
                            StationObjModel backStation = entity.getBackStation();
                            StationCommand command = stationThread.getCommand(StationCommandType.MOVE, commonService.getWorkNo(WrkIoType.STATION_BACK.id), stationId, backStation.getStationId(), 0);
                            if (command == null) {
                                News.taskInfo(stationProtocol.getTaskNo(), "{}工作,获取输送线命令失败", stationProtocol.getTaskNo());
                                continue;
                            }
                            MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command));
                            News.taskInfo(stationProtocol.getTaskNo(), "{}扫码异常,已退回至{}", backStation.getStationId());
                            redisUtil.set(RedisKeyType.GENERATE_STATION_BACK_LIMIT.key + stationProtocol.getTaskNo(), "lock", 10);
                        }
                        // 检测任务是否生成
                        List<WrkMast> wrkMasts = wrkMastService
                                .list(new QueryWrapper<WrkMast>()
                                        .eq("barcode", stationProtocol.getBarcode()));
                        if (!wrkMasts.isEmpty()) {
                            continue;
                        }
                        Object lock = redisUtil.get(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId);
                        if (lock != null) {
                            continue;
                        }
                        String barcode = stationProtocol.getBarcode();
                        Integer stationIdVal = stationProtocol.getStationId();
                        Integer taskNo = stationProtocol.getTaskNo();
                        // 1. 首先查询是否有已完成的异步响应
                        String response = wmsOperateUtils.queryAsyncInTaskResponse(barcode, stationIdVal, taskNo);
                        if (!Cools.isEmpty(response)) {
                            // 2. 有响应结果,处理响应
                            if (response.equals("FAILED") || response.startsWith("ERROR:")) {
                                // 请求失败,重新发起异步请求
                                News.error("WMS入库请求失败,重新发起请求,barcode={},stationId={},response={}", barcode,
                                        stationIdVal, response);
                                wmsOperateUtils.applyInTaskAsync(barcode, stationIdVal, taskNo,
                                        stationProtocol.getPalletHeight());
                                redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                                stationProtocol.setSystemWarning("请求入库失败,WMS返回=" + response);
                                continue;
                            }
                            // 解析响应
                            JSONObject jsonObject = JSON.parseObject(response);
                            if (jsonObject.getInteger("code").equals(200)) {
                                StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                                CreateInTaskParam taskParam = new CreateInTaskParam();
                                taskParam.setTaskNo(dto.getTaskNo());
                                taskParam.setLocNo(dto.getLocNo());
                                taskParam.setTaskPri(dto.getTaskPri());
                                taskParam.setBarcode(barcode);
                                WrkMast wrkMast = commonService.createInTask(taskParam);
                                stationProtocol.setSystemWarning("");
                            } else {
                                // 接口返回非200,重新发起请求
                                News.error("WMS入库接口返回非200,重新发起请求,barcode={},stationId={},response={}", barcode,
                                        stationIdVal, response);
                                wmsOperateUtils.applyInTaskAsync(barcode, stationIdVal, taskNo,
                                        stationProtocol.getPalletHeight());
                                redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                                stationProtocol.setSystemWarning("请求入库失败,WMS返回=" + response);
                            }
                        } else {
                            // 3. 没有响应结果,检查是否有请求正在进行中
                            if (!wmsOperateUtils.isAsyncRequestInProgress(barcode, stationIdVal, taskNo)) {
                                // 没有请求进行中,发起新的异步请求
                                News.info("发起异步WMS入库请求,barcode={},stationId={}", barcode, stationIdVal);
                                wmsOperateUtils.applyInTaskAsync(barcode, stationIdVal, taskNo,
                                        stationProtocol.getPalletHeight());
                                redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                                stationProtocol.setSystemWarning("请求入库失败,WMS无返回");
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
    @Override
    public boolean beforeApply(StoreInTaskContext context) {
        StationProtocol stationProtocol = context.getStationProtocol();
        if (stationProtocol.getError() <= 0) {
            return true;
        }
        Object lock = redisUtil.get(RedisKeyType.GENERATE_STATION_BACK_LIMIT.key + stationProtocol.getTaskNo());
        if (lock != null) {
            return false;
        }
        StationObjModel backStation = context.getStationObjModel().getBackStation();
        StationCommand command = context.getStationThread().getCommand(StationCommandType.MOVE,
                commonService.getWorkNo(WrkIoType.STATION_BACK.id),
                context.getStationObjModel().getStationId(),
                backStation.getStationId(), 0);
        if (command == null) {
            News.taskInfo(stationProtocol.getTaskNo(), "{}工作,获取输送线命令失败", stationProtocol.getTaskNo());
            return false;
        }
        MessageQueue.offer(SlaveType.Devp, context.getBasDevp().getDevpNo(), new Task(2, command));
        News.taskInfo(stationProtocol.getTaskNo(), "{}扫码异常,已退回至{}", backStation.getStationId());
        redisUtil.set(RedisKeyType.GENERATE_STATION_BACK_LIMIT.key + stationProtocol.getTaskNo(), "lock", 10);
        return true;
    }
    //检测入库站是否有任务生成,并启动入库
src/main/java/com/zy/core/plugin/store/AsyncInTaskResult.java
New file
@@ -0,0 +1,24 @@
package com.zy.core.plugin.store;
import lombok.Data;
@Data
public class AsyncInTaskResult {
    private String bizKey;
    private AsyncInTaskStatus status;
    private String response;
    private String message;
    public boolean isSuccess() {
        return AsyncInTaskStatus.SUCCESS.equals(status);
    }
    public boolean isRetryableFailure() {
        return AsyncInTaskStatus.RETRYABLE_FAIL.equals(status);
    }
}
src/main/java/com/zy/core/plugin/store/AsyncInTaskStatus.java
New file
@@ -0,0 +1,9 @@
package com.zy.core.plugin.store;
public enum AsyncInTaskStatus {
    SUCCESS,
    RETRYABLE_FAIL,
    FINAL_FAIL
}
src/main/java/com/zy/core/plugin/store/InTaskApplyRequest.java
New file
@@ -0,0 +1,23 @@
package com.zy.core.plugin.store;
import lombok.Data;
import java.util.LinkedHashMap;
import java.util.Map;
@Data
public class InTaskApplyRequest {
    private String bizKey;
    private String barcode;
    private Integer sourceStaNo;
    private Integer taskNo;
    private Integer locType1;
    private Map<String, Object> extraParams = new LinkedHashMap<>();
}
src/main/java/com/zy/core/plugin/store/StoreInTaskContext.java
New file
@@ -0,0 +1,22 @@
package com.zy.core.plugin.store;
import com.zy.asrs.entity.BasDevp;
import com.zy.core.model.StationObjModel;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.thread.StationThread;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class StoreInTaskContext {
    private BasDevp basDevp;
    private StationThread stationThread;
    private StationObjModel stationObjModel;
    private StationProtocol stationProtocol;
}
src/main/java/com/zy/core/plugin/store/StoreInTaskGenerationService.java
New file
@@ -0,0 +1,190 @@
package com.zy.core.plugin.store;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.common.Cools;
import com.zy.asrs.domain.param.CreateInTaskParam;
import com.zy.asrs.entity.BasDevp;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.BasDevpService;
import com.zy.asrs.service.WrkMastService;
import com.zy.common.model.StartupDto;
import com.zy.common.service.CommonService;
import com.zy.common.utils.RedisUtil;
import com.zy.core.News;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.RedisKeyType;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.StationObjModel;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.thread.StationThread;
import com.zy.core.utils.StationOperateProcessUtils;
import com.zy.core.utils.WmsOperateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class StoreInTaskGenerationService {
    @Autowired
    private BasDevpService basDevpService;
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private StationOperateProcessUtils stationOperateProcessUtils;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private WmsOperateUtils wmsOperateUtils;
    @Autowired
    private CommonService commonService;
    public void generate(StoreInTaskPolicy policy) {
        try {
            if (!policy.isEnabled()) {
                return;
            }
            Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
            if (systemConfigMapObj == null) {
                return;
            }
            HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
            int conveyorStationTaskLimit = 30;
            String conveyorStationTaskLimitStr = systemConfigMap.get("conveyorStationTaskLimit");
            if (conveyorStationTaskLimitStr != null) {
                conveyorStationTaskLimit = Integer.parseInt(conveyorStationTaskLimitStr);
            }
            int currentStationTaskCount = stationOperateProcessUtils.getCurrentStationTaskCount();
            if (currentStationTaskCount > conveyorStationTaskLimit) {
                News.error("输送站点任务已达到上限,上限值:{},站点任务数:{}", conveyorStationTaskLimit, currentStationTaskCount);
                return;
            }
            List<BasDevp> basDevps = basDevpService.list(new QueryWrapper<>());
            for (BasDevp basDevp : basDevps) {
                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
                if (stationThread == null) {
                    continue;
                }
                Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
                List<StationObjModel> barcodeStations = policy.getBarcodeStations(basDevp);
                for (StationObjModel stationObjModel : barcodeStations) {
                    Integer stationId = stationObjModel.getStationId();
                    if (!stationMap.containsKey(stationId)) {
                        continue;
                    }
                    StationProtocol stationProtocol = stationMap.get(stationId);
                    if (stationProtocol == null) {
                        continue;
                    }
                    StoreInTaskContext context = new StoreInTaskContext(basDevp, stationThread, stationObjModel,
                            stationProtocol);
                    if (!policy.matchCandidate(context)) {
                        continue;
                    }
                    if (!policy.beforeApply(context)) {
                        continue;
                    }
                    List<WrkMast> wrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>()
                            .eq("barcode", stationProtocol.getBarcode()));
                    if (!wrkMasts.isEmpty()) {
                        continue;
                    }
                    String generateLockKey = policy.getGenerateLockKey(context);
                    Object lock = redisUtil.get(generateLockKey);
                    if (lock != null) {
                        continue;
                    }
                    policy.onRequestPermitGranted(context);
                    InTaskApplyRequest request = policy.buildApplyRequest(context);
                    AsyncInTaskResult result = wmsOperateUtils.queryAsyncInTaskResponse(request);
                    if (result != null) {
                        handleApplyResult(policy, context, request, result);
                        continue;
                    }
                    if (wmsOperateUtils.isAsyncRequestInProgress(request)) {
                        continue;
                    }
                    News.info("发起异步WMS入库请求,barcode={},stationId={}", request.getBarcode(),
                            request.getSourceStaNo());
                    wmsOperateUtils.applyInTaskAsync(request);
                    redisUtil.set(generateLockKey, "lock", policy.getSubmitLockSeconds(context));
                    policy.onApplySubmitted(context);
                }
            }
        } catch (Exception e) {
            News.error("生成入库任务异常,policy={}", policy.getPolicyName(), e);
        }
    }
    private void handleApplyResult(StoreInTaskPolicy policy, StoreInTaskContext context, InTaskApplyRequest request,
                                   AsyncInTaskResult result) {
        if (result.isSuccess()) {
            handleApplySuccess(policy, context, request, result);
            return;
        }
        if (result.isRetryableFailure()) {
            News.error("WMS入库请求失败,重新发起请求,barcode={},stationId={},response={}",
                    request.getBarcode(), request.getSourceStaNo(), policy.buildFailureMessage(result));
            wmsOperateUtils.clearAsyncInTaskResponse(request);
            wmsOperateUtils.applyInTaskAsync(request);
            redisUtil.set(policy.getGenerateLockKey(context), "lock", policy.getRetryLockSeconds(context));
            policy.onApplyFailed(context, result);
            return;
        }
        policy.onApplyFailed(context, result);
    }
    private void handleApplySuccess(StoreInTaskPolicy policy, StoreInTaskContext context, InTaskApplyRequest request,
                                    AsyncInTaskResult result) {
        try {
            JSONObject jsonObject = JSON.parseObject(result.getResponse());
            if (jsonObject == null || !Integer.valueOf(200).equals(jsonObject.getInteger("code"))) {
                AsyncInTaskResult failResult = new AsyncInTaskResult();
                failResult.setStatus(AsyncInTaskStatus.RETRYABLE_FAIL);
                failResult.setResponse(result.getResponse());
                failResult.setMessage("WMS返回非200");
                handleApplyResult(policy, context, request, failResult);
                return;
            }
            StartupDto dto = jsonObject.getObject("data", StartupDto.class);
            if (dto == null) {
                AsyncInTaskResult failResult = new AsyncInTaskResult();
                failResult.setStatus(AsyncInTaskStatus.RETRYABLE_FAIL);
                failResult.setResponse(result.getResponse());
                failResult.setMessage("WMS返回data为空");
                handleApplyResult(policy, context, request, failResult);
                return;
            }
            CreateInTaskParam taskParam = policy.buildCreateInTaskParam(context, dto);
            WrkMast wrkMast = commonService.createInTask(taskParam);
            policy.afterTaskCreated(context, wrkMast);
            context.getStationProtocol().setSystemWarning("");
            wmsOperateUtils.clearAsyncInTaskResponse(request);
        } catch (Exception e) {
            News.error("处理WMS入库成功响应失败,barcode={},stationId={}", request.getBarcode(),
                    request.getSourceStaNo(), e);
        }
    }
}
src/main/java/com/zy/core/plugin/store/StoreInTaskPolicy.java
New file
@@ -0,0 +1,84 @@
package com.zy.core.plugin.store;
import com.core.common.Cools;
import com.zy.asrs.domain.param.CreateInTaskParam;
import com.zy.asrs.entity.BasDevp;
import com.zy.asrs.entity.WrkMast;
import com.zy.common.model.StartupDto;
import com.zy.core.enums.RedisKeyType;
import com.zy.core.model.StationObjModel;
import java.util.List;
public interface StoreInTaskPolicy {
    default boolean isEnabled() {
        return true;
    }
    default String getPolicyName() {
        return getClass().getSimpleName();
    }
    default List<StationObjModel> getBarcodeStations(BasDevp basDevp) {
        return basDevp.getBarcodeStationList$();
    }
    boolean matchCandidate(StoreInTaskContext context);
    default boolean beforeApply(StoreInTaskContext context) {
        return true;
    }
    default void onRequestPermitGranted(StoreInTaskContext context) {
    }
    default String getGenerateLockKey(StoreInTaskContext context) {
        return RedisKeyType.GENERATE_IN_TASK_LIMIT.key + context.getStationObjModel().getStationId();
    }
    default int getSubmitLockSeconds(StoreInTaskContext context) {
        return 2;
    }
    default int getRetryLockSeconds(StoreInTaskContext context) {
        return 2;
    }
    default InTaskApplyRequest buildApplyRequest(StoreInTaskContext context) {
        InTaskApplyRequest request = new InTaskApplyRequest();
        request.setBarcode(context.getStationProtocol().getBarcode());
        request.setSourceStaNo(context.getStationProtocol().getStationId());
        request.setTaskNo(context.getStationProtocol().getTaskNo());
        request.setLocType1(context.getStationProtocol().getPalletHeight());
        return request;
    }
    default CreateInTaskParam buildCreateInTaskParam(StoreInTaskContext context, StartupDto dto) {
        CreateInTaskParam taskParam = new CreateInTaskParam();
        taskParam.setTaskNo(dto.getTaskNo());
        taskParam.setLocNo(dto.getLocNo());
        taskParam.setTaskPri(dto.getTaskPri());
        taskParam.setBarcode(context.getStationProtocol().getBarcode());
        return taskParam;
    }
    default void afterTaskCreated(StoreInTaskContext context, WrkMast wrkMast) {
    }
    default void onApplySubmitted(StoreInTaskContext context) {
        context.getStationProtocol().setSystemWarning("请求入库中");
    }
    default void onApplyFailed(StoreInTaskContext context, AsyncInTaskResult result) {
        context.getStationProtocol().setSystemWarning("请求入库失败,WMS返回=" + buildFailureMessage(result));
    }
    default String buildFailureMessage(AsyncInTaskResult result) {
        if (!Cools.isEmpty(result.getResponse())) {
            return result.getResponse();
        }
        return result.getMessage();
    }
}
src/main/java/com/zy/core/utils/WmsOperateUtils.java
@@ -23,6 +23,9 @@
import com.zy.core.News;
import com.zy.core.enums.RedisKeyType;
import com.zy.core.enums.SlaveType;
import com.zy.core.plugin.store.AsyncInTaskResult;
import com.zy.core.plugin.store.AsyncInTaskStatus;
import com.zy.core.plugin.store.InTaskApplyRequest;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -31,7 +34,9 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.LinkedBlockingQueue;
@@ -82,6 +87,23 @@
    private final ConcurrentMap<String, Boolean> asyncInTaskInflight = new ConcurrentHashMap<>();
    private String buildAsyncInTaskBizKey(InTaskApplyRequest request) {
        if (!Cools.isEmpty(request.getBizKey())) {
            return request.getBizKey();
        }
        StringBuilder keyBuilder = new StringBuilder(request.getBarcode())
                .append("_")
                .append(request.getSourceStaNo());
        if (request.getTaskNo() != null && request.getTaskNo() > 0) {
            keyBuilder.append("_").append(request.getTaskNo());
        }
        return keyBuilder.toString();
    }
    private String buildAsyncInTaskKey(String prefix, InTaskApplyRequest request) {
        return prefix + buildAsyncInTaskBizKey(request);
    }
    private String buildAsyncInTaskKey(String prefix, String barcode, Integer stationId, Integer taskNo) {
        StringBuilder keyBuilder = new StringBuilder(prefix)
                .append(barcode)
@@ -95,6 +117,14 @@
    // 申请入库任务
    public String applyInTask(String barcode, Integer sourceStaNo, Integer locType1) {
        InTaskApplyRequest request = new InTaskApplyRequest();
        request.setBarcode(barcode);
        request.setSourceStaNo(sourceStaNo);
        request.setLocType1(locType1);
        return applyInTask(request);
    }
    public String applyInTask(InTaskApplyRequest request) {
        Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
        if (systemConfigMapObj == null) {
            News.error("系统Config缓存失效");
@@ -114,26 +144,29 @@
            return null;
        }
        HashMap<String, Object> requestParam = new HashMap<>();
        Map<String, Object> requestParam = new LinkedHashMap<>();
        String response = null;
        int result = 0;
        try {
            BasStation basStation = basStationService
                    .getOne(new QueryWrapper<BasStation>().eq("station_id", sourceStaNo));
                    .getOne(new QueryWrapper<BasStation>().eq("station_id", request.getSourceStaNo()));
            if (basStation == null) {
                News.error("站点{}不存在", sourceStaNo);
                News.error("站点{}不存在", request.getSourceStaNo());
                return null;
            }
            String stationNo = String.valueOf(sourceStaNo);
            String stationNo = String.valueOf(request.getSourceStaNo());
            if (!Cools.isEmpty(basStation.getStationAlias())) {
                stationNo = basStation.getStationAlias();
            }
            requestParam.put("barcode", barcode);
            requestParam.put("barcode", request.getBarcode());
            requestParam.put("sourceStaNo", stationNo);
            requestParam.put("locType1", locType1 == null ? 1 : locType1);
            requestParam.put("row", Utils.getInTaskEnableRow(sourceStaNo));
            requestParam.put("locType1", request.getLocType1() == null ? 1 : request.getLocType1());
            requestParam.put("row", Utils.getInTaskEnableRow(request.getSourceStaNo()));
            if (request.getExtraParams() != null && !request.getExtraParams().isEmpty()) {
                requestParam.putAll(request.getExtraParams());
            }
            response = new HttpHandler.Builder()
                    .setUri(wmsUrl)
@@ -184,8 +217,17 @@
    }
    public void applyInTaskAsync(String barcode, Integer sourceStaNo, Integer taskNo, Integer locType1) {
        String requestKey = buildAsyncInTaskKey(RedisKeyType.ASYNC_WMS_IN_TASK_REQUEST.key, barcode, sourceStaNo, taskNo);
        String responseKey = buildAsyncInTaskKey(RedisKeyType.ASYNC_WMS_IN_TASK_RESPONSE.key, barcode, sourceStaNo, taskNo);
        InTaskApplyRequest request = new InTaskApplyRequest();
        request.setBarcode(barcode);
        request.setSourceStaNo(sourceStaNo);
        request.setTaskNo(taskNo);
        request.setLocType1(locType1);
        applyInTaskAsync(request);
    }
    public void applyInTaskAsync(InTaskApplyRequest request) {
        String requestKey = buildAsyncInTaskKey(RedisKeyType.ASYNC_WMS_IN_TASK_REQUEST.key, request);
        String responseKey = buildAsyncInTaskKey(RedisKeyType.ASYNC_WMS_IN_TASK_RESPONSE.key, request);
        if (asyncInTaskInflight.putIfAbsent(requestKey, Boolean.TRUE) != null) {
            return;
@@ -204,20 +246,17 @@
        try {
            APPLY_IN_TASK_EXECUTOR.execute(() -> {
                try {
                    String response = applyInTask(barcode, sourceStaNo, locType1);
                    if (response != null) {
                        redisUtil.set(responseKey, response, APPLY_IN_TASK_RESPONSE_TTL_SECONDS);
                        News.info("异步WMS入库请求完成,barcode={},stationId={},taskNo={},response={}",
                                barcode, sourceStaNo, taskNo, response);
                    } else {
                        redisUtil.set(responseKey, "FAILED", 10);
                        News.error("异步WMS入库请求失败,barcode={},stationId={},taskNo={}",
                                barcode, sourceStaNo, taskNo);
                    }
                    String response = applyInTask(request);
                    AsyncInTaskResult result = buildAsyncInTaskResult(request, response, null);
                    redisUtil.set(responseKey, JSON.toJSONString(result), APPLY_IN_TASK_RESPONSE_TTL_SECONDS);
                    News.info("异步WMS入库请求完成,barcode={},stationId={},taskNo={},status={},response={}",
                            request.getBarcode(), request.getSourceStaNo(), request.getTaskNo(),
                            result.getStatus(), response);
                } catch (Exception e) {
                    News.error("异步WMS入库请求异常,barcode={},stationId={},taskNo={},error={}",
                            barcode, sourceStaNo, taskNo, e.getMessage());
                    redisUtil.set(responseKey, "ERROR:" + e.getMessage(), 10);
                            request.getBarcode(), request.getSourceStaNo(), request.getTaskNo(), e.getMessage());
                    AsyncInTaskResult result = buildAsyncInTaskResult(request, null, e);
                    redisUtil.set(responseKey, JSON.toJSONString(result), APPLY_IN_TASK_RESPONSE_TTL_SECONDS);
                } finally {
                    asyncInTaskInflight.remove(requestKey);
                    redisUtil.del(requestKey);
@@ -226,9 +265,13 @@
        } catch (RejectedExecutionException e) {
            asyncInTaskInflight.remove(requestKey);
            redisUtil.del(requestKey);
            redisUtil.set(responseKey, "ERROR:ASYNC_QUEUE_FULL", 10);
            AsyncInTaskResult result = new AsyncInTaskResult();
            result.setBizKey(buildAsyncInTaskBizKey(request));
            result.setStatus(AsyncInTaskStatus.RETRYABLE_FAIL);
            result.setMessage("ERROR:ASYNC_QUEUE_FULL");
            redisUtil.set(responseKey, JSON.toJSONString(result), APPLY_IN_TASK_RESPONSE_TTL_SECONDS);
            News.error("异步WMS入库请求被拒绝,线程池已满,barcode={},stationId={},taskNo={}",
                    barcode, sourceStaNo, taskNo);
                    request.getBarcode(), request.getSourceStaNo(), request.getTaskNo());
        }
    }
@@ -244,14 +287,68 @@
    }
    public String queryAsyncInTaskResponse(String barcode, Integer stationId, Integer taskNo) {
        String responseKey = buildAsyncInTaskKey(RedisKeyType.ASYNC_WMS_IN_TASK_RESPONSE.key, barcode, stationId, taskNo);
        Object response = redisUtil.get(responseKey);
        if (response != null) {
            // 获取后删除,避免重复处理
            redisUtil.del(responseKey);
            return response.toString();
        InTaskApplyRequest request = new InTaskApplyRequest();
        request.setBarcode(barcode);
        request.setSourceStaNo(stationId);
        request.setTaskNo(taskNo);
        AsyncInTaskResult result = queryAsyncInTaskResponse(request);
        if (result == null) {
            return null;
        }
        return null;
        clearAsyncInTaskResponse(request);
        if (result.isSuccess()) {
            return result.getResponse();
        }
        if (!Cools.isEmpty(result.getMessage())) {
            return result.getMessage();
        }
        return result.getResponse();
    }
    public AsyncInTaskResult queryAsyncInTaskResponse(InTaskApplyRequest request) {
        String responseKey = buildAsyncInTaskKey(RedisKeyType.ASYNC_WMS_IN_TASK_RESPONSE.key, request);
        Object response = redisUtil.get(responseKey);
        if (response == null) {
            return null;
        }
        return parseAsyncInTaskResult(buildAsyncInTaskBizKey(request), response.toString());
    }
    public void clearAsyncInTaskResponse(InTaskApplyRequest request) {
        String responseKey = buildAsyncInTaskKey(RedisKeyType.ASYNC_WMS_IN_TASK_RESPONSE.key, request);
        redisUtil.del(responseKey);
    }
    private AsyncInTaskResult parseAsyncInTaskResult(String bizKey, String responseValue) {
        AsyncInTaskResult result = null;
        try {
            JSONObject jsonObject = JSON.parseObject(responseValue);
            if (jsonObject != null && jsonObject.containsKey("status")) {
                result = jsonObject.toJavaObject(AsyncInTaskResult.class);
            } else if (jsonObject != null && jsonObject.containsKey("code")) {
                result = new AsyncInTaskResult();
                result.setBizKey(bizKey);
                result.setResponse(responseValue);
                if (Integer.valueOf(200).equals(jsonObject.getInteger("code"))) {
                    result.setStatus(AsyncInTaskStatus.SUCCESS);
                } else {
                    result.setStatus(AsyncInTaskStatus.RETRYABLE_FAIL);
                    result.setMessage(responseValue);
                }
            }
        } catch (Exception ignored) {
        }
        if (result != null) {
            return result;
        }
        result = new AsyncInTaskResult();
        result.setBizKey(bizKey);
        result.setResponse(responseValue);
        result.setStatus(AsyncInTaskStatus.RETRYABLE_FAIL);
        result.setMessage(responseValue);
        return result;
    }
    /**
@@ -266,10 +363,48 @@
    }
    public boolean isAsyncRequestInProgress(String barcode, Integer stationId, Integer taskNo) {
        String requestKey = buildAsyncInTaskKey(RedisKeyType.ASYNC_WMS_IN_TASK_REQUEST.key, barcode, stationId, taskNo);
        InTaskApplyRequest request = new InTaskApplyRequest();
        request.setBarcode(barcode);
        request.setSourceStaNo(stationId);
        request.setTaskNo(taskNo);
        return isAsyncRequestInProgress(request);
    }
    public boolean isAsyncRequestInProgress(InTaskApplyRequest request) {
        String requestKey = buildAsyncInTaskKey(RedisKeyType.ASYNC_WMS_IN_TASK_REQUEST.key, request);
        return asyncInTaskInflight.containsKey(requestKey) || redisUtil.get(requestKey) != null;
    }
    private AsyncInTaskResult buildAsyncInTaskResult(InTaskApplyRequest request, String response, Exception exception) {
        AsyncInTaskResult result = new AsyncInTaskResult();
        result.setBizKey(buildAsyncInTaskBizKey(request));
        result.setResponse(response);
        if (exception != null) {
            result.setStatus(AsyncInTaskStatus.RETRYABLE_FAIL);
            result.setMessage("ERROR:" + exception.getMessage());
            return result;
        }
        if (response == null) {
            result.setStatus(AsyncInTaskStatus.RETRYABLE_FAIL);
            result.setMessage("FAILED");
            return result;
        }
        try {
            JSONObject jsonObject = JSON.parseObject(response);
            if (jsonObject != null && Integer.valueOf(200).equals(jsonObject.getInteger("code"))) {
                result.setStatus(AsyncInTaskStatus.SUCCESS);
                return result;
            }
        } catch (Exception ignored) {
        }
        result.setStatus(AsyncInTaskStatus.RETRYABLE_FAIL);
        result.setMessage(response);
        return result;
    }
    // 申请任务重新分配库位
    public synchronized String applyReassignTaskLocNo(Integer taskNo, Integer stationId) {
        String wmsUrl = null;
src/main/webapp/components/DevpCard.js
@@ -277,6 +277,7 @@
        { label: "任务可写区", value: this.orDash(item.taskWriteIdx) },
        { label: "故障代码", value: this.orDash(item.error) },
        { label: "故障信息", value: this.orDash(item.errorMsg) },
        { label: "系统告警", value: this.orDash(item.systemWarning) },
        { label: "扩展数据", value: this.orDash(item.extend) }
      ];
    },