From 93975533b026625ce6a7725d342eb69fc8155896 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 13 Jan 2026 18:22:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E4=B8=AD=E4=BB=BB=E5=8A=A1=E7=9A=84=E5=BB=B6=E8=AF=AF=E6=89=A3?= =?UTF-8?q?=E5=88=86=E8=AE=A1=E7=AE=97=EF=BC=88=E5=BD=93=E5=89=8D=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E8=B6=85=E8=BF=87deadline=E6=97=B6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designhub/service/AnalyticsService.java | 106 ++++++++++++++++-- 1 file changed, 94 insertions(+), 12 deletions(-) diff --git a/backend/src/main/java/com/designhub/service/AnalyticsService.java b/backend/src/main/java/com/designhub/service/AnalyticsService.java index 68c10fc..3c972f7 100644 --- a/backend/src/main/java/com/designhub/service/AnalyticsService.java +++ b/backend/src/main/java/com/designhub/service/AnalyticsService.java @@ -666,19 +666,21 @@ public class AnalyticsService { // 获取扣分比例配置(默认每延误1小时扣任务积分的1%) BigDecimal deductionRate = getDeductionRate(designer.getDeptId(), currentMonth); + LocalDateTime now = LocalDateTime.now(); for (Task task : designerTasks) { - // 只计算在指定月份内完成的任务(与getDesignerDeductionDetails保持一致) + // 计算任务积分 + BigDecimal taskScore = BigDecimal.ZERO; + if (task.getScoreReward() != null && task.getScoreReward().compareTo(BigDecimal.ZERO) > 0) { + taskScore = task.getScoreReward(); + } else if (task.getScore() != null) { + taskScore = BigDecimal.valueOf(task.getScore()); + } + + // 计算已完成任务的积分和延误扣分 if ("completed".equals(task.getStatus()) && task.getActualEndTime() != null && !task.getActualEndTime().isBefore(startTime) && !task.getActualEndTime().isAfter(endTime)) { - // 计算任务积分 - BigDecimal taskScore = BigDecimal.ZERO; - if (task.getScoreReward() != null && task.getScoreReward().compareTo(BigDecimal.ZERO) > 0) { - taskScore = task.getScoreReward(); - } else if (task.getScore() != null) { - taskScore = BigDecimal.valueOf(task.getScore()); - } totalScore = totalScore.add(taskScore); // 计算延误扣分(如果超时完成) @@ -700,6 +702,26 @@ public class AnalyticsService { } } } + // 计算进行中任务的延误扣分(当前时间超过deadline时) + else if ("in_progress".equals(task.getStatus()) && task.getDeadline() != null + && task.getDeadline().isBefore(endTime) // deadline在查询月份范围内 + && now.isAfter(task.getDeadline()) // 当前时间已超过deadline + && taskScore.compareTo(BigDecimal.ZERO) > 0) { + // 计算延误小时数(当前时间 - deadline) + long overdueHours = Duration.between(task.getDeadline(), now).toHours(); + if (overdueHours > 0) { + // 扣分 = 任务积分 * 延误小时数 * 扣分比例 + BigDecimal taskDeduction = taskScore + .multiply(BigDecimal.valueOf(overdueHours)) + .multiply(deductionRate) + .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP); + // 扣分不能超过任务积分 + if (taskDeduction.compareTo(taskScore) > 0) { + taskDeduction = taskScore; + } + deductionScore = deductionScore.add(taskDeduction); + } + } } // 添加进度未更新扣分 @@ -1336,9 +1358,19 @@ public class AnalyticsService { .le(Task::getActualEndTime, endTime) ); - log.info("获取设计师扣分明细 - 用户: {}, 月份: {}, 已完成任务数: {}", + // 获取进行中的任务(deadline在查询月份范围内) + List inProgressTasks = taskMapper.selectList( + new LambdaQueryWrapper() + .eq(Task::getReceiverId, userId) + .eq(Task::getStatus, "in_progress") + .isNotNull(Task::getDeadline) + .ge(Task::getDeadline, startTime) + .le(Task::getDeadline, endTime) + ); + + log.info("获取设计师扣分明细 - 用户: {}, 月份: {}, 已完成任务数: {}, 进行中任务数: {}", designer.getRealName() != null ? designer.getRealName() : designer.getUsername(), - currentMonth, completedTasks.size()); + currentMonth, completedTasks.size(), inProgressTasks.size()); // 获取扣分比例配置 BigDecimal deductionRate = getDeductionRate(designer.getDeptId(), currentMonth); @@ -1347,9 +1379,11 @@ public class AnalyticsService { // 计算延误扣分明细 List delayDeductions = new ArrayList<>(); BigDecimal totalDelayDeduction = BigDecimal.ZERO; + LocalDateTime now = LocalDateTime.now(); + // 处理已完成任务的延误扣分 for (Task task : completedTasks) { - log.info("检查任务: taskNo={}, deadline={}, actualEndTime={}, scoreReward={}, score={}", + log.info("检查已完成任务: taskNo={}, deadline={}, actualEndTime={}, scoreReward={}, score={}", task.getTaskNo(), task.getDeadline(), task.getActualEndTime(), task.getScoreReward(), task.getScore()); @@ -1382,7 +1416,7 @@ public class AnalyticsService { totalDelayDeduction = totalDelayDeduction.add(taskDeduction); - log.info("发现延误任务: taskNo={}, 任务积分={}, 延误小时={}, 扣分={}", + log.info("发现已完成延误任务: taskNo={}, 任务积分={}, 延误小时={}, 扣分={}", task.getTaskNo(), taskScore, overdueHours, taskDeduction); delayDeductions.add(DeductionDetailVO.DelayDeductionItem.builder() @@ -1401,6 +1435,54 @@ public class AnalyticsService { } } + // 处理进行中任务的延误扣分(当前时间超过deadline时) + for (Task task : inProgressTasks) { + if (task.getDeadline() != null && now.isAfter(task.getDeadline())) { + // 计算任务积分 + BigDecimal taskScore = BigDecimal.ZERO; + if (task.getScoreReward() != null && task.getScoreReward().compareTo(BigDecimal.ZERO) > 0) { + taskScore = task.getScoreReward(); + } else if (task.getScore() != null) { + taskScore = BigDecimal.valueOf(task.getScore()); + } + + if (taskScore.compareTo(BigDecimal.ZERO) > 0) { + // 计算延误小时数(当前时间 - deadline) + long overdueHours = Duration.between(task.getDeadline(), now).toHours(); + + if (overdueHours > 0) { + // 计算扣分 + BigDecimal taskDeduction = taskScore + .multiply(BigDecimal.valueOf(overdueHours)) + .multiply(deductionRate) + .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP); + + // 扣分不能超过任务积分 + if (taskDeduction.compareTo(taskScore) > 0) { + taskDeduction = taskScore; + } + + totalDelayDeduction = totalDelayDeduction.add(taskDeduction); + + log.info("发现进行中延误任务: taskNo={}, 任务积分={}, 延误小时={}, 扣分={}", + task.getTaskNo(), taskScore, overdueHours, taskDeduction); + + delayDeductions.add(DeductionDetailVO.DelayDeductionItem.builder() + .taskId(task.getId()) + .taskNo(task.getTaskNo()) + .taskTitle(task.getTitle()) + .taskScore(taskScore) + .deadline(task.getDeadline()) + .actualEndTime(null) // 进行中任务没有完成时间 + .overdueHours(overdueHours) + .deductionScore(taskDeduction) + .deductionReason("任务进行中,已延误 " + overdueHours + " 小时") + .build()); + } + } + } + } + log.info("延误扣分总数: {}, 延误扣分记录数: {}", totalDelayDeduction, delayDeductions.size()); // 获取进度未更新扣分明细