SchedulingCache.java 7.57 KB
package com.ruoyi.common.cache;

import com.ruoyi.pojo.response.ResponseSchedulingDto;
import com.ruoyi.utils.ConstDateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.security.MessageDigest;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static com.ruoyi.common.redispre.GlobalRedisPreName.DRIVER_SCHEDULING_PRE;

/**
 * 排班缓存
 *
 * @author 20412
 */
@Component
public class SchedulingCache {

    Logger log = LoggerFactory.getLogger(SchedulingCache.class);


    //    @Value("${api.url.getSchedulingInfoNew}")
    private static final String getSchedulingInfoUrl = "http://192.168.50.120:9089/webservice/rest/schedule_real/sch_jk_db/%s/%s?timestamp=%d&nonce=%s&password=%s&sign=%s";
    //    @Value("${api.config.nonce}")
    private static final String NONCE = "adfsad";
    //    @Value("${api.config.password}")
    private static final String PASSWORD = "c4dd3d8cb9a82f6d6a625818618b28ca7bebb464";

    /**
     * 实时更新排班
     */
    private static ConcurrentHashMap<String, Map<String, List<ResponseSchedulingDto>>> cacheScheduling = new ConcurrentHashMap<>();


    public SchedulingCache() {
        log.info("项目启动加载中获取实时班次并存入缓存-----");
        schedulingInit();
    }


    /**
     * 初始化排班数据 并存入缓存
     */
    private void schedulingInit() {
        String formatNowDate = ConstDateUtil.formatDate(new Date());
        String url = getUrl(formatNowDate);
        log.info("初始化排班数据:{}", formatNowDate);
        saveSchedulingToCache(url, formatNowDate);
        String formatYesterdayDate = ConstDateUtil.formatDate(ConstDateUtil.getTheSpecifiedNumberOfDaysOfTime(-1));
        log.info("初始化排班数据:{}", formatYesterdayDate);
        url = getUrl(formatYesterdayDate);
        saveSchedulingToCache(url, formatYesterdayDate);
    }

    private String getUrl(String formatNowDate) {
        String url = null;
        long timestamp = System.currentTimeMillis();
//        String formatDate = ConstDateUtil.formatDate(ConstDateUtil.getTheSpecifiedNumberOfDaysOfTime(-1));
        // 获取排班请求
        try {
            url = String.format(getSchedulingInfoUrl, "99", formatNowDate, timestamp, NONCE, PASSWORD, getSHA1(getStringStringMap(String.valueOf(timestamp))));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return url;
    }

    /**
     * 获取签名
     *
     * @param map
     * @return
     * @throws Exception
     */
    private String getSHA1(Map<String, String> map) throws Exception {
        try {
            String[] array = new String[map.size()];
            map.values().toArray(array);
            StringBuffer sb = new StringBuffer();
            // 字符串排序
            Arrays.sort(array);
            for (int i = 0; i < array.length; i++) {
                sb.append(array[i]);
            }
            String str = sb.toString();
            // SHA1签名生成
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.update(str.getBytes());
            byte[] digest = md.digest();
            StringBuffer hexstr = new StringBuffer();
            String shaHex = "";
            for (int i = 0; i < digest.length; i++) {
                shaHex = Integer.toHexString(digest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexstr.append(0);
                }
                hexstr.append(shaHex);
            }
            return hexstr.toString();
        } catch (Exception e) {
            throw e;
        }


    }


    private Map<String, List<ResponseSchedulingDto>> saveSchedulingToCache(String getSchedulingInfoUrl, String dateKey) {
        log.info("开始拉取排班:{}", dateKey);
        List<ResponseSchedulingDto> originSchedulingList = new RestTemplate().exchange(
                getSchedulingInfoUrl,
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<ResponseSchedulingDto>>() {
                }).getBody();

        Map<String, List<ResponseSchedulingDto>> driverSchedulingMap = new HashMap<>(200);
        // 按照员工工号来获取排班信息
        originSchedulingList = originSchedulingList.stream()
                .map(subItem -> {
                    subItem.setJobCode(subItem.getJsy().split("/")[0]);
                    return subItem;
                }).collect(Collectors.toList());
        // 以员工号为key存入排班集合
        originSchedulingList.stream().forEach(item -> {
            // 员工号为key
            String jobCode = item.getJsy().split("/")[0];
            String salePersonJobCode = item.getSpy().split("/").length > 0 ? item.getSpy().split("/")[0] : null;
            item.setJobCode(jobCode);
            splitSaveScheduling(driverSchedulingMap, jobCode, item);
            splitSaveScheduling(driverSchedulingMap, salePersonJobCode, item);
        });
        // 排序
        List<String> keys = new ArrayList<>(driverSchedulingMap.keySet());
        for (String key : keys) {
            List<ResponseSchedulingDto> schedulingList = driverSchedulingMap.get(key);
            schedulingList.sort(Comparator.comparing(ResponseSchedulingDto::getFcsjT));
        }
        // 存入数据库
//        DRIVER_SERVICE.saveDriverScheduling(originSchedulingList);
        // 存入redis
        setCacheScheduling(DRIVER_SCHEDULING_PRE + dateKey, driverSchedulingMap);
//        REDIS_CACHE.setCacheMap(DRIVER_SCHEDULING_PRE + dateKey, driverSchedulingMap, 2, TimeUnit.DAYS);
        log.info("拉取排班完毕:{}", dateKey);
        return driverSchedulingMap;
    }

    private void splitSaveScheduling(Map<String, List<ResponseSchedulingDto>> driverSchedulingMap, String jobCode, ResponseSchedulingDto item) {
        if (!Objects.isNull(jobCode))
            if (Objects.isNull(driverSchedulingMap.get(jobCode))) {
                List<ResponseSchedulingDto> oneDriverScheduling = new ArrayList<>();
                oneDriverScheduling.add(item);
                driverSchedulingMap.put(jobCode, oneDriverScheduling);
            } else {
                driverSchedulingMap.get(jobCode).add(item);
            }
    }

    private Map<String, String> getStringStringMap(String timestamp) {
        Map<String, String> configMap = new HashMap<>(5);
        configMap.put("timestamp", String.valueOf(timestamp));
        configMap.put("nonce", NONCE);
        configMap.put("password", PASSWORD);
        return configMap;
    }

    public void setCacheScheduling(String key, Map<String, List<ResponseSchedulingDto>> mapValue) {
        cacheScheduling.put(key, mapValue);
    }

    public void removeCacheSchedulingByKey(String key) {
        cacheScheduling.remove(key);
    }

    public List<String> getKeys() {
        return new ArrayList<>(cacheScheduling.keySet());
    }

    public Integer size() {
        return cacheScheduling.size();
    }

    public List<ResponseSchedulingDto> getCacheSchedulingMapValueByHKey(String key, String HKey) {
        Map<String, List<ResponseSchedulingDto>> map = cacheScheduling.get(key);
        if (Objects.isNull(map)) {
            return null;
        }
        List<ResponseSchedulingDto> list = map.get(HKey);

        return Objects.isNull(list) ? null : list;
    }

    public List<String> getHKeysByKey(String key) {
        return new ArrayList<>(cacheScheduling.get(key).keySet());
    }

}