自动化立体仓库 - WMS系统
pang.jiabao
5 天以前 ef28fc12367f1be5f80682d4300c1e3891bfe5c8
完成部署服务器
22个文件已修改
2个文件已删除
979 ■■■■■ 已修改文件
license.lic 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WrkDetl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WrkMast.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WrkMastLog.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/BasDevpServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/AutoLocMoveScheduler.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/BareBoardScheduler.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/WorkLogScheduler.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/WorkLogHandler.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/config/AdminInterceptor.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/service/CommonService.java 175 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/web/WcsController.java 372 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/web/param/CanningLineInLocParam.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/web/param/SearchLocParam.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/license.lic 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastLogMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/common.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/index.html 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/login.html 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/mat/mat.html 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
license.lic
Binary files differ
src/main/java/com/zy/asrs/entity/WrkDetl.java
@@ -167,7 +167,7 @@
    /**
     * 长度
     */
    @ApiModelProperty(value= "长度")
    @ApiModelProperty(value= "毛重")
    @TableField("man_length")
    private Double manLength;
@@ -225,9 +225,9 @@
    private Integer source;
    /**
     * 要求检验 1: 是  0: 否
     * 贴标结果(1.成功,0.失败)
     */
    @ApiModelProperty(value= "要求检验 1: 是  0: 否  ")
    @ApiModelProperty(value= "贴标结果(1.成功,0.失败)")
    private Integer inspect;
    /**
src/main/java/com/zy/asrs/entity/WrkMast.java
@@ -294,7 +294,7 @@
    // Y:销售订单出库任务
    @ApiModelProperty(value= "")
    @TableField("Pdc_type")
    private String PdcType;
    private String pdcType;
    @ApiModelProperty(value= "")
    @TableField("ctn_no")
src/main/java/com/zy/asrs/entity/WrkMastLog.java
@@ -297,7 +297,7 @@
    @ApiModelProperty(value= "")
    @TableField("Pdc_type")
    private String PdcType;
    private String pdcType;
    @ApiModelProperty(value= "")
    @TableField("ctn_no")
src/main/java/com/zy/asrs/service/impl/BasDevpServiceImpl.java
@@ -55,7 +55,7 @@
            if(station.getLoading()==null || !station.getLoading().equals("Y")) {
                throw new CoolException(devpNo+"站点无物");
            }
            if(station.getWrkNo()!=null && station.getWrkNo()>0 && station.getWrkNo() < 9990) {
            if(station.getWrkNo()!=null && station.getWrkNo()!= 0) {
                throw new CoolException(devpNo+"站点已有工作号");
            }
//            if(!station.getInEnable().equals("Y")) {
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -644,8 +644,8 @@
            wrkMast.setWrkNo(workNo);
            wrkMast.setIoTime(now);
            wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID
            wrkMast.setIoType(locMast.getLocSts().equals("M") ? 111 : 112); // 入出库状态
            wrkMast.setIoPri(10D);
            wrkMast.setIoType(110); // 入出库状态
            wrkMast.setIoPri(14D);
            wrkMast.setSourceStaNo(sourceStaNo); // 源站
            wrkMast.setStaNo(param.getOutSite()); // 目标站
            wrkMast.setCrnNo(locMast.getCrnNo());
@@ -659,7 +659,6 @@
            wrkMast.setAppeTime(now);
            wrkMast.setModiUser(1L);
            wrkMast.setModiTime(now);
            wrkMast.setMemo("生成自动空板出库");
            boolean res = wrkMastService.insert(wrkMast);
            if (!res) {
                throw new CoolException("保存工作档失败");
@@ -814,15 +813,26 @@
        if (Cools.isEmpty(wrkMast)){
            throw new CoolException(workNo+"工作档不存在");
        }
        if (wrkMast.getStaNo() == 1090 && wrkMast.getLocNo() == null) {
            throw new CoolException(workNo+"工作档无法完成,库位号为空!");
        }
        if (wrkMast.getWrkSts() == 4 || wrkMast.getWrkSts() == 14) {
            throw new CoolException("当前工作档已完成");
        }
        // 完成空桶库入出库任务另一个任务
        int workNoOther = 0;
        // 入库 + 库位转移
        if (wrkMast.getWrkSts() < 4 || (wrkMast.getWrkSts() > 10 && wrkMast.getIoType()==11)) {
        if ((wrkMast.getWrkSts() < 4 && wrkMast.getIoType() != 101 && wrkMast.getIoType() != 110) || (wrkMast.getWrkSts() > 10 && wrkMast.getIoType()==11)) {
            wrkMast.setWrkSts(4L);
            workNoOther = wrkMast.getWorkNoOther();
        // 出库
        } else if (wrkMast.getWrkSts() > 10) {
            wrkMast.setWrkSts(14L);
        } else if (wrkMast.getIoType() == 101 || wrkMast.getIoType() == 110) {
            if(wrkMast.getWrkSts() == 2) {
                wrkMast.setWrkSts(15L);
            } else {
                wrkMast.setWrkSts(14L);
            }
            workNoOther = wrkMast.getWorkNoOther();
        }
        Date now = new Date();
        wrkMast.setCrnStrTime(DateUtils.calculate(now, 1L, TimeUnit.SECONDS, true));
@@ -833,6 +843,16 @@
        wrkMast.setManuType("手动完成");
        if (!wrkMastService.updateById(wrkMast)) {
            throw new CoolException("修改工作档失败");
        }
        if(workNoOther != 0) {
            WrkMast wrkMast1 = wrkMastService.selectById(workNoOther);
            wrkMast1.setWrkSts(wrkMast.getWrkSts());
            wrkMast1.setCrnStrTime(wrkMast.getCrnStrTime());
            wrkMast1.setCrnEndTime(now);
            wrkMast1.setModiTime(now);
            wrkMast1.setModiUser(userId);
            wrkMast1.setManuType("手动完成");
            wrkMastService.updateById(wrkMast1);
        }
    }
@@ -1068,7 +1088,7 @@
        String locNo = ""; // 待修改目标库位
        String locSts = ""; // 待修改目标库位状态
        // 入库取消(修改目标库位)
        if (wrkMast.getWrkSts() < 4) {
        if (wrkMast.getWrkSts() <= 10) {
            locNo = wrkMast.getLocNo();
            locSts = "O";
@@ -1088,13 +1108,12 @@
        } else if (wrkMast.getWrkSts() > 10 && wrkMast.getWrkSts() != 14) {
            locNo = wrkMast.getSourceLocNo();
            if (wrkMast.getIoType() == 110) {
                locSts = "D";
                // 出库 M.空母托盘
            } else if (wrkMast.getIoType() == 111) {
                locSts = "M";
                // 出库Z.空子托盘
            } else if (wrkMast.getIoType() == 112) {
                locSts = "Z";
                if(wrkMast.getStaNo() == 1035) { // 子拆盘机站点
                    locSts = "Z";
                }else {
                    locSts = "M";
                }
//                locSts = "D";
            } else if (wrkMast.getIoType() > 100 && wrkMast.getIoType() != 110) {
                // 出库 ===>> F.在库
                locSts = "F";
@@ -1115,21 +1134,9 @@
            throw new CoolException("当前工作状态无法取消");
        }
        //取消入库工作档时,查询组托表,如果有将状态改为待处理
        if(wrkMast.getIoType() == 1) {
            List<WaitPakin> waitPakins=waitPakinService.selectList(new EntityWrapper<WaitPakin>().eq("zpallet", wrkMast.getBarcode()));
            for (WaitPakin waitPakin:waitPakins){
                if (!Cools.isEmpty(waitPakin)) {
                    waitPakin.setIoStatus("N");
                    waitPakin.setLocNo("");
                    waitPakinService.update(waitPakin, new EntityWrapper<WaitPakin>()
//                            .eq("order_no", waitPakin.getOrderNo())
                            .eq("zpallet",waitPakin.getZpallet())
                            .eq("matnr", waitPakin.getMatnr())
                            .eq("batch", waitPakin.getBatch()));
                }
            }
        }
         // 删除组托通知档
         waitPakinService.delete(new EntityWrapper<WaitPakin>().eq("zpallet",wrkMast.getBarcode()));
        //取消出库工作档时,查询单据管理表,回滚作业中数量
        if(wrkMast.getIoType() == 101 || wrkMast.getIoType() == 103) {
@@ -1195,27 +1202,59 @@
        }
        // 删除工作主档
        boolean wrkMastRes = wrkMastService.deleteById(wrkMast);
        // 保存明细
        wrkDetlLogService.save(wrkMast.getWrkNo());
        // 删除工作档明细
        boolean wrkDetlRes = wrkDetlService.delete(new EntityWrapper<WrkDetl>().eq("wrk_no", workNo));
        if (wrkMast.getIoType() != 10 && wrkMast.getIoType() != 110) {
            // 保存工作明细档历史档
            if (!wrkDetlLogService.save(wrkMast.getWrkNo())) {
//                throw new CoolException("保存工作明细历史档失败, workNo = " + wrkMast.getWrkNo());
        // 空桶库任务
        if(wrkMast.getWorkNoOther()  != null && wrkMast.getWorkNoOther() != 0) {
            WrkMast wrkMast1 = wrkMastService.selectById(wrkMast.getWorkNoOther());
            if (wrkMast1 != null) {
                if(wrkMast1.getIoType() == 1) {
                    wrkMast1.setLocSts("O");
                } else {
                    wrkMast1.setLocSts("F");
                }
                // 取消操作人员记录
                wrkMast1.setManuType("手动取消");
                wrkMast1.setModiUser(userId);
                wrkMast1.setModiTime(now);
                // 删除组托通知档
                waitPakinService.delete(new EntityWrapper<WaitPakin>().eq("zpallet",wrkMast1.getBarcode()));
                // 删除工作主档
                wrkMastService.deleteById(wrkMast1);
                // 保存工作明细
                wrkDetlLogService.save(wrkMast1.getWrkNo());
                // 删除工作明细
                wrkDetlService.delete(new EntityWrapper<WrkDetl>().eq("wrk_no", wrkMast1.getWrkNo()));
                // 修改库位状态
                LocMast locMast = locMastService.selectById(wrkMast1.getIoType() == 1 ? wrkMast1.getLocNo() : wrkMast1.getSourceLocNo());
                if (Cools.isEmpty(locMast)) {
                    throw new CoolException("取消工作档失败,库位不存在:" + locNo);
                }
                locMast.setLocSts(locSts);
                locMast.setModiTime(now);
                locMast.setModiUser(userId);
                locMastService.updateById(locMast);
            }
            // 删除工作档明细
            boolean wrkDetlRes = wrkDetlService.delete(new EntityWrapper<WrkDetl>().eq("wrk_no", workNo));
        }
        // 修改库位状态
        LocMast locMast = locMastService.selectById(locNo);
        if (Cools.isEmpty(locMast)) {
            throw new CoolException("取消工作档失败,库位不存在:"+ locNo);
        }
        locMast.setLocSts(locSts);
        locMast.setModiTime(now);
        locMast.setModiUser(userId);
        boolean locMastRes = locMastService.updateById(locMast);
        if (!wrkMastRes || !locMastRes) {
            throw new CoolException("保存数据失败");
        if(locNo != null) {
            LocMast locMast = locMastService.selectById(locNo);
            if (Cools.isEmpty(locMast)) {
                throw new CoolException("取消工作档失败,库位不存在:"+ locNo);
            }
            locMast.setLocSts(locSts);
            locMast.setModiTime(now);
            locMast.setModiUser(userId);
            boolean locMastRes = locMastService.updateById(locMast);
            if (!wrkMastRes || !locMastRes) {
                throw new CoolException("保存数据失败");
            }
        }
    }
@@ -1283,7 +1322,7 @@
        }
        LocTypeDto locTypeDto = new LocTypeDto();
        locTypeDto.setLocType1((short) 1);
        return wcsController.startupFullPutStore(301, list.get(0).getZpallet(), locTypeDto, list.get(0),1,false);
        return wcsController.startupFullPutStore(301, list.get(0).getZpallet(), locTypeDto, list.get(0),false);
    }
    @Override
src/main/java/com/zy/asrs/task/AutoLocMoveScheduler.java
File was deleted
src/main/java/com/zy/asrs/task/BareBoardScheduler.java
File was deleted
src/main/java/com/zy/asrs/task/WorkLogScheduler.java
@@ -1,6 +1,7 @@
package com.zy.asrs.task;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.task.core.ReturnT;
import com.zy.asrs.task.handler.WorkLogHandler;
@@ -9,6 +10,7 @@
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
@@ -23,6 +25,9 @@
    @Autowired
    private WrkMastService wrkMastService;
    @Resource
    private LocMastService locMastService;
    @Scheduled(cron = "0/3 * * * * ? ")
    private void execute(){
        List<WrkMast> wrkMasts = wrkMastService.selectToBeHistoryData();
@@ -37,4 +42,47 @@
        }
    }
// 插入库位
//    @Scheduled(cron = "0 43 * * * ?")
//    private void execute1(){
//        for(int i = 5; i<= 6; i++)
//            for(int j = 41; j<= 56; j ++)
//                for(int k = 1; k <= 11; k++){
//                    LocMast locMast = new LocMast();
//                    locMast.setLocNo("0"+i+"0"+j +""+(k <= 9 ? "0"+k:k));
//                    locMast.setRow1(i);
//                    locMast.setBay1(j);
//                    locMast.setLev1(k);
//                    locMast.setLocSts("O");
//                    locMast.setCrnNo(2);
//                    locMast.setWhsType(1L);
//                    locMast.setLocType1((short)1);
//                    locMast.setLocType2((short)1);
//                    locMast.setLocType3((short)1);
//                    locMast.setFullPlt("N");
//                    locMastService.insert(locMast);
//                }
//        System.out.println("完成---");
//        for(int i = 7; i<= 8; i++)
//            for(int j = 41; j<= 56; j ++)
//                for(int k = 1; k <= 11; k++){
//                    LocMast locMast = new LocMast();
//                    locMast.setLocNo("0"+i+"0"+j +""+(k <= 9 ? "0"+k:k));
//                    locMast.setRow1(i);
//                    locMast.setBay1(j);
//                    locMast.setLev1(k);
//                    locMast.setLocSts("O");
//                    locMast.setCrnNo(3);
//                    locMast.setWhsType(1L);
//                    locMast.setLocType1((short)1);
//                    locMast.setLocType2((short)1);
//                    locMast.setLocType3((short)1);
//                    locMast.setFullPlt("N");
//                    locMastService.insert(locMast);
//                }
//        System.out.println("完成--完成-");
//
//    }
}
src/main/java/com/zy/asrs/task/handler/WorkLogHandler.java
@@ -64,7 +64,7 @@
            // 入库 --------------------------------------------------------------------------------
            if (wrkMast.getWrkSts() == 5) {
                // 全板入库
                if (wrkMast.getIoType() == 1 || wrkMast.getIoType() == 2) {
                if (wrkMast.getIoType() == 1 || wrkMast.getIoType() == 3 || wrkMast.getIoType() == 10) {
                    // 入库通知单
                    if (!Cools.isEmpty(wrkMast.getBarcode())) {
                        // 保存入库通知档历史档
src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java
@@ -55,10 +55,12 @@
        Date now = new Date();
        LocMast locMast = locMastService.selectById(wrkMast.getLocNo());
        try {
            if (null == locMast && wrkMast.getIoType() != 2) {
//                exceptionHandle("工作档[workNo={0}]库位号错误[locNo={1}]", wrkMast.getWrkNo(), wrkMast.getLocNo());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return FAIL.setMsg("工作档[workNo=" + wrkMast.getWrkNo() + "]库位号错误[locNo=" + wrkMast.getLocNo() + "]");
            if (wrkMast.getIoType() != 3) {
                if (null == locMast) {
                    // exceptionHandle("工作档[workNo={0}]库位号错误[locNo={1}]", wrkMast.getWrkNo(), wrkMast.getLocNo());
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return FAIL.setMsg("工作档[workNo=" + wrkMast.getWrkNo() + "]库位号错误[locNo=" + wrkMast.getLocNo() + "]");
                }
            }
            switch (wrkMast.getIoType()) {
@@ -69,7 +71,7 @@
                        if (!Cools.isEmpty(wrkMast.getBarcode())) {
                            locMast.setBarcode(wrkMast.getBarcode());
                        }
                        locMast.setLocSts(wrkMast.getSourceStaNo() == 1027 || wrkMast.getSourceStaNo() == 1020 ? "M" : "Z");
                        locMast.setLocSts(wrkMast.getSourceStaNo() == 1027 || wrkMast.getSourceStaNo() == 1020 || wrkMast.getSourceStaNo() == 1019 ? "M" : "Z");
                        locMast.setIoTime(now);
                        locMast.setModiTime(now);
                        if (!locMastService.updateById(locMast)) {
@@ -540,6 +542,10 @@
            }
            // 修改工作主档状态
            wrkMast.setWrkSts(15L);
            // 空桶出库完成,状态改为2.设备上走
            if(wrkMast.getIoType() == 101 || wrkMast.getIoType() == 110) {
                wrkMast.setWrkSts(2L);
            }
            wrkMast.setModiTime(now);
            if (!wrkMastService.updateById(wrkMast)) {
//                exceptionHandle("更新出库完成状态失败;[workNo={0}]", wrkMast.getWrkNo());
src/main/java/com/zy/common/config/AdminInterceptor.java
@@ -1,6 +1,5 @@
package com.zy.common.config;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.annotations.AppAuth;
import com.core.annotations.ManagerAuth;
@@ -120,7 +119,7 @@
//            String deToken = Cools.deTokn(token, user.getPassword());
//            long timestamp = Long.parseLong(deToken.substring(0, 13));
            // 15分钟后过期
            if (System.currentTimeMillis() - userLogin.getCreateTime().getTime() > 900000){
            if (System.currentTimeMillis() - userLogin.getCreateTime().getTime() > 3600000){
                Http.response(response, BaseRes.DENIED);
                return false;
            }
src/main/java/com/zy/common/service/CommonService.java
@@ -7,6 +7,7 @@
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.result.FindLocNoAttributeVo;
import com.zy.asrs.mapper.LocMastMapper;
import com.zy.asrs.mapper.WrkMastMapper;
import com.zy.asrs.service.*;
import com.zy.asrs.utils.Utils;
@@ -22,7 +23,8 @@
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
 * 货架核心功能
@@ -58,10 +60,8 @@
    @Resource
    private WrkMastMapper wrkMastMapper;
    /**
     * 罐装线号映射目标站点 下标:目标站点
     */
    private static final int[] fillingLineMappingSite = {0,1079,1065,1072};
    @Resource
    private LocMastMapper locMastMapper;
    /**
     * 生成工作号
@@ -169,50 +169,151 @@
        // 入空桶库
        if (staDescId == 1 && locArea == 2) {
            String model = findLocNoAttributeVo.getModel(); // 当前桶类型
            List<WrkMast> wrkMastList = wrkMastMapper.selectLastInEmptyLoc(); // 前面入空桶库的任务(未执行堆垛机入库)
            if (wrkMastList.size() == 0) {
                // 取新库位组的第一个库位
                locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts", 'O').in("row1", 9, 11).orderBy("lev1").orderBy("bay1").orderBy("row1"));
                List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().eq("crn_no", 4).eq("loc_sts", "O"));
                List<LocMast> collect = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 9 || locMast1.getRow1() == 11).collect(Collectors.toList());
                List<LocMast> collect1 = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 10 || locMast1.getRow1() == 12).collect(Collectors.toList()); // 第一个先放这两排
                if (collect.size() == 0 || collect1.size() == 0) {
                    log.error("-----空桶库无空库位----");
                    throw new CoolException("空桶库无空库位");
                }
                // 可用库位组
                List<LocMast> locMastList = new ArrayList<>();
                for(LocMast locMast1:collect) {
                    Optional<LocMast> first = collect1.stream().filter(locMast2 -> locMast1.getRow1() + 1 == locMast2.getRow1() && Objects.equals(locMast1.getLev1(), locMast2.getLev1())
                            && Objects.equals(locMast1.getBay1(), locMast2.getBay1())).findFirst();
                    first.ifPresent(locMastList::add);
                }
                if (locMastList.size() == 0) {
                    log.error("-----空桶库无对应空空桶组----");
                    throw new CoolException("空桶库无对应空空桶组");
                }
                String model = findLocNoAttributeVo.getModel(); // 当前桶类型
                if (model.equals("208L") && locMastList.size() <= 40 * 2 * 2) { // 最上面一层只能放208L,库位剩余量不多时,如果是208L桶入库,则先从最顶层放
                    locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).reversed().thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
                } else {
                    locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
                }
                locMast = locMastList.get(0);
            } else {
                WrkMast wrkMast = wrkMastList.get(0); // 最后一个入空桶库任务
                // 前一个任务明细
                WrkDetl wrkDetl = wrkDetlService.selectOne(new EntityWrapper<WrkDetl>().eq("wrk_no",wrkMast.getWrkNo()));
                // 前一个任务桶类型
                String oldModel = wrkDetl.getModel();
                String oldModel = wrkMast.getPdcType();
                // 前一个任务尾托标识
                Integer oldCtnType = wrkMast.getCtnType();
                if(model.equals(oldModel)) { // 当前桶与前桶是一种类型
                // 当前桶类型
                String matnr = findLocNoAttributeVo.getMatnr();
                if(findLocNoAttributeVo.getMatnr().equals(wrkMast.getPdcType())) { // 当前桶与前桶是一种类型
                    // 当前桶类型的任务有几个
                    long count = wrkMastList.stream().filter(wrkMast1 -> wrkMast1.getPdcType().equals(oldModel)).count();
                    long count = wrkMastList.stream().filter(wrkMast1 -> wrkMast1.getPdcType().equals(matnr)).count();
                    if (count % 2  == 0) { // 偶数,取一组新库位
                        locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts", 'O').in("row1", 9, 11).orderBy("lev1").orderBy("bay1").orderBy("row1"));
                        // 取新库位组的第一个库位
                        List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().eq("crn_no", 4).eq("loc_sts", "O"));
                        List<LocMast> collect = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 9 || locMast1.getRow1() == 11).collect(Collectors.toList());
                        List<LocMast> collect1 = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 10 || locMast1.getRow1() == 12).collect(Collectors.toList()); // 第一个先放这两排
                        if (collect.size() == 0 || collect1.size() == 0) {
                            log.error("-----空桶库无空库位----");
                            throw new CoolException("空桶库无空库位");
                        }
                        // 可用库位组
                        List<LocMast> locMastList = new ArrayList<>();
                        for(LocMast locMast1:collect) {
                            Optional<LocMast> first = collect1.stream().filter(locMast2 -> locMast1.getRow1() + 1 == locMast2.getRow1() && Objects.equals(locMast1.getLev1(), locMast2.getLev1())
                                    && Objects.equals(locMast1.getBay1(), locMast2.getBay1())).findFirst();
                            first.ifPresent(locMastList::add);
                        }
                        if (locMastList.size() == 0) {
                            log.error("-----空桶库无对应空空桶组----");
                            throw new CoolException("空桶库无对应空空桶组");
                        }
                        String model = findLocNoAttributeVo.getModel(); // 当前桶类型
                        if (model.equals("208L") && locMastList.size() <= 40 * 2 * 2) { // 最上面一层只能放208L,库位剩余量不多时,如果是208L桶入库,则先从最顶层放
                            locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).reversed().thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
                        } else {
                            locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
                        }
                        locMast = locMastList.get(0);
                    } else { // 奇数,取前一库位对应的空库位
                        String locNo = wrkMast.getLocNo();
                        int row = Integer.parseInt(locNo.substring(0, 2));
                        if(row == 9 || row == 11) {
                            String newLocNo = (row + 1) + locNo.substring(2);
                        if(row == 10 || row == 12) {
                            String newLocNo =(row == 10 ? "09" : "11") + locNo.substring(2);
                            locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", newLocNo).eq("loc_sts","O"));
                            if (locMast == null) {
                                log.error("-----与前面桶类型一样,前面该桶类型任务数是奇数,是9,11排,但是对应库位不为空----");
                                throw new CoolException("与前面桶类型一样,前面该桶类型任务数是奇数,是9,11排,但是对应库位不为空");
                                log.error("-----与前面桶类型一样,前面该桶类型任务数是奇数,10,12排,但是对应库位不为空----");
                                throw new CoolException("与前面桶类型一样,前面该桶类型任务数是奇数,是10,12排,但是对应库位不为空");
                            }
                        } else {
                            log.error("-----与前面桶类型一样,前面该桶类型任务数是奇数,但是不是9,11排----");
                            throw new CoolException("与前面桶类型一样,前面该桶类型任务数是奇数,但是不是9,11排");
                            log.error("-----与前面桶类型一样,前面该桶类型任务数是奇数,但是不是10,12排----");
                            throw new CoolException("与前面桶类型一样,前面该桶类型任务数是奇数,但是不是10,12排");
                        }
                    }
                } else { // 当前桶与前桶不是一种类型
                      if(oldCtnType == 1) { // 前面是尾桶
                          // 取新库位组的第一个库位
                          locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts", 'O').in("row1", 9, 11).orderBy("lev1").orderBy("bay1").orderBy("row1"));
                          List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().eq("crn_no", 4).eq("loc_sts", "O"));
                          List<LocMast> collect = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 9 || locMast1.getRow1() == 11).collect(Collectors.toList());
                          List<LocMast> collect1 = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 10 || locMast1.getRow1() == 12).collect(Collectors.toList()); // 第一个先放这两排
                          if (collect.size() == 0 || collect1.size() == 0) {
                              log.error("-----空桶库无空库位----");
                              throw new CoolException("空桶库无空库位");
                          }
                          // 可用库位组
                          List<LocMast> locMastList = new ArrayList<>();
                          for(LocMast locMast1:collect) {
                              Optional<LocMast> first = collect1.stream().filter(locMast2 -> locMast1.getRow1() + 1 == locMast2.getRow1() && Objects.equals(locMast1.getLev1(), locMast2.getLev1())
                                      && Objects.equals(locMast1.getBay1(), locMast2.getBay1())).findFirst();
                              first.ifPresent(locMastList::add);
                          }
                          if (locMastList.size() == 0) {
                              log.error("-----空桶库无对应空空桶组----");
                              throw new CoolException("空桶库无对应空空桶组");
                          }
                          String model = findLocNoAttributeVo.getModel(); // 当前桶类型
                          if (model.equals("208L") && locMastList.size() <= 40 * 2 * 2) { // 最上面一层只能放208L,库位剩余量不多时,如果是208L桶入库,则先从最顶层放
                              locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).reversed().thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
                          } else {
                              locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
                          }
                          locMast = locMastList.get(0);
                      } else { // 前面不是尾桶
                          // 判断前面入空桶库任务数量(未执行堆垛机入库)
                          long count = wrkMastList.stream().filter(wrkMast1 -> wrkMast1.getPdcType().equals(oldModel)).count();
                          if (count % 2 == 0) { // 偶数,可以入库
                              // 取新库位组的第一个库位
                              locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts", 'O').in("row1", 9, 11).orderBy("lev1").orderBy("bay1").orderBy("row1"));
                              List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().eq("crn_no", 4).eq("loc_sts", "O"));
                              List<LocMast> collect = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 9 || locMast1.getRow1() == 11).collect(Collectors.toList());
                              List<LocMast> collect1 = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 10 || locMast1.getRow1() == 12).collect(Collectors.toList()); // 第一个先放这两排
                              if (collect.size() == 0 || collect1.size() == 0) {
                                  log.error("-----空桶库无空库位----");
                                  throw new CoolException("空桶库无空库位");
                              }
                              // 可用库位组
                              List<LocMast> locMastList = new ArrayList<>();
                              for(LocMast locMast1:collect) {
                                  Optional<LocMast> first = collect1.stream().filter(locMast2 -> locMast1.getRow1() + 1 == locMast2.getRow1() && Objects.equals(locMast1.getLev1(), locMast2.getLev1())
                                          && Objects.equals(locMast1.getBay1(), locMast2.getBay1())).findFirst();
                                  first.ifPresent(locMastList::add);
                              }
                              if (locMastList.size() == 0) {
                                  log.error("-----空桶库无对应空空桶组----");
                                  throw new CoolException("空桶库无对应空空桶组");
                              }
                              String model = findLocNoAttributeVo.getModel(); // 当前桶类型
                              if (model.equals("208L") && locMastList.size() <= 40 * 2 * 2) { // 最上面一层只能放208L,库位剩余量不多时,如果是208L桶入库,则先从最顶层放
                                  locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).reversed().thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
                              } else {
                                  locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
                              }
                              locMast = locMastList.get(0);
                          } else { // 奇数,不可以入库
                              log.error("-----与前面桶类型不一样,前面桶不是尾桶,前面该桶类型任务数不是偶数,不能入库----");
                              throw new CoolException("与前面桶类型不一样,前面桶不是尾桶,前面该桶类型任务数不是偶数,不能入库");
@@ -222,17 +323,34 @@
            }
        } else if ((staDescId == 1 && locArea == 1) || staDescId == 10) { // 满板入成品库或者空板入成品库
            // 按层列排顺序获取一个CanningLineInLocParam param库位
            locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts", 'O').in("row1", 1, 4, 5, 6, 7, 8).orderBy("lev1").orderBy("bay1").orderBy("row1"));
            // 浅库位没有了则获取一个浅库位
            // 入成品库摆放规则 判断可用堆垛机自动-无报警 按层列排顺序从下往上,从前往后排 先深库位在浅库位 最上面一层只能放208L桶(剩余库位达到一个阈值208L就先从最上面开始放,下面留给其他货物-后续优化)
            List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<BasCrnp>().eq("crn_sts", 3).eq("crn_err", 0).in("crn_no",1,2,3));
            if (basCrnps.size() == 0) {
                log.error("入库请求库位失败,没有联机堆垛机或堆垛机异常");
                throw new CoolException("入库请求库位失败,没有联机堆垛机或堆垛机异常");
            }
            List<Integer> crnList = basCrnps.stream().map(BasCrnp::getCrnNo).collect(Collectors.toList());
            // 入库桶型
            String model = findLocNoAttributeVo.getModel();
            Wrapper<LocMast> wrapper = new EntityWrapper<LocMast>().eq("loc_sts", 'O')
                    .in("crn_no", crnList).orderBy("lev1").orderBy("bay1").orderBy("row1");
            // 入库桶型是不是208L
            if (model == null || !model.equals("208L")) {
                wrapper.ne("lev1", 11);
            }
            locMast = locMastService.selectOne(wrapper.in("row1", 1, 4, 5, 6, 7, 8));
            // 深库位没有了则获取一个浅库位
            if (locMast == null) {
                locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts", 'O').in("row1", 2, 3).orderBy("lev1").orderBy("bay1").orderBy("row1"));
                locMast = locMastService.selectOne(wrapper.in("row1", 2, 3));
                if (locMast == null) {
                    log.error("-----库位不足----");
                    throw new CoolException("库位不足");
                } else {
                    int count = locMastService.selectCount(new EntityWrapper<LocMast>().eq("loc_sts", 'O'));
                    int count = locMastService.selectCount(wrapper.in("row1", 2, 3));
                    if (count <= 10) {
                        log.error("-----库位不足,预留10个库位用来库位转移----");
                        throw new CoolException("库位不足,预留10个库位用来库位转移");
@@ -271,15 +389,14 @@
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public StartupDto getLocNo(SearchLocParam param, Integer wantBucketFlag) {
    public StartupDto getLocNo(SearchLocParam param, Integer staNo) {
        // 返回dto
        StartupDto startupDto = new StartupDto();
        startupDto.setWorkNo(getWorkNo(0)); // 工作号
        startupDto.setSourceStaNo(param.getSourceStaNo()); // 源站点
        startupDto.setStaNo(fillingLineMappingSite[wantBucketFlag]); // 目标站点
        startupDto.setCrnNo(wantBucketFlag); // 记录罐装线号,wcs清除要桶信号
        startupDto.setStaNo(staNo); // 目标站点
        return startupDto;
    }
src/main/java/com/zy/common/web/WcsController.java
@@ -16,6 +16,7 @@
import com.zy.common.service.CommonService;
import com.zy.common.web.param.CanningLineInLocParam;
import com.zy.common.web.param.SearchLocParam;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,10 +25,7 @@
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.*;
/**
 * Created by vincent on 2020/10/30
@@ -80,22 +78,6 @@
        if (param.getIoType() == 1) {
            // 先创建入库通知档
            waitPakin = comb(param.getBarcode(),param.getBucketType(),param.getBucketCount());
//            if (Cools.isEmpty(param.getBarcode())) {
//                return R.error("条码不能为空");
//            }
//            waitPakins = waitPakinService.selectList(new EntityWrapper<WaitPakin>().eq("zpallet", param.getBarcode()));
//            if (Cools.isEmpty(waitPakins)) {
//                WrkMast wrkMast = wrkMastService.selectByBarcode(param.getBarcode());
//                if (wrkMast != null && wrkMast.getIoType() == 103) {
//                    return R.parse(CodeRes.PICK_600);
//                }
//                return R.parse(CodeRes.NO_COMB_700);
//            }
//            int countLoc = locDetlService.selectCount(new EntityWrapper<LocDetl>().eq("zpallet",param.getBarcode()));
//            int countWrk = wrkDetlService.selectCount(new EntityWrapper<WrkDetl>().eq("zpallet",param.getBarcode()));
//            if (countLoc > 0 || countWrk > 0) {
//                return R.error(CodeRes.EXIST_500);
//            }
        }
        if (Cools.isEmpty(param.getLocType1())){
            return R.error("高低检测信号不能为空");
@@ -109,12 +91,13 @@
        StartupDto dto = null;
        if(param.getIoType() == 1) {
            Map<Integer, String> wantBucketFlag = param.getWantBucketFlag();
            if(!wantBucketFlag.isEmpty()) {
            List<SearchLocParam.WantBucket> wantBucketFlag = param.getWantBucketFlag();
            Optional<SearchLocParam.WantBucket> first = wantBucketFlag.stream().filter(wantBucket -> wantBucket.getBucketType() == param.getBucketType()).findFirst();
            if (first.isPresent()) {
                if(waitPakin == null) {
                    return R.error("入库通知档为空");
                } else {
                    dto = startupFullPutStore(param,waitPakin); // 直供罐装线任务
                    dto = startupFullPutStore(param,waitPakin,first.get()); // 直供罐装线任务
                    if (dto != null) {
                        log.info("WCS入库直供罐装线接口返参:{},托盘码:{}", dto, param.getBarcode());
                        return R.ok().add(dto);
@@ -126,7 +109,7 @@
        switch (param.getIoType()) {
            case 1://满托盘入库
                assert waitPakin != null;
                dto = startupFullPutStore(param.getSourceStaNo(), param.getBarcode(), locTypeDto, waitPakin, param.getLocArea(),param.isTailSupportFlag());
                dto = startupFullPutStore(param.getSourceStaNo(), param.getBarcode(), locTypeDto, waitPakin, param.isTailSupportFlag());
                break;
            case 10://空托盘入库
                dto = emptyPlateIn(param.getSourceStaNo(), locTypeDto, param.getBarcode(), 1);
@@ -142,7 +125,7 @@
    @PostMapping("/pakin/CanningLine/loc/v1")
    @ResponseBody
    @Transactional
    public synchronized R getLocNo(@RequestBody CanningLineInLocParam param) {
    public synchronized R inCanningLine(@RequestBody CanningLineInLocParam param) {
        log.info("收到WCS罐装入库接口请求====>>入参:{}", param);
        if (Cools.isEmpty(param.getWrkNo())) {
            return R.error("工作号不能为空");
@@ -155,71 +138,248 @@
        WrkMast wrkMast1 = wrkMastService.selectById(param.getWrkNo());
        // 根据任务号查询任务明细
        WrkDetl wrkDetl1 = wrkDetlService.selectOne(new EntityWrapper<WrkDetl>().eq("wrk_no", wrkMast1.getWrkNo()));
        // 分配库位
        StartupDto dto = commonService.getLocNoNew(1, param.getSourceStaNo(), null, 1);
        // 创建新任务
        int workNo = dto.getWorkNo();
        Mat mat = matService.selectByMatnr(param.getMatnr());
        if (mat == null) {
            log.error("罐装完成入库,反馈给wcs成品标识不存在:{}",param.getMatnr());
            return R.error("罐装完成入库,反馈给wcs成品标识不存在:" + param.getMatnr());
        }
        // 获取系统配置,看成品罐装完成是否直接出到发货口
        Config config = configService.selectConfigByCode("gzwcfh");
        String fhFlag = "";
        if (config != null && config.getStatus() == 1 && !Cools.isEmpty(config.getValue())) {
            fhFlag = config.getValue();
        }
        Date now = new Date();
        // 生成工作档
        WrkMast wrkMast = new WrkMast();
        wrkMast.setWrkNo(workNo);
        wrkMast.setIoTime(now);
        wrkMast.setWrkSts(2L); // 工作状态:生成入库ID
        wrkMast.setIoType(1); // 入出库状态:1.入库
        wrkMast.setIoPri(13D); // 优先级
        wrkMast.setCrnNo(dto.getCrnNo());
        wrkMast.setSourceStaNo(dto.getSourceStaNo());
        wrkMast.setStaNo(dto.getStaNo());
        wrkMast.setLocNo(dto.getLocNo());
        wrkMast.setBarcode(wrkMast1.getBarcode()); // 托盘码
        wrkMast.setFullPlt("Y"); // 满板:Y
        wrkMast.setPicking("N"); // 拣料
        wrkMast.setExitMk("N"); // 退出
        wrkMast.setEmptyMk("N"); // 空板
        wrkMast.setLinkMis("Y");
        wrkMast.setCtnType(wrkMast1.getCtnType()); // 尾托标识
        wrkMast.setPdcType(wrkMast1.getPdcType()); // 空桶类型
        wrkMast.setAppeTime(now);
        boolean res = wrkMastService.insert(wrkMast);
        if (!res) {
            throw new CoolException("保存工作档失败");
        }
        StartupDto dto;
        // 生成工作档明细
        // todo 入成品桶库的物料 这里先根据空桶类型指定成品桶物料
        String matnr;
        if(wrkMast1.getPdcType().equals("208L")) {
            matnr = "YJ2025011814414206";
        } else {
            matnr = "YJ2025011814412359";
        }
        Mat mat = matService.selectByMatnr(matnr);
        WrkDetl wrkDetl = new WrkDetl();
        wrkDetl.sync(mat);
        wrkDetl.setWrkNo(workNo);
        wrkDetl.setAnfme(wrkDetl1.getAnfme());
        wrkDetl.setZpallet(wrkMast1.getBarcode());
        wrkDetl.setIoTime(now);
        wrkDetl.setAppeTime(now);
        if (!wrkDetlService.insert(wrkDetl)) {
            throw new CoolException("保存工作明细失败");
        }
        // 判断贴标异常,复检重量异常的,不分配库位,去往异常口1090
//        if ( !param.isTbFlag() || param.getGrossWeight() < param.getWeight()) {
//
//            // 生成工作档 ------------------------------------------------------
//            WrkMast wrkMast = new WrkMast();
//            wrkMast.setWrkNo(commonService.getWorkNo(0));
//            wrkMast.setIoTime(now);
//            wrkMast.setIoType(3); // 入出库类型3.站到站
//            wrkMast.setWrkSts(2L);
//            wrkMast.setIoPri(13D); // 优先级
////            wrkMast.setCrnNo(dto.getCrnNo());
//            wrkMast.setSourceStaNo(param.getSourceStaNo());
//            wrkMast.setStaNo(1090);
////            wrkMast.setLocNo(dto.getLocNo());
//            wrkMast.setBarcode(wrkMast1.getBarcode()); // 托盘码
//            wrkMast.setFullPlt("Y"); // 满板:Y
////            wrkMast.setPicking("N"); // 拣料
////            wrkMast.setExitMk("N"); // 退出
////            wrkMast.setEmptyMk("N"); // 空板
////            wrkMast.setLinkMis("Y");
////            wrkMast.setCtnType(wrkMast1.getCtnType()); // 尾托标识
//            wrkMast.setPdcType(wrkMast1.getPdcType()); // 空桶类型
//            wrkMast.setAppeTime(now);
//            wrkMastService.insert(wrkMast);
//
//            // 生成工作档明细----------------------------------------------------
//            WrkDetl wrkDetl = new WrkDetl();
//            wrkDetl.sync(mat);
//            wrkDetl.setWrkNo(wrkMast.getWrkNo());
//            wrkDetl.setAnfme(wrkDetl1.getAnfme());
//            wrkDetl.setZpallet(wrkMast1.getBarcode());
//            wrkDetl.setBatch(param.getBatch());
//            wrkDetl.setManuDate(param.getManuDate());
//            wrkDetl.setWeight(param.getWeight());
//            wrkDetl.setManLength(param.getGrossWeight());
//            wrkDetl.setInspect(1); // 贴标成功
//            wrkDetl.setIoTime(now);
//            wrkDetl.setAppeTime(now);
//            wrkDetlService.insert(wrkDetl);
//
//            dto = new StartupDto();
//            dto.setWorkNo(wrkMast.getWrkNo());
//            dto.setSourceStaNo(wrkMast.getSourceStaNo());
//            dto.setStaNo(wrkMast.getStaNo());
//        } else
        if(param.getMatnr().equals(fhFlag)) { // 直接发货
            // 生成工作档 ------------------------------------------------------
            WrkMast wrkMast = new WrkMast();
            wrkMast.setWrkNo(commonService.getWorkNo(0));
            wrkMast.setIoTime(now);
            wrkMast.setIoType(3); // 入出库类型3.站到站
            wrkMast.setWrkSts(2L);
            wrkMast.setIoPri(13D); // 优先级
//            wrkMast.setCrnNo(dto.getCrnNo());
            wrkMast.setSourceStaNo(param.getSourceStaNo());
            wrkMast.setStaNo(1016);
//            wrkMast.setLocNo(dto.getLocNo());
            wrkMast.setBarcode(wrkMast1.getBarcode()); // 托盘码
            wrkMast.setFullPlt("Y"); // 满板:Y
//            wrkMast.setPicking("N"); // 拣料
//            wrkMast.setExitMk("N"); // 退出
//            wrkMast.setEmptyMk("N"); // 空板
//            wrkMast.setLinkMis("Y");
//            wrkMast.setCtnType(wrkMast1.getCtnType()); // 尾托标识
            wrkMast.setPdcType(wrkMast1.getPdcType()); // 空桶类型
            wrkMast.setAppeTime(now);
            wrkMastService.insert(wrkMast);
        // 完成旧任务(直供罐装线任务手动完成,出库任务任务号消失会自动完成)
        if (wrkMast1.getIoType() == 2) {
            wrkMast1.setWrkSts(4L);
            // 生成工作档明细----------------------------------------------------
            WrkDetl wrkDetl = new WrkDetl();
            wrkDetl.sync(mat);
            wrkDetl.setWrkNo(wrkMast.getWrkNo());
            wrkDetl.setAnfme(wrkDetl1.getAnfme());
            wrkDetl.setZpallet(wrkMast1.getBarcode());
            wrkDetl.setBatch(param.getBatch());
            wrkDetl.setManuDate(param.getManuDate());
            wrkDetl.setWeight(param.getWeight());
            wrkDetl.setManLength(param.getGrossWeight());
            wrkDetl.setInspect(1);
            wrkDetl.setIoTime(now);
            wrkDetl.setAppeTime(now);
            wrkDetlService.insert(wrkDetl);
            dto = new StartupDto();
            dto.setWorkNo(wrkMast.getWrkNo());
            dto.setSourceStaNo(wrkMast.getSourceStaNo());
            dto.setStaNo(wrkMast.getStaNo());
        } else  { // 检测成功,入成品库
                // 检索库位条件
                FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo();
                findLocNoAttributeVo.setMatnr(wrkDetl1.getMatnr());
                findLocNoAttributeVo.setModel(wrkDetl1.getModel());
                // 分配库位
                dto = commonService.getLocNoNew(1, param.getSourceStaNo(), findLocNoAttributeVo, 1);
                // 创建新任务
                int workNo = dto.getWorkNo();
                // 生成工作档
                WrkMast wrkMast = new WrkMast();
                wrkMast.setWrkNo(workNo);
                wrkMast.setIoTime(now);
                wrkMast.setWrkSts(2L); // 工作状态:生成入库ID
                wrkMast.setIoType(1); // 入出库状态:1.入库
                wrkMast.setIoPri(13D); // 优先级
                wrkMast.setCrnNo(dto.getCrnNo());
                wrkMast.setSourceStaNo(dto.getSourceStaNo());
                wrkMast.setStaNo(dto.getStaNo());
                wrkMast.setLocNo(dto.getLocNo());
                wrkMast.setBarcode(wrkMast1.getBarcode()); // 托盘码
                wrkMast.setFullPlt("Y"); // 满板:Y
                wrkMast.setPicking("N"); // 拣料
                wrkMast.setExitMk("N"); // 退出
                wrkMast.setEmptyMk("N"); // 空板
                wrkMast.setLinkMis("Y");
//            wrkMast.setCtnType(wrkMast1.getCtnType()); // 尾托标识
                wrkMast.setPdcType(wrkMast1.getPdcType()); // 空桶类型
                wrkMast.setAppeTime(now);
                wrkMastService.insert(wrkMast);
                // 生成工作档明细
                WrkDetl wrkDetl = new WrkDetl();
                wrkDetl.sync(mat);
                wrkDetl.setWrkNo(workNo);
                wrkDetl.setAnfme(wrkDetl1.getAnfme());
                wrkDetl.setZpallet(wrkMast1.getBarcode());
                wrkDetl.setBatch(param.getBatch());
                wrkDetl.setManuDate(param.getManuDate());
                wrkDetl.setWeight(param.getWeight());
                wrkDetl.setManLength(param.getGrossWeight());
                wrkDetl.setInspect(1); // 贴标成功
                wrkDetl.setIoTime(now);
                wrkDetl.setAppeTime(now);
                wrkDetlService.insert(wrkDetl);
                // 更新目标库位状态
                LocMast locMast = locMastService.selectById(dto.getLocNo());
                if (locMast.getLocSts().equals("O")) {
                    locMast.setLocSts("S"); // S.入库预约
                    locMast.setModiTime(now);
                    if (!locMastService.updateById(locMast)) {
                        throw new CoolException("改变库位状态失败");
                    }
                } else {
                    log.error(dto.getLocNo() + "目标库位已被占用");
                    throw new CoolException(dto.getLocNo() + "目标库位已被占用");
                }
            }
        // 完成旧任务(直供罐装线任务手动完成)
        if (wrkMast1.getIoType() == 3 && wrkMast1.getWrkSts() == 2) {
            wrkMast1.setWrkSts(5L);
            wrkMast1.setModiTime(now);
            wrkMastService.updateById(wrkMast1);
        } else if(wrkMast1.getIoType() == 101 && wrkMast1.getWrkSts() == 2) {
            wrkMast1.setWrkSts(15L);
            wrkMast1.setModiTime(now);
            wrkMastService.updateById(wrkMast1);
        } else {
            log.error("罐装完成,完成旧任务失败:{}",wrkMast1.getWrkNo());
            return R.parse("罐装完成,完成旧任务失败:"+wrkMast1.getWrkNo());
        }
        // 更新源站点信息
        BasDevp basDevp = basDevpService.selectById(param.getSourceStaNo());
        basDevp.setWrkNo(workNo);
        basDevp.setWrkNo(dto.getWorkNo());
        basDevp.setModiTime(now);
        if (!basDevpService.updateById(basDevp)) {
            throw new CoolException("更新源站失败");
        }
        log.info("WCS罐装入库接口返参:{},托盘码:{}", dto, wrkMast1.getBarcode());
        return R.ok(dto);
    }
    // 异常口入库,获取库位
    @PostMapping("/pakin/abnormalMouthWarehousing/loc/v1")
    @ResponseBody
    @Transactional
    public synchronized R abnormalMouthWarehousing(@RequestBody CanningLineInLocParam param) {
        log.info("收到WCS异常口入库接口请求====>>入参:{}", param);
        int wrkNo = param.getWrkNo();
        Integer sourceStaNo = param.getSourceStaNo();
        if (Cools.isEmpty(wrkNo)) {
            return R.error("工作号不能为空");
        }
        if (Cools.isEmpty(sourceStaNo)) {
            return R.error("源站编号不能为空");
        }
        Date now = new Date();
        StartupDto dto;
        WrkMast wrkMast = wrkMastService.selectById(wrkNo);
        if (wrkMast == null) {
            throw new CoolException("异常口入库任务号无任务:" + wrkNo);
        } else if (wrkMast.getLocNo() != null) {
            throw new CoolException("异常口入库库位已分配:" + wrkMast.getLocNo());
        }
        if(!param.isTbFlag()) { //下线出库
            wrkMast.setSourceStaNo(1090);
            wrkMast.setStaNo(1016); // 异常下线默认入库站点为1016
            wrkMastService.updateById(wrkMast);
            return R.ok();
        }
        WrkDetl wrkDetl = wrkDetlService.selectOne(new EntityWrapper<WrkDetl>().eq("wrk_no", wrkNo));
        // 检索库位条件
        FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo();
        findLocNoAttributeVo.setMatnr(wrkDetl.getMatnr());
        findLocNoAttributeVo.setModel(wrkDetl.getModel());
        // 分配库位
        dto = commonService.getLocNoNew(1, param.getSourceStaNo(), findLocNoAttributeVo, 1);
        dto.setWorkNo(wrkMast.getWrkNo()); // 使用原工作号
        wrkMast.setIoType(1); // 入出库类型 1.入库
        wrkMast.setCrnNo(dto.getCrnNo());
        wrkMast.setLocNo(dto.getLocNo());
        wrkMast.setSourceStaNo(dto.getSourceStaNo());
        wrkMast.setStaNo(dto.getStaNo());
        wrkMastService.updateById(wrkMast);
        // 更新目标库位状态
        LocMast locMast = locMastService.selectById(dto.getLocNo());
@@ -234,12 +394,20 @@
            throw new CoolException(dto.getLocNo() + "目标库位已被占用");
        }
        log.info("WCS罐装入库接口返参:{},托盘码:{}", dto, wrkMast1.getBarcode());
        // 更新源站点信息
        BasDevp basDevp = basDevpService.selectById(sourceStaNo);
        basDevp.setWrkNo(dto.getWorkNo());
        basDevp.setModiTime(now);
        if (!basDevpService.updateById(basDevp)) {
            throw new CoolException("更新源站失败");
        }
        log.info("WCS异常口入库接口返参:{},托盘码:{}", dto, wrkMast.getBarcode());
        return R.ok(dto);
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public WaitPakin comb(String barcode, String matnr,int bucketCount) {
    public WaitPakin comb(String barcode, int matnr,int bucketCount) {
        if (Cools.isEmpty(barcode, matnr,bucketCount)) {
            throw new CoolException(BaseRes.PARAM);
        }
@@ -282,7 +450,7 @@
//            for (DetlDto detlDto : detlDtos) {
                Mat mat = matService.selectByMatnr(matnr);
                Mat mat = matService.selectByMatnr(String.valueOf(matnr));
                if (Cools.isEmpty(mat)) {
                    throw new CoolException(matnr + "商品档案不存在");
                }
@@ -443,15 +611,12 @@
     * 全板入库
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public StartupDto startupFullPutStore(Integer devpNo, String barcode, LocTypeDto locTypeDto, WaitPakin waitPakins, int locArea,boolean tailSupportFlag) {
    public StartupDto startupFullPutStore(Integer devpNo, String barcode, LocTypeDto locTypeDto, WaitPakin waitPakins,boolean tailSupportFlag) {
        // 源站点状态检测
        BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true);
        // 检索库位
//        List<String> matnrs = waitPakins.stream().map(WaitPakin::getMatnr).distinct().collect(Collectors.toList());
//        List<String> batchs = waitPakins.stream().map(WaitPakin::getBatch).distinct().collect(Collectors.toList());
//        FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(matnrs.get(0), batchs.get(0));
        FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(waitPakins);
        StartupDto dto = commonService.getLocNoNew( 1, devpNo,findLocNoAttributeVo, locArea);
        StartupDto dto = commonService.getLocNoNew( 1, devpNo,findLocNoAttributeVo,waitPakins.getModel().equals("空托盘") ? 1 : 2);
        int workNo = dto.getWorkNo();
        Date now = new Date();
        // 生成工作档
@@ -472,7 +637,7 @@
        wrkMast.setEmptyMk("N"); // 空板
        wrkMast.setLinkMis("Y");
        wrkMast.setCtnType(tailSupportFlag ? 1 : 0); // 尾托标识
        wrkMast.setPdcType(waitPakins.getModel()); // 空桶类型
        wrkMast.setPdcType(waitPakins.getMatnr()); // 空桶类型
        // 操作人员数据
        wrkMast.setAppeTime(now);
        wrkMast.setModiTime(now);
@@ -524,43 +689,30 @@
     * 直供罐装线
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public StartupDto startupFullPutStore(SearchLocParam param,WaitPakin waitPakin) {
    public StartupDto startupFullPutStore(SearchLocParam param,WaitPakin waitPakin,SearchLocParam.WantBucket wantBucket) {
        // 源站点状态检测
        BasDevp sourceStaNo = basDevpService.checkSiteStatus(param.getSourceStaNo(), true);
        String model = waitPakin.getModel();
        // 判断空桶库有多少这种桶型
        int count = locDetlService.selectCount(new EntityWrapper<LocDetl>().eq("matnr", param.getBucketType()).where("CAST(SUBSTRING(loc_no, 1, 2) as int) >= 9"));
        Integer wantBucketFlag = 0; // 罐装线号
        String wantBucketType; // 桶类型
        boolean flag = true;
        for(Map.Entry<Integer,String> entry :param.getWantBucketFlag().entrySet()) {
            wantBucketFlag = entry.getKey();
            wantBucketType = entry.getValue();
            if(model.equals(wantBucketType)) { // 当前桶类型是罐装线要的类型
                // 空桶库无该类型桶
                int count = locDetlService.selectCount(new EntityWrapper<LocDetl>().eq("model", model).where("CAST(SUBSTRING(loc_no, 1, 2) as int) >= 9"));
                if (count == 0) {
                    flag = false;
                    break;
                }
            }
        }
        if (flag) { // 不满足直供罐装线条件
        // 小于10个则直供罐装线,避免入空桶库后在出库
        if (count > 10) {
             return null;
        }
        StartupDto dto = commonService.getLocNo(param,wantBucketFlag);
        StartupDto dto = commonService.getLocNo(param,wantBucket.getSite());
        int workNo = dto.getWorkNo();
        Date now = new Date();
        // 生成工作档
        WrkMast wrkMast = new WrkMast();
        wrkMast.setWrkNo(workNo);
        wrkMast.setIoTime(now);
        wrkMast.setWrkSts(2L); // 工作状态:生成入库ID
        wrkMast.setIoType(2); // 入出库状态:2.直供罐装线
        wrkMast.setWrkSts(2L);
        wrkMast.setIoType(3); // 入出库状态:3.站到站
        wrkMast.setIoPri(13D); // 优先级
        wrkMast.setCrnNo(dto.getCrnNo());
//        wrkMast.setCrnNo(dto.getCrnNo());
        wrkMast.setSourceStaNo(dto.getSourceStaNo());
        wrkMast.setStaNo(dto.getStaNo());
//        wrkMast.setLocNo(dto.getLocNo());
@@ -571,7 +723,7 @@
        wrkMast.setEmptyMk("N"); // 空板
        wrkMast.setLinkMis("Y");
        wrkMast.setCtnType(param.isTailSupportFlag() ? 1 : 0); // 尾托标识
        wrkMast.setPdcType(model); // 空桶类型
        wrkMast.setPdcType(waitPakin.getMatnr()); // 空桶类型
        // 操作人员数据
        wrkMast.setAppeTime(now);
        wrkMast.setModiTime(now);
@@ -634,8 +786,8 @@
        wrkMast.setExitMk("N"); // 退出
        wrkMast.setEmptyMk("Y"); // 空板
        wrkMast.setLinkMis("Y");
        wrkMast.setBarcode(barcode);
        wrkMast.setCtnType(sourceStaNo.getCtnType()); // 容器类型
//        wrkMast.setBarcode(barcode);
//        wrkMast.setCtnType(sourceStaNo.getCtnType()); // 容器类型
        // 操作人员数据
        wrkMast.setAppeTime(new Date());
        wrkMast.setModiTime(new Date());
src/main/java/com/zy/common/web/param/CanningLineInLocParam.java
@@ -10,14 +10,28 @@
@Data
public class CanningLineInLocParam {
    /**
     * 任务号
     */
    private Integer wrkNo;
    // 任务号
    private int wrkNo;
    /**
     * 源站点
     */
    // 桶型标识
    private String matnr;
    //  批号
    private String batch;
    // 生产日期
    private String manuDate;
    // 净重
    private double weight;
    // 复检重量
    private double grossWeight;
    // 源站点
    private Integer sourceStaNo;
    // 贴标成功否
    private boolean tbFlag;
}
src/main/java/com/zy/common/web/param/SearchLocParam.java
@@ -1,9 +1,9 @@
package com.zy.common.web.param;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
/**
 * Created by vincent on 2020/10/30
@@ -20,11 +20,8 @@
    // 库位规格( 0:未知, 1:低库位, 2:高库位)
    private Short locType1;
    // 库区类型 1.成品库,2.空桶库
    private int locArea;
    // 入库桶编号/物料号
    private String bucketType;
    private int bucketType;
    // 入库桶数量
    private int bucketCount;
@@ -32,6 +29,13 @@
    // 尾托标识
    private boolean tailSupportFlag;
    // 罐装线要桶标识
    private Map<Integer,String> wantBucketFlag =  new HashMap<>();
    // 罐装线要桶 罐装线号-桶类型
    private List<WantBucket> wantBucketFlag;
    @Data
    @AllArgsConstructor
    public static class WantBucket{
        private int site;
        private int bucketType;
    }
}
src/main/resources/application.yml
@@ -10,7 +10,7 @@
    enabled: false
  datasource:
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    url: jdbc:sqlserver://127.0.0.1:1433;databasename=mdqzasrs
    url: jdbc:sqlserver://192.168.2.201:1433;databasename=mdqzasrs
    username: sa
    password: sa@123
  mvc:
src/main/resources/license.lic
Binary files differ
src/main/resources/mapper/WrkMastLogMapper.xml
@@ -65,6 +65,7 @@
        <result column="rgv_ssta_no" property="rgvSstaNo" />
        <result column="rgv_dsta_no" property="rgvDstaNo" />
        <result column="work_no_other" property="workNoOther" />
        <result column="Pdc_type" property="pdcType" />
    </resultMap>
    <sql id="queryWhere">
        <where>
src/main/resources/mapper/WrkMastMapper.xml
@@ -64,6 +64,7 @@
        <result column="rgv_ssta_no" property="rgvSstaNo" />
        <result column="rgv_dsta_no" property="rgvDstaNo" />
        <result column="work_no_other" property="workNoOther" />
        <result column="Pdc_type" property="pdcType" />
    </resultMap>
    <select id="selectToBeCompleteData" resultMap="BaseResultMap">
@@ -152,7 +153,7 @@
        </choose>
    </select>
    <select id="selectLastInEmptyLoc" resultType="com.zy.asrs.entity.WrkMast">
        select wrk_no wrkNo,ctn_type ctnType,Pdc_type PdcType,loc_no locNo from asr_wrk_mast where sta_no = 1050 and wrk_sts in(2,9,10) order by io_time desc
        select wrk_no wrkNo,ctn_type ctnType,Pdc_type pdcType,loc_no locNo from asr_wrk_mast where sta_no = 1050 and wrk_sts in(2,9,10) order by io_time desc
    </select>
</mapper>
src/main/webapp/static/js/common.js
@@ -188,7 +188,7 @@
    ,{field: 'maktx', align: 'center',title: '商品名称(品名)', width: 200}
    // ,{field: 'name', align: 'center',title: '别名'}
    ,{field: 'specs', align: 'center',title: '规格'}
    ,{field: 'model', align: 'center',title: '代码', hide: true}
    ,{field: 'model', align: 'center',title: '桶型'}
    ,{field: 'color', align: 'center',title: '颜色', hide: true}
    ,{field: 'brand', align: 'center',title: '品牌', hide: true}
    ,{field: 'unit', align: 'center',title: '单位', hide: false}
src/main/webapp/views/index.html
@@ -2,11 +2,11 @@
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>中扬 - 自动化立体仓库 - AS / RS</title>
  <title>自动仓库WMS系统</title>
  <meta name="renderer" content="webkit">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
  <link rel="icon" type="image/x-icon" href="../static/image/favicon.ico" />
<!--  <link rel="icon" type="image/x-icon" href="../static/image/favicon.ico" />-->
  <link rel="stylesheet" href="../static/layui/css/layui.css" media="all">
  <link rel="stylesheet" href="../static/css/admin.css?v=318" media="all">
  <link rel="stylesheet" href="../static/css/loader.css" media="all">
@@ -26,7 +26,7 @@
  <!-- 头部 -->
  <div class="layui-header">
    <div class="layui-logo">
      <img src="../static/image/logo.png" style="display: inline-block; width: 40%;height: auto">
<!--      <img src="../static/image/logo.png" style="display: inline-block; width: 40%;height: auto">-->
      <!--          <span style="margin-top: 0; letter-spacing: 10px">中扬立库</span>-->
      <!--          <img src="../static/image/logo.svg"/>-->
      <!--          <cite>中扬 - Zoneyung</cite>-->
@@ -75,7 +75,7 @@
  <div class="layui-body"></div>
  <!-- 底部 -->
  <div class="layui-footer layui-text">
    copyright © 2022 <a href="https://www.superton.cn/" target="_blank">浙江中扬立库有限公司</a> all rights reserved.
<!--    copyright © 2022 <a href="https://www.superton.cn/" target="_blank">浙江中扬立库有限公司</a> all rights reserved.-->
    <span class="pull-right">Version 1.0.0</span>
  </div>
src/main/webapp/views/login.html
@@ -53,7 +53,7 @@
                    z-index: 100;
                    top: 22px;
                    left: 20px;">
        <img src="../static/image/logo.png" alt="" style="width: 20%">
<!--        <img src="../static/image/logo.png" alt="" style="width: 20%">-->
      </div>
      <div class="p-sketch-outline">
        <h2 class="p-sketch-outline__title">Automatic Storage and Retrieval System</h2>
@@ -67,7 +67,7 @@
    <div id="sidebar">
      <div class="login-contain">
        <div class="login-box">
          <img src="../static/image/logo.png" alt="" style="width: 80%">
<!--          <img src="../static/image/logo.png" alt="" style="width: 80%">-->
<!--          <span class="login100-form-title p-t-20 p-b-45">中扬立库</span>-->
<!--          <span class="login100-form-title p-t-20 p-b-45" style="margin: 15px 0;color: #868686;font-size: 24px">WMS</span>-->
          <div class="wrap-input100 validate-input m-b-10" data-validate="请输入用户名">
src/main/webapp/views/mat/mat.html
@@ -199,9 +199,9 @@
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">配置</label>
                    <label class="layui-form-label">桶型</label>
                    <div class="layui-input-block">
                        <input name="specs" placeholder="请输入配置" class="layui-input">
                        <input name="model" placeholder="请输入桶型" class="layui-input">
                    </div>
                </div>