UserCarCountHandler.java 11.3 KB
package com.bsth.handler;

import com.bsth.entity.LineConfig;
import com.bsth.entity.ScheduleRealInfo;
import com.bsth.entity.result.WorkingHours_jsy;
import com.bsth.service.LineConfigService;
import com.bsth.service.ScheduleRealInfoService;
import com.bsth.util.ConvertUtil;
import com.google.common.collect.ArrayListMultimap;
import com.mysql.fabric.xmlrpc.base.Data;

import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 人员车辆班次里程处理程序
 */
@Component
public class UserCarCountHandler {

    /**
     * 结算规则, 周几 ——> 结算前几天 (考虑间隔)
     */
    private static Map<Integer, Integer> runRuleMap;

    /**
     * 间隔1天(留一天的时间给各个公司检查路单)
     */
    private final static int DAY_SPACE = 1;

    /**
     * 判定分班时间阈值
     */
    private final static long FB_THRESHOLD_TIME = 1000 * 60 * 60 * 2;

    @Autowired
    ScheduleRealInfoService scheduleRealInfoService;
    @Autowired
    LineConfigService lineConfigService;

    @Autowired
    JdbcTemplate jdbcTemplate;

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

    static {
        //0 是周天
        runRuleMap = new HashMap<>();
        runRuleMap.put(1, 0);
        runRuleMap.put(2, 3);
        runRuleMap.put(3, 1);
        runRuleMap.put(4, 1);
        runRuleMap.put(5, 1);
        runRuleMap.put(6, 1);
        runRuleMap.put(0, 0);
    }

    /*public void calc() {
        DateTime dt = DateTime.now();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dt.toDate());
        //今天要结算多少天的工时
        int count = runRuleMap.get(calendar.get(Calendar.DAY_OF_WEEK) - 1);

        dt = dt.minusDays(DAY_SPACE + count);
        String rq;
        for (int i = 0; i < count; i++) {
            rq = dt.toString("yyyy-MM-dd");
            calc(rq);
            dt = dt.plusDays(1);
        }
    }*/

    public void calcLast(){
    	//计算前一天班次里程
    	Date dNow = new Date();   
    	Calendar calendar = Calendar.getInstance(); 
    	calendar.setTime(dNow);
    	calendar.add(Calendar.DAY_OF_MONTH, -1);  //设置为前一天
    	Date dBefore = calendar.getTime();   //得到前一天的时间
    	SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); //设置时间格式
    	SimpleDateFormat sdf2=new SimpleDateFormat(" HH:mm");//得到当前时间
    	String lastRq = sdf.format(dBefore);    //格式化前一天
		String time=sdf2.format(dNow); //格式化当前时间
		String times[] =time.split(":");
		time=times[0]+times[1];
		int t=Integer.parseInt(times[0])*60+Integer.parseInt(times[1]);
    	calc(lastRq,t);
    	
    }
    
    private void calc(String rq,int t){
    	 try {
    		 List<LineConfig> listLineConfig=lineConfigService.findAllList();
    		 for (int i = 0; i < listLineConfig.size(); i++) {
    			 LineConfig lineConfig=listLineConfig.get(i);
    			 String lineCode=lineConfig.getLineCode();
    			 String startOpt=lineConfig.getStartOpt();
    			 String times[] =startOpt.split(":");
    			 int time=Integer.parseInt(times[0])*60+Integer.parseInt(times[1])-30; 
    			 //线路重新排版前30分钟 统计该线路前一天的 班次 里程
    			 if(time>t){
    				 //查询该线路前一天的排班
    			 }
				
			}
    		 
    	 }catch (Exception e) {
             logger.error("", e);
         }
    }
    
    /*private void calc(String rq) {
        try {
            logger.info("开始结算工时: " + rq);
            List<WorkingHours_jsy> list = new ArrayList<>();
            //实际班次,路单数据
            List<ScheduleRealInfo> sjList = scheduleRealInfoService.findAll(rq);
            //计划班次,计调数据
            List<ScheduleRealInfo> jhList = scheduleRealInfoService.findAll_JH(rq);

            //附加停站时间
            addStopTime(sjList);
            addStopTime(jhList);

            //合计工时
            List<WorkingHours_jsy> jhArray = count(jhList, true);
            List<WorkingHours_jsy> sjArray = count(sjList, false);

            //合并计划和实际
            Map<String, WorkingHours_jsy> merges = new HashMap<>();
            for (WorkingHours_jsy jh : jhArray) {
                jh.setHoursSj(0);
                merges.put(jh.keys(), jh);
            }

            String key;
            for (WorkingHours_jsy sj : sjArray) {
                key = sj.keys();
                if (merges.containsKey(key)) {
                    merges.get(key).setHoursSj(sj.getHoursSj());
                } else {
                    sj.setHoursJh(0);
                    merges.put(key, sj);
                }
            }
            //入库
            save(new ArrayList(merges.values()));
            logger.info("结算工时成功: " + rq + " -size: " + merges.values().size());
        } catch (Exception e) {
            logger.error("", e);
        }
    }*/

    private void addStopTime(List<ScheduleRealInfo> list) throws NoSuchFieldException {
        Class clazz = ScheduleRealInfo.class;
        //按驾驶员分组班次
        ArrayListMultimap<String, ScheduleRealInfo> multimap = new ConvertUtil<ScheduleRealInfo>()
                .groupMultiList(list, "", clazz.getDeclaredField("jGh"));

        //为班次附上停站时间
        Set<String> ks = multimap.keySet();
        for (String k : ks) {
            calcOne(multimap.get(k));
        }
    }

    private List<WorkingHours_jsy> count(List<ScheduleRealInfo> list, boolean isJh) throws NoSuchFieldException {
        List<WorkingHours_jsy> rs = new ArrayList<>();
        Class clazz = ScheduleRealInfo.class;
        //按 线路_路牌_驾驶员_车辆分组数据
        Field xl_f = clazz.getDeclaredField("xlBm"),
                lp_f = clazz.getDeclaredField("lpName"),
                jsy_f = clazz.getDeclaredField("jGh"),
                cl_f = clazz.getDeclaredField("clZbh");

        ArrayListMultimap<String, ScheduleRealInfo> multimap = new ConvertUtil<ScheduleRealInfo>()
                .groupMultiList(list, "_", xl_f, lp_f, jsy_f, cl_f);

        //合计工时
        Date d = new Date();
        Set<String> ks = multimap.keySet();
        WorkingHours_jsy wh;
        for (String k : ks) {
            wh = sum(multimap.get(k), isJh);
            wh.setCreateDate(d);
            rs.add(wh);
        }

        return rs;
    }

    private void save(final List<WorkingHours_jsy> list) {
        String sql = "insert into z_calc_hoursjsy(company_id, sub_company_id, line_code, line_name, jsy, jsy_name, nbbm, lp_name, rq, hours_jh, hours_sj, source, remarks, create_date) " +
                "  VALUES(?, ?, ?, ?, ?,?, ?, ?,?,?,?,?,?,?)";

        //编程式事务
        DataSourceTransactionManager tran = new DataSourceTransactionManager(jdbcTemplate.getDataSource());
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = tran.getTransaction(def);

        try {
            jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
                @Override
                public void setValues(PreparedStatement ps, int i) throws SQLException {
                    WorkingHours_jsy wh = list.get(i);
                    ps.setString(1, wh.getCompanyId());
                    ps.setString(2, wh.getSubCompanyId());
                    ps.setString(3, wh.getLineCode());
                    ps.setString(4, wh.getLineName());
                    ps.setString(5, wh.getJsy());
                    ps.setString(6, wh.getJsyName());
                    ps.setString(7, wh.getNbbm());
                    ps.setString(8, wh.getLpName());
                    ps.setString(9, wh.getRq());
                    ps.setDouble(10, wh.getHoursJh());
                    ps.setDouble(11, wh.getHoursSj());
                    ps.setInt(12, wh.getSource());
                    ps.setString(13, wh.getRemarks());
                    ps.setDate(14, new java.sql.Date(wh.getCreateDate().getTime()));
                }

                @Override
                public int getBatchSize() {
                    return list.size();
                }
            });

            tran.commit(status);
        } catch (Exception e) {
            tran.rollback(status);
            logger.error("", e);
        }
    }


    /**
     * 合计工时
     *
     * @param list
     * @return
     */
    private WorkingHours_jsy sum(List<ScheduleRealInfo> list, boolean jh) {
        ScheduleRealInfo sch = list.get(0);
        WorkingHours_jsy wh = new WorkingHours_jsy();

        wh.setCompanyId(sch.getGsBm());
        wh.setSubCompanyId(sch.getFgsBm());
        wh.setLineCode(sch.getXlBm());
        wh.setLpName(sch.getLpName());
        wh.setJsy(sch.getjGh());
        wh.setJsyName(sch.getjName());
        wh.setNbbm(sch.getClZbh());
        wh.setLineName(sch.getXlName());
        wh.setRq(sch.getScheduleDateStr());
        //wh.set
        Integer sum = 0;

        for (ScheduleRealInfo s : list) {
            sum += s.getHours();
        }

        if (jh)
            wh.setHoursJh(sum);
        else
            wh.setHoursSj(sum);
        return wh;
    }

    /**
     * 计算每个班次的工时(包括停站时间)
     *
     * @param list
     */
    private void calcOne(List<ScheduleRealInfo> list) {
        if (list.size() <= 1)
            return;


        Collections.sort(list, new Comparator<ScheduleRealInfo>() {
            @Override
            public int compare(ScheduleRealInfo s1, ScheduleRealInfo s2) {
                return (int) (s1.getDfsjT() - s2.getDfsjT());
            }
        });

        int len = list.size() - 1;
        for (int i = 0; i < len; i++) {
            calcToNextHours(list.get(i), list.get(i + 1));
        }

    }

    /**
     * 当前班次 和 下一个班次计算工时
     *
     * @param sch
     * @param next
     */
    private void calcToNextHours(ScheduleRealInfo sch, ScheduleRealInfo next) {
        /*if(sch.getjGh().equals("008435") && sch.getClZbh().equals("W0F-017"))
            System.out.println("aaa");*/
        //分班班次
        /*if (isIn(sch) && isOut(next) )
            return;*/

        //分班间隔
        if (next.getFcsjT() - sch.getFcsjT() >= FB_THRESHOLD_TIME){
            if(sch.getStatus()==-1)
                sch.setHours(0);
            return;
        }

        //把停站时间算进去
        //sch.setHours((int) ((next.getFcsjT() - sch.getFcsjT()) / 1000 / 60));
        sch.setHours((int) ((next.getFcsjActualTime() - sch.getFcsjActualTime()) / 1000 / 60));
    }

    private boolean isIn(ScheduleRealInfo sch) {
        return sch.getBcType().equals("in");
    }

    private boolean isOut(ScheduleRealInfo sch) {
        return sch.getBcType().equals("out");
    }
}