You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
weaver-ningbojinghua/src/com/engine/kq/job/SynClockInTimeJob.java

428 lines
18 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.engine.kq.job;
import com.alibaba.fastjson.JSON;
import com.engine.kq.biz.KQShiftOnOffWorkSectionComInfo;
import com.engine.kq.biz.KQShiftRestTimeSectionComInfo;
import com.engine.kq.biz.KQWorkTime;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import weaver.common.DateUtil;
import weaver.conn.RecordSet;
import weaver.general.TimeUtil;
import weaver.general.Util;
import weaver.interfaces.schedule.BaseCronJob;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
/**
* @Title
* @Author wangchaofa
* @CreateDate 2024/1/7
* @Version 1.0
* @Description
*/
public class SynClockInTimeJob extends BaseCronJob {
/**
* 日期时间格式化
*/
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
@Override
public void execute() {
RecordSet rs = new RecordSet();
rs.writeLog("----------- start to syn overtime work card time ------------");
String currentdate = TimeUtil.getCurrentDateString();
String currenttime = TimeUtil.getOnlyCurrentTimeString();
String currentdatetime = currentdate+" "+currenttime;
String lastdate = addDateDay(currentdate,-50);
String lastdatetime = lastdate+" "+currenttime;
try{
RecordSet rs1 = new RecordSet();
rs.executeQuery("select * from uf_jbtz where ksrq>=? and jsrq<=?",lastdate,currentdate);
while(rs.next()){
String mainid = Util.null2String(rs.getString("id"));
String userid = Util.null2String(rs.getString("jbr"));
String ksrq = Util.null2String(rs.getString("ksrq"));
String kssj = Util.null2String(rs.getString("kssj"));
String jsrq = Util.null2String(rs.getString("jsrq"));
String jssj = Util.null2String(rs.getString("jssj"));
String starttime = ksrq+" "+kssj+":00";
String endtime = jsrq+" "+jssj+":00";
String beforetwohours_starttime = addDateHour(starttime,-2);
String aftertwohours_endtime = addDateHour(endtime,2);
String earlystarttime = getEarlyStartTime(beforetwohours_starttime,starttime,ksrq,userid);
String afterendtime = getAfterEndTime(endtime,aftertwohours_endtime,jsrq,userid);
boolean bool = rs1.executeUpdate("update uf_jbtz set zzdksj=?,zwdkrq=? where id=?",earlystarttime,afterendtime,mainid);
if(bool){
rs.writeLog(userid+ " ------------ "+ kssj +" ------------ "+ jsrq +" ---------- "+ bool);
// 计算有效时长
rs.writeLog("计算有效时长开始");
String gzrq = Util.null2String(rs.getString("gzrq"));
updateEffectiveDuration(mainid, userid, gzrq, earlystarttime, afterendtime);
rs.writeLog("计算有效时长结束");
}
}
}catch(Exception e){
e.printStackTrace();
rs.writeLog("---------- syn overtime work card time error ---------- "+ e);
}
rs.writeLog("---------- end to syn overtime work card time ----------");
}
/**
* 更新加班台账表,有效时长字段
* <p/>
* <p>导入的加班数据增加根据班次的最早最晚打卡时间取交集,按照系统的加班单和打卡数据取交集处理</p>
*
* @param mainId 当前数据ID
* @param userId 加班人ID
* @param gzrq 归属日志
* @param earlyStartTime 最早打卡时间
* @param afterEndTime 最晚打卡时间
*/
private void updateEffectiveDuration(String mainId, String userId, String gzrq, String earlyStartTime, String afterEndTime) {
RecordSet recordSet = new RecordSet();
try {
KQWorkTime kqWorkTime = new KQWorkTime();
Map<String, Object> serialInfo = kqWorkTime.getSerialInfo(userId, gzrq, false, true);
recordSet.writeLog("userId==" + userId + ",serialInfo===" + JSON.toJSONString(serialInfo));
String serialId = Util.null2String(serialInfo.get(gzrq));
List<Object> workSectionTimes = new KQShiftOnOffWorkSectionComInfo().getWorkSectionTimes(serialId);
recordSet.writeLog("userId==" + userId + ",workSectionTimes===" + JSON.toJSONString(workSectionTimes));
// 转换所有的工作时间
List<Map<String, String>> workTimeList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(workSectionTimes)) {
convertDateTime(gzrq, workSectionTimes, workTimeList);
recordSet.writeLog("userId==" + userId + ",workTimeList===" + JSON.toJSONString(workTimeList));
}
// 转换所有的休息时间
List<Object> restSectionTimes = new KQShiftRestTimeSectionComInfo().getRestSectionTimes(serialId);
recordSet.writeLog("userId==" + userId + ",restSectionTimes===" + JSON.toJSONString(restSectionTimes));
List<Map<String, String>> restTimeList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(restSectionTimes)) {
convertDateTime(gzrq, restSectionTimes, restTimeList);
recordSet.writeLog("userId==" + userId + ",restTimeList===" + JSON.toJSONString(restTimeList));
}
// 所有的有效时间区间
List<String> effectiveTime = getEffectiveTime(earlyStartTime, afterEndTime, workTimeList, restTimeList);
recordSet.writeLog("userId==" + userId + ",effectiveTime===" + JSON.toJSONString(effectiveTime));
// 有效区间总计分钟数
long totalMinutes = effectiveTime.stream()
.mapToInt(interval -> {
String[] parts = interval.split(",");
LocalDateTime start = LocalDateTime.parse(parts[0], DATE_TIME_FORMATTER);
LocalDateTime end = LocalDateTime.parse(parts[1], DATE_TIME_FORMATTER);
return (int) (start.until(end, ChronoUnit.MINUTES));
})
.sum();
double totalHours = (double) totalMinutes / 60;
// 将小时数按照0.5小时的单位向下取整
double roundedHours = (int) Math.floor(totalHours / 0.5) * 0.5;
recordSet.writeLog("userId==" + userId + ",totalMinutes===" + totalMinutes + ",totalHours==" + totalHours + ",roundedHours==" + roundedHours);
// 更新当前数据的有效时长
recordSet.executeUpdate("update uf_jbtz set yxsc=? where id=? ", roundedHours, mainId);
} catch (Exception e) {
recordSet.writeLog(e);
}
}
/**
* 获取有效时长时间区间
*
* @param earlyStartTime 最早打卡时间
* @param afterEndTime 最晚打卡时间
* @param workTimeList 工作时间集合
* @param restTimeList 休息时间集合
* @return
*/
private List<String> getEffectiveTime(String earlyStartTime, String afterEndTime, List<Map<String, String>> workTimeList, List<Map<String, String>> restTimeList) {
// 打卡时间区间,去除所有的休息时间
List<String> effectiveTimeList = new ArrayList<>();
LocalDateTime startSignTime = LocalDateTime.parse(earlyStartTime, DATE_TIME_FORMATTER);
LocalDateTime endSignTime = LocalDateTime.parse(afterEndTime, DATE_TIME_FORMATTER);
for (Map<String, String> workTimeMap : workTimeList) {
LocalDateTime startWorkTime = LocalDateTime.parse(workTimeMap.get("startTimes"), DATE_TIME_FORMATTER);
LocalDateTime endWorkTime = LocalDateTime.parse(workTimeMap.get("endTimes"), DATE_TIME_FORMATTER);
// 计算交集
LocalDateTime intersectionStart = startSignTime.isAfter(startWorkTime) ? startSignTime : startWorkTime;
LocalDateTime intersectionEnd = endSignTime.isBefore(endWorkTime) ? endSignTime : endWorkTime;
if (intersectionStart.isBefore(intersectionEnd)) {
// 去除休息时间
for (Map<String, String> restTimeMap : restTimeList) {
LocalDateTime startRestTime = LocalDateTime.parse(restTimeMap.get("startTimes"), DATE_TIME_FORMATTER);
LocalDateTime endRestTime = LocalDateTime.parse(restTimeMap.get("endTimes"), DATE_TIME_FORMATTER);
if (!intersectionEnd.isBefore(startRestTime) && !intersectionStart.isAfter(endRestTime)) {
if (intersectionStart.isBefore(startRestTime)) {
// 交集在休息时间之前
intersectionEnd = intersectionEnd.isBefore(startRestTime) ? intersectionEnd : startRestTime;
} else if (intersectionEnd.isAfter(endRestTime)) {
// 交集在休息时间之后
intersectionStart = intersectionStart.isAfter(endRestTime) ? intersectionStart : endRestTime;
} else {
// 休息时间在交集中间
intersectionStart = startRestTime;
intersectionEnd = endRestTime;
}
}
}
effectiveTimeList.add(intersectionStart.format(DATE_TIME_FORMATTER) + "," + intersectionEnd.format(DATE_TIME_FORMATTER));
}
}
return effectiveTimeList;
}
/**
* 转换日期时间
*
* @param gzrq 归属日期
* @param sectionTimes 转换前时间
* @param timeList 转换后日期时间
*/
private void convertDateTime(String gzrq, List<Object> sectionTimes, List<Map<String, String>> timeList) {
String currentDate = gzrq;
String preTime = "";
for (Object sectionTime : sectionTimes) {
List<Map<String, String>> sectionTime1 = (List) sectionTime;
if (sectionTime1.size() != 2) {
break;
}
// 获取当前的打卡时间
Map<String, String> startMap = sectionTime1.get(0);
String startTimes = startMap.get("times");
Map<String, String> map = new HashMap<>();
currentDate = getDateStr(currentDate, preTime, startTimes);
map.put("startTimes", currentDate + " " + startTimes);
Map<String, String> endMap = sectionTime1.get(1);
String endTimes = endMap.get("times");
currentDate = getDateStr(currentDate, startTimes, endTimes);
map.put("endTimes", currentDate + " " + endTimes);
preTime = endTimes;
timeList.add(map);
}
}
/**
* 组合日期、时间
*
* @param currentDate 当前日期
* @param preTime 之前处理的时间
* @param currentTime 当前需要处理的时间
* @return
*/
private String getDateStr(String currentDate, String preTime, String currentTime) {
// 前一个时间为空,返回当前日期+当前时间
if (StringUtils.isBlank(preTime)) {
return currentDate;
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
LocalTime localPreTime = LocalTime.parse(preTime, formatter);
LocalTime localCurrentTime = LocalTime.parse(currentTime, formatter);
if (localPreTime.isAfter(localCurrentTime)) {
return DateUtil.addDate(currentDate, 1);
} else {
return currentDate;
}
}
/**
* 获取 最早开始日期时间
* @param beforetwohours_starttime
* @param starttime
* @param ksrq
* @param userid
* @return
*/
public static String getEarlyStartTime(String beforetwohours_starttime,String starttime,String ksrq,String userid){
String result = "";
RecordSet rs = new RecordSet();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
List<Date> list = new ArrayList<>();
try {
rs.executeQuery("select a.*,b.subcompanyId1,b.departmentId,b.jobtitle,b.workcode " +
" from HrmScheduleSign a,HrmResource b " +
" where a.userId=b.id and (signfrom is null or signfrom='' or signfrom not like 'card%') " +
" and (signDate is not null and signDate>='"+ ksrq +"') " +
" and (signDate is not null and signDate<='"+ ksrq +"') " +
" and (loginId is not null and loginId<>'') " +
" and signType=1 "+
" and (b.status = 0 or b.status = 1 or b.status = 2 or b.status = 3)" +
" and userId in ("+ userid +")" +
" order by signDate,signTime");
while (rs.next()) {
String signDate = Util.null2String(rs.getString("signDate"));
String signTime = Util.null2String(rs.getString("signTime"));
String signdatetime = signDate + " " + signTime;
boolean bool = belongCalendar(signdatetime, beforetwohours_starttime, starttime);
if (bool) {
list.add(format.parse(signdatetime));
}
}
if(list.size()>0){
if(list.size()>1){
result = format.format(Collections.min(list));
}else{
result = format.format(list.get(0));
}
}
}catch (Exception e){
e.printStackTrace();
}
return result;
}
/**
* 获取 最晚结束日期时间
* @param endtime
* @param aftertwohours_endtime
* @param jsrq
* @param userid
* @return
*/
public static String getAfterEndTime(String endtime,String aftertwohours_endtime,String jsrq,String userid){
String result = "";
RecordSet rs = new RecordSet();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
List<Date> list = new ArrayList<>();
try {
rs.executeQuery("select a.*,b.subcompanyId1,b.departmentId,b.jobtitle,b.workcode " +
" from HrmScheduleSign a,HrmResource b " +
" where a.userId=b.id and (signfrom is null or signfrom='' or signfrom not like 'card%') " +
" and (signDate is not null and signDate>='"+ jsrq +"') " +
" and (signDate is not null and signDate<='"+ jsrq +"') " +
" and (loginId is not null and loginId<>'') " +
" and signType=1 "+
" and (b.status = 0 or b.status = 1 or b.status = 2 or b.status = 3)" +
" and userId in ("+ userid +")" +
" order by signDate,signTime");
while (rs.next()) {
String signDate = Util.null2String(rs.getString("signDate"));
String signTime = Util.null2String(rs.getString("signTime"));
String signdatetime = signDate + " " + signTime;
boolean bool = belongCalendar(signdatetime, endtime, aftertwohours_endtime);
if (bool) {
list.add(format.parse(signdatetime));
}
}
if(list.size()>0){
if(list.size()>1){
result = format.format(Collections.max(list));
}else{
result = format.format(list.get(0));
}
}
}catch (Exception e){
e.printStackTrace();
}
return result;
}
/**
* 判断一个时间是否在一个时间段内
*
* @param nowString 当前时间
* @param beginString 开始时间
* @param endString 结束时间
*/
public static boolean belongCalendar(String nowString, String beginString, String endString) {
boolean b = false;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date nowTime = format.parse(nowString);
Calendar date = Calendar.getInstance();
date.setTime(nowTime);
Date beginTime = format.parse(beginString);
Calendar begin = Calendar.getInstance();
begin.setTime(beginTime);
Date endTime = format.parse(endString);
Calendar end = Calendar.getInstance();
end.setTime(endTime);
if (date.after(begin) && date.before(end)) {//在时间段内
b = true;
}
}catch (Exception e){
e.printStackTrace();
}
return b;
}
/**
* 对时间的天数进行加减
* @param daytime 时间的格式yyyy-MM-dd
* @param day 天数 -1则代表减一天
* @return
*/
public static String addDateDay(String daytime, int day){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = format.parse(daytime);
if (date == null){
return "";
}
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DAY_OF_MONTH, day);// 加一天
date = cal.getTime();
cal = null;
return format.format(date);
} catch (Exception ex) {
ex.printStackTrace();
}
return "";
}
/**
* 给时间加上几个小时
* @param day 时间的格式yyyy-MM-dd HH:mm:ss
* @param hour 需要加的小时数 -1 则代表减1小时
* @return
*/
public static String addDateHour(String day, int hour){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try {
date = format.parse(day);
if (date == null){
return "";
}
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.HOUR, hour);// 24小时制
date = cal.getTime();
cal = null;
return format.format(date);
} catch (Exception ex) {
ex.printStackTrace();
}
return "";
}
}