diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/PerformanceReportServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/PerformanceReportServiceImpl.java index 30ee134..3ca4af9 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/PerformanceReportServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/PerformanceReportServiceImpl.java @@ -60,8 +60,36 @@ public class PerformanceReportServiceImpl implements IPerformanceReportService { vo.setResponsibleProjects(responsibleProjects); // 3.1) 延期项目(筛选出延期的项目) + // 规则: + // 1)显式标记延期:isPostpone > 0 + // 2)时间上发生逾期: + // - 如果存在 postponeTime,则 finishTime > postponeTime 视为逾期完成 + // - 否则,如果存在 originalFinishTime,则 finishTime > originalFinishTime 视为逾期完成 + // - 对于仍未完成的项目,如果当前时间 > (postponeTime 或 originalFinishTime),也视为逾期中 + Date now = new Date(); List postponedProjects = responsibleProjects.stream() - .filter(p -> p.getIsPostpone() != null && p.getIsPostpone() > 0) + .filter(p -> { + // 条件 1:显式延期标记 + if (p.getIsPostpone() != null && p.getIsPostpone() > 0) { + return true; + } + Date finishTime = p.getFinishTime(); + Date postponeTime = p.getPostponeTime(); + Date originalFinishTime = p.getOriginalFinishTime(); + + // 计算“应完成时间” + Date dueTime = postponeTime != null ? postponeTime : originalFinishTime; + if (dueTime == null) { + return false; + } + + // 条件 2:已完成但完成时间晚于应完成时间 + if (finishTime != null && finishTime.after(dueTime)) { + return true; + } + // 条件 3:未完成,当前时间已经晚于应完成时间 + return finishTime == null && now.after(dueTime); + }) .collect(Collectors.toList()); vo.setPostponedProjects(postponedProjects); @@ -74,21 +102,26 @@ public class PerformanceReportServiceImpl implements IPerformanceReportService { .collect(Collectors.toList()); vo.setMyScheduleStepDetails(mySteps); - // 4.1) 延期进度步骤(未完成 && planEnd < 当前时间) - // 注意:mySteps 已经是在查询时间范围内的步骤,所以不需要再限制 planEnd 的范围 + // 4.1) 延期进度步骤 + // 规则: + // 1)有计划结束时间 planEnd + // 2)若已完成(actualEnd 不为空),则 actualEnd > planEnd 视为“逾期完成” + // 3)若未完成(actualEnd 为空),则当前时间 now > planEnd 视为“正在逾期” + // 说明:mySteps 已经限定在本次查询时间范围内 Date now = new Date(); List delayedSteps = mySteps.stream() .filter(s -> { - // 未完成:status != 1 - if (s.getStatus() == null || s.getStatus() == 1) { + Date planEnd = s.getPlanEnd(); + if (planEnd == null) { return false; } - // 有预计结束时间 - if (s.getPlanEnd() == null) { - return false; + Date actualEnd = s.getActualEnd(); + // 已完成:完成时间晚于计划结束时间 + if (actualEnd != null) { + return actualEnd.after(planEnd); } - // 预计结束时间已过期(当前时间已超过计划结束时间) - return s.getPlanEnd().before(now) || s.getPlanEnd().equals(now); + // 未完成:当前时间已晚于计划结束时间 + return now.after(planEnd); }) .collect(Collectors.toList()); vo.setDelayedScheduleStepDetails(delayedSteps); @@ -105,20 +138,25 @@ public class PerformanceReportServiceImpl implements IPerformanceReportService { List taskDetails = sysOaTaskMapper.selectPerformanceTaskList(userId, startDate, endDate); vo.setTaskDetails(taskDetails); - // 6.1) 延期任务(未完成 && finishTime < 当前时间) - // 注意:taskDetails 已经是在查询时间范围内的任务,所以不需要再限制 finishTime 的范围 + // 6.1) 延期任务 + // 规则: + // 1)有预计结束时间 finishTime + // 2)若已完成(completedTime 不为空),则 completedTime > finishTime 视为“逾期完成” + // 3)若未完成(completedTime 为空),则当前时间 now > finishTime 视为“正在逾期” + // 说明:taskDetails 已经限定在本次查询时间范围内 List delayedTasks = taskDetails.stream() .filter(t -> { - // 未完成:completedTime == null - if (t.getCompletedTime() != null) { + Date finishTime = t.getFinishTime(); + if (finishTime == null) { return false; } - // 有预计结束时间 - if (t.getFinishTime() == null) { - return false; + Date completedTime = t.getCompletedTime(); + // 已完成:完成时间晚于预计结束时间 + if (completedTime != null) { + return completedTime.after(finishTime); } - // 预计结束时间已过期(当前时间已超过预计结束时间) - return t.getFinishTime().before(now) || t.getFinishTime().equals(now); + // 未完成:当前时间已晚于预计结束时间 + return now.after(finishTime); }) .collect(Collectors.toList()); vo.setDelayedTaskDetails(delayedTasks);