diff --git a/backend/src/main/java/com/designhub/service/AnalyticsService.java b/backend/src/main/java/com/designhub/service/AnalyticsService.java index 9d27f2d..2bd0d6c 100644 --- a/backend/src/main/java/com/designhub/service/AnalyticsService.java +++ b/backend/src/main/java/com/designhub/service/AnalyticsService.java @@ -1719,13 +1719,16 @@ public class AnalyticsService { designer.getRealName() != null ? designer.getRealName() : designer.getUsername(), currentMonth, completedTaskItems.size(), inProgressTaskItems.size()); - // 处理已完成的子任务的延误扣分(使用子任务自己的estimatedHours计算deadline) + // 处理已完成的子任务的延误扣分(使用子任务自己的deadline和claimTime) for (TaskItem item : completedTaskItems) { - if (item.getEstimatedHours() != null && item.getEstimatedHours().compareTo(BigDecimal.ZERO) > 0 - && item.getCreateTime() != null && item.getCompleteTime() != null) { + if (item.getCompleteTime() != null) { - // 计算子任务的预期deadline:createTime + estimatedHours(使用工作时间计算) - LocalDateTime expectedDeadline = workHoursCalculator.calculateDeadline(item.getCreateTime(), item.getEstimatedHours()); + // 优先使用数据库中已存储的deadline,如果没有则根据claimTime计算 + LocalDateTime expectedDeadline = item.getDeadline(); + if (expectedDeadline == null && item.getClaimTime() != null && item.getEstimatedHours() != null + && item.getEstimatedHours().compareTo(BigDecimal.ZERO) > 0) { + expectedDeadline = workHoursCalculator.calculateDeadline(item.getClaimTime(), item.getEstimatedHours()); + } // 如果完成时间超过预期deadline,计算延误扣分 if (expectedDeadline != null && item.getCompleteTime().isAfter(expectedDeadline)) { @@ -1776,58 +1779,58 @@ public class AnalyticsService { } } - // 处理进行中的子任务的延误扣分(使用子任务自己的estimatedHours计算deadline) + // 处理进行中的子任务的延误扣分(使用子任务自己的deadline和claimTime) for (TaskItem item : inProgressTaskItems) { - if (item.getEstimatedHours() != null && item.getEstimatedHours().compareTo(BigDecimal.ZERO) > 0 - && item.getCreateTime() != null) { + // 优先使用数据库中已存储的deadline,如果没有则根据claimTime计算 + LocalDateTime expectedDeadline = item.getDeadline(); + if (expectedDeadline == null && item.getClaimTime() != null && item.getEstimatedHours() != null + && item.getEstimatedHours().compareTo(BigDecimal.ZERO) > 0) { + expectedDeadline = workHoursCalculator.calculateDeadline(item.getClaimTime(), item.getEstimatedHours()); + } + + // 如果当前时间超过预期deadline,计算延误扣分 + if (expectedDeadline != null && now.isAfter(expectedDeadline)) { + BigDecimal itemScore = item.getTotalScore() != null ? item.getTotalScore() : BigDecimal.ZERO; - // 计算子任务的预期deadline:createTime + estimatedHours(使用工作时间计算) - LocalDateTime expectedDeadline = workHoursCalculator.calculateDeadline(item.getCreateTime(), item.getEstimatedHours()); - - // 如果当前时间超过预期deadline,计算延误扣分 - if (expectedDeadline != null && now.isAfter(expectedDeadline)) { - BigDecimal itemScore = item.getTotalScore() != null ? item.getTotalScore() : BigDecimal.ZERO; + if (itemScore.compareTo(BigDecimal.ZERO) > 0) { + // 计算延误小时数(只计算工作时间段内的延误) + BigDecimal overdueHours = workHoursCalculator.calculateDelayHours(expectedDeadline, now); - if (itemScore.compareTo(BigDecimal.ZERO) > 0) { - // 计算延误小时数(只计算工作时间段内的延误) - BigDecimal overdueHours = workHoursCalculator.calculateDelayHours(expectedDeadline, now); + if (overdueHours.compareTo(BigDecimal.ZERO) > 0) { + // 计算扣分 + BigDecimal itemDeduction = itemScore + .multiply(overdueHours) + .multiply(deductionRate) + .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP); - if (overdueHours.compareTo(BigDecimal.ZERO) > 0) { - // 计算扣分 - BigDecimal itemDeduction = itemScore - .multiply(overdueHours) - .multiply(deductionRate) - .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP); - - // 扣分不能超过任务积分 - if (itemDeduction.compareTo(itemScore) > 0) { - itemDeduction = itemScore; - } - - totalDelayDeduction = totalDelayDeduction.add(itemDeduction); - - // 获取主任务信息用于显示 - Task mainTask = taskMapper.selectById(item.getTaskId()); - String taskNo = item.getItemNo() != null ? item.getItemNo() : ""; - String taskTitle = mainTask != null ? mainTask.getTitle() : "子任务"; - - long overdueHoursLong = overdueHours.longValue(); - log.info("发现进行中延误子任务: itemNo={}, 任务积分={}, 延误小时={}, 扣分={}", - taskNo, itemScore, overdueHoursLong, itemDeduction); - - delayDeductions.add(DeductionDetailVO.DelayDeductionItem.builder() - .taskId(item.getTaskId()) // 使用主任务ID - .taskNo(taskNo) - .taskTitle(taskTitle + " (" + taskNo + ")") - .taskScore(itemScore) - .claimTime(item.getClaimTime()) // 子任务使用claimTime - .deadline(expectedDeadline) - .actualEndTime(null) // 进行中子任务没有完成时间 - .overdueHours(overdueHoursLong) - .deductionScore(itemDeduction) - .deductionReason("子任务进行中,已延误 " + overdueHoursLong + " 小时") - .build()); + // 扣分不能超过任务积分 + if (itemDeduction.compareTo(itemScore) > 0) { + itemDeduction = itemScore; } + + totalDelayDeduction = totalDelayDeduction.add(itemDeduction); + + // 获取主任务信息用于显示 + Task mainTask = taskMapper.selectById(item.getTaskId()); + String taskNo = item.getItemNo() != null ? item.getItemNo() : ""; + String taskTitle = mainTask != null ? mainTask.getTitle() : "子任务"; + + long overdueHoursLong = overdueHours.longValue(); + log.info("发现进行中延误子任务: itemNo={}, 任务积分={}, 延误小时={}, 扣分={}", + taskNo, itemScore, overdueHoursLong, itemDeduction); + + delayDeductions.add(DeductionDetailVO.DelayDeductionItem.builder() + .taskId(item.getTaskId()) // 使用主任务ID + .taskNo(taskNo) + .taskTitle(taskTitle + " (" + taskNo + ")") + .taskScore(itemScore) + .claimTime(item.getClaimTime()) // 子任务使用claimTime + .deadline(expectedDeadline) + .actualEndTime(null) // 进行中子任务没有完成时间 + .overdueHours(overdueHoursLong) + .deductionScore(itemDeduction) + .deductionReason("子任务进行中,已延误 " + overdueHoursLong + " 小时") + .build()); } } }