自动化立体仓库 - WMS系统
cl
13 小时以前 91c235d583d3f6579d060fac9fa91faa65a1b42c
src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
@@ -33,7 +33,6 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.rmi.CORBA.Util;
import java.util.*;
import java.util.stream.Collectors;
@@ -98,6 +97,8 @@
    private WorkService workService;
    @Autowired
    private BasCrnpService basCrnpService;
    @Autowired
    private ApiLogService apiLogService;
    @Override
    @Transactional
@@ -377,12 +378,12 @@
        if (param == null || Cools.isEmpty(param.getOrderId())) {
            throw new CoolException("orderNo不能为空");
        }
        if (param.getReason() == null) {
            throw new CoolException("reason不能为空");
        if (param.getExecute() == null) {
            throw new CoolException("execute不能为空");
        }
        List<WrkMast> activeTasks = findActiveOutboundTasks(param.getOrderId());
        if (Objects.equals(param.getReason(), 1)) {
        if (Objects.equals(param.getExecute(), 1)) {
            // ERP确认立即执行,仅处理待下发的出库任务。
            List<WrkMast> pendingTasks = activeTasks.stream()
                    .filter(wrkMast -> wrkMast != null && Objects.equals(wrkMast.getWrkSts(), 11L))
@@ -415,94 +416,47 @@
            result.put("confirmedCount", confirmedCount);
            return R.ok(confirmedCount == 0 ? "任务已确认执行" : "ERP确认执行出库成功").add(result);
        }
        if (Objects.equals(param.getReason(), 2)) {
            // ERP请求取消任务:未下发任务直接本地取消,已下发任务交给WCS判定可取消清单。
        if (Objects.equals(param.getExecute(), 2)) {
            // ERP请求取消任务:直接收集任务号,按 taskList 格式发送给 WCS。
            Map<String, Object> result = new HashMap<>();
            result.put("orderNo", param.getOrderId());
            result.put("reason", param.getReason());
            result.put("execute", param.getExecute());
            result.put("taskCount", activeTasks.size());
            if (activeTasks.isEmpty()) {
                result.put("successList", Collections.emptyList());
                result.put("failList", Collections.emptyList());
                result.put("cancelledCount", 0);
                return R.ok("无有效出库任务").add(result);
            }
            Map<String, WrkMast> taskIndex = activeTasks.stream()
                    .filter(wrkMast -> wrkMast != null && wrkMast.getWrkNo() != null)
                    .collect(Collectors.toMap(
                            wrkMast -> String.valueOf(wrkMast.getWrkNo()),
                            wrkMast -> wrkMast,
                            (left, right) -> left,
                            LinkedHashMap::new
                    ));
            List<WrkMast> directCancelTasks = activeTasks.stream()
                    .filter(wrkMast -> wrkMast != null && !needNotifyWcsStop(wrkMast))
                    .collect(Collectors.toList());
            List<WrkMast> wcsCancelTasks = activeTasks.stream()
                    .filter(this::needNotifyWcsStop)
                    .collect(Collectors.toList());
            LinkedHashSet<String> successTaskNos = new LinkedHashSet<>();
            LinkedHashSet<String> failTaskNos = new LinkedHashSet<>();
            cancelOutboundTasks(directCancelTasks.stream()
                    .map(WrkMast::getWrkNo)
                    .filter(Objects::nonNull)
                    .map(String::valueOf)
                    .collect(Collectors.toList()), taskIndex, successTaskNos);
            List<String> wcsSuccessList = Collections.emptyList();
            List<String> wcsFailList = Collections.emptyList();
            if (!wcsCancelTasks.isEmpty()) {
                R wcsResult = wcsApiService.pauseOutTasks(buildStopOutTaskParams(param, wcsCancelTasks));
                wcsSuccessList = extractTaskNoList(wcsResult, "successList");
                wcsFailList = extractTaskNoList(wcsResult, "failList");
                cancelOutboundTasks(wcsSuccessList, taskIndex, successTaskNos);
                LinkedHashSet<String> wcsFailTaskNos = new LinkedHashSet<>(wcsFailList);
                if (wcsFailTaskNos.isEmpty()) {
                    for (WrkMast wrkMast : wcsCancelTasks) {
                        String taskNo = String.valueOf(wrkMast.getWrkNo());
                        if (!successTaskNos.contains(taskNo)) {
                            wcsFailTaskNos.add(taskNo);
                        }
                    }
            List<HashMap<String,Object>> taskList = new ArrayList<>();
            for (WrkMast wrkMast : activeTasks) {
                HashMap<String,Object> hashMap = new HashMap<>();
                hashMap.put("taskNo", wrkMast.getWrkNo());
                if (!Cools.isEmpty(wrkMast) && wrkMast.getWrkSts() ==11L) {
                    workService.cancelWrkMast(wrkMast.getWrkNo()+"", 9955L);
                    continue;
                }
                failTaskNos.addAll(wcsFailTaskNos);
                wcsFailList = new ArrayList<>(wcsFailTaskNos);
                taskList.add(hashMap);
            }
            result.put("wcsTaskCount", wcsCancelTasks.size());
            result.put("wcsSuccessList", wcsSuccessList);
            result.put("wcsFailList", wcsFailList);
            result.put("successList", new ArrayList<>(successTaskNos));
            result.put("failList", new ArrayList<>(failTaskNos));
            result.put("cancelledCount", successTaskNos.size());
            result.put("failCount", failTaskNos.size());
            return R.ok(successTaskNos.isEmpty() ? "没有可取消任务" : "取消出库任务成功").add(result);
            wcsApiService.pauseOutTasks(taskList);
            return R.ok("取消任务已发送至WCS").add(result);
        }
        throw new CoolException("reason仅支持1或2");
    }
    /** WCS 返回非成功码时抛错 */
    private void requireWcsPauseOk(R wcsR) {
        if (wcsR == null) {
            throw new CoolException("WCS取消出库任务无返回");
        }
        Object codeObj = wcsR.get("code");
        int code = codeObj instanceof Number ? ((Number) codeObj).intValue() : -1;
        if (code != 200) {
            Object msgObj = wcsR.get("msg");
            throw new CoolException(msgObj == null ? "WCS取消出库任务失败" : String.valueOf(msgObj));
        }
    }
    @Override
    @Transactional
    public R pakoutOrderExecute(OpenOrderPakoutExecuteParam param) {
        if (param == null || Cools.isEmpty(param.getOrderId())) {
            throw new CoolException("orderId不能为空");
        }
        if (param.getExecute() == null) {
            throw new CoolException("execute不能为空");
        }
        if (Objects.equals(param.getExecute(), 1)) {
            return createPakoutTasks(param.getOrderId());
        }
        if (Objects.equals(param.getExecute(), 2)) {
            OpenOrderPakoutPauseParam pauseParam = new OpenOrderPakoutPauseParam();
            pauseParam.setOrderId(param.getOrderId());
            pauseParam.setReason(2);
            return pakoutOrderPause(pauseParam);
        }
        throw new CoolException("execute仅支持1或2");
        return null;
    }
    private List<WrkMast> findActiveOutboundTasks(String orderNo) {
@@ -631,14 +585,7 @@
        return orderDetl.getMatnr() + "|batch=" + (orderDetl.getBatch() == null ? "" : orderDetl.getBatch()) + "|lack=" + lackQty;
    }
    private boolean needNotifyWcsStop(WrkMast wrkMast) {
        return wrkMast != null
                && wrkMast.getWrkSts() != null
                && wrkMast.getWrkSts() >= 12L
                && wrkMast.getWrkSts() < 14L;
    }
    private StopOutTaskParams buildStopOutTaskParams(OpenOrderPakoutPauseParam param, List<WrkMast> wrkMasts) {
    private StopOutTaskParams buildStopOutTaskParams(List<WrkMast> wrkMasts) {
        StopOutTaskParams stopParams = new StopOutTaskParams();
        // WCS取消接口仅接收 taskList.taskNo。
        for (WrkMast wrkMast : wrkMasts) {
@@ -647,50 +594,6 @@
            stopParams.getTasks().add(item);
        }
        return stopParams;
    }
    private List<String> extractTaskNoList(R result, String key) {
        if (result == null) {
            return Collections.emptyList();
        }
        List<String> taskNos = toTaskNoList(result.get(key));
        if (!taskNos.isEmpty()) {
            return taskNos;
        }
        Object data = result.get("data");
        if (data instanceof Map) {
            return toTaskNoList(((Map<?, ?>) data).get(key));
        }
        if (data instanceof JSONObject) {
            return toTaskNoList(((JSONObject) data).get(key));
        }
        return Collections.emptyList();
    }
    private List<String> toTaskNoList(Object value) {
        if (value == null) {
            return Collections.emptyList();
        }
        if (value instanceof Collection) {
            List<String> taskNos = new ArrayList<>();
            for (Object item : (Collection<?>) value) {
                if (item != null) {
                    taskNos.add(String.valueOf(item));
                }
            }
            return taskNos;
        }
        return JSON.parseArray(JSON.toJSONString(value), String.class);
    }
    private void cancelOutboundTasks(List<String> taskNos, Map<String, WrkMast> taskIndex, Set<String> successTaskNos) {
        for (String taskNo : taskNos) {
            if (Cools.isEmpty(taskNo) || successTaskNos.contains(taskNo) || !taskIndex.containsKey(taskNo)) {
                continue;
            }
            workService.cancelWrkMast(taskNo, 9527L);
            successTaskNos.add(taskNo);
        }
    }
    @Override
@@ -1336,7 +1239,10 @@
                stationParams.add(stationParam);
            }
        }
        String requestJson = JSON.toJSONString(stationParams);
        String response = "";
        boolean pushOk = false;
        String pushUrl = buildMesStationRequestUrl();
        try {
            //获取Cookie值
            HashMap<String, Object> headers = new HashMap<>();
@@ -1346,19 +1252,50 @@
                    .setHeaders(headers)
                    .setUri(mesUrl)
                    .setPath(stationAddress)
                    .setJson(JSON.toJSONString(stationParams))
                    .setJson(requestJson)
                    .build()
                    .doPost();
            JSONObject jsonResponse = JSON.parseObject(response);
            if (jsonResponse.getInteger("code") == 200) {
            if (jsonResponse != null && Integer.valueOf(200).equals(jsonResponse.getInteger("code"))) {
                pushOk = true;
            } else {
                return R.error();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                apiLogService.save(
                        "推ERP-站点同步",
                        pushUrl,
                        null,
                        "127.0.0.1",
                        requestJson,
                        response,
                        pushOk,
                        "站点同步推对方"
                );
            } catch (Exception logEx) {
                log.error("save station sync api log failed", logEx);
            }
        }
        return R.ok();
    }
    private String buildMesStationRequestUrl() {
        if (Cools.isEmpty(mesUrl)) {
            return stationAddress;
        }
        if (stationAddress == null) {
            return mesUrl;
        }
        if (mesUrl.endsWith("/") && stationAddress.startsWith("/")) {
            return mesUrl + stationAddress.substring(1);
        }
        if (!mesUrl.endsWith("/") && !stationAddress.startsWith("/")) {
            return mesUrl + "/" + stationAddress;
        }
        return mesUrl + stationAddress;
    }
    @Override
@@ -1373,7 +1310,12 @@
            if (param.getFull() == 1) {
                //满托盘
                mat = matService.selectByMatnr("emptyPallet");
                if(param.getBoxType1().equals("aws")){
                    mat = matService.selectByMatnr("amazon");
                }else {
                    mat = matService.selectByMatnr("cloudWarehouse");
                }
            } else if (param.getFull() == 0) {
                //空托盘
                mat = matService.selectByMatnr("emptyPallet");
@@ -1398,17 +1340,19 @@
        waitPakin.setManu(String.valueOf(param.getLocId()));//mes具体库位编号
        waitPakin.setThreeCode(param.getBizNo());
        waitPakin.setBeBatch(param.getPackage1());//是否散货,0 非散货;1 散货;为了管控出货速率,散货可以出慢点。
        // ERP 入口默认打 erp,MQTT 组托会在参数里显式传 aws。
        waitPakin.setBoxType1(Cools.isEmpty(param.getBoxType1()) ? "erp" : param.getBoxType1());
        if (!waitPakinService.insert(waitPakin)) {
            throw new CoolException("保存入库通知档失败");
        }
        return null;
        return R.ok().add(Cools.add("palletId", param.getPalletId()).add("orderId", param.getOrderId()));
    }
    @Override
    public R outOrder(OutTaskParam param) {
    public R outOrder(OutTaskParam param,int count) {
        LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts", "F").eq("barcode", param.getPalletId()));
        if (locMast == null) {
            return R.error("没有找到托盘码=" + param.getPalletId() + "对应的库位");
            throw new CoolException("没有找到托盘码=" + param.getPalletId() + "对应的库位");
        }
        Integer ioType = 101;
        // 获取路径
@@ -1461,6 +1405,7 @@
            wrkDetl.setAppeUser(9995L);
            wrkDetl.setModiTime(now);
            wrkDetl.setModiUser(9995L);
            wrkDetl.setSupp(param.getSeq()+"/"+count);
            if (!wrkDetlService.insert(wrkDetl)) {
                throw new CoolException("保存工作档明细失败");
@@ -1479,7 +1424,21 @@
            log.error(locMast.getLocNo() + "库位不是在库状态");
            throw new CoolException(locMast.getLocNo() + "库位不是在库状态");
        }
        return R.ok().add(Cools.add("wrkNo", workNo).add("orderId", param.getOrderId()));
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R outOrderBatch(List<OutTaskParam> params) {
        int n = params.size();
        for (OutTaskParam outTaskParam : params) {
            R r = outOrder(outTaskParam, n);
            if (!Objects.equals(r.get("code"), 200)) {
                throw new CoolException("出库建单失败");
            }
        }
        return R.ok();
    }
}