Commit 37974856 sunke

1 自动绑定逻辑:a)按soseq对需求单进行一次绑定 b)入库时对料盘进行绑定

2  自动出库逻辑: 分盘料,指定料直接出库, 首盘和补料根据建议时间和必须出库时间进行出库(出库到料架上)
3  缺料重发: 首盘和补料缺料时,自动重发到料串上
4  完成任务数比分配任务多的问题修正(机器人正在放料时又进行了扫码)
5  维护料盘厚度与实测厚度不一致时,到机器人扫码位NG的问题(修改为只有在入库时与维护料盘尺寸进行比对,出库时不比对)
6  DN单绑定信息保持(更新不影响已绑定的料串)
7  机器人料架信息保持(更新不影响正在出库的工单)
8  料串信息保持(更新不影响分盘料/指定料/缺料重发)
9  出入库任务保持(更新会记录更新前的任务,更新后继续之前的任务)
10 料盘尺寸与维护尺寸不一致时的提示信息
1 个父辈 ea58a9ac
package com.myproject.bean.update.qisda;
import com.myproject.bean.BaseMongoBean;
import com.myproject.util.StorageConstants;
import org.springframework.data.annotation.Transient;
import java.util.*;
/**
* 缓存信息
*/
public class CacheInfo extends BaseMongoBean {
private String cacheKey = "";
private Object cacheValue = "";
public String getCacheKey() {
return cacheKey;
}
public void setCacheKey(String cacheKey) {
this.cacheKey = cacheKey;
}
public Object getCacheValue() {
return cacheValue;
}
public void setCacheValue(Object cacheValue) {
this.cacheValue = cacheValue;
}
}
package com.myproject.dao.mongo.qisda;
import com.myproject.bean.update.qisda.CacheInfo;
import com.myproject.bean.update.qisda.OutInfo;
import com.myproject.dao.mongo.IMongoDao;
import java.util.List;
public interface ICacheInfoDao extends IMongoDao {
void updateCacheItem(String cacheKey, Object cacheValue);
CacheInfo getCacheInfo(String cacheKey);
}
package com.myproject.dao.mongo.qisda.impl;
import com.myproject.bean.BaseMongoBean;
import com.myproject.bean.update.qisda.CacheInfo;
import com.myproject.bean.update.qisda.OutInfo;
import com.myproject.dao.mongo.AbstractMongoDao;
import com.myproject.dao.mongo.qisda.ICacheInfoDao;
import com.myproject.dao.mongo.qisda.IOutInfoDao;
import com.myproject.util.StorageConstants;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class CacheInfoDaoImpl extends AbstractMongoDao implements ICacheInfoDao {
@Override
public void updateCacheItem(String cacheKey, Object cacheValue){
CacheInfo cacheInfo = getCacheInfo(cacheKey);
if(cacheInfo == null){
cacheInfo = new CacheInfo();
cacheInfo.setCacheKey(cacheKey);
}
cacheInfo.setCacheValue(cacheValue);
save(cacheInfo);
// Update update = Update.update("cacheValue",cacheValue);
// Criteria c = Criteria.where("cacheKey").is(cacheKey);
// Query query = Query.query(c);
// upsert(query,update);
}
@Override
public CacheInfo getCacheInfo(String cacheKey){
return findOneByCondition(new String[]{"cacheKey"}, new String[]{cacheKey});
}
@Override
public Class getEntityClass() {
return CacheInfo.class;
}
}
package com.myproject.webapp.controller.qisda.util;
import com.google.common.collect.Lists;
import com.myproject.bean.qisda.AppendInfo;
import com.myproject.bean.qisda.InquiryShelfBean;
import com.myproject.bean.update.Barcode;
import com.myproject.bean.update.StoragePos;
import com.myproject.bean.update.qisda.OutInfo;
import com.myproject.bean.update.qisda.OutItem;
import com.myproject.dao.mongo.IStoragePosDao;
import com.myproject.dao.mongo.qisda.IOutInfoDao;
import com.myproject.dao.mongo.qisda.IOutItemDao;
import com.myproject.util.DateUtil;
import com.myproject.util.QisdaApi;
import com.myproject.util.StorageConstants;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by sunke on 2020/3/5.
*/
@Service
public class SoseqCache {
protected final transient Logger log = LogManager.getLogger(getClass());
/**
* key为工单序号,Value为分盘需求单(存放整个工单序号的绑定和发料信息)
*/
private static Map<String,OutInfo> soSeqCacheMap = new ConcurrentHashMap<>();
@Autowired
private IOutInfoDao outInfoDao;
@Autowired
private IOutItemDao outItemDao;
public OutItem getCutOutItem(String soseq, int slotSeq){
OutInfo outInfo = getCutActionInfoFromCache(soseq);
if(outInfo != null){
OutItem cutOutItem = outInfo.findOutItem(slotSeq);
if(cutOutItem == null){
cutOutItem = outItemDao.findItem(outInfo.gethSerial(), slotSeq);
log.warn("未找到outItem,从数据库中加载soseq=" + soseq + " slotSeq=" + slotSeq);
}
return cutOutItem;
}
return null;
}
public void checkRealBindStatus(String soseq){
OutInfo outInfo = getCutActionInfoFromCache(soseq);
if(outInfo != null){
boolean hasBindItem = false;
boolean allItemsBindOk = true;
for (OutItem outItem : outInfo.getOutItems()) {
if(outItem.getRealLockQty() > 0 && !outItem.isCutMaterial()){
hasBindItem = true;
}
if(outItem.realBindLessQty() > 0){
//还未绑定完成
allItemsBindOk = false;
}
}
if(hasBindItem){
//已经执行过真实绑定
int bindStatus = StorageConstants.BIND_STATUS.REAL_BIND_LESS;
if(allItemsBindOk){
//所有的Item都绑定OK
bindStatus = StorageConstants.BIND_STATUS.REAL_BIND_OK;
log.info("工单soseq=["+outInfo.getSoseq()+"]真实绑定OK");
}
outInfoDao.updateStatus(outInfo.gethSerial(),bindStatus, -1);
outInfo.setBindStatus(bindStatus);
soSeqCacheMap.put(outInfo.getSoseq(), outInfo);
}
}
}
public void addToTotalSendQty(OutItem outItem, int sendQty){
OutInfo outInfo = getCutActionInfoFromCache(outItem.getSoseq());
if(outInfo != null){
OutItem cutOutItem = getCutOutItem(outItem.getSoseq(), outItem.getSlotlocation());
if(cutOutItem != null){
if(cutOutItem != null){
int totalSendQty = cutOutItem.getSendQty();
totalSendQty = totalSendQty + sendQty;
int outQty = 0;
if(outItem.isFirstReelAction()){
//首盘
outQty = sendQty;
}
cutOutItem.setOutQty(sendQty);
cutOutItem.setSendQty(totalSendQty);
outItemDao.updateQty(cutOutItem.getId(), outQty, totalSendQty);
outInfo.updateItem(cutOutItem);
soSeqCacheMap.put(outInfo.getSoseq(), outInfo);
}else{
log.error("更新总发料数量时,未找到分盘的 soseq="+outItem.getSoseq() +" slotSeq=" + outItem.getSlotlocation());
}
}
}
}
/**
* 更新总的预绑定数量
*/
public void udpateTotalPreLockQty(OutItem outItem, int totalPreLockQty){
updateTotalLockQty(outItem, totalPreLockQty, -1);
}
/**
* 更新总的真实绑定的数量
*/
public void updateTotalRealLockQty(OutItem outItem, int totalRealLockQty){
updateTotalLockQty(outItem, -1, totalRealLockQty);
}
private void updateTotalLockQty(OutItem outItem, int totalPreLockQty, int totalRealLockQty){
OutInfo outInfo = getCutActionInfoFromCache(outItem.getSoseq());
if(outInfo != null){
OutItem cutOutItem = outInfo.findOutItem(outItem.getSlotlocation());
if(cutOutItem == null){
cutOutItem = outItemDao.findItem(outInfo.gethSerial(), outItem.getSlotlocation());
log.warn("未找到outItem,从数据库中加载soseq=" + outItem.getSoseq() + " slotSeq=" + outItem.getSlotlocation());
}
if(cutOutItem != null){
if(cutOutItem != null){
if(totalPreLockQty > 0){
cutOutItem.setLockQty(totalPreLockQty);
}
if(totalRealLockQty > 0){
cutOutItem.setRealLockQty(totalRealLockQty);
}
outItemDao.updateLockQty(cutOutItem.getId(), totalPreLockQty, totalRealLockQty);
outInfo.updateItem(cutOutItem);
soSeqCacheMap.put(outInfo.getSoseq(), outInfo);
}else{
log.error("更新总绑定数量时,未找到分盘的 soseq="+outItem.getSoseq() +" slotSeq=" + outItem.getSlotlocation());
}
}
}
}
/**
* 将需求单加入到缓存
*/
public void addTotalOutInfo(OutInfo outInfo){
if(outInfo.isReelCutAction()){
log.info("将分盘需求单"+ outInfo +"加入到累计缓存");
soSeqCacheMap.put(outInfo.getSoseq(), outInfo);
}
}
/**
* 从缓存中清除
* @param soseq
*/
public void closeSoseq(String soseq){
soSeqCacheMap.remove(soseq);
}
/**
* 根据soseq从缓存中查找工单累计信息,如果未找到再从数据库中查找
*/
public OutInfo getCutActionInfoFromCache(String soseq){
if(Strings.isBlank(soseq)){
return null;
}
OutInfo outInfo = soSeqCacheMap.get(soseq);
if(outInfo == null){
log.info("未找到工单序号["+soseq+"]的缓存信息,从数据库中加载");
outInfo = outInfoDao.findCutActionOutInfo(soseq);
}
if(outInfo != null){
Map<String, OutItem> itemMap = outInfo.getOutItemMap();
if(itemMap == null){
List<OutItem> outItems = outItemDao.findByHSerial(outInfo.gethSerial());
outInfo.updateOutItems(outItems);
soSeqCacheMap.put(outInfo.getSoseq(), outInfo);
}
}
return outInfo;
}
}
package com.myproject.webapp.controller.webService;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.myproject.bean.CodeBean;
import com.myproject.bean.json.InventoryItem;
import com.myproject.bean.json.PlateSizeBean;
import com.myproject.bean.qisda.InquiryShelfBean;
import com.myproject.bean.qisda.ShelfInfo;
import com.myproject.bean.update.*;
import com.myproject.bean.update.qisda.CacheInfo;
import com.myproject.bean.update.qisda.DNInfo;
import com.myproject.bean.update.qisda.DNItem;
import com.myproject.dao.mongo.qisda.ICacheInfoDao;
import com.myproject.dao.mongo.qisda.IDNItemDao;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* 缓存
* Created by sunke on 17/3/17.
*/
@Repository
public class QisdaCache {
protected static final transient Logger log = LogManager.getLogger(QisdaCache.class);
private static ICacheInfoDao cacheInfoDao;
private static IDNItemDao dNItemDao;
private static String CURRENT_ORDER_HSERIAL_KEY = "currentOrderHSerial";
/**
* RFID绑定的DN单信息Key
*/
private static String RFID_DN_MAP_KEY = "rfidDnMap";
/**
* 料架信息缓存key
*/
private static String HSERIAL_SHELF_MAP_KEY = "hSerialShelfMap";
/**
* 当前正在执行的工单需求单(首盘,补料),未完成时,其他工单需求单不可执行
*/
private static String currentOrderHSerial;
/**
* RFID绑定DN单和Facility, Key为RFID, Value为DN单信息
*/
private static Map<String, DNInfo> rfidDnMap;
/**
* 保存料架缓存信息
* @param hSerialShelfMap
*/
public static void saveShelfMap(Map<String,Map<String,ShelfInfo>> hSerialShelfMap){
cacheInfoDao.updateCacheItem(HSERIAL_SHELF_MAP_KEY, hSerialShelfMap);
}
/**
* 加载料架缓存信息
*/
public static Map<String,Map<String,ShelfInfo>> loadShelfMap(){
Map<String,Map<String,ShelfInfo>> hSerialShelfMap = new ConcurrentHashMap<>();
CacheInfo cacheInfo = cacheInfoDao.getCacheInfo(HSERIAL_SHELF_MAP_KEY);
if(cacheInfo != null){
hSerialShelfMap = (Map<String,Map<String,ShelfInfo>>) cacheInfo.getCacheValue();
}
return hSerialShelfMap;
}
public void initRfidDnMap(){
if(rfidDnMap == null){
CacheInfo cacheInfo = cacheInfoDao.getCacheInfo(RFID_DN_MAP_KEY);
if(cacheInfo == null){
rfidDnMap = new ConcurrentHashMap<>();
}else{
rfidDnMap = (Map<String, DNInfo>) cacheInfo.getCacheValue();
}
}
}
private synchronized static void saveRfidDnMap(){
cacheInfoDao.updateCacheItem(RFID_DN_MAP_KEY,rfidDnMap);
}
/**
* 获取RFID绑定的DN单信息
* @param rfid
* @return
*/
public static DNInfo getDnInfo(String rfid){
if(rfid == null || rfid.equals("000")){
//rfid = "";
return null;
}
DNInfo dnInfo = rfidDnMap.get(rfid);
String usedRfid = "=" + rfid;
if(dnInfo == null){
dnInfo = rfidDnMap.get(usedRfid);
}else{
//已经使用过,清除掉
rfidDnMap.remove(rfid);
rfidDnMap.put(usedRfid, dnInfo);
saveRfidDnMap();
}
if(dnInfo == null){
//如果未找到料架对应的DNInfo,当作纯入库处理
dnInfo = new DNInfo();
dnInfo.setDnNo("");
}else{
if(dnInfo.getItems().isEmpty()){
List<DNItem> items = dNItemDao.findDnItems(dnInfo.getDnNo());
dnInfo.addItems(items);
}
}
return dnInfo;
}
public static void bindRfidDnInfo(String rfid, DNInfo dnInfo){
rfidDnMap.put(rfid, dnInfo);
saveRfidDnMap();
}
/**
* 清理RFID绑定的DN单信息
*/
public static void clearRfidDn(String rfid){
rfidDnMap.remove(rfid);
saveRfidDnMap();
}
/**
* 当前正在执行的工单需求单
* @param executeHSerial
*/
public static void setCurrentOrderHSerial(String executeHSerial) {
if(currentOrderHSerial == null){
currentOrderHSerial = "";
}
String oldHSerial = currentOrderHSerial;
log.info("设置当前正在执行的工单料需求为:" + executeHSerial+"清理之前["+oldHSerial+"]出库使用的料架");
InquiryShelfBean.clearShelf(oldHSerial);
currentOrderHSerial = executeHSerial;
cacheInfoDao.updateCacheItem(CURRENT_ORDER_HSERIAL_KEY, currentOrderHSerial);
}
/**
* 当前正在执行的工单需求单
*/
public static String getCurrentOrderHSerial() {
if(currentOrderHSerial == null){
CacheInfo cacheInfo = cacheInfoDao.getCacheInfo(CURRENT_ORDER_HSERIAL_KEY);
if(cacheInfo == null){
currentOrderHSerial = "";
}else{
currentOrderHSerial = cacheInfo.getCacheValue().toString();
}
}
return currentOrderHSerial;
}
@Autowired
public void setCacheInfoDao(ICacheInfoDao cacheInfoDao) {
QisdaCache.cacheInfoDao = cacheInfoDao;
}
@Autowired
public void setdNItemDao(IDNItemDao dNItemDao) {
QisdaCache.dNItemDao = dNItemDao;
}
}
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!