| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- package nju.seec.helper.service.impl;
- import cn.hutool.core.util.IdUtil;
- import com.google.common.collect.Lists;
- import nju.seec.helper.aspect.auth.LoginUser;
- import nju.seec.helper.dao.*;
- import nju.seec.helper.dto.question.BaseQuestionDTO;
- import nju.seec.helper.dto.question.StudentAnswerDTO;
- 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.UserRole;
- import nju.seec.helper.exception.HelperException;
- import nju.seec.helper.service.QuestionService;
- import nju.seec.helper.sys.bok.api.QuestionApi;
- import nju.seec.helper.sys.bok.api.QuestionQueryApi;
- import nju.seec.helper.sys.bok.api.RecordApi;
- import nju.seec.helper.sys.bok.api.UserInteractiveApi;
- import nju.seec.helper.sys.bok.dto.CollectDTO;
- import nju.seec.helper.sys.bok.dto.RateDTO;
- import nju.seec.helper.sys.bok.dto.RecordDTO;
- import nju.seec.helper.sys.bok.vo.InteractiveVO;
- import nju.seec.helper.sys.bok.vo.QuestionVO;
- import nju.seec.helper.sys.bok.vo.RecordQuestionVO;
- import nju.seec.helper.sys.dataanalysis.api.ExerciseApi;
- import nju.seec.helper.sys.dataanalysis.model.ExerciseRecord;
- import nju.seec.helper.sys.ml.api.RecommendationApi;
- import nju.seec.helper.vo.question.BaseQuestionVO;
- 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.Collections;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import java.util.stream.Collectors;
- /**
- * @author xst
- * <p>
- * updated by cst
- */
- @Service
- public class QuestionServiceImpl implements QuestionService {
- private final QuizDAO quizDAO;
- private final UserDAO userDAO;
- private final QuestionRecordDAO questionRecordDAO;
- private final ChooseDAO chooseDAO;
- private final CourseDAO courseDAO;
- private final QuestionApi questionApi;
- private final QuestionQueryApi questionQueryApi;
- private final UserInteractiveApi userInteractiveApi;
- private final RecordApi recordApi;
- private final RecommendationApi recommendationApi;
- private final ExerciseApi exerciseApi;
- @Autowired
- public QuestionServiceImpl(QuizDAO quizDAO
- , UserDAO userDAO
- , QuestionRecordDAO questionRecordDAO
- , ChooseDAO chooseDAO
- , CourseDAO courseDAO
- , QuestionApi questionApi
- , QuestionQueryApi questionQueryApi
- , UserInteractiveApi userInteractiveApi
- , RecordApi recordApi
- , RecommendationApi recommendationApi
- , ExerciseApi exerciseApi
- ) {
- this.quizDAO = quizDAO;
- this.userDAO = userDAO;
- this.questionRecordDAO = questionRecordDAO;
- this.chooseDAO = chooseDAO;
- this.courseDAO = courseDAO;
- this.questionApi = questionApi;
- this.questionQueryApi = questionQueryApi;
- this.userInteractiveApi = userInteractiveApi;
- this.recordApi = recordApi;
- this.recommendationApi = recommendationApi;
- this.exerciseApi = exerciseApi;
- }
- @Override
- public Page<BaseQuestionVO> getQuestions(LoginUser user, String stem, String tag, String knowledgeId, Pageable pageable) {
- return questionApi.getQuestionList(stem, tag, knowledgeId, pageable).map(bokQuestion -> BaseQuestionVO.convertBokQuestionToVO(bokQuestion, true));
- }
- @Transactional(readOnly = true)
- @Override
- public List<BaseQuestionVO> getQuestionsByQuizId(LoginUser user, Long quizId) {
- Quiz quiz = quizDAO.findQuizById(quizId);
- return questionQueryApi.getQuestionListById(quiz.getQuestions())
- .stream()
- .map(bokQuestion -> BaseQuestionVO.convertBokQuestionToVO(bokQuestion, quiz.getState() == QuizState.CLOSED || user.getRole() == UserRole.TEACHER))
- .collect(Collectors.toList());
- }
- @Override
- public List<BaseQuestionVO> getQuestionsByIds(List<String> questionIds) {
- return questionQueryApi.getQuestionListById(questionIds)
- .stream()
- .map(bokQuestion -> BaseQuestionVO.convertBokQuestionToVO(bokQuestion, true))
- .collect(Collectors.toList());
- }
- @Override
- public BaseQuestionVO getOneQuestion(LoginUser user, String questionId) {
- return BaseQuestionVO.convertBokQuestionToVO(questionApi.getQuestionsById(questionId), true);
- }
- @Transactional(rollbackFor = Exception.class)
- @Override
- public BaseQuestionVO createQuestion(LoginUser user, BaseQuestionDTO baseQuestionDTO) {
- String questionId;
- do {
- // 保证不产生重复QuestionId
- questionId = IdUtil.fastSimpleUUID();
- } while (questionRecordDAO.existsByQuestionId(questionId));
- QuestionVO questionVO = questionApi.createQuestion(questionId, baseQuestionDTO);
- questionRecordDAO.save(new QuestionRecord()
- .setTeacher(userDAO.findUserById(user.getId()))
- .setQuestionId(questionVO.getId()));
- return BaseQuestionVO.convertBokQuestionToVO(questionVO, 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, "您无权修改该问题"));
- QuestionVO questionVO = questionApi.updateQuestion(questionId, baseQuestionDTO);
- questionRecordDAO.save(questionRecord);
- return BaseQuestionVO.convertBokQuestionToVO(questionVO, 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, "您无权删除该问题"));
- questionApi.deleteQuestion(questionId);
- questionRecordDAO.delete(questionRecord);
- }
- @Transactional(readOnly = true)
- @Override
- public Page<BaseQuestionVO> getCreatedQuestions(LoginUser user, Pageable pageable) {
- Page<String> questionIdPage = questionRecordDAO.findQuestionIdsByTeacher(userDAO.findUserById(user.getId()), pageable);
- return new PageImpl<>(
- questionQueryApi.getQuestionListById(questionIdPage.getContent())
- .stream()
- .map(bokQuestion -> BaseQuestionVO.convertBokQuestionToVO(bokQuestion, true))
- .collect(Collectors.toList())
- , pageable
- , questionIdPage.getTotalElements()
- );
- }
- @Transactional(readOnly = true)
- @Override
- public Set<String> getIdsOfCreatedQuestions(LoginUser user) {
- return questionRecordDAO.findQuestionIdsByTeacher(userDAO.findUserById(user.getId()));
- }
- @Override
- public void collectQuestion(LoginUser user, String questionId, CollectDTO collectDTO) {
- userInteractiveApi.collectQuestion(String.valueOf(user.getPid()), questionId, collectDTO);
- }
- @Override
- public void rateQuestion(LoginUser user, String questionId, RateDTO rateDTO) {
- userInteractiveApi.rateQuestion(String.valueOf(user.getPid()), questionId, rateDTO);
- }
- @Transactional(readOnly = true)
- @Override
- public Page<BaseQuestionVO> getCollectedAndRatedQuestions(LoginUser user, Boolean collect, Boolean rate, Pageable pageable) {
- return convert(user, userInteractiveApi.getCollectAndRateQuestions(String.valueOf(user.getPid()), collect, rate, pageable));
- }
- @Transactional(readOnly = true)
- @Override
- public Page<BaseQuestionVO> getCompletedQuestions(LoginUser user, Pageable pageable) {
- RecordQuestionVO recordQuestionVO = recordApi.getUserRecordQuestions(String.valueOf(user.getPid()), pageable);
- return convert(user, new PageImpl<>(recordQuestionVO.getQuestions(), pageable, recordQuestionVO.getPage().getTotalElements()));
- }
- @Override
- public List<InteractiveVO> getInteractiveList(LoginUser user, String questionId) {
- return userInteractiveApi.getInteractive(String.valueOf(user.getPid()), questionId);
- }
- @Override
- public List<BaseQuestionVO> getRecommendationQuestions(LoginUser user, List<String> knowledgeId, Integer questionNum) {
- return questionQueryApi.getQuestionListById(recommendationApi.getRecommendResult(String.valueOf(user.getPid()), knowledgeId, questionNum))
- .stream()
- .map(questionVO -> BaseQuestionVO.convertBokQuestionToVO(questionVO, true))
- .collect(Collectors.toList());
- }
- @Transactional(readOnly = true)
- @Override
- public List<BaseQuestionVO> getRecommendationQuestionsByCourse(LoginUser user, Long courseId, Integer questionNum) {
- return this.getRecommendationQuestions(user, courseDAO.findCourseById(courseId).getKnowledgeId(), questionNum);
- }
- @Override
- public void record(LoginUser user, StudentAnswerDTO studentAnswerDTO) {
- if (studentAnswerDTO.getRecords() == null || studentAnswerDTO.getRecords().isEmpty()) {
- return;
- }
- Map<String, StudentAnswerDTO.AnswerRecordDTO> recordMap = studentAnswerDTO.getRecords()
- .entrySet()
- .stream()
- .filter(entry -> entry.getValue().getStartAt().isBefore(entry.getValue().getEndAt()))
- .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
- if (recordMap.isEmpty()) {
- return;
- }
- List<BaseQuestionVO> baseQuestionVOList = questionQueryApi.getQuestionListById(Lists.newArrayList(recordMap.keySet()))
- .stream()
- .map(questionVO -> BaseQuestionVO.convertBokQuestionToVO(questionVO, true))
- .collect(Collectors.toList());
- // 创建两个列表
- int size = recordMap.size();
- List<ExerciseRecord> exerciseRecords = Lists.newArrayListWithExpectedSize(size);
- List<RecordDTO> records = Lists.newArrayListWithExpectedSize(size);
- // 填充列表
- String userId = String.valueOf(user.getPid());
- baseQuestionVOList.forEach(baseQuestionVO -> {
- String questionId = baseQuestionVO.getId();
- StudentAnswerDTO.AnswerRecordDTO answerRecord = recordMap.get(questionId);
- Object answer = answerRecord.getAnswer();
- Boolean pass = baseQuestionVO.pass(answer);
- exerciseRecords.add(exerciseApi.createExerciseRecordDTO(userId, questionId, answerRecord.getStartAt(), answerRecord.getEndAt(), pass));
- records.add(recordApi.createRecordDTO(userId, questionId, answer, pass, answerRecord.getStartAt(), answerRecord.getEndAt()));
- });
- exerciseApi.reportExercise(exerciseRecords);
- recordApi.reportUserRecord(records);
- }
- private static final Set<QuizState> HIDE_QUESTION_ANSWER_STATES = Collections.singleton(QuizState.ONGOING);
- private Page<BaseQuestionVO> convert(LoginUser user, Page<QuestionVO> questionVOList) {
- List<String> hideQuestionIds = quizDAO.findByCourseIdInAndStateIn(chooseDAO.findCourseIdsByStudentId(user.getId()), HIDE_QUESTION_ANSWER_STATES)
- .stream()
- .flatMap(quiz -> quiz.getQuestions().stream())
- .collect(Collectors.toList());
- return questionVOList.map(questionVO -> BaseQuestionVO.convertBokQuestionToVO(questionVO, !hideQuestionIds.contains(questionVO.getId())));
- }
- }
|