package com.engine.jucailinkq.attendance.workflow.action; import com.engine.jucailinkq.attendance.attendanceanalysis.service.UtilService; import com.engine.jucailinkq.attendance.attendanceanalysis.service.impl.UtilServiceImpl; import com.engine.jucailinkq.attendance.component.persongroup.commonutil.PersongroupCommonUtil; import com.engine.jucailinkq.attendance.enums.*; import com.engine.jucailinkq.attendance.workflow.service.MakeUpClockInService; import com.engine.jucailinkq.attendance.workflow.service.impl.MakeUpClockInServiceImpl; import com.engine.jucailinkq.common.util.*; import com.engine.common.util.ServiceUtil; import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; import weaver.general.TimeUtil; import weaver.general.Util; import weaver.interfaces.workflow.action.Action; import weaver.soa.workflow.request.RequestInfo; import java.time.ZoneOffset; import java.util.*; import java.util.stream.Collectors; /** * 加班计划流程提交检查 */ @Slf4j public class OvertimePlanCheckAction implements Action { private MakeUpClockInService makeUpClockInService = ServiceUtil.getService(MakeUpClockInServiceImpl.class); private UtilService utilService = ServiceUtil.getService(UtilServiceImpl.class); @Override public String execute(RequestInfo requestInfo) { String requestid = requestInfo.getRequestid(); // 流程表单主表数据 HashMap mainTableData = CommonUtil.getMainTableInfo(requestInfo); // 流程表单明细表数据 List> detailTableData = CommonUtil.getDetailTableInfo(requestInfo,0); log.info("OvertimePlanCheckAction_start, detailTableData_size : {}",detailTableData.size()); log.info("detailTableData : [{}]", detailTableData); //加班人员 // String jbry = mainTableData.get("jbry"); String mainStartDate = Util.null2String(mainTableData.get("ksrq")); String mainEndDate = Util.null2String(mainTableData.get("jsrq")); try { List startDateList = detailTableData.stream().map(map -> map.get("ksrq")).collect(Collectors.toList()); List endDateList = detailTableData.stream().map(map -> map.get("jsrq")).collect(Collectors.toList()); if (startDateList.size() == 0 || endDateList.size() == 0) { log.error("明细表数据缺少加班起始或者结束日期!"); requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222"); requestInfo.getRequestManager().setMessagecontent("明细表数据缺少加班起始或者结束日期!"); return Action.FAILURE_AND_CONTINUE; } mainStartDate = startDateList.stream().min(Comparator.comparing(e->DateUtil.getTime(e).toInstant(ZoneOffset.of("+8")).toEpochMilli())).get(); mainEndDate = endDateList.stream().max(Comparator.comparing(e->DateUtil.getTime(e).toInstant(ZoneOffset.of("+8")).toEpochMilli())).get(); //获取人员id和姓名信息 // List empIdList = Arrays.asList(jbry.split(",")); List empIdList = detailTableData.stream().map(map -> map.get("jbry")).collect(Collectors.toList()); Map empIdToNameInfo = CommonUtil.empIdToNameInfo(empIdList); //获取作用时段包含计划加班的加班类型的考勤项目集合 String sql = "select id,mc, bddrqlx, jbqsfzs, xzzjbsc, rzdjbxss, zzdjbxss, yzdjbxss, zysd, ccclfs from uf_jcl_kq_kqxm where xmlx = ?"; List> jblxAttendanceList = DbTools.getSqlToList(sql, AttendanceItemTypeEnum.WORK_OVERTIME.getKey()); Map> jblxInfo = jblxAttendanceList.stream() .filter(f -> Util.null2String(f.get("zysd")).contains(WorkForTimeEnum.PLAN_WORK_OVERTIME.getKey())) .collect(Collectors.toMap(e->e.get("id").toString(), e->e)); //获取目标人员列表已存在的加班计划 Map>> existOvertimePlanInfo = getOvertimePlanInfo(empIdList, DateUtil.beforeDay(mainStartDate, 1)); List> existOvertimePlanList = new ArrayList<>(); //获取人员列表在日期区间的班次数据 Map>> scheduleInfoMap = utilService.getScheduleInfoWithEmpId(empIdList, DateUtil.beforeDay(mainStartDate, 1), DateUtil.AfterDay(mainEndDate,1)); List workBdlxList = new ArrayList<>(); workBdlxList.add(ClassSegmentTypeEnum.WORK_TIME.getKey());workBdlxList.add(ClassSegmentTypeEnum.EXTENDED_OVERTIME.getKey()); workBdlxList.add(ClassSegmentTypeEnum.EARLY_OVERTIME.getKey());workBdlxList.add(ClassSegmentTypeEnum.OVERTIME_IN_CLASS.getKey()); //明细数据按照人员分组 Map>> detailGroupMap = detailTableData.stream().collect(Collectors.groupingBy(e->Util.null2String(e.get("jbry")))); List errorMessage = new ArrayList<>(); ExtensionClassHolder.setPersonBelongGroupThreadLocal(PersongroupCommonUtil.getAllpersonBelongGroup()); for (Map.Entry>> tableEntry :detailGroupMap.entrySet()){ List> detailGroupByUserList = tableEntry.getValue(); Map params = Maps.newHashMap(); String empId = tableEntry.getKey(); if ("".equals(empId)){ log.error("明细表中存在缺少加班人员信息的数据!"); requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222"); requestInfo.getRequestManager().setMessagecontent("明细表中存在缺少加班人员信息的数据!"); return Action.FAILURE_AND_CONTINUE; }else { params.put("userId", empId); } params.put("submitDate",DateUtil.getCurrentDate()); params.put("submitStr","ksrq"); params.put("submitDataList",detailGroupByUserList); /** * 考勤周期校验 */ if (detailGroupByUserList == null || detailGroupByUserList.size() == 0){ log.error("明细表没有数据!"); requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222"); requestInfo.getRequestManager().setMessagecontent("明细表没有数据!"); return Action.FAILURE_AND_CONTINUE; } Map dataMap = makeUpClockInService.getKqCycleTimeIntervalCmd(params); List> closeList = (List>)dataMap.get("closeList"); List nocycleList = (List)dataMap.get("nocycleList"); List> dateList = (List>)dataMap.get("dataList"); boolean status = (boolean)dataMap.get("status"); if (!status){ log.error("该人员没有考勤周期"); requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222"); requestInfo.getRequestManager().setMessagecontent("该人员没有考勤周期!"); return Action.FAILURE_AND_CONTINUE; } if (closeList.size() > 0 || nocycleList.size() > 0){ String message = ""; if (nocycleList.size() > 0){ message = message +String.join(",",nocycleList)+"未找对对应的考勤周期;"; } if (closeList.size() > 0){ List list = closeList.stream().map(e->e.get("rq").toString()).collect(Collectors.toList()); message = message +String.join(",",list)+"对应的考勤周期的考勤周期已关账"; } requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222"); requestInfo.getRequestManager().setMessagecontent(message); return Action.FAILURE_AND_CONTINUE; } //获取人员已存在的加班计划信息 existOvertimePlanList = existOvertimePlanInfo.get(empId); //获取该人员的日期与班次id的映射 List> scheduleInfoList = scheduleInfoMap.get(empId); Map dateToBcxxMap = scheduleInfoList == null ? new HashMap<>() : scheduleInfoList.stream().collect(Collectors.toMap(e->Util.null2String(e.get("bcrq")), e->Util.null2String(e.get("bcxx")))); //校验加班类型中最小加班分钟数、工作日最大加班小时数、周最大加班小时数、月最大加班小时数等限定值 List> overtimeDetailList = tableEntry.getValue(); Map matchItemInfo; if (overtimeDetailList == null || overtimeDetailList.size() == 0) { continue; } //校验该组加班明细之间是否有时间重叠情况 if (overtimeDetailList.size() > 1) { boolean overlappingSign; Map targetOvertimeDetail; Map compareOvertimeDetail; String targetStartTime; String targetEndTime; String compareStartTime; String compareEndTime; for (int i = 0; i < overtimeDetailList.size() - 1; i++) { targetOvertimeDetail = overtimeDetailList.get(i); targetStartTime = targetOvertimeDetail.get("ksrq") + " " + targetOvertimeDetail.get("kssj"); targetEndTime = targetOvertimeDetail.get("jsrq") + " " + targetOvertimeDetail.get("jssj"); for (int j = i + 1; j < overtimeDetailList.size(); j++) { compareOvertimeDetail = overtimeDetailList.get(j); compareStartTime = compareOvertimeDetail.get("ksrq") + " " + compareOvertimeDetail.get("kssj"); compareEndTime = compareOvertimeDetail.get("jsrq") + " " + compareOvertimeDetail.get("jssj"); //判断两组时段是否有重叠时段 overlappingSign = DateUtil.isOverlapping(targetStartTime, targetEndTime, compareStartTime, compareEndTime); if (overlappingSign) { String message = Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + targetOvertimeDetail.get("ksrq") + "的加班计划和本次提交的其他加班计划存在时间重叠,不允许申请加班!"; log.error(message); requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222"); requestInfo.getRequestManager().setMessagecontent(message); return Action.FAILURE_AND_CONTINUE; } } } } Map weekOvertimeInfo = new HashMap<>(); Map monthOvertimeInfo = new HashMap<>(); for (Map overtimeDetailItem : overtimeDetailList) { String belongDate = overtimeDetailItem.get("gsrq"); //从排班信息获取归属日日期类型 String belongDateType = utilService.getRqlxInScheduleInfo(empId, belongDate); //排班信息无法获取日期类型时,从日历信息获取 belongDateType = "".equals(belongDateType) ? CommonUtil.getRqlx(empId, belongDate) : belongDateType; //排班和日历都无法获取时,默认为工作日 belongDateType = "".equals(belongDateType) ? DateTypeEnum.WORK_DAY.getKey() : belongDateType; String startDate = overtimeDetailItem.get("ksrq"); String startTime = overtimeDetailItem.get("kssj"); String endDate = overtimeDetailItem.get("jsrq"); String endTime = overtimeDetailItem.get("jssj"); String jbsc = overtimeDetailItem.get("jbsc"); double overtimeMinutes = Double.parseDouble(jbsc) * 60; String jblxId = overtimeDetailItem.getOrDefault("jblx", ""); matchItemInfo = jblxInfo.getOrDefault(jblxId, new HashMap<>()); //判断该组明细是否与已存在的加班计划有重叠 boolean overLappingSign = checkOverlapping(existOvertimePlanList, startDate + " " +startTime, endDate + " " + endTime); if (overLappingSign) { String message = Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + startDate + "的加班计划区间和已申请的加班计划(已审核/待审核)出现时间重叠,不允许申请加班!"; log.error(message); requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222"); requestInfo.getRequestManager().setMessagecontent(message); return Action.FAILURE_AND_CONTINUE; } //判断是否与临近班次班段重叠,重叠班次是否为非休息班次的非休息时段 //获取当天班次id String currentDayBcId = Util.null2String(dateToBcxxMap.get(startDate)).split("-")[0]; //判断当天班次是否为休息班次、且“休息班打卡自动加班”未勾选 boolean currentDayRestBc = checkRestBc(currentDayBcId); if (!currentDayRestBc) { String overlapInfo = checkBcOverlap(startDate, currentDayBcId, workBdlxList, startDate + " " + startTime, endDate + " " + endTime); if (!"".equals(overlapInfo)) { String message = Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + startDate + "的加班计划区间" + overlapInfo; log.error(message); requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222"); requestInfo.getRequestManager().setMessagecontent(message); return Action.FAILURE_AND_CONTINUE; } } //获取前1天班次id String beforeDayBcId = Util.null2String(dateToBcxxMap.get(DateUtil.beforeDay(startDate, 1))).split("-")[0]; //判断前1天班次是否为休息班次、且“休息班打卡自动加班”未勾选 boolean beforeDayRestBc = checkRestBc(beforeDayBcId); if (!beforeDayRestBc) { String overlapInfo = checkBcOverlap(DateUtil.beforeDay(startDate, 1), beforeDayBcId, workBdlxList, startDate + " " + startTime, endDate + " " + endTime); if (!"".equals(overlapInfo)) { String message = Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + startDate + "的加班计划区间" + overlapInfo; log.error(message); requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222"); requestInfo.getRequestManager().setMessagecontent(message); return Action.FAILURE_AND_CONTINUE; } } //获取次日班次id String nextDayBcId = Util.null2String(dateToBcxxMap.get(DateUtil.AfterDay(startDate, 1))).split("-")[0]; //判断次日班次是否为休息班次、且“休息班打卡自动加班”未勾选 boolean nextDayRestBc = checkRestBc(nextDayBcId); if (!nextDayRestBc) { String overlapInfo = checkBcOverlap(DateUtil.AfterDay(startDate, 1), nextDayBcId, workBdlxList, startDate + " " + startTime, endDate + " " + endTime); if (!"".equals(overlapInfo)) { String message = Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + startDate + "的加班计划区间" + overlapInfo; log.error(message); requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222"); requestInfo.getRequestManager().setMessagecontent(message); return Action.FAILURE_AND_CONTINUE; } } //判断是否满足最小加班分钟数 String minMinutes = Util.null2String(matchItemInfo.get("jbqsfzs")); if (!"".equals(minMinutes) && Integer.parseInt(minMinutes) > overtimeMinutes) { //最小加班分钟数大于单条明细的加班时长分钟数 String message = Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + startDate + "的加班分钟数小于加班类型-" + Util.null2String(matchItemInfo.get("mc")) +"设置的最小加班分钟数!"; log.error(message); requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222"); requestInfo.getRequestManager().setMessagecontent(message); return Action.FAILURE_AND_CONTINUE; } String limitTotalOvertimeSc = Util.null2String(matchItemInfo.get("xzzjbsc")); if ("1".equals(limitTotalOvertimeSc)) { String limitWorkDayHours = Util.null2String(matchItemInfo.get("rzdjbxss")); String limitWeekHours = Util.null2String(matchItemInfo.get("zzdjbxss")); String limitMonthHours = Util.null2String(matchItemInfo.get("yzdjbxss")); String limitDealType = Util.null2String(matchItemInfo.get("ccclfs")); boolean doLimitWorkDayHours = false; boolean doLimitWeekHours = false; boolean doLimitMonthHours = false; //判断是否满足工作日加班最大小时数 boolean needCheckWorkDayHours = !"".equals(limitWorkDayHours) && (belongDateType.equals(DateTypeEnum.WORK_DAY.getKey()) || belongDateType.equals(DateTypeEnum.CHANGECLASS.getKey())); if (needCheckWorkDayHours && Double.compare(Double.parseDouble(limitWorkDayHours), overtimeMinutes / 60.0) < 0) { doLimitWorkDayHours = true; errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + startDate + "的加班时长累计后超过了加班类型-" + Util.null2String(matchItemInfo.get("mc")) +"设置的工作日加班最大小时数!"); } //判断是否满足周加班最大小时数 if (!"".equals(limitWeekHours)) { int weekRank = DateUtil.weekRank(belongDate); double maxWeekMinutes = Double.parseDouble(limitWeekHours) *60; double weekOvertimeMinutes; if (weekOvertimeInfo.get(belongDate.split("-")[0] + "" + weekRank) == null) { String countStartDate = DateUtil.beforeDay(belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-01", 6); String countEndDate = DateUtil.AfterDay(belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-28", 9); weekOvertimeMinutes = getWeekTimeMinutes(getWorkOverTimeResults(countStartDate, countEndDate, empId), belongDate); } else { weekOvertimeMinutes = weekOvertimeInfo.get(belongDate.split("-")[0] + "" + weekRank); } weekOvertimeInfo.put(belongDate.split("-")[0] + "" + weekRank, weekOvertimeMinutes + overtimeMinutes); if (maxWeekMinutes - weekOvertimeMinutes - overtimeMinutes < 0) { //达到周加班最大小时数 doLimitWeekHours = true; errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + startDate + "的加班时长累计后超过了加班类型-" + Util.null2String(matchItemInfo.get("mc")) +"设置的周加班最大小时数!"); } } //判断是否满足月加班最大小时数 if (!"".equals(limitMonthHours)) { String yearMonth = belongDate.substring(0, 7); double maxMonthMinutes = Double.parseDouble(limitMonthHours) *60; double monthOvertimeMinutes; if (monthOvertimeInfo.get(yearMonth) == null) { String countStartDate = belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-01"; String countEndDate = belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-31"; monthOvertimeMinutes = getMonthTimeMinutes(getWorkOverTimeResults(countStartDate, countEndDate, empId), belongDate); } else { monthOvertimeMinutes = monthOvertimeInfo.get(yearMonth); } monthOvertimeInfo.put(yearMonth, monthOvertimeMinutes + overtimeMinutes); if (maxMonthMinutes - monthOvertimeMinutes - overtimeMinutes < 0) { //达到月加班最大小时数 doLimitMonthHours = true; errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + startDate + "的加班时长累计后超过了加班类型-" + Util.null2String(matchItemInfo.get("mc")) +"设置的月加班最大小时数!"); } } //判断是否超出工作日、周、月最大小时数要求,在加班类型考勤项目中设置为“禁止提交时”,返回报错 if ("1".equals(limitDealType) && (doLimitWorkDayHours || doLimitWeekHours || doLimitMonthHours)) { log.error("超出加班类型工作日/周/月最大加班小时数限制!"); requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222"); requestInfo.getRequestManager().setMessagecontent(String.valueOf(errorMessage)); return Action.FAILURE_AND_CONTINUE; } } } } }catch (Exception e){ log.error("OvertimePlanCheckAction error : [{}]",e); return Action.FAILURE_AND_CONTINUE; } return Action.SUCCESS; } /** * 获得一周加班分钟数 * @param dataList * @return */ public double getWeekTimeMinutes(List> dataList,String date){ int day = TimeUtil.getDayOfWeek(date); if (day ==0){ day = 7; } String startDate = DateUtil.beforeDay(date,day-1); String endDate = DateUtil.AfterDay(date,7-day); List> list = dataList.stream().filter(e->{ String sjksrq = Util.null2String(e.get("sjksrq")); if (DateUtil.getTime(sjksrq).compareTo(DateUtil.getTime(startDate)) >=0 && DateUtil.getTime(sjksrq).compareTo(DateUtil.getTime(endDate)) <=0 && DateUtil.getTime(sjksrq).compareTo(DateUtil.getTime(date)) !=0){ return true; }else { return false; } }).collect(Collectors.toList()); double totalMinutes = 0; for (Map data:list){ String hsdw = data.get("hsdw").toString(); totalMinutes += Utils.getItemduration(1, AccountingUnitEnum.MINUTES.getKey(), Double.valueOf(data.get("sjjbsc").toString()),AccountingUnitEnum.getEnum(hsdw),8); } return totalMinutes; } /** * 获得一个月加班分钟数 * @param dataList * @return */ public double getMonthTimeMinutes(List> dataList,String date){ String startDate = date.split("-")[0]+"-"+ date.split("-")[1]+"-01"; String endDate = date.split("-")[0]+"-"+ date.split("-")[1]+"-31"; List> list = dataList.stream().filter(e->DateUtil.getTime(e.get("sjksrq").toString()).compareTo(DateUtil.getTime(startDate))>=0 && DateUtil.getTime(e.get("sjjsrq").toString()).compareTo(DateUtil.getTime(endDate))<=0).collect(Collectors.toList()); double totalMinutes = 0; for (Map data:list){ String hsdw = data.get("hsdw").toString(); totalMinutes += Utils.getItemduration(1,AccountingUnitEnum.MINUTES.getKey(), Double.valueOf(data.get("sjjbsc").toString()),AccountingUnitEnum.getEnum(hsdw),8); } return totalMinutes; } /** * 获取目标人员时间区间内的加班结果、加班计划 */ public List> getWorkOverTimeResults(String startDate,String endDate,String userId){ String sql = "select a.sjjbsc, a.sjksrq, a.sjjsrq, a.jbjhid, a.jblx, b.hsdw from uf_jcl_kq_jbjg a left join uf_jcl_kq_kqxm b on a.jblx = b.id where a.zt != 2 and a.jbry=? and a.sjksrq>=? and a.sjjsrq<=?"; List> jbjgDataList = DbTools.getSqlToList(sql,userId,startDate,endDate); sql = "select b.jbsc as sjjbsc, b.ksrq as sjksrq, b.jsrq as sjjsrq, a.id as jbjhid, b.jblx, c.hsdw from uf_jcl_kq_jbjh a " + "left join uf_jcl_kq_jbjh_dt1 b on a.id = b.mainid left join uf_jcl_kq_kqxm c on b.jblx = c.id where a.jlzt != 2 and b.jbry = ? and b.ksrq >= ? and b.jsrq <= ?"; List> jbjhDataList = DbTools.getSqlToList(sql,userId,startDate,endDate); //去除加班计划中数据已转换为加班结果的数据 Set jbjhIds = jbjgDataList.stream().filter(f -> !"".equals(Util.null2String(f.get("jbjhid")))).map(e->e.get("jbjhid").toString()).collect(Collectors.toSet()); jbjhDataList = jbjhDataList.stream().filter(f -> !jbjhIds.contains(f.get("jbjhid").toString())).collect(Collectors.toList()); if (jbjhDataList.size() > 0) { jbjgDataList.addAll(jbjhDataList); } return jbjgDataList; } private boolean checkOverlapping(List> existOvertimePlanList, String startTimePoint, String endTimePoint) { boolean overlappingSign = false; if (existOvertimePlanList != null && existOvertimePlanList.size() > 0) { String contrastStartPoint = ""; String contrastEndPoint = ""; for (Map item : existOvertimePlanList) { contrastStartPoint = item.get("ksrq") + " " + item.get("kssj"); contrastEndPoint = item.get("jsrq") + " " + item.get("jssj"); overlappingSign = DateUtil.isOverlapping(contrastStartPoint, contrastEndPoint, startTimePoint, endTimePoint); if (overlappingSign) { break; } } } return overlappingSign; } /** * 获取目标人员在加班计划表中结束日期大于等于匹配日期的数据记录 * @param empIdList 人员id列表 * @param matchDate 匹配日期 * @returnd */ private Map>> getOvertimePlanInfo(List empIdList, String matchDate) { Map>> result = new HashMap<>(); if (empIdList.size() > 0 && !"".equals(matchDate)) { String sql = "select b.id, b.jbry, b.ksrq, b.jsrq, b.kssj, b.jssj from uf_jcl_kq_jbjh a left join uf_jcl_kq_jbjh_dt1 b on b.mainid = a.id where a.jlzt != 2 and b.jsrq >= '" + matchDate + "' and b.jbry in (" + String.join(",",empIdList) + ")"; List> data = DbTools.getSqlToList(sql); result = data.stream().collect(Collectors.groupingBy(e->e.get("jbry").toString())); } return result; } private boolean checkRestBc(String bcId) { boolean restSign = false; if (!"".equals(bcId)) { //查询当天班次明细 String sql = "select id, sfxx, xxbdkzdjb from uf_jcl_kq_bcxx where id = " + bcId; Map data = DbTools.getSqlToMap(sql); if ("1".equals(Util.null2String(data.get("sfxx"))) && !"1".equals(Util.null2String(data.get("xxbdkzdjb")))) { restSign = true; } } return restSign; } public String getBcStartAndEndTime(String date, String currentDayBcId, List workBdlxList) { String startToEnd = ""; if (!"".equals(currentDayBcId)) { //查询当天班次明细 String sql = "select id, bdlx, gsrq, kssj, jssj from uf_jcl_kq_bcxx_dt1 where mainid = " + currentDayBcId + " order by gsrq desc, kssj desc"; List> bcDetailData = DbTools.getSqlToList(sql); bcDetailData = bcDetailData.stream().filter(e -> workBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList()); if (bcDetailData.size() > 0) { String endGsrqValue = Util.null2String(bcDetailData.get(0).get("gsrq")); String lastJssj = Util.null2String(bcDetailData.get(0).get("jssj")); String lastKssj = Util.null2String(bcDetailData.get(0).get("kssj")); String bdEndDate = "2".equals(endGsrqValue) ? DateUtil.AfterDay(date,1) : ("0".equals(endGsrqValue) ? DateUtil.beforeDay(date,1) : date); bdEndDate = lastKssj.compareTo(lastJssj) >= 0 ? DateUtil.AfterDay(bdEndDate,1) : bdEndDate; String startGsrqValue = Util.null2String(bcDetailData.get(bcDetailData.size() - 1).get("gsrq")); String firstKssj = Util.null2String(bcDetailData.get(bcDetailData.size() - 1).get("kssj")); String bdStartDate = "2".equals(startGsrqValue) ? DateUtil.AfterDay(date,1) : ("0".equals(startGsrqValue) ? DateUtil.beforeDay(date,1) : date); startToEnd = bdStartDate + " " + firstKssj + "," + bdEndDate + " " + lastJssj; } } return startToEnd; } private String checkBcOverlap(String startDate, String currentDayBcId, List workBdlxList, String overtimePlanStart, String overtimePlanEnd) { //获取当前日期班次开始时间和结束时间 String currentDayStartToEnd = getBcStartAndEndTime(startDate, currentDayBcId, workBdlxList); String currentDayStartTime = !"".equals(currentDayStartToEnd) ? currentDayStartToEnd.split(",")[0] : ""; String currentDayEndTime = !"".equals(currentDayStartToEnd) ? currentDayStartToEnd.split(",")[1] : ""; //如果加班计划区间和班次区间有交集 boolean noOverlapSign = overtimePlanStart.compareTo(currentDayEndTime) >= 0 || overtimePlanEnd.compareTo(currentDayStartTime) <= 0; if (!noOverlapSign) { //判断交集部分是否完全属于班次的休息、就餐时段 boolean onlyInRestPeriod = overtimeOnlyInRestRange(currentDayBcId, overtimePlanStart, overtimePlanEnd, startDate); if (!onlyInRestPeriod) { return "与" + startDate + "班次中的非休息、就餐时段存在交集!"; } else { return ""; } } else { return ""; } } /** * 判断请假区间是否完全处于班次中的休息时段内 */ private boolean overtimeOnlyInRestRange(String bcId, String startTime, String endTime, String date) { int overRangeMinutes = DateUtil.getBetWeenMinutes(startTime, endTime); List countBdlxList = new ArrayList<>(); countBdlxList.add(ClassSegmentTypeEnum.REST_AND_DINE.getKey()); countBdlxList.add(ClassSegmentTypeEnum.REST_PERIOD.getKey()); countBdlxList.add(ClassSegmentTypeEnum.DINING_PERIOD.getKey()); String sql = "select id, bdlx, gsrq, kssj as dtkssj, jssj as dtjssj from uf_jcl_kq_bcxx_dt1 where mainid = " + bcId; List> bcDetailData = DbTools.getSqlToList(sql); bcDetailData = bcDetailData.stream().filter(e -> countBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList()); //获取需要累计的班段时长区间和目标区间存在交集的分钟数,并与请假区间内的分钟数最比较 return overRangeMinutes == Utils.removeTime(startTime, endTime, bcDetailData, date); } }