Commit 2e89c33b sunke

启动时加载最近12个小时未完成的任务

取消料架时,如果最后一个料架已无空位,查找上一个有空位的料架
发料任务结束时,保存上一个需求单使用的料架,用于判断是否是新的料架
包装仓AGV任务被取消时,导致锁定库位无法清理的问题
一个机器人工作时,无法放入大料架12或小料架70,71,72位置的问题
出库优先,入库查找没有出库任务的料仓,如果无空闲料仓,进行等待
1 个父辈 503d4410
...@@ -355,8 +355,8 @@ IP: 10.85.160.181 ...@@ -355,8 +355,8 @@ IP: 10.85.160.181
>>` {"code":0,"msg":"ok","data":""}` >>` {"code":0,"msg":"ok","data":""}`
>> >>
>> - code: 0为正常,其他为异常, >> - code: 0为正常,其他为异常,
>> - msg:消息, >> - msg:消息,
>> - data: >> - data:
...@@ -46,7 +46,7 @@ public class InquiryShelfBean { ...@@ -46,7 +46,7 @@ public class InquiryShelfBean {
if(hSerial != null){ if(hSerial != null){
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial); Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
if(shelfMap != null){ if(shelfMap != null){
log.info("清理["+hSerial+"]使用的过料架"); log.info("清理["+hSerial+"]使用过的料架");
hSerialShelfMap.remove(hSerial); hSerialShelfMap.remove(hSerial);
QisdaCache.saveShelfMap(hSerialShelfMap); QisdaCache.saveShelfMap(hSerialShelfMap);
} }
...@@ -619,7 +619,7 @@ public class InquiryShelfBean { ...@@ -619,7 +619,7 @@ public class InquiryShelfBean {
//包装料还需要取消C料架 //包装料还需要取消C料架
targetShelfType = StorageConstants.SHEFL_TYPE.C; targetShelfType = StorageConstants.SHEFL_TYPE.C;
} }
if(shelfInfo.getShelfType().equals(targetShelfType)){ if(shelfInfo.getShelfType().equals(targetShelfType) && !shelfInfo.isFull()){
if(maxShelf == null || shelfInfo.getRfidIndex() > maxShelf.getRfidIndex()){ if(maxShelf == null || shelfInfo.getRfidIndex() > maxShelf.getRfidIndex()){
maxShelf = shelfInfo; maxShelf = shelfInfo;
} }
......
...@@ -348,6 +348,16 @@ public class ShelfInfo { ...@@ -348,6 +348,16 @@ public class ShelfInfo {
} }
} }
} }
if(shelfLoc == null && StorageConstants.SHEFL_TYPE.isCShelf(shelfType)){
//如果执行到这里还有空,说明另一个机器人停掉了只能分配了
for(int i=usedCount; i> 0; i--){
shelfLoc = lockLocation(i,barcode,reelType);
if(shelfLoc != null){
return shelfLoc;
}
}
}
return shelfLoc; return shelfLoc;
}else if(robotIndex.equals("2")){ }else if(robotIndex.equals("2")){
...@@ -372,6 +382,16 @@ public class ShelfInfo { ...@@ -372,6 +382,16 @@ public class ShelfInfo {
} }
} }
} }
if(shelfLoc == null && StorageConstants.SHEFL_TYPE.isDShelf(shelfType)){
//如果执行到这里还有空,说明另一个机器人停掉了只能分配了
for(int i=usedCount; i> 0; i--){
shelfLoc = lockLocation(i,barcode,reelType);
if(shelfLoc != null){
return shelfLoc;
}
}
}
return shelfLoc; return shelfLoc;
}else { }else {
......
...@@ -115,9 +115,9 @@ public class DataLogDaoImpl extends AbstractMongoDao implements IDataLogDao { ...@@ -115,9 +115,9 @@ public class DataLogDaoImpl extends AbstractMongoDao implements IDataLogDao {
//Criteria c = Criteria.where("appendInfo.hSerial").is(executingHSerial).and("lessSendReel").is(false).and("status").nin(StorageConstants.OP_STATUS.FINISHED.name(),StorageConstants.OP_STATUS.CANCEL.name()); //Criteria c = Criteria.where("appendInfo.hSerial").is(executingHSerial).and("lessSendReel").is(false).and("status").nin(StorageConstants.OP_STATUS.FINISHED.name(),StorageConstants.OP_STATUS.CANCEL.name());
Criteria c = Criteria.where("status").nin(StorageConstants.OP_STATUS.FINISHED.name(),StorageConstants.OP_STATUS.CANCEL.name()).and("stopSendToQisda").is(false); Criteria c = Criteria.where("status").nin(StorageConstants.OP_STATUS.FINISHED.name(),StorageConstants.OP_STATUS.CANCEL.name()).and("stopSendToQisda").is(false);
//只查找近5个小时未完成的任务 //只查找近12个小时未完成的任务
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.HOUR_OF_DAY,-5); calendar.add(Calendar.HOUR_OF_DAY,-12);
c.and("createDate").gte(calendar.getTime()); c.and("createDate").gte(calendar.getTime());
Query query = Query.query(c); Query query = Query.query(c);
List<DataLog> unFinishedTasks = findByQuery(query); List<DataLog> unFinishedTasks = findByQuery(query);
......
...@@ -9,7 +9,7 @@ public interface IOutItemDao extends IMongoDao { ...@@ -9,7 +9,7 @@ public interface IOutItemDao extends IMongoDao {
List<OutItem> findByHSerial(String hSerial); List<OutItem> findByHSerial(String hSerial);
List<OutItem> findCutItemList(List<String> cutHserialList, String pn, String facility); List<OutItem> findCutItemList(List<String> soseqList, String pn, String facility);
OutItem findItem(String hSerial, int slotSeq); OutItem findItem(String hSerial, int slotSeq);
......
...@@ -332,8 +332,9 @@ public class OutInfoCache { ...@@ -332,8 +332,9 @@ public class OutInfoCache {
* 任务开始时,初始化出库任务数 * 任务开始时,初始化出库任务数
* @param hSerial * @param hSerial
* @param outReelNum * @param outReelNum
* @param lessSend 是否是缺料补发
*/ */
public void resetTaskNum(String hSerial, int outReelNum){ public void resetTaskNum(String hSerial, int outReelNum, boolean lessSend){
OutInfo outInfo = getOutInfoFromCache(hSerial); OutInfo outInfo = getOutInfoFromCache(hSerial);
if(outInfo != null){ if(outInfo != null){
outInfo.setOutReelNum(0); outInfo.setOutReelNum(0);
...@@ -440,12 +441,6 @@ public class OutInfoCache { ...@@ -440,12 +441,6 @@ public class OutInfoCache {
outInfoMap.put(hSerial, outInfo); outInfoMap.put(hSerial, outInfo);
outInfoDao.updateTaskFinishNum(hSerial,taskFinishNum); outInfoDao.updateTaskFinishNum(hSerial,taskFinishNum);
updateSendStatus(outInfo.gethSerial()); updateSendStatus(outInfo.gethSerial());
if(outInfo.isTaskEnd()){
//本次任务已结束,清理料架
InquiryShelfBean.clearShelf(outInfo.gethSerial());
}
return outInfo; return outInfo;
...@@ -476,7 +471,6 @@ public class OutInfoCache { ...@@ -476,7 +471,6 @@ public class OutInfoCache {
} }
if(outInfo.isTaskEnd()){ if(outInfo.isTaskEnd()){
outInfo.setTaskEndTime(System.currentTimeMillis());
if(sendEnd){ if(sendEnd){
outInfo.setSendStatus(StorageConstants.SEND_STATUS.SEND_OK); outInfo.setSendStatus(StorageConstants.SEND_STATUS.SEND_OK);
}else{ }else{
...@@ -484,6 +478,21 @@ public class OutInfoCache { ...@@ -484,6 +478,21 @@ public class OutInfoCache {
outInfo.setSendStatus(StorageConstants.SEND_STATUS.SEND_LESS); outInfo.setSendStatus(StorageConstants.SEND_STATUS.SEND_LESS);
} }
//本次任务已结束,清理料架(首盘和补料使用的C和D料架不清理)
long lastTaskEndTime = outInfo.getTaskEndTime();
if(lastTaskEndTime <= 0){
//outInfo是第一次执行的首盘或补料需求单,更新上次需求单使用过的料架
if(outInfo.isFirstReelAction() || outInfo.isTailAction()){
List<String> usedRfidList = InquiryShelfBean.getUsedRfidList(outInfo.gethSerial());
QisdaCache.updateUsedRfid(usedRfidList);
log.info("更新需求单["+outInfo.gethSerial()+"]使用过的料架:" + String.join("," + usedRfidList));
}
}
InquiryShelfBean.clearShelf(outInfo.gethSerial());
outInfo.setTaskEndTime(System.currentTimeMillis());
outInfoDao.updateTaskEndTime(outInfo.gethSerial(), outInfo.getTaskEndTime()); outInfoDao.updateTaskEndTime(outInfo.gethSerial(), outInfo.getTaskEndTime());
outInfoDao.updateStatus(outInfo.gethSerial(), -1 , outInfo.getSendStatus()); outInfoDao.updateStatus(outInfo.gethSerial(), -1 , outInfo.getSendStatus());
} }
...@@ -689,7 +698,7 @@ public class OutInfoCache { ...@@ -689,7 +698,7 @@ public class OutInfoCache {
if(outReelNum > 0){ if(outReelNum > 0){
log.info("需求单"+outInfo.gethSerial()+"已出("+outInfo.getOutReelNum()+")/已发("+outInfo.getTaskFinishNum()+") 本次出库料盘数量:" + outReelNum); log.info("需求单"+outInfo.gethSerial()+"已出("+outInfo.getOutReelNum()+")/已发("+outInfo.getTaskFinishNum()+") 本次出库料盘数量:" + outReelNum);
resetTaskNum(hSerial, outReelNum); resetTaskNum(hSerial, outReelNum,outInfoExecuted);
//补料出库,且不是缺料重发,需要重新排序,按站位序号循环出,每次出最大的盘 //补料出库,且不是缺料重发,需要重新排序,按站位序号循环出,每次出最大的盘
if(outInfo.isTailAction() && !outInfoExecuted){ if(outInfo.isTailAction() && !outInfoExecuted){
...@@ -713,7 +722,7 @@ public class OutInfoCache { ...@@ -713,7 +722,7 @@ public class OutInfoCache {
} }
if(outInfo.isReelCutAction() || outInfo.isFirstReelAction()){ if(outInfo.isReelCutAction() || outInfo.isFirstReelAction()){
if(outReelNum == 0){ if(!outInfoExecuted && outReelNum == 0){
List<OutItem> outItemList = outItemDao.findByHSerial(outInfo.gethSerial()); List<OutItem> outItemList = outItemDao.findByHSerial(outInfo.gethSerial());
boolean lessBind = false; boolean lessBind = false;
QisdaApi.VMILocationOutFeedback(outItemList, lessBind); QisdaApi.VMILocationOutFeedback(outItemList, lessBind);
......
...@@ -235,15 +235,6 @@ public class QisdaBindService { ...@@ -235,15 +235,6 @@ public class QisdaBindService {
log.info("\t分盘料["+barcode.getBarcode()+"]绑定到So=["+outItem.getSo()+"]hSerial=["+outItem.getSourceName()+"]数量:" + lockQty +"/" + outItem.getQty()); log.info("\t分盘料["+barcode.getBarcode()+"]绑定到So=["+outItem.getSo()+"]hSerial=["+outItem.getSourceName()+"]数量:" + lockQty +"/" + outItem.getQty());
if(!barcode.hasCutInfo()){ if(!barcode.hasCutInfo()){
//没有分盘信息,可以直接绑定 //没有分盘信息,可以直接绑定
// AppendInfo appendInfo = barcode.getAppendInfo();
// appendInfo.sethSerial(outItem.gethSerial());
// appendInfo.setRefno(outItem.getRefno());
// appendInfo.setSo(outItem.getSo());
// appendInfo.setSoseq(outItem.getSoseq());
// appendInfo.setSlotStr(outItem.getSlotStr());
// appendInfo.setBindSlot(outItem.getSlotlocation() + "");
// appendInfo.setSlotIndex(outItem.getSlotlocation());
// barcode.setAppendInfo(appendInfo);
barcode.realBindItem(outItem); barcode.realBindItem(outItem);
int realLockQty = outItem.getRealLockQty() + barcode.getAmount(); int realLockQty = outItem.getRealLockQty() + barcode.getAmount();
outItem.setRealLockQty(realLockQty); outItem.setRealLockQty(realLockQty);
...@@ -442,7 +433,7 @@ public class QisdaBindService { ...@@ -442,7 +433,7 @@ public class QisdaBindService {
List<String> lessSoseqList = new ArrayList<>(); List<String> lessSoseqList = new ArrayList<>();
List<OutInfo> cacheOutInfoList = outInfoCache.getCachedOutInfos(); List<OutInfo> cacheOutInfoList = outInfoCache.getCachedOutInfos();
for (OutInfo unEndOutInfo : cacheOutInfoList) { for (OutInfo unEndOutInfo : cacheOutInfoList) {
if(!unEndOutInfo.isClosed() && unEndOutInfo.isSendLess()){ if(!unEndOutInfo.isClosed() && unEndOutInfo.isRealBindLess()){
String soseq = unEndOutInfo.getSoseq(); String soseq = unEndOutInfo.getSoseq();
if(!lessSoseqList.contains(soseq)){ if(!lessSoseqList.contains(soseq)){
lessSoseqList.add(soseq); lessSoseqList.add(soseq);
...@@ -460,7 +451,7 @@ public class QisdaBindService { ...@@ -460,7 +451,7 @@ public class QisdaBindService {
for (OutItem outItem : cutItemList) { for (OutItem outItem : cutItemList) {
if(!outItem.isBindOk()){ if(!outItem.isBindOk()){
OutInfo outInfo = soseqCache.getCutActionInfoFromCache(outItem.gethSerial()); OutInfo outInfo = soseqCache.getCutActionInfoFromCache(outItem.getSoseq());
if(outInfo != null){ if(outInfo != null){
//真实绑定缺料 //真实绑定缺料
if(outItem.realBindLessQty() > 0){ if(outItem.realBindLessQty() > 0){
......
...@@ -115,6 +115,30 @@ public class QisdaCache { ...@@ -115,6 +115,30 @@ public class QisdaCache {
} }
/** /**
* 根据料架和料架位置获取锁定的库位信息,如果不存在,返回null
* @param rfid
* @param rfidLoc
* @return
*/
public static ReelLockPosInfo getLockPosInfoByRfidLoc(String rfid, String rfidLoc){
if(Strings.isNotBlank(rfid) && Strings.isNotBlank(rfidLoc)){
for (ReelLockPosInfo reelLockPosInfo : reelLocKPosMap.values()) {
String lockRfid = reelLockPosInfo.getRfid();
String lockRfidLoc = reelLockPosInfo.getRfidLoc();
if(Strings.isNotBlank(lockRfid) && Strings.isNotBlank(lockRfidLoc)){
if(rfid.equals(lockRfid) && rfidLoc.equals(rfidLoc)){
return reelLockPosInfo;
}
}
}
}
return null;
}
/**
* 获取料架上料盘锁定的库位信息 * 获取料架上料盘锁定的库位信息
* @param rfid * @param rfid
* @return * @return
...@@ -278,12 +302,15 @@ public class QisdaCache { ...@@ -278,12 +302,15 @@ public class QisdaCache {
} }
String oldHSerial = currentOrderHSerial; String oldHSerial = currentOrderHSerial;
log.info("设置当前正在执行的工单料需求为:" + executeHSerial+"清理之前["+oldHSerial+"]出库使用的料架"); log.info("设置当前正在执行的工单料需求为:" + executeHSerial+"清理之前["+oldHSerial+"]出库使用的料架");
lastHSerialUsedRfidList = InquiryShelfBean.getUsedRfidList(oldHSerial);
InquiryShelfBean.clearShelf(oldHSerial); InquiryShelfBean.clearShelf(oldHSerial);
currentOrderHSerial = executeHSerial; currentOrderHSerial = executeHSerial;
cacheInfoDao.updateCacheItem(CURRENT_ORDER_HSERIAL_KEY, currentOrderHSerial); cacheInfoDao.updateCacheItem(CURRENT_ORDER_HSERIAL_KEY, currentOrderHSerial);
} }
public static void updateUsedRfid(List<String> usedRfidList){
lastHSerialUsedRfidList = usedRfidList;
}
/** /**
* 是否是上个工单需求单使用过的料架 * 是否是上个工单需求单使用过的料架
*/ */
......
...@@ -954,6 +954,8 @@ public class QisdaDeviceController extends BaseController { ...@@ -954,6 +954,8 @@ public class QisdaDeviceController extends BaseController {
if(cacheTask != null){ if(cacheTask != null){
hSerial = cacheTask.getAppendInfo().gethSerial(); hSerial = cacheTask.getAppendInfo().gethSerial();
} }
List<String> usedRfidList = InquiryShelfBean.getUsedRfidList(hSerial);
ShelfInfo shelfInfo = InquiryShelfBean.findSameShelf(hSerial,rfid); ShelfInfo shelfInfo = InquiryShelfBean.findSameShelf(hSerial,rfid);
if(shelfInfo != null){ if(shelfInfo != null){
Map<Integer, ShelfLoc> locMap = shelfInfo.getLocMap(); Map<Integer, ShelfLoc> locMap = shelfInfo.getLocMap();
...@@ -981,10 +983,17 @@ public class QisdaDeviceController extends BaseController { ...@@ -981,10 +983,17 @@ public class QisdaDeviceController extends BaseController {
smallEmpty = 100; smallEmpty = 100;
bigEmpty = 100; bigEmpty = 100;
packageEmpty = 100; packageEmpty = 100;
}else{
//为了料架能重用,如果当前执行的需求单料已经放上料架,则清空上一个需求单使用过的料架
if(!usedRfidList.isEmpty()){
log.info("料架["+rfid+"]上一个需求单已使用,当前需求单["+hSerial+"]物料已放上料架,清理上一个需求单使用过的料架");
QisdaCache.updateUsedRfid(null);
}
} }
} }
List<String> usedRfidList = InquiryShelfBean.getUsedRfidList(hSerial);
//剩余的任务数 //剩余的任务数
Map<String,Object> resultMap = new HashMap<>(); Map<String,Object> resultMap = new HashMap<>();
......
...@@ -583,54 +583,53 @@ public class StorageDataController extends BaseController { ...@@ -583,54 +583,53 @@ public class StorageDataController extends BaseController {
try { try {
Barcode barcode = dataCache.resolveOneValideBarcode(code); Barcode barcode = dataCache.resolveOneValideBarcode(code);
String lockPosId = QisdaCache.getReelLockPosId(barcode.getBarcode());
StoragePos pos = null; StoragePos pos = taskService.findEmptyPosForPutIn(storageList,barcode, rfid);
if(!Strings.isNullOrEmpty(lockPosId)){
//已有锁定库位 if(pos != null){
pos = storagePosManager.get(lockPosId);
Storage storage = dataCache.getStorageById(pos.getStorageId());
if(pos != null ){ if(!storage.isPackage()){
if(pos.getW() < barcode.getPlateSize() || pos.getH() < barcode.getHeight()){ //不是包装仓,如果所在料仓有出库任务,暂停入库
log.info("条码["+barcode.getBarcode()+"]尺寸已改变,无法放入已锁定库位["+pos.getPosName()+"],重新查找库位"); Collection<DataLog> tasks = taskService.getQueueTasks();
pos = null; for (DataLog task : tasks) {
}else{ if(task.isCheckOutTask() && task.getStorageId().equals(pos.getStorageId())){
Barcode posBarcode = pos.getBarcode(); errorMsg = "库位["+ pos.getPosName() + "]所在料仓有出库任务,暂停入库";
if(posBarcode == null){ lineMsg = errorMsg;
log.info("条码["+barcode.getBarcode()+"]已锁定库位["+pos.getPosName()+"],返回锁定中的库位"); resultMap.put("result","99");
}else{ resultMap.put("msg",errorMsg);
log.info("条码["+barcode.getBarcode()+"]已锁定库位["+pos.getPosName()+"]中已有物料["+posBarcode.getBarcode()+"],重新查找库位"); return resultMap;
pos = null;
} }
} }
} }
}
if(pos == null){
pos = taskService.findEmptyPosForPutIn(storageList,barcode, rfid);
}
if(pos != null){
String result = "0"; Storage theStorage = dataCache.getStorageById(pos.getStorageId());
resultMap.put("result","0");
resultMap.put("msg","");
//如果料仓有正在执行或者等待执行的任务,客户端先进行等待 okMsg = "["+rfid+"]["+barcode.getBarcode()+"]锁定库位["+pos.getPosName()+"]";
Collection<DataLog> tasks = taskService.getQueueTasks();
for (DataLog task : tasks) { ReelLockPosInfo oldLockInfo = QisdaCache.getLockPosInfoByRfidLoc(rfid, rfidLoc);
if(task.isCheckOutTask() && task.getStorageId().equals(pos.getStorageId())){ if(oldLockInfo != null){
lineMsg = "库位["+ pos.getPosName() + "]所在料仓有出库任务,暂停入库"; if(!oldLockInfo.getBarcode().equals(barcode.getBarcode())){
result = "99"; String result = "-1";
break; okMsg = "["+rfid+"]["+barcode.getBarcode()+"]锁定库位["+pos.getPosName()+"],清理旧有锁定库位";
resultMap.put("result",result);
resultMap.put("msg",okMsg);
//已经锁定过库位,但不是同一个条码,需要把对应位置的锁定信息清理掉
List<ReelLockPosInfo> lockPosInfoList = QisdaCache.getShelfLockPosInfo(rfid);
for (ReelLockPosInfo reelLockPosInfo : lockPosInfoList) {
QisdaCache.removeReelLockPosInfo(reelLockPosInfo.getBarcode());
log.info("清理料架"+reelLockPosInfo.getRfid()+"["+reelLockPosInfo.getRfidLoc()+"]上物料["+reelLockPosInfo.getBarcode()+"]锁定的库位");
}
} }
} }
resultMap.put("result",result);
resultMap.put("msg","");
resultMap.put("pos",pos.getPosName());
resultMap.put("barcode",barcode.getBarcode());
Storage theStorage = dataCache.getStorageById(pos.getStorageId());
resultMap.put("cid",theStorage.getCid());
okMsg = "["+rfid+"]["+barcode.getBarcode()+"]锁定库位["+pos.getPosName()+"]";
log.info(okMsg); log.info(okMsg);
ReelLockPosInfo reelLocInfo = new ReelLockPosInfo(); ReelLockPosInfo reelLocInfo = new ReelLockPosInfo();
reelLocInfo.setBarcode(barcode.getBarcode()); reelLocInfo.setBarcode(barcode.getBarcode());
reelLocInfo.setCid(theStorage.getCid()); reelLocInfo.setCid(theStorage.getCid());
...@@ -639,14 +638,18 @@ public class StorageDataController extends BaseController { ...@@ -639,14 +638,18 @@ public class StorageDataController extends BaseController {
reelLocInfo.setRfid(rfid); reelLocInfo.setRfid(rfid);
reelLocInfo.setRfidLoc(rfidLoc); reelLocInfo.setRfidLoc(rfidLoc);
QisdaCache.addReelLockPosInfo(reelLocInfo); QisdaCache.addReelLockPosInfo(reelLocInfo);
//taskService.addPutInTaskToExecute(theStorage, barcode, pos);
resultMap.put("pos",pos.getPosName());
resultMap.put("barcode",barcode.getBarcode());
resultMap.put("cid",theStorage.getCid());
}else{ }else{
resultMap.put("result","104"); resultMap.put("result","104");
errorMsg = "未找到可用的["+barcode.getPlateSize() + "x" + barcode.getHeight()+"]仓位"; errorMsg = "["+barcode.getBarcode()+"]未找到可用的["+barcode.getPlateSize() + "x" + barcode.getHeight()+"]仓位";
resultMap.put("msg",errorMsg); resultMap.put("msg",errorMsg);
} }
} catch (ValidateException e) { } catch (Exception e) {
errorMsg = e.getMessage(); errorMsg = e.getMessage();
log.info("查找空库位失败:" + errorMsg); log.info("查找空库位失败:" + errorMsg);
resultMap.put("result","105"); resultMap.put("result","105");
......
...@@ -470,6 +470,13 @@ public class TaskService implements ITaskService { ...@@ -470,6 +470,13 @@ public class TaskService implements ITaskService {
public StoragePos findEmptyPosForPutIn(List<Storage> storageList, Barcode barcode, String inRFID) throws ValidateException{ public StoragePos findEmptyPosForPutIn(List<Storage> storageList, Barcode barcode, String inRFID) throws ValidateException{
verifyBarcodePutIn(storageList ,barcode, inRFID); verifyBarcodePutIn(storageList ,barcode, inRFID);
//查找任务数最少的料仓
Map<String,Integer> storageTaskCountMap = new HashMap<>();
for (Storage storage : storageList) {
storageTaskCountMap.put(storage.getId(), 0);
}
Set<String> hasOutTaskStorageIds = new HashSet<>();
//如果有正在执行的任务,把库位发过去 //如果有正在执行的任务,把库位发过去
Collection<DataLog> allTasks = taskMap.values(); Collection<DataLog> allTasks = taskMap.values();
for (DataLog task : allTasks) { for (DataLog task : allTasks) {
...@@ -478,32 +485,48 @@ public class TaskService implements ITaskService { ...@@ -478,32 +485,48 @@ public class TaskService implements ITaskService {
log.info(barcode.getBarcode() + " 已有任务,返回任务中的库位:" + task.getPosName()); log.info(barcode.getBarcode() + " 已有任务,返回任务中的库位:" + task.getPosName());
return storagePosManager.get(posId); return storagePosManager.get(posId);
} }
}
//查找任务数最少的料仓
Map<String,Integer> executingTaskCountMap = new HashMap<>();
for (Storage storage : storageList) {
executingTaskCountMap.put(storage.getId(), 0);
}
Set<String> hasOutTaskStorageIds = new HashSet<>();
for (DataLog task : allTasks) {
String storageId = task.getStorageId(); String storageId = task.getStorageId();
if(!Strings.isNullOrEmpty(storageId)){ if(!Strings.isNullOrEmpty(storageId)){
Integer taskCount = executingTaskCountMap.get(storageId); Integer taskCount = storageTaskCountMap.get(storageId);
if(taskCount != null){ if(taskCount != null){
if(task.isExecuting()){ taskCount = taskCount + 1;
taskCount = taskCount + 1; storageTaskCountMap.put(storageId, taskCount);
executingTaskCountMap.put(storageId, taskCount);
}
} }
if(task.isCheckOutTask() && task.isExecuting()){ if(task.isCheckOutTask()){
hasOutTaskStorageIds.add(storageId); hasOutTaskStorageIds.add(storageId);
} }
} }
} }
String lockPosId = QisdaCache.getReelLockPosId(barcode.getBarcode());
StoragePos pos = null;
if(!Strings.isNullOrEmpty(lockPosId)){
//已有锁定库位
pos = storagePosManager.get(lockPosId);
if(pos != null ){
if(pos.getW() < barcode.getPlateSize() || pos.getH() < barcode.getHeight()){
log.info("条码["+barcode.getBarcode()+"]尺寸已改变,无法放入已锁定库位["+pos.getPosName()+"],重新查找库位");
pos = null;
}else{
Barcode posBarcode = pos.getBarcode();
if(posBarcode == null){
log.info("条码["+barcode.getBarcode()+"]已锁定库位["+pos.getPosName()+"],返回锁定中的库位");
}else{
log.info("条码["+barcode.getBarcode()+"]已锁定库位["+pos.getPosName()+"]中已有物料["+posBarcode.getBarcode()+"],重新查找库位");
pos = null;
}
}
}
}
if(pos != null){
return pos;
}
//可用的料仓(在线,且可以放入) //可用的料仓(在线,且可以放入)
List<Storage> availbleStorageList = new ArrayList<>(); List<Storage> availbleStorageList = new ArrayList<>();
...@@ -512,14 +535,14 @@ public class TaskService implements ITaskService { ...@@ -512,14 +535,14 @@ public class TaskService implements ITaskService {
if(status.timeOut()){ if(status.timeOut()){
continue; continue;
} }
if(!status.isBoxCanPutIn()){ // if(!status.isBoxCanPutIn()){
//料仓不可入库 // //料仓不可入库
continue; // continue;
} // }
if(hasOutTaskStorageIds.contains(storage.getId())){ // if(hasOutTaskStorageIds.contains(storage.getId())){
//有正在执行的出库任务 // //有出库任务
continue; // continue;
} // }
if(storage.canPutIn(barcode.getPlateSize(),barcode.getHeight())){ if(storage.canPutIn(barcode.getPlateSize(),barcode.getHeight())){
availbleStorageList.add(storage); availbleStorageList.add(storage);
...@@ -530,49 +553,30 @@ public class TaskService implements ITaskService { ...@@ -530,49 +553,30 @@ public class TaskService implements ITaskService {
throw new ValidateException("料仓列表中未找到可用的料仓"); throw new ValidateException("料仓列表中未找到可用的料仓");
} }
return findEmptyPosInStorages(barcode, availbleStorageList, executingTaskCountMap); return findEmptyPosInStorages(barcode, availbleStorageList, storageTaskCountMap);
} }
private synchronized StoragePos findEmptyPosInStorages(Barcode barcode, List<Storage> availbleStorageList, Map<String,Integer> executingTaskCountMap){ private synchronized StoragePos findEmptyPosInStorages(Barcode barcode, List<Storage> availbleStorageList, final Map<String,Integer> executingTaskCountMap){
//优先从没有出库任务的料仓中查找库位 availbleStorageList.sort(new Comparator<Storage>() {
for (Storage storage : availbleStorageList) { @Override
Integer executingTaskCount = executingTaskCountMap.get(storage.getId()); public int compare(Storage o1, Storage o2) {
if(executingTaskCount >= 1){ Integer taskCount1 = executingTaskCountMap.get(o1.getId());
continue; Integer taskCount2 = executingTaskCountMap.get(o2.getId());
} return taskCount1.compareTo(taskCount2);
try{
log.info("尝试从无出库任务的料仓["+storage.getCid()+"]中为["+barcode.getBarcode()+"]查找空位,当前料仓正在执行任务数:" + executingTaskCount);
return findLineEmptyPosForPutIn(storage,barcode);
}catch(Exception e){
log.info("尝试从["+storage.getCid()+"]中为["+barcode.getBarcode()+"]查找空位失败:" + e.getMessage());
}
}
for (Storage storage : availbleStorageList) {
Integer executingTaskCount = executingTaskCountMap.get(storage.getId());
if(executingTaskCount >= 2){
continue;
} }
});
try{ Collection<String> operatingPosIds = excludePosIds();
log.info("尝试从["+storage.getCid()+"]为["+barcode.getBarcode()+"]查找空位,当前料仓正在执行任务数:" + executingTaskCount);
return findLineEmptyPosForPutIn(storage,barcode);
}catch(Exception e){
log.info("尝试从["+storage.getCid()+"]中为["+barcode.getBarcode()+"]查找空位失败:" + e.getMessage());
}
}
//只有一个料仓可以入时,只能继续往里面放
log.info("可用料仓太少,不按任务数分配,重新查找...");
for (Storage storage : availbleStorageList) { for (Storage storage : availbleStorageList) {
try{ try{
log.info("不按任务数分配,尝试从["+storage.getCid()+"]中为["+barcode.getBarcode()+"]查找空位"); log.info("尝试从["+storage.getCid()+"]中为["+barcode.getBarcode()+"]查找空位");
return findLineEmptyPosForPutIn(storage,barcode); StoragePos pos = storagePosManager.getEmptyPosByStorage(storage, barcode , operatingPosIds);
if(pos != null){
return pos;
}
}catch(Exception e){ }catch(Exception e){
log.info("尝试从["+storage.getCid()+"]中为["+barcode.getBarcode()+"]查找空位失败:" + e.getMessage()); log.info("尝试从["+storage.getCid()+"]中为["+barcode.getBarcode()+"]查找空位失败:" + e.getMessage());
} }
} }
return null; return null;
} }
/** /**
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!