qiangdanxitong/backend/src/main/java/com/designhub/service/DelayPenaltyService.java

184 lines
6.3 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.designhub.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.designhub.entity.DelayPenaltyRecord;
import com.designhub.entity.DelayPenaltyRule;
import com.designhub.mapper.DelayPenaltyRecordMapper;
import com.designhub.mapper.DelayPenaltyRuleMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
/**
* 延误扣分Service
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class DelayPenaltyService {
private final DelayPenaltyRecordMapper delayPenaltyRecordMapper;
private final DelayPenaltyRuleMapper delayPenaltyRuleMapper;
/**
* 计算延误扣分
* 根据需求文档的规则:
* - 轻微延误(< 2小时):每小时扣2分
* - 一般延误(2-8小时):每小时扣3分
* - 严重延误(8-24小时):每小时扣5分
* - 重大延误(> 24小时):基础50分+每天10分
*/
public DelayPenaltyRecord calculateDelayPenalty(Long taskId, Long designerId,
LocalDateTime deadline,
LocalDateTime actualTime) {
if (deadline == null || actualTime == null) {
return null;
}
// 如果实际时间早于截止时间,未延误
if (actualTime.isBefore(deadline) || actualTime.isEqual(deadline)) {
return null;
}
// 计算延误小时数
long delayHours = ChronoUnit.HOURS.between(deadline, actualTime);
long delayDays = ChronoUnit.DAYS.between(deadline, actualTime);
// 确定延误等级和扣分
String delayLevel;
Integer penaltyScore;
if (delayHours < 2) {
// 轻微延误:每小时扣2分
delayLevel = "light";
penaltyScore = (int) Math.ceil(delayHours * 2.0);
} else if (delayHours < 8) {
// 一般延误:每小时扣3分
delayLevel = "general";
penaltyScore = (int) Math.ceil(delayHours * 3.0);
} else if (delayHours < 24) {
// 严重延误:每小时扣5分
delayLevel = "severe";
penaltyScore = (int) Math.ceil(delayHours * 5.0);
} else {
// 重大延误:基础50分+每天10分
delayLevel = "major";
penaltyScore = 50 + (int) delayDays * 10;
}
// 创建延误扣分记录
DelayPenaltyRecord record = new DelayPenaltyRecord();
record.setTaskId(taskId);
record.setDesignerId(designerId);
record.setDelayDays((int) delayDays);
record.setDelayHours(delayHours);
record.setDelayLevel(delayLevel);
record.setPenaltyScore(penaltyScore);
record.setOriginalDeadline(deadline);
record.setActualTime(actualTime);
record.setStatus("confirmed");
log.info("计算延误扣分: taskId={}, designerId={}, delayHours={}, delayLevel={}, penaltyScore={}",
taskId, designerId, delayHours, delayLevel, penaltyScore);
return record;
}
/**
* 保存延误扣分记录
*/
@Transactional(rollbackFor = Exception.class)
public DelayPenaltyRecord saveDelayPenaltyRecord(DelayPenaltyRecord record) {
if (record == null) {
return null;
}
delayPenaltyRecordMapper.insert(record);
log.info("保存延误扣分记录: recordId={}, taskId={}, penaltyScore={}",
record.getId(), record.getTaskId(), record.getPenaltyScore());
return record;
}
/**
* 根据任务ID查询延误记录
*/
public List<DelayPenaltyRecord> getDelayRecordsByTaskId(Long taskId) {
return delayPenaltyRecordMapper.findByTaskId(taskId);
}
/**
* 根据设计师ID查询延误记录
*/
public List<DelayPenaltyRecord> getDelayRecordsByDesignerId(Long designerId) {
return delayPenaltyRecordMapper.findByDesignerId(designerId);
}
/**
* 统计设计师的延误扣分总数
*/
public Integer getTotalPenaltyScoreByDesignerId(Long designerId) {
Integer total = delayPenaltyRecordMapper.sumPenaltyScoreByDesignerId(designerId);
return total != null ? total : 0;
}
/**
* 申诉延误扣分
*/
@Transactional(rollbackFor = Exception.class)
public void appealDelayPenalty(Long recordId, Long designerId, String appealReason) {
DelayPenaltyRecord record = delayPenaltyRecordMapper.selectById(recordId);
if (record == null) {
throw new RuntimeException("延误扣分记录不存在");
}
if (!record.getDesignerId().equals(designerId)) {
throw new RuntimeException("无权申诉此记录");
}
if (!"confirmed".equals(record.getStatus())) {
throw new RuntimeException("该记录已申诉或已处理");
}
record.setStatus("appealed");
record.setAppealReason(appealReason);
record.setAppealTime(LocalDateTime.now());
delayPenaltyRecordMapper.updateById(record);
log.info("设计师申诉延误扣分: recordId={}, designerId={}, reason={}",
recordId, designerId, appealReason);
}
/**
* 管理员审批申诉
*/
@Transactional(rollbackFor = Exception.class)
public void approveAppeal(Long recordId, Long approverId, Boolean approved, String appealResult) {
DelayPenaltyRecord record = delayPenaltyRecordMapper.selectById(recordId);
if (record == null) {
throw new RuntimeException("延误扣分记录不存在");
}
if (!"appealed".equals(record.getStatus())) {
throw new RuntimeException("该记录不是申诉状态");
}
if (approved) {
record.setStatus("approved");
} else {
record.setStatus("rejected");
}
record.setAppealResult(appealResult);
record.setApproverId(approverId);
record.setApproveTime(LocalDateTime.now());
delayPenaltyRecordMapper.updateById(record);
log.info("管理员审批申诉: recordId={}, approverId={}, approved={}",
recordId, approverId, approved);
}
}