|  |  | 
 |  |  | package com.vincent.rsf.server.api.utils; | 
 |  |  |  | 
 |  |  | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 
 |  |  | import com.vincent.rsf.framework.common.Arith; | 
 |  |  | import com.vincent.rsf.framework.common.Cools; | 
 |  |  | import com.vincent.rsf.framework.common.SpringUtils; | 
 |  |  | import com.vincent.rsf.framework.exception.CoolException; | 
 |  |  | import com.vincent.rsf.server.api.entity.dto.InTaskMsgDto; | 
 |  |  | import com.vincent.rsf.server.api.entity.dto.LocTypeDto; | 
 |  |  | import com.vincent.rsf.server.manager.entity.DeviceBind; | 
 |  |  | import com.vincent.rsf.server.manager.entity.Loc; | 
 |  |  | import com.vincent.rsf.server.manager.service.DeviceBindService; | 
 |  |  | import com.vincent.rsf.server.manager.service.LocService; | 
 |  |  | import com.vincent.rsf.server.manager.entity.*; | 
 |  |  | import com.vincent.rsf.server.manager.enums.LocStsType; | 
 |  |  | import com.vincent.rsf.server.manager.enums.TaskStsType; | 
 |  |  | import com.vincent.rsf.server.manager.service.*; | 
 |  |  | import org.slf4j.Logger; | 
 |  |  | import org.slf4j.LoggerFactory; | 
 |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
 |  |  | import org.springframework.stereotype.Component; | 
 |  |  |  | 
 |  |  |  | 
 |  |  | import javax.annotation.PostConstruct; | 
 |  |  | import java.util.List; | 
 |  |  |  | 
 |  |  | @Component | 
 |  |  | public class LocUtils { | 
 |  |  |  | 
 |  |  |     public static final Logger logger = LoggerFactory.getLogger(LocUtils.class); | 
 |  |  |  | 
 |  |  |     private static List<Integer>  doubleLocs; | 
 |  |  |  | 
 |  |  |     private static Boolean isDoubleDeep; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     private SlaveProperties slavePropertie; | 
 |  |  |  | 
 |  |  |     @PostConstruct | 
 |  |  |     public void init() { | 
 |  |  |         doubleLocs = slavePropertie.getDoubleLocs(); | 
 |  |  |         isDoubleDeep = slavePropertie.isDoubleDeep(); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 获取 浅库位对应的深库位号 | 
 |  |  |      */ | 
 |  |  |     public static String getDeepLoc(SlaveProperties slaveProperties, String shallowLoc) { | 
 |  |  |     public static String getDeepLoc(String shallowLoc) { | 
 |  |  |         LocService locService = SpringUtils.getBean(LocService.class); | 
 |  |  |         Loc shaLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, shallowLoc)); | 
 |  |  |         int row = shaLoc.getRow()-1; | 
 |  |  |         boolean contains = slaveProperties.getDoubleLocs().contains(row); | 
 |  |  |         boolean contains = doubleLocs.contains(row); | 
 |  |  |         Loc deepLoc = null; | 
 |  |  |         if (contains) { | 
 |  |  |             deepLoc = locService.getOne(new LambdaQueryWrapper<Loc>() | 
 |  |  | 
 |  |  |     /** | 
 |  |  |      * 获取 深库位对应的浅库位号 | 
 |  |  |      */ | 
 |  |  |     public static String getShallowLoc(SlaveProperties slaveProperties, String deepLoc) { | 
 |  |  |     public static String getShallowLoc(String deepLoc) { | 
 |  |  |         LocService locService = SpringUtils.getBean(LocService.class); | 
 |  |  |         Loc depLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, deepLoc)); | 
 |  |  |         int row = depLoc.getRow()-1; | 
 |  |  |         boolean contains = slaveProperties.getDoubleLocs().contains(row); | 
 |  |  |         int row; | 
 |  |  |         if (depLoc.getRow() != 1) { | 
 |  |  |             row = depLoc.getRow()-1; | 
 |  |  |         } else { | 
 |  |  |             row = depLoc.getRow(); | 
 |  |  |         } | 
 |  |  |         boolean contains = doubleLocs.contains(row); | 
 |  |  |         Loc shallowLoc = null; | 
 |  |  |         if (!contains) { | 
 |  |  |             shallowLoc = locService.getOne(new LambdaQueryWrapper<Loc>() | 
 |  |  | 
 |  |  |     /** | 
 |  |  |      * 判断是否为浅库位 | 
 |  |  |      */ | 
 |  |  |     public static boolean isShallowLoc(SlaveProperties slaveProperties, String locNo) { | 
 |  |  |         if (slaveProperties.isDoubleDeep()) { | 
 |  |  |     public static boolean isShallowLoc(String locNo) { | 
 |  |  |         if (isDoubleDeep) { | 
 |  |  |             int row = getRow(locNo); | 
 |  |  |             return !slaveProperties.getDoubleLocs().contains(row); | 
 |  |  |             return !doubleLocs.contains(row); | 
 |  |  |         } else { | 
 |  |  |             return false; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     //获取站点对应的库类型 | 
 |  |  |     public static Long getAreaType(Integer sourceStaNo) { | 
 |  |  |     public static Long getAreaType(String sourceStaNo) { | 
 |  |  |         DeviceBindService rowLastnoService = SpringUtils.getBean(DeviceBindService.class); | 
 |  |  |         List<DeviceBind> deviceBinds = rowLastnoService.list(new LambdaQueryWrapper<DeviceBind>()); | 
 |  |  |         for (DeviceBind deviceBind : deviceBinds) { | 
 |  |  |             String[] staNoList = deviceBind.getStaList().split(";"); | 
 |  |  |             for (String staNo : staNoList) { | 
 |  |  |                 if (staNo.equals(sourceStaNo.toString())) { | 
 |  |  |                 if (staNo.equals(sourceStaNo)) { | 
 |  |  |                     return deviceBind.getId(); | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  | 
 |  |  |  | 
 |  |  |     //库位排号分配 | 
 |  |  |     public static int[] LocNecessaryParameters(DeviceBind deviceBind, Integer curRow, Integer crnNumber) { | 
 |  |  |  | 
 |  |  |       return LocNecessaryParametersDoubleExtension(curRow, crnNumber); //已完善 | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     //经典双伸库位 | 
 |  |  |     //经典双伸库位,  获取双深排 | 
 |  |  |     public static int[] LocNecessaryParametersDoubleExtension( Integer curRow, Integer crnNumber) { | 
 |  |  |         int[] necessaryParameters = new int[]{0, 0, 0, 0}; | 
 |  |  |  | 
 |  |  | 
 |  |  |         return dto.getLocType1().equals(Integer.parseInt(loc.getType())); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public static String  getCrnLoc() { | 
 |  |  | //        SlaveProperties bean = SpringUtils.getBean(SlaveProperties.class); | 
 |  |  |         System.out.println(doubleLocs); | 
 |  |  |  | 
 |  |  |         return null; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     public static String zerofill(String msg, Integer count) { | 
 |  |  |         if (msg.length() == count) { | 
 |  |  |             return msg; | 
 |  |  | 
 |  |  |             return msgBuilder.toString(); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 获取堆垛机库位信息 | 
 |  |  |      * @param deviceBind | 
 |  |  |      * @param area | 
 |  |  |      * @param sourceStaNo | 
 |  |  |      * @param matnr | 
 |  |  |      * @param batch | 
 |  |  |      * @param locTypeDto | 
 |  |  |      * @param times | 
 |  |  |      * @param ioType 作业类型(*必传参数) | 
 |  |  |      * @return | 
 |  |  |      */ | 
 |  |  |     public static InTaskMsgDto getLocNoCrn(DeviceBind deviceBind, Long area, String sourceStaNo, String matnr, String batch, LocTypeDto locTypeDto, int times, Integer ioType) { | 
 |  |  |         DeviceBindService deviceBindService = SpringUtils.getBean(DeviceBindService.class); | 
 |  |  |         DeviceSiteService deviceSiteService = SpringUtils.getBean(DeviceSiteService.class); | 
 |  |  |         LocService locService = SpringUtils.getBean(LocService.class); | 
 |  |  |         LocItemService locItemService = SpringUtils.getBean(LocItemService.class); | 
 |  |  |  | 
 |  |  |         if (Cools.isEmpty(matnr)) {  //物料号 | 
 |  |  |             matnr = ""; | 
 |  |  |         } | 
 |  |  |         if (Cools.isEmpty(batch)) {  //批次 | 
 |  |  |             batch = ""; | 
 |  |  |         } | 
 |  |  |         // 初始化参数 | 
 |  |  |         int channel = 0;      //堆垛机号 | 
 |  |  |         int nearRow = 0;    //最浅库位排 | 
 |  |  |         int curRow = 0;     //最深库位排 | 
 |  |  |         int rowCount = 0;   //轮询轮次 | 
 |  |  |         Loc loc = null;     // 目标库位 | 
 |  |  |  | 
 |  |  |         InTaskMsgDto inTaskMsgDto = new InTaskMsgDto(); | 
 |  |  |  | 
 |  |  |         int sRow = deviceBind.getStartRow(); | 
 |  |  |         int eRow = deviceBind.getEndRow(); | 
 |  |  |         int deviceQty = deviceBind.getDeviceQty(); | 
 |  |  |  | 
 |  |  |         // ===============>>>> 开始执行 | 
 |  |  |         curRow = deviceBind.getCurrentRow(); | 
 |  |  |  | 
 |  |  |         //此程序用于优化堆垛机异常时的运行时间 | 
 |  |  |         for (int i = times; i <= deviceQty * 2; i++) { | 
 |  |  |             int[] locNecessaryParameters = LocUtils.LocNecessaryParameters(deviceBind, curRow, deviceQty); | 
 |  |  |             curRow = locNecessaryParameters[1]; | 
 |  |  |             channel = locNecessaryParameters[2]; | 
 |  |  |             rowCount = locNecessaryParameters[0]; | 
 |  |  |             nearRow = locNecessaryParameters[3]; | 
 |  |  |             break; | 
 |  |  |         } | 
 |  |  |         if (nearRow == 0) { | 
 |  |  |             throw new CoolException("无可用堆垛机"); | 
 |  |  |         } | 
 |  |  |         //入库靠近摆放 | 
 |  |  |         if (ioType == 1 && deviceBind.getBeSimilar().equals("1") && !Cools.isEmpty(matnr)) { | 
 |  |  |             if (nearRow != curRow) { | 
 |  |  |                 List<LocItem> locItems = locItemService.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getMatnrCode, matnr)); | 
 |  |  |                 for (LocItem locItem : locItems) { | 
 |  |  |                     Loc loc1 = locService.getById(locItem.getLocId()); | 
 |  |  |                     if (LocUtils.isShallowLoc(loc1.getCode())) { | 
 |  |  |                         continue; | 
 |  |  |                     } | 
 |  |  |                     String shallowLocNo = LocUtils.getShallowLoc(loc1.getCode()); | 
 |  |  |                     // 检测目标库位是否为空库位 | 
 |  |  |                     Loc shallowLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, shallowLocNo)); | 
 |  |  |                     if (shallowLoc != null && shallowLoc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_O.type)) { | 
 |  |  |                         if (LocUtils.locMoveCheckLocTypeComplete(shallowLoc, locTypeDto)) { | 
 |  |  |                             loc = shallowLoc; | 
 |  |  |                             channel = shallowLoc.getChannel(); | 
 |  |  |                             break; | 
 |  |  |                         } | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  | //        // 靠近摆放规则 --- 空托 //互通版 | 
 |  |  | //        if (ioType == 10 && deviceBind.getEmptySimilar().equals("1")) { | 
 |  |  | //            List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>() | 
 |  |  | //                    .eq("loc_sts", "D").ge("row1", sRow).le("row1", eRow).eq("whs_type", rowLastnoType.getType().longValue())); | 
 |  |  | //            if (!locMasts.isEmpty()) { | 
 |  |  | //                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 (VersionUtils.locMoveCheckLocTypeComplete(shallowLoc, locTypeDto)) { | 
 |  |  | //                            if (basCrnpService.checkSiteError(shallowLoc.getCrnNo(), true)) { | 
 |  |  | //                                locMast = shallowLoc; | 
 |  |  | //                                crnNo = locMast.getCrnNo(); | 
 |  |  | //                                break; | 
 |  |  | //                            } | 
 |  |  | //                        } | 
 |  |  | //                    } | 
 |  |  | //                } | 
 |  |  | //            } | 
 |  |  | //        } | 
 |  |  |         //查找路径 | 
 |  |  |         DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() | 
 |  |  |                 .eq(DeviceSite::getType, ioType) | 
 |  |  |                 .eq(DeviceSite::getSite, sourceStaNo) | 
 |  |  |                 .eq(DeviceSite::getChannel, channel) | 
 |  |  |         ); | 
 |  |  |         if (Cools.isEmpty(deviceSite)) { | 
 |  |  |             channel = 0; | 
 |  |  |         } else { | 
 |  |  |             inTaskMsgDto.setStaNo(deviceSite.getDeviceSite()); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         //更新当前排 | 
 |  |  |         deviceBind.setCurrentRow(curRow); | 
 |  |  |         deviceBindService.updateById(deviceBind); | 
 |  |  |  | 
 |  |  |         // 开始查找库位 ==============================>> | 
 |  |  |  | 
 |  |  |         // 1.按规则查找库位 | 
 |  |  |         if (Cools.isEmpty(loc) && channel != 0) { | 
 |  |  |             List<Loc> locMasts = null; | 
 |  |  |             locMasts = locService.list(new LambdaQueryWrapper<Loc>() | 
 |  |  |                     .eq(Loc::getRow, nearRow) | 
 |  |  |                     .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type) | 
 |  |  |                     .eq(Loc::getType, locTypeDto.getLocType1()) | 
 |  |  |                     .eq(Loc::getAreaId, area) | 
 |  |  |                     .orderByAsc(Loc::getLev) | 
 |  |  |                     .orderByAsc(Loc::getCol) | 
 |  |  |             ); | 
 |  |  |             for (Loc locMast1 : locMasts) { | 
 |  |  |                 if (!LocUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) { | 
 |  |  |                     continue; | 
 |  |  |                 } | 
 |  |  |                 String shallowLoc = LocUtils.getDeepLoc(locMast1.getCode()); | 
 |  |  |                 if ((ioType == TaskStsType.GENERATE_IN.id && deviceBind.getBeSimilar().equals("1"))) { | 
 |  |  |                     //相似物料打开,判断深库位有没有货,没货就放深库位,有货就不操作 | 
 |  |  |                     Loc locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>() | 
 |  |  |                             .eq(Loc::getCode, shallowLoc) | 
 |  |  |                             .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type) | 
 |  |  |                             .eq(Loc::getAreaId, area) | 
 |  |  |                     ); | 
 |  |  |                     if (!Cools.isEmpty(locMast2)) { | 
 |  |  |                         loc = locMast2; | 
 |  |  |                         break; | 
 |  |  |                     } | 
 |  |  |                 } else { | 
 |  |  |                     //相似物料关闭,判断深库位有没有货,有货就放浅库位,无货就不操作 | 
 |  |  |                     Loc locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>() | 
 |  |  |                             .eq(Loc::getCode, shallowLoc) | 
 |  |  |                             .in(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_D.type, LocStsType.LOC_STS_TYPE_F.type) | 
 |  |  |                             .eq(Loc::getAreaId, area) | 
 |  |  |                     ); | 
 |  |  |                     if (!Cools.isEmpty(locMast2)) { | 
 |  |  |                         loc = locMast1; | 
 |  |  |                         break; | 
 |  |  |                     } else { | 
 |  |  |                         locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>() | 
 |  |  |                                 .eq(Loc::getCode, shallowLoc) | 
 |  |  |                                 .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type) | 
 |  |  |                                 .eq(Loc::getAreaId, area) | 
 |  |  |                         ); | 
 |  |  |                         if (!Cools.isEmpty(locMast2)) { | 
 |  |  |                             loc = locMast2; | 
 |  |  |                             break; | 
 |  |  |                         } | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             if (Cools.isEmpty(loc) && deviceBind.getBeSimilar().equals("1")) { | 
 |  |  |                 for (Loc locMast1 : locMasts) { | 
 |  |  |                     if (!LocUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) { | 
 |  |  |                         continue; | 
 |  |  |                     } | 
 |  |  |                     if (deviceBind.getBeSimilar().equals("1")) { | 
 |  |  |                         String shallowLoc = LocUtils.getDeepLoc(locMast1.getCode()); | 
 |  |  |                         Loc locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>() | 
 |  |  |                                 .eq(Loc::getCode, shallowLoc) | 
 |  |  |                                 .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type) | 
 |  |  |                                 .eq(Loc::getAreaId, area) | 
 |  |  |                         ); | 
 |  |  |                         if (!Cools.isEmpty(locMast2)) { | 
 |  |  |                             loc = locMast2; | 
 |  |  |                             break; | 
 |  |  |                         } else { | 
 |  |  |                             locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>() | 
 |  |  |                                     .eq(Loc::getCode, shallowLoc) | 
 |  |  |                                     .in(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_D.type, LocStsType.LOC_STS_TYPE_D.type) | 
 |  |  |                                     .eq(Loc::getAreaId, area) | 
 |  |  |                             ); | 
 |  |  |                             if (!Cools.isEmpty(locMast2)) { | 
 |  |  |                                 loc = locMast1; | 
 |  |  |                                 break; | 
 |  |  |                             } | 
 |  |  |                         } | 
 |  |  |                     } else { | 
 |  |  |                         if (!Cools.isEmpty(locMast1)) { | 
 |  |  |                             loc = locMast1; | 
 |  |  |                             break; | 
 |  |  |                         } | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |         //查询当前库位类型空库位 小于5个则locmast = null | 
 |  |  |         List<Loc> locTypeLocMasts = locService.list(new LambdaQueryWrapper<Loc>() | 
 |  |  |                 .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type) | 
 |  |  |                 .eq(Loc::getChannel, channel) | 
 |  |  |                 .eq(Loc::getType, locTypeDto.getLocType1()) | 
 |  |  |                 .eq(Loc::getAreaId, area) | 
 |  |  |         ); | 
 |  |  |         if (null != locTypeLocMasts && locTypeLocMasts.size() <= 5) { | 
 |  |  |             loc = null; | 
 |  |  |         } | 
 |  |  |         // 递归查询 | 
 |  |  |         if (Cools.isEmpty(loc) || !loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_O.type)) { | 
 |  |  |             // 当前巷道无空库位时,递归调整至下一巷道,检索全部巷道无果后,跳出递归 | 
 |  |  |             if (times < rowCount * 2) { | 
 |  |  |                 times = times + 1; | 
 |  |  |                 return getLocNoCrn(deviceBind, area, sourceStaNo, matnr, batch, locTypeDto, times, ioType); | 
 |  |  |  | 
 |  |  |             } | 
 |  |  |             // 2.库位当前所属尺寸无空库位时,调整尺寸参数,向上兼容检索库位 | 
 |  |  |             if (locTypeDto.getLocType1() < 3) { | 
 |  |  |                 int i = locTypeDto.getLocType1() + 1; | 
 |  |  |                 locTypeDto.setLocType1(i); | 
 |  |  |                 return getLocNoCrn(deviceBind, area, sourceStaNo, matnr, batch, locTypeDto, 0, ioType); | 
 |  |  |             } | 
 |  |  |             throw new CoolException("没有空库位"); | 
 |  |  |         } | 
 |  |  |         String locNo = loc.getCode(); | 
 |  |  |  | 
 |  |  |         // 返回dto | 
 |  |  |         inTaskMsgDto.setDeviceNo(channel); | 
 |  |  |         inTaskMsgDto.setSourceStaNo(sourceStaNo); | 
 |  |  | //        inTaskMsgDto.setStaNo(); | 
 |  |  |         inTaskMsgDto.setLocNo(locNo); | 
 |  |  |         return inTaskMsgDto; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  | } |