ScheduleRedisService.java 8 KB
package com.bsth.redis;

import com.bsth.common.BasicData;
import com.bsth.entity.ScheduleRealInfo;
import com.bsth.redis.util.RedisUtils;
import com.bsth.repository.ScheduleRealInfoRepository;
import com.bsth.server_rs.base_info.line.buffer.LineBufferData;
import com.bsth.util.ConvertUtil;
import com.google.common.collect.ArrayListMultimap;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 班次 redis 缓存管理
 * Created by panzhao on 2017/3/13.
 */
@Service
@Order(2)
public class ScheduleRedisService implements CommandLineRunner {

    @Autowired
    ScheduleRealInfoRepository scheduleRealInfoRepository;

    private final static String REDIS_KEY_PREFIX = "schedule:";

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    RedisUtils redisUtils;

    static Logger logger = LoggerFactory.getLogger(ScheduleRedisService.class);

    private final static long DAY_TIME = 1000 * 60 * 60 * 24L;

    /**
     * 将一批班次写入redis
     *
     * @param list
     */
    public void wirte(List<ScheduleRealInfo> list) {
        ArrayListMultimap<String, ScheduleRealInfo> multimap;
        try {
            if (list.size() == 0)
                return;
            //按日期和线路分组数据
            Class clazz = ScheduleRealInfo.class;
            multimap = new ConvertUtil().groupMultiList(list, ":", clazz.getDeclaredField("xlBm"), clazz.getDeclaredField("scheduleDateStr"));

            //写入redis
            Iterator<String> iterator = multimap.keySet().iterator();
            String key;
            while (iterator.hasNext()) {
                key = iterator.next();
                replace(key, multimap.get(key));
            }
        } catch (Exception e) {
            logger.error("", e);
        }
    }

    /**
     * 将 list 与redis里的数据合并
     *
     * @param key
     * @param list
     */
    public void mergeData(String key, List<ScheduleRealInfo> list) {
        key = REDIS_KEY_PREFIX + key.replaceAll("-", "");

        ListOperations<String, ScheduleRealInfo> ops = redisTemplate.opsForList();
        List<ScheduleRealInfo> cacheList = ops.range(key, 0, -1);

        for (ScheduleRealInfo sch : cacheList) {
            if (!list.contains(sch))
                list.add(sch);
        }

        //更新
        redisTemplate.execute(redisUtils.getUpdateCallback(key, list));
    }

    /**
     * 覆盖数据
     *
     * @param key
     * @param list
     */
    public void replace(String key, List<ScheduleRealInfo> list) {
        key = REDIS_KEY_PREFIX + key.replaceAll("-", "");
        redisTemplate.execute(redisUtils.getUpdateCallback(key, list));
    }

    /**
     * 删除数据
     *
     * @param key
     */
    public void delete(String lineCode, String rq) {
        String key = REDIS_KEY_PREFIX + (lineCode + ":" + rq).replaceAll("-", "");
        redisTemplate.delete(key);
    }

    /**
     * 根据日期和线路编码从redis获取班次
     *
     * @param dateStr
     * @param lineCode
     * @return
     */
    public List<ScheduleRealInfo> read(String dateStr, String lineCode) {
        return redisTemplate.opsForList().range(REDIS_KEY_PREFIX + lineCode + ":" + dateStr, 0, -1);
    }

    /**
     * 返回指定日期,公司的实际排班,并按线路_车辆分组
     *
     * @param rq
     * @param companyId
     * @return
     */
    public ArrayListMultimap<String, ScheduleRealInfo> findByDateAndGroupByNbbm(String rq, String companyId) {
        List<String> lineArray = LineBufferData.findCodesByCompany(companyId);
        ArrayListMultimap<String, ScheduleRealInfo> rs = ArrayListMultimap.create();

        rq = rq.replaceAll("-", "");
        List<ScheduleRealInfo> list;
        for (String lineCode : lineArray) {

            list = read(rq, lineCode);

            for (ScheduleRealInfo sch : list) {
                rs.put(sch.getXlBm() + "_" + sch.getClZbh(), sch);
            }
        }
        return rs;
    }

    /**
     * 返回指定日期,公司的实际排班,并按线路分组
     *
     * @param rq
     * @param companyId
     * @return
     */
    public ArrayListMultimap<String, ScheduleRealInfo> findByDateAndGroupByLine(String rq, String companyId) {

        List<String> lineArray = LineBufferData.findCodesByCompany(companyId);
        ArrayListMultimap<String, ScheduleRealInfo> rs = ArrayListMultimap.create();

        rq = rq.replaceAll("-", "");
        List<ScheduleRealInfo> list;
        for (String lineCode : lineArray) {

            list = read(rq, lineCode);

            for (ScheduleRealInfo sch : list) {
                rs.put(sch.getXlBm(), sch);
            }
        }
        return rs;
    }

    /**
     * 返回指定日期,所有实际排班,并按自编号分组
     *
     * @param rq
     * @return
     */
    public ArrayListMultimap<String, ScheduleRealInfo> findByDate(String rq) {

        ArrayListMultimap<String, ScheduleRealInfo> rs = ArrayListMultimap.create();

        List<ScheduleRealInfo> list = scheduleRealInfoRepository.findAll(rq);
        for (ScheduleRealInfo sch : list) {
            rs.put(sch.getClZbh(), sch);
        }
        return rs;
    }

    @Override
    public void run(String... strings) throws Exception {

    }

    public List<ScheduleRealInfo> findByMultiLine(List<String> lineArray, String rq) {
        rq = rq.replaceAll("-", "");
        List<ScheduleRealInfo> rs = new ArrayList<>();
        for (String lineCode : lineArray) {
            rs.addAll(read(rq, lineCode));
        }
        return rs;
    }

    /**
     * ############ 时间戳计算 ##########
     */
    private static DateTimeFormatter fmtyyyyMMddHHmm = DateTimeFormat.forPattern("yyyy-MM-ddHH:mm"),
            fmtHHmm = DateTimeFormat.forPattern("HH:mm");

    public void calcTime(List<ScheduleRealInfo> list) {
        if (list.size() == 0)
            return;

        //计算真实执行日期 和 时间戳
        for (ScheduleRealInfo sch : list) {
            calcRealDate(BasicData.lineStartTimeMap.get(sch.getXlBm()), sch);
        }
    }

    /**
     * @Title: calcRealDate
     * @Description: TODO(计算班次的真实执行日期)
     */
    public void calcRealDate(String startTime, ScheduleRealInfo sch) {
        try {
            if (null == startTime)
                return;

            if (null == sch.getBcsj())
                sch.setBcsj(0);

            String rq = sch.getScheduleDateStr();
            //计发时间
            sch.setFcsjT(parseTime(rq, sch.getFcsj(), startTime));
            //待发时间
            sch.setDfsjT(parseTime(rq, sch.getDfsj(), startTime));
            //计划终点时间
            if (StringUtils.isEmpty(sch.getZdsj())) {
                sch.setZdsjT(sch.getFcsjT() + (sch.getBcsj() * 60 * 1000));
                sch.setZdsj(fmtHHmm.print(sch.getZdsjT()));
            } else
                sch.setZdsjT(sch.getFcsjT() + (sch.getBcsj() * 60 * 1000));
            //实发时间
            if (StringUtils.isNotEmpty(sch.getFcsjActual()))
                sch.setFcsjActualAll(parseTime(rq, sch.getFcsjActual(), startTime));

            //实达时间
            if (StringUtils.isNotEmpty(sch.getZdsjActual()))
                sch.setZdsjActualAll(parseTime(rq, sch.getZdsjActual(), startTime));
        } catch (Exception e) {
            logger.error("", e);
        }
    }

    private long parseTime(String rq, String sj, String startTime) {
        long t = fmtyyyyMMddHHmm.parseMillis(rq + sj);
        if (sj.compareTo(startTime) < 0) {
            t += DAY_TIME;
        }
        return t;
    }
}