⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cheliangdjtask.java

📁 一个真实项目的源代码。有一个比较优秀的时间类
💻 JAVA
字号:
package com.zx.cheliang;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.TimerTask;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.work.db.DbConnection;
import com.work.db.DbUtil;
import com.work.exception.OurException;
import com.work.util.DateUtil;
/**
 * 系统根据车辆分配、司机安排情况,系统自动从用车申请审批流程中取出数据,
 * 统计司机对应的出车记录和出车时间,
 * 以方便计算发给司机的出车补助和加班补助。
 * @author wangmj
 *
 */
public class CheLiangDjTask extends TimerTask{

	private static Log log = LogFactory.getLog(CheLiangDjTask.class);

	/**
	 * 为了实现用车申请流程中的数据自动登记;<br>
	 * 实现思路:首先判断此用车申请流程是否结束。将用车申请流程中的数据从zx_ycsqd表中查询出来,
	 * 然后插入到表zx_ycsqdj中去,同时将zx_ycsqd表中符合条件记录的sfdj设置为1
	 * 
	 * @return void
	 */
	public void ycsqDj() throws OurException {

		String ycsqdSql = "select  ycdw ," + // 用车党委
				"ycsj, " + // 用车时间
				"rs ," + // 人数
				"yt," + // 用途
				"qd," + // 起点

				"mdd," + // 目的地
				"sqbz," + // 申请备注
				"cldqz ," + // 处领导签字
				"qzrq," + // 签字日期
				"jtkjtap," + // 交通科具体安排
				
				"cph," + // 车牌号
				"siji," + // 司机
				"lckss ," + // 里程开始数
				"lcjss ," + // 里程结束数
				"ccrq," + // 出车日期
				
				"ccxs," + // 出车小时
				"ccf," + // 出车分
				"hjrq," + // 回局日期					
				"hjxs," + // 回局小时
				"hjf," + // 回局分
				
				"fhccqk," + // 返回乘车情况
				"remark ," + // 备注				

				"id,  " + // 系统id zx_ycsqd的id,即流程实例id
				"F_UserName  " + //
				"from zx_ycsqd where sfdj=0";
		log.debug(ycsqdSql);
		List srcList = DbUtil.executeQueryList(ycsqdSql);
		if (srcList == null) {
			log.info("没有需要归档的用车申请流程流程记录。");
			return;
		}
		int LEN = srcList.size(); // 需要登记的用车申请流程记录数;

		List needGdList = new ArrayList();
		// =====================判断流程是否结束,然后来决定对哪些记录进行自动登记===========
		for (int i = 0; i < LEN; i++) {
			HashMap map = (HashMap) srcList.get(i);
			String id = (String) map.get("id");
			String tempSql = "select step_closedtype from enrol_flow where process_inst_id='"
					+ id + "' order by id desc";

			List tempList = DbUtil.executeQueryList(tempSql);
			if (tempList == null)
				break;// 跳出循环
			int tempLen = tempList.size();
			// Finished
			boolean tempFlag = false; // 用来判断此流程过程中是否结束,如果有一条记录包含Finished,那么说明此流程已经结束,可以登记了。
			for (int j = 0; j < tempLen; j++) {
				if (((String) ((HashMap) tempList.get(j))
						.get("step_closedtype")).equals("Finished")) {
					tempFlag = true;
					break;
				}
			}
			if (tempFlag)
				needGdList.add(map);
		}

		// =================================================
		LEN = needGdList.size();
		if (LEN < 1) {
			log.info("没有需要归档的用车申请流程记录。");
			return;
		}
		log.debug("需要归档用车申请流程的记录数为:" + LEN + "条。");
		String djSql = "insert into zx_ycsqdj "
				+ "( ycdw, ycsj, rs, yt, qd," +
					" mdd, sqbz, cldqz, qzrq,jtkjtap, " +
					"cph, siji, lckss, lcjss, ccrq, " +
					"ccxs,ccf,hjrq,hjxs,hjf, fhccqk, remark,id,F_UserName,sjgls,gls,jbsj) values (?,?,?,?,?, ?,?,?,?,?, ?,?,?,?,?, ?,?,?,?,? ,?,?,?,?,?,?,?)";
		String sfygdSql = "update zx_ycsqd set sfdj=1 where id =? "; // 更新发文流程中对应的记录数
		
		String ycdw = "";
		String ycsj = "";
		String rs = ""; //整形
		String yt = "";
		String qd = "";

		String mdd = "";
		String sqbz = "";
		String cldqz = "";
		String qzrq = "";
		String jtkjtap = "";

		String cph = "";
		String siji = "";
		
		String lckss = ""; //里程开始数  整型
		String lcjss = ""; //里程结束数 整型
 		String ccrq = "";  //出车日期
		String ccxs = ""; //整型
		String ccf = "";//整型
		
		String hjrq = "";
		String hjxs = "";//整型
		String hjf = "";//整型
		
		String fhccqk = "";
		String remark = "";
	
		String id = "";
		String F_UserName = "";
		
		int sjgls = 0; // 新增加的 实际公里数
		int gls = 0; //经过计算的
		int jbsj = 0 ;//加班时间,单位小时。
		
		
		Connection conn = DbConnection.getConn();
		if (conn == null)
			throw new OurException("获取数据库连接失败!");
		PreparedStatement pst = null;
		PreparedStatement pst2 = null;
		int result = 0;
		int result2 = 0; // 这个sqlserver驱动程序竟然不支持PreparedStatement循环传递参数。

		try {
			conn.setAutoCommit(false);
			pst = conn.prepareStatement(djSql);
			pst2 = conn.prepareStatement(sfygdSql);
			for (int i = 0; i < LEN; i++) {
				HashMap map = (HashMap) needGdList.get(i);
				
				ycdw = (String) map.get("ycdw");
				ycsj = (String) map.get("ycsj");
				rs =  map.get("rs").toString();if(rs==null || rs.equals("") || rs.toLowerCase().equals("null") ) rs ="1";
				yt = (String) map.get("yt"); 
				qd = (String) map.get("qd");

				mdd = (String) map.get("mdd");
				sqbz = (String) map.get("sqbz");
				cldqz = (String) map.get("cldqz");
				qzrq = (String) map.get("qzrq");
				jtkjtap = (String) map.get("jtkjtap");
				
				cph = (String) map.get("cph");
				siji = (String) map.get("siji");
				lckss = map.get("lckss").toString();
				if(lckss==null || lckss.equals("") || lckss.toLowerCase().equals("null") ) lckss ="0";
				lcjss = map.get("lcjss").toString();
				if(lcjss==null || lcjss.equals("") || lcjss.toLowerCase().equals("null") ) lcjss ="0";
				ccrq = map.get("ccrq").toString();
				
				ccxs = map.get("ccxs").toString();
				if(ccxs==null || ccxs.equals("") || ccxs.toLowerCase().equals("null") ) ccxs ="0";
				ccf =  map.get("ccf").toString();	
				if(ccf==null || ccf.equals("") || ccf.toLowerCase().equals("null") ) ccf ="0";
				hjrq = (String) map.get("hjrq");
				hjxs =  map.get("hjxs").toString();
				if(hjxs==null || hjxs.equals("") || hjxs.toLowerCase().equals("null") ) hjxs ="0";
				hjf =  map.get("hjf").toString();
				if(hjf==null || hjf.equals("") || hjf.toLowerCase().equals("null") ) hjf ="0";
				
				fhccqk = (String) map.get("fhccqk");
				remark = (String) map.get("remark");
				
				id = (String) map.get("id");
				F_UserName = (String)map.get("f_username");
//===========================开始计算加班时间=============================================
				int tempFenAm = 0;//用来临时记住上午的分钟数;
				int tempFenPm =0;//用来临时记住下午的分钟数;
				//首先计算实际公里数、公里数
				sjgls = Integer.parseInt(lcjss)-Integer.parseInt(lckss);
				if(sjgls<30) gls = 30;  //如果不足30按照30公里计算
				//然后开始计算加班时间。
				//1、如果当前返回的。即回局日期和出车日期相同的。上午8点之前视为加班,下午4:30之后的是为加班,
				//将加班时间相加,然后精确到小时,不足30分钟的四舍五入掉。
				if(hjrq.equals(ccrq)){
					if(DateUtil.getDayOfWeek(ccrq)==1 || DateUtil.getDayOfWeek(ccrq)==7){
						//说明当天为星期天或者星期六,加班时间为8小时。
						jbsj = 8;
					}else{
						//当前返回,如果出车时间的小时数小于8,说明上午加班了。
						if(Integer.parseInt(ccxs)<8){
							tempFenAm = 8*60 - Integer.parseInt(ccxs)*60 - Integer.parseInt(ccf); //直接计算多少分钟;
						}
						//如果回局分钟数大于30 ,回局小时数大于等于16,说明下午加班了。
						if(Integer.parseInt(hjf)>30 && Integer.parseInt(hjxs)>=16){
							tempFenPm = Integer.parseInt(hjxs)*60+Integer.parseInt(hjf) -(14*60+30);
						}
						//总的分钟数为
						int sumFen = tempFenAm + tempFenPm ;
						jbsj = dtJbsj(sumFen);						
					}
				}else if(hjrq.compareTo(ccrq)>0){ //回局日期要大于出车日期
				
				//2、对于不能当天返回的,正常上班视为出差,不论一天开多少小时的车都不计入加班。
				//但是出差期间的休息日(周六周日等假日)计入加班,每天按8小时算。
					//实现方式,计算这两天之间有多少个星期六星期天,总数乘以8即可。					
					jbsj = DateUtil.countWeekend(hjrq,ccrq)*8;
					
					
				}else{
					log.info("警告!回局日期小于出车日期,本条用车申请流程填写出错了。");
				}
//===========================计算加班时间结束===========================================				
				
				pst.setString(1, ycdw);
				pst.setString(2, ycsj);
				pst.setInt(3, Integer.parseInt(rs));
				pst.setString(4, yt);
				pst.setString(5, qd);

				pst.setString(6, mdd);
				pst.setString(7, sqbz);
				pst.setString(8, cldqz);
				pst.setString(9, qzrq);
				pst.setString(10, jtkjtap);
				
				pst.setString(11, cph);
				pst.setString(12, siji);
				pst.setInt(13, Integer.parseInt(lckss));	
				pst.setInt(14, Integer.parseInt(lcjss));
				pst.setString(15, ccrq);
				
				pst.setInt(16, Integer.parseInt(ccxs));
				pst.setInt(17, Integer.parseInt(ccf));
				pst.setString(18, hjrq);
				pst.setInt(19, Integer.parseInt(hjxs));
				pst.setInt(20, Integer.parseInt(hjf));
				
				pst.setString(21, fhccqk);
				pst.setString(22, remark);
				pst.setString(23, id);
				pst.setString(24,F_UserName);
				pst.setInt(25, sjgls);
				
				pst.setInt(26, gls);
				pst.setInt(27, jbsj);
				
				
				pst2.setString(1, id);
				result += pst.executeUpdate();
				result2 += pst2.executeUpdate();
				// 将已经归档的zx_ycsqd中对应的记录设置sfdj为1
			}

			conn.commit();
			log.debug("共" + result + "条用车申请流程记录登记成功!共" + result2
					+ "条用车申请流程记录设置登记标志成功!");

		} catch (SQLException e) {
			log.error("出现异常!由于登记了" + result + "记录,更新了" + result2
					+ "条记录!所以登记失败!" + "估计是记录数目太多,超出了PreparedStatement的缓存数!");
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			throw new OurException("用车申请流程自动登记执行失败!请通知管理员!", e);

		} finally {
			DbUtil.closeStatement(pst2);
			DbUtil.closeStatement(pst);
			DbUtil.closeConnection(conn);
		}
	}
	/**
	 * 用来计算当天的加班时间。转换为小时,不足30分钟的四舍五入掉。
	 * @param sumFen 计算得出的加班分钟数。
	 * @return
	 */
	private static int dtJbsj(final int sumFen){
		int hour = sumFen/60;
		if((sumFen %60) >30 ){
			hour ++;
		}
		return hour;
	}
	/**
	 * 简单的测试。
	 * @param args
	 */
	public static  void main (String[] args){
		System.out.println(dtJbsj(155)); //3
		System.out.println(dtJbsj(125)); //2
	}
	/* (non-Javadoc)
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
		try {
			ycsqDj();
		} catch (OurException e) {
			System.out.println(com.work.exception.ExceptionUtil
					.getDetailMessage(e));

		}
	}
}
/*
 * b)	公里数,每次出车如果实际公里数小于30公里,则计为30公里;30公里以上的按实际公里数计算。(用于计算加班费)
 * 实际上就是lcjss-lckss  如果小于30 ,那么结果为30,大于30按实际的计算;
 * c)	实际公里数 = 起始公里数 — 回局时公里数
 * d)	加班时间,分两种情况:当天返回的和不能当天返回的
 * i.	对于当天返回的,早上时间在8:00之前的时间视为加班,下午16:30以后的时间视为加班。精确到小时,不足30分钟的四舍五入掉。
 * ccrq ccxs ccf  看看是不是在8点之前。 再看看是不是在16:30之后,然后把加班的时间合起来。
 * ii.	对于不能当天返回的,正常上班视为出差,不论一天开多少小时的车都不计入加班。但是出差期间的休息日(周六周日等假日)计入加班,每天按8小时算。

*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -