QisdaCache.java 8.5 KB
package com.myproject.webapp.controller.webService;

import com.myproject.bean.qisda.InquiryShelfBean;
import com.myproject.bean.qisda.QisdaApiRequest;
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 com.myproject.exception.ApiException;
import com.myproject.util.HttpHelper;
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";

    /**
     * 重发消息key
     */
    private static String FAILED_REQUEST_MAP_KEY = "failedRequestMap";

    /**
     * 当前正在执行的工单需求单(首盘,补料),未完成时,其他工单需求单不可执行
     */
    private static String currentOrderHSerial;

    /**
     * RFID绑定DN单和Facility, Key为RFID, Value为DN单信息
     */
    private static Map<String, DNInfo> rfidDnMap;

    /**
     * 需要重新向佳世达发送的指令列表
     */
    private static Map<String, QisdaApiRequest> failedRequestMap;

    private static boolean isProcessTimer = false;
    /**
     * 定时器,每10秒执行一次
     */
    public static void runTimer(){
        if(!isProcessTimer){
            isProcessTimer = true;
            try {
                sendFailedRequest();
            }catch (Exception e){
                log.error("发送失败请求定时器执行出错:"+e.getMessage());
            }finally {
                isProcessTimer = false;
            }
        }
    }
    /**
     * 获取失败列表,进行定时发送
     */
    private static void sendFailedRequest() throws ApiException {
        List<QisdaApiRequest> failedList = new ArrayList<>();
        failedList.addAll(failedRequestMap.values());
        failedList.sort(new Comparator<QisdaApiRequest>() {
            @Override
            public int compare(QisdaApiRequest o1, QisdaApiRequest o2) {
                return o1.getDate().compareTo(o2.getDate()) ;
            }
        });

        for (QisdaApiRequest apiRequest : failedList) {
            log.info("重发通知指令[" + apiRequest.getMapKey() + "]到Qisda");
            String result = HttpHelper.postParam(apiRequest.getUrl(),apiRequest.getParamMap());
            log.info("重发通知指令[" + apiRequest.getMapKey() + "]到Qisda返回:" + result);
            QisdaCache.removeFailedRequest(apiRequest);
        }
        
    }

    /**
     * 加载请求指令信息
     */
    public static void initApiRequestMap(){
        if(failedRequestMap == null){
            failedRequestMap = new ConcurrentHashMap<>();
            CacheInfo cacheInfo = cacheInfoDao.getCacheInfo(FAILED_REQUEST_MAP_KEY);
            if(cacheInfo != null){
                Map<String, QisdaApiRequest> dbFailedRequestMap = (Map<String, QisdaApiRequest>) cacheInfo.getCacheValue();
                failedRequestMap.putAll(dbFailedRequestMap);
                log.info("当前发送通知失败指令:" + failedRequestMap);
            }
        }
    }

    public static void addFailedRequest(QisdaApiRequest apiRequest){
        String mapKey = apiRequest.getMapKey();
        if(failedRequestMap.get(mapKey) == null){
            log.info(mapKey + "通知指令发送到Qisda失败,加入到缓存");
            failedRequestMap.put(apiRequest.getMapKey(), apiRequest);
        }
    }

    public static void removeFailedRequest(QisdaApiRequest apiRequest){
        String mapKey = apiRequest.getMapKey();
        if(failedRequestMap.get(mapKey) == null){
            log.info(mapKey + "通知指令发送到Qisda成功,从缓存中移除");
            failedRequestMap.remove(apiRequest.getMapKey());
        }
    }



    /**
     * 保存料架缓存信息
     * @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){
            Map<String, Map<String, ShelfInfo>> dbShelfMap = (Map<String, Map<String, ShelfInfo>>) cacheInfo.getCacheValue();
            hSerialShelfMap.putAll(dbShelfMap);
        }
        return hSerialShelfMap;
    }

    /**
     * 初始化DN单绑定缓存信息
     */
    public void initRfidDnMap(){
        if(rfidDnMap == null){
            CacheInfo cacheInfo = cacheInfoDao.getCacheInfo(RFID_DN_MAP_KEY);
            rfidDnMap = new ConcurrentHashMap<>();
            if(cacheInfo != null){
                Map<String, DNInfo> dbRfidDnMap = (Map<String, DNInfo>) cacheInfo.getCacheValue();
                rfidDnMap.putAll(dbRfidDnMap);
                log.info("当前收料绑定:" + rfidDnMap);
            }
        }
    }

    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;
    }
}