|
|
|
@ -1,103 +1,167 @@
|
|
|
|
|
// 定义包名,表示该类属于com.yf.exam.modules.paper.service.impl包下
|
|
|
|
|
package com.yf.exam.modules.paper.service.impl;
|
|
|
|
|
|
|
|
|
|
// 导入MyBatis Plus框架的核心类,用于构建查询条件
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
|
|
// 导入MyBatis Plus框架的分页功能相关类
|
|
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
|
|
// 导入MyBatis Plus框架的工具类,用于生成唯一ID
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
|
|
|
|
// 导入MyBatis Plus框架的服务实现类
|
|
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
|
// 导入项目中定义的作业组枚举
|
|
|
|
|
import com.yf.exam.ability.job.enums.JobGroup;
|
|
|
|
|
// 导入项目中定义的作业前缀枚举
|
|
|
|
|
import com.yf.exam.ability.job.enums.JobPrefix;
|
|
|
|
|
// 导入项目中的作业服务接口
|
|
|
|
|
import com.yf.exam.ability.job.service.JobService;
|
|
|
|
|
// 导入项目中定义的API错误码类
|
|
|
|
|
import com.yf.exam.core.api.ApiError;
|
|
|
|
|
// 导入项目中定义的DTO类,用于分页请求
|
|
|
|
|
import com.yf.exam.core.api.dto.PagingReqDTO;
|
|
|
|
|
// 导入项目中的服务异常类
|
|
|
|
|
import com.yf.exam.core.exception.ServiceException;
|
|
|
|
|
// 导入项目中定义的Bean映射工具类
|
|
|
|
|
import com.yf.exam.core.utils.BeanMapper;
|
|
|
|
|
// 导入项目中定义的Cron表达式工具类
|
|
|
|
|
import com.yf.exam.core.utils.CronUtils;
|
|
|
|
|
// 导入项目中定义的考试DTO类
|
|
|
|
|
import com.yf.exam.modules.exam.dto.ExamDTO;
|
|
|
|
|
// 导入项目中定义的考试题库DTO类
|
|
|
|
|
import com.yf.exam.modules.exam.dto.ExamRepoDTO;
|
|
|
|
|
// 导入项目中定义的扩展考试题库DTO类
|
|
|
|
|
import com.yf.exam.modules.exam.dto.ext.ExamRepoExtDTO;
|
|
|
|
|
// 导入项目中的考试服务接口
|
|
|
|
|
import com.yf.exam.modules.exam.service.ExamRepoService;
|
|
|
|
|
// 导入项目中的考试服务接口
|
|
|
|
|
import com.yf.exam.modules.exam.service.ExamService;
|
|
|
|
|
// 导入项目中定义的试卷DTO类
|
|
|
|
|
import com.yf.exam.modules.paper.dto.PaperDTO;
|
|
|
|
|
// 导入项目中定义的试卷题目DTO类
|
|
|
|
|
import com.yf.exam.modules.paper.dto.PaperQuDTO;
|
|
|
|
|
// 导入项目中定义的扩展试卷题目答案DTO类
|
|
|
|
|
import com.yf.exam.modules.paper.dto.ext.PaperQuAnswerExtDTO;
|
|
|
|
|
// 导入项目中定义的试卷题目详情DTO类
|
|
|
|
|
import com.yf.exam.modules.paper.dto.ext.PaperQuDetailDTO;
|
|
|
|
|
// 导入项目中定义的试卷答案DTO类
|
|
|
|
|
import com.yf.exam.modules.paper.dto.request.PaperAnswerDTO;
|
|
|
|
|
// 导入项目中定义的试卷列表请求DTO类
|
|
|
|
|
import com.yf.exam.modules.paper.dto.request.PaperListReqDTO;
|
|
|
|
|
// 导入项目中定义的试卷列表响应DTO类
|
|
|
|
|
import com.yf.exam.modules.paper.dto.response.ExamDetailRespDTO;
|
|
|
|
|
// 导入项目中定义的考试结果响应DTO类
|
|
|
|
|
import com.yf.exam.modules.paper.dto.response.ExamResultRespDTO;
|
|
|
|
|
// 导入项目中定义的试卷列表响应DTO类
|
|
|
|
|
import com.yf.exam.modules.paper.dto.response.PaperListRespDTO;
|
|
|
|
|
// 导入项目中定义的试卷实体类
|
|
|
|
|
import com.yf.exam.modules.paper.entity.Paper;
|
|
|
|
|
// 导入项目中定义的试卷题目实体类
|
|
|
|
|
import com.yf.exam.modules.paper.entity.PaperQu;
|
|
|
|
|
// 导入项目中定义的试卷题目答案实体类
|
|
|
|
|
import com.yf.exam.modules.paper.entity.PaperQuAnswer;
|
|
|
|
|
// 导入项目中定义的考试状态枚举
|
|
|
|
|
import com.yf.exam.modules.paper.enums.ExamState;
|
|
|
|
|
// 导入项目中定义的试卷状态枚举
|
|
|
|
|
import com.yf.exam.modules.paper.enums.PaperState;
|
|
|
|
|
// 导入项目中定义的强制交卷作业类
|
|
|
|
|
import com.yf.exam.modules.paper.job.BreakExamJob;
|
|
|
|
|
// 导入项目中定义的试卷Mapper接口
|
|
|
|
|
import com.yf.exam.modules.paper.mapper.PaperMapper;
|
|
|
|
|
// 导入项目中定义的试卷题目服务接口
|
|
|
|
|
import com.yf.exam.modules.paper.service.PaperQuAnswerService;
|
|
|
|
|
// 导入项目中定义的试卷题目服务接口
|
|
|
|
|
import com.yf.exam.modules.paper.service.PaperQuService;
|
|
|
|
|
// 导入项目中定义的试卷服务接口
|
|
|
|
|
import com.yf.exam.modules.paper.service.PaperService;
|
|
|
|
|
// 导入项目中定义的题目实体类
|
|
|
|
|
import com.yf.exam.modules.qu.entity.Qu;
|
|
|
|
|
// 导入项目中定义的题目答案实体类
|
|
|
|
|
import com.yf.exam.modules.qu.entity.QuAnswer;
|
|
|
|
|
// 导入项目中定义的题目类型枚举
|
|
|
|
|
import com.yf.exam.modules.qu.enums.QuType;
|
|
|
|
|
// 导入项目中定义的题目服务接口
|
|
|
|
|
import com.yf.exam.modules.qu.service.QuAnswerService;
|
|
|
|
|
// 导入项目中定义的题目服务接口
|
|
|
|
|
import com.yf.exam.modules.qu.service.QuService;
|
|
|
|
|
// 导入项目中定义的系统用户实体类
|
|
|
|
|
import com.yf.exam.modules.sys.user.entity.SysUser;
|
|
|
|
|
// 导入项目中定义的系统用户服务接口
|
|
|
|
|
import com.yf.exam.modules.sys.user.service.SysUserService;
|
|
|
|
|
// 导入项目中定义的用户书籍服务接口
|
|
|
|
|
import com.yf.exam.modules.user.book.service.UserBookService;
|
|
|
|
|
// 导入项目中定义的用户考试服务接口
|
|
|
|
|
import com.yf.exam.modules.user.exam.service.UserExamService;
|
|
|
|
|
// 导入Apache Commons Lang库中的StringUtils类,用于字符串操作
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
// 导入Spring框架中的注解,用于自动注入依赖
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
// 导入Spring框架中的注解,用于声明服务组件
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
// 导入Spring框架中的注解,用于声明事务管理
|
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
// 导入Spring框架中的类,用于工具操作
|
|
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
|
|
|
|
|
|
// 导入Java.util包下的类,用于集合操作
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
// 定义语言设置服务实现类,继承自ServiceImpl,并实现PaperService接口
|
|
|
|
|
/**
|
|
|
|
|
* <p>
|
|
|
|
|
* 语言设置 服务实现类
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @author 聪明笨狗
|
|
|
|
|
* @since 2020-05-25 16:33
|
|
|
|
|
*/
|
|
|
|
|
* <p>
|
|
|
|
|
* 语言设置 服务实现类
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @author 聪明笨狗
|
|
|
|
|
* @since 2020-05-25 16:33
|
|
|
|
|
*/
|
|
|
|
|
@Service
|
|
|
|
|
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements PaperService {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 自动注入系统用户服务
|
|
|
|
|
@Autowired
|
|
|
|
|
private SysUserService sysUserService;
|
|
|
|
|
|
|
|
|
|
// 自动注入考试服务
|
|
|
|
|
@Autowired
|
|
|
|
|
private ExamService examService;
|
|
|
|
|
|
|
|
|
|
// 自动注入题目服务
|
|
|
|
|
@Autowired
|
|
|
|
|
private QuService quService;
|
|
|
|
|
|
|
|
|
|
// 自动注入题目答案服务
|
|
|
|
|
@Autowired
|
|
|
|
|
private QuAnswerService quAnswerService;
|
|
|
|
|
|
|
|
|
|
// 自动注入试卷服务
|
|
|
|
|
@Autowired
|
|
|
|
|
private PaperService paperService;
|
|
|
|
|
|
|
|
|
|
// 自动注入试卷题目服务
|
|
|
|
|
@Autowired
|
|
|
|
|
private PaperQuService paperQuService;
|
|
|
|
|
|
|
|
|
|
// 自动注入试卷题目答案服务
|
|
|
|
|
@Autowired
|
|
|
|
|
private PaperQuAnswerService paperQuAnswerService;
|
|
|
|
|
|
|
|
|
|
// 自动注入用户书籍服务
|
|
|
|
|
@Autowired
|
|
|
|
|
private UserBookService userBookService;
|
|
|
|
|
|
|
|
|
|
// 自动注入考试题库服务
|
|
|
|
|
@Autowired
|
|
|
|
|
private ExamRepoService examRepoService;
|
|
|
|
|
|
|
|
|
|
// 自动注入用户考试服务
|
|
|
|
|
@Autowired
|
|
|
|
|
private UserExamService userExamService;
|
|
|
|
|
|
|
|
|
|
// 自动注入作业服务
|
|
|
|
|
@Autowired
|
|
|
|
|
private JobService jobService;
|
|
|
|
|
|
|
|
|
|
// 定义展示的选项,如ABC这样的选项列表
|
|
|
|
|
/**
|
|
|
|
|
* 展示的选项,ABC这样
|
|
|
|
|
*/
|
|
|
|
@ -106,68 +170,83 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
|
|
|
|
|
,"Y","Z"
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 声明创建试卷的方法,使用事务管理,如果发生异常则回滚
|
|
|
|
|
/**
|
|
|
|
|
* 创建试卷的方法
|
|
|
|
|
* @param userId 用户ID
|
|
|
|
|
* @param examId 考试ID
|
|
|
|
|
* @return 返回试卷ID
|
|
|
|
|
*/
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
@Override
|
|
|
|
|
public String createPaper(String userId, String examId) {
|
|
|
|
|
|
|
|
|
|
// 校验是否有正在考试的试卷
|
|
|
|
|
// 构建查询条件,查询是否有正在考试的试卷
|
|
|
|
|
QueryWrapper<Paper> wrapper = new QueryWrapper<>();
|
|
|
|
|
wrapper.lambda()
|
|
|
|
|
.eq(Paper::getUserId, userId)
|
|
|
|
|
.eq(Paper::getState, PaperState.ING);
|
|
|
|
|
|
|
|
|
|
// 统计符合条件的试卷数量
|
|
|
|
|
int exists = this.count(wrapper);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 如果存在正在考试的试卷,则抛出服务异常
|
|
|
|
|
if (exists > 0) {
|
|
|
|
|
throw new ServiceException(ApiError.ERROR_20010002);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查找考试
|
|
|
|
|
// 根据考试ID查询考试信息
|
|
|
|
|
ExamDTO exam = examService.findById(examId);
|
|
|
|
|
|
|
|
|
|
// 如果考试信息不存在,则抛出服务异常
|
|
|
|
|
if(exam == null){
|
|
|
|
|
throw new ServiceException(1, "考试不存在!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果考试状态不正确,则抛出服务异常
|
|
|
|
|
if(!ExamState.ENABLE.equals(exam.getState())){
|
|
|
|
|
throw new ServiceException(1, "考试状态不正确!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 考试题目列表
|
|
|
|
|
// 根据考试ID生成试卷题目列表
|
|
|
|
|
|
|
|
|
|
List<PaperQu> quList = this.generateByRepo(examId);
|
|
|
|
|
|
|
|
|
|
// 如果题目列表为空,则抛出服务异常
|
|
|
|
|
if(CollectionUtils.isEmpty(quList)){
|
|
|
|
|
throw new ServiceException(1, "规则不正确,无对应的考题!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//保存试卷内容
|
|
|
|
|
// 保存试卷内容,并返回试卷ID
|
|
|
|
|
Paper paper = this.savePaper(userId, exam, quList);
|
|
|
|
|
|
|
|
|
|
// 强制交卷任务
|
|
|
|
|
// 添加强制交卷任务
|
|
|
|
|
String jobName = JobPrefix.BREAK_EXAM + paper.getId();
|
|
|
|
|
jobService.addCronJob(BreakExamJob.class, jobName, CronUtils.dateToCron(paper.getLimitTime()), paper.getId());
|
|
|
|
|
|
|
|
|
|
return paper.getId();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ExamDetailRespDTO paperDetail(String paperId) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 声明查询试卷详情的方法
|
|
|
|
|
/**
|
|
|
|
|
* 查询试卷详情的方法
|
|
|
|
|
* @param paperId 试卷ID
|
|
|
|
|
* @return 返回考试详情响应DTO
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ExamDetailRespDTO paperDetail(String paperId) {
|
|
|
|
|
|
|
|
|
|
// 创建考试详情响应DTO对象
|
|
|
|
|
ExamDetailRespDTO respDTO = new ExamDetailRespDTO();
|
|
|
|
|
|
|
|
|
|
// 试题基本信息
|
|
|
|
|
// 根据试卷ID查询试卷基本信息,并复制到响应DTO中
|
|
|
|
|
Paper paper = paperService.getById(paperId);
|
|
|
|
|
BeanMapper.copy(paper, respDTO);
|
|
|
|
|
|
|
|
|
|
// 查找题目列表
|
|
|
|
|
// 根据试卷ID查询题目列表
|
|
|
|
|
List<PaperQuDTO> list = paperQuService.listByPaper(paperId);
|
|
|
|
|
|
|
|
|
|
// 分类题目列表
|
|
|
|
|
List<PaperQuDTO> radioList = new ArrayList<>();
|
|
|
|
|
List<PaperQuDTO> multiList = new ArrayList<>();
|
|
|
|
|
List<PaperQuDTO> judgeList = new ArrayList<>();
|
|
|
|
@ -183,69 +262,87 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置分类后的题目列表到响应DTO中
|
|
|
|
|
respDTO.setRadioList(radioList);
|
|
|
|
|
respDTO.setMultiList(multiList);
|
|
|
|
|
respDTO.setJudgeList(judgeList);
|
|
|
|
|
return respDTO;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ExamResultRespDTO paperResult(String paperId) {
|
|
|
|
|
// 声明查询试卷结果的方法
|
|
|
|
|
/**
|
|
|
|
|
* 查询试卷结果的方法
|
|
|
|
|
* @param paperId 试卷ID
|
|
|
|
|
* @return 返回考试结果响应DTO
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ExamResultRespDTO paperResult(String paperId) {
|
|
|
|
|
|
|
|
|
|
// 创建考试结果响应DTO对象
|
|
|
|
|
ExamResultRespDTO respDTO = new ExamResultRespDTO();
|
|
|
|
|
|
|
|
|
|
// 试题基本信息
|
|
|
|
|
// 根据试卷ID查询试卷基本信息,并复制到响应DTO中
|
|
|
|
|
Paper paper = paperService.getById(paperId);
|
|
|
|
|
BeanMapper.copy(paper, respDTO);
|
|
|
|
|
|
|
|
|
|
// 根据试卷ID查询题目列表
|
|
|
|
|
List<PaperQuDetailDTO> quList = paperQuService.listForPaperResult(paperId);
|
|
|
|
|
respDTO.setQuList(quList);
|
|
|
|
|
|
|
|
|
|
return respDTO;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public PaperQuDetailDTO findQuDetail(String paperId, String quId) {
|
|
|
|
|
// 声明查询题目详情的方法
|
|
|
|
|
/**
|
|
|
|
|
* 查询题目详情的方法
|
|
|
|
|
* @param paperId 试卷ID
|
|
|
|
|
* @param quId 题目ID
|
|
|
|
|
* @return 返回题目详情DTO
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public PaperQuDetailDTO findQuDetail(String paperId, String quId) {
|
|
|
|
|
|
|
|
|
|
// 创建题目详情DTO对象
|
|
|
|
|
PaperQuDetailDTO respDTO = new PaperQuDetailDTO();
|
|
|
|
|
// 问题
|
|
|
|
|
// 根据题目ID查询题目信息
|
|
|
|
|
Qu qu = quService.getById(quId);
|
|
|
|
|
|
|
|
|
|
// 基本信息
|
|
|
|
|
// 根据试卷ID和题目ID查询试卷题目信息,并复制到响应DTO中
|
|
|
|
|
PaperQu paperQu = paperQuService.findByKey(paperId, quId);
|
|
|
|
|
BeanMapper.copy(paperQu, respDTO);
|
|
|
|
|
respDTO.setContent(qu.getContent());
|
|
|
|
|
respDTO.setImage(qu.getImage());
|
|
|
|
|
|
|
|
|
|
// 答案列表
|
|
|
|
|
// 根据试卷ID和题目ID查询答案列表,并设置到响应DTO中
|
|
|
|
|
List<PaperQuAnswerExtDTO> list = paperQuAnswerService.listForExam(paperId, quId);
|
|
|
|
|
respDTO.setAnswerList(list);
|
|
|
|
|
|
|
|
|
|
return respDTO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 题库组题方式产生题目列表
|
|
|
|
|
* @param examId
|
|
|
|
|
* @return
|
|
|
|
|
// 声明题库组题方式产生题目列表的私有方法
|
|
|
|
|
/**
|
|
|
|
|
* 题库组题方式产生题目列表的方法
|
|
|
|
|
* @param examId 考试ID
|
|
|
|
|
* @return 返回题目列表
|
|
|
|
|
*/
|
|
|
|
|
private List<PaperQu> generateByRepo(String examId){
|
|
|
|
|
private List<PaperQu> generateByRepo(String examId){
|
|
|
|
|
|
|
|
|
|
// 查找规则指定的题库
|
|
|
|
|
// 查询规则指定的题库
|
|
|
|
|
List<ExamRepoExtDTO> list = examRepoService.listByExam(examId);
|
|
|
|
|
|
|
|
|
|
//最终的题目列表
|
|
|
|
|
// 最终的题目列表
|
|
|
|
|
List<PaperQu> quList = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
//排除ID,避免题目重复
|
|
|
|
|
// 排除ID,避免题目重复
|
|
|
|
|
List<String> excludes = new ArrayList<>();
|
|
|
|
|
excludes.add("none");
|
|
|
|
|
|
|
|
|
|
// 如果题库列表不为空,则进行题目抽取
|
|
|
|
|
if (!CollectionUtils.isEmpty(list)) {
|
|
|
|
|
for (ExamRepoExtDTO item : list) {
|
|
|
|
|
|
|
|
|
|
// 单选题
|
|
|
|
|
// 抽取单选题
|
|
|
|
|
if(item.getRadioCount() > 0){
|
|
|
|
|
List<Qu> radioList = quService.listByRandom(item.getRepoId(), QuType.RADIO, excludes, item.getRadioCount());
|
|
|
|
|
for (Qu qu : radioList) {
|
|
|
|
@ -255,7 +352,7 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//多选题
|
|
|
|
|
// 抽取多选题
|
|
|
|
|
if(item.getMultiCount() > 0) {
|
|
|
|
|
List<Qu> multiList = quService.listByRandom(item.getRepoId(), QuType.MULTI, excludes,
|
|
|
|
|
item.getMultiCount());
|
|
|
|
@ -266,7 +363,7 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 判断题
|
|
|
|
|
// 抽取判断题
|
|
|
|
|
if(item.getJudgeCount() > 0) {
|
|
|
|
|
List<Qu> judgeList = quService.listByRandom(item.getRepoId(), QuType.JUDGE, excludes,
|
|
|
|
|
item.getJudgeCount());
|
|
|
|
@ -279,58 +376,60 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return quList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 填充试题题目信息
|
|
|
|
|
* @param repo
|
|
|
|
|
* @param qu
|
|
|
|
|
* @return
|
|
|
|
|
// 声明填充试题题目信息的私有方法
|
|
|
|
|
/**
|
|
|
|
|
* 填充试题题目信息的方法
|
|
|
|
|
* @param repo 考试题库DTO
|
|
|
|
|
* @param qu 题目实体
|
|
|
|
|
* @return 返回试卷题目实体
|
|
|
|
|
*/
|
|
|
|
|
private PaperQu processPaperQu(ExamRepoDTO repo, Qu qu) {
|
|
|
|
|
private PaperQu processPaperQu(ExamRepoDTO repo, Qu qu) {
|
|
|
|
|
|
|
|
|
|
//保存试题信息
|
|
|
|
|
// 创建试卷题目实体
|
|
|
|
|
PaperQu paperQu = new PaperQu();
|
|
|
|
|
paperQu.setQuId(qu.getId());
|
|
|
|
|
paperQu.setAnswered(false);
|
|
|
|
|
paperQu.setIsRight(false);
|
|
|
|
|
paperQu.setQuType(qu.getQuType());
|
|
|
|
|
|
|
|
|
|
// 设置单选题分数
|
|
|
|
|
if (QuType.RADIO.equals(qu.getQuType())) {
|
|
|
|
|
paperQu.setScore(repo.getRadioScore());
|
|
|
|
|
paperQu.setActualScore(repo.getRadioScore());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置多选题分数
|
|
|
|
|
if (QuType.MULTI.equals(qu.getQuType())) {
|
|
|
|
|
paperQu.setScore(repo.getMultiScore());
|
|
|
|
|
paperQu.setActualScore(repo.getMultiScore());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置判断题分数
|
|
|
|
|
if (QuType.JUDGE.equals(qu.getQuType())) {
|
|
|
|
|
paperQu.setScore(repo.getJudgeScore());
|
|
|
|
|
paperQu.setActualScore(repo.getJudgeScore());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return paperQu;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 保存试卷
|
|
|
|
|
* @param userId
|
|
|
|
|
* @param exam
|
|
|
|
|
* @param quList
|
|
|
|
|
* @return
|
|
|
|
|
// 声明保存试卷的私有方法
|
|
|
|
|
/**
|
|
|
|
|
* 保存试卷的方法
|
|
|
|
|
* @param userId 用户ID
|
|
|
|
|
* @param exam 考试DTO
|
|
|
|
|
* @param quList 题目列表
|
|
|
|
|
* @return 返回试卷实体
|
|
|
|
|
*/
|
|
|
|
|
private Paper savePaper(String userId, ExamDTO exam, List<PaperQu> quList) {
|
|
|
|
|
private Paper savePaper(String userId, ExamDTO exam, List<PaperQu> quList) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 查找用户
|
|
|
|
|
// 根据用户ID查询用户信息
|
|
|
|
|
SysUser user = sysUserService.getById(userId);
|
|
|
|
|
|
|
|
|
|
//保存试卷基本信息
|
|
|
|
|
// 创建试卷基本信息,并设置属性
|
|
|
|
|
Paper paper = new Paper();
|
|
|
|
|
paper.setDepartId(user.getDepartId());
|
|
|
|
|
paper.setExamId(exam.getId());
|
|
|
|
@ -345,45 +444,51 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
|
|
|
|
|
paper.setState(PaperState.ING);
|
|
|
|
|
paper.setHasSaq(false);
|
|
|
|
|
|
|
|
|
|
// 截止时间
|
|
|
|
|
// 计算截止时间
|
|
|
|
|
Calendar cl = Calendar.getInstance();
|
|
|
|
|
cl.setTimeInMillis(System.currentTimeMillis());
|
|
|
|
|
cl.add(Calendar.MINUTE, exam.getTotalTime());
|
|
|
|
|
paper.setLimitTime(cl.getTime());
|
|
|
|
|
|
|
|
|
|
// 保存试卷基本信息
|
|
|
|
|
paperService.save(paper);
|
|
|
|
|
|
|
|
|
|
// 如果题目列表不为空,则保存试卷题目列表
|
|
|
|
|
if (!CollectionUtils.isEmpty(quList)) {
|
|
|
|
|
this.savePaperQu(paper.getId(), quList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return paper;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 保存试卷试题列表
|
|
|
|
|
* @param paperId
|
|
|
|
|
* @param quList
|
|
|
|
|
// 声明保存试卷试题列表的私有方法
|
|
|
|
|
/**
|
|
|
|
|
* 保存试卷试题列表的方法
|
|
|
|
|
* @param paperId 试卷ID
|
|
|
|
|
* @param quList 题目列表
|
|
|
|
|
*/
|
|
|
|
|
private void savePaperQu(String paperId, List<PaperQu> quList){
|
|
|
|
|
private void savePaperQu(String paperId, List<PaperQu> quList){
|
|
|
|
|
|
|
|
|
|
// 创建批量保存的题目列表和答案列表
|
|
|
|
|
List<PaperQu> batchQuList = new ArrayList<>();
|
|
|
|
|
List<PaperQuAnswer> batchAnswerList = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
// 初始化排序号
|
|
|
|
|
int sort = 0;
|
|
|
|
|
for (PaperQu item : quList) {
|
|
|
|
|
|
|
|
|
|
// 设置试卷ID和排序号,并生成ID
|
|
|
|
|
item.setPaperId(paperId);
|
|
|
|
|
item.setSort(sort);
|
|
|
|
|
item.setId(IdWorker.getIdStr());
|
|
|
|
|
|
|
|
|
|
//回答列表
|
|
|
|
|
// 查询题目的答案列表
|
|
|
|
|
List<QuAnswer> answerList = quAnswerService.listAnswerByRandom(item.getQuId());
|
|
|
|
|
|
|
|
|
|
// 如果答案列表不为空,则进行处理
|
|
|
|
|
if (!CollectionUtils.isEmpty(answerList)) {
|
|
|
|
|
|
|
|
|
|
// 初始化答案排序号
|
|
|
|
|
int ii = 0;
|
|
|
|
|
for (QuAnswer answer : answerList) {
|
|
|
|
|
PaperQuAnswer paperQuAnswer = new PaperQuAnswer();
|
|
|
|
@ -400,51 +505,57 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加到批量保存的题目列表中
|
|
|
|
|
batchQuList.add(item);
|
|
|
|
|
sort++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//添加问题
|
|
|
|
|
// 批量添加题目
|
|
|
|
|
paperQuService.saveBatch(batchQuList);
|
|
|
|
|
|
|
|
|
|
//批量添加问题答案
|
|
|
|
|
// 批量添加答案
|
|
|
|
|
paperQuAnswerService.saveBatch(batchAnswerList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
@Override
|
|
|
|
|
public void fillAnswer(PaperAnswerDTO reqDTO) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 声明填充答案的方法,使用事务管理
|
|
|
|
|
/**
|
|
|
|
|
* 填充答案的方法
|
|
|
|
|
* @param reqDTO 试卷答案DTO
|
|
|
|
|
*/
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
@Override
|
|
|
|
|
public void fillAnswer(PaperAnswerDTO reqDTO) {
|
|
|
|
|
|
|
|
|
|
// 未作答
|
|
|
|
|
// 如果答案列表为空且答案字符串也为空,则直接返回
|
|
|
|
|
if(CollectionUtils.isEmpty(reqDTO.getAnswers())
|
|
|
|
|
&& StringUtils.isBlank(reqDTO.getAnswer())){
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//查找答案列表
|
|
|
|
|
// 查询答案列表
|
|
|
|
|
List<PaperQuAnswer> list = paperQuAnswerService.listForFill(reqDTO.getPaperId(), reqDTO.getQuId());
|
|
|
|
|
|
|
|
|
|
//是否正确
|
|
|
|
|
// 初始化是否正确的标记
|
|
|
|
|
boolean right = true;
|
|
|
|
|
|
|
|
|
|
//更新正确答案
|
|
|
|
|
// 更新正确答案
|
|
|
|
|
for (PaperQuAnswer item : list) {
|
|
|
|
|
|
|
|
|
|
// 设置答案是否被选中
|
|
|
|
|
if (reqDTO.getAnswers().contains(item.getId())) {
|
|
|
|
|
item.setChecked(true);
|
|
|
|
|
} else {
|
|
|
|
|
item.setChecked(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//有一个对不上就是错的
|
|
|
|
|
// 如果有一个答案不正确,则标记为错误
|
|
|
|
|
if (item.getIsRight()!=null && !item.getIsRight().equals(item.getChecked())) {
|
|
|
|
|
right = false;
|
|
|
|
|
}
|
|
|
|
|
paperQuAnswerService.updateById(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//修改为已回答
|
|
|
|
|
// 修改为已回答
|
|
|
|
|
PaperQu qu = new PaperQu();
|
|
|
|
|
qu.setQuId(reqDTO.getQuId());
|
|
|
|
|
qu.setPaperId(reqDTO.getPaperId());
|
|
|
|
@ -454,29 +565,34 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
|
|
|
|
|
|
|
|
|
|
paperQuService.updateByKey(qu);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
@Override
|
|
|
|
|
public void handExam(String paperId) {
|
|
|
|
|
// 声明交卷的方法,使用事务管理
|
|
|
|
|
/**
|
|
|
|
|
* 交卷的方法
|
|
|
|
|
* @param paperId 试卷ID
|
|
|
|
|
*/
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
@Override
|
|
|
|
|
public void handExam(String paperId) {
|
|
|
|
|
|
|
|
|
|
//获取试卷信息
|
|
|
|
|
// 获取试卷信息
|
|
|
|
|
Paper paper = paperService.getById(paperId);
|
|
|
|
|
|
|
|
|
|
//如果不是正常的,抛出异常
|
|
|
|
|
// 如果试卷状态不正确,则抛出服务异常
|
|
|
|
|
if(!PaperState.ING.equals(paper.getState())){
|
|
|
|
|
throw new ServiceException(1, "试卷状态不正确!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 客观分
|
|
|
|
|
// 计算客观题分数
|
|
|
|
|
int objScore = paperQuService.sumObjective(paperId);
|
|
|
|
|
paper.setObjScore(objScore);
|
|
|
|
|
paper.setUserScore(objScore);
|
|
|
|
|
|
|
|
|
|
// 主观分,因为要阅卷,所以给0
|
|
|
|
|
// 设置主观题分数为0
|
|
|
|
|
paper.setSubjScore(0);
|
|
|
|
|
|
|
|
|
|
// 待阅卷
|
|
|
|
|
// 如果有主观题,则设置状态为待阅卷
|
|
|
|
|
if(paper.getHasSaq()) {
|
|
|
|
|
paper.setState(PaperState.WAIT_OPT);
|
|
|
|
|
}else {
|
|
|
|
@ -484,11 +600,12 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
|
|
|
|
|
// 同步保存考试成绩
|
|
|
|
|
userExamService.joinResult(paper.getUserId(), paper.getExamId(), objScore, objScore>=paper.getQualifyScore());
|
|
|
|
|
|
|
|
|
|
// 设置状态为已完成
|
|
|
|
|
paper.setState(PaperState.FINISHED);
|
|
|
|
|
}
|
|
|
|
|
paper.setUpdateTime(new Date());
|
|
|
|
|
|
|
|
|
|
//计算考试时长
|
|
|
|
|
// 计算考试时长
|
|
|
|
|
Calendar cl = Calendar.getInstance();
|
|
|
|
|
cl.setTimeInMillis(System.currentTimeMillis());
|
|
|
|
|
int userTime = (int)((System.currentTimeMillis() - paper.getCreateTime().getTime()) / 1000 / 60);
|
|
|
|
@ -497,15 +614,14 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
|
|
|
|
|
}
|
|
|
|
|
paper.setUserTime(userTime);
|
|
|
|
|
|
|
|
|
|
//更新试卷
|
|
|
|
|
// 更新试卷信息
|
|
|
|
|
paperService.updateById(paper);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 终止定时任务
|
|
|
|
|
String name = JobPrefix.BREAK_EXAM + paperId;
|
|
|
|
|
jobService.deleteJob(name, JobGroup.SYSTEM);
|
|
|
|
|
|
|
|
|
|
//把打错的问题加入错题本
|
|
|
|
|
// 把打错的问题加入错题本
|
|
|
|
|
List<PaperQuDTO> list = paperQuService.listByPaper(paperId);
|
|
|
|
|
for(PaperQuDTO qu: list){
|
|
|
|
|
// 主观题和对的都不加入错题库
|
|
|
|
@ -515,28 +631,42 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
|
|
|
|
|
//加入错题本
|
|
|
|
|
new Thread(() -> userBookService.addBook(paper.getExamId(), qu.getQuId())).run();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public IPage<PaperListRespDTO> paging(PagingReqDTO<PaperListReqDTO> reqDTO) {
|
|
|
|
|
// 声明分页查询试卷列表的方法
|
|
|
|
|
/**
|
|
|
|
|
* 分页查询试卷列表的方法
|
|
|
|
|
* @param reqDTO 分页请求DTO
|
|
|
|
|
* @return 返回分页响应
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public IPage<PaperListRespDTO> paging(PagingReqDTO<PaperListReqDTO> reqDTO) {
|
|
|
|
|
return baseMapper.paging(reqDTO.toPage(), reqDTO.getParams());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public PaperDTO checkProcess(String userId) {
|
|
|
|
|
// 声明检查考试进度的方法
|
|
|
|
|
/**
|
|
|
|
|
* 检查考试进度的方法
|
|
|
|
|
* @param userId 用户ID
|
|
|
|
|
* @return 返回试卷DTO
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public PaperDTO checkProcess(String userId) {
|
|
|
|
|
|
|
|
|
|
// 构建查询条件,查询是否有正在进行的考试
|
|
|
|
|
QueryWrapper<Paper> wrapper = new QueryWrapper<>();
|
|
|
|
|
wrapper.lambda()
|
|
|
|
|
.eq(Paper::getUserId, userId)
|
|
|
|
|
.eq(Paper::getState, PaperState.ING);
|
|
|
|
|
|
|
|
|
|
// 查询正在进行的考试
|
|
|
|
|
Paper paper = this.getOne(wrapper, false);
|
|
|
|
|
|
|
|
|
|
// 如果存在正在进行的考试,则返回试卷DTO
|
|
|
|
|
if (paper != null) {
|
|
|
|
|
return BeanMapper.map(paper, PaperDTO.class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果不存在正在进行的考试,则返回null
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|