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.domain.ExQuestionBank;
import com.gkhy.exam.system.mapper.*;
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.*;
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 ExQuestionBankMapper questionBankMapper;
@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);
//获取题库名称
List bankIds=new ArrayList<>();
bankIds.add(examPaper.getSingleBankId());
bankIds.add(examPaper.getMultiBankId());
bankIds.add(examPaper.getJudgeBankId());
bankIds.add(examPaper.getEasyBankId());
List questionBanks=questionBankMapper.selectQuestionBankByIds(bankIds);
questionBanks.forEach(item -> {
if(Objects.equals(item.getId(), examPaper.getSingleBankId())){
examPaper.setSingleBankName(item.getName());
}
if(Objects.equals(item.getId(), examPaper.getMultiBankId())){
examPaper.setMultiBankName(item.getName());
}
if(Objects.equals(item.getId(), examPaper.getJudgeBankId())){
examPaper.setJudgeBankName(item.getName());
}
if(Objects.equals(item.getId(), examPaper.getEasyBankId())){
examPaper.setEasyBankName(item.getName());
}
});
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) {
validatedData(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.setLimited(1);
}else{
examPaper.setLimited(0);
}
int row=baseMapper.insert(examPaper);
if(row<1){
throw new ApiException("新增试卷失败");
}
//分配试题
if(Optional.ofNullable(examPaper.getSingleNum()).orElse(0)>0) {
assignSingleQuestion(examPaper);
}
if(Optional.ofNullable(examPaper.getMultiNum()).orElse(0)>0) {
assignMultiQuestion(examPaper);
}
if(Optional.ofNullable(examPaper.getJudgeNum()).orElse(0)>0) {
assignJudgeQuestion(examPaper);
}
if(Optional.ofNullable(examPaper.getEasyNum()).orElse(0)>0) {
assignEasyQuestion(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(examPaper.getCompanyId()!=null&&!currentUser.getCompanyId().equals(examPaper.getCompanyId())){
throw new ApiException("没有权限操作其他企业试卷");
}
}
public void validatedData(ExExamPaper examPaper){
if(Optional.ofNullable(examPaper.getSingleNum()).orElse(0)<=0
&&Optional.ofNullable(examPaper.getMultiNum()).orElse(0)<=0
&&Optional.ofNullable(examPaper.getJudgeNum()).orElse(0)<=0
&&Optional.ofNullable(examPaper.getEasyNum()).orElse(0)<=0){
throw new ApiException("试卷题目数量不能为空");
}
if(Optional.ofNullable(examPaper.getSingleNum()).orElse(0)>0){
if(Optional.ofNullable(examPaper.getSingleScore()).orElse(0)<=0 || examPaper.getSingleMethod()==null||examPaper.getSingleBankId()==null){
throw new ApiException("单选题参数错误");
}
}
if(Optional.ofNullable(examPaper.getMultiNum()).orElse(0)>0){
if(Optional.ofNullable(examPaper.getMultiScore()).orElse(0)<=0 || examPaper.getMultiMethod()==null||examPaper.getMultiBankId()==null){
throw new ApiException("多选题参数错误");
}
}
if(Optional.ofNullable(examPaper.getJudgeNum()).orElse(0)>0){
if(Optional.ofNullable(examPaper.getJudgeScore()).orElse(0)<=0 || examPaper.getJudgeMethod()==null||examPaper.getJudgeBankId()==null){
throw new ApiException("判断题参数错误");
}
}
if(Optional.ofNullable(examPaper.getEasyNum()).orElse(0)>0){
if(Optional.ofNullable(examPaper.getEasyScore()).orElse(0)<=0 || examPaper.getEasyMethod()==null||examPaper.getEasyBankId()==null){
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);
}
//分配简答题
public void assignEasyQuestion(ExExamPaper examPaper){
List paperQuestionList = getPaperQuestions(examPaper.getId(), examPaper.getEasyBankId(),
examPaper.getEasyMethod(),examPaper.getEasyNum(), examPaper.getEasyScore(),QuestionTypeEnum.EASY);
paperQuestionMapper.batchInsert(paperQuestionList);
}
private List getPaperQuestions(Long paperId,Long bankId,Integer questionMethod,Integer questionCount,Integer questionScore, QuestionTypeEnum questionTypeEnum) {
SysUser currentUser=SecurityUtils.getLoginUser().getUser();
Integer totalQuestionCount=questionMapper.selectCountByBankId(currentUser.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(currentUser.getCompanyId(), bankId,questionTypeEnum.getCode(), questionCount);
}else{//顺序分配
int totalPage=totalQuestionCount/questionCount;//不能整除,忽略最后一页
Random random=new Random();
int startIndex=random.nextInt(totalPage)+1;
questions=questionMapper.selectQuestionWithLimit(currentUser.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) {
validatedData(examPaper);
checkUserAllowed(examPaper);
if(!checkNameUnique(examPaper)){
throw new ApiException("试卷名称已存在");
}
//校验考卷下是否有学员
if(checkPaperHasStudent(examPaper.getId())){
throw new ApiException("该试卷下已分配学员,不能编辑");
}
examPaper.setCode(null);//编号不能修改
if(examPaper.getLimitTime()>0){
examPaper.setLimited(1);
}else{
examPaper.setLimited(0);
examPaper.setLimitTime(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);
}
if(examPaper.getEasyRebuild()==1) {
deletePaperQuestion(examPaper.getId(),QuestionTypeEnum.EASY);
assignEasyQuestion(examPaper);
}
return row;
}
public void deletePaperQuestion(Long paperId,QuestionTypeEnum questionTypeEnum){
paperQuestionMapper.deletePaperQuestion(paperId,questionTypeEnum!=null?questionTypeEnum.getCode():null);
}
@Override
public int deleteExamPaperById(Long paperId) {
checkUserAllowed(baseMapper.selectById(paperId));
//查询该试卷分配的学员人数
if(checkPaperHasStudent(paperId)){
throw new ApiException("该试卷下已分配学员,不能删除");
}
int row=baseMapper.deletePaperById(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) {
SysUser currentUser=SecurityUtils.getLoginUser().getUser();
Long paperId=examPaper.getId()==null?-1L:examPaper.getId();
ExExamPaper paper= baseMapper.checkNameUnique(examPaper.getName(),currentUser.getCompanyId());
if(paper!=null&&paper.getId().longValue()!=paperId.longValue()){
return UserConstant.NOT_UNIQUE;
}
return UserConstant.UNIQUE;
}
@Override
public int changeExamPaperStatus(Long paperId, Integer status) {
checkUserAllowed(baseMapper.selectById(paperId));
return baseMapper.updateById(new ExExamPaper().setId(paperId).setStatus(status).setUpdateBy(SecurityUtils.getUsername()));
}
}