SchAttrCalculator.java 8.42 KB
package com.bsth.data.schedule;

import com.bsth.data.LineConfigData;
import com.bsth.entity.realcontrol.LineConfig;
import com.bsth.entity.realcontrol.ScheduleRealInfo;
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.stereotype.Component;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author PanZhao
 * @ClassName: SchAttrCalculator
 * @Description: TODO(班次相关属性计算器)
 * @date 2016年8月15日 下午4:40:26
 */
@Component
public class SchAttrCalculator {

    @Autowired
    LineConfigData lineConfigData;

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

    Logger logger = LoggerFactory.getLogger(this.getClass());

    private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd"), fmtHHmm = DateTimeFormat.forPattern("HH:mm"), fmtyyyyMMddHHmm = DateTimeFormat.forPattern("yyyy-MM-ddHH:mm");

    /**
     * @Title: calcRealDate
     * @Description: TODO(计算班次的真实执行日期)
     */
    public SchAttrCalculator calcRealDate(ScheduleRealInfo sch) {
        LineConfig conf = lineConfigData.get(sch.getXlBm());

        try {
            if (null == sch.getFcsjT())
                calcFcsjTime(sch);

            String rq = sch.getScheduleDateStr();
            //计发時間
            sch.setFcsjAll(getTime(rq, sch.getFcsj(), conf));

            //待发時間
            sch.setDfsjAll(getTime(rq, sch.getDfsj(), conf));
            /*if (sch.getDfsj().compareTo(conf.getStartOpt()) < 0) {
                sch.setDfsjAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr() + sch.getDfsj()) + DAY_TIME);
            } else
                sch.setDfsjAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr() + sch.getDfsj()));*/

            //实发時間
            sch.setFcsjActualAll(getTime(rq, sch.getFcsjActual(), conf));
            /*if (StringUtils.isNotEmpty(sch.getFcsjActual()) &&
                    sch.getFcsjActual().compareTo(conf.getStartOpt()) < 0) {
                sch.setFcsjActualAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr() + sch.getFcsjActual()) + DAY_TIME);
            }*/

            //实际终点時間
            sch.setZdsjActualAll(getTime(rq, sch.getZdsjActual(), conf));
            /*if (StringUtils.isNotEmpty(sch.getZdsjActual()) &&
                    sch.getZdsjActual().compareTo(conf.getStartOpt()) < 0) {
                sch.setZdsjActualAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr() + sch.getZdsjActual()) + DAY_TIME);
            }*/

            sch.setRealExecDate(fmtyyyyMMdd.print(sch.getFcsjT()));
        } catch (Exception e) {
            logger.error("", e);
        }
        return this;
    }

    public Long getTime(String rq, String timeStr, LineConfig conf) {
        Long t = null;
        if (StringUtils.isNotEmpty(timeStr)) {
            t = fmtyyyyMMddHHmm.parseMillis(rq + timeStr);
            if(timeStr.compareTo(conf.getStartOpt()) < 0)
                return t + DAY_TIME;
        }
        return t;
    }

    /**
     * @Title: calcAllTimeByFcsj
     * @Description: TODO(根据发车时间字符串计算 (计发时间,终点时间,待发时间))
     */
    public SchAttrCalculator calcAllTimeByFcsj(ScheduleRealInfo sch) {
        try {
            // 生成时间戳
            calcTimestamp(sch);

            // 计划终点时间
            if (sch.getBcsj() != null) {
                sch.setZdsjT(sch.getFcsjT() + (sch.getBcsj() * 60 * 1000));
                sch.setZdsj(fmtHHmm.print(sch.getZdsjT()));
            }
        } catch (ParseException e) {
            logger.error("", e);
        }
        return this;
    }

    /**
     * @Title: calcQdzTimePlan
     * @Description: TODO(计算班次的起点应到时间)
     */
    public void calcQdzTimePlan(List<ScheduleRealInfo> list) {
        Collections.sort(list, new ScheduleComparator.FCSJ());

        int len = list.size();
        if (len == 0)
            return;

        ScheduleRealInfo prve = list.get(0), curr;
        for (int i = 1; i < len; i++) {
            curr = list.get(i);

            if (isJoin(prve, curr)) {
                curr.setQdzArrDatejh(prve.getZdsj());
                if (StringUtils.isNotEmpty(prve.getZdsjActual()))
                    curr.setQdzArrDatesj(prve.getZdsjActual());
            }
            prve = curr;
        }
    }

    private boolean isJoin(ScheduleRealInfo prve, ScheduleRealInfo curr) {
        return prve.getZdzName().equals(curr.getQdzName())//名称相等
                || prve.getZdzCode().equals(curr.getQdzCode())//编码相等
                || prve.getZdzName().startsWith(curr.getQdzName())//起始包括
                || curr.getQdzName().startsWith(prve.getZdzName());//起始包括
    }

    /**
     * @Title: updateQdzTimePlan
     * @Description: TODO(更新班次的起点应到时间) 并返回被更新的班次
     */
    public List<ScheduleRealInfo> updateQdzTimePlan(List<ScheduleRealInfo> list) {
        Collections.sort(list, new ScheduleComparator.FCSJ());

        List<ScheduleRealInfo> updateList = new ArrayList<>();
        int len = list.size();
        if (len == 0)
            return updateList;

        ScheduleRealInfo prve = list.get(0), curr;
        for (int i = 1; i < len; i++) {
            curr = list.get(i);

            if (prve.getZdzName().equals(curr.getQdzName())
                    || prve.getZdzCode().equals(curr.getQdzCode())) {

                if (curr.getQdzArrDatejh() != null && prve.getZdsj().equals(curr.getQdzArrDatejh())) {
                    prve = curr;
                    continue;
                }

                curr.setQdzArrDatejh(prve.getZdsj());
                updateList.add(curr);
            } else {
                curr.setQdzArrDatejh(null);
                updateList.add(curr);
            }
            prve = curr;
        }

        return updateList;
    }

    public SchAttrCalculator calcFcsjTime(ScheduleRealInfo sch) throws ParseException {
        sch.setFcsjT(fmtyyyyMMddHHmm.parseMillis(sch.getRealExecDate() + sch.getFcsj()));
        return this;
    }

    public void calcTimestamp(ScheduleRealInfo sch) throws ParseException {
        //计发时间
        if (sch.getFcsjT() == null)
            calcFcsjTime(sch);

        //待发时间
        if (sch.getDfsj() == null)
            sch.setDfsjAll(sch.getFcsjT());
        if (sch.getDfsjT() == null)
            sch.setDfsjAll(sch.getDfsj());

        //实发时间戳
        if (sch.getFcsjActualTime() == null && sch.getFcsjActual() != null)
            sch.setFcsjActualAll(sch.getFcsjActual());

        //实达时间戳
        if (sch.getZdsjActualTime() == null && sch.getZdsjActual() != null)
            sch.setZdsjActualAll(sch.getZdsjActual());
    }

    /**
     * 计算当前要执行的班次
     *
     * @param list
     * @return
     */
    public ScheduleRealInfo calcCurrentExecSch(List<ScheduleRealInfo> list) {
        if(list.size()==0)
            return null;
        String lineCode = list.get(0).getXlBm();
        LineConfig conf = lineConfigData.get(lineCode);

        int outConfig = -1;
        //限定出站既出场的停车场
        List<String> parks = null;
        if (conf != null) {
            outConfig = conf.getOutConfig();
            parks = conf.findTwinsParkList();
        }
        boolean limitPark = null != parks && parks.size() > 0;

        ScheduleRealInfo sch, prev = null;
        for(int i = list.size() - 1; i >= 0; i --){
            sch = list.get(i);

            //如果是出站既出场,忽略出场班次
            if (outConfig == 2 && sch.getBcType().equals("out")
                    && (!limitPark || parks.contains(sch.getQdzCode()))
                    && (sch.getBcsj()==0 || sch.getJhlcOrig().intValue()==0))
                continue;

            //忽略烂班
            if (sch.isDestroy())
                continue;

            if (StringUtils.isNotEmpty(sch.getZdsjActual()))
                break;

            prev = sch;
        }
        return prev;
    }
}