package com.gkhy.exam.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gkhy.exam.common.api.CommonPage;
import com.gkhy.exam.common.constant.UserConstant;
import com.gkhy.exam.common.domain.entity.SysUser;
import com.gkhy.exam.common.enums.CodeTypeEnum;
import com.gkhy.exam.common.enums.QuestionAssignEnum;
import com.gkhy.exam.common.enums.QuestionTypeEnum;
import com.gkhy.exam.common.enums.UserTypeEnum;
import com.gkhy.exam.common.exception.ApiException;
import com.gkhy.exam.common.utils.PageUtils;
import com.gkhy.exam.common.utils.SecurityUtils;
import com.gkhy.exam.system.domain.ExExamPaper;
import com.gkhy.exam.system.domain.ExPaperQuestion;
import com.gkhy.exam.system.domain.ExQuestion;
import com.gkhy.exam.system.mapper.ExExamPaperMapper;
import com.gkhy.exam.system.mapper.ExPaperQuestionMapper;
import com.gkhy.exam.system.mapper.ExPaperStudentMapper;
import com.gkhy.exam.system.mapper.ExQuestionMapper;
import com.gkhy.exam.system.service.ExExamPaperService;
import com.gkhy.exam.system.utils.SequenceUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.stream.Collectors;
/**
*
* 考卷(组卷)表 服务实现类
*
*
* @author kzy
* @since 2024-06-05 15:07:36
*/
@Service
public class ExExamPaperServiceImpl extends ServiceImpl implements ExExamPaperService {
@Autowired
private ExPaperStudentMapper paperStudentMapper;
@Autowired
private ExPaperQuestionMapper paperQuestionMapper;
@Autowired
private ExQuestionMapper questionMapper;
@Autowired
private SequenceUtils sequenceUtils;
@Override
public CommonPage selectExamPaperList(ExExamPaper examPaper) {
SysUser currentUser= SecurityUtils.getLoginUser().getUser();
if(!Objects.equals(currentUser.getUserType(), UserTypeEnum.SYSTEM_USER.getCode())){
examPaper.setCompanyId(currentUser.getCompanyId());
}
PageUtils.startPage();
List paperList=baseMapper.selectExamPaperList(examPaper);
return CommonPage.restPage(paperList);
}
@Override
public ExExamPaper selectExamPaperById(Long paperId) {
ExExamPaper examPaper= baseMapper.selectExamPaperById(paperId);
SysUser currentUser= SecurityUtils.getLoginUser().getUser();
if(currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){
return examPaper;
}
if(!examPaper.getCompanyId().equals(currentUser.getCompanyId())){
throw new ApiException("无权限查看其它企业考卷信息");
}
return examPaper;
}
@Override
@Transactional(rollbackFor = RuntimeException.class)
public int insertExamPaper(ExExamPaper examPaper) {
checkUserAllowed(examPaper);
if(!checkNameUnique(examPaper)){
throw new ApiException("试卷名称已存在");
}
//生成编码
examPaper.setCode(sequenceUtils.getNextSequence(CodeTypeEnum.EXAM_PAPER.getCode()));
examPaper.setCreateBy(SecurityUtils.getUsername());
if(examPaper.getLimitTime()>0){
examPaper.setLimit(1);
}
int row=baseMapper.insert(examPaper);
if(row<1){
throw new ApiException("新增试卷失败");
}
//分配试题
assignSingleQuestion(examPaper);
assignMultiQuestion(examPaper);
assignJudgeQuestion(examPaper);
return row;
}
public void checkUserAllowed(ExExamPaper examPaper) {
SysUser currentUser= SecurityUtils.getLoginUser().getUser();
if(currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){
throw new ApiException("系统用户不能创建、修改试卷");
}
if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){
throw new ApiException("没有权限操作");
}
if(!currentUser.getCompanyId().equals(examPaper.getCompanyId())){
throw new ApiException("没有权限操作其他企业试卷");
}
}
//分配单选题
public void assignSingleQuestion(ExExamPaper examPaper){
List paperQuestionList = getPaperQuestions(examPaper.getId(), examPaper.getSingleBankId(),
examPaper.getSingleMethod(),examPaper.getSingleNum(), examPaper.getSingleScore(),QuestionTypeEnum.SINGLE);
paperQuestionMapper.batchInsert(paperQuestionList);
}
//分配多选题
public void assignMultiQuestion(ExExamPaper examPaper){
List paperQuestionList = getPaperQuestions(examPaper.getId(), examPaper.getMultiBankId(),
examPaper.getMultiMethod(),examPaper.getMultiNum(), examPaper.getMultiScore(),QuestionTypeEnum.MULTI);
paperQuestionMapper.batchInsert(paperQuestionList);
}
//分配判断题
public void assignJudgeQuestion(ExExamPaper examPaper){
List paperQuestionList = getPaperQuestions(examPaper.getId(), examPaper.getJudgeBankId(),
examPaper.getJudgeMethod(),examPaper.getJudgeNum(), examPaper.getJudgeScore(),QuestionTypeEnum.JUDGE);
paperQuestionMapper.batchInsert(paperQuestionList);
}
private List getPaperQuestions(Long paperId,Long bankId,Integer questionMethod,Integer questionCount,Integer questionScore, QuestionTypeEnum questionTypeEnum) {
SysUser user=SecurityUtils.getLoginUser().getUser();
Integer totalQuestionCount=questionMapper.selectCountByBankId(user.getCompanyId(), bankId, questionTypeEnum.getCode());
if(totalQuestionCount< questionCount){
throw new ApiException(String.format("所选题库<%s>数量不足,无法分配",questionTypeEnum.getInfo()));
}
List questions=new ArrayList<>();
if(Objects.equals(questionMethod, QuestionAssignEnum.RANDOM.getCode())){//随机分配
questions=questionMapper.selectRandomQuestion(user.getCompanyId(), bankId,questionTypeEnum.getCode(), questionCount);
}else{//顺序分配
int totalPage=questionCount/ questionMethod;//不能整除,忽略最后一页
Random random=new Random();
int startIndex=random.nextInt(totalPage)+1;
questions=questionMapper.selectQuestionWithLimit(user.getCompanyId(), bankId,questionTypeEnum.getCode(),startIndex, questionCount);
}
List paperQuestionList=questions.stream().map(item -> {
ExPaperQuestion exPaperQuestion=new ExPaperQuestion();
exPaperQuestion.setPaperId(paperId);
exPaperQuestion.setQuestionId(item.getId());
exPaperQuestion.setScore(questionScore);
return exPaperQuestion;
}).collect(Collectors.toList());
return paperQuestionList;
}
@Override
public int updateExamPaper(ExExamPaper examPaper) {
if(!checkNameUnique(examPaper)){
throw new ApiException("试卷名称已存在");
}
//校验考卷下是否有学员
if(checkPaperHasStudent(examPaper.getId())){
throw new ApiException("该试卷下已分配学员,不能编辑");
}
examPaper.setCode(null);//编号不能修改
if(examPaper.getLimitTime()==0){
examPaper.setLimit(0);
}
int row=baseMapper.updateById(examPaper);
if(row<1){
throw new ApiException("更新试卷失败");
}
//重新分配题
if(examPaper.getSingleRebuild()==1){
deletePaperQuestion(examPaper.getId(),QuestionTypeEnum.SINGLE);
assignSingleQuestion(examPaper);
}
if(examPaper.getMultiRebuild()==1) {
deletePaperQuestion(examPaper.getId(),QuestionTypeEnum.MULTI);
assignMultiQuestion(examPaper);
}
if(examPaper.getJudgeRebuild()==1) {
deletePaperQuestion(examPaper.getId(),QuestionTypeEnum.JUDGE);
assignJudgeQuestion(examPaper);
}
return row;
}
public void deletePaperQuestion(Long paperId,QuestionTypeEnum questionTypeEnum){
paperQuestionMapper.deletePaperQuestion(paperId,questionTypeEnum!=null?questionTypeEnum.getCode():null);
}
@Override
public int deleteExamPaperById(Long paperId) {
//查询该试卷分配的学员人数
if(checkPaperHasStudent(paperId)){
throw new ApiException("该试卷下已分配学员,不能删除");
}
int row=baseMapper.deleteById(paperId);
if(row<1){
throw new ApiException("删除试卷失败");
}
//删除考卷试题
paperQuestionMapper.deletebyPapaerId(paperId);
return row;
}
public Boolean checkPaperHasStudent(Long paperId){
//查询该试卷分配的学员人数
int studentCount=paperStudentMapper.countByPaperId(paperId);
if(studentCount>0){
return true;
}
return false;
}
@Override
public boolean checkNameUnique(ExExamPaper examPaper) {
Long paperId=examPaper.getId()==null?-1L:examPaper.getId();
ExExamPaper paper= baseMapper.checkNameUnique(examPaper.getName());
if(paper!=null&&paper.getId().longValue()!=paperId.longValue()){
return UserConstant.NOT_UNIQUE;
}
return UserConstant.UNIQUE;
}
@Override
public int changeExamPaperStatus(Long paperId, Integer status) {
return baseMapper.updateById(new ExExamPaper().setId(paperId).setStatus(status).setUpdateBy(SecurityUtils.getUsername()));
}
}