自动化立体仓库 - WMS系统
#
whycq
2024-01-12 ef106c9a6002872892de9db355ef7cd37512dba5
#
3个文件已修改
2个文件已添加
440 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/task/LocMoveAllScheduler.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/LocMoveAllHandler.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/Utils.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/service/CommonService.java 190 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/LocMoveAllScheduler.java
New file
@@ -0,0 +1,91 @@
package com.zy.asrs.task;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.entity.BasCrnp;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.BasCrnpService;
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.LocMoveAllHandler;
import com.zy.asrs.utils.Utils;
import com.zy.common.properties.SlaveProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * Created by vincent on 2020/7/7
 */
@Slf4j
@Component
public class LocMoveAllScheduler {
    @Value("${loc-move.move-all}")
    private boolean moveAll;
    @Autowired
    private LocMoveAllHandler locMoveAllHandler;
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private LocMastService locMastService;
    @Autowired
    private BasCrnpService basCrnpService;
    @Autowired
    private SlaveProperties slaveProperties;
    @Scheduled(cron = "0/3 * * * * ? ")
    private void execute(){
        if (!moveAll) return;
        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<BasCrnp>());
        if (basCrnps.isEmpty()){
            return;
        }
        for (BasCrnp basCrnp:basCrnps){
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("crn_no",basCrnp.getCrnNo()));
            if (Cools.isEmpty(wrkMasts) || wrkMasts.size()==0) {
                LocMast locMastStart = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts","D").eq("crn_no",basCrnp.getCrnNo()).orderBy("appe_time",true));//空板所在
                if (Cools.isEmpty(locMastStart)){
                    continue;
                }
                if (!Utils.isShallowLoc(slaveProperties, locMastStart.getLocNo())){
                    String shallowLocNo = Utils.getShallowLoc(slaveProperties, locMastStart.getLocNo());
                    LocMast locNo = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", shallowLocNo));
                    if (!locNo.getLocSts().equals("O")){
                        locMastStart = locNo;
                    }
                }
                LocMast locMastEnd = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts","O").eq("crn_no",basCrnp.getCrnNo()).ne("modi_user",66).orderBy("row1",true));//目标
                if (Cools.isEmpty(locMastEnd)){
                    continue;
                }
                if (!Utils.isShallowLoc(slaveProperties, locMastEnd.getLocNo())){
                    String shallowLocNo = Utils.getShallowLoc(slaveProperties, locMastEnd.getLocNo());
                    LocMast locNo = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", shallowLocNo));
                    if (locNo.getLocSts().equals("O")){
                    }else {
                        locMastEnd.setModiUser(66L);
                        locMastService.updateById(locMastEnd);
                        continue;
                    }
                }
//                if (Cools.isEmpty(locMastStart) || Cools.isEmpty(locMastEnd)){
                ReturnT<String> result = locMoveAllHandler.start(locMastStart,locMastEnd,basCrnp.getCrnNo());
                if (!result.isSuccess()) {
                    log.error("处理失败");
                }
            }
        }
    }
}
src/main/java/com/zy/asrs/task/handler/LocMoveAllHandler.java
New file
@@ -0,0 +1,80 @@
package com.zy.asrs.task.handler;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.WorkService;
import com.zy.asrs.task.AbstractHandler;
import com.zy.asrs.task.core.ReturnT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
/**
 * Created by vincent on 2020/7/6
 */
@Slf4j
@Service
public class LocMoveAllHandler extends AbstractHandler<String> {
    @Autowired
    private WorkService workService;
    @Autowired
    private LocMastService locMastService;
    private final Integer BAY = 6;//PINGSHANG
    @Transactional
    public ReturnT<String> start(LocMast locMastStart, LocMast locMastEnd, Integer crnNo) {
        try {
            LocMast locMastEndNew = null;
            Integer row1 = locMastStart.getRow1();
            Integer row2 = 0;
            Integer bay1 = locMastStart.getBay1();
            Integer lev1 = locMastStart.getLev1();
            if (row1==crnNo*2){
                row1 = crnNo*2-1;
                row2 = row1+1;
            }else {
                row1=crnNo*2;
                row2 = row1-1;
            }
            Integer signInt = 0;
            while (Cools.isEmpty(locMastEndNew) && lev1<10 && signInt<100){
                signInt++;
                bay1 = BAY+1-bay1;
                if ((bay1<BAY && bay1>0) || (bay1.equals(BAY) && lev1>3)){
                }else {
                    bay1=1;
                    lev1++;
                }
                locMastEndNew = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts","O").eq("row1",row1).eq("bay1",bay1).eq("lev1",lev1).ne("modi_user",66));
                LocMast locMastEndNew2 = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts","O").eq("row1",row2).eq("bay1",bay1).eq("lev1",lev1).ne("modi_user",66));
                if (!Cools.isEmpty(locMastEndNew) && !Cools.isEmpty(locMastEndNew2)){
                    locMastEnd = locMastEndNew;
                }
                if ((bay1<BAY && bay1>0)){
                    bay1++;
                }
                if (signInt==100){
                    bay1=1;
                    lev1++;
                    signInt=0;
                }
            }
            workService.locMove(locMastStart.getLocNo(), locMastEnd.getLocNo(), 66L);
        } catch (Exception e) {
            log.error("fail", e);
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return FAIL.setMsg(e.getMessage());
        }
        return SUCCESS;
    }
}
src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java
@@ -272,6 +272,7 @@
                case 11:
                    // 默认目标库位是空板
                    String locSts = "D";
                    Long modiUser = wrkMast.getModiUser();
                    // 库位移转判断是否为空板移转
                    if (wrkMast.getEmptyMk().equals("N")) {
                        locSts = "F";
@@ -289,6 +290,7 @@
                        sourceLoc.setLocSts("O");
                        sourceLoc.setModiTime(now);
                        sourceLoc.setIoTime(now);
                        sourceLoc.setModiUser(modiUser);
                        if (!locMastService.updateById(sourceLoc)) {
//                            exceptionHandle("库位移转 ===>> 修改源库位状态失败;[workNo={0}],[sourceLoc={1}]", wrkMast.getWrkNo(), wrkMast.getSourceLocNo());
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
@@ -300,6 +302,7 @@
                    locMast.setBarcode(wrkMast.getBarcode());
                    locMast.setIoTime(now);
                    locMast.setModiTime(now);
                    locMast.setModiUser(modiUser);
                    if (!locMastService.updateById(locMast)) {
//                        exceptionHandle("库位移转 ===>> 修改目标库位状态失败;[workNo={0}],[locNo={1}]", wrkMast.getWrkNo(), wrkMast.getLocNo());
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
src/main/java/com/zy/asrs/utils/Utils.java
@@ -2,6 +2,7 @@
import com.core.common.Arith;
import com.core.common.Cools;
import com.core.exception.CoolException;
import com.zy.common.properties.SlaveProperties;
import java.text.DecimalFormat;
@@ -172,4 +173,79 @@
        System.out.println(deepRow);
    }
    //库位排号分配
    public static int[] LocNecessaryParameters(Integer whsType, Integer curRow, Integer crnNumber) {
        switch (whsType){
            case 1://经典双伸库位
                return LocNecessaryParametersDoubleExtension(whsType, curRow, crnNumber);
            default:
                return LocNecessaryParametersMove(whsType, curRow, crnNumber);//moveCrnNo
        }
    }
    //经典双伸库位
    public static int[] LocNecessaryParametersDoubleExtension(Integer whsType, Integer curRow, Integer crnNumber) {
        int[] necessaryParameters = new int[]{0, 0, 0, 0};
        if (BooleanWhsTypeSta(whsType)) {
            necessaryParameters[0] = crnNumber; // 轮询次数
            //满板正常入库
            if (curRow.equals(crnNumber * 4)) {
                necessaryParameters[1] = 1;    //curRow   最深库位排
                necessaryParameters[2] = 1;     //crnNo     堆垛机号
                necessaryParameters[3] = 2;    //nearRow  最浅库位排
            } else if (curRow.equals(crnNumber * 4 - 3)) {
                necessaryParameters[1] = 4;    //curRow   最深库位排
                necessaryParameters[2] = 1;     //crnNo     堆垛机号
                necessaryParameters[3] = 3;    //nearRow  最浅库位排
            } else {
                curRow = curRow + 4;
                if (curRow < 1 || curRow > (crnNumber * 4)) {
                    throw new CoolException("库位排号异常:排号:" + curRow);
                }
                if ((curRow - 1) % 4 == 0) {
                    necessaryParameters[1] = curRow;    //curRow   最深库位排
                    necessaryParameters[2] = (curRow + 3) / 4;     //crnNo     堆垛机号
                    necessaryParameters[3] = curRow + 1;    //nearRow  最浅库位排
                } else if (curRow % 4 == 0) {
                    necessaryParameters[1] = curRow;    //curRow   最深库位排
                    necessaryParameters[2] = curRow / 4;     //crnNo     堆垛机号
                    necessaryParameters[3] = curRow - 1;    //nearRow  最浅库位排
                } else {
                    throw new CoolException("库位排号异常:排号:" + curRow);
                }
            }
        }
        return necessaryParameters;
    }
    //经典双伸库位移库
    public static int[] LocNecessaryParametersMove(Integer whsType, Integer curRow, Integer moveCrnNo) {
        int[] necessaryParameters = new int[]{0, 0, 0, 0};
        necessaryParameters[0] = 2; // 轮询次数
        if (curRow.equals(moveCrnNo*4-2)){
            necessaryParameters[1] = curRow+2;    //curRow   最深库位排
            necessaryParameters[2] = moveCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = curRow+1;    //nearRow  最浅库位排
        }else {
            necessaryParameters[1] = curRow-2;    //curRow   最深库位排
            necessaryParameters[2] = moveCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = curRow-1;    //nearRow  最浅库位排
        }
        return necessaryParameters;
    }
    public static boolean BooleanWhsTypeSta(Integer whsType) {
        if (whsType == 6) {
            return true;
        }
        return false;
    }
    public static boolean BooleanWhsTypeSta(Integer whsType, Integer staDescId) {
        if (whsType == 6 && staDescId != 11 && staDescId != 111) {
            return true;
        }
        return false;
    }
}
src/main/java/com/zy/common/service/CommonService.java
@@ -118,49 +118,6 @@
        // 目标库位
        LocMast locMast = null;
//        // 靠近摆放规则 --- 同天同规格物料
//        if (!Cools.isEmpty(matNos)) {
//            List<String> locNos = locDetlService.getSameDetlToday(matNos.get(0), sRow, eRow);
//            for (String locNo : locNos) {
//                if (Utils.isShallowLoc(slaveProperties, locNo)) {
//                    continue;
//                }
//                String shallowLocNo = Utils.getShallowLoc(slaveProperties, locNo);
//                // 检测目标库位是否为空库位
//                LocMast shallowLoc = locMastService.selectById(shallowLocNo);
//                if (shallowLoc != null && shallowLoc.getLocSts().equals("O")) {
//                    if (VersionUtils.locMoveCheckLocType(shallowLoc, locTypeDto)) {
//                        if (basCrnpService.checkSiteError(shallowLoc.getCrnNo(), true)) {
//                            locMast = shallowLoc;
//                            crnNo = locMast.getCrnNo();
//                            break;
//                        }
//                    }
//                }
//            }
//        }
//
//        // 靠近摆放规则 --- 空托
//        if (staDescId == 10) {
//            List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().eq("loc_sts", "D").ge("row1", sRow).le("row1", eRow));
//            if (locMasts.size() > 0) {
//                for (LocMast loc : locMasts) {
//                    if (Utils.isShallowLoc(slaveProperties, loc.getLocNo())) {
//                        continue;
//                    }
//                    String shallowLocNo = Utils.getShallowLoc(slaveProperties,  loc.getLocNo());
//                    // 检测目标库位是否为空库位
//                    LocMast shallowLoc = locMastService.selectById(shallowLocNo);
//                    if (shallowLoc != null && shallowLoc.getLocSts().equals("O")) {
//                        if (basCrnpService.checkSiteError(shallowLoc.getCrnNo(), true)) {
//                            locMast = shallowLoc;
//                            crnNo = locMast.getCrnNo();
//                            break;
//                        }
//                    }
//                }
//            }
//        }
        // 如果没有相近物料,则按规则轮询货架
        if (null == locMast) {
@@ -320,5 +277,152 @@
                throw new CoolException("根据入库站获取库位排号分配失败,入库站:" + sourceStaNo);
        }
    }
    /**
     * 检索库位号
     * @param whsType 类型 1:双深式货架
     * @param staDescId 路径工作类型
     * @param sourceStaNo 源站
     * @param matnr 商品编号集合
     * @return locNo 检索到的库位号
     */
    @Transactional
    public StartupDto getLocNoRun(Integer whsType, Integer staDescId, Integer sourceStaNo, String matnr, String batch, String grade, Integer moveCrnNo, LocTypeDto locTypeDto, int times) {
        if (Cools.isEmpty(matnr)) {  //物料号
            matnr = "";
        }
        if (Cools.isEmpty(batch)) {  //箱号
            batch = "";
        }
        if (Cools.isEmpty(grade)) {  //备用
            grade = "";
        }
        StartupDto startupDto = new StartupDto();
        RowLastno rowLastno = rowLastnoService.selectById(whsType);
        if (Cools.isEmpty(rowLastno)) {
            throw new CoolException("数据异常,请联系管理员");
        }
        // ===============>>>> 开始执行
        int curRow = rowLastno.getCurrentRow();
        int sRow = rowLastno.getsRow();
        int eRow = rowLastno.geteRow();
        int crn_qty = rowLastno.getCrnQty();
        int rowCount = eRow - sRow + 1;
        // 目标堆垛机号
        int crnNo = 0;
        // 目标库位
        LocMast locMast = null;
        // 如果没有相近物料,则按规则轮询货架
        if (null == locMast) {
            Shelves shelves = new Shelves(rowCount, crn_qty);
            int divides = (int) Arith.divides(1, curRow - 1, 2);
            curRow = (int) Arith.remainder(curRow, 2);
            if (curRow == 0) {
                curRow = 2;
            }
            for (int i = 0; i < shelves.group; i ++) {
                curRow = shelves.start(curRow);
                if (curRow < 0) {
                    throw new CoolException("检索库位失败,请联系管理员");
                }
                Integer crnNo1 = shelves.get(curRow);
                crnNo1 = crnNo1 + divides*1;
                if (basCrnpService.checkSiteError(crnNo1, true)) {
                    crnNo = crnNo1;
                    curRow = curRow + divides*2;
                    break;
                }
            }
        }
        if (crnNo == 0) {
            throw new CoolException("没有可用的堆垛机");
        }
        // 获取目标站
        Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
                .eq("type_no", staDescId)
                .eq("stn_no", sourceStaNo)
                .eq("crn_no", crnNo);
        StaDesc staDesc = staDescService.selectOne(wrapper);
        if (Cools.isEmpty(staDesc)) {
            log.error("type_no={},stn_no={},crn_no={}", staDescId, sourceStaNo, crnNo);
            throw new CoolException("入库路径不存在");
        }
        BasDevp staNo = basDevpService.selectById(staDesc.getCrnStn());
        if (!staNo.getAutoing().equals("Y")) {
            throw new CoolException("目标站"+staDesc.getCrnStn()+"不可用");
        }
        // 更新库位排号
        rowLastno.setCurrentRow(curRow);
        rowLastnoService.updateById(rowLastno);
        // 开始查找库位 ==============================>>
        // 1.当检索库排为浅库位排时,优先寻找当前库排的深库位排
        if (locMast == null) {
            if (Utils.isShallowLoc(slaveProperties, curRow)) {
                Integer deepRow = Utils.getDeepRow(slaveProperties, curRow);
                locMast = locMastService.queryFreeLocMast(deepRow, locTypeDto.getLocType1());
                // todo:luxiaotao 如果用浅排找到的深库位,那么则需要判断这个深库位对应的浅库位是否有货(F、X、D)
                // 因库位移转、需预留空库位
                if (!locMastService.checkEmptyCount(locMast)) {
                    locMast = null;
                }
            }
            if (Cools.isEmpty(locMast)) {
                locMast = locMastService.queryFreeLocMast(curRow, locTypeDto.getLocType1());
                // 因库位移转、需预留空库位
                if (!locMastService.checkEmptyCount(locMast)) {
                    locMast = null;
                }
                // 目标库位 ===>> 浅库位, 则校验其深库位是否为 F D X
                if (null != locMast && Utils.isShallowLoc(slaveProperties, locMast.getLocNo())) {
                    LocMast deepLoc = locMastService.selectById(Utils.getDeepLoc(slaveProperties, locMast.getLocNo()));
                    if (!deepLoc.getLocSts().equals("F") && !deepLoc.getLocSts().equals("D") && !deepLoc.getLocSts().equals("X")) {
                        locMast = null;
                    }
                }
                // 目标库位 ===>> 深库位, 则校验其浅库位是否为 O
                if (null != locMast && Utils.isDeepLoc(slaveProperties, locMast.getLocNo())) {
                    LocMast shallowLoc = locMastService.selectById(Utils.getShallowLoc(slaveProperties, locMast.getLocNo()));
                    if (!shallowLoc.getLocSts().equals("O")) {
                        locMast = null;
                    }
                }
            }
        }
        // 2.库位当前所属尺寸无空库位时,调整尺寸参数,向上兼容检索库位
        if (Cools.isEmpty(locMast)) {
            // 当前巷道无空库位时,递归调整至下一巷道,检索全部巷道无果后,跳出递归
            if (times < rowCount) {
                times = times + 1;
                return getLocNoRun(1, staDescId, sourceStaNo, matnr, batch, grade,moveCrnNo, locTypeDto, times);
            }
            // 轻货物找轻库位为空时,可以去找重库位仓
            //if (locTypeDto.getLocType1() == 1) {
            //    locTypeDto.setLocType1((short) 2);
            //    return getLocNoRun(1, staDescId, sourceStaNo, matnr, batch, grade,moveCrnNo, locTypeDto, times);
            //}
            log.error("系统没有空库位!!! 尺寸规格: {}, 轮询次数:{}", JSON.toJSONString(locTypeDto), times);
            throw new CoolException("没有空库位");
        }
        String locNo = locMast.getLocNo();
        // 生成工作号
        int workNo = getWorkNo(0);
        // 返回dto
        startupDto.setWorkNo(workNo);
        startupDto.setCrnNo(crnNo);
        startupDto.setSourceStaNo(sourceStaNo);
        startupDto.setStaNo(staNo.getDevNo());
        startupDto.setLocNo(locNo);
        return startupDto;
    }
}