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.

399 lines
23 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.attendance.attendanceanalysis.cmd;
import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.entity.BizLogContext;
import com.engine.common.util.DateUtil;
import com.engine.core.interceptor.CommandContext;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import weaver.general.Util;
import java.time.ZoneOffset;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j
public class GetClockInTimeItemCmd extends AbstractCommonCommand<Map<String,Object>> {
public GetClockInTimeItemCmd(Map<String, Object> params){
this.params=params;
}
@Override
public BizLogContext getLogContext() {
return null;
}
@Override
public Map<String, Object> execute(CommandContext commandContext) {
//打卡日期
String needGetDate = Util.null2String(params.get("date"));
//打卡数据
Map<String, List<Map<String,Object>>> clockInTimeCollect = (Map<String, List<Map<String,Object>>>)params.get("clockInTimeCollect");
//班次数据
Map<String, List<Map<String,Object>>> schedulingResultCollect = (Map<String, List<Map<String,Object>>>)params.get("schedulingResultCollect");
Map<String, Object> resultMap = Maps.newHashMap();
List<Map<String, Object>> resultList = Lists.newArrayList();
//当天打卡日期集合
List<Map<String,Object>> needGetDateList = clockInTimeCollect.get(needGetDate);
//当天班次
List<Map<String,Object>> needGetDateScheduling = schedulingResultCollect.get(needGetDate);
//前一天的打卡集合
List<Map<String,Object>> beforeNeedGetDateList = clockInTimeCollect.get(DateUtil.beforeDay(needGetDate,1));
//前一天班次
List<Map<String,Object>> beforeNeedGetDateScheduling = schedulingResultCollect.get(DateUtil.beforeDay(needGetDate,1));
//后一天的打卡集合
List<Map<String,Object>> afterNeedGetDateList = clockInTimeCollect.get(DateUtil.AfterDay(needGetDate,1));
//后一天班次
List<Map<String,Object>> afterNeedGetDateScheduling = schedulingResultCollect.get(DateUtil.AfterDay(needGetDate,1));
if (needGetDateList == null || needGetDateScheduling== null){
return resultMap;
}else if (beforeNeedGetDateList == null && afterNeedGetDateList == null ){
resultList = needGetDateList;
}else if (beforeNeedGetDateList != null && afterNeedGetDateList == null){//前一天有打卡数据,后一天没有打卡数据
if (beforeNeedGetDateScheduling == null){
resultMap.put("resultList",needGetDateList);
return resultMap;
}
resultList=computeStartTime(beforeNeedGetDateScheduling,beforeNeedGetDateList,needGetDateScheduling,needGetDateList,needGetDate);
}else if (beforeNeedGetDateList == null && afterNeedGetDateList != null){ //前一天没有打卡数据,后一天有打卡数据
if (afterNeedGetDateScheduling == null){
resultMap.put("resultList",needGetDateList);
return resultMap;
}
resultList=computeEndTime(afterNeedGetDateScheduling,afterNeedGetDateList,needGetDateScheduling,needGetDateList,needGetDate);
}else if (beforeNeedGetDateList !=null && afterNeedGetDateList != null){
//前后一天都有打卡数据
if (beforeNeedGetDateScheduling == null && afterNeedGetDateScheduling ==null){
resultList = needGetDateList;
}else if (beforeNeedGetDateScheduling != null && afterNeedGetDateScheduling ==null){
resultList=computeStartTime(beforeNeedGetDateScheduling,beforeNeedGetDateList,needGetDateScheduling,needGetDateList,needGetDate);
}else if (beforeNeedGetDateScheduling == null && afterNeedGetDateScheduling != null){
resultList=computeEndTime(afterNeedGetDateScheduling,afterNeedGetDateList,needGetDateScheduling,needGetDateList,needGetDate);
}else if (beforeNeedGetDateScheduling != null && afterNeedGetDateScheduling != null){
resultList=computeStartTime(beforeNeedGetDateScheduling,beforeNeedGetDateList,needGetDateScheduling,needGetDateList,needGetDate);
resultList=computeEndTime(afterNeedGetDateScheduling,afterNeedGetDateList,needGetDateScheduling,resultList,needGetDate);
}
}
resultList = resultList.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.get("signdate")+" "+e.get("signtime")).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
log.info("needGetDate : [{}],resultList : [{}]",needGetDate,resultList);
resultMap.put("resultList",resultList);
return resultMap;
}
/**
*
* 计算当天的开始工作时间
* @param beforeNeedGetDateScheduling 前一天班次
* @param beforeNeedGetDateList 前一天打卡数据集合
* @param needGetDateScheduling 当天班次
* @param needGetDateList 当天打卡数据集合
* @return
*/
public List<Map<String,Object>> computeStartTime(List<Map<String,Object>> beforeNeedGetDateScheduling,List<Map<String,Object>> beforeNeedGetDateList,
List<Map<String,Object>> needGetDateScheduling,List<Map<String,Object>> needGetDateList,String needGetDate){
//前一天是否跨天 1:跨天
String beforesfkt = Util.null2String(beforeNeedGetDateScheduling.get(0).get("sfkt"));
//当天是否跨天 1跨天
String nowsfkt = Util.null2String(needGetDateScheduling.get(0).get("sfkt"));
if ("1".equals(beforesfkt) && !"1".equals(nowsfkt)){
//前一天跨天,当天没有跨天
//昨天的最晚打卡数据在今天,今天剔除昨天的打卡数据
needGetDateList = computeStartTimeRemove(beforeNeedGetDateScheduling,needGetDateList,needGetDate);
}else if (!"1".equals(beforesfkt) && "1".equals(nowsfkt)){
//前一天没有跨天,当天跨天
//今天的最早打卡数据在昨天,今天的打卡数据里添加昨天的打卡数据
needGetDateList = computeStartTimeAdd(beforeNeedGetDateScheduling,beforeNeedGetDateList,needGetDateScheduling,needGetDateList,needGetDate);
}else if ("1".equals(beforesfkt) && "1".equals(nowsfkt)){
//前一天跨天,当天也跨天
/** 前一天 */
beforeNeedGetDateScheduling = beforeNeedGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("jsdk")))).collect(Collectors.toList());
Map<String,Object> lastDataMap = beforeNeedGetDateScheduling.get(beforeNeedGetDateScheduling.size()-1);
String beforekssj = needGetDate +" "+Util.null2String(lastDataMap.get("dtkssj"));
String beforejssj = needGetDate +" "+Util.null2String(lastDataMap.get("dtjssj"));
/** 当天 */
needGetDateScheduling = needGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("ksdk")))).collect(Collectors.toList());
Map<String,Object> firstDataMap = needGetDateScheduling.get(0);
//判断最早日期是否跨天
String nowkssj = needGetDate +" "+Util.null2String(firstDataMap.get("dtkssj"));
String nowjssj = needGetDate +" "+Util.null2String(firstDataMap.get("dtjssj"));
if (DateUtil.getTime(beforekssj).compareTo(DateUtil.getTime(beforejssj)) > 0 &&
DateUtil.getTime(nowkssj).compareTo(DateUtil.getTime(nowjssj)) > 0){
//前一天的最晚打卡时间在今天,今天的最早打卡时间在昨天
/** 目前没有这种情况,会造成数据混乱,无法判定时间归属哪一天。逻辑待定**/
}else if (DateUtil.getTime(beforekssj).compareTo(DateUtil.getTime(beforejssj)) <= 0 &&
DateUtil.getTime(nowkssj).compareTo(DateUtil.getTime(nowjssj)) > 0){
//今天的最早打卡数据在昨天
needGetDateList = computeStartTimeAdd(beforeNeedGetDateScheduling,beforeNeedGetDateList,needGetDateScheduling,needGetDateList,needGetDate);
}else if (DateUtil.getTime(beforekssj).compareTo(DateUtil.getTime(beforejssj)) > 0 && DateUtil.getTime(nowkssj).compareTo(DateUtil.getTime(nowjssj)) <= 0){
//昨天的最晚打卡数据在今天
needGetDateList = computeStartTimeRemove(beforeNeedGetDateScheduling,needGetDateList,needGetDate);
}
}
return needGetDateList;
}
/***
* 计算当天的结束工作时间
* @param afterNeedGetDateScheduling 后一天排班班次
* @param afterNeedGetDateList 后一天打卡数据
* @param needGetDateScheduling 今天班次
* @param needGetDateList 今天打卡数据
* @param needGetDate 当天日期
* @return
*/
public List<Map<String,Object>> computeEndTime(List<Map<String,Object>> afterNeedGetDateScheduling,List<Map<String,Object>> afterNeedGetDateList,
List<Map<String,Object>> needGetDateScheduling,List<Map<String,Object>> needGetDateList,String needGetDate){
//后一天是否跨天 1:跨天
String aftersfkt = Util.null2String(afterNeedGetDateScheduling.get(0).get("sfkt"));
//当天是否跨天 1跨天
String nowsfkt = Util.null2String(needGetDateScheduling.get(0).get("sfkt"));
if ("1".equals(aftersfkt) && !"1".equals(nowsfkt)){
//后一天跨天,当天没有跨天
//后一天的最早开始时间在今天
needGetDateList = computeEndTimeRemove(afterNeedGetDateScheduling,needGetDateScheduling,needGetDateList,needGetDate);
}else if (!"1".equals(aftersfkt) && "1".equals(nowsfkt)){
//后没有跨天,当天跨天
//今天的最晚打卡数据在后一天,添加今天里面后一天的打卡数据
needGetDateList = computeEndTimeAdd(afterNeedGetDateList,needGetDateScheduling,needGetDateList,needGetDate);
}else if ("1".equals(aftersfkt) && "1".equals(nowsfkt)){
//前后2天都跨天
/** 当天 **/
needGetDateScheduling = needGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("jsdk")))).collect(Collectors.toList());
Map<String,Object> endNeedGetDateSchedule = needGetDateScheduling.get(needGetDateScheduling.size()-1);
//判断最晚打卡时间是否跨天
String nowkssj = needGetDate +" "+Util.null2String(endNeedGetDateSchedule.get("dtkssj"));
String nowjssj = needGetDate +" "+Util.null2String(endNeedGetDateSchedule.get("dtjssj"));
/** 后天 **/
afterNeedGetDateScheduling = afterNeedGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("ksdk")))).collect(Collectors.toList());
Map<String,Object> firstDataMap = afterNeedGetDateScheduling.get(0);
String afterkssj = needGetDate +" "+Util.null2String(firstDataMap.get("dtkssj"));
String afterjssj = needGetDate +" "+Util.null2String(firstDataMap.get("dtjssj"));
if (DateUtil.getTime(afterkssj).compareTo(DateUtil.getTime(afterjssj)) > 0 &&
DateUtil.getTime(nowkssj).compareTo(DateUtil.getTime(nowjssj)) > 0){
//前一天的最晚打卡时间在今天,今天的最早打卡时间在昨天
/** 目前没有这种情况,会造成数据混乱,无法判定时间归属哪一天。逻辑待定**/
}else if (DateUtil.getTime(afterkssj).compareTo(DateUtil.getTime(afterkssj)) <= 0 &&
DateUtil.getTime(nowkssj).compareTo(DateUtil.getTime(nowjssj)) > 0){
//今天的最晚打卡数据在后一天
needGetDateList = computeEndTimeAdd(afterNeedGetDateList,needGetDateScheduling,needGetDateList,needGetDate);
}else if (DateUtil.getTime(afterkssj).compareTo(DateUtil.getTime(afterkssj)) > 0 && DateUtil.getTime(nowkssj).compareTo(DateUtil.getTime(nowjssj)) <= 0){
//后一天的最早开始时间在今天
needGetDateList = computeEndTimeRemove(afterNeedGetDateScheduling,needGetDateScheduling,needGetDateList,needGetDate);
}
}
return needGetDateList;
}
/**
* 后一天的最早开始时间在今天,由于打卡时间以前一天优先,所暂不做任何处理
* @param afterNeedGetDateScheduling
* @param needGetDateScheduling
* @param needGetDateList
* @return
*/
public List<Map<String,Object>> computeEndTimeRemove(List<Map<String,Object>> afterNeedGetDateScheduling,
List<Map<String,Object>> needGetDateScheduling,List<Map<String,Object>> needGetDateList,String needGetDate){
//获得需要打卡的
afterNeedGetDateScheduling = afterNeedGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("ksdk")))).collect(Collectors.toList());
Map<String,Object> firstDataMap = afterNeedGetDateScheduling.get(0);
needGetDateScheduling = needGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("ksdk")))).collect(Collectors.toList());
Map<String,Object> endNeedGetDateSchedule = needGetDateScheduling.get(needGetDateScheduling.size()-1);
//判断最早日期是否跨天
String kssj = needGetDate +" "+Util.null2String(firstDataMap.get("dtkssj"));
String jssj = needGetDate +" "+Util.null2String(firstDataMap.get("dtjssj"));
if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(jssj)) > 0){
//最早打卡日期跨天
}
return needGetDateList;
}
/**
* 今天的最晚打卡数据在后一天,添加后一天的打卡数据
* @param afterNeedGetDateList
* @param needGetDateScheduling
* @param needGetDateList
* @param needGetDate
* @return
*/
public List<Map<String,Object>> computeEndTimeAdd(List<Map<String,Object>> afterNeedGetDateList,
List<Map<String,Object>> needGetDateScheduling,List<Map<String,Object>> needGetDateList,String needGetDate){
needGetDateScheduling = needGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("jsdk")))).collect(Collectors.toList());
Map<String,Object> endNeedGetDateSchedule = needGetDateScheduling.get(needGetDateScheduling.size()-1);
//判断最晚打卡时间是否跨天
String kssj = needGetDate +" "+Util.null2String(endNeedGetDateSchedule.get("dtkssj"));
String jssj = needGetDate +" "+Util.null2String(endNeedGetDateSchedule.get("dtjssj"));
if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(jssj)) > 0){
//结束时间
jssj = DateUtil.AfterDay(needGetDate,1) +" "+endNeedGetDateSchedule.get("dtjssj");
//推后打卡分钟数
long thdkfzs = Util.null2String(endNeedGetDateSchedule.get("thdkfzs")).equals("") ? 0:Long.valueOf(Util.null2String(endNeedGetDateSchedule.get("thdkfzs")));
String latestTime = DateUtil.AfterMinutes(jssj,thdkfzs);
for (int i=afterNeedGetDateList.size()-1;i>=0;i--){
//前一天的打卡数据集合里在当天最早打卡日期之后的都属于当天
String dateTime = afterNeedGetDateList.get(i).get("signdate")+" "+afterNeedGetDateList.get(i).get("signtime");
if (DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dateTime)) >=0){
needGetDateList.add(afterNeedGetDateList.get(i));
}
if (DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dateTime)) <0 &&
DateUtil.getTime(latestTime).compareTo(DateUtil.getTime(dateTime)) >=0){
needGetDateList.add(afterNeedGetDateList.get(i));
break;
}
}
//排序
// needGetDateList = needGetDateList.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.get("signdate")+" "+e.get("signtime")).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
}
return needGetDateList;
}
/**
* 计算当天开始时间,昨天的最晚打卡数据在今天,今天的打卡数据剔除昨天的打卡数据
* @param beforeNeedGetDateScheduling
* @param needGetDateList
* @param needGetDate
* @return
*/
public List<Map<String,Object>> computeStartTimeRemove(List<Map<String,Object>> beforeNeedGetDateScheduling,List<Map<String,Object>> needGetDateList,String needGetDate){
//获得需要打卡的
beforeNeedGetDateScheduling = beforeNeedGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("jsdk")))).collect(Collectors.toList());
Map<String,Object> lastDataMap = beforeNeedGetDateScheduling.get(beforeNeedGetDateScheduling.size()-1);
String kssj = needGetDate +" "+Util.null2String(lastDataMap.get("dtkssj"));
String jssj = needGetDate +" "+Util.null2String(lastDataMap.get("dtjssj"));
List<Map<String,Object>> resultList = Lists.newArrayList();
//昨天的最晚打卡数据在今天
if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(jssj)) > 0){
//最后打卡日期跨天
jssj = needGetDate +" "+lastDataMap.get("dtjssj");
//最大打卡时间
long thdkfzs = Util.null2String(lastDataMap.get("thdkfzs")).equals("") ? 0:Long.valueOf(Util.null2String(lastDataMap.get("thdkfzs")));
String mostTime = DateUtil.AfterMinutes(jssj,thdkfzs);
for (Map<String,Object> date : needGetDateList){
//前一天最后打卡日期之前的打卡数据都归属前一天,进行过滤
String dateTime = date.get("signdate")+" "+date.get("signtime");
if (DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dateTime)) <=0){
resultList.add(date);
}
}
Map<String,Object> resultMap = resultList.stream().min(Comparator.comparing(e->DateUtil.getTime(e.get("signdate")+" "+e.get("signtime")).toInstant(ZoneOffset.of("+8")).toEpochMilli())).get();
String minTime = resultMap.get("signdate")+" "+resultMap.get("signtime");
if (DateUtil.getTime(mostTime).compareTo(DateUtil.getTime(minTime)) >=0){
//当天第一比时间在,最后打卡日期之后,最长延迟打卡时间之前的,归属前一天
resultList.remove(resultMap);
}
needGetDateList = resultList;
}
return needGetDateList;
}
/**
* 计算当天开始时间,今天的最早打卡数据在昨天,往今天的打卡数据里添加昨天的打卡数据
* @param beforeNeedGetDateList
* @param needGetDateScheduling
* @param needGetDateList
* @param needGetDate
* @return
*/
public List<Map<String,Object>> computeStartTimeAdd(List<Map<String,Object>> beforeNeedGetDateScheduling,List<Map<String,Object>> beforeNeedGetDateList,
List<Map<String,Object>> needGetDateScheduling,List<Map<String,Object>> needGetDateList,String needGetDate){
//获得需要打卡的
needGetDateScheduling = needGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("ksdk")))).collect(Collectors.toList());
Map<String,Object> firstDataMap = needGetDateScheduling.get(0);
beforeNeedGetDateScheduling = beforeNeedGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("jsdk")))).collect(Collectors.toList());
Map<String,Object> lastDataMap = beforeNeedGetDateScheduling.get(beforeNeedGetDateScheduling.size()-1);
//判断最早日期是否跨天
String kssj = needGetDate +" "+Util.null2String(firstDataMap.get("dtkssj"));
String jssj = needGetDate +" "+Util.null2String(firstDataMap.get("dtjssj"));
//今天的最早打卡数据在昨天
if(DateUtil.getTime(kssj).compareTo(DateUtil.getTime(jssj)) > 0){
//最早打卡日期
kssj = DateUtil.beforeDay(needGetDate,1) +" "+firstDataMap.get("dtkssj");
//最早打卡时间
long tqdkfzs = Util.null2String(firstDataMap.get("tqdkfzs")).equals("") ? 0:Long.valueOf(Util.null2String(firstDataMap.get("tqdkfzs")));
String earliestTime = DateUtil.beforeMinutes(kssj,tqdkfzs);
//前一天最晚打卡日期
String beforejssj = DateUtil.beforeDay(needGetDate,1) + " "+Util.null2String(lastDataMap.get("dtjssj"));
//前一天最晚延迟打卡日期
long beforethdkfzs = Util.null2String(firstDataMap.get("thdkfzs")).equals("") ? 0:Long.valueOf(Util.null2String(firstDataMap.get("thdkfzs")));
String lastestTime = DateUtil.AfterMinutes(jssj,beforethdkfzs);
List<Map<String,Object>> beforeleaveDate = Lists.newArrayList();
for (Map<String,Object> map : beforeNeedGetDateList){
String dateTime = map.get("signdate")+" "+map.get("signtime");
if (DateUtil.getTime(beforejssj).compareTo(DateUtil.getTime(dateTime)) <=0){
beforeleaveDate.add(map);
}
}
if (beforeleaveDate.size() > 0){
String dateTime = beforeleaveDate.get(0).get("signdate")+" "+beforeleaveDate.get(0).get("signtime");
if (DateUtil.getTime(beforejssj).compareTo(DateUtil.getTime(dateTime)) <=0 && DateUtil.getTime(lastestTime).compareTo(DateUtil.getTime(dateTime)) >=0){
beforeleaveDate.remove(0);
}
}
for (int i=beforeleaveDate.size()-1;i>=0;i--){
//前一天的打卡数据集合里在当天最早打卡日期之后的都属于当天
String dateTime = beforeNeedGetDateList.get(i).get("signdate")+" "+beforeNeedGetDateList.get(i).get("signtime");
if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dateTime)) <=0){
needGetDateList.add(beforeNeedGetDateList.get(i));
}
if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dateTime)) >0 &&
DateUtil.getTime(earliestTime).compareTo(DateUtil.getTime(dateTime)) <=0){
//取前一天
needGetDateList.add(beforeNeedGetDateList.get(i));
break;
}
}
//排序
// needGetDateList = needGetDateList.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.get("signdate")+" "+e.get("signtime")).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
}
return needGetDateList;
}
}