package com.gkhy.exam.system.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gkhy.exam.common.api.CommonPage;
import com.gkhy.exam.common.constant.Constant;
import com.gkhy.exam.common.domain.entity.SysUser;
import com.gkhy.exam.common.enums.PaperStudentStateEnum;
import com.gkhy.exam.common.enums.QuestionTypeEnum;
import com.gkhy.exam.common.enums.StudentAnswerPassEnum;
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.common.utils.StringUtils;
import com.gkhy.exam.system.domain.*;
import com.gkhy.exam.system.domain.vo.BatchPaperStudentVO;
import com.gkhy.exam.system.domain.vo.ExPaperStudentVO;
import com.gkhy.exam.system.mapper.*;
import com.gkhy.exam.system.service.ExPaperStudentService;
import com.gkhy.exam.system.service.ExStudentAnswerService;
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-06 13:53:17
*/
@Service
public class ExPaperStudentServiceImpl extends ServiceImpl implements ExPaperStudentService {
@Autowired
private ExExamPaperMapper examPaperMapper;
@Autowired
private ExStudentAnswerService studentAnswerService;
@Autowired
private ExStudentAnswerMapper studentAnswerMapper;
@Autowired
private ExStudentMapper studentMapper;
@Autowired
private ExPhaseStudentMapper phaseStudentMapper;
@Autowired
private ExQuestionMapper questionMapper;
@Override
public CommonPage selectPaperStudentListForStudent(ExPaperStudent paperStudent) {
SysUser user= SecurityUtils.getLoginUser().getUser();
if(!Objects.equals(user.getUserType(), UserTypeEnum.STUDENT.getCode())){
throw new ApiException("非学员用户,不能查看");
}
paperStudent.setStudentId(user.getId());
PageUtils.startPage();
List paperList=baseMapper.selectPaperStudentList(paperStudent);
return CommonPage.restPage(paperList);
}
@Override
public ExPaperStudent selectPaperStudentById(Long paperStudentId) {
return baseMapper.selectPaperStudentById(paperStudentId);
}
@Override
public ExPaperStudent selectPaperStudentById(ExPaperStudent paperStudent) {
return baseMapper.selectByPaperStudentId(paperStudent);
}
@Override
public int addPaperStudent(ExPaperStudent paperStudent) {
checkUserAllowed(paperStudent);
checkStudentUnique(Collections.singletonList(paperStudent));
paperStudent.setCreateId(SecurityUtils.getUserId());
int row=baseMapper.insert(paperStudent);
if(row<1){
throw new ApiException("分配学员失败");
}
return row;
}
@Override
public int batchAddPaperStudent(BatchPaperStudentVO batchPaperStudentVO) {
List phaseIds= batchPaperStudentVO.getPhaseIds();
List studentIds= batchPaperStudentVO.getStudentIds();
Long paperId=batchPaperStudentVO.getPaperId();
if(ObjectUtil.isEmpty(phaseIds) && ObjectUtil.isEmpty(studentIds)){
throw new ApiException("批次id与学员id不能同时为空");
}
List allStudentIds=new ArrayList<>();
//按批次绑定用户
if(phaseIds!=null&&!phaseIds.isEmpty()){
List phaseStudentList=phaseStudentMapper.selectList( Wrappers.lambdaQuery()
.in(ExPhaseStudent::getPhaseId, phaseIds));
allStudentIds=phaseStudentList.stream().map(item -> item.getStudentId()).distinct().collect(Collectors.toList());
}
if(studentIds!=null&&!studentIds.isEmpty()){
allStudentIds.addAll(studentIds);
}
List paperStudentList=baseMapper.selectList( Wrappers.lambdaQuery()
.eq(true,ExPaperStudent::getPaperId, paperId)
.in(true,ExPaperStudent::getStudentId,allStudentIds));
if(paperStudentList.size()>0) {
List existStudentIds = paperStudentList.stream().map(item -> item.getStudentId()).distinct().collect(Collectors.toList());
allStudentIds.removeAll(existStudentIds);
}
if(allStudentIds.isEmpty()){
throw new ApiException("未匹配到学员");
}
allStudentIds= allStudentIds.stream().distinct().collect(Collectors.toList());
List paperStudents=allStudentIds.stream().map(item -> {
return new ExPaperStudent().setPaperId(paperId).setStudentId(item).setCreateId(SecurityUtils.getUserId());
}).collect(Collectors.toList());
// checkStudentUnique(paperStudents);
int row=baseMapper.batchInsert(paperStudents);
if(row<1){
throw new ApiException("批量分配学员失败");
}
return row;
}
@Override
public void checkStudentUnique(List paperStudents){
for(ExPaperStudent paperStudent:paperStudents) {
Integer existCount = baseMapper.selectCountByPaperStudentId(paperStudent.getPaperId(), paperStudent.getStudentId());
if (existCount > 0) {
ExStudent student = studentMapper.selectById(paperStudent.getStudentId());
throw new ApiException(String.format("待分配学员<%s>已存在", student.getName()));
}
}
}
@Override
@Transactional(rollbackFor = RuntimeException.class)
public void doReview(ExPaperStudentVO paperStudentVO) {
checkUserAllowed(new ExPaperStudent().setPaperId(paperStudentVO.getPaperId()));
ExPaperStudent paperStudent=baseMapper.selectById(paperStudentVO.getId());
ExExamPaper examPaper=examPaperMapper.selectById(paperStudent.getPaperId());
if(paperStudent.getState().equals(PaperStudentStateEnum.WAIT_EXAM.getCode())){
throw new ApiException("待考试状态的试卷不能批改!");
}
List studentAnswerList=studentAnswerMapper.selectList(Wrappers.lambdaQuery()
.eq(true,ExStudentAnswer::getStudentId,paperStudent.getStudentId())
.eq(true,ExStudentAnswer::getPaperId,paperStudent.getPaperId()));
Map collectMap = studentAnswerList.stream().collect(Collectors.toMap(ExStudentAnswer::getQuestionId, k -> k));
List questionVOList=paperStudentVO.getQuestions();
List updateStudentAnswerList=new ArrayList<>();
for (ExPaperStudentVO.QuestionVO questionVO:questionVOList){
ExStudentAnswer sa=collectMap.get(questionVO.getQuestionId());
if(sa!=null){
int score=questionVO.getScore();
sa.setScore(score);
if(score>examPaper.getEasyScore()){
throw new ApiException("得分不能超过题目的最高分!");
}else if(score==examPaper.getEasyScore()){
sa.setPassed(StudentAnswerPassEnum.CORRECT.getCode());
}else{
sa.setPassed(StudentAnswerPassEnum.ERROR.getCode());
}
updateStudentAnswerList.add(sa);
}
}
int totalScore=0;
for(ExStudentAnswer studentAnswer:studentAnswerList){
if(studentAnswer.getScore()!=null) {
totalScore = totalScore + studentAnswer.getScore();
}
}
paperStudent.setState(PaperStudentStateEnum.DONE_REVIEW.getCode());
paperStudent.setScore(totalScore);
if(totalScore paperStudentList=baseMapper.selectPaperStudentList(paperStudent);
return CommonPage.restPage(paperStudentList);
}
@Override
public int deletePaperStudent(Long paperStudentId) {
ExPaperStudent paperStudent=baseMapper.selectSimplePaperStudentById(paperStudentId);
if(ObjectUtil.isNull(paperStudent)){
throw new ApiException("学员与试卷关系不存在");
}
checkUserAllowed(paperStudent);
int studentAnswerCount=studentAnswerMapper.countByPaperId(paperStudent.getPaperId(),paperStudent.getStudentId());
if(studentAnswerCount>0){
throw new ApiException("学员已进行答题,不能删除");
}
//删除学员与试卷关系
return baseMapper.deleteById(paperStudentId);
}
@Override
@Transactional(rollbackFor = RuntimeException.class)
public void batchDeletePaperStudent(List paperStudentIds) {
for(Long paperStudentId:paperStudentIds){
deletePaperStudent(paperStudentId);
}
}
public void checkUserAllowed(ExPaperStudent paperStudent) {
SysUser currentUser= SecurityUtils.getLoginUser().getUser();
if(currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){
return;
}
if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){
throw new ApiException("没有权限操作");
}
ExExamPaper examPaper=examPaperMapper.selectById(paperStudent.getPaperId());
if(!currentUser.getCompanyId().equals(examPaper.getCompanyId())){
throw new ApiException("没有权限操作其他企业考卷");
}
}
@Override
public void endExam(ExPaperStudent pStudent) {
if(pStudent.getId()==null){
throw new ApiException("学员与试卷关系id不能为空");
}
ExPaperStudent existPs=baseMapper.selectById(pStudent.getId());
if(existPs==null){
throw new ApiException("学员与试卷关系不存在");
}
Long endTime=System.currentTimeMillis();
existPs.setEndTime(endTime);
handlePaperData(existPs);
}
@Override
@Transactional(rollbackFor = RuntimeException.class)
public void handlePaperData(ExPaperStudent paperStudent){
//计算考试成绩
ExExamPaper paper=examPaperMapper.selectById(paperStudent.getPaperId());
paperStudent.setState(PaperStudentStateEnum.WAIT_REVIEW.getCode());
List studentAnswerList=studentAnswerMapper.selectList(Wrappers.lambdaQuery()
.eq(true,ExStudentAnswer::getStudentId,paperStudent.getStudentId())
.eq(true,ExStudentAnswer::getPaperId,paperStudent.getPaperId()));
List questionList=questionMapper.selectQuestionByPaperId(paperStudent.getPaperId());
Map collectMap = studentAnswerList.stream().collect(Collectors.toMap(ExStudentAnswer::getQuestionId, k -> k));
List updateStudentAnswers=new ArrayList<>();
int totalScore=0;
boolean easyViewFlag=false;
for(ExQuestion question:questionList){
ExStudentAnswer sa=collectMap.get(question.getId());
if(sa!=null){
if(question.getQuestionType().equals(QuestionTypeEnum.EASY.getCode())) {
if(StringUtils.isBlank(sa.getAnswer())){
sa.setPassed(StudentAnswerPassEnum.ERROR.getCode());
sa.setScore(0);
}else{
sa.setPassed(StudentAnswerPassEnum.WAIT_REVIEW.getCode());
easyViewFlag=true;
}
}else{
if (sa.getAnswer().equals(question.getAnswer())) {
sa.setPassed(StudentAnswerPassEnum.CORRECT.getCode());
sa.setScore(getScore(paper, question.getQuestionType()));
totalScore = totalScore + sa.getScore();
}else {
sa.setPassed(StudentAnswerPassEnum.ERROR.getCode());
sa.setScore(0);
}
}
}else{
sa=new ExStudentAnswer();
sa.setPassed(StudentAnswerPassEnum.ERROR.getCode());
sa.setScore(0);
sa.setStudentId(paperStudent.getStudentId());
sa.setPaperId(paperStudent.getPaperId());
sa.setQuestionId(question.getId());
}
updateStudentAnswers.add(sa);
}
studentAnswerService.saveOrUpdateBatch(updateStudentAnswers);
paperStudent.setScore(totalScore);
if(!easyViewFlag){
//没有简答题,直接批改试卷
paperStudent.setState(PaperStudentStateEnum.DONE_REVIEW.getCode());
if(paper.getPassScore()>totalScore){
paperStudent.setPassed(Constant.EXAM_UNPASS);
}else{
paperStudent.setPassed(Constant.EXAM_PASS);
}
}
int row=baseMapper.updateById(paperStudent);
if(row<1){
throw new ApiException("提交考试失败");
}
}
private Integer getScore(ExExamPaper examPaper,Integer questionType){
if(questionType.equals(QuestionTypeEnum.SINGLE.getCode())){
return examPaper.getSingleScore();
}else if(questionType.equals(QuestionTypeEnum.MULTI.getCode())){
return examPaper.getMultiScore();
}else if(questionType.equals(QuestionTypeEnum.JUDGE.getCode())){
return examPaper.getJudgeScore();
}else if(questionType.equals(QuestionTypeEnum.EASY.getCode())){
return examPaper.getEasyScore();
}
return 0;
}
}