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> { public GetClockInTimeItemCmd(Map params){ this.params=params; } @Override public BizLogContext getLogContext() { return null; } @Override public Map execute(CommandContext commandContext) { //打卡日期 String needGetDate = Util.null2String(params.get("date")); //打卡数据 Map>> clockInTimeCollect = (Map>>)params.get("clockInTimeCollect"); //班次数据 Map>> schedulingResultCollect = (Map>>)params.get("schedulingResultCollect"); Map resultMap = Maps.newHashMap(); List> resultList = Lists.newArrayList(); //当天打卡日期集合 List> needGetDateList = clockInTimeCollect.get(needGetDate); //当天班次 List> needGetDateScheduling = schedulingResultCollect.get(needGetDate); //前一天的打卡集合 List> beforeNeedGetDateList = clockInTimeCollect.get(DateUtil.beforeDay(needGetDate,1)); //前一天班次 List> beforeNeedGetDateScheduling = schedulingResultCollect.get(DateUtil.beforeDay(needGetDate,1)); //后一天的打卡集合 List> afterNeedGetDateList = clockInTimeCollect.get(DateUtil.AfterDay(needGetDate,1)); //后一天班次 List> 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> computeStartTime(List> beforeNeedGetDateScheduling,List> beforeNeedGetDateList, List> needGetDateScheduling,List> 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 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 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> computeEndTime(List> afterNeedGetDateScheduling,List> afterNeedGetDateList, List> needGetDateScheduling,List> 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 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 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> computeEndTimeRemove(List> afterNeedGetDateScheduling, List> needGetDateScheduling,List> needGetDateList,String needGetDate){ //获得需要打卡的 afterNeedGetDateScheduling = afterNeedGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("ksdk")))).collect(Collectors.toList()); Map firstDataMap = afterNeedGetDateScheduling.get(0); needGetDateScheduling = needGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("ksdk")))).collect(Collectors.toList()); Map 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> computeEndTimeAdd(List> afterNeedGetDateList, List> needGetDateScheduling,List> needGetDateList,String needGetDate){ needGetDateScheduling = needGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("jsdk")))).collect(Collectors.toList()); Map 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> computeStartTimeRemove(List> beforeNeedGetDateScheduling,List> needGetDateList,String needGetDate){ //获得需要打卡的 beforeNeedGetDateScheduling = beforeNeedGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("jsdk")))).collect(Collectors.toList()); Map lastDataMap = beforeNeedGetDateScheduling.get(beforeNeedGetDateScheduling.size()-1); String kssj = needGetDate +" "+Util.null2String(lastDataMap.get("dtkssj")); String jssj = needGetDate +" "+Util.null2String(lastDataMap.get("dtjssj")); List> 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 date : needGetDateList){ //前一天最后打卡日期之前的打卡数据都归属前一天,进行过滤 String dateTime = date.get("signdate")+" "+date.get("signtime"); if (DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dateTime)) <=0){ resultList.add(date); } } Map 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> computeStartTimeAdd(List> beforeNeedGetDateScheduling,List> beforeNeedGetDateList, List> needGetDateScheduling,List> needGetDateList,String needGetDate){ //获得需要打卡的 needGetDateScheduling = needGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("ksdk")))).collect(Collectors.toList()); Map firstDataMap = needGetDateScheduling.get(0); beforeNeedGetDateScheduling = beforeNeedGetDateScheduling.stream().filter(e -> "1".equals(Util.null2String(e.get("jsdk")))).collect(Collectors.toList()); Map 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> beforeleaveDate = Lists.newArrayList(); for (Map 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; } }