自动化立体仓库 - WMS系统
pang.jiabao
2026-01-19 78b8f5141aa11bfa0f94361407ed43362c8852ce
WMS功能完善
1个文件已添加
37个文件已修改
2505 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/DigitalTwinController.java 313 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/LocMastController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/MesController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/TaskLogController.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WrkMastLog.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/digitaltwin/DtDetainMatVo.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/digitaltwin/DtInAndOutBoundVo.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/MesOutApply.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/rcs/SiteBind.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/enums/RcsRetMethodEnum.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/BasDevpMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/DigitalTwinMapper.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/DigitalTwinService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/RcsService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/DigitalTwinServiceImpl.java 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MesServiceImpl.java 1406 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/RcsServiceImpl.java 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WrkMastLogServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/JlerScheduler.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/OrderSyncScheduler.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/JlerHandler.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/config/AdminInterceptor.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/web/WcsController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/system/controller/UserController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/BasDevpMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocCountMapper.xml 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ViewDigitalTwinMapper.xml 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ViewInOutMapper.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ViewStayTimeMapper.xml 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ViewStockUseMapper.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ViewWorkInMapper.xml 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/locDetl/locDetl.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/pakStore/emptyOut.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/pakStore/emptyOut.html 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/DigitalTwinController.java
@@ -31,16 +31,16 @@
//    @ManagerAuth
    public R overview(@RequestParam(required = false) String areaId){
        //digitalTwinService.overview(areaId);
        DtOverviewVo dtOverviewVo = digitalTwinService.overview(areaId);
        DtOverviewVo dtOverviewVo = DtOverviewVo.builder()
                .totalLoc(999)
                .useLoc(900)
                .idleLoc(99)
                .todayOutbound(160)
                .todayWarehousing(170)
                .remainingStock(180)
                .build();
//        DtOverviewVo dtOverviewVo = DtOverviewVo.builder()
//                .totalLoc(999)
//                .useLoc(900)
//                .idleLoc(99)
//                .todayOutbound(160)
//                .todayWarehousing(170)
//                .remainingStock(180)
//                .build();
        return R.ok().add(dtOverviewVo);
    }
@@ -57,19 +57,19 @@
    public R recentOrder(@RequestParam(required = false) String startDate,
                         @RequestParam(required = false) String endDate){
//        digitalTwinService.order(startDate, endDate);
        List<DtOrderVo> orderVoList = digitalTwinService.order(startDate, endDate);
        DtOrderVo dtOrderVo = DtOrderVo.builder()
                .orderDate("2025-10-22")
                .orderNum(156)
                .build();
        DtOrderVo dtOrderVo2 = DtOrderVo.builder()
                .orderDate("2025-10-23")
                .orderNum(166)
                .build();
        List<DtOrderVo> orderVoList = new ArrayList<>();
        orderVoList.add(dtOrderVo);
        orderVoList.add(dtOrderVo2);
//        DtOrderVo dtOrderVo = DtOrderVo.builder()
//                .orderDate("2025-10-22")
//                .orderNum(156)
//                .build();
//        DtOrderVo dtOrderVo2 = DtOrderVo.builder()
//                .orderDate("2025-10-23")
//                .orderNum(166)
//                .build();
//        List<DtOrderVo> orderVoList = new ArrayList<>();
//        orderVoList.add(dtOrderVo);
//        orderVoList.add(dtOrderVo2);
        return R.ok().add(orderVoList);
    }
@@ -88,19 +88,19 @@
                           @RequestParam(required = false) String startDate,
                         @RequestParam(required = false) String endDate){
//        digitalTwinService.recentLoc(areaId, startDate, endDate);
        List<DtLocVo> locVoList = digitalTwinService.recentLoc(areaId, startDate, endDate);
        DtLocVo dtLocVo = DtLocVo.builder()
                .locDate("2025-10-22")
                .idleNum(208)
                .build();
        DtLocVo dtLocVo2 = DtLocVo.builder()
                .locDate("2025-10-23")
                .idleNum(177)
                .build();
        List<DtLocVo> locVoList = new ArrayList<>();
        locVoList.add(dtLocVo);
        locVoList.add(dtLocVo2);
//        DtLocVo dtLocVo = DtLocVo.builder()
//                .locDate("2025-10-22")
//                .idleNum(208)
//                .build();
//        DtLocVo dtLocVo2 = DtLocVo.builder()
//                .locDate("2025-10-23")
//                .idleNum(177)
//                .build();
//        List<DtLocVo> locVoList = new ArrayList<>();
//        locVoList.add(dtLocVo);
//        locVoList.add(dtLocVo2);
        return R.ok().add(locVoList);
    }
@@ -119,21 +119,21 @@
                           @RequestParam(required = false) String startDate,
                           @RequestParam(required = false) String endDate){
//        digitalTwinService.inAndOutBound(areaId, startDate, endDate);
        DtInAndOutBoundVo dtInAndOutBoundVo = DtInAndOutBoundVo.builder()
                .boundDate("2025-10-22")
                .inBoundNum(237)
                .outBoundNum(487)
                .build();
        DtInAndOutBoundVo dtInAndOutBoundVo2 = DtInAndOutBoundVo.builder()
                .boundDate("2025-10-23")
                .inBoundNum(187)
                .outBoundNum(287)
                .build();
        List<DtInAndOutBoundVo> inAndOutBoundVoList = new ArrayList<>();
        inAndOutBoundVoList.add(dtInAndOutBoundVo);
        inAndOutBoundVoList.add(dtInAndOutBoundVo2);
        List<DtInAndOutBoundVo> inAndOutBoundVoList = digitalTwinService.inAndOutBound(areaId, startDate, endDate);
//
//        DtInAndOutBoundVo dtInAndOutBoundVo = DtInAndOutBoundVo.builder()
//                .boundDate("2025-10-22")
//                .inBoundNum(237)
//                .outBoundNum(487)
//                .build();
//        DtInAndOutBoundVo dtInAndOutBoundVo2 = DtInAndOutBoundVo.builder()
//                .boundDate("2025-10-23")
//                .inBoundNum(187)
//                .outBoundNum(287)
//                .build();
//        List<DtInAndOutBoundVo> inAndOutBoundVoList = new ArrayList<>();
//        inAndOutBoundVoList.add(dtInAndOutBoundVo);
//        inAndOutBoundVoList.add(dtInAndOutBoundVo2);
        return R.ok().add(inAndOutBoundVoList);
    }
@@ -152,31 +152,31 @@
                             @RequestParam(required = false) Integer pageIndex,
                             @RequestParam(required = false) Integer pageSize){
//        digitalTwinService.recentDetainMat(areaId, overDayNum, pageIndex, pageSize);
        List<DtDetainMatVo> detainMatVoList = digitalTwinService.recentDetainMat(areaId, overDayNum, pageIndex, pageSize);
        DtDetainMatVo dtDetainMatVo = DtDetainMatVo.builder()
                .belongAreaId("A1")
                .belongAreaName("刀具库")
                .matId("mat10001")
                .matName("道具把")
                .lokId("loc1001")
                .lokName("库位10001")
                .detainTime(765)
                .inBoundTime("2025-10-11T11:15:16")
                .build();
        DtDetainMatVo dtDetainMatVo2 = DtDetainMatVo.builder()
                .belongAreaId("A1")
                .belongAreaName("刀具库")
                .matId("mat10002")
                .matName("道具把")
                .lokId("loc1002")
                .lokName("库位10002")
                .detainTime(665)
                .inBoundTime("2025-10-10T11:15:16")
                .build();
        List<DtDetainMatVo> detainMatVoList = new ArrayList<>();
        detainMatVoList.add(dtDetainMatVo);
        detainMatVoList.add(dtDetainMatVo2);
//        DtDetainMatVo dtDetainMatVo = DtDetainMatVo.builder()
//                .belongAreaId("A1")
//                .belongAreaName("刀具库")
//                .matId("mat10001")
//                .matName("道具把")
//                .lokId("loc1001")
//                .lokName("库位10001")
//                .detainTime(765)
//                .inBoundTime("2025-10-11T11:15:16")
//                .build();
//        DtDetainMatVo dtDetainMatVo2 = DtDetainMatVo.builder()
//                .belongAreaId("A1")
//                .belongAreaName("刀具库")
//                .matId("mat10002")
//                .matName("道具把")
//                .lokId("loc1002")
//                .lokName("库位10002")
//                .detainTime(665)
//                .inBoundTime("2025-10-10T11:15:16")
//                .build();
//        List<DtDetainMatVo> detainMatVoList = new ArrayList<>();
//        detainMatVoList.add(dtDetainMatVo);
//        detainMatVoList.add(dtDetainMatVo2);
        return R.ok().add(detainMatVoList);
    }
@@ -191,35 +191,37 @@
//    @ManagerAuth
    public R equipment(@RequestParam(required = false) String areaId){
        DtEquipmentVo dtDetainMatVo = DtEquipmentVo.builder()
                .equipmentId("eq1001")
                .equipmentName("堆垛机1")
                .equipmentType(1)
                .belongAreaId("A1")
                .belongAreaName("刀具库")
                .verticalSpeed(288)
                .horizontalSpeed(203)
                .voltage(48)
                .status(1)
                .operateMethod(1)
                .build();
        DtEquipmentVo dtDetainMatVo2 = DtEquipmentVo.builder()
                .equipmentId("eq1002")
                .equipmentName("堆垛机2")
                .equipmentType(1)
                .belongAreaId("A1")
                .belongAreaName("刀具库")
                .verticalSpeed(208)
                .horizontalSpeed(253)
                .voltage(48)
                .status(1)
                .operateMethod(1)
                .build();
        List<DtEquipmentVo> dtEquipmentVoList = new ArrayList<>();
        dtEquipmentVoList.add(dtDetainMatVo);
        dtEquipmentVoList.add(dtDetainMatVo2);
        return R.ok(digitalTwinService.equipment(areaId));
        return R.ok().add(dtEquipmentVoList);
//        DtEquipmentVo dtDetainMatVo = DtEquipmentVo.builder()
//                .equipmentId("eq1001")
//                .equipmentName("堆垛机1")
//                .equipmentType(1)
//                .belongAreaId("A1")
//                .belongAreaName("刀具库")
//                .verticalSpeed(288)
//                .horizontalSpeed(203)
//                .voltage(48)
//                .status(1)
//                .operateMethod(1)
//                .build();
//        DtEquipmentVo dtDetainMatVo2 = DtEquipmentVo.builder()
//                .equipmentId("eq1002")
//                .equipmentName("堆垛机2")
//                .equipmentType(1)
//                .belongAreaId("A1")
//                .belongAreaName("刀具库")
//                .verticalSpeed(208)
//                .horizontalSpeed(253)
//                .voltage(48)
//                .status(1)
//                .operateMethod(1)
//                .build();
//        List<DtEquipmentVo> dtEquipmentVoList = new ArrayList<>();
//        dtEquipmentVoList.add(dtDetainMatVo);
//        dtEquipmentVoList.add(dtDetainMatVo2);
//
//        return R.ok().add(dtEquipmentVoList);
    }
    /**
@@ -232,61 +234,60 @@
//    @ManagerAuth
    public R warehouseDetail(@RequestParam(required = false) String areaId){
//        digitalTwinService.warehouseDetail(areaId);
        List<DtLocDetailVo> dtLocDetailVoList = new ArrayList<>();
        DtLocDetailVo dtLocDetailVo = new DtLocDetailVo();
        dtLocDetailVo.setLocNo("CA0100202");
        dtLocDetailVo.setLocSts("O");
        dtLocDetailVo.setAreaId(10010L);
        dtLocDetailVo.setAreaName("刀具库");
        dtLocDetailVo.setRow1(1);
        dtLocDetailVo.setBay1(2);
        dtLocDetailVo.setLev1(2);
        LocMast locMast = new LocMast();
        locMast.setLocNo("CA0100202");
        locMast.setLocSts("O");
        locMast.setRow1(1);
        locMast.setBay1(2);
        locMast.setLev1(2);
        dtLocDetailVo.setLocMast(locMast);
        LocDetl locDetl = new LocDetl();
        locDetl.setLocNo("CA0100202");
        locDetl.setAreaId(10010L);
        locDetl.setAreaName("刀具库");
        locDetl.setMatnr("mat10001");
        locDetl.setMaktx("刀把");
        dtLocDetailVo.setLocDetl(locDetl);
        dtLocDetailVoList.add(dtLocDetailVo);
        DtLocDetailVo dtLocDetailVo2 = new DtLocDetailVo();
        dtLocDetailVo2.setLocNo("CA0100202");
        dtLocDetailVo2.setLocSts("O");
        dtLocDetailVo2.setAreaId(10010L);
        dtLocDetailVo2.setAreaName("刀具库");
        dtLocDetailVo2.setRow1(1);
        dtLocDetailVo2.setBay1(2);
        dtLocDetailVo2.setLev1(2);
        LocMast locMast2 = new LocMast();
        locMast2.setLocNo("CA0100203");
        locMast2.setLocSts("O");
        locMast2.setRow1(1);
        locMast2.setBay1(2);
        locMast2.setLev1(3);
        dtLocDetailVo2.setLocMast(locMast2);
        LocDetl locDetl2 = new LocDetl();
        locDetl2.setLocNo("CA0100203");
        locDetl2.setAreaId(10010L);
        locDetl2.setAreaName("刀具库");
        locDetl2.setMatnr("mat10001");
        locDetl2.setMaktx("刀把");
        dtLocDetailVo2.setLocDetl(locDetl2);
        dtLocDetailVoList.add(dtLocDetailVo2);
        return R.ok(digitalTwinService.warehouseDetail(areaId));
//        List<DtLocDetailVo> dtLocDetailVoList = new ArrayList<>();
//        DtLocDetailVo dtLocDetailVo = new DtLocDetailVo();
//        dtLocDetailVo.setLocNo("CA0100202");
//        dtLocDetailVo.setLocSts("O");
//        dtLocDetailVo.setAreaId(10010L);
//        dtLocDetailVo.setAreaName("刀具库");
//        dtLocDetailVo.setRow1(1);
//        dtLocDetailVo.setBay1(2);
//        dtLocDetailVo.setLev1(2);
//
//        LocMast locMast = new LocMast();
//        locMast.setLocNo("CA0100202");
//        locMast.setLocSts("O");
//        locMast.setRow1(1);
//        locMast.setBay1(2);
//        locMast.setLev1(2);
//        dtLocDetailVo.setLocMast(locMast);
//
//        LocDetl locDetl = new LocDetl();
//        locDetl.setLocNo("CA0100202");
//        locDetl.setAreaId(10010L);
//        locDetl.setAreaName("刀具库");
//        locDetl.setMatnr("mat10001");
//        locDetl.setMaktx("刀把");
//        dtLocDetailVo.setLocDetl(locDetl);
//        dtLocDetailVoList.add(dtLocDetailVo);
//
//
//        DtLocDetailVo dtLocDetailVo2 = new DtLocDetailVo();
//        dtLocDetailVo2.setLocNo("CA0100202");
//        dtLocDetailVo2.setLocSts("O");
//        dtLocDetailVo2.setAreaId(10010L);
//        dtLocDetailVo2.setAreaName("刀具库");
//        dtLocDetailVo2.setRow1(1);
//        dtLocDetailVo2.setBay1(2);
//        dtLocDetailVo2.setLev1(2);
//
//        LocMast locMast2 = new LocMast();
//        locMast2.setLocNo("CA0100203");
//        locMast2.setLocSts("O");
//        locMast2.setRow1(1);
//        locMast2.setBay1(2);
//        locMast2.setLev1(3);
//        dtLocDetailVo2.setLocMast(locMast2);
//
//        LocDetl locDetl2 = new LocDetl();
//        locDetl2.setLocNo("CA0100203");
//        locDetl2.setAreaId(10010L);
//        locDetl2.setAreaName("刀具库");
//        locDetl2.setMatnr("mat10001");
//        locDetl2.setMaktx("刀把");
//        dtLocDetailVo2.setLocDetl(locDetl2);
//        dtLocDetailVoList.add(dtLocDetailVo2);
//        LocDetl locDetl2 = new LocDetl();
@@ -300,7 +301,7 @@
////        locDetlList.add(locDetl);
////        locDetlList.add(locDetl2);
        return R.ok().add(dtLocDetailVoList);
//        return R.ok().add(dtLocDetailVoList);
    }
}
src/main/java/com/zy/asrs/controller/LocMastController.java
@@ -2,6 +2,7 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
@@ -76,6 +77,11 @@
                  @RequestParam Map<String, Object> param) {
        excludeTrash(param);
        EntityWrapper<LocMast> wrapper = new EntityWrapper<>();
        Object barcode = param.get("barcode");
        if(!Cools.isEmpty(barcode)) {
            wrapper.like("barcode", (String) barcode,SqlLike.RIGHT);
            param.remove("barcode");
        }
        convert(param, wrapper);
        if (!Cools.isEmpty(orderByField)) {
            wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));
src/main/java/com/zy/asrs/controller/MesController.java
@@ -37,6 +37,7 @@
                mesReturn = mesService.matInfoAndInBound(matRecvForm);
            }
        } catch (Exception e) {
            e.printStackTrace();
            mesReturn.setSuccess("2");
            mesReturn.setMessage("物料信息同步失败");
        }
src/main/java/com/zy/asrs/controller/TaskLogController.java
@@ -42,7 +42,9 @@
        excludeTrash(param);
        convert(param, wrapper);
        allLike(TaskLog.class, param.keySet(), wrapper, condition);
        if (!Cools.isEmpty(orderByField)){wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));}
        if (!Cools.isEmpty(orderByField)){wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));} else {
            wrapper.orderBy("modi_time", false);
        }
        return R.ok(taskLogService.selectPage(new Page<>(curr, limit), wrapper));
    }
src/main/java/com/zy/asrs/entity/WrkMastLog.java
@@ -29,8 +29,8 @@
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("日志ID")
    private Long logId;
//    @ApiModelProperty("日志ID")
//    private Long logId;
    /**
     * 工作号
src/main/java/com/zy/asrs/entity/digitaltwin/DtDetainMatVo.java
@@ -5,7 +5,6 @@
// 数字孪生:呆滞品信息
@Data
@Builder
public class DtDetainMatVo {
    // 归属库区ID
src/main/java/com/zy/asrs/entity/digitaltwin/DtInAndOutBoundVo.java
@@ -3,15 +3,17 @@
import lombok.Builder;
import lombok.Data;
import java.math.BigDecimal;
// 数字孪生:按天出入库数量
@Data
@Builder
//@Builder
public class DtInAndOutBoundVo {
    // 日期
    private String boundDate;
    // 入库数量
    private Integer inBoundNum;
    private BigDecimal inBoundNum;
    // 出库数量
    private Integer outBoundNum;
}
    private BigDecimal outBoundNum;
}
src/main/java/com/zy/asrs/entity/mes/MesOutApply.java
@@ -45,4 +45,10 @@
    @JSONField(name = "ItemBarcode")
    private List<String> ItemBarcode;
    /**
     * 托盘类型 11.角架托盘
     * 12.调节螺杆,13.调节螺套,14.横向连杆,15.纵向连杆
     */
    private String palletType;
}
src/main/java/com/zy/asrs/entity/rcs/SiteBind.java
New file
@@ -0,0 +1,46 @@
package com.zy.asrs.entity.rcs;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @author pang.jiabao
 * @description 载具与站点绑定接口
 * @createDate 2025/12/27 14:36
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SiteBind {
    /**
     * 存储对象种类类型
     */
    private String slotCategory;
    /**
     * 站点编号/站点别名
     */
    private String slotCode;
    /**
     * 搬运对象种类类型
     */
    private String carrierCategory;
    /**
     * 载具编号/载具别名
     */
    private String carrierCode;
    /**
     * 绑定解绑的变更。
     * 固定枚举值:
     * BIND
     * 绑定
     * UNBIND
     * 解绑
     */
    private String invoke;
}
src/main/java/com/zy/asrs/enums/RcsRetMethodEnum.java
@@ -5,7 +5,9 @@
    TASK_START("start", "任务开始"),
    TASK_END("end", "任务完成"),
    TASK_OUT_BIN("outbin", "走出储位"),
    APPLY_PUT("applyPut", "放货申请"),
    APPLY_PICK("applyPick", "取货申请"),
    PICK_COMPLETE("pickComplete", "取货完成"),
    APPLY_IN_STATION("applyInStation", "入站请求"),
    APPLY_OFF_STATION("applyOutStation", "离站请求"),
    ARRIVE_ON_STATION("arriveOnStation", "到站完成"),
src/main/java/com/zy/asrs/mapper/BasDevpMapper.java
@@ -15,4 +15,12 @@
    List<Integer> getAvailableInSite(@Param("typeNo") Integer typeNo);
    List<Integer> getAvailableOutSite(@Param("typeNo") Integer typeNo);
    /**
     * 更新入库暂存数
     * @param devNo 站点号
     * @param type 1.加1,2.减1
     * @return 更新数量
     */
    int updateInQty(@Param("typeNo") Integer devNo,@Param("typeNo") Integer type);
}
src/main/java/com/zy/asrs/mapper/DigitalTwinMapper.java
@@ -7,6 +7,7 @@
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.Date;
import java.util.List;
@Mapper
@@ -15,12 +16,12 @@
    List<Double> overview(@Param("areaId")String areaId);
    List<DtOrderVo> recentOrder(@Param("startTime")String startTime, @Param("endTime")String endTime);
    List<DtOrderVo> recentOrder(@Param("startTime") Date startTime, @Param("endTime")Date endTime);
    List<DtInAndOutBoundVo> recentInBound(@Param("areaId")String areaId, @Param("startTime")String startTime, @Param("endTime")String endTime);
    List<DtInAndOutBoundVo> recentInBound(@Param("areaId")String areaId, @Param("startTime")Date startTime, @Param("endTime")Date endTime);
    List<DtInAndOutBoundVo> recentOutBound(@Param("areaId")String areaId, @Param("startTime")String startTime, @Param("endTime")String endTime);
    List<DtInAndOutBoundVo> recentOutBound(@Param("areaId")String areaId, @Param("startTime")Date startTime, @Param("endTime")Date endTime);
    List<DtDetainMatVo> recentDetainMat(@Param("areaId")String areaId, @Param("startTime")String startTime,
    List<DtDetainMatVo> recentDetainMat(@Param("areaId")String areaId, @Param("startTime")Date startTime,
                                        @Param("pageIndex")Integer pageIndex, @Param("pageSize")Integer pageSize);
}
src/main/java/com/zy/asrs/service/DigitalTwinService.java
@@ -67,4 +67,6 @@
     *
     */
    void locNumCount();
    DtEquipmentVo equipment(String areaId);
}
src/main/java/com/zy/asrs/service/RcsService.java
@@ -63,4 +63,9 @@
     * @return
     */
    JSONObject hxApplyInLine(TransParent apply);
    /**
     * 2.1.12 存储对象与搬运对象绑定解绑接口
     */
    RcsReturn siteBind(SiteBind siteBind);
}
src/main/java/com/zy/asrs/service/impl/DigitalTwinServiceImpl.java
@@ -1,15 +1,22 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.entity.BasCrnp;
import com.zy.asrs.entity.LocCount;
import com.zy.asrs.entity.LocDetl;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.digitaltwin.*;
import com.zy.asrs.mapper.DigitalTwinMapper;
import com.zy.asrs.mapper.LocCountMapper;
import com.zy.asrs.service.BasCrnpService;
import com.zy.asrs.service.DigitalTwinService;
import com.zy.asrs.service.LocMastService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
@@ -57,24 +64,32 @@
     */
    public List<DtOrderVo> order(String startDate, String endDate) {
        String startTime;
        String endTime;
        Date startTime = new Date();
        Date endTime = new Date();
        if (startDate == null || endDate == null || startDate.isEmpty() || endDate.isEmpty()){
            Date now = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(now);
            calendar.add(Calendar.DAY_OF_MONTH, -7);
            Date start = calendar.getTime();
            startTime = calendar.getTime();
            endTime = now;
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            endDate = sdf.format(now);
            startDate = sdf.format(start);
        } else {
            SimpleDateFormat sdf =
                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
            try {
                startTime  = sdf.parse(startDate);
                endTime = sdf.parse(endDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        startTime = startDate.substring(0, 4) + "-" + startDate.substring(4, 6) + "-" + startDate.substring(6, 8) + "00:00:00";
        endTime = endDate.substring(0, 4) + "-" + endDate.substring(4, 6) + "-" + endDate.substring(6, 8) + "00:00:00";
        List<DtOrderVo> dbOrder = digitalTwinMapper.recentOrder(startTime, endTime);
        // 空日期补全
        for (DtOrderVo dtOrderVo : dbOrder) {
            dtOrderVo.setOrderDate(dtOrderVo.getOrderDate());
        }
        return dbOrder;
    }
@@ -89,27 +104,34 @@
     */
    public List<DtInAndOutBoundVo> inAndOutBound(String areaId, String startDate, String endDate) {
        List<DtInAndOutBoundVo> dtInAndOutBoundVos = new ArrayList<>();
        String startTime;
        String endTime;
        Date startTime = new Date();
        Date endTime = new Date();
        if (startDate == null || endDate == null || startDate.isEmpty() || endDate.isEmpty()){
            Date now = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(now);
            calendar.add(Calendar.DAY_OF_MONTH, -7);
            Date start = calendar.getTime();
            startTime = calendar.getTime();
            endTime = now;
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            endDate = sdf.format(now);
            startDate = sdf.format(start);
        } else {
            SimpleDateFormat sdf =
                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
            try {
                startTime  = sdf.parse(startDate);
                endTime = sdf.parse(endDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        startTime = startDate.substring(0, 4) + "-" + startDate.substring(4, 6) + "-" + startDate.substring(6, 8) + "00:00:00";
        endTime = endDate.substring(0, 4) + "-" + endDate.substring(4, 6) + "-" + endDate.substring(6, 8) + "00:00:00";
        List<DtInAndOutBoundVo> dtInBoundVos = digitalTwinMapper.recentInBound(areaId, startTime, endTime);
        List<DtInAndOutBoundVo> dtOutBoundVos = digitalTwinMapper.recentOutBound(areaId, startTime, endTime);
        // 格式整理
        List<DtInAndOutBoundVo> dtInAndOutBoundVos = new ArrayList<>(dtInBoundVos);
        dtInAndOutBoundVos.addAll(dtOutBoundVos);
        return dtInAndOutBoundVos;
    }
@@ -134,13 +156,14 @@
        calendar.setTime(now);
        calendar.add(Calendar.DAY_OF_MONTH, -overDayNum);
        Date start = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String startTime = sdf.format(start);
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        Date startTime = sdf.parse(start);
        List<DtDetainMatVo> dbDetainMats = digitalTwinMapper.recentDetainMat(areaId, startTime, pageIndex, pageSize);
        return dbDetainMats;
        return digitalTwinMapper.recentDetainMat(areaId, start, pageIndex, pageSize);
    }
    @Resource
    private LocMastService locMastService;
    /**
     * 查询库存和库位详细信息
@@ -149,31 +172,39 @@
     * @return
     */
    public List<DtLocDetailVo> warehouseDetail(String areaId) {
        List<DtLocDetailVo> locDetailVos = new ArrayList<>();
        List<LocMast> locMasts = new ArrayList<>();
        List<LocDetl> locDetls = new ArrayList<>();
        for (LocMast locMast : locMasts) {
            DtLocDetailVo dtLocDetailVo = new DtLocDetailVo();
            dtLocDetailVo.setLocMast(locMast);
            dtLocDetailVo.setLocNo(locMast.getLocNo());
            dtLocDetailVo.setLocSts(locMast.getLocSts());
            dtLocDetailVo.setRow1(locMast.getRow1());
            dtLocDetailVo.setBay1(locMast.getBay1());
            dtLocDetailVo.setLev1(locMast.getLev1());
            for (LocDetl locDetl : locDetls) {
                List<LocDetl> locDetl1 = locDetls.parallelStream().filter(a -> a.getLocNo().equals(locDetl.getLocNo())).collect(Collectors.toList());
                if (locDetl1 != null && locDetl1.size() == 1) {
                    dtLocDetailVo.setLocDetl(locDetl1.get(0));
                    dtLocDetailVo.setAreaId(locDetl.getAreaId());
                    dtLocDetailVo.setAreaName(locDetl.getAreaName());
                }
            }
            locDetailVos.add(dtLocDetailVo);
        }
        return locDetailVos;
        List<LocMast> locMastList = locMastService.selectList(new EntityWrapper<>());
        return locMastList.stream()
                .map(loc -> {
                    DtLocDetailVo vo = new DtLocDetailVo();
                    BeanUtils.copyProperties(loc, vo);
                    return vo;
                })
                .collect(Collectors.toList());
//        List<DtLocDetailVo> locDetailVos = new ArrayList<>();
//
//        List<LocMast> locMasts = new ArrayList<>();
//        List<LocDetl> locDetls = new ArrayList<>();
//
//        for (LocMast locMast : locMasts) {
//            DtLocDetailVo dtLocDetailVo = new DtLocDetailVo();
//            dtLocDetailVo.setLocMast(locMast);
//            dtLocDetailVo.setLocNo(locMast.getLocNo());
//            dtLocDetailVo.setLocSts(locMast.getLocSts());
//            dtLocDetailVo.setRow1(locMast.getRow1());
//            dtLocDetailVo.setBay1(locMast.getBay1());
//            dtLocDetailVo.setLev1(locMast.getLev1());
//            for (LocDetl locDetl : locDetls) {
//                List<LocDetl> locDetl1 = locDetls.parallelStream().filter(a -> a.getLocNo().equals(locDetl.getLocNo())).collect(Collectors.toList());
//                if (locDetl1 != null && locDetl1.size() == 1) {
//                    dtLocDetailVo.setLocDetl(locDetl1.get(0));
//                    dtLocDetailVo.setAreaId(locDetl.getAreaId());
//                    dtLocDetailVo.setAreaName(locDetl.getAreaName());
//                }
//            }
//            locDetailVos.add(dtLocDetailVo);
//        }
//
//        return locDetailVos;
    }
    /**
@@ -201,11 +232,11 @@
        }
        List<LocCount> locCounts;
        if(areaId.isEmpty()){
//        if(areaId.isEmpty()){
            locCounts = locCountMapper.getByDate(Integer.parseInt(startDate), Integer.parseInt(endDate));
        } else {
            locCounts = locCountMapper.getByAreaAndDate(areaId, Integer.parseInt(startDate), Integer.parseInt(endDate));
        }
//        } else {
//            locCounts = locCountMapper.getByAreaAndDate(areaId, Integer.parseInt(startDate), Integer.parseInt(endDate));
//        }
        for (LocCount locCount : locCounts) {
            String date = locCount.getDate().toString();
@@ -225,29 +256,30 @@
     *
     */
    public void locNumCount() {
        List<LocCount> result = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String date = sdf.format(new Date());
        List<LocCount> totalLoc = locCountMapper.totalLoc();
        List<LocCount> useLoc = locCountMapper.useLoc();
        for (LocCount locCount : totalLoc) {
            LocCount locCount1 = new LocCount();
            locCount1.setDate(Integer.valueOf(date));
            locCount1.setAreaId(locCount.getAreaId());
            locCount1.setLocNum(locCount1.getLocNum());
            for (LocCount locCount2 : useLoc) {
                if(locCount1.getAreaId().equals(locCount2.getAreaId())){
                    locCount1.setRemainNum(locCount1.getLocNum() - locCount2.getLocNum());
                }
            }
            result.add(locCount1);
        }
        for (LocCount locCount  : result) {
            locCountMapper.insertOrUpdate(locCount);
        }
        LocCount locCount1 = new LocCount();
        locCount1.setDate(Integer.valueOf(date));
        locCount1.setLocNum(totalLoc.get(0).getLocNum());
        locCount1.setRemainNum(locCount1.getLocNum() - useLoc.get(0).getLocNum());
        locCountMapper.insertOrUpdate(locCount1);
    }
    @Resource
    private BasCrnpService basCrnpService;
    @Override
    public DtEquipmentVo equipment(String areaId) {
        BasCrnp crnp = basCrnpService.selectOne(new EntityWrapper<>());
        return DtEquipmentVo.builder()
                .equipmentId("1").equipmentName("堆垛机1").equipmentType(1)
                .belongAreaId("A").belongAreaName("加工库").verticalSpeed(Integer.valueOf(Cools.isEmpty(crnp.getCtlHp()) ? "0" : crnp.getCtlHp()))
                .horizontalSpeed(Integer.valueOf( Cools.isEmpty(crnp.getCtlRest()) ? "0" : crnp.getCtlRest())).voltage(220).status(crnp.getCrnErr() == 0 ? 1 : 3).operateMethod(crnp.getCrnSts() == 3 ? 1 : 3).build();
    }
src/main/java/com/zy/asrs/service/impl/MesServiceImpl.java
@@ -1,1405 +1 @@
package com.zy.asrs.service.impl;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.core.common.SnowflakeIdWorker;
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.mes.*;
import com.zy.asrs.entity.rcs.*;
import com.zy.asrs.mapper.AgvInfoMapper;
import com.zy.asrs.mapper.MatItemBarcodeMapper;
import com.zy.asrs.service.*;
import com.zy.asrs.utils.OrderInAndOutUtil;
import com.zy.common.model.LocDetlDto;
import com.zy.common.model.enums.WorkNoType;
import com.zy.common.service.CommonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Service
public class MesServiceImpl implements MesService {
    @Value("${mes.url}")
    public String MES_URL;
    @Value("${wms.currentName}")
    public String WMS_CURRENT_NAME;
    @Value("${wms.wmsTransStartStation1}")
    public String WMS_TRANS_START_STATION_1;
    @Value("${wms.wmsTransStartStation2}")
    public String WMS_TRANS_START_STATION_2;
    @Value("${wms.wmsTransStartStation3}")
    public String WMS_TRANS_START_STATION_3;
    @Value("${mes.defaultUserId}")
    public long defaultUserId;
    @Value("${wms.zpalletId}")
    public String WMS_ZPALLET_ID;
    @Resource
    private RcsService rcsService;
    @Resource
    private MatService matService;
    @Resource
    private TagService tagService;
    @Resource
    private OrderPakinService orderPakinService;
    @Resource
    private OrderDetlPakinService orderDetlPakinService;
    @Resource
    private OrderPakoutService orderPakoutService;
    @Resource
    private OrderDetlPakoutService orderDetlPakoutService;
    @Resource
    private WaitPakinService waitPakinService;
    @Resource
    private TaskService taskService;
    @Resource
    private TaskDetlService taskDetlService;
    @Resource
    private SnowflakeIdWorker snowflakeIdWorker;
    @Resource
    private CommonService commonService;
    @Resource
    private AgvInfoMapper agvInfoMapper;
    @Resource
    private WorkService workService;
    @Resource
    private MatItemBarcodeMapper matItemBarcodeMapper;
    @Resource
    private LocMastService locMastService;
    @Resource
    private LocDetlService locDetlService;
    @Resource
    private MobileService mobileService;
    @Resource
    private WrkMastService wrkMastService;
    @Resource
    private WrkDetlService wrkDetlService;
    // region MES接口
    /**
     * 物料信息同步,MES->WMS
     * 功能:同步物料信息->生成入库单
     * 后续流程:入库时,需要实时调用recvFeedback返回入库数量
     *
     * @param matRecvForm
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public MesReturn matInfoAndInBound(MesMatRecvForm matRecvForm) throws CoolException {
        MesReturn mesReturn = new MesReturn();
        // 1、物料信息同步
        for (MesMatInfo mesMatInfo : matRecvForm.getItemdata()) {
            if (synMatInfo(mesMatInfo) == 1) {
            } else {
                throw new CoolException("同步物料信息失败");
            }
        }
        // 2、生成入库单
        if (inBoundOrder_List(matRecvForm) == 1) {
            mesReturn.setSuccess("1");
            mesReturn.setMessage("");
        } else {
            throw new CoolException("同步物料信息,生成入库单失败");
        }
        return mesReturn;
    }
    /**
     * 新增、修改物料信息
     *
     * @param mesMatInfo
     * @return 1 成功;-1 保存物料类型失败;-2 保存物料失败;
     * @throws ParseException
     */
    public int synMatInfo(MesMatInfo mesMatInfo) {
        // 规则定义:默认第2层为库名(如:加工库),第3层为同步的物料类型
        long secondPath = 2;
        String secondParentName = WMS_CURRENT_NAME;
        Date now = new Date();
        // 物料类型更新
        long tagId = 0;
        EntityWrapper<Tag> wrapper = new EntityWrapper<>();
        wrapper.eq("name", mesMatInfo.getItemType());
        Tag tag = tagService.selectByName(mesMatInfo.getItemType(), 3);
        if (tag == null || StringUtils.isEmpty(tag.getName())) {
            Tag newTag = new Tag();
            newTag.setName(mesMatInfo.getItemType());
            newTag.setParentId(secondPath);
            newTag.setParentName(secondParentName);
            newTag.setPath("2");
            newTag.setPathName(secondParentName);
            newTag.setLevel(3);
            newTag.setStatus(1);
            newTag.setCreateBy(defaultUserId);
            newTag.setCreateTime(now);
            newTag.setUpdateBy(defaultUserId);
            newTag.setUpdateTime(now);
            if (!tagService.insert(newTag))
                return -1;
            tagId = newTag.getId();
        } else {
            tagId = tag.getId();
        }
        // 物料更新
        if (tagId > 0) {
            //        tagId = tagService.selectByName(mesMatInfo.getItem_type(), 3).getId();
            Mat mat = matService.selectByMatnr(mesMatInfo.getItemNo());
            Mat newMat = new Mat();
            newMat.setMatnr(mesMatInfo.getItemNo());
            newMat.setMaktx(mesMatInfo.getDescription());
            newMat.setTagId(tagId);
            newMat.setLocType(tagId);   //locType
            newMat.setSpecs(mesMatInfo.getSpecification());
            newMat.setUnit(mesMatInfo.getUnitOfMeasure());
            newMat.setModel(mesMatInfo.getClassificationCode());
            newMat.setMemo(JSONObject.toJSONString(mesMatInfo));
            newMat.setCreateBy(defaultUserId);
            newMat.setCreateTime(now);
            newMat.setUpdateBy(defaultUserId);
            newMat.setUpdateTime(now);
            newMat.setStatus(1);
            if (mat == null) {
                if (!matService.insert(newMat))
                    return -2;
            } else {
                JSONObject dbMemo = JSONObject.parseObject(mat.getMemo());
                dbMemo.remove("OrderNo");
                dbMemo.remove("qty");
                dbMemo.remove("ItemBarcode");
                JSONObject newMemo = JSONObject.parseObject(newMat.getMemo());
                newMemo.remove("OrderNo");
                newMemo.remove("qty");
                dbMemo.remove("ItemBarcode");
                if (!dbMemo.equals(newMemo)) {
                    newMat.setId(mat.getId());
                    if (!matService.updateById(newMat))
                        return -2;
                }
            }
        } else {
            return -1;
        }
        return 1;
    }
    /**
     * 物料同步入库单,按OrderNo生成多个订单
     *
     *
     * @param matRecvForm
     * @return
     */
    public int inBoundOrder_List(MesMatRecvForm matRecvForm){
        long docType = 4;   // docType根据库类型确定
        long settle = 1;
        Date now = new Date();
        // 按OrderNo分组,然后再生成入库单
        List<MesMatInfo> mesInApply = matRecvForm.getItemdata();
        Map<String, List<MesMatInfo>> map = mesInApply.stream().collect(Collectors.groupingBy(MesMatInfo::getOrderNo));
        for (Map.Entry<String, List<MesMatInfo>> entry : map.entrySet()) {
            List<MesMatInfo> list = entry.getValue();
            // 校验订单是否重复
            OrderPakin order = orderPakinService.selectByNo(entry.getKey());
            if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
                return -1;
            }
            // 生成订单
            JSONObject newMemo = new JSONObject();
            newMemo.put("sourceNo", matRecvForm.getSourceNo());
            newMemo.put("sourceName", matRecvForm.getSourceName());
            newMemo.put("operuser", matRecvForm.getOperuser());
            newMemo.put("itemdata", list);
            OrderPakin orderPakin = new OrderPakin();
            orderPakin.setUuid(String.valueOf(snowflakeIdWorker.nextId()));
            orderPakin.setOrderNo(entry.getKey());
            orderPakin.setOrderTime(com.core.common.DateUtils.convert(now));
            orderPakin.setDocType(docType);
            orderPakin.setSettle(settle);
            orderPakin.setStatus(1);
            orderPakin.setCreateBy(defaultUserId);
            orderPakin.setCreateTime(now);
            orderPakin.setUpdateBy(defaultUserId);
            orderPakin.setUpdateTime(now);
            orderPakin.setMemo(newMemo.toJSONString());  //为领料入库完成反馈保存   JSONObject.toJSONString(matRecvForm)
            orderPakin.setPakinPakoutStatus(1);
            if (!orderPakinService.insert(orderPakin)) {
                log.error("MES保存入库订单主档失败");
                throw new CoolException("保存入库订单主档失败");
            }
            // 生成明细
            for (MesMatInfo mesMat : list) {
                Mat mat = matService.selectByMatnr(mesMat.getItemNo());
                OrderDetlPakin orderDetlPakin = new OrderDetlPakin();
                orderDetlPakin.setOrderId(orderPakin.getId());
                orderDetlPakin.setOrderNo(orderPakin.getOrderNo());
                orderDetlPakin.setAnfme(Double.valueOf(mesMat.getQty()));
                orderDetlPakin.setQty(0.0);
                orderDetlPakin.setMatnr(mat.getMatnr());
                orderDetlPakin.setMaktx(mat.getMaktx());
                orderDetlPakin.setSpecs(mat.getSpecs());
                orderDetlPakin.setModel(mat.getModel());
                orderDetlPakin.setStandby1(barCodeListToStr(mesMat.getItemBarcode()));   // 零件二维码
                orderDetlPakin.setStandby2("1");  //保存齐套性检查标识,1 检查;0 不检查;
                orderDetlPakin.setCreateBy(defaultUserId);
                orderDetlPakin.setCreateTime(now);
                orderDetlPakin.setUpdateBy(defaultUserId);
                orderDetlPakin.setUpdateTime(now);
                orderDetlPakin.setStatus(1);
                orderDetlPakin.setPakinPakoutStatus(1);
                if (!orderDetlPakinService.insert(orderDetlPakin)) {
                    log.error("MES保存入库订单明细档失败1");
                    throw new CoolException("保存入库订单明细档失败1");
                }
            }
        }
        return 1;
    }
    /**
     * 领料入库反馈
     * 触发条件:物料同步接口入库单,入库后
     * 推送时机:当订单中有物料入库后(应该在每托入库完成后,可以在更新OrderDetlPakin之后)则推送,不等全部订单完成
     *
     * @param orderNo
     * @param zapplet
     * @return
     */
    public int recvFeedback(String orderNo, String zapplet) {
        OrderPakin order = orderPakinService.selectByNo(orderNo);
        if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
            List<MesRecvFeedback.MesRecvFeedbackItem> list = new ArrayList<>();
            JSONObject dbMemo = JSONObject.parseObject(order.getMemo());
            // 从组托信息中查询入库的信息
            EntityWrapper<WaitPakin> waitPakinEntityWrapper = new EntityWrapper<>();
            waitPakinEntityWrapper.eq("zpallet", zapplet);
            List<WaitPakin> zpalletMat = waitPakinService.selectList(waitPakinEntityWrapper);
            EntityWrapper<OrderDetlPakin> wrapper = new EntityWrapper<>();
            wrapper.eq("order_no", orderNo);
            List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectList(wrapper);
            if (orderDetlPakins != null && !orderDetlPakins.isEmpty()) {
                for (OrderDetlPakin orderDetl : orderDetlPakins) {
                    for (WaitPakin zMat : zpalletMat) {
                        if (orderDetl.getMatnr().equals(zMat.getMatnr())) {
                            MesRecvFeedback.MesRecvFeedbackItem item = new MesRecvFeedback.MesRecvFeedbackItem();
                            item.setItemNo(orderDetl.getMatnr());
                            item.setOrderNo(orderNo);
                            item.setQty(orderDetl.getAnfme().intValue());
                            item.setRealQty(zMat.getAnfme().intValue());
                            // 回传托盘绑定的零件二维码
                            EntityWrapper<MatItemBarcode> matItemBarcodeEntityWrapper = new EntityWrapper<>();
                            matItemBarcodeEntityWrapper.eq("zapplet", zapplet).eq("status", 1);
                            List<MatItemBarcode> barcodes = matItemBarcodeMapper.selectList(matItemBarcodeEntityWrapper);
                            if (barcodes != null) {
                                List<String> itemBarcode = new ArrayList<>();
                                for (MatItemBarcode barcode : barcodes) {
                                    itemBarcode.add(barcode.getItemBarcode());
                                }
                                item.setItemBarcode(itemBarcode);
                                list.add(item);
                            }
                        }
                    }
                }
            }
            MesRecvFeedback mesRecvFeedback = new MesRecvFeedback();
            mesRecvFeedback.setSourceNo(dbMemo.getString("sourceNo"));
            mesRecvFeedback.setOperuser(dbMemo.getString("operuser"));
            mesRecvFeedback.setItemdata(list);
            String url = MES_URL + "MaterialReceiptAndReturn";
            String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesRecvFeedback));
            if (!StringUtils.isEmpty(response) && response.contains("Success")){
                MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                if("1".equals(mesReturn.getSuccess())) {
                    return 1;
                }
            }
        }
        return 0;
    }
    /**
     * 出库申请,加工库、刀具库
     * 出库后需要自动呼叫AGV送货
     * 出库规则:需要按零件二维码(一件一码)出库,整托出库,该托上有其他物料也一起出库,他们后期会再入库
     *
     * @param mesOutApply
     * @return 1 成功;-1 订单重复;
     */
    @Transactional
    public int outBoundOrder(MesOutApply mesOutApply){
        // 空托出库
        if (StringUtils.isEmpty(mesOutApply.getOrderNo()) && "01".equals(mesOutApply.getTransType())) {
            // 生成空托出库任务
            mobileService.callEmptyBinOutBound(mesOutApply,mesOutApply.getStationId().startsWith("LL") ? WMS_TRANS_START_STATION_3 : WMS_TRANS_START_STATION_1,"1",1,defaultUserId);
//            try {
//                if (!StringUtils.isEmpty(mesOutApply.getTaskno()) && !StringUtils.isEmpty(mesOutApply.getStationId())) {
//                    TransTask transTask = new TransTask();
//                    transTask.setTaskno(mesOutApply.getTaskno());
//                    transTask.setTaskname(mesOutApply.getTaskname());
//                    transTask.setOrderNo(mesOutApply.getOrderNo());
//                    transTask.setTransType(mesOutApply.getTransType());
//                    transTask.setCurStationId(WMS_TRANS_START_STATION_1);
//                    transTask.setNextProcess(mesOutApply.getProductLineId());
//                    transTask.setNextStationId(mesOutApply.getStationId());
//                    transTask.setItemno(WMS_ZPALLET_ID);  // 固定为空托的编码
//                    transTask.setQty(1);    // 空托只出1个
//                    transTask.setProductLineId(mesOutApply.getProductLineId());
//                    transTask.setOperateType(1);
//                    transTask.setAgvFactory(1);
//                    JSONObject sendAgvTask = submitTask(transTask);
//                    if (!"1".equals(sendAgvTask.getString("Success"))) {
//                        log.error("出库下发agv运输任务失败:{}", JSONObject.toJSONString(transTask));
//                    }
//                }
//            } catch (Exception e) {
//                log.error("下发AGV运输任务失败", e);
//            }
            return 1;
        } else {    // 毛坯(物料)出库
            // docType根据库类型确定
            long docType = 7;
            long settle = 2;
            // 校验订单是否重复
            OrderPakout order = orderPakoutService.selectByNo(mesOutApply.getOrderNo());
            if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
                log.error("出库订单号重复:{}",mesOutApply.getOrderNo());
                return -1;
            }
            String itemBarcode = barCodeListToStr(mesOutApply.getItemBarcode());
            // 自动出库
            LocDetl locDetl = locDetlService.selectOne(new EntityWrapper<LocDetl>().eq("standby1", itemBarcode));
            if (locDetl == null) {
                throw new CoolException("零件二维码没有匹配到库存:" +itemBarcode );
            }
            LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", locDetl.getLocNo()));
            if (!locMast.getLocSts().equals("F")) {
                throw new CoolException("库位状态不为F:" +locMast.getLocNo() );
            }
            // 生成订单
            Date now = new Date();
            OrderPakout orderPakout = new OrderPakout();
            orderPakout.setUuid( String.valueOf(snowflakeIdWorker.nextId()));
            orderPakout.setOrderNo(mesOutApply.getOrderNo());
            orderPakout.setOrderTime(com.core.common.DateUtils.convert(now));
            orderPakout.setDocType(docType);
            orderPakout.setSettle(settle);
            orderPakout.setStatus(1);
            orderPakout.setCreateBy(defaultUserId);
            orderPakout.setCreateTime(now);
            orderPakout.setUpdateBy(defaultUserId);
            orderPakout.setUpdateTime(now);
            orderPakout.setMemo(JSONObject.toJSONString(mesOutApply));
            orderPakout.setPakinPakoutStatus(2);
            orderPakout.setNumber(locMast.getBarcode()); // 托盘条码,上报时用
            if (!orderPakoutService.insert(orderPakout)) {
                log.error("MES保存出库订单主档失败");
                throw new CoolException("保存出库订单主档失败");
            }
            // 生成明细
            Mat mat = matService.selectByMatnr(mesOutApply.getItemno());
            OrderDetlPakout orderDetlPakout = new OrderDetlPakout();
            orderDetlPakout.setOrderId(orderPakout.getId());
            orderDetlPakout.setOrderNo(orderPakout.getOrderNo());
            orderDetlPakout.setAnfme(Double.valueOf(mesOutApply.getQty()));
            orderDetlPakout.setWorkQty(orderDetlPakout.getAnfme());
            orderDetlPakout.setQty(0.0);
            orderDetlPakout.setMatnr(mat.getMatnr());
            orderDetlPakout.setMaktx(mat.getMaktx());
            orderDetlPakout.setSpecs(mat.getSpecs());
            orderDetlPakout.setModel(mat.getModel());
            orderDetlPakout.setStandby1(itemBarcode);
            orderDetlPakout.setCreateBy(defaultUserId);
            orderDetlPakout.setCreateTime(now);
            orderDetlPakout.setUpdateBy(defaultUserId);
            orderDetlPakout.setUpdateTime(now);
            orderDetlPakout.setStatus(1);
            orderDetlPakout.setPakinPakoutStatus(2);
            if (!orderDetlPakoutService.insert(orderDetlPakout)) {
                log.error("MES保存出库订单明细档失败");
                throw new CoolException("保存出库订单明细档失败");
            }
            // 生成工作号
            int workNo = commonService.getWorkNo(WorkNoType.getWorkNoType(101));
            // 生成工作档
            WrkMast wrkMast = new WrkMast();
            wrkMast.setWrkNo(workNo);
            wrkMast.setIoTime(now);
            wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID
            wrkMast.setIoType(101); // 入出库状态
            wrkMast.setIoPri(13D); // 优先级:13
            wrkMast.setCrnNo(1);
            if(mesOutApply.getStationId().startsWith("LL")) {
                wrkMast.setSourceStaNo("203"); // 源站
                wrkMast.setStaNo("204"); // 目标站
            } else {
                wrkMast.setSourceStaNo("205"); // 源站
                wrkMast.setStaNo("205"); // 目标站
            }
            wrkMast.setSourceLocNo(locMast.getLocNo()); // 源库位
            wrkMast.setFullPlt("Y"); // 满板:Y
            wrkMast.setPicking("N"); // 拣料
            wrkMast.setExitMk("N"); // 退出
            wrkMast.setEmptyMk("N"); // 空板
            wrkMast.setLinkMis("N");
            wrkMast.setBarcode(locMast.getBarcode());
            wrkMast.setAppeUser(defaultUserId); // 操作人员数据
            wrkMast.setAppeTime(now);
            wrkMast.setModiUser(defaultUserId);
            wrkMast.setModiTime(now);
            wrkMast.setMemo(JSONObject.toJSONString(mesOutApply));
            wrkMast.setTaskNo(mesOutApply.getTaskno());
            wrkMast.setAgvSta(mesOutApply.getStationId());
            wrkMastService.insert(wrkMast);
            // 生成工作档明细
                WrkDetl wrkDetl = new WrkDetl();
                wrkDetl.sync(locDetl);
                wrkDetl.setOrderNo(orderPakout.getOrderNo()); // 手动出库不需要带出库存中的单据编号
                wrkDetl.setWrkNo(workNo);
                wrkDetl.setIoTime(now);
                wrkDetl.setAnfme(orderDetlPakout.getAnfme()); // 数量
                wrkDetl.setAppeTime(now);
                wrkDetl.setAppeUser(defaultUserId);
                wrkDetl.setModiTime(now);
                wrkDetl.setModiUser(defaultUserId);
//                wrkDetl.setMatnr(detlDto.getLocDetl().getMatnr());
//                wrkDetl.setMaktx(detlDto.getLocDetl().getMaktx());
//                wrkDetl.setUnit(detlDto.getLocDetl().getUnit());
//                wrkDetl.setSpecs(detlDto.getLocDetl().getSpecs());
//                wrkDetl.setUnit(detlDto.getLocDetl().getUnit());
//                wrkDetl.setModel(detlDto.getLocDetl().getModel());
                wrkDetlService.insert(wrkDetl);
            // 修改库位状态:   F.在库 ====>>> R.出库预约/P.拣料/盘点/并板出库中
            if (locMast.getLocSts().equals("F")) {
                locMast.setLocSts("R");
                locMast.setModiUser(defaultUserId);
                locMast.setModiTime(now);
                locMastService.updateById(locMast);
            }
            log.info("出库任务生成成功,任务号:{}",workNo);
            // 立库生成订单后,自动调度AGV运送到站点,目前多托生成多个。
//            try {
//                if (!StringUtils.isEmpty(mesOutApply.getTaskno()) && !StringUtils.isEmpty(mesOutApply.getStationId())) {
//                    // 按零件二维码查询有几个托,多托生成多个任务,每托对应零件二维码
////                    String barCode = barCodeListToStr(mesOutApply.getItemBarcode());
////                    EntityWrapper<MatItemBarcode> matItemBarcodeEntityWrapper = new EntityWrapper<>();
////                    matItemBarcodeEntityWrapper.in("item_barcode", barCode);
////                    List<MatItemBarcode> barcodes = matItemBarcodeMapper.selectList(matItemBarcodeEntityWrapper);
////                     if (barcodes != null) {
////                        Map<String, List<MatItemBarcode>> map = barcodes.stream().collect(Collectors.groupingBy(MatItemBarcode::getZapplet));
////                        for (Map.Entry<String, List<MatItemBarcode>> entry : map.entrySet()) {
////                            List<MatItemBarcode> list = entry.getValue();
////                            List<String> codes = new ArrayList<>();
////                            for (MatItemBarcode zapllet : list) {
////                                codes.add(zapllet.getItemBarcode());
////                            }
//
//                            TransTask transTask = new TransTask();
//                            transTask.setTaskno(mesOutApply.getTaskno());
//                            transTask.setTaskname(mesOutApply.getTaskname());
//                            transTask.setOrderNo(mesOutApply.getOrderNo());
//                            transTask.setTransType(mesOutApply.getTransType());
//                            transTask.setCurStationId(WMS_TRANS_START_STATION_3);
//                            transTask.setNextProcess(mesOutApply.getProductLineId());
//                            transTask.setNextStationId(mesOutApply.getStationId());
//                            transTask.setItemno(mesOutApply.getItemno());
//                            transTask.setQty(mesOutApply.getQty());
//                            transTask.setProductLineId(mesOutApply.getProductLineId());
//                            transTask.setItemBarcode(mesOutApply.getItemBarcode());
//                            transTask.setTuoPanId(locDetl.getZpallet());
//                            transTask.setOperateType(1);
//                            transTask.setAgvFactory(1);
//                            JSONObject sendAgvTask = submitTask(transTask);
//                            if (!"1".equals(sendAgvTask.getString("Success"))) {
//                                log.error("出库下发agv运输任务失败", JSONObject.toJSONString(transTask));
//                            }
////                        }
////                    }
//                }
//            } catch (Exception e) {
//                log.error("下发AGV运输任务失败", e);
//            }
        }
        return 1;
    }
    /**
     * 入库申请
     * 收到入库申请后自动呼叫AGV取货
     *
     * @param mesInApply
     */
    @Transactional
    public int inBoundOrder(MesInApply mesInApply){
        // 空托回库
        if (StringUtils.isEmpty(mesInApply.getOrderNo()) && StringUtils.isEmpty(mesInApply.getItemno())) {
                if (!StringUtils.isEmpty(mesInApply.getTaskno()) && !StringUtils.isEmpty(mesInApply.getStationID())) {
                    TransTask transTask = new TransTask();
                    transTask.setTaskno(mesInApply.getTaskno());
                    transTask.setTaskname(mesInApply.getTaskname());
                    transTask.setOrderNo(mesInApply.getOrderNo());
                    transTask.setTransType(mesInApply.getTransType());
                    transTask.setCurProcess(mesInApply.getProductLineId());
                    transTask.setCurStationId(mesInApply.getStationID());
                    transTask.setNextStationId(mesInApply.getStationID().startsWith("LL") ? WMS_TRANS_START_STATION_2 : WMS_TRANS_START_STATION_1);
                    transTask.setItemno(WMS_ZPALLET_ID);  // 固定为空托的编码
                    transTask.setQty(1);    // 空托只回1个
                    transTask.setProductLineId(mesInApply.getProductLineId());
                    transTask.setOperateType(1);
                    transTask.setAgvFactory(1);
                    JSONObject sendAgvTask = submitTask(transTask);
                    if (!"1".equals(sendAgvTask.getString("Success"))) {
                        log.error("入库下发agv运输任务失败,{}", JSONObject.toJSONString(transTask));
                        return 2;
                    }
                } else {
                    log.error("无任务号:{},或无物料编码:{}",mesInApply.getTaskno(),mesInApply.getItemno() );
                    return 2;
                }
            return 1;
        } else {    // 毛坯、成品回库
            // docType根据库类型确定
            long docType = 3;
            long settle = 1;
            // 校验订单是否重复
            OrderPakin order = orderPakinService.selectByNo(mesInApply.getOrderNo());
            if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
                log.error("订单重复:{}", mesInApply.getOrderNo());
                return 2;
            }
            // 生成订单
            Date now = new Date();
            OrderPakin orderPakin = new OrderPakin();
            orderPakin.setUuid(String.valueOf(snowflakeIdWorker.nextId()));
            orderPakin.setOrderNo(mesInApply.getOrderNo());
            orderPakin.setOrderTime(com.core.common.DateUtils.convert(now));
            orderPakin.setDocType(docType);
            orderPakin.setSettle(settle);
            orderPakin.setStatus(1);
            orderPakin.setCreateBy(defaultUserId);
            orderPakin.setCreateTime(now);
            orderPakin.setUpdateBy(defaultUserId);
            orderPakin.setUpdateTime(now);
            orderPakin.setMemo(JSONObject.toJSONString(mesInApply));  //为出库完成反馈保存
            orderPakin.setPakinPakoutStatus(1);
            orderPakinService.insert(orderPakin);
            // 生成明细
            Mat mat = matService.selectByMatnr(mesInApply.getItemno());
            OrderDetlPakin orderDetlPakin = new OrderDetlPakin();
            orderDetlPakin.setOrderId(orderPakin.getId());
            orderDetlPakin.setOrderNo(orderPakin.getOrderNo());
            orderDetlPakin.setAnfme(Double.valueOf(mesInApply.getQty()));
            orderDetlPakin.setQty(0.0);
            orderDetlPakin.setMatnr(mat.getMatnr());
            orderDetlPakin.setMaktx(mat.getMaktx());
            orderDetlPakin.setSpecs(mat.getSpecs());
            orderDetlPakin.setModel(mat.getModel());
            List<String> itemBarcode = mesInApply.getProductInfo().stream().map(MesInApply.ProductInfo::getItemBarcode).collect(Collectors.toList());
            orderDetlPakin.setStandby1(barCodeListToStr(itemBarcode)); //零件详情存在1
            orderDetlPakin.setStandby2("0");  //保存齐套性检查标识,1 检查;0 不检查;
            orderDetlPakin.setCreateBy(defaultUserId);
            orderDetlPakin.setCreateTime(now);
            orderDetlPakin.setUpdateBy(defaultUserId);
            orderDetlPakin.setUpdateTime(now);
            orderDetlPakin.setStatus(1);
            orderDetlPakin.setPakinPakoutStatus(1);
            orderDetlPakinService.insert(orderDetlPakin);
            // 生成入库通知档
            WaitPakin waitPakin = new WaitPakin();
            BeanUtils.copyProperties(mat, waitPakin);
//                waitPakin.sync(mat);
            waitPakin.setOrderNo(orderPakin.getOrderNo());   // 单据编号
            waitPakin.setOrderId(orderPakin.getId());
            waitPakin.setZpallet(mesInApply.getTuoPanId());   // 托盘码
            waitPakin.setIoStatus("N");     // 入出状态
            waitPakin.setAnfme(orderDetlPakin.getAnfme());  // 数量
            waitPakin.setStatus("Y");    // 状态
            waitPakin.setAppeUser(defaultUserId);
            waitPakin.setAppeTime(now);
            waitPakin.setModiUser(defaultUserId);
            waitPakin.setModiTime(now);
            waitPakin.setStandby1(barCodeListToStr(itemBarcode));
            waitPakinService.insert(waitPakin);
            OrderInAndOutUtil.increaseWorkQty(Boolean.TRUE, orderPakin.getId(), orderDetlPakin.getMatnr(), orderDetlPakin.getBatch(),
                    orderDetlPakin.getBrand(), orderDetlPakin.getStandby1(), orderDetlPakin.getStandby2(), orderDetlPakin.getStandby3(),
                    orderDetlPakin.getBoxType1(), orderDetlPakin.getBoxType2(), orderDetlPakin.getBoxType3(), orderDetlPakin.getAnfme());
            OrderInAndOutUtil.updateOrder(Boolean.TRUE, orderPakin.getId(), 2L, defaultUserId);
            // 呼叫AGV从产线运回立库
                if (!StringUtils.isEmpty(mesInApply.getTaskno())) {
                    TransTask transTask = new TransTask();
                    transTask.setTaskno(mesInApply.getTaskno());
                    transTask.setTaskname(mesInApply.getTaskname());
                    transTask.setOrderNo(mesInApply.getOrderNo());
                    transTask.setTransType(mesInApply.getTransType());
                    transTask.setCurProcess(mesInApply.getProductLineId());
                    transTask.setCurStationId(mesInApply.getStationID());
                    transTask.setNextStationId(mesInApply.getStationID().startsWith("LL") ? WMS_TRANS_START_STATION_2 : WMS_TRANS_START_STATION_1);
                    transTask.setItemno(mesInApply.getItemno());
                    transTask.setQty(mesInApply.getQty());
                    transTask.setProductLineId(mesInApply.getProductLineId());
                    transTask.setItemBarcode(itemBarcode);
                    transTask.setTuoPanId(mesInApply.getTuoPanId());
                    transTask.setOperateType(1);
                    transTask.setAgvFactory(1);
                    JSONObject sendAgvTask = submitTask(transTask);
                    if (!"1".equals(sendAgvTask.getString("Success"))) {
                        log.error("入库下发agv运输任务失败:{}", JSONObject.toJSONString(transTask));
                        throw new CoolException("入库下发agv运输任务失败");
                    }
                } else {
                    throw new CoolException("MES入库下发agv运输任务失败");
                }
        }
        return 1;
    }
    /**
     * 出库完成
     * 出库后,按托推送,非整个订单
     *
     * @param orderNo
     * @return
     */
    public int outFeedbackByTuo(String orderNo, Task agvTask) {
        int success = 0;
        OrderPakout order = orderPakoutService.selectByNo(orderNo);
        if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
            JSONObject dbMemo = JSONObject.parseObject(order.getMemo());
            // TODO:出库完成后,若未解绑托盘和物料,则执行托盘解绑
            // TODO:出库完成后,若未清除零件二维码,则执行清除,也可以在AGV送货完成后清除
//            EntityWrapper<OrderDetlPakout> wrapper = new EntityWrapper<>();
//            wrapper.eq("order_no", orderNo);
//            List<OrderDetlPakout> orderDetlPakouts = orderDetlPakoutService.selectList(wrapper);
//            if (orderDetlPakouts != null && !orderDetlPakouts.isEmpty()) {
//                for (OrderDetlPakout orderDetl : orderDetlPakouts) {
//                    StringBuilder palletId = new StringBuilder();
//                    EntityWrapper<WaitPakin> wrapper2 = new EntityWrapper<>();
//                    wrapper2.eq("order_no", orderDetl.getOrderNo());
//                    List<WaitPakin> waitPakins = waitPakinService.selectList(wrapper2);
//                    if (waitPakins != null && waitPakins.size() > 0) {
//                        for (WaitPakin waitPakin : waitPakins) {
//                            palletId.append(waitPakin.getZpallet()).append(",");
//                        }
//                    }
//
//                    MesOutFeedback mesOutFeedback = new MesOutFeedback();
//                    mesOutFeedback.setTaskno(dbMemo.getString("taskno"));
//                    mesOutFeedback.setTaskname(dbMemo.getString("taskname"));
//                    mesOutFeedback.setProductLineId(dbMemo.getString("ProductLineId"));
//                    mesOutFeedback.setStationId(dbMemo.getString("StationID"));
//                    mesOutFeedback.setItemno(orderDetl.getMatnr());
//                    mesOutFeedback.setTuoPanId(zpalletId);
//                    mesOutFeedback.setQty(orderDetl.getQty().intValue());
//                    if (!StringUtils.isEmpty(dbMemo.getString("ItemBarcode"))) {
//                        mesOutFeedback.setItemBarcode(barCodeStrToList(dbMemo.getString("ItemBarcode")));
//                    }
//                    mesOutFeedback.setOrderNo(orderNo);
//                }
//            }
            EntityWrapper<TaskDetl> entityWrapper = new EntityWrapper<>();
            entityWrapper.eq("wrk_no", agvTask.getWrkNo());
            TaskDetl taskDetl = taskDetlService.selectOne(entityWrapper);
            String zpalletId = taskDetl.getZpallet();
            List<String> itemBarCode = new ArrayList<>();
            JSONArray array = JSONArray.parseArray(taskDetl.getMemo());
            for (Object one : array) {
                itemBarCode.add(one.toString());
                // TODO:入库时存储零件码(ItemBarCode),并绑定托盘,出库后这里考虑解绑
            }
            MesOutFeedback mesOutFeedback = new MesOutFeedback();
            mesOutFeedback.setTaskno(agvTask.getTaskNo());
            mesOutFeedback.setTaskname(dbMemo.getString("taskname"));
            mesOutFeedback.setProductLineId(dbMemo.getString("ProductLineId"));
            mesOutFeedback.setStationId(dbMemo.getString("StationId"));
            mesOutFeedback.setItemno(dbMemo.getString("Itemno"));
            mesOutFeedback.setTuoPanId(zpalletId);
            if (itemBarCode.size() > 0) {
                mesOutFeedback.setQty(itemBarCode.size());
                mesOutFeedback.setItemBarcode(itemBarCode);
            }
            mesOutFeedback.setOrderNo(orderNo);
            String url = MES_URL + "issueComplete";
            String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesOutFeedback));
            if (!StringUtils.isEmpty(response) && response.contains("Success")){
                MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                if("1".equals(mesReturn.getSuccess())) {
                    success = 1;
                }
            }
        }
        return success;
    }
    /**
     * 入库完成
     * 入库后,按托推送,非整个订单
     *
     * @param orderNo
     * @param zapplet
     * @return
     */
    public int inFeedbackByTuo(String orderNo, String zapplet) {
        int success = 0;
        OrderPakin order = orderPakinService.selectByNo(orderNo);
        if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
            List<MesInApply.ProductInfo> list = new ArrayList<>();
            // 从托盘绑定的零件二维码中查询信息
            EntityWrapper<MatItemBarcode> matItemBarcodeEntityWrapper = new EntityWrapper<>();
            matItemBarcodeEntityWrapper.eq("zapplet", zapplet).eq("status", 1);
            List<MatItemBarcode> barcodes = matItemBarcodeMapper.selectList(matItemBarcodeEntityWrapper);
            for (MatItemBarcode barcode : barcodes) {
                MesInApply.ProductInfo productInfo = new MesInApply.ProductInfo();
                productInfo.setItemBarcode(barcode.getItemBarcode());
                productInfo.setQualityStatus(barcode.getQualityStatus());
                list.add(productInfo);
            }
            MesInApply result = JSONObject.parseObject(order.getMemo(), MesInApply.class);
            result.setProductInfo(list);
            result.setQty(list.size());
            String url = MES_URL + "loadComplete";
            String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(result));
            if (!StringUtils.isEmpty(response) && response.contains("Success")){
                MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                if("1".equals(mesReturn.getSuccess())) {
                    success = 1;
                }
            }
        }
        return success;
    }
    /**
     * 零件二维码,数组转string
     *
     * @param list
     * @return
     */
    public static String barCodeListToStr(List<String> list) {
        if(list.isEmpty()) {
            return "";
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (String str : list) {
            stringBuilder.append(str).append(",");
        }
        String result = stringBuilder.toString();
        return result.endsWith(",") ? result.substring(0, result.length() - 1) : result;
    }
    /**
     * 零件二维码,string转数组
     *
     * @param str
     * @return
     */
    public static List<String> barCodeStrToList(String str) {
        String[] array = str.split(",");
        return Arrays.asList(array);
    }
    /**
     * 入库完成
     * 入库单完成后,整单推送
     *
     * @param orderNo
     * @return
     */
    public int inFeedback(String orderNo) {
        int success = 0;
        OrderPakin order = orderPakinService.selectByNo(orderNo);
        if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
            EntityWrapper<OrderDetlPakin> wrapper = new EntityWrapper<>();
            wrapper.eq("order_no", orderNo);
            List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectList(wrapper);
            if (orderDetlPakins != null && !orderDetlPakins.isEmpty()) {
                for (OrderDetlPakin orderDetl : orderDetlPakins) {
                    MesInApply result = JSONObject.parseObject(order.getMemo(), MesInApply.class);
                    result.setQty(orderDetl.getQty().intValue());
                    String url = MES_URL + "loadComplete";
                    String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(result));
                    if (!StringUtils.isEmpty(response) && response.contains("Success")){
                        MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                        if("1".equals(mesReturn.getSuccess())) {
                            success++;
                        }
                    }
                }
                if (success == orderDetlPakins.size()) {
                    success = 1;
                } else {
                    success = 0;
                }
            }
        }
        return success;
    }
    /**
     * (备份)出库订单完成
     *
     * @param orderNo
     * @return
     */
    public int outFeedback(String orderNo) {
        int success = 0;
        OrderPakout order = orderPakoutService.selectByNo(orderNo);
        if (order != null && order.getSettle() == 4) {   // 校验是否完成
            JSONObject dbMemo = JSONObject.parseObject(order.getMemo());
            EntityWrapper<OrderDetlPakout> wrapper = new EntityWrapper<>();
            wrapper.eq("order_no", orderNo);
            List<OrderDetlPakout> orderDetlPakouts = orderDetlPakoutService.selectList(wrapper);
            if (orderDetlPakouts != null && !orderDetlPakouts.isEmpty()) {
                for (OrderDetlPakout orderDetl : orderDetlPakouts) {
                    StringBuilder palletId = new StringBuilder();
                    EntityWrapper<WaitPakin> wrapper2 = new EntityWrapper<>();
                    wrapper2.eq("order_no", orderDetl.getOrderNo());
                    List<WaitPakin> waitPakins = waitPakinService.selectList(wrapper2);
                    if (waitPakins != null && waitPakins.size() > 0) {
                        for (WaitPakin waitPakin : waitPakins) {
                            palletId.append(waitPakin.getZpallet()).append(",");
                        }
                    }
                    MesOutFeedback mesOutFeedback = new MesOutFeedback();
                    mesOutFeedback.setTaskno(dbMemo.getString("taskno"));
                    mesOutFeedback.setTaskname(dbMemo.getString("taskname"));
                    mesOutFeedback.setProductLineId(dbMemo.getString("ProductLineId"));
                    mesOutFeedback.setStationId(dbMemo.getString("StationID"));
                    mesOutFeedback.setItemno(orderDetl.getMatnr());
                    if (!StringUtils.isEmpty(palletId.toString())) {
                        mesOutFeedback.setTuoPanId(palletId.substring(0, palletId.length() - 1));
                    }
                    mesOutFeedback.setQty(orderDetl.getQty().intValue());
                    if (!StringUtils.isEmpty(dbMemo.getString("ItemBarcode"))) {
                        mesOutFeedback.setItemBarcode(barCodeStrToList(dbMemo.getString("ItemBarcode")));
                    }
                    mesOutFeedback.setOrderNo(orderNo);
                    // TODO:备注:出库完成后解绑托盘和物料,若前面未解绑,此处需要解绑
                    String url = MES_URL + "issueComplete";
                    String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesOutFeedback));
                    if (!StringUtils.isEmpty(response) && response.contains("Success")){
                        MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                        if("1".equals(mesReturn.getSuccess())) {
                            success++;
                        }
                    }
                }
                if (success == orderDetlPakouts.size()) {
                    success = 1;
                    // TODO:立库出库后自动调度AGV运送到站点
                    String taskNo = dbMemo.getString("taskno");
                    if (!StringUtils.isEmpty(taskNo)) {
                        TransTask transTask = new TransTask();
                        transTask.setTaskno(dbMemo.getString("taskno"));
                        transTask.setTaskname(dbMemo.getString("taskname"));
                        transTask.setOrderNo(dbMemo.getString("OrderNo"));
                        transTask.setTransType(dbMemo.getString("TransType"));
//                    transTask.setCurProcess();
                        transTask.setCurStationId(WMS_TRANS_START_STATION_3);
                        transTask.setNextProcess(dbMemo.getString("ProductLineId"));
                        transTask.setNextStationId(dbMemo.getString("StationId"));
                        transTask.setItemno(dbMemo.getString("Itemno"));
                        transTask.setQty(dbMemo.getInteger("Qty"));
                        transTask.setProductLineId(dbMemo.getString("ProductLineId"));
                        transTask.setItemBarcode(barCodeStrToList(dbMemo.getString("ItemBarcode")));
                        transTask.setOperateType(1);
                        transTask.setAgvFactory(1);
                        JSONObject sendAgvTask = submitTask(transTask);
                        if (!"1".equals(sendAgvTask.getString("Success"))) {
                            log.error("出库下发agv运输任务失败:{}", JSONObject.toJSONString(transTask));
                        }
                    }
                } else {
                    success = 0;
                }
            }
        }
        return success;
    }
    /**
     * 出库申请(叫料),装配库、滑块库
     *
     * @param mesCallOutApply
     * @return
     */
    public int callOutBoundOrder(MesCallOutApply mesCallOutApply){
        // docType根据库类型确定
        long docType = 7;
        long settle = 1;
        // 校验订单是否重复
        OrderPakout order = orderPakoutService.selectByNo(mesCallOutApply.getOrderNo());
        if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
            return -1;
        }
        // 生成订单
        Date now = new Date();
        OrderPakout orderPakout = new OrderPakout();
        orderPakout.setUuid(String.valueOf(snowflakeIdWorker.nextId()));
        orderPakout.setOrderNo(mesCallOutApply.getOrderNo());
        orderPakout.setOrderTime(com.core.common.DateUtils.convert(now));
        orderPakout.setDocType(docType);
        orderPakout.setSettle(settle);
        orderPakout.setStatus(1);
        orderPakout.setCreateBy(defaultUserId);
        orderPakout.setCreateTime(now);
        orderPakout.setUpdateBy(defaultUserId);
        orderPakout.setUpdateTime(now);
        orderPakout.setMemo(JSONObject.toJSONString(mesCallOutApply));
        orderPakout.setPakinPakoutStatus(2);
        if (!orderPakoutService.insert(orderPakout)) {
            log.error("MES保存出库订单(叫料)主档失败");
            throw new CoolException("保存出库订单(叫料)主档失败");
        }
        // 生成明细
        if (mesCallOutApply.getItemdata() != null && !mesCallOutApply.getItemdata().isEmpty()) {
            for (MesCallOutApply.MesOutApplyItem mesOutApplyItem : mesCallOutApply.getItemdata()) {
                Mat mat = matService.selectByMatnr(mesOutApplyItem.getItemno());
                OrderDetlPakout orderDetlPakout = new OrderDetlPakout();
                orderDetlPakout.setOrderId(orderPakout.getId());
                orderDetlPakout.setOrderNo(orderPakout.getOrderNo());
                orderDetlPakout.setAnfme(Double.valueOf(mesOutApplyItem.getQty()));
                orderDetlPakout.setQty(0.0);
                orderDetlPakout.setMatnr(mat.getMatnr());
                orderDetlPakout.setMaktx(mat.getMaktx());
                orderDetlPakout.setSpecs(mat.getSpecs());
                orderDetlPakout.setModel(mat.getModel());
                orderDetlPakout.setThreeCode(mesOutApplyItem.getItemBarcode());
                orderDetlPakout.setStandby1(mesOutApplyItem.getTrayid());   //保存配盘号,非托盘号
                orderDetlPakout.setCreateBy(defaultUserId);
                orderDetlPakout.setCreateTime(now);
                orderDetlPakout.setUpdateBy(defaultUserId);
                orderDetlPakout.setUpdateTime(now);
                orderDetlPakout.setStatus(1);
                orderDetlPakout.setPakinPakoutStatus(2);
                if (!orderDetlPakoutService.insert(orderDetlPakout)) {
                    log.error("MES保存出库订单(叫料)明细档失败");
                    throw new CoolException("保存出库订单(叫料)明细档失败");
                }
            }
        }
        return 1;
    }
    // endregion
    // region 搬运任务调度
    // route转发3个WCS任务
    /**
     * 9.1下发运输任务
     *
     * @param transTask
     * @return
     */
    @Transactional
    public JSONObject submitTask(TransTask transTask) {
        JSONObject result = new JSONObject();
        result.put("taskno", transTask.getTaskno());
        // 重复性校验
        EntityWrapper<Task> wrapper = new EntityWrapper<>();
        wrapper.eq("task_no", transTask.getTaskno());
        List<Task> tasks = taskService.selectList(wrapper);
        if (tasks != null && !tasks.isEmpty()) {
            log.error("agv任务号重复:{}", transTask.getTaskno());
            result.put("Success", "2");
            result.put("Message", "agv任务号重复:" + transTask.getTaskno());
            return result;
        }
        // 下发给RCS
        RcsTaskSubmit rcsTaskSubmit = new RcsTaskSubmit();
        // 模板名
        if(transTask.getCurStationId().startsWith("LL") || transTask.getCurStationId().startsWith("LG")) { // 起点产线
            rcsTaskSubmit.setTaskType("CS2");
        } else if(transTask.getNextStationId().startsWith("LL") || transTask.getNextStationId().startsWith("LG")) { // 终点产线
            rcsTaskSubmit.setTaskType("CS");
        } else { // 不涉及产线
            rcsTaskSubmit.setTaskType("CS3");
        }
        rcsTaskSubmit.setRobotTaskCode(transTask.getTaskno());
        rcsTaskSubmit.setInitPriority(10);  //默认10
        List<RcsTaskTargetRoute> targetRouteList = new ArrayList<>();
        RcsTaskTargetRoute startRoute = new RcsTaskTargetRoute();
        startRoute.setSeq(0);
        startRoute.setCode(transTask.getCurStationId());
        startRoute.setOperation("COLLECT");
        targetRouteList.add(startRoute);
        RcsTaskTargetRoute endRoute = new RcsTaskTargetRoute();
        endRoute.setSeq(1);
        endRoute.setCode(transTask.getNextStationId());
        endRoute.setOperation("DELIVERY");
        targetRouteList.add(endRoute);
        rcsTaskSubmit.setTargetRoute(targetRouteList);
        // 转发给海康或华晓RCS
        RcsReturn rcsReturn = rcsService.submitTask(rcsTaskSubmit, transTask.getAgvFactory());
        if (rcsReturn.getCode().equals("SUCCESS")) {
            int workNo = commonService.getWorkNo(WorkNoType.OTHER.type);
            Date now = new Date();
            Task task = new Task();
            task.setWrkNo(workNo);
            task.setTaskType("AGV");
            task.setWrkSts(301L);
            task.setIoType(3);
            task.setIoPri(10.00);
            task.setWrkDate(now);
            task.setSourceStaNo(transTask.getCurStationId());
            task.setStaNo(transTask.getNextStationId());
            task.setBarcode(transTask.getTuoPanId());
            task.setModiUser(defaultUserId);
            task.setModiTime(now);
            task.setAppeUser(defaultUserId);
            task.setAppeTime(now);
            task.setTaskNo(transTask.getTaskno());
            task.setMemo(JSONObject.toJSONString(transTask));
            taskService.insert(task);
            Mat mat = matService.selectByMatnr(transTask.getItemno());
            TaskDetl taskDetl = new TaskDetl();
            taskDetl.setWrkNo(task.getWrkNo());
            taskDetl.setIoTime(task.getIoTime());
            taskDetl.setMatnr(transTask.getItemno());
            taskDetl.setAnfme(0.0);
//            taskDetl.setStandby1(String.valueOf(transTask.getQty()));
            taskDetl.setMaktx(mat.getMaktx());
            taskDetl.setSpecs(mat.getSpecs());
            taskDetl.setOrderNo(transTask.getOrderNo());
            taskDetl.setZpallet(transTask.getTuoPanId());
            taskDetl.setMemo(Cools.isEmpty(transTask.getItemBarcode()) ? "":barCodeListToStr(transTask.getItemBarcode()));
            taskDetl.setModiUser(defaultUserId);
            taskDetl.setModiTime(now);
            taskDetl.setAppeUser(defaultUserId);
            taskDetl.setAppeTime(now);
            taskDetlService.insert(taskDetl);
            result.put("Success", "1");
            result.put("Message", "任务接收成功");
        } else {
            result.put("Success", "2");
            result.put("Message", "任务下发给RCS失败");
        }
        return result;
    }
    /**
     * 9.2返回任务执行结果
     *
     * @param rcsReporterTask
     * @return
     */
    public int reporterTask(RcsReporterTask rcsReporterTask) {
        // 结果汇总
        boolean completed = true;
        EntityWrapper<Task> wrapper = new EntityWrapper<>();
        wrapper.eq("task_no", rcsReporterTask.getRobotTaskCode());
        List<Task> tasks = taskService.selectList(wrapper);
        if (tasks != null && !tasks.isEmpty()) {
            for (Task task : tasks) {
                if (task.getWrkSts() != 304) {   // TODO:确认完成,可能存在多盘任务
                    completed = false;
                }
            }
        }
        if (completed) {
            TransTaskFeedback transTaskFeedback = new TransTaskFeedback();
            transTaskFeedback.setTaskno(rcsReporterTask.getRobotTaskCode());
//            transTaskFeedback.setTaskname();
            transTaskFeedback.setResult(1);
            String url = MES_URL + "api/task/reporter";
            String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(transTaskFeedback));
            if (!StringUtils.isEmpty(response) && response.contains("Success")){
                MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                if("1".equals(mesReturn.getSuccess())) {
                    return 1;
                }
            }
        }
        return 0;
    }
    /**
     * 9.8申请华晓AGV进入生产线
     *
     * @param apply
     * @return
     */
    public String applyInLine(TransParent apply) {
        String url = MES_URL + "api/apply/inLine";
        String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply));
        if (!StringUtils.isEmpty(response) && response.contains("Success")){
            JSONObject jsonObject = JSONObject.parseObject(response);
            if("1".equals(jsonObject.getString("Success"))) {
                return jsonObject.getJSONObject("Data").getString("status");
            }
        }
        return "N";
    }
    /**
     * 入站请求:转发AGV->入站请求->给MES
     *
     * @param apply
     * @return
     */
    public int applyInStation(TransParent apply) {
        String path = ("LL").equals(apply.getProductLineId()) ? "AGVTransportPalletNotice" : "Aprs/AGVTransportPalletNotice";
        String url = MES_URL + path;
        String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply));
        if (!StringUtils.isEmpty(response) && response.contains("Success")){
            MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
            if("1".equals(mesReturn.getSuccess())) {
                return 1;
            }
        }
        return 0;
    }
    /**
     * 入站允许:转发MES->允许入站->给AGV
     *
     * @param allow
     * @return
     */
    public MesReturn allowInStation(TransInOutStationAllow allow) {
        MesReturn mesReturn = new MesReturn();
        mesReturn.setSuccess("1");
        if ("Y".equals(allow.getStatus())) {
            RcsTaskContinue rcsTaskContinue = new RcsTaskContinue();
            rcsTaskContinue.setRobotTaskCode(allow.getTaskno());
            rcsTaskContinue.setTriggerType("TASK");
            rcsTaskContinue.setTriggerCode(allow.getTaskno());
//            rcsTaskContinue.setTriggerType("ROBOT");
//            rcsTaskContinue.setTriggerCode(allow.getAgvCode());
            int success = rcsService.continueTask(rcsTaskContinue, 1);
            mesReturn.setSuccess(success == 1 ? "1" : "2");
            mesReturn.setMessage(success == 1 ? "" : "转发给RCS失败");
        }
        return mesReturn;
    }
    /**
     * 到站完成:转发AGV->到站完成->给MES
     *
     * @param arrivalStation
     * @return
     */
    public int arriveOnStation(TransArrivalStation arrivalStation) {
        if ("01".equals(arrivalStation.getDaotype())) {
            arrivalStation.setItemno(null);
            arrivalStation.setItemBarcode(new ArrayList<>());
            arrivalStation.setOrderNo(null);
        }
        String path = ("LL").equals(arrivalStation.getProductLineId()) ? "AGVArrivalCompleted" : "Aprs/AGVArrivalCompleted";
        String url = MES_URL + path;
        String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(arrivalStation));
        if (!StringUtils.isEmpty(response) && response.contains("Success")){
            MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
            if("1".equals(mesReturn.getSuccess())) {
                return 1;
            }
        }
        return 0;
    }
    /**
     * 离站请求:转发AGV->离站请求->给MES
     *
     * @param apply
     * @return
     */
    public int applyOutStation(TransParent apply) {
        String url = MES_URL + "api/apply/outStation";
        String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply));
        if (!StringUtils.isEmpty(response) && response.contains("Success")){
            MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
            if("1".equals(mesReturn.getSuccess())) {
                return 1;
            }
        }
        return 0;
    }
    /**
     * 离站允许:转发MES->允许离站->给AGV
     *
     * @param allow
     * @return
     */
    public MesReturn allowOutStation(TransInOutStationAllow allow) {
        MesReturn mesReturn = new MesReturn();
        mesReturn.setSuccess("1");
        if ("Y".equals(allow.getStatus())) {
            RcsTaskContinue rcsTaskContinue = new RcsTaskContinue();
            rcsTaskContinue.setRobotTaskCode(allow.getTaskno());
            rcsTaskContinue.setTriggerType("TASK");
            rcsTaskContinue.setTriggerCode(allow.getTaskno());
            int success = rcsService.continueTask(rcsTaskContinue, checkRcsFactory(allow.getAgvCode()));
            mesReturn.setSuccess(success == 1 ? "1" : "2");
            mesReturn.setMessage(success == 1 ? "" : "转发给RCS失败");
        }
        return mesReturn;
    }
    /**
     * 离站完成:转发AGV->离站完成->给MES
     *
     * @param apply
     * @return
     */
    public int outStation(TransParent apply) {
        String path = ("LL").equals(apply.getProductLineId()) ? "AGVDepartureCompleted" : "Aprs/AGVDepartureCompleted";
        String url = MES_URL + path;
        String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply));
        if (!StringUtils.isEmpty(response) && response.contains("Success")){
            MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
            if("1".equals(mesReturn.getSuccess())) {
                return 1;
            }
        }
        return 0;
    }
    @Override
    public MesReturn queryInventory(String itemno,String orderNo) {
        MesReturn mesReturn = new MesReturn();
        mesReturn.setSuccess("1");
        List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("matnr", itemno).eq("order_no",orderNo));
        int count = 0;
        for(LocDetl locDetl:locDetls) {
            count += locDetl.getAnfme();
        }
        mesReturn.setMessage(String.valueOf(count));
        return mesReturn;
    }
    // endregion
    /**
     * 查询Rcs地址
     *
     * @param agvNo
     * @return 1 海康;2 华晓
     */
    private int checkRcsFactory(String agvNo) {
        AgvInfo agvInfo = agvInfoMapper.selectById(agvNo);
        return agvInfo.getAgvFactory();
    }
}
package com.zy.asrs.service.impl; import com.alibaba.excel.util.StringUtils; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.core.common.SnowflakeIdWorker; import com.core.exception.CoolException; import com.zy.asrs.entity.*; import com.zy.asrs.entity.mes.*; import com.zy.asrs.entity.rcs.*; import com.zy.asrs.mapper.AgvInfoMapper; import com.zy.asrs.mapper.BasDevpMapper; import com.zy.asrs.mapper.MatItemBarcodeMapper; import com.zy.asrs.service.*; import com.zy.asrs.utils.OrderInAndOutUtil; import com.zy.common.model.LocDetlDto; import com.zy.common.model.enums.WorkNoType; import com.zy.common.service.CommonService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.text.ParseException; import java.util.*; import java.util.stream.Collectors; @Slf4j @Service public class MesServiceImpl implements MesService {     @Value("${mes.url}")     public String MES_URL;     @Value("${wms.currentName}")     public String WMS_CURRENT_NAME;     @Value("${wms.wmsTransStartStation1}")     public String WMS_TRANS_START_STATION_1;     @Value("${wms.wmsTransStartStation2}")     public String WMS_TRANS_START_STATION_2;     @Value("${wms.wmsTransStartStation3}")     public String WMS_TRANS_START_STATION_3;     @Value("${mes.defaultUserId}")     public long defaultUserId;     @Value("${wms.zpalletId}")     public String WMS_ZPALLET_ID;     @Resource     private RcsService rcsService;     @Resource     private MatService matService;     @Resource     private TagService tagService;     @Resource     private OrderPakinService orderPakinService;     @Resource     private OrderDetlPakinService orderDetlPakinService;     @Resource     private OrderPakoutService orderPakoutService;     @Resource     private OrderDetlPakoutService orderDetlPakoutService;     @Resource     private WaitPakinService waitPakinService;     @Resource     private TaskService taskService;     @Resource     private TaskDetlService taskDetlService;     @Resource     private SnowflakeIdWorker snowflakeIdWorker;     @Resource     private CommonService commonService;     @Resource     private AgvInfoMapper agvInfoMapper;     @Resource     private WorkService workService;     @Resource     private MatItemBarcodeMapper matItemBarcodeMapper;     @Resource     private LocMastService locMastService;     @Resource     private LocDetlService locDetlService;     @Resource     private MobileService mobileService;     @Resource     private WrkMastService wrkMastService;     @Resource     private WrkDetlService wrkDetlService;     // region MES接口     /**      * 物料信息同步,MES->WMS      * 功能:同步物料信息->生成入库单      * 后续流程:入库时,需要实时调用recvFeedback返回入库数量      *      * @param matRecvForm      * @return      */     @Transactional(rollbackFor = Exception.class)     public MesReturn matInfoAndInBound(MesMatRecvForm matRecvForm) throws CoolException {         MesReturn mesReturn = new MesReturn();         // 1、物料信息同步         for (MesMatInfo mesMatInfo : matRecvForm.getItemdata()) {             if (synMatInfo(mesMatInfo) == 1) {             } else {                 throw new CoolException("同步物料信息失败");             }         }         // 2、生成入库单         if (inBoundOrder_List(matRecvForm) == 1) {             mesReturn.setSuccess("1");             mesReturn.setMessage("");         } else {             throw new CoolException("同步物料信息,生成入库单失败");         }         return mesReturn;     }     /**      * 新增、修改物料信息      *      * @param mesMatInfo      * @return 1 成功;-1 保存物料类型失败;-2 保存物料失败;      * @throws ParseException      */     public int synMatInfo(MesMatInfo mesMatInfo) {         // 规则定义:默认第2层为库名(如:加工库),第3层为同步的物料类型         long secondPath = 2;         String secondParentName = WMS_CURRENT_NAME;         Date now = new Date();         // 物料类型更新         long tagId = 0;         EntityWrapper<Tag> wrapper = new EntityWrapper<>();         wrapper.eq("name", mesMatInfo.getItemType());         Tag tag = tagService.selectByName(mesMatInfo.getItemType(), 3);         if (tag == null || StringUtils.isEmpty(tag.getName())) {             Tag newTag = new Tag();             newTag.setName(mesMatInfo.getItemType());             newTag.setParentId(secondPath);             newTag.setParentName(secondParentName);             newTag.setPath("2");             newTag.setPathName(secondParentName);             newTag.setLevel(3);             newTag.setStatus(1);             newTag.setCreateBy(defaultUserId);             newTag.setCreateTime(now);             newTag.setUpdateBy(defaultUserId);             newTag.setUpdateTime(now);             if (!tagService.insert(newTag))                 return -1;             tagId = newTag.getId();         } else {             tagId = tag.getId();         }         // 物料更新         if (tagId > 0) {             //        tagId = tagService.selectByName(mesMatInfo.getItem_type(), 3).getId();             Mat mat = matService.selectByMatnr(mesMatInfo.getItemNo());             Mat newMat = new Mat();             newMat.setMatnr(mesMatInfo.getItemNo());             newMat.setMaktx(mesMatInfo.getDescription());             newMat.setTagId(tagId);             newMat.setLocType(tagId);   //locType             newMat.setSpecs(mesMatInfo.getSpecification());             newMat.setUnit(mesMatInfo.getUnitOfMeasure());             newMat.setModel(mesMatInfo.getClassificationCode());             newMat.setMemo(JSONObject.toJSONString(mesMatInfo));             newMat.setCreateBy(defaultUserId);             newMat.setCreateTime(now);             newMat.setUpdateBy(defaultUserId);             newMat.setUpdateTime(now);             newMat.setStatus(1);             if (mat == null) {                 if (!matService.insert(newMat))                     return -2;             } else {                 JSONObject dbMemo = JSONObject.parseObject(mat.getMemo());                 dbMemo.remove("OrderNo");                 dbMemo.remove("qty");                 dbMemo.remove("ItemBarcode");                 JSONObject newMemo = JSONObject.parseObject(newMat.getMemo());                 newMemo.remove("OrderNo");                 newMemo.remove("qty");                 dbMemo.remove("ItemBarcode");                 if (!dbMemo.equals(newMemo)) {                     newMat.setId(mat.getId());                     if (!matService.updateById(newMat))                         return -2;                 }             }         } else {             return -1;         }         return 1;     }     /**      * 物料同步入库单,按OrderNo生成多个订单      *      *      * @param matRecvForm      * @return      */     public int inBoundOrder_List(MesMatRecvForm matRecvForm){         long docType = 4;   // docType根据库类型确定         long settle = 1;         Date now = new Date();         // 按OrderNo分组,然后再生成入库单         List<MesMatInfo> mesInApply = matRecvForm.getItemdata();         Map<String, List<MesMatInfo>> map = mesInApply.stream().collect(Collectors.groupingBy(MesMatInfo::getOrderNo));         for (Map.Entry<String, List<MesMatInfo>> entry : map.entrySet()) {             List<MesMatInfo> list = entry.getValue();             // 校验订单是否重复             OrderPakin order = orderPakinService.selectByNo(entry.getKey());             if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {                 return -1;             }             // 生成订单             JSONObject newMemo = new JSONObject();             newMemo.put("sourceNo", matRecvForm.getSourceNo());             newMemo.put("sourceName", matRecvForm.getSourceName());             newMemo.put("operuser", matRecvForm.getOperuser());             newMemo.put("itemdata", list);             OrderPakin orderPakin = new OrderPakin();             orderPakin.setUuid(String.valueOf(snowflakeIdWorker.nextId()));             orderPakin.setOrderNo(entry.getKey());             orderPakin.setOrderTime(com.core.common.DateUtils.convert(now));             orderPakin.setDocType(docType);             orderPakin.setSettle(settle);             orderPakin.setStatus(1);             orderPakin.setCreateBy(defaultUserId);             orderPakin.setCreateTime(now);             orderPakin.setUpdateBy(defaultUserId);             orderPakin.setUpdateTime(now);             orderPakin.setMemo(newMemo.toJSONString());  //为领料入库完成反馈保存   JSONObject.toJSONString(matRecvForm)             orderPakin.setPakinPakoutStatus(1);             if (!orderPakinService.insert(orderPakin)) {                 log.error("MES保存入库订单主档失败");                 throw new CoolException("保存入库订单主档失败");             }             // 生成明细             for (MesMatInfo mesMat : list) {                 Mat mat = matService.selectByMatnr(mesMat.getItemNo());                 OrderDetlPakin orderDetlPakin = new OrderDetlPakin();                 orderDetlPakin.setOrderId(orderPakin.getId());                 orderDetlPakin.setOrderNo(orderPakin.getOrderNo());                 orderDetlPakin.setAnfme(Double.valueOf(mesMat.getQty()));                 orderDetlPakin.setQty(0.0);                 orderDetlPakin.setMatnr(mat.getMatnr());                 orderDetlPakin.setMaktx(mat.getMaktx());                 orderDetlPakin.setSpecs(mat.getSpecs());                 orderDetlPakin.setModel(mat.getModel());                 orderDetlPakin.setStandby1(barCodeListToStr(mesMat.getItemBarcode()));   // 零件二维码                 orderDetlPakin.setStandby2("1");  //保存齐套性检查标识,1 检查;0 不检查;                 orderDetlPakin.setCreateBy(defaultUserId);                 orderDetlPakin.setCreateTime(now);                 orderDetlPakin.setUpdateBy(defaultUserId);                 orderDetlPakin.setUpdateTime(now);                 orderDetlPakin.setStatus(1);                 orderDetlPakin.setPakinPakoutStatus(1);                 if (!orderDetlPakinService.insert(orderDetlPakin)) {                     log.error("MES保存入库订单明细档失败1");                     throw new CoolException("保存入库订单明细档失败1");                 }             }         }         return 1;     }     /**      * 领料入库反馈      * 触发条件:物料同步接口入库单,入库后      * 推送时机:当订单中有物料入库后(应该在每托入库完成后,可以在更新OrderDetlPakin之后)则推送,不等全部订单完成      *      * @param orderNo      * @param zapplet      * @return      */     public int recvFeedback(String orderNo, String zapplet) {         OrderPakin order = orderPakinService.selectByNo(orderNo);         if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {             List<MesRecvFeedback.MesRecvFeedbackItem> list = new ArrayList<>();             JSONObject dbMemo = JSONObject.parseObject(order.getMemo());             // 从组托信息中查询入库的信息             EntityWrapper<WaitPakin> waitPakinEntityWrapper = new EntityWrapper<>();             waitPakinEntityWrapper.eq("zpallet", zapplet);             List<WaitPakin> zpalletMat = waitPakinService.selectList(waitPakinEntityWrapper);             EntityWrapper<OrderDetlPakin> wrapper = new EntityWrapper<>();             wrapper.eq("order_no", orderNo);             List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectList(wrapper);             if (orderDetlPakins != null && !orderDetlPakins.isEmpty()) {                 for (OrderDetlPakin orderDetl : orderDetlPakins) {                     for (WaitPakin zMat : zpalletMat) {                         if (orderDetl.getMatnr().equals(zMat.getMatnr())) {                             MesRecvFeedback.MesRecvFeedbackItem item = new MesRecvFeedback.MesRecvFeedbackItem();                             item.setItemNo(orderDetl.getMatnr());                             item.setOrderNo(orderNo);                             item.setQty(orderDetl.getAnfme().intValue());                             item.setRealQty(zMat.getAnfme().intValue());                             // 回传托盘绑定的零件二维码                             EntityWrapper<MatItemBarcode> matItemBarcodeEntityWrapper = new EntityWrapper<>();                             matItemBarcodeEntityWrapper.eq("zapplet", zapplet).eq("status", 1);                             List<MatItemBarcode> barcodes = matItemBarcodeMapper.selectList(matItemBarcodeEntityWrapper);                             if (barcodes != null) {                                 List<String> itemBarcode = new ArrayList<>();                                 for (MatItemBarcode barcode : barcodes) {                                     itemBarcode.add(barcode.getItemBarcode());                                 }                                 item.setItemBarcode(itemBarcode);                                 list.add(item);                             }                         }                     }                 }             }             MesRecvFeedback mesRecvFeedback = new MesRecvFeedback();             mesRecvFeedback.setSourceNo(dbMemo.getString("sourceNo"));             mesRecvFeedback.setOperuser(dbMemo.getString("operuser"));             mesRecvFeedback.setItemdata(list);             String url = MES_URL + "MaterialReceiptAndReturn";             String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesRecvFeedback));             if (!StringUtils.isEmpty(response) && response.contains("Success")){                 MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);                 if("1".equals(mesReturn.getSuccess())) {                     return 1;                 }             }         }         return 0;     }     /**      * 出库申请,加工库、刀具库      * 出库后需要自动呼叫AGV送货      * 出库规则:需要按零件二维码(一件一码)出库,整托出库,该托上有其他物料也一起出库,他们后期会再入库      *      * @param mesOutApply      * @return 1 成功;-1 订单重复;      */     @Transactional     public int outBoundOrder(MesOutApply mesOutApply){         // 空托出库         if (StringUtils.isEmpty(mesOutApply.getOrderNo()) && "01".equals(mesOutApply.getTransType())) {             // 生成空托出库任务             mobileService.callEmptyBinOutBound(mesOutApply,mesOutApply.getStationId().startsWith("LJ") ? WMS_TRANS_START_STATION_1 : WMS_TRANS_START_STATION_3,mesOutApply.getPalletType(),1,defaultUserId); //            try { //                if (!StringUtils.isEmpty(mesOutApply.getTaskno()) && !StringUtils.isEmpty(mesOutApply.getStationId())) { //                    TransTask transTask = new TransTask(); //                    transTask.setTaskno(mesOutApply.getTaskno()); //                    transTask.setTaskname(mesOutApply.getTaskname()); //                    transTask.setOrderNo(mesOutApply.getOrderNo()); //                    transTask.setTransType(mesOutApply.getTransType()); //                    transTask.setCurStationId(WMS_TRANS_START_STATION_1); //                    transTask.setNextProcess(mesOutApply.getProductLineId()); //                    transTask.setNextStationId(mesOutApply.getStationId()); //                    transTask.setItemno(WMS_ZPALLET_ID);  // 固定为空托的编码 //                    transTask.setQty(1);    // 空托只出1个 //                    transTask.setProductLineId(mesOutApply.getProductLineId()); //                    transTask.setOperateType(1); //                    transTask.setAgvFactory(1); //                    JSONObject sendAgvTask = submitTask(transTask); //                    if (!"1".equals(sendAgvTask.getString("Success"))) { //                        log.error("出库下发agv运输任务失败:{}", JSONObject.toJSONString(transTask)); //                    } //                } //            } catch (Exception e) { //                log.error("下发AGV运输任务失败", e); //            }             return 1;         } else {    // 毛坯(物料)出库             // docType根据库类型确定             long docType = 7;             long settle = 2;             // 校验订单是否重复             OrderPakout order = orderPakoutService.selectByNo(mesOutApply.getOrderNo());             if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {                 log.error("出库订单号重复:{}",mesOutApply.getOrderNo());                 return -1;             }             if (Cools.isEmpty(mesOutApply.getItemBarcode())) {                 log.error("出库零件二维码为空:" +mesOutApply.getItemBarcode());                 return 2;             }             String itemBarcode = barCodeListToStr(mesOutApply.getItemBarcode());             // 自动出库             LocDetl locDetl = locDetlService.selectOne(new EntityWrapper<LocDetl>().eq("standby1", itemBarcode));             if (locDetl == null) {                 throw new CoolException("零件二维码没有匹配到库存:" +itemBarcode );             }             LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", locDetl.getLocNo()));             if (!locMast.getLocSts().equals("F")) {                 throw new CoolException("库位状态不为F:" +locMast.getLocNo() );             }             // 生成订单             Date now = new Date();             OrderPakout orderPakout = new OrderPakout();             orderPakout.setUuid( String.valueOf(snowflakeIdWorker.nextId()));             orderPakout.setOrderNo(mesOutApply.getOrderNo());             orderPakout.setOrderTime(com.core.common.DateUtils.convert(now));             orderPakout.setDocType(docType);             orderPakout.setSettle(settle);             orderPakout.setStatus(1);             orderPakout.setCreateBy(defaultUserId);             orderPakout.setCreateTime(now);             orderPakout.setUpdateBy(defaultUserId);             orderPakout.setUpdateTime(now);             orderPakout.setMemo(JSONObject.toJSONString(mesOutApply));             orderPakout.setPakinPakoutStatus(2);             orderPakout.setNumber(locMast.getBarcode()); // 托盘条码,上报时用             if (!orderPakoutService.insert(orderPakout)) {                 log.error("MES保存出库订单主档失败");                 throw new CoolException("保存出库订单主档失败");             }             // 生成明细             Mat mat = matService.selectByMatnr(mesOutApply.getItemno());             OrderDetlPakout orderDetlPakout = new OrderDetlPakout();             orderDetlPakout.setOrderId(orderPakout.getId());             orderDetlPakout.setOrderNo(orderPakout.getOrderNo());             orderDetlPakout.setAnfme(Double.valueOf(mesOutApply.getQty()));             orderDetlPakout.setWorkQty(orderDetlPakout.getAnfme());             orderDetlPakout.setQty(0.0);             orderDetlPakout.setMatnr(mat.getMatnr());             orderDetlPakout.setMaktx(mat.getMaktx());             orderDetlPakout.setSpecs(mat.getSpecs());             orderDetlPakout.setModel(mat.getModel());             orderDetlPakout.setStandby1(itemBarcode);             orderDetlPakout.setCreateBy(defaultUserId);             orderDetlPakout.setCreateTime(now);             orderDetlPakout.setUpdateBy(defaultUserId);             orderDetlPakout.setUpdateTime(now);             orderDetlPakout.setStatus(1);             orderDetlPakout.setPakinPakoutStatus(2);             if (!orderDetlPakoutService.insert(orderDetlPakout)) {                 log.error("MES保存出库订单明细档失败");                 throw new CoolException("保存出库订单明细档失败");             }             // 生成工作号             int workNo = commonService.getWorkNo(WorkNoType.getWorkNoType(101));             // 生成工作档             WrkMast wrkMast = new WrkMast();             wrkMast.setWrkNo(workNo);             wrkMast.setIoTime(now);             wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID             wrkMast.setIoType(101); // 入出库状态             wrkMast.setIoPri(13D); // 优先级:13             wrkMast.setCrnNo(1);             if(mesOutApply.getStationId().startsWith("LJ")) {                 wrkMast.setSourceStaNo("205"); // 源站                 wrkMast.setStaNo("205"); // 目标站             } else {                 wrkMast.setSourceStaNo("203"); // 源站                 wrkMast.setStaNo("204"); // 目标站             }             wrkMast.setSourceLocNo(locMast.getLocNo()); // 源库位             wrkMast.setFullPlt("Y"); // 满板:Y             wrkMast.setPicking("N"); // 拣料             wrkMast.setExitMk("N"); // 退出             wrkMast.setEmptyMk("N"); // 空板             wrkMast.setLinkMis("N");             wrkMast.setBarcode(locMast.getBarcode());             wrkMast.setAppeUser(defaultUserId); // 操作人员数据             wrkMast.setAppeTime(now);             wrkMast.setModiUser(defaultUserId);             wrkMast.setModiTime(now);             wrkMast.setMemo(JSONObject.toJSONString(mesOutApply));             wrkMast.setTaskNo(mesOutApply.getTaskno());             wrkMast.setAgvSta(mesOutApply.getStationId());             wrkMastService.insert(wrkMast);             // 生成工作档明细                 WrkDetl wrkDetl = new WrkDetl();                 wrkDetl.sync(locDetl);                 wrkDetl.setOrderNo(orderPakout.getOrderNo()); // 手动出库不需要带出库存中的单据编号                 wrkDetl.setWrkNo(workNo);                 wrkDetl.setIoTime(now);                 wrkDetl.setAnfme(orderDetlPakout.getAnfme()); // 数量                 wrkDetl.setAppeTime(now);                 wrkDetl.setAppeUser(defaultUserId);                 wrkDetl.setModiTime(now);                 wrkDetl.setModiUser(defaultUserId); //                wrkDetl.setMatnr(detlDto.getLocDetl().getMatnr()); //                wrkDetl.setMaktx(detlDto.getLocDetl().getMaktx()); //                wrkDetl.setUnit(detlDto.getLocDetl().getUnit()); //                wrkDetl.setSpecs(detlDto.getLocDetl().getSpecs()); //                wrkDetl.setUnit(detlDto.getLocDetl().getUnit()); //                wrkDetl.setModel(detlDto.getLocDetl().getModel());                 wrkDetlService.insert(wrkDetl);             // 修改库位状态:   F.在库 ====>>> R.出库预约/P.拣料/盘点/并板出库中             if (locMast.getLocSts().equals("F")) {                 locMast.setLocSts("R");                 locMast.setModiUser(defaultUserId);                 locMast.setModiTime(now);                 locMastService.updateById(locMast);             }             log.info("出库任务生成成功,任务号:{}",workNo);             // 立库生成订单后,自动调度AGV运送到站点,目前多托生成多个。 //            try { //                if (!StringUtils.isEmpty(mesOutApply.getTaskno()) && !StringUtils.isEmpty(mesOutApply.getStationId())) { //                    // 按零件二维码查询有几个托,多托生成多个任务,每托对应零件二维码 ////                    String barCode = barCodeListToStr(mesOutApply.getItemBarcode()); ////                    EntityWrapper<MatItemBarcode> matItemBarcodeEntityWrapper = new EntityWrapper<>(); ////                    matItemBarcodeEntityWrapper.in("item_barcode", barCode); ////                    List<MatItemBarcode> barcodes = matItemBarcodeMapper.selectList(matItemBarcodeEntityWrapper); ////                     if (barcodes != null) { ////                        Map<String, List<MatItemBarcode>> map = barcodes.stream().collect(Collectors.groupingBy(MatItemBarcode::getZapplet)); ////                        for (Map.Entry<String, List<MatItemBarcode>> entry : map.entrySet()) { ////                            List<MatItemBarcode> list = entry.getValue(); ////                            List<String> codes = new ArrayList<>(); ////                            for (MatItemBarcode zapllet : list) { ////                                codes.add(zapllet.getItemBarcode()); ////                            } // //                            TransTask transTask = new TransTask(); //                            transTask.setTaskno(mesOutApply.getTaskno()); //                            transTask.setTaskname(mesOutApply.getTaskname()); //                            transTask.setOrderNo(mesOutApply.getOrderNo()); //                            transTask.setTransType(mesOutApply.getTransType()); //                            transTask.setCurStationId(WMS_TRANS_START_STATION_3); //                            transTask.setNextProcess(mesOutApply.getProductLineId()); //                            transTask.setNextStationId(mesOutApply.getStationId()); //                            transTask.setItemno(mesOutApply.getItemno()); //                            transTask.setQty(mesOutApply.getQty()); //                            transTask.setProductLineId(mesOutApply.getProductLineId()); //                            transTask.setItemBarcode(mesOutApply.getItemBarcode()); //                            transTask.setTuoPanId(locDetl.getZpallet()); //                            transTask.setOperateType(1); //                            transTask.setAgvFactory(1); //                            JSONObject sendAgvTask = submitTask(transTask); //                            if (!"1".equals(sendAgvTask.getString("Success"))) { //                                log.error("出库下发agv运输任务失败", JSONObject.toJSONString(transTask)); //                            } ////                        } ////                    } //                } //            } catch (Exception e) { //                log.error("下发AGV运输任务失败", e); //            }         }         return 1;     }     /**      * 入库申请      * 收到入库申请后自动呼叫AGV取货      *      * @param mesInApply      */     @Transactional     public int inBoundOrder(MesInApply mesInApply){         // 出入库任务控制 入库前判断是否有出库任务         if(mesInApply.getStationID().startsWith("LG") || mesInApply.getStationID().startsWith("LT")) { // 侧面只能螺杆线出入,205口             int count = wrkMastService.selectCount(new EntityWrapper<WrkMast>().in("io_type", 101, 103, 107, 110).eq("sta_no", 205));             if(count >0) {                 log.warn("该入库站点:{},存在执行的出库任务:{}条", 205, count);                 return 2;             }         }         // 空托回库         if (StringUtils.isEmpty(mesInApply.getOrderNo()) && StringUtils.isEmpty(mesInApply.getItemno())) {                 if (!StringUtils.isEmpty(mesInApply.getTaskno()) && !StringUtils.isEmpty(mesInApply.getStationID())) {                     TransTask transTask = new TransTask();                     transTask.setTaskno(mesInApply.getTaskno());                     transTask.setTaskname(mesInApply.getTaskname());                     transTask.setOrderNo(mesInApply.getOrderNo());                     transTask.setTransType(mesInApply.getTransType());                     transTask.setCurProcess(mesInApply.getProductLineId());                     transTask.setCurStationId(mesInApply.getStationID());                     transTask.setNextStationId(mesInApply.getStationID().startsWith("LJ") ? WMS_TRANS_START_STATION_1 : WMS_TRANS_START_STATION_2);                     transTask.setItemno(WMS_ZPALLET_ID);  // 固定为空托的编码                     transTask.setQty(1);    // 空托只回1个                     transTask.setProductLineId(mesInApply.getProductLineId());                     transTask.setOperateType(1);                     transTask.setAgvFactory(1);                     transTask.setTuoPanId(mesInApply.getTuoPanId());                     JSONObject sendAgvTask = submitTask(transTask);                     if (!"1".equals(sendAgvTask.getString("Success"))) {                         log.error("入库下发agv运输任务失败,{}", JSONObject.toJSONString(transTask));                         return 2;                     }                 } else {                     log.error("无任务号:{},或无物料编码:{}",mesInApply.getTaskno(),mesInApply.getItemno() );                     return 2;                 }             return 1;         } else {    // 毛坯、成品回库             // docType根据库类型确定             long docType = 3;             long settle = 1;             // 校验订单是否重复             OrderPakin order = orderPakinService.selectByNo(mesInApply.getOrderNo());             if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {                 log.error("订单重复:{}", mesInApply.getOrderNo());                 return 2;             }             // 生成订单             Date now = new Date();             OrderPakin orderPakin = new OrderPakin();             orderPakin.setUuid(String.valueOf(snowflakeIdWorker.nextId()));             orderPakin.setOrderNo(mesInApply.getOrderNo());             orderPakin.setOrderTime(com.core.common.DateUtils.convert(now));             orderPakin.setDocType(docType);             orderPakin.setSettle(settle);             orderPakin.setStatus(1);             orderPakin.setCreateBy(defaultUserId);             orderPakin.setCreateTime(now);             orderPakin.setUpdateBy(defaultUserId);             orderPakin.setUpdateTime(now);             orderPakin.setMemo(JSONObject.toJSONString(mesInApply));  //为出库完成反馈保存             orderPakin.setPakinPakoutStatus(1);             orderPakinService.insert(orderPakin);             // 生成明细             Mat mat = matService.selectByMatnr(mesInApply.getItemno());             OrderDetlPakin orderDetlPakin = new OrderDetlPakin();             orderDetlPakin.setOrderId(orderPakin.getId());             orderDetlPakin.setOrderNo(orderPakin.getOrderNo());             orderDetlPakin.setAnfme(Double.valueOf(mesInApply.getQty()));             orderDetlPakin.setQty(0.0);             orderDetlPakin.setMatnr(mat.getMatnr());             orderDetlPakin.setMaktx(mat.getMaktx());             orderDetlPakin.setSpecs(mat.getSpecs());             orderDetlPakin.setModel(mat.getModel());             List<String> itemBarcode = mesInApply.getProductInfo().stream().map(MesInApply.ProductInfo::getItemBarcode).collect(Collectors.toList());             orderDetlPakin.setStandby1(barCodeListToStr(itemBarcode)); //零件详情存在1             orderDetlPakin.setStandby2("0");  //保存齐套性检查标识,1 检查;0 不检查;             orderDetlPakin.setCreateBy(defaultUserId);             orderDetlPakin.setCreateTime(now);             orderDetlPakin.setUpdateBy(defaultUserId);             orderDetlPakin.setUpdateTime(now);             orderDetlPakin.setStatus(1);             orderDetlPakin.setPakinPakoutStatus(1);             orderDetlPakinService.insert(orderDetlPakin);             // 生成入库通知档             WaitPakin waitPakin = new WaitPakin();             BeanUtils.copyProperties(mat, waitPakin); //                waitPakin.sync(mat);             waitPakin.setOrderNo(orderPakin.getOrderNo());   // 单据编号             waitPakin.setOrderId(orderPakin.getId());             waitPakin.setZpallet(mesInApply.getTuoPanId());   // 托盘码             waitPakin.setIoStatus("N");     // 入出状态             waitPakin.setAnfme(orderDetlPakin.getAnfme());  // 数量             waitPakin.setStatus("Y");    // 状态             waitPakin.setAppeUser(defaultUserId);             waitPakin.setAppeTime(now);             waitPakin.setModiUser(defaultUserId);             waitPakin.setModiTime(now);             waitPakin.setStandby1(barCodeListToStr(itemBarcode));             waitPakinService.insert(waitPakin);             OrderInAndOutUtil.increaseWorkQty(Boolean.TRUE, orderPakin.getId(), orderDetlPakin.getMatnr(), orderDetlPakin.getBatch(),                     orderDetlPakin.getBrand(), orderDetlPakin.getStandby1(), orderDetlPakin.getStandby2(), orderDetlPakin.getStandby3(),                     orderDetlPakin.getBoxType1(), orderDetlPakin.getBoxType2(), orderDetlPakin.getBoxType3(), orderDetlPakin.getAnfme());             OrderInAndOutUtil.updateOrder(Boolean.TRUE, orderPakin.getId(), 2L, defaultUserId);             // 呼叫AGV从产线运回立库                 if (!StringUtils.isEmpty(mesInApply.getTaskno())) {                     TransTask transTask = new TransTask();                     transTask.setTaskno(mesInApply.getTaskno());                     transTask.setTaskname(mesInApply.getTaskname());                     transTask.setOrderNo(mesInApply.getOrderNo());                     transTask.setTransType(mesInApply.getTransType());                     transTask.setCurProcess(mesInApply.getProductLineId());                     transTask.setCurStationId(mesInApply.getStationID());                     transTask.setNextStationId(mesInApply.getStationID().startsWith("LJ") ? WMS_TRANS_START_STATION_1 : WMS_TRANS_START_STATION_2);                     transTask.setItemno(mesInApply.getItemno());                     transTask.setQty(mesInApply.getQty());                     transTask.setProductLineId(mesInApply.getProductLineId());                     transTask.setItemBarcode(itemBarcode);                     transTask.setTuoPanId(mesInApply.getTuoPanId());                     transTask.setOperateType(1);                     transTask.setAgvFactory(1);                     JSONObject sendAgvTask = submitTask(transTask);                     if (!"1".equals(sendAgvTask.getString("Success"))) {                         log.error("入库下发agv运输任务失败:{}", JSONObject.toJSONString(transTask));                         throw new CoolException("入库下发agv运输任务失败");                     }                 } else {                     throw new CoolException("MES入库下发agv运输任务失败");                 }         }         return 1;     }     /**      * 出库完成      * 出库后,按托推送,非整个订单      *      * @param orderNo      * @return      */     public int outFeedbackByTuo(String orderNo, Task agvTask) {         int success = 0;         OrderPakout order = orderPakoutService.selectByNo(orderNo);         if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {             JSONObject dbMemo = JSONObject.parseObject(order.getMemo());             // TODO:出库完成后,若未解绑托盘和物料,则执行托盘解绑             // TODO:出库完成后,若未清除零件二维码,则执行清除,也可以在AGV送货完成后清除 //            EntityWrapper<OrderDetlPakout> wrapper = new EntityWrapper<>(); //            wrapper.eq("order_no", orderNo); //            List<OrderDetlPakout> orderDetlPakouts = orderDetlPakoutService.selectList(wrapper); //            if (orderDetlPakouts != null && !orderDetlPakouts.isEmpty()) { //                for (OrderDetlPakout orderDetl : orderDetlPakouts) { //                    StringBuilder palletId = new StringBuilder(); //                    EntityWrapper<WaitPakin> wrapper2 = new EntityWrapper<>(); //                    wrapper2.eq("order_no", orderDetl.getOrderNo()); //                    List<WaitPakin> waitPakins = waitPakinService.selectList(wrapper2); //                    if (waitPakins != null && waitPakins.size() > 0) { //                        for (WaitPakin waitPakin : waitPakins) { //                            palletId.append(waitPakin.getZpallet()).append(","); //                        } //                    } // //                    MesOutFeedback mesOutFeedback = new MesOutFeedback(); //                    mesOutFeedback.setTaskno(dbMemo.getString("taskno")); //                    mesOutFeedback.setTaskname(dbMemo.getString("taskname")); //                    mesOutFeedback.setProductLineId(dbMemo.getString("ProductLineId")); //                    mesOutFeedback.setStationId(dbMemo.getString("StationID")); //                    mesOutFeedback.setItemno(orderDetl.getMatnr()); //                    mesOutFeedback.setTuoPanId(zpalletId); //                    mesOutFeedback.setQty(orderDetl.getQty().intValue()); //                    if (!StringUtils.isEmpty(dbMemo.getString("ItemBarcode"))) { //                        mesOutFeedback.setItemBarcode(barCodeStrToList(dbMemo.getString("ItemBarcode"))); //                    } //                    mesOutFeedback.setOrderNo(orderNo); //                } //            }             EntityWrapper<TaskDetl> entityWrapper = new EntityWrapper<>();             entityWrapper.eq("wrk_no", agvTask.getWrkNo());             TaskDetl taskDetl = taskDetlService.selectOne(entityWrapper);             String zpalletId = taskDetl.getZpallet();             List<String> itemBarCode = new ArrayList<>();             JSONArray array = JSONArray.parseArray(taskDetl.getMemo());             for (Object one : array) {                 itemBarCode.add(one.toString());                 // TODO:入库时存储零件码(ItemBarCode),并绑定托盘,出库后这里考虑解绑             }             MesOutFeedback mesOutFeedback = new MesOutFeedback();             mesOutFeedback.setTaskno(agvTask.getTaskNo());             mesOutFeedback.setTaskname(dbMemo.getString("taskname"));             mesOutFeedback.setProductLineId(dbMemo.getString("ProductLineId"));             mesOutFeedback.setStationId(dbMemo.getString("StationId"));             mesOutFeedback.setItemno(dbMemo.getString("Itemno"));             mesOutFeedback.setTuoPanId(zpalletId);             if (itemBarCode.size() > 0) {                 mesOutFeedback.setQty(itemBarCode.size());                 mesOutFeedback.setItemBarcode(itemBarCode);             }             mesOutFeedback.setOrderNo(orderNo);             String url = MES_URL + "issueComplete";             String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesOutFeedback));             if (!StringUtils.isEmpty(response) && response.contains("Success")){                 MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);                 if("1".equals(mesReturn.getSuccess())) {                     success = 1;                 }             }         }         return success;     }     /**      * 入库完成      * 入库后,按托推送,非整个订单      *      * @param orderNo      * @param zapplet      * @return      */     public int inFeedbackByTuo(String orderNo, String zapplet) {         int success = 0;         OrderPakin order = orderPakinService.selectByNo(orderNo);         if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {             List<MesInApply.ProductInfo> list = new ArrayList<>();             // 从托盘绑定的零件二维码中查询信息             EntityWrapper<MatItemBarcode> matItemBarcodeEntityWrapper = new EntityWrapper<>();             matItemBarcodeEntityWrapper.eq("zapplet", zapplet).eq("status", 1);             List<MatItemBarcode> barcodes = matItemBarcodeMapper.selectList(matItemBarcodeEntityWrapper);             for (MatItemBarcode barcode : barcodes) {                 MesInApply.ProductInfo productInfo = new MesInApply.ProductInfo();                 productInfo.setItemBarcode(barcode.getItemBarcode());                 productInfo.setQualityStatus(barcode.getQualityStatus());                 list.add(productInfo);             }             MesInApply result = JSONObject.parseObject(order.getMemo(), MesInApply.class);             result.setProductInfo(list);             result.setQty(list.size());             String url = MES_URL + "loadComplete";             String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(result));             if (!StringUtils.isEmpty(response) && response.contains("Success")){                 MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);                 if("1".equals(mesReturn.getSuccess())) {                     success = 1;                 }             }         }         return success;     }     /**      * 零件二维码,数组转string      *      * @param list      * @return      */     public static String barCodeListToStr(List<String> list) {         if(list.isEmpty()) {             return "";         }         StringBuilder stringBuilder = new StringBuilder();         for (String str : list) {             stringBuilder.append(str).append(",");         }         String result = stringBuilder.toString();         return result.endsWith(",") ? result.substring(0, result.length() - 1) : result;     }     /**      * 零件二维码,string转数组      *      * @param str      * @return      */     public static List<String> barCodeStrToList(String str) {         String[] array = str.split(",");         return Arrays.asList(array);     }     /**      * 入库完成      * 入库单完成后,整单推送      *      * @param orderNo      * @return      */     public int inFeedback(String orderNo) {         int success = 0;         OrderPakin order = orderPakinService.selectByNo(orderNo);         if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {             EntityWrapper<OrderDetlPakin> wrapper = new EntityWrapper<>();             wrapper.eq("order_no", orderNo);             List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectList(wrapper);             if (orderDetlPakins != null && !orderDetlPakins.isEmpty()) {                 for (OrderDetlPakin orderDetl : orderDetlPakins) {                     MesInApply result = JSONObject.parseObject(order.getMemo(), MesInApply.class);                     result.setQty(orderDetl.getQty().intValue());                     String url = MES_URL + "loadComplete";                     String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(result));                     if (!StringUtils.isEmpty(response) && response.contains("Success")){                         MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);                         if("1".equals(mesReturn.getSuccess())) {                             success++;                         }                     }                 }                 if (success == orderDetlPakins.size()) {                     success = 1;                 } else {                     success = 0;                 }             }         }         return success;     }     /**      * (备份)出库订单完成      *      * @param orderNo      * @return      */     public int outFeedback(String orderNo) {         int success = 0;         OrderPakout order = orderPakoutService.selectByNo(orderNo);         if (order != null && order.getSettle() == 4) {   // 校验是否完成             JSONObject dbMemo = JSONObject.parseObject(order.getMemo());             EntityWrapper<OrderDetlPakout> wrapper = new EntityWrapper<>();             wrapper.eq("order_no", orderNo);             List<OrderDetlPakout> orderDetlPakouts = orderDetlPakoutService.selectList(wrapper);             if (orderDetlPakouts != null && !orderDetlPakouts.isEmpty()) {                 for (OrderDetlPakout orderDetl : orderDetlPakouts) {                     StringBuilder palletId = new StringBuilder();                     EntityWrapper<WaitPakin> wrapper2 = new EntityWrapper<>();                     wrapper2.eq("order_no", orderDetl.getOrderNo());                     List<WaitPakin> waitPakins = waitPakinService.selectList(wrapper2);                     if (waitPakins != null && waitPakins.size() > 0) {                         for (WaitPakin waitPakin : waitPakins) {                             palletId.append(waitPakin.getZpallet()).append(",");                         }                     }                     MesOutFeedback mesOutFeedback = new MesOutFeedback();                     mesOutFeedback.setTaskno(dbMemo.getString("taskno"));                     mesOutFeedback.setTaskname(dbMemo.getString("taskname"));                     mesOutFeedback.setProductLineId(dbMemo.getString("ProductLineId"));                     mesOutFeedback.setStationId(dbMemo.getString("StationID"));                     mesOutFeedback.setItemno(orderDetl.getMatnr());                     if (!StringUtils.isEmpty(palletId.toString())) {                         mesOutFeedback.setTuoPanId(palletId.substring(0, palletId.length() - 1));                     }                     mesOutFeedback.setQty(orderDetl.getQty().intValue());                     if (!StringUtils.isEmpty(dbMemo.getString("ItemBarcode"))) {                         mesOutFeedback.setItemBarcode(barCodeStrToList(dbMemo.getString("ItemBarcode")));                     }                     mesOutFeedback.setOrderNo(orderNo);                     // TODO:备注:出库完成后解绑托盘和物料,若前面未解绑,此处需要解绑                     String url = MES_URL + "issueComplete";                     String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesOutFeedback));                     if (!StringUtils.isEmpty(response) && response.contains("Success")){                         MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);                         if("1".equals(mesReturn.getSuccess())) {                             success++;                         }                     }                 }                 if (success == orderDetlPakouts.size()) {                     success = 1;                     // TODO:立库出库后自动调度AGV运送到站点                     String taskNo = dbMemo.getString("taskno");                     if (!StringUtils.isEmpty(taskNo)) {                         TransTask transTask = new TransTask();                         transTask.setTaskno(dbMemo.getString("taskno"));                         transTask.setTaskname(dbMemo.getString("taskname"));                         transTask.setOrderNo(dbMemo.getString("OrderNo"));                         transTask.setTransType(dbMemo.getString("TransType")); //                    transTask.setCurProcess();                         transTask.setCurStationId(WMS_TRANS_START_STATION_3);                         transTask.setNextProcess(dbMemo.getString("ProductLineId"));                         transTask.setNextStationId(dbMemo.getString("StationId"));                         transTask.setItemno(dbMemo.getString("Itemno"));                         transTask.setQty(dbMemo.getInteger("Qty"));                         transTask.setProductLineId(dbMemo.getString("ProductLineId"));                         transTask.setItemBarcode(barCodeStrToList(dbMemo.getString("ItemBarcode")));                         transTask.setOperateType(1);                         transTask.setAgvFactory(1);                         JSONObject sendAgvTask = submitTask(transTask);                         if (!"1".equals(sendAgvTask.getString("Success"))) {                             log.error("出库下发agv运输任务失败:{}", JSONObject.toJSONString(transTask));                         }                     }                 } else {                     success = 0;                 }             }         }         return success;     }     /**      * 出库申请(叫料),装配库、滑块库      *      * @param mesCallOutApply      * @return      */     public int callOutBoundOrder(MesCallOutApply mesCallOutApply){         // docType根据库类型确定         long docType = 7;         long settle = 1;         // 校验订单是否重复         OrderPakout order = orderPakoutService.selectByNo(mesCallOutApply.getOrderNo());         if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {             return -1;         }         // 生成订单         Date now = new Date();         OrderPakout orderPakout = new OrderPakout();         orderPakout.setUuid(String.valueOf(snowflakeIdWorker.nextId()));         orderPakout.setOrderNo(mesCallOutApply.getOrderNo());         orderPakout.setOrderTime(com.core.common.DateUtils.convert(now));         orderPakout.setDocType(docType);         orderPakout.setSettle(settle);         orderPakout.setStatus(1);         orderPakout.setCreateBy(defaultUserId);         orderPakout.setCreateTime(now);         orderPakout.setUpdateBy(defaultUserId);         orderPakout.setUpdateTime(now);         orderPakout.setMemo(JSONObject.toJSONString(mesCallOutApply));         orderPakout.setPakinPakoutStatus(2);         if (!orderPakoutService.insert(orderPakout)) {             log.error("MES保存出库订单(叫料)主档失败");             throw new CoolException("保存出库订单(叫料)主档失败");         }         // 生成明细         if (mesCallOutApply.getItemdata() != null && !mesCallOutApply.getItemdata().isEmpty()) {             for (MesCallOutApply.MesOutApplyItem mesOutApplyItem : mesCallOutApply.getItemdata()) {                 Mat mat = matService.selectByMatnr(mesOutApplyItem.getItemno());                 OrderDetlPakout orderDetlPakout = new OrderDetlPakout();                 orderDetlPakout.setOrderId(orderPakout.getId());                 orderDetlPakout.setOrderNo(orderPakout.getOrderNo());                 orderDetlPakout.setAnfme(Double.valueOf(mesOutApplyItem.getQty()));                 orderDetlPakout.setQty(0.0);                 orderDetlPakout.setMatnr(mat.getMatnr());                 orderDetlPakout.setMaktx(mat.getMaktx());                 orderDetlPakout.setSpecs(mat.getSpecs());                 orderDetlPakout.setModel(mat.getModel());                 orderDetlPakout.setThreeCode(mesOutApplyItem.getItemBarcode());                 orderDetlPakout.setStandby1(mesOutApplyItem.getTrayid());   //保存配盘号,非托盘号                 orderDetlPakout.setCreateBy(defaultUserId);                 orderDetlPakout.setCreateTime(now);                 orderDetlPakout.setUpdateBy(defaultUserId);                 orderDetlPakout.setUpdateTime(now);                 orderDetlPakout.setStatus(1);                 orderDetlPakout.setPakinPakoutStatus(2);                 if (!orderDetlPakoutService.insert(orderDetlPakout)) {                     log.error("MES保存出库订单(叫料)明细档失败");                     throw new CoolException("保存出库订单(叫料)明细档失败");                 }             }         }         return 1;     }     // endregion     // region 搬运任务调度     // route转发3个WCS任务     @Resource     private BasDevpMapper basDevpMapper;     /**      * 9.1下发运输任务      *      * @param transTask      * @return      */     @Transactional     public JSONObject submitTask(TransTask transTask) {         JSONObject result = new JSONObject();         result.put("taskno", transTask.getTaskno());         // 重复性校验         EntityWrapper<Task> wrapper = new EntityWrapper<>();         wrapper.eq("task_no", transTask.getTaskno());         List<Task> tasks = taskService.selectList(wrapper);         if (tasks != null && !tasks.isEmpty()) {             log.error("agv任务号重复:{}", transTask.getTaskno());             result.put("Success", "2");             result.put("Message", "agv任务号重复:" + transTask.getTaskno());             return result;         }         // 下发给RCS         RcsTaskSubmit rcsTaskSubmit = new RcsTaskSubmit();         // 模板名         if(transTask.getCurStationId().startsWith("LL") || transTask.getCurStationId().startsWith("LJ")                 || transTask.getCurStationId().startsWith("LG") || transTask.getCurStationId().startsWith("LT")) { // 起点产线             rcsTaskSubmit.setTaskType("JJIN");         } else if(transTask.getNextStationId().startsWith("LL") || transTask.getNextStationId().startsWith("LJ")                 || transTask.getNextStationId().startsWith("LG") || transTask.getNextStationId().startsWith("LT")) { // 终点产线             rcsTaskSubmit.setTaskType("JJOUT");         } else if(transTask.getCurStationId().startsWith("B")) { // 不涉及产线,起点接驳位,入库             rcsTaskSubmit.setTaskType("CS4");         } else if(transTask.getNextStationId().startsWith("B")){  // 不涉及产线,终点接驳位,出库             rcsTaskSubmit.setTaskType("CS3");         } else {             log.error("根据起点:{},终点:{},无法匹配模板", transTask.getCurStationId(),transTask.getNextStationId());             result.put("Success", "2");             result.put("Message", "根据起点:"+transTask.getCurStationId()+",终点:"+transTask.getNextStationId()+",无法匹配模板");             return result;         }         rcsTaskSubmit.setRobotTaskCode(transTask.getTaskno());         rcsTaskSubmit.setInitPriority(10);  //默认10         List<RcsTaskTargetRoute> targetRouteList = new ArrayList<>();         RcsTaskTargetRoute startRoute = new RcsTaskTargetRoute();         RcsTaskTargetRoute endRoute = new RcsTaskTargetRoute();         startRoute.setSeq(0);         startRoute.setOperation("COLLECT");         endRoute.setSeq(1);         endRoute.setOperation("DELIVERY");         String curStationId = transTask.getCurStationId(); // 起点         String nextStationId = transTask.getNextStationId(); // 终点         // 起点和终点是输送线时 根据托盘码给AGV不同的站点         startRoute.setCode(transTask.getCurStationId());         if (curStationId.equals("202") || curStationId.equals("204") || curStationId.equals("205")) {             if(curStationId.equals("202") || curStationId.equals("204")) {                 startRoute.setCode(transTask.getCurStationId() + (transTask.getTuoPanId().startsWith("11") ? "-2" : "-1"));             }             // 出库先绑定载具             SiteBind siteBind = new SiteBind("SITE", startRoute.getCode(), "POD", transTask.getTuoPanId(), "BIND");             RcsReturn carrierBindReturn = rcsService.siteBind(siteBind);             if (!carrierBindReturn.getCode().equals("SUCCESS")) {                 log.error("出库绑定载具失败:{}", JSONObject.toJSONString(carrierBindReturn));                 result.put("Success", "2");                 result.put("Message", "出库绑定载具失败:" + JSONObject.toJSONString(carrierBindReturn));                 return result;             }         }         endRoute.setCode(transTask.getNextStationId());         if(nextStationId.equals("202") || nextStationId.equals("204")) {             endRoute.setCode(transTask.getNextStationId() + (transTask.getTuoPanId().startsWith("11") ? "-2" : "-1"));         }         targetRouteList.add(startRoute);         targetRouteList.add(endRoute);         rcsTaskSubmit.setTargetRoute(targetRouteList);         // 转发给海康或华晓RCS         RcsReturn rcsReturn = rcsService.submitTask(rcsTaskSubmit, transTask.getAgvFactory());         if (rcsReturn.getCode().equals("SUCCESS")) {             int workNo = commonService.getWorkNo(WorkNoType.OTHER.type);             Date now = new Date();             Task task = new Task();             task.setWrkNo(workNo);             task.setTaskType("AGV");             task.setWrkSts(301L);             task.setIoType(3);             task.setIoPri(10.00);             task.setWrkDate(now);             task.setSourceStaNo(transTask.getCurStationId());             task.setStaNo(transTask.getNextStationId());             task.setBarcode(transTask.getTuoPanId());             task.setModiUser(defaultUserId);             task.setModiTime(now);             task.setAppeUser(defaultUserId);             task.setAppeTime(now);             task.setTaskNo(transTask.getTaskno());             task.setMemo(JSONObject.toJSONString(transTask));             taskService.insert(task);             Mat mat = matService.selectByMatnr(transTask.getItemno());             TaskDetl taskDetl = new TaskDetl();             taskDetl.setWrkNo(task.getWrkNo());             taskDetl.setIoTime(task.getIoTime());             taskDetl.setMatnr(transTask.getItemno());             taskDetl.setAnfme(0.0); //            taskDetl.setStandby1(String.valueOf(transTask.getQty()));             taskDetl.setMaktx(mat.getMaktx());             taskDetl.setSpecs(mat.getSpecs());             taskDetl.setOrderNo(transTask.getOrderNo());             taskDetl.setZpallet(transTask.getTuoPanId());             taskDetl.setMemo(Cools.isEmpty(transTask.getItemBarcode()) ? "":barCodeListToStr(transTask.getItemBarcode()));             taskDetl.setModiUser(defaultUserId);             taskDetl.setModiTime(now);             taskDetl.setAppeUser(defaultUserId);             taskDetl.setAppeTime(now);             taskDetlService.insert(taskDetl);             result.put("Success", "1");             result.put("Message", "任务接收成功");             // 出入库任务控制 入库暂存+1             if(task.getStaNo().equals("205")) {                 basDevpMapper.updateInQty(Integer.parseInt(task.getStaNo()),1);             }         } else {             result.put("Success", "2");             result.put("Message", "任务下发给RCS失败");         }         return result;     }     /**      * 9.2返回任务执行结果      *      * @param rcsReporterTask      * @return      */     public int reporterTask(RcsReporterTask rcsReporterTask) {         // 结果汇总         boolean completed = true;         EntityWrapper<Task> wrapper = new EntityWrapper<>();         wrapper.eq("task_no", rcsReporterTask.getRobotTaskCode());         List<Task> tasks = taskService.selectList(wrapper);         if (tasks != null && !tasks.isEmpty()) {             for (Task task : tasks) {                 if (task.getWrkSts() != 304) {   // TODO:确认完成,可能存在多盘任务                     completed = false;                 }             }         }         if (completed) {             TransTaskFeedback transTaskFeedback = new TransTaskFeedback();             transTaskFeedback.setTaskno(rcsReporterTask.getRobotTaskCode()); //            transTaskFeedback.setTaskname();             transTaskFeedback.setResult(1);             String url = MES_URL + "api/task/reporter";             String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(transTaskFeedback));             if (!StringUtils.isEmpty(response) && response.contains("Success")){                 MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);                 if("1".equals(mesReturn.getSuccess())) {                     return 1;                 }             }         }         return 0;     }     /**      * 9.8申请华晓AGV进入生产线      *      * @param apply      * @return      */     public String applyInLine(TransParent apply) {         String url = MES_URL + "api/apply/inLine";         String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply));         if (!StringUtils.isEmpty(response) && response.contains("Success")){             JSONObject jsonObject = JSONObject.parseObject(response);             if("1".equals(jsonObject.getString("Success"))) {                 return jsonObject.getJSONObject("Data").getString("status");             }         }         return "N";     }     /**      * 入站请求:转发AGV->入站请求->给MES      *      * @param apply      * @return      */     public int applyInStation(TransParent apply) {         String path = ("LL").equals(apply.getProductLineId()) || ("LJ").equals(apply.getProductLineId()) ? "AGVTransportPalletNotice" : "Aprs/AGVTransportPalletNotice";         String url = MES_URL + path;         String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply));         if (!StringUtils.isEmpty(response) && response.contains("Success")){             MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);             if("1".equals(mesReturn.getSuccess())) {                 return 1;             }         }         return 0;     }     /**      * 入站允许:转发MES->允许入站->给AGV      *      * @param allow      * @return      */     public MesReturn allowInStation(TransInOutStationAllow allow) {         MesReturn mesReturn = new MesReturn();         mesReturn.setSuccess("1");         if ("Y".equals(allow.getStatus())) {             RcsTaskContinue rcsTaskContinue = new RcsTaskContinue();             rcsTaskContinue.setRobotTaskCode(allow.getTaskno());             rcsTaskContinue.setTriggerType("TASK");             rcsTaskContinue.setTriggerCode(allow.getTaskno()); //            rcsTaskContinue.setTriggerType("ROBOT"); //            rcsTaskContinue.setTriggerCode(allow.getAgvCode());             int success = rcsService.continueTask(rcsTaskContinue, 1);             mesReturn.setSuccess(success == 1 ? "1" : "2");             mesReturn.setMessage(success == 1 ? "" : "转发给RCS失败");         }         return mesReturn;     }     /**      * 到站完成:转发AGV->到站完成->给MES      *      * @param arrivalStation      * @return      */     public int arriveOnStation(TransArrivalStation arrivalStation) {         if ("01".equals(arrivalStation.getDaotype())) {             arrivalStation.setItemno(null);             arrivalStation.setItemBarcode(new ArrayList<>());             arrivalStation.setOrderNo(null);         }         String path = ("LL").equals(arrivalStation.getProductLineId()) || ("LJ").equals(arrivalStation.getProductLineId()) ? "AGVArrivalCompleted" : "Aprs/AGVArrivalCompleted";         String url = MES_URL + path;         String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(arrivalStation));         if (!StringUtils.isEmpty(response) && response.contains("Success")){             MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);             if("1".equals(mesReturn.getSuccess())) {                 return 1;             }         }         return 0;     }     /**      * 离站请求:转发AGV->离站请求->给MES      *      * @param apply      * @return      */     public int applyOutStation(TransParent apply) {         String url = MES_URL + "api/apply/outStation";         String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply));         if (!StringUtils.isEmpty(response) && response.contains("Success")){             MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);             if("1".equals(mesReturn.getSuccess())) {                 return 1;             }         }         return 0;     }     /**      * 离站允许:转发MES->允许离站->给AGV      *      * @param allow      * @return      */     public MesReturn allowOutStation(TransInOutStationAllow allow) {         MesReturn mesReturn = new MesReturn();         mesReturn.setSuccess("1");         if ("Y".equals(allow.getStatus())) {             RcsTaskContinue rcsTaskContinue = new RcsTaskContinue();             rcsTaskContinue.setRobotTaskCode(allow.getTaskno());             rcsTaskContinue.setTriggerType("TASK");             rcsTaskContinue.setTriggerCode(allow.getTaskno());             int success = rcsService.continueTask(rcsTaskContinue, checkRcsFactory(allow.getAgvCode()));             mesReturn.setSuccess(success == 1 ? "1" : "2");             mesReturn.setMessage(success == 1 ? "" : "转发给RCS失败");         }         return mesReturn;     }     /**      * 离站完成:转发AGV->离站完成->给MES      *      * @param apply      * @return      */     public int outStation(TransParent apply) {         String path = ("LL").equals(apply.getProductLineId()) || ("LJ").equals(apply.getProductLineId()) ? "AGVDepartureCompleted" : "Aprs/AGVDepartureCompleted";         String url = MES_URL + path;         String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply));         if (!StringUtils.isEmpty(response) && response.contains("Success")){             MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);             if("1".equals(mesReturn.getSuccess())) {                 return 1;             }         }         return 0;     }     @Override     public MesReturn queryInventory(String itemno,String orderNo) {         MesReturn mesReturn = new MesReturn();         mesReturn.setSuccess("1");         List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("matnr", itemno).eq("order_no",orderNo));         int count = 0;         for(LocDetl locDetl:locDetls) {             count += locDetl.getAnfme();         }         mesReturn.setMessage(String.valueOf(count));         return mesReturn;     }     // endregion     /**      * 查询Rcs地址      *      * @param agvNo      * @return 1 海康;2 华晓      */     private int checkRcsFactory(String agvNo) {         AgvInfo agvInfo = agvInfoMapper.selectById(agvNo);         return agvInfo.getAgvFactory();     } }
src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java
@@ -2,6 +2,7 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.core.common.*;
@@ -1292,7 +1293,7 @@
    @Transactional
    public R callEmptyBinOutBound(MesOutApply mesOutApply, String staNo, String locType,int count, Long userId) {
        List<LocMast> locMastList = locMastService.selectList(new EntityWrapper<LocMast>().setSqlSelect("TOP " + count + " *")
                .eq("loc_sts", "D").eq("frozen", 0).eq("loc_type2", locType).orderBy("lev1").orderBy("bay1").orderBy("row1"));
                .eq("loc_sts", "D").eq("frozen", 0).like("barcode", locType, SqlLike.RIGHT).orderBy("lev1").orderBy("bay1").orderBy("row1"));
        if (locMastList.size() < count) {
            return R.parse("空托数量不足(或冻结),剩余数量:" + locMastList.size());
        }
@@ -1300,7 +1301,7 @@
        // 获取路径
        Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
                .eq("type_no", 110)
                .eq("stn_no", 204)
                .eq("stn_no", staNo.startsWith("B") ? 204 : staNo)
                .eq("crn_no", 1);
        StaDesc staDesc = staDescService.selectOne(wrapper);
        if (staDesc == null) {
@@ -1329,6 +1330,7 @@
            wrkMast.setAppeTime(now);
            wrkMast.setModiUser(userId);
            wrkMast.setModiTime(now);
            wrkMast.setBarcode(locMast.getBarcode());
            if (mesOutApply != null) {
                wrkMast.setTaskNo(mesOutApply.getTaskno());
                wrkMast.setAgvSta(mesOutApply.getStationId());
src/main/java/com/zy/asrs/service/impl/RcsServiceImpl.java
@@ -10,6 +10,7 @@
import com.zy.asrs.entity.mes.TransParent;
import com.zy.asrs.entity.rcs.*;
import com.zy.asrs.enums.RcsRetMethodEnum;
import com.zy.asrs.mapper.BasDevpMapper;
import com.zy.asrs.mapper.BlockStationMapper;
import com.zy.asrs.mapper.BlockTaskMapper;
import com.zy.asrs.service.*;
@@ -339,6 +340,9 @@
        return 0;
    }
    @Resource
    private BasDevpMapper basDevpMapper;
    /**
     * 2.2.1任务执行回馈
     * 厂家:海量、华晓
@@ -387,6 +391,100 @@
//                        JSONObject taskMemo = JSONObject.parseObject(task.getMemo());
//                        mesService.outFeedbackByTuo(taskMemo.getString("OrderNo"), task);
                    } break;
                    case APPLY_PUT: { // 放货申请
                        String staNo = task.getStaNo();
                        BasDevp basDevp = basDevpMapper.selectById(staNo);
                        if(basDevp.getAutoing().equals("Y") && basDevp.getLoading().equals("N") && basDevp.getWrkNo() == 0) {
                            // 205 触发条码扫描
                            if (staNo.equals("205")) {
                                Map<String,Object> params = new HashMap<>();
                                params.put("siteId",staNo);
                                String response = new HttpHandler.Builder()
                                        .setUri(WCS_URL)
                                        .setPath("/site/startScan")
                                        .setParams(params)
                                        .build()
                                        .doPost();
                                log.info("{}放货申请给wcs下发条码扫描原始返回:{}",staNo,response);
                            }
                            // 满足放货条件,调用RCS任务继续执行
                            RcsTaskContinue rcsTaskContinue = new RcsTaskContinue();
                            rcsTaskContinue.setRobotTaskCode(robotTaskCode);
                            rcsTaskContinue.setTriggerType("TASK");
                            rcsTaskContinue.setTriggerCode(robotTaskCode);
                            int success = continueTask(rcsTaskContinue, 1);
                            if(success != 1) {
                                rcsReturn.setCode("Err_RobotCodeNotMatch");
                                rcsReturn.setMessage("继续执行失败");
                                JSONObject data = new JSONObject();
                                data.put("robotTaskCode", robotTaskCode);
                                rcsReturn.setData(data);
                                return rcsReturn;
                            }
                        }else {
                            log.warn("站点:{},不满足放货条件,自动:{},无物:{},任务号:{}",staNo,basDevp.getAutoing(),basDevp.getLoading(),basDevp.getWrkNo());
                            rcsReturn.setCode("Err_RobotCodeNotMatch");
                            rcsReturn.setMessage("站点不满足放货条件");
                            JSONObject data = new JSONObject();
                            data.put("robotTaskCode", robotTaskCode);
                            rcsReturn.setData(data);
                            return rcsReturn;
                        }
                    } break;
                    case APPLY_PICK: { // 取货申请
                        String staNo = task.getSourceStaNo();
                        BasDevp basDevp = basDevpMapper.selectById(staNo);
                        if(basDevp.getAutoing().equals("Y") && basDevp.getLoading().equals("Y")
                                && basDevp.getWrkNo()  > 0 && basDevp.getWrkNo() <= 9990) {
                            // 满足放货条件,调用RCS任务继续执行
                            RcsTaskContinue rcsTaskContinue = new RcsTaskContinue();
                            rcsTaskContinue.setRobotTaskCode(robotTaskCode);
                            rcsTaskContinue.setTriggerType("TASK");
                            rcsTaskContinue.setTriggerCode(robotTaskCode);
                            int success = continueTask(rcsTaskContinue, 1);
                            if(success != 1) {
                                rcsReturn.setCode("Err_RobotCodeNotMatch");
                                rcsReturn.setMessage("继续执行失败");
                                JSONObject data = new JSONObject();
                                data.put("robotTaskCode", robotTaskCode);
                                rcsReturn.setData(data);
                                return rcsReturn;
                            }
                        }else {
                            log.warn("站点:{},不满足取货条件,自动:{},无物:{},任务号:{}",staNo,basDevp.getAutoing(),basDevp.getLoading(),basDevp.getWrkNo());
                            rcsReturn.setCode("Err_RobotCodeNotMatch");
                            rcsReturn.setMessage("站点不满足放货条件");
                            JSONObject data = new JSONObject();
                            data.put("robotTaskCode", robotTaskCode);
                            rcsReturn.setData(data);
                            return rcsReturn;
                        }
                    } break;
                    case PICK_COMPLETE: { // 取货完成
                        String staNo = task.getSourceStaNo();
                        // 清除输送线任务号
                        Map<String,Object> params = new HashMap<>();
                        params.put("siteId",staNo);
                        params.put("workNo",0);
                        params.put("staNo", 0);
                        params.put("pakMk","Y");
                        String response = new HttpHandler.Builder()
                                .setUri(WCS_URL)
                                .setPath("/site/detl/update")
                                .setParams(params)
                                .build()
                                .doPost();
                        log.info("agv反馈pickComplete给wcs发命令:{},返回:{}",JSONObject.toJSONString(params),response);
                        // agv继续执行
//                        TransInOutStationAllow inOutStationAllow = new TransInOutStationAllow();
//                        inOutStationAllow.setTaskno(robotTaskCode);
//                        inOutStationAllow.setStatus("Y");
//                        inOutStationAllow.setAgvCode("agv001");
//                        mesService.allowOutStation(inOutStationAllow);
                    } break;
                    case TASK_END: {
                        // 更新任务状态等内部逻辑
                        task.setWrkSts(304L);   // 301 任务下发、302 任务执行、303 任务中断、304 任务结束
@@ -394,9 +492,10 @@
                        task.setModiUser(defaultUserId);
                        taskService.updateById(task);
                        // 任务完成
                        mesService.reporterTask(rcsReporterTask);
//                        mesService.reporterTask(rcsReporterTask);
                        // 入立库时,区分是空托还是满托,给输送线下发命令9990 空,9995满
                        // 侧面205 9996空,9997满
                        String transType = memo.getString("TransType");
                        if("02".equals(transType) || "04".equals(transType)) {
                            int wrkNo = 9995;
@@ -409,11 +508,14 @@
                                }
                            }
                            int staNo = Integer.parseInt(task.getStaNo());
                            if(staNo == 205) { // 侧面任务号转换
                                wrkNo = wrkNo == 9990 ? 9996 : 9997;
                            }
                            Map<String,Object> params = new HashMap<>();
                            params.put("siteId",staNo);
                            params.put("workNo",wrkNo);
                            params.put("staNo", staNo == 205 ? 205 : (staNo-1) );
                            params.put("String","Y");
                            params.put("pakMk","Y");
                            String response = new HttpHandler.Builder()
                                    .setUri(WCS_URL)
                                    .setPath("/site/detl/update")
@@ -460,11 +562,11 @@
                            mesService.outStation(apply);
                            // agv继续执行
                            TransInOutStationAllow inOutStationAllow = new TransInOutStationAllow();
                            inOutStationAllow.setTaskno(robotTaskCode);
                            inOutStationAllow.setStatus("Y");
                            inOutStationAllow.setAgvCode("agv001");
                            mesService.allowOutStation(inOutStationAllow);
//                            TransInOutStationAllow inOutStationAllow = new TransInOutStationAllow();
//                            inOutStationAllow.setTaskno(robotTaskCode);
//                            inOutStationAllow.setStatus("Y");
//                            inOutStationAllow.setAgvCode("agv001");
//                            mesService.allowOutStation(inOutStationAllow);
                        }
                    } break;
                    case ARRIVE_ON_STATION: {
@@ -476,7 +578,7 @@
                        TransArrivalStation arrivalStation = new TransArrivalStation();
                        arrivalStation.setTaskno(robotTaskCode);
                        arrivalStation.setTaskname(memo.getString("taskName"));
                        arrivalStation.setTuoPanId(taskDetl == null ? "":taskDetl.getZpallet());  // memo.getString("TuoPanId")
                        arrivalStation.setTuoPanId(task.getBarcode());  // memo.getString("TuoPanId")
                        arrivalStation.setProductLineId(memo.getString("ProductLineId"));
                        String transType = memo.getString("TransType");
                        arrivalStation.setDaotype(transType);
@@ -737,5 +839,19 @@
        return result.toString();
    }
    @Override
    public RcsReturn siteBind(SiteBind siteBind) {
        RcsReturn rcsReturn = new RcsReturn();
        String url = HIK_URL + "api/robot/controller/site/bind";
        String response = sendPost(url, JSONObject.toJSONString(siteBind));
        if (!StringUtils.isEmpty(response) && response.contains("code")){
            rcsReturn = JSONObject.parseObject(response, RcsReturn.class);
        } else {
            rcsReturn.setCode("ERROR");
            rcsReturn.setMessage("调用绑定接口RCS无返回");
        }
        return rcsReturn;
    }
    // endregion
}
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -611,6 +611,7 @@
            wrkMast.setAppeTime(now);
            wrkMast.setModiUser(userId);
            wrkMast.setModiTime(now);
            wrkMast.setBarcode(locMast.getBarcode());
            boolean res = wrkMastService.insert(wrkMast);
            if (!res) {
                throw new CoolException("保存工作档失败");
src/main/java/com/zy/asrs/service/impl/WrkMastLogServiceImpl.java
@@ -36,8 +36,10 @@
        }
        WrkMastLog mastLog = new WrkMastLog();
        BeanUtils.copyProperties(mast, mastLog);
        mastLog.setLogId(mast.getId());
//        mastLog.setLogId(mast.getId());
        mastLog.setWrkSts(mast.getWrkSts().intValue());
        mastLog.setSourceStaNo(Integer.valueOf(mast.getSourceStaNo()));
        mastLog.setStaNo(Integer.valueOf(mast.getStaNo()));
        if (!wrkMastLogService.insert(mastLog)) {
            throw new CoolException("任务日志保存失败!!");
        }
src/main/java/com/zy/asrs/task/JlerScheduler.java
@@ -7,6 +7,7 @@
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.mapper.WrkMastMapper;
import com.zy.asrs.service.BasDevpService;
import com.zy.asrs.service.DigitalTwinService;
import com.zy.asrs.service.TaskService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.task.handler.JlerHandler;
@@ -51,8 +52,8 @@
     */
    @Scheduled(cron = "0/5 * * * * ? ")
    private void createAgvOutTasks() {
        List<BasDevp> devps = basDevpService.selectList(new EntityWrapper<BasDevp>().in("dev_no", 202, 204)
                .gt("wrk_no",0).lt("wrk_no",9990));
        List<BasDevp> devps = basDevpService.selectList(new EntityWrapper<BasDevp>().in("dev_no", 202, 204, 205)
                .gt("wrk_no",6000).le("wrk_no",9000).eq("loading","Y"));
        for(BasDevp basDevp:devps) {
            WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", basDevp.getWrkNo()));
            if(wrkMast != null && wrkMast.getCallAgv() == 0 && !Cools.isEmpty(wrkMast.getAgvSta())) {
@@ -61,5 +62,17 @@
        }
    }
    @Resource
    private DigitalTwinService digitalTwinService;
    /**
     * 定时统计每天剩余库存
     */
    @Scheduled(cron = "0 50 23 * * ?")
    private void locNumCount() {
        digitalTwinService.locNumCount();
    }
}
src/main/java/com/zy/asrs/task/OrderSyncScheduler.java
@@ -7,6 +7,7 @@
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.mes.*;
import com.zy.asrs.service.*;
import com.zy.asrs.service.impl.MesServiceImpl;
import com.zy.asrs.service.impl.RcsServiceImpl;
import com.zy.asrs.task.core.ReturnT;
import com.zy.asrs.task.handler.OrderSyncHandler;
@@ -146,11 +147,11 @@
                // 回传托盘绑定的零件二维码
                String itemBarcode = orderDetl.getStandby1();
                List<String> itemBarCodeList = new ArrayList<>();
                Matcher matcher = Pattern.compile("\"([^\"]*)\"").matcher(itemBarcode);
                while (matcher.find()) {
                    itemBarCodeList.add(matcher.group(1));
                }
                item.setItemBarcode(itemBarCodeList);
//                Matcher matcher = Pattern.compile("\"([^\"]*)\"").matcher(itemBarcode);
//                while (matcher.find()) {
//                    itemBarCodeList.add(matcher.group(1));
//                }
                item.setItemBarcode(MesServiceImpl.barCodeStrToList(itemBarcode));
                list.add(item);
            }
            MesRecvFeedback mesRecvFeedback = new MesRecvFeedback();
@@ -159,15 +160,15 @@
            mesRecvFeedback.setItemdata(list);
            String url = MES_URL + "MaterialReceiptAndReturn";
//            String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesRecvFeedback));
//            if (!StringUtils.isEmpty(response) && response.contains("Success")) {
//                MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
//                if ("1".equals(mesReturn.getSuccess())) {
            String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesRecvFeedback));
            if (!StringUtils.isEmpty(response) && response.contains("Success")) {
                MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                if ("1".equals(mesReturn.getSuccess())) {
                    orderPakin.setSettle(6L);
                    orderPakinService.updateById(orderPakin);
                    log.info("订单上报成功,orderNo={}", orderNo);
//                }
//            }
                }
            }
        }
    }
src/main/java/com/zy/asrs/task/handler/JlerHandler.java
@@ -63,6 +63,7 @@
//                transTask.setProductLineId(mesOutApply.getProductLineId());
                transTask.setOperateType(1);
                transTask.setAgvFactory(1);
                transTask.setTuoPanId(wrkMast.getBarcode());
                JSONObject sendAgvTask = mesService.submitTask(transTask);
                if ("1".equals(sendAgvTask.getString("Success"))) {
                    wrkMast.setCallAgv(1);
@@ -85,6 +86,7 @@
                transTask.setProductLineId(mesOutApply.getProductLineId());
                transTask.setOperateType(1);
                transTask.setAgvFactory(1);
                transTask.setTuoPanId(wrkMast.getBarcode());
                JSONObject sendAgvTask = mesService.submitTask(transTask);
                if ("1".equals(sendAgvTask.getString("Success"))) {
                    wrkMast.setCallAgv(1);
src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java
@@ -5,6 +5,7 @@
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.enums.LocStsType;
import com.zy.asrs.mapper.BasDevpMapper;
import com.zy.asrs.service.*;
import com.zy.asrs.service.impl.BasStationServiceImpl;
import com.zy.asrs.service.impl.LocCacheServiceImpl;
@@ -57,6 +58,9 @@
    private TaskDetlService taskDetlService;
    @Autowired
    private BasStationServiceImpl basStationService;
    @Resource
    private BasDevpMapper basDevpMapper;
    public ReturnT<String> start(WrkMast wrkMast) {
        // 4.入库完成
@@ -437,6 +441,11 @@
                default:
                    break;
            }
            // 出入库任务控制 入库暂存-1
            if(wrkMast.getSourceStaNo().equals("205")) {
                basDevpMapper.updateInQty(Integer.parseInt(wrkMast.getSourceStaNo()),2);
            }
            // 修改工作主档状态
            wrkMast.setWrkSts(5L);
            wrkMast.setModiTime(now);
src/main/java/com/zy/common/config/AdminInterceptor.java
@@ -128,8 +128,8 @@
            User user = userService.selectById(userLogin.getUserId());
//            String deToken = Cools.deTokn(token, user.getPassword());
//            long timestamp = Long.parseLong(deToken.substring(0, 13));
            // 15分钟后过期
            if (System.currentTimeMillis() - userLogin.getCreateTime().getTime() > 900000){
            // 45分钟后过期
            if (System.currentTimeMillis() - userLogin.getCreateTime().getTime() > 2700000){
                Http.response(response, BaseRes.DENIED);
                return false;
            }
src/main/java/com/zy/common/web/WcsController.java
@@ -63,6 +63,9 @@
        if (Cools.isEmpty(param.getSourceStaNo())) {
            return R.error("源站编号不能为空");
        }
        if (Cools.isEmpty(param.getBarcode())) {
            return R.error("条码不能为空");
        }
        List<WaitPakin> waitPakins = null;
        if (param.getIoType() == 1) {
            if (Cools.isEmpty(param.getBarcode())) {
src/main/java/com/zy/system/controller/UserController.java
@@ -117,6 +117,10 @@
        if (user.getMobile()!=null) {
            entity.setMobile(user.getMobile());
        }
        if (user.getRoleId()!=null) {
            entity.setRoleId(user.getRoleId());
        }
        userService.updateById(entity);
        return R.ok();
    }
src/main/resources/application-dev.yml
@@ -133,8 +133,8 @@
#mes对接
mes:
  url: http://172.26.11.250/dev-api/basicmodel/Api/WMS/
#  url: http://192.9.100.173:8088/prod-api/basicmodel/Api/WMS/
#  url: http://172.26.11.250/dev-api/basicmodel/Api/WMS/
  url: http://192.9.100.173:8088/prod-api/basicmodel/Api/WMS/
  #默认接口操作人员id
  defaultUserId: 30
src/main/resources/mapper/BasDevpMapper.xml
@@ -66,4 +66,15 @@
        group by abd.dev_no
    </select>
    <update id="updateInQty">
        UPDATE asr_bas_devp
        SET in_qty =
        CASE
        WHEN #{type} = 1 THEN in_qty + 1
        WHEN #{type} = 2 AND in_qty > 0 THEN in_qty - 1
        ELSE in_qty
        END
        WHERE dev_no = #{devNo}
    </update>
</mapper>
src/main/resources/mapper/LocCountMapper.xml
@@ -22,11 +22,18 @@
    </select>
    <insert id="insertOrUpdate" parameterType="com.zy.asrs.entity.LocCount">
        IF EXISTS (SELECT date FROM asr_loc_count WHERE date = #{model.date} AND area_id = #{model.areaId})
            INSERT INTO asr_loc_count(date, area_id, loc_num, remain_num)
            VALUES (#{model.date}, #{model.areaId}, #{model.locNum}, #{model.remainNum})
        IF EXISTS (SELECT 1 FROM asr_loc_count WHERE date = #{model.date})
        BEGIN
        UPDATE asr_loc_count
        SET loc_num = #{model.locNum},
        remain_num = #{model.remainNum}
        WHERE date = #{model.date}
        END
        ELSE
            UPDATE asr_loc_count SET loc_num = #{model.locNum}, remain_num = #{model.remainNum}
        BEGIN
        INSERT INTO asr_loc_count(date, area_id, loc_num, remain_num)
        VALUES (#{model.date}, #{model.areaId}, #{model.locNum}, #{model.remainNum})
        END
    </insert>
    <select id="totalLoc" resultType="com.zy.asrs.entity.LocCount">
src/main/resources/mapper/ViewDigitalTwinMapper.xml
@@ -6,45 +6,61 @@
    <!--总览:总库位、已用库位、今日库存、今日出库、今日入库-->
    <select id="overview" resultType="Double">
        SELECT COUNT(*) FROM asr_loc_mast WHERE loc_sts != 'Z'
            <if test="areaId != null">
                and area_id = #{areaId}
            </if>
        <!--            <if test="areaId != null">-->
        <!--                and area_id = #{areaId}-->
        <!--            </if>-->
        UNION ALL
        SELECT COUNT(*) FROM asr_loc_mast WHERE loc_sts = 'F' or loc_sts = 'P' or loc_sts = 'Q' or loc_sts = 'R' or loc_sts = 'S' or loc_sts = 'X'
        <if test="areaId != null">
            and area_id = #{areaId}
        </if>
        <!--        <if test="areaId != null">-->
        <!--            and area_id = #{areaId}-->
        <!--        </if>-->
        UNION ALL
        SELECT ISNULL(SUM(anfme), 0) FROM asr_loc_detl
        <if test="areaId != null">
            WHERE area_id = #{areaId}
        </if>
        <!--        <if test="areaId != null">-->
        <!--            WHERE area_id = #{areaId}-->
        <!--        </if>-->
        UNION ALL
        SELECT ISNULL(SUM(anfme), 0) FROM asr_wrkin_view WHERE CONVERT(VARCHAR, io_time, 23) = CONVERT(VARCHAR, GETDATE(), 23)
        <if test="areaId != null">
            and area_id = #{areaId}
        </if>
        <!--        <if test="areaId != null">-->
        <!--            and area_id = #{areaId}-->
        <!--        </if>-->
        UNION ALL
        SELECT ISNULL(SUM(anfme), 0) FROM asr_wrkout_view WHERE CONVERT(VARCHAR, io_time, 23) = CONVERT(VARCHAR, GETDATE(), 23)
        <if test="areaId != null">
            and area_id = #{areaId}
        </if>
        <!--        <if test="areaId != null">-->
        <!--            and area_id = #{areaId}-->
        <!--        </if>-->
    </select>
    <select id="recentOrder" resultType="com.zy.asrs.entity.digitaltwin.DtOrderVo">
        SELECT CONVERT(VARCHAR, order_time, 23) as orderDate, COUNT(*) AS orderNum
        FROM man_order
        SELECT
        FORMAT(orderDate, 'yyyyMMdd') as orderDate,
        COUNT(*) as orderNum
        FROM (
        SELECT
        CAST(order_time AS DATE) as orderDate
        FROM man_order_pakin
        WHERE order_time BETWEEN #{startTime} AND #{endTime}
        GROUP BY CONVERT(VARCHAR, order_time, 23)
        UNION ALL
        SELECT
        CAST(order_time AS DATE) as orderDate
        FROM man_order_pakout
        WHERE order_time BETWEEN #{startTime} AND #{endTime}
        ) combined
        GROUP BY orderDate
        ORDER BY orderDate
    </select>
    <select id="recentInBound" resultType="com.zy.asrs.entity.digitaltwin.DtInAndOutBoundVo">
        SELECT CONVERT(VARCHAR, io_time, 23) AS boundDate, SUM(anfme) AS inBoundNum
        FROM asr_wrkin_view
        WHERE io_time BETWEEN #{startTime} AND #{endTime}
        <if test="areaId != null">
            and area_id = #{areaId}
        </if>
<!--        <if test="areaId != null">-->
<!--            and area_id = #{areaId}-->
<!--        </if>-->
        GROUP BY CONVERT(VARCHAR, io_time, 23)
    </select>
@@ -52,28 +68,31 @@
        SELECT CONVERT(VARCHAR, io_time, 23) AS boundDate, SUM(anfme) AS outBoundNum
        FROM asr_wrkout_view
        WHERE io_time BETWEEN #{startTime} AND #{endTime}
        <if test="areaId != null">
            and area_id = #{areaId}
        </if>
<!--        <if test="areaId != null">-->
<!--            and area_id = #{areaId}-->
<!--        </if>-->
        GROUP BY CONVERT(VARCHAR, io_time, 23)
    </select>
    <select id="recentDetainMat" resultType="com.zy.asrs.entity.digitaltwin.DtDetainMatVo">
        select
        *
        from (
            select
                ROW_NUMBER() OVER(Order by t.io_time desc) as row , *
            from (
                SELECT area_id AS belongAreaId, area_name AS belongAreaName, matnr AS matId, maktx AS matName,
                       loc_no AS lokId, '' AS lokName,
                       DATEDIFF(MINUTE, appe_time, GETDATE()) AS detainTime, appe_time AS inBoundTime
                    FROM asr_loc_detl WHERE appe_time &lt; #{startTime}
                <if test="areaId != null">
                    and area_id = #{areaId}
                </if>
                ) t
        ) a where 1=1 and a.row between ((#{pageIndex}-1)*#{pageSize}+1) and (#{pageIndex}*#{pageSize})
        SELECT *
        FROM (
        SELECT
        ROW_NUMBER() OVER(ORDER BY t.inBoundTime DESC) AS rownum,
        t.*
        FROM (
        SELECT
        matnr AS matId,
        maktx AS matName,
        loc_no AS lokId,
        '' AS lokName,
        DATEDIFF(MINUTE, appe_time, GETDATE()) AS detainTime,
        appe_time AS inBoundTime
        FROM asr_loc_detl
        WHERE appe_time &lt;= #{startTime}
        ) t
        ) a
        WHERE a.rownum BETWEEN ((#{pageIndex}-1)*#{pageSize}+1) AND (#{pageIndex}*#{pageSize})
    </select>
</mapper>
src/main/resources/mapper/ViewInOutMapper.xml
@@ -19,9 +19,22 @@
            ]]>            
        </if>
</sql>
    <resultMap id="ViewInOutMap" type="com.zy.asrs.entity.ViewInOutBean">
        <result column="ymd" property="ymd"/>
        <result column="source_sta_no" property="source_sta_no"/>
        <result column="sto_qty" property="sto_qty"/>
        <result column="ret_qty" property="ret_qty"/>
        <result column="total_qty" property="total_qty"/>
        <!-- 查询条件字段(一般不从 SQL 返回,也写上不影响) -->
        <result column="begin_date" property="begin_date"/>
        <result column="end_date" property="end_date"/>
    </resultMap>
<!-- 分页查询所有信息 -->
<select id="queryViewInOutList" parameterType="com.zy.asrs.entity.ViewInOutBean" resultType="com.zy.asrs.entity.ViewInOutBean">
<select id="queryViewInOutList" parameterType="com.zy.asrs.entity.ViewInOutBean" resultMap="ViewInOutMap">
select * from ( 
select *,ROW_NUMBER() OVER(Order by ymd desc) as rowid
 from asr_sta_inout_view
src/main/resources/mapper/ViewStayTimeMapper.xml
@@ -38,9 +38,66 @@
            ]]>
        </if>
</sql>
    <resultMap id="ViewStayTimeMap" type="com.zy.asrs.entity.ViewStayTimeBean">
        <!-- 分页 / 行号 -->
        <result column="row" property="row"/>
        <result column="stay_time" property="stay_time"/>
        <!-- 时间条件 -->
        <result column="begin_date" property="begin_date"/>
        <result column="end_date" property="end_date"/>
        <!-- 基础信息 -->
        <result column="loc_no" property="loc_no"/>
        <result column="zpallet" property="zpallet"/>
        <result column="anfme" property="anfme"/>
        <result column="matnr" property="matnr"/>
        <result column="maktx" property="maktx"/>
        <result column="batch" property="batch"/>
        <!-- ⚠️ 特别注意这个 -->
        <result column="order_no" property="orderNo"/>
        <result column="specs" property="specs"/>
        <result column="model" property="model"/>
        <result column="color" property="color"/>
        <result column="brand" property="brand"/>
        <result column="unit" property="unit"/>
        <result column="price" property="price"/>
        <result column="sku" property="sku"/>
        <result column="units" property="units"/>
        <result column="barcode" property="barcode"/>
        <result column="origin" property="origin"/>
        <result column="manu" property="manu"/>
        <result column="manu_date" property="manu_date"/>
        <result column="item_num" property="item_num"/>
        <result column="safe_qty" property="safe_qty"/>
        <result column="weight" property="weight"/>
        <result column="man_length" property="man_length"/>
        <result column="volume" property="volume"/>
        <result column="three_code" property="three_code"/>
        <result column="supp" property="supp"/>
        <result column="supp_code" property="supp_code"/>
        <!-- 标志位 -->
        <result column="be_batch" property="be_batch"/>
        <result column="dead_time" property="dead_time"/>
        <result column="dead_warn" property="dead_warn"/>
        <result column="source" property="source"/>
        <result column="inspect" property="inspect"/>
        <result column="danger" property="danger"/>
        <!-- 审计字段 -->
        <result column="modi_user" property="modi_user"/>
        <result column="modi_time" property="modi_time"/>
        <result column="appe_user" property="appe_user"/>
        <result column="appe_time" property="appe_time"/>
        <result column="memo" property="memo"/>
    </resultMap>
<!-- 分页查询所有信息 -->
<select id="queryViewStayTimeList" parameterType="com.zy.asrs.entity.ViewStayTimeBean" resultType="com.zy.asrs.entity.ViewStayTimeBean">
<select id="queryViewStayTimeList" parameterType="com.zy.asrs.entity.ViewStayTimeBean" resultMap="ViewStayTimeMap">
    select
    *
    from (
src/main/resources/mapper/ViewStockUseMapper.xml
@@ -9,9 +9,20 @@
            and row1 like '%' + #{row1} + '%'
        </if>
</sql>
    <resultMap id="ViewStockUseMap" type="com.zy.asrs.entity.ViewStockUseBean">
        <id column="row1" property="row1"/>
        <result column="total_qty"  property="total_qty"/>
        <result column="full_qty"   property="full_qty"/>
        <result column="null_qty"   property="null_qty"/>
        <result column="forbid_qty" property="forbid_qty"/>
        <result column="empty_qty"  property="empty_qty"/>
        <!--        <result column="use_qty"    property="use_qty"/>-->
        <result column="full_rate"  property="full_rate"/>
        <result column="occ_rate"   property="occ_rate"/>
    </resultMap>
<!-- 分页查询所有信息 -->
<select id="queryViewStockUseList" parameterType="com.zy.asrs.entity.ViewStockUseBean" resultType="com.zy.asrs.entity.ViewStockUseBean">
<select id="queryViewStockUseList" parameterType="com.zy.asrs.entity.ViewStockUseBean" resultMap="ViewStockUseMap">
select top (#{pageSize}) * from asr_stk_use_view 
<where>
    row1 not in (select top ((#{pageNumber}-1)*#{pageSize}) row1 from asr_stk_use_view 
src/main/resources/mapper/ViewWorkInMapper.xml
@@ -83,10 +83,76 @@
            ]]>
        </if>
</sql>
    <resultMap id="ViewWorkInMap" type="com.zy.asrs.entity.ViewWorkInBean">
        <!-- 分页 / 行号 / 停留时长 -->
        <result column="row" property="row"/>
        <result column="stay_time" property="stay_time"/>
        <!-- 查询条件 -->
        <result column="begin_date" property="begin_date"/>
        <result column="end_date" property="end_date"/>
        <result column="query_date" property="query_date"/>
        <!-- 堆垛机 / 时间 -->
        <result column="crn_str_time" property="crn_str_time"/>
        <result column="crn_end_time" property="crn_end_time"/>
        <!-- 作业信息 -->
        <result column="wrk_no" property="wrk_no"/>
        <result column="io_time" property="io_time"/>
        <!-- 库存信息 -->
        <result column="loc_no" property="loc_no"/>
        <result column="zpallet" property="zpallet"/>
        <result column="anfme" property="anfme"/>
        <result column="matnr" property="matnr"/>
        <result column="maktx" property="maktx"/>
        <result column="batch" property="batch"/>
        <!-- ⚠️ 注解在 XML 中无效,必须手动 -->
        <result column="order_no" property="orderNo"/>
        <result column="specs" property="specs"/>
        <result column="model" property="model"/>
        <result column="color" property="color"/>
        <result column="brand" property="brand"/>
        <result column="unit" property="unit"/>
        <result column="price" property="price"/>
        <result column="sku" property="sku"/>
        <result column="units" property="units"/>
        <result column="barcode" property="barcode"/>
        <result column="origin" property="origin"/>
        <result column="manu" property="manu"/>
        <result column="manu_date" property="manu_date"/>
        <result column="item_num" property="item_num"/>
        <result column="safe_qty" property="safe_qty"/>
        <result column="weight" property="weight"/>
        <result column="man_length" property="man_length"/>
        <result column="volume" property="volume"/>
        <result column="three_code" property="three_code"/>
        <result column="supp" property="supp"/>
        <result column="supp_code" property="supp_code"/>
        <!-- 标志 / 策略 -->
        <result column="be_batch" property="be_batch"/>
        <result column="dead_time" property="dead_time"/>
        <result column="dead_warn" property="dead_warn"/>
        <result column="source" property="source"/>
        <result column="inspect" property="inspect"/>
        <result column="danger" property="danger"/>
        <!-- 审计字段 -->
        <result column="modi_user" property="modi_user"/>
        <result column="modi_time" property="modi_time"/>
        <result column="appe_user" property="appe_user"/>
        <result column="appe_time" property="appe_time"/>
        <result column="memo" property="memo"/>
    </resultMap>
<!-- 入库统计 -->
<!-- 分页查询所有信息 -->
<select id="queryViewWorkInList" parameterType="com.zy.asrs.entity.ViewWorkInBean" resultType="com.zy.asrs.entity.ViewWorkInBean">
<select id="queryViewWorkInList" parameterType="com.zy.asrs.entity.ViewWorkInBean" resultMap="ViewWorkInMap">
    select
    *
    from (
@@ -122,7 +188,7 @@
<!-- 出库统计 -->
<!-- 分页查询所有信息 -->
<select id="queryViewWorkOutList" parameterType="com.zy.asrs.entity.ViewWorkInBean" resultType="com.zy.asrs.entity.ViewWorkInBean">
<select id="queryViewWorkOutList" parameterType="com.zy.asrs.entity.ViewWorkInBean" resultMap="ViewWorkInMap">
    select
src/main/webapp/static/js/locDetl/locDetl.js
@@ -10,7 +10,8 @@
        ,{field: 'batch', align: 'center',title: '批号', width: 300, hide:true}
        ,{field: 'anfme', align: 'center',title: '数量'}
        ,{field: 'zpallet', align: 'center',title: '托盘条码'}
        ,{field: 'specs', align: 'center',title: '规格'}
        ,{field: 'standby1', align: 'center',title: '物料二维码'}
        ,{field: 'specs', align: 'center',title: '规格',hide: true}
        ,{field: 'model', align: 'center',title: '代码', hide: true}
        ,{field: 'color', align: 'center',title: '颜色', hide: true}
        ,{field: 'brand', align: 'center',title: '品牌', hide: true}
src/main/webapp/static/js/pakStore/emptyOut.js
@@ -55,6 +55,7 @@
            ,{field: 'row1', align: 'center',title: '排'}
            ,{field: 'bay1', align: 'center',title: '列'}
            ,{field: 'lev1', align: 'center',title: '层'}
            ,{field: 'barcode', align: 'center',title: '托盘码'}
            ,{field: 'fullPlt', align: 'center',title: '满板', templet:function(row){
                    var html = "<input value='fullPlt' type='checkbox' disabled=‘disabled’ lay-skin='primary' lay-filter='tableCheckbox' table-index='"+row.LAY_TABLE_INDEX+"'";
                    if(row.fullPlt === 'Y'){html += " checked ";}
src/main/webapp/views/pakStore/emptyOut.html
@@ -81,6 +81,19 @@
    </div>
    <div class="layui-inline">
        <div class="layui-input-inline">
            <select name="barcode" lay-search>
                <option value="">托盘类型</option>
                <option value="11">角架托盘</option>
                <option value="12">调节螺杆</option>
                <option value="13">调节螺套</option>
                <option value="14">横向连杆</option>
                <option value="15">纵向连杆</option>
                <!-- 后续可以继续加 -->
            </select>
        </div>
    </div>
    <div class="layui-inline">
        <div class="layui-input-inline">
            <input class="layui-input" type="text" name="row1" placeholder="排" lay-verify="number"  autocomplete="off">
        </div>
    </div>