Merge branch 'dev2' of http://110.42.96.64:19890/GoCo/OL-LearnPlatform-Backend into dev2
merge
This commit is contained in:
commit
a3a1ef430e
@ -1,5 +1,7 @@
|
|||||||
package org.jeecg.modules.aiol.controller;
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -17,6 +19,7 @@ import org.jeecg.common.api.vo.Result;
|
|||||||
import org.jeecg.common.system.query.QueryGenerator;
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.dto.ExaminationResult;
|
||||||
import org.jeecg.modules.aiol.dto.QuestionAnswerDTO;
|
import org.jeecg.modules.aiol.dto.QuestionAnswerDTO;
|
||||||
import org.jeecg.modules.aiol.dto.QuestionAnswerUser;
|
import org.jeecg.modules.aiol.dto.QuestionAnswerUser;
|
||||||
import org.jeecg.modules.aiol.entity.*;
|
import org.jeecg.modules.aiol.entity.*;
|
||||||
@ -317,11 +320,10 @@ public class AiolExamController extends JeecgController<AiolExam, IAiolExamServi
|
|||||||
updateWrapper.set(AiolExamRecord::getDeviceInfo, examRecord.getDeviceInfo());
|
updateWrapper.set(AiolExamRecord::getDeviceInfo, examRecord.getDeviceInfo());
|
||||||
}
|
}
|
||||||
// 阅卷
|
// 阅卷
|
||||||
List<AiolExamAnswer> gradedAnswers = gradeExam(examRecord.getExamId(), examRecord.getUserId());
|
List<AiolExamAnswer> gradedAnswers = gradeExam(examRecord.getExamId(), examRecord.getUserId(), updateWrapper);
|
||||||
examAnswerService.updateBatchById(gradedAnswers);
|
examAnswerService.updateBatchById(gradedAnswers);
|
||||||
// 更新考试状态,提交时间
|
// 更新考试状态,提交时间
|
||||||
updateWrapper.
|
updateWrapper.
|
||||||
set(AiolExamRecord::getStatus,1).
|
|
||||||
set(AiolExamRecord::getSubmittedAt, new Date());
|
set(AiolExamRecord::getSubmittedAt, new Date());
|
||||||
// 更新
|
// 更新
|
||||||
return examRecordService.update(updateWrapper) ? Result.OK() : Result.error("提交考试失败");
|
return examRecordService.update(updateWrapper) ? Result.OK() : Result.error("提交考试失败");
|
||||||
@ -522,7 +524,15 @@ public class AiolExamController extends JeecgController<AiolExam, IAiolExamServi
|
|||||||
.eq(AiolExamRecord::getUserId, userId)
|
.eq(AiolExamRecord::getUserId, userId)
|
||||||
);
|
);
|
||||||
if(one == null){
|
if(one == null){
|
||||||
return Result.error("用户暂未考试,可获取考试题目");
|
return Result.ok("用户暂未考试,可获取考试题目");
|
||||||
|
}
|
||||||
|
LocalDateTime submittedAt = LocalDateTime.ofInstant(one.getSubmittedAt().toInstant(), ZoneId.systemDefault());
|
||||||
|
LocalDateTime examEndTime = submittedAt.plusMinutes(byId.getTotalTime());
|
||||||
|
if(examEndTime.isAfter(LocalDateTime.now(ZoneId.systemDefault()))){
|
||||||
|
return Result.ok("考试总时间已过");
|
||||||
|
}
|
||||||
|
if(one.getStatus() == 2){
|
||||||
|
return Result.OK("已批改",one);
|
||||||
}
|
}
|
||||||
return Result.OK(examAnswerService.
|
return Result.OK(examAnswerService.
|
||||||
list(new LambdaQueryWrapper<AiolExamAnswer>().
|
list(new LambdaQueryWrapper<AiolExamAnswer>().
|
||||||
@ -531,6 +541,113 @@ public class AiolExamController extends JeecgController<AiolExam, IAiolExamServi
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//查询考试结果
|
||||||
|
@GetMapping("/queryExamResult")
|
||||||
|
@Operation(summary = "查询考试结果")
|
||||||
|
public Result<?> queryExamResult(@RequestParam String examId, @RequestParam String userId) {
|
||||||
|
AiolExamRecord one = examRecordService.getOne(
|
||||||
|
new LambdaQueryWrapper<AiolExamRecord>()
|
||||||
|
.eq(AiolExamRecord::getExamId, examId)
|
||||||
|
.eq(AiolExamRecord::getUserId, userId)
|
||||||
|
);
|
||||||
|
if(one == null){
|
||||||
|
return Result.error("考试记录不存在");
|
||||||
|
}
|
||||||
|
if(one.getStatus() != 2){
|
||||||
|
return Result.error("考试未批改");
|
||||||
|
}
|
||||||
|
// 获取学生的答题列表
|
||||||
|
List<AiolExamAnswer> examAnswerList = examAnswerService.list(
|
||||||
|
new LambdaQueryWrapper<AiolExamAnswer>()
|
||||||
|
.eq(AiolExamAnswer::getExamId, examId)
|
||||||
|
.eq(AiolExamAnswer::getUserId, userId)
|
||||||
|
);
|
||||||
|
//创建题目id到学生答案的映射
|
||||||
|
Map<String, AiolExamAnswer> examAnswerMap = examAnswerList.stream()
|
||||||
|
.collect(Collectors.toMap(AiolExamAnswer::getQuestionId, examAnswer -> examAnswer));
|
||||||
|
// 提取所有题目ID
|
||||||
|
List<String> questionIds = examAnswerList.stream()
|
||||||
|
.map(AiolExamAnswer::getQuestionId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
// 查询题目
|
||||||
|
List<AiolQuestion> questions = questionService.list(
|
||||||
|
new LambdaQueryWrapper<AiolQuestion>()
|
||||||
|
.in(AiolQuestion::getId, questionIds)
|
||||||
|
);
|
||||||
|
// 按父题目id分类
|
||||||
|
Map<String, List<AiolQuestion>> questionsByParentId = questions.stream()
|
||||||
|
.collect(Collectors.groupingBy(
|
||||||
|
q -> q.getParentId() != null ? q.getParentId() : "NULL_PARENT"
|
||||||
|
));
|
||||||
|
// 按题目类型分组
|
||||||
|
Map<Integer, List<AiolQuestion>> questionsByType = questions.stream()
|
||||||
|
.collect(Collectors.groupingBy(AiolQuestion::getType));
|
||||||
|
// 分离选择题(0、1、2)
|
||||||
|
List<AiolQuestion> choiceQuestions = questionsByType.entrySet().stream()
|
||||||
|
.filter(entry -> entry.getKey() < 3)
|
||||||
|
.flatMap(entry -> entry.getValue().stream())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
// 获取填空题和简答题(3、4)
|
||||||
|
List<AiolQuestion> fillAndEssayQuestions = new ArrayList<>();
|
||||||
|
if (questionsByType.containsKey(3)) {
|
||||||
|
fillAndEssayQuestions.addAll(questionsByType.get(3));
|
||||||
|
}
|
||||||
|
if (questionsByType.containsKey(4)) {
|
||||||
|
fillAndEssayQuestions.addAll(questionsByType.get(4));
|
||||||
|
}
|
||||||
|
// 查询题目的选项
|
||||||
|
List<AiolQuestionOption> questionOptions = questionOptionService.list(
|
||||||
|
new LambdaQueryWrapper<AiolQuestionOption>()
|
||||||
|
.in(AiolQuestionOption::getQuestionId,
|
||||||
|
choiceQuestions.stream()
|
||||||
|
.map(AiolQuestion::getId)
|
||||||
|
.collect(Collectors.toList()))
|
||||||
|
);
|
||||||
|
// 查询填空题简答题的答案
|
||||||
|
List<AiolQuestionAnswer> questionAnswers = questionAnswerService.list(
|
||||||
|
new LambdaQueryWrapper<AiolQuestionAnswer>()
|
||||||
|
.in(AiolQuestionAnswer::getQuestionId,
|
||||||
|
fillAndEssayQuestions.stream()
|
||||||
|
.map(AiolQuestion::getId)
|
||||||
|
.collect(Collectors.toList()))
|
||||||
|
);
|
||||||
|
// 构建选择题选项映射:题目ID -> 选项列表
|
||||||
|
Map<String, List<AiolQuestionOption>> questionOptionMap = questionOptions.stream()
|
||||||
|
.collect(Collectors.groupingBy(AiolQuestionOption::getQuestionId));
|
||||||
|
|
||||||
|
// 构建填空题和简答题答案映射:题目ID -> 答案列表
|
||||||
|
Map<String, List<AiolQuestionAnswer>> questionAnswerMap = questionAnswers.stream()
|
||||||
|
.collect(Collectors.groupingBy(AiolQuestionAnswer::getQuestionId));
|
||||||
|
|
||||||
|
// 合并到一个映射中
|
||||||
|
Map<String, List<?>> questionOrIdMap = new HashMap<>();
|
||||||
|
questionOrIdMap.putAll(questionOptionMap);
|
||||||
|
questionOrIdMap.putAll(questionAnswerMap);
|
||||||
|
List<ExaminationResult> examinationResultList = new ArrayList<>();
|
||||||
|
// 遍历没有父题目的题目
|
||||||
|
questionsByParentId.get("NULL_PARENT").forEach(q -> {
|
||||||
|
ExaminationResult examinationResult = new ExaminationResult();
|
||||||
|
examinationResult.setQuestion(q);
|
||||||
|
examinationResult.setUserAnswer(examAnswerMap.get(q.getId()));
|
||||||
|
examinationResult.setAnswer(questionOrIdMap.get(q.getId()));
|
||||||
|
// 检查当前题目是否是复合题目
|
||||||
|
if (questionsByParentId.containsKey(q.getId())) {
|
||||||
|
// 如果是复合题目,查找其子题目
|
||||||
|
List<ExaminationResult> childResults = new ArrayList<>();
|
||||||
|
questionsByParentId.get(q.getId()).forEach(childQ -> {
|
||||||
|
ExaminationResult childResult = new ExaminationResult();
|
||||||
|
childResult.setQuestion(childQ);
|
||||||
|
childResult.setUserAnswer(examAnswerMap.get(childQ.getId()));
|
||||||
|
childResult.setAnswer(questionOrIdMap.get(childQ.getId()));
|
||||||
|
childResults.add(childResult);
|
||||||
|
});
|
||||||
|
examinationResult.setChildren(childResults);
|
||||||
|
}
|
||||||
|
examinationResultList.add(examinationResult);
|
||||||
|
});
|
||||||
|
return Result.OK(examinationResultList);
|
||||||
|
}
|
||||||
|
|
||||||
//根据考试规则随机组卷
|
//根据考试规则随机组卷
|
||||||
public List<String> random(List<AiolQuestionRepo> list, String rules) {
|
public List<String> random(List<AiolQuestionRepo> list, String rules) {
|
||||||
JSONObject ruleJson = JSON.parseObject(rules);
|
JSONObject ruleJson = JSON.parseObject(rules);
|
||||||
@ -620,9 +737,10 @@ public class AiolExamController extends JeecgController<AiolExam, IAiolExamServi
|
|||||||
* 批量阅卷
|
* 批量阅卷
|
||||||
* @param examId 考试ID
|
* @param examId 考试ID
|
||||||
* @param userId 用户ID
|
* @param userId 用户ID
|
||||||
|
*
|
||||||
* @return 阅卷后的答题列表
|
* @return 阅卷后的答题列表
|
||||||
*/
|
*/
|
||||||
private List<AiolExamAnswer> gradeExam(String examId, String userId) {
|
private List<AiolExamAnswer> gradeExam(String examId, String userId , LambdaUpdateWrapper<AiolExamRecord> updateWrapper) {
|
||||||
//获取试卷信息
|
//获取试卷信息
|
||||||
AiolExam exam = examService.getById(examId);
|
AiolExam exam = examService.getById(examId);
|
||||||
//获取组卷信息
|
//获取组卷信息
|
||||||
@ -714,6 +832,7 @@ public class AiolExamController extends JeecgController<AiolExam, IAiolExamServi
|
|||||||
));
|
));
|
||||||
|
|
||||||
// 遍历学生的答案,进行评分
|
// 遍历学生的答案,进行评分
|
||||||
|
Double totalPoint = 0.0;
|
||||||
for (AiolExamAnswer examAnswer : examAnswerList) {
|
for (AiolExamAnswer examAnswer : examAnswerList) {
|
||||||
String studentAnswer = examAnswer.getAnswer();
|
String studentAnswer = examAnswer.getAnswer();
|
||||||
AiolQuestion question = questionMap.get(examAnswer.getQuestionId());
|
AiolQuestion question = questionMap.get(examAnswer.getQuestionId());
|
||||||
@ -818,13 +937,21 @@ public class AiolExamController extends JeecgController<AiolExam, IAiolExamServi
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
totalPoint += score;
|
||||||
examAnswer.setScore(score);
|
examAnswer.setScore(score);
|
||||||
// 只有得了满分才算对
|
// 只有得了满分才算对
|
||||||
examAnswer.setIzCorrect(score > 0 && score == (paper.getGenerateMode() == 0 ?
|
examAnswer.setIzCorrect(score > 0 && score == (paper.getGenerateMode() == 0 ?
|
||||||
questionScoreMap.get(question.getId()) :
|
questionScoreMap.get(question.getId()) :
|
||||||
ruleJson.getDouble("type" + question.getType() + "_score")) ? 1 : 0);
|
ruleJson.getDouble("type" + question.getType() + "_score")) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
if(paper.getRequireReview()==1){
|
||||||
|
updateWrapper
|
||||||
|
.set(AiolExamRecord::getStatus, 1);
|
||||||
|
}else {
|
||||||
|
updateWrapper
|
||||||
|
.set(AiolExamRecord::getStatus, 2)
|
||||||
|
.set(AiolExamRecord::getTotalScore, totalPoint);
|
||||||
|
}
|
||||||
return examAnswerList;
|
return examAnswerList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolExamAnswer;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestion;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ExaminationResult {
|
||||||
|
//题目内容
|
||||||
|
private AiolQuestion question;
|
||||||
|
//选项答案
|
||||||
|
private List<?> answer;
|
||||||
|
//用户答案
|
||||||
|
private AiolExamAnswer userAnswer;
|
||||||
|
//子题目列表
|
||||||
|
private List<ExaminationResult> children;
|
||||||
|
}
|
@ -2,6 +2,7 @@ package org.jeecg.modules.aiol.mapper;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.jeecg.modules.aiol.entity.AiolRepo;
|
import org.jeecg.modules.aiol.entity.AiolRepo;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
@ -12,6 +13,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|||||||
* @Date: 2025-08-31
|
* @Date: 2025-08-31
|
||||||
* @Version: V1.0
|
* @Version: V1.0
|
||||||
*/
|
*/
|
||||||
|
@Mapper
|
||||||
public interface AiolRepoMapper extends BaseMapper<AiolRepo> {
|
public interface AiolRepoMapper extends BaseMapper<AiolRepo> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user