feat: 添加子任务的延误扣分计算(使用子任务自己的estimatedHours和createTime计算deadline)

This commit is contained in:
Your Name 2026-01-13 19:00:05 +08:00
parent 07b1afe2fb
commit fdea487a71

View File

@ -32,6 +32,7 @@ import java.util.stream.Collectors;
public class AnalyticsService {
private final TaskMapper taskMapper;
private final TaskItemMapper taskItemMapper;
private final UserMapper userMapper;
private final DepartmentMapper departmentMapper;
private final TeamScorePoolMapper teamScorePoolMapper;
@ -1489,6 +1490,140 @@ public class AnalyticsService {
}
}
// 查询已完成的子任务(按完成时间查询)
List<TaskItem> completedTaskItems = taskItemMapper.selectList(
new LambdaQueryWrapper<TaskItem>()
.eq(TaskItem::getReceiverId, userId)
.eq(TaskItem::getStatus, "completed")
.isNotNull(TaskItem::getCompleteTime)
.ge(TaskItem::getCompleteTime, startTime)
.le(TaskItem::getCompleteTime, endTime)
);
// 查询进行中的子任务
List<TaskItem> inProgressTaskItems = taskItemMapper.selectList(
new LambdaQueryWrapper<TaskItem>()
.eq(TaskItem::getReceiverId, userId)
.eq(TaskItem::getStatus, "in_progress")
.isNotNull(TaskItem::getEstimatedHours)
);
log.info("获取设计师扣分明细 - 用户: {}, 月份: {}, 已完成子任务数: {}, 进行中子任务数: {}",
designer.getRealName() != null ? designer.getRealName() : designer.getUsername(),
currentMonth, completedTaskItems.size(), inProgressTaskItems.size());
// 处理已完成的子任务的延误扣分(使用子任务自己的estimatedHours计算deadline)
for (TaskItem item : completedTaskItems) {
if (item.getEstimatedHours() != null && item.getEstimatedHours().compareTo(BigDecimal.ZERO) > 0
&& item.getCreateTime() != null && item.getCompleteTime() != null) {
// 计算子任务的预期deadline:createTime + estimatedHours
long estimatedMinutes = item.getEstimatedHours().multiply(BigDecimal.valueOf(60)).longValue();
LocalDateTime expectedDeadline = item.getCreateTime().plusMinutes(estimatedMinutes);
// 如果完成时间超过预期deadline,计算延误扣分
if (item.getCompleteTime().isAfter(expectedDeadline)) {
BigDecimal itemScore = item.getTotalScore() != null ? BigDecimal.valueOf(item.getTotalScore()) : BigDecimal.ZERO;
if (itemScore.compareTo(BigDecimal.ZERO) > 0) {
// 计算延误小时数
long overdueHours = Duration.between(expectedDeadline, item.getCompleteTime()).toHours();
if (overdueHours > 0) {
// 计算扣分
BigDecimal itemDeduction = itemScore
.multiply(BigDecimal.valueOf(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() : "子任务";
log.info("发现已完成延误子任务: itemNo={}, 任务积分={}, 延误小时={}, 扣分={}",
taskNo, itemScore, overdueHours, itemDeduction);
delayDeductions.add(DeductionDetailVO.DelayDeductionItem.builder()
.taskId(item.getTaskId()) // 使用主任务ID
.taskNo(taskNo)
.taskTitle(taskTitle + " (" + taskNo + ")")
.taskScore(itemScore)
.deadline(expectedDeadline)
.actualEndTime(item.getCompleteTime())
.overdueHours(overdueHours)
.deductionScore(itemDeduction)
.deductionReason("子任务延误 " + overdueHours + " 小时")
.build());
}
}
}
}
}
// 处理进行中的子任务的延误扣分(使用子任务自己的estimatedHours计算deadline)
for (TaskItem item : inProgressTaskItems) {
if (item.getEstimatedHours() != null && item.getEstimatedHours().compareTo(BigDecimal.ZERO) > 0
&& item.getCreateTime() != null) {
// 计算子任务的预期deadline:createTime + estimatedHours
long estimatedMinutes = item.getEstimatedHours().multiply(BigDecimal.valueOf(60)).longValue();
LocalDateTime expectedDeadline = item.getCreateTime().plusMinutes(estimatedMinutes);
// 如果当前时间超过预期deadline,计算延误扣分
if (now.isAfter(expectedDeadline)) {
BigDecimal itemScore = item.getTotalScore() != null ? BigDecimal.valueOf(item.getTotalScore()) : BigDecimal.ZERO;
if (itemScore.compareTo(BigDecimal.ZERO) > 0) {
// 计算延误小时数(当前时间 - 预期deadline)
long overdueHours = Duration.between(expectedDeadline, now).toHours();
if (overdueHours > 0) {
// 计算扣分
BigDecimal itemDeduction = itemScore
.multiply(BigDecimal.valueOf(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() : "子任务";
log.info("发现进行中延误子任务: itemNo={}, 任务积分={}, 延误小时={}, 扣分={}",
taskNo, itemScore, overdueHours, itemDeduction);
delayDeductions.add(DeductionDetailVO.DelayDeductionItem.builder()
.taskId(item.getTaskId()) // 使用主任务ID
.taskNo(taskNo)
.taskTitle(taskTitle + " (" + taskNo + ")")
.taskScore(itemScore)
.deadline(expectedDeadline)
.actualEndTime(null) // 进行中子任务没有完成时间
.overdueHours(overdueHours)
.deductionScore(itemDeduction)
.deductionReason("子任务进行中,已延误 " + overdueHours + " 小时")
.build());
}
}
}
}
}
log.info("延误扣分总数: {}, 延误扣分记录数: {}", totalDelayDeduction, delayDeductions.size());
// 获取进度未更新扣分明细