|
|
|
@ -6,25 +6,37 @@ import cn.hutool.core.date.DateUtil; |
|
|
|
import cn.hutool.core.lang.Validator; |
|
|
|
import cn.hutool.core.util.StrUtil; |
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper; |
|
|
|
import com.project.base.domain.exception.BusinessErrorException; |
|
|
|
import com.project.classicpaper.domain.entity.ClassicPaperSetEntity; |
|
|
|
import com.project.classicpaper.domain.service.ClassicPaperSetBaseService; |
|
|
|
import com.project.task.domain.dto.TaskDTO; |
|
|
|
import com.project.task.domain.entity.TaskEntity; |
|
|
|
import com.project.task.domain.service.TaskBaseService; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.stereotype.Component; |
|
|
|
|
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.math.RoundingMode; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Objects; |
|
|
|
|
|
|
|
/** |
|
|
|
* 经典套题模式:校验 + 字段默认值 |
|
|
|
* 赋分来自套卷本身,此处不做赋分计算 |
|
|
|
*/ |
|
|
|
@Slf4j |
|
|
|
@Component |
|
|
|
public class ClassicTaskConfigStrategy implements TaskConfigStrategy { |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private TaskBaseService taskBaseService; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private ClassicPaperSetBaseService classicPaperSetBaseService; |
|
|
|
|
|
|
|
private final ObjectMapper objectMapper = new ObjectMapper(); |
|
|
|
|
|
|
|
@Override |
|
|
|
public void validateAndConfigure(TaskDTO dto) throws Exception { |
|
|
|
validate(dto); |
|
|
|
@ -85,7 +97,7 @@ public class ClassicTaskConfigStrategy implements TaskConfigStrategy { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 经典模式下题目数量和分数来自套卷,DTO 中可能为 null,赋默认值 0 避免 NPE |
|
|
|
* 经典模式下题目数量和分数来自套卷,DTO 中可能为 null,赋默认值避免 NPE |
|
|
|
*/ |
|
|
|
private void fillDefaults(TaskDTO dto) { |
|
|
|
if (dto.getSingleChoiceNum() == null) { |
|
|
|
@ -100,6 +112,10 @@ public class ClassicTaskConfigStrategy implements TaskConfigStrategy { |
|
|
|
if (dto.getShortAnswerNum() == null) { |
|
|
|
dto.setShortAnswerNum(0); |
|
|
|
} |
|
|
|
|
|
|
|
// 从套题组的分值比例计算每题分值(保留2位小数)
|
|
|
|
calculateScoresFromRatio(dto); |
|
|
|
|
|
|
|
if (dto.getSingleChoiceScore() == null) { |
|
|
|
dto.setSingleChoiceScore(0.0); |
|
|
|
} |
|
|
|
@ -119,7 +135,46 @@ public class ClassicTaskConfigStrategy implements TaskConfigStrategy { |
|
|
|
dto.setVagueGraspNum(0); |
|
|
|
} |
|
|
|
if (dto.getTotalScore() == null) { |
|
|
|
dto.setTotalScore(0); |
|
|
|
dto.setTotalScore(100); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 从 ClassicPaperSet.scoreRatio 解析比例,计算每题分值 |
|
|
|
* 公式:每题分值 = 100 × 题型比例 / 总比例 / 该题型数量 |
|
|
|
*/ |
|
|
|
private void calculateScoresFromRatio(TaskDTO dto) { |
|
|
|
if (dto.getClassicPaperSetId() == null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
ClassicPaperSetEntity paperSet = classicPaperSetBaseService.getById(dto.getClassicPaperSetId()); |
|
|
|
if (paperSet == null || StrUtil.isBlank(paperSet.getScoreRatio())) { |
|
|
|
return; |
|
|
|
} |
|
|
|
try { |
|
|
|
Map<String, Integer> ratioMap = objectMapper.readValue(paperSet.getScoreRatio(), Map.class); |
|
|
|
int totalRatio = ratioMap.values().stream().mapToInt(Integer::intValue).sum(); |
|
|
|
if (totalRatio <= 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
if (paperSet.getSingleChoiceNum() != null && paperSet.getSingleChoiceNum() > 0) { |
|
|
|
double perScore = 100.0 * ratioMap.getOrDefault("single", 0) / totalRatio / paperSet.getSingleChoiceNum(); |
|
|
|
dto.setSingleChoiceScore(BigDecimal.valueOf(perScore).setScale(2, RoundingMode.HALF_UP).doubleValue()); |
|
|
|
} |
|
|
|
if (paperSet.getMultipleChoiceNum() != null && paperSet.getMultipleChoiceNum() > 0) { |
|
|
|
double perScore = 100.0 * ratioMap.getOrDefault("multiple", 0) / totalRatio / paperSet.getMultipleChoiceNum(); |
|
|
|
dto.setMultipleChoiceScore(BigDecimal.valueOf(perScore).setScale(2, RoundingMode.HALF_UP).doubleValue()); |
|
|
|
} |
|
|
|
if (paperSet.getTrueFalseNum() != null && paperSet.getTrueFalseNum() > 0) { |
|
|
|
double perScore = 100.0 * ratioMap.getOrDefault("trueFalse", 0) / totalRatio / paperSet.getTrueFalseNum(); |
|
|
|
dto.setTrueFalseScore(BigDecimal.valueOf(perScore).setScale(2, RoundingMode.HALF_UP).doubleValue()); |
|
|
|
} |
|
|
|
if (paperSet.getShortAnswerNum() != null && paperSet.getShortAnswerNum() > 0) { |
|
|
|
double perScore = 100.0 * ratioMap.getOrDefault("shortAnswer", 0) / totalRatio / paperSet.getShortAnswerNum(); |
|
|
|
dto.setShortAnswerScore(BigDecimal.valueOf(perScore).setScale(2, RoundingMode.HALF_UP).doubleValue()); |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
log.warn(">>> [经典模式] scoreRatio 解析失败, paperSetId={}", dto.getClassicPaperSetId(), e); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|