Browse Source

Merge remote-tracking branch 'origin/master'

master
luogw 2 months ago
parent
commit
111fc9c70e
  1. 4
      src/main/java/com/project/classicpaper/application/ClassicPaperSetApplicationService.java
  2. 10
      src/main/java/com/project/classicpaper/application/impl/ClassicPaperSetApplicationServiceImpl.java
  3. 2
      src/main/java/com/project/classicpaper/controller/ClassicPaperSetController.java
  4. 23
      src/main/java/com/project/classicpaper/domain/service/impl/ImportClassicPaperDomainServiceImpl.java
  5. 5
      src/main/java/com/project/ding/domain/service/impl/AuthDomainServiceImpl.java
  6. 2
      src/main/java/com/project/exam/domain/service/impl/AdminSearchExamRecordDomainServiceImpl.java
  7. 61
      src/main/java/com/project/task/domain/service/strategy/ClassicTaskConfigStrategy.java

4
src/main/java/com/project/classicpaper/application/ClassicPaperSetApplicationService.java

@ -6,8 +6,6 @@ import com.project.classicpaper.domain.dto.ClassicPaperSetDTO;
import com.project.classicpaper.domain.param.ClassicPaperSetParam;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
public interface ClassicPaperSetApplicationService {
/**
@ -30,7 +28,7 @@ public interface ClassicPaperSetApplicationService {
/**
* 废弃套题组连带所有版本
*/
Result<String> delete(List<Long> ids) throws Exception;
Result<String> delete(String ids) throws Exception;
/**
* 更新分值比例同时计算每道题的分值

10
src/main/java/com/project/classicpaper/application/impl/ClassicPaperSetApplicationServiceImpl.java

@ -22,6 +22,7 @@ import com.project.classicpaper.domain.entity.ClassicCategoryEntity;
import com.project.classicpaper.domain.service.*;
import com.project.question.domain.entity.QuestionEntity;
import com.project.question.domain.service.QuestionBaseService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -229,8 +230,13 @@ public class ClassicPaperSetApplicationServiceImpl implements ClassicPaperSetApp
@Override
@Transactional(rollbackFor = Exception.class)
public Result<String> delete(List<Long> ids) throws Exception {
classicPaperSetBaseService.removeBatchByIds(ids);
public Result<String> delete(String ids) throws Exception {
if (StringUtils.isBlank(ids)) {
throw new BusinessErrorException("ids is empty");
}
List<Long> idList = Arrays.asList(ids.split(",")).stream().map(id -> Long.valueOf(id)).collect(Collectors.toList());
classicPaperSetBaseService.removeBatchByIds(idList);
return Result.success("删除成功");
}

2
src/main/java/com/project/classicpaper/controller/ClassicPaperSetController.java

@ -52,7 +52,7 @@ public class ClassicPaperSetController {
}
@PostMapping("/delete")
public Result<String> delete(List<Long> ids) throws Exception {
public Result<String> delete(String ids) throws Exception {
return classicPaperSetApplicationService.delete(ids);
}

23
src/main/java/com/project/classicpaper/domain/service/impl/ImportClassicPaperDomainServiceImpl.java

@ -1,5 +1,6 @@
package com.project.classicpaper.domain.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.project.classicpaper.domain.dto.ClassicPaperDTO;
import com.project.classicpaper.domain.dto.ClassicPaperQuestionDTO;
import com.project.classicpaper.domain.dto.ClassicPaperSetDTO;
@ -19,6 +20,7 @@ import com.project.question.domain.entity.QuestionEntity;
import com.project.question.domain.enums.QuestionSourceTypeEnum;
import com.project.question.domain.service.QuestionBaseService;
import com.project.question.domain.service.SaveQuestionDomainService;
import com.project.task.config.ExamScoreRatioConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -27,6 +29,7 @@ import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@ -62,6 +65,11 @@ public class ImportClassicPaperDomainServiceImpl implements ImportClassicPaperDo
@Autowired
private MinIoUtils minIoUtils;
@Autowired
private ExamScoreRatioConfig examScoreRatioConfig;
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
@Transactional(rollbackFor = Exception.class)
public ClassicPaperSetDTO importFromWord(MultipartFile file, Long classicCategoryId, String paperName) throws Exception {
@ -115,6 +123,21 @@ public class ImportClassicPaperDomainServiceImpl implements ImportClassicPaperDo
paperSet.setTrueFalseNum(trueFalseNum);
paperSet.setShortAnswerNum(shortAnswerNum);
paperSet.setStatus(ClassicPaperStatusEnum.DRAFT.getValue());
// 设置默认分值比例(只包含数量 > 0 的题型)
Map<String, Integer> ratioMap = new LinkedHashMap<>();
if (singleChoiceNum > 0) ratioMap.put("single", examScoreRatioConfig.getSingle());
if (multipleChoiceNum > 0) ratioMap.put("multiple", examScoreRatioConfig.getMultiple());
if (trueFalseNum > 0) ratioMap.put("trueFalse", examScoreRatioConfig.getTrueFalse());
if (shortAnswerNum > 0) ratioMap.put("shortAnswer", examScoreRatioConfig.getShortAnswer());
if (!ratioMap.isEmpty()) {
try {
paperSet.setScoreRatio(objectMapper.writeValueAsString(ratioMap));
} catch (Exception e) {
log.warn(">>> [历史导入] scoreRatio 序列化失败", e);
}
}
classicPaperSetBaseService.save(paperSet);
// 3. 创建套卷(版本1)

5
src/main/java/com/project/ding/domain/service/impl/AuthDomainServiceImpl.java

@ -15,6 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.security.core.GrantedAuthority;
@ -92,7 +93,9 @@ public class AuthDomainServiceImpl implements AuthDomainService {
if (Objects.nonNull(adminWhiteListEntity)) {
roles.add("ROLE_ADMIN");
}
if (adminWhiteListEntity.getAdminType() != null && adminWhiteListEntity.getAdminType() == 1) {
roles.add("ROLE_SUPER_ADMIN");
}
// 3. 生成 JWT
String token = jwtUtils.createToken(user.getId(), roles);

2
src/main/java/com/project/exam/domain/service/impl/AdminSearchExamRecordDomainServiceImpl.java

@ -147,7 +147,7 @@ public class AdminSearchExamRecordDomainServiceImpl implements AdminSearchExamRe
private ExamRecordPictureDTO buildPictureDTO(ExamRecordPictureEntity entity) {
ExamRecordPictureDTO dto = entity.toDTO(ExamRecordPictureDTO::new);
dto.setPreviewUrl(minIoUtils.getPreviewUrl(entity.getFilePath()));
dto.setPreviewUrl(minIoUtils.getPublicUrl(entity.getFilePath()));
return dto;
}
}

61
src/main/java/com/project/task/domain/service/strategy/ClassicTaskConfigStrategy.java

@ -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);
}
}
}

Loading…
Cancel
Save