package nju.seec.helper.service.impl;
import nju.seec.helper.api.BokApi;
import nju.seec.helper.aspect.auth.LoginUser;
import nju.seec.helper.dao.QuestionRecordDAO;
import nju.seec.helper.dao.QuizDAO;
import nju.seec.helper.dao.UserDAO;
import nju.seec.helper.dto.question.BaseQuestionDTO;
import nju.seec.helper.entity.QuestionRecord;
import nju.seec.helper.entity.Quiz;
import nju.seec.helper.enums.ExceptionType;
import nju.seec.helper.enums.QuizState;
import nju.seec.helper.enums.UserType;
import nju.seec.helper.exception.HelperException;
import nju.seec.helper.service.QuestionService;
import nju.seec.helper.vo.question.BaseQuestionVO;
import nju.seec.helper.vo.question.BokQuestion;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author xst
*
* updated by cst
*/
@Service
public class QuestionServiceImpl implements QuestionService {
private final QuizDAO quizDAO;
private final UserDAO userDAO;
private final QuestionRecordDAO questionRecordDAO;
private final BokApi bokApi;
@Autowired
public QuestionServiceImpl(QuizDAO quizDAO
, UserDAO userDAO
, QuestionRecordDAO questionRecordDAO, BokApi bokApi) {
this.quizDAO = quizDAO;
this.userDAO = userDAO;
this.questionRecordDAO = questionRecordDAO;
this.bokApi = bokApi;
}
@Override
public Page getQuestions(LoginUser user, String stem, Pageable pageable) {
return bokApi.bokFindByStemLike(stem, pageable).map(bokQuestion -> BaseQuestionVO.convertBokQuestionToVO(bokQuestion, true));
}
@Transactional(readOnly = true)
@Override
public List getQuestionsByQuiz(LoginUser user, Long quizId) {
Quiz quiz = quizDAO.findQuizById(quizId);
List questionIds = quiz.getQuestions();
return bokApi.bokFindByIdIn(questionIds)
.stream()
.map(bokQuestion -> BaseQuestionVO.convertBokQuestionToVO(bokQuestion, quiz.getState() == QuizState.CLOSED || user.getType() == UserType.TEACHER))
.collect(Collectors.toList());
}
@Transactional(readOnly = true)
@Override
public List getQuestionsByQuiz(Quiz quiz) {
List questionIds = quiz.getQuestions();
return bokApi.bokFindByIdIn(questionIds)
.stream()
.map(bokQuestion -> BaseQuestionVO.convertBokQuestionToVO(bokQuestion, true))
.collect(Collectors.toList());
}
@Override
public BaseQuestionVO getOneQuestion(LoginUser user, String questionId) {
return BaseQuestionVO.convertBokQuestionToVO(bokApi.bokFindById(questionId), true);
}
@Transactional(rollbackFor = Exception.class)
@Override
public BaseQuestionVO createQuestion(LoginUser user, BaseQuestionDTO baseQuestionDTO) {
String questionId;
do {
// 保证不产生重复QuestionId
questionId = UUID.randomUUID().toString().replaceAll("-", "");
} while (questionRecordDAO.existsByQuestionId(questionId));
BokQuestion bokQuestion = bokApi.createQuestion(questionId, baseQuestionDTO);
questionRecordDAO.save(new QuestionRecord()
.setTeacher(userDAO.findUserById(user.getId()))
.setQuestionId(bokQuestion.getId()));
return BaseQuestionVO.convertBokQuestionToVO(bokQuestion, true);
}
@Transactional(readOnly = true)
@Override
public BaseQuestionVO modifyQuestion(LoginUser user, String questionId, BaseQuestionDTO baseQuestionDTO) {
QuestionRecord questionRecord = questionRecordDAO.findByTeacherAndQuestionId(userDAO.findUserById(user.getId()), questionId)
.orElseThrow(() -> HelperException.of(ExceptionType.FORBIDDEN, "您无权修改该问题"));
BokQuestion bokQuestion = bokApi.modifyQuestion(questionId, baseQuestionDTO);
questionRecordDAO.save(questionRecord);
return BaseQuestionVO.convertBokQuestionToVO(bokQuestion, true);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteQuestion(LoginUser user, String questionId) {
QuestionRecord questionRecord = questionRecordDAO.findByTeacherAndQuestionId(userDAO.findUserById(user.getId()), questionId)
.orElseThrow(() -> HelperException.of(ExceptionType.FORBIDDEN, "您无权删除该问题"));
bokApi.deleteQuestion(questionId);
questionRecordDAO.delete(questionRecord);
}
@Transactional(readOnly = true)
@Override
public Page getCreatedQuestions(LoginUser user, Pageable pageable) {
Page questionIdPage = questionRecordDAO.findQuestionIdsByTeacher(userDAO.findUserById(user.getId()), pageable);
return new PageImpl<>(
bokApi.bokFindByIdIn(questionIdPage.getContent())
.stream()
.map(bokQuestion -> BaseQuestionVO.convertBokQuestionToVO(bokQuestion, true))
.collect(Collectors.toList())
, pageable
, questionIdPage.getTotalElements()
);
}
@Transactional(readOnly = true)
@Override
public Set getIdsOfCreatedQuestions(LoginUser user) {
return questionRecordDAO.findQuestionIdsByTeacher(userDAO.findUserById(user.getId()));
}
}