|
@@ -0,0 +1,384 @@
|
|
|
+package cn.com.qmth.examcloud.core.questions.service.impl;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.UUID;
|
|
|
+
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.domain.Page;
|
|
|
+import org.springframework.data.domain.PageImpl;
|
|
|
+import org.springframework.data.domain.PageRequest;
|
|
|
+import org.springframework.data.mongodb.core.MongoTemplate;
|
|
|
+import org.springframework.data.mongodb.core.query.Criteria;
|
|
|
+import org.springframework.data.mongodb.core.query.Query;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import cn.com.qmth.examcloud.commons.base.exception.StatusException;
|
|
|
+import cn.com.qmth.examcloud.core.questions.base.CommonUtils;
|
|
|
+import cn.com.qmth.examcloud.core.questions.base.question.enums.QuesStructType;
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.QuesRepo;
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.QuesOption;
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.Question;
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.QuestionProviderService;
|
|
|
+import cn.com.qmth.examcloud.question.core.question.DefaultQuestion;
|
|
|
+import cn.com.qmth.examcloud.question.core.question.DefaultQuestionOption;
|
|
|
+import cn.com.qmth.examcloud.question.core.question.DefaultQuestionStructure;
|
|
|
+import cn.com.qmth.examcloud.question.core.question.DefaultQuestionUnit;
|
|
|
+import cn.com.qmth.examcloud.question.core.question.QuestionType;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author weiwenhai
|
|
|
+ * @date 2018.9.10
|
|
|
+ * @company qmth
|
|
|
+ * @describle 试题对象服务实现类
|
|
|
+ * @code 012
|
|
|
+ */
|
|
|
+@Service("questionProviderService")
|
|
|
+public class QuestionProviderServiceImpl implements QuestionProviderService{
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ QuesRepo quesRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ MongoTemplate mongoTemplate;
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ @Override
|
|
|
+ public String save(DefaultQuestion defaultQuestion) {
|
|
|
+ Question question = new Question();
|
|
|
+ if(StringUtils.isBlank(defaultQuestion.getId())){
|
|
|
+ question.setId(defaultQuestion.getId());
|
|
|
+ }
|
|
|
+ question.setOrgId(defaultQuestion.getRootOrgId().toString());
|
|
|
+ question.setCreateTime(CommonUtils.getCurDateTime());
|
|
|
+ question.setDifficulty("中");
|
|
|
+ question.setDifficultyDegree(0.5);
|
|
|
+ question.setIsolated(true);
|
|
|
+ question.setPublicity(true);
|
|
|
+ question.setProperties(defaultQuestion.getProperties());
|
|
|
+ DefaultQuestionStructure defaultQuestionStructure = (DefaultQuestionStructure) defaultQuestion.getMasterVersion();
|
|
|
+ //判断试题单元对象
|
|
|
+ List<DefaultQuestionUnit> questionUnitList = (List<DefaultQuestionUnit>) defaultQuestionStructure.getQuestionUnitList();
|
|
|
+ if(questionUnitList == null || questionUnitList.size()<1){
|
|
|
+ throw new StatusException("Q-012033", "试题单元对象为空");
|
|
|
+ }
|
|
|
+ if(questionUnitList.size()==1){
|
|
|
+ DefaultQuestionUnit defaultQuestionUnit = questionUnitList.get(0);
|
|
|
+ //判断试题题型
|
|
|
+ if(defaultQuestionUnit.getQuestionType() == null){
|
|
|
+ throw new StatusException("Q-012039", "试题单元中题型为空");
|
|
|
+ }
|
|
|
+ //设置题干
|
|
|
+ question.setQuesBody(defaultQuestionUnit.getBody());
|
|
|
+ QuesStructType type = buildQuesType(defaultQuestionUnit.getQuestionType());
|
|
|
+ if(type == null){
|
|
|
+ throw new StatusException("Q-012043", "试题单元中题型值不对");
|
|
|
+ }
|
|
|
+ //设置题型
|
|
|
+ question.setQuestionType(type);
|
|
|
+ //如果是选择题,判断选项
|
|
|
+ if(defaultQuestionUnit.getQuestionType() == QuestionType.SINGLE_CHOICE || defaultQuestionUnit.getQuestionType() == QuestionType.MULTIPLE_CHOICE){
|
|
|
+ List<DefaultQuestionOption> questionOptionList = (List<DefaultQuestionOption>) defaultQuestionUnit.getQuestionOptionList();
|
|
|
+ if(questionOptionList == null || questionOptionList.size()<1){
|
|
|
+ throw new StatusException("Q-012049", "试题单元中选项为空");
|
|
|
+ }
|
|
|
+ //设置选项
|
|
|
+ List<QuesOption> quesOptions = buildOptions(questionOptionList, defaultQuestionUnit.getRightAnswer());
|
|
|
+ question.setQuesOptions(quesOptions);
|
|
|
+ }
|
|
|
+ //设置答案
|
|
|
+ question.setQuesAnswer(buildAnswer(defaultQuestionUnit));
|
|
|
+ }else {
|
|
|
+ //套题
|
|
|
+ //设置题干
|
|
|
+ question.setQuesBody(defaultQuestionStructure.getBody());
|
|
|
+ question.setQuestionType(QuesStructType.NESTED_ANSWER_QUESTION);
|
|
|
+ //生成子题
|
|
|
+ List<Question> subList = new ArrayList<Question>();
|
|
|
+ for(DefaultQuestionUnit defaultQuestionUnit:questionUnitList){
|
|
|
+ Question subQues = new Question();
|
|
|
+ subQues.setId(UUID.randomUUID().toString());
|
|
|
+ subQues.setDifficulty("中");
|
|
|
+ subQues.setDifficultyDegree(0.5);
|
|
|
+ subQues.setPublicity(true);
|
|
|
+ //判断试题题型
|
|
|
+ if(defaultQuestionUnit.getQuestionType() == null){
|
|
|
+ throw new StatusException("Q-012039", "试题单元中题型为空");
|
|
|
+ }
|
|
|
+ //设置题干
|
|
|
+ subQues.setQuesBody(defaultQuestionUnit.getBody());
|
|
|
+ QuesStructType type = buildQuesType(defaultQuestionUnit.getQuestionType());
|
|
|
+ if(type == null){
|
|
|
+ throw new StatusException("Q-012043", "试题单元中题型值不对");
|
|
|
+ }
|
|
|
+ //设置题型
|
|
|
+ subQues.setQuestionType(type);
|
|
|
+ //如果是选择题,判断选项
|
|
|
+ if(defaultQuestionUnit.getQuestionType() == QuestionType.SINGLE_CHOICE || defaultQuestionUnit.getQuestionType() == QuestionType.MULTIPLE_CHOICE){
|
|
|
+ List<DefaultQuestionOption> questionOptionList = (List<DefaultQuestionOption>) defaultQuestionUnit.getQuestionOptionList();
|
|
|
+ if(questionOptionList == null || questionOptionList.size()<1){
|
|
|
+ throw new StatusException("Q-012049", "试题单元中选项为空");
|
|
|
+ }
|
|
|
+ //设置选项
|
|
|
+ List<QuesOption> quesOptions = buildOptions(questionOptionList, defaultQuestionUnit.getRightAnswer());
|
|
|
+ subQues.setQuesOptions(quesOptions);
|
|
|
+ }
|
|
|
+ //设置答案
|
|
|
+ subQues.setQuesAnswer(buildAnswer(defaultQuestionUnit));
|
|
|
+ subList.add(subQues);
|
|
|
+ }
|
|
|
+ question.setSubQuestions(subList);
|
|
|
+ }
|
|
|
+ question = quesRepo.save(question);
|
|
|
+ return question.getId();
|
|
|
+ }
|
|
|
+
|
|
|
+ //构建题型
|
|
|
+ private QuesStructType buildQuesType(QuestionType type){
|
|
|
+ if(type == QuestionType.SINGLE_CHOICE){
|
|
|
+ return QuesStructType.SINGLE_ANSWER_QUESTION;
|
|
|
+ }else if (type == QuestionType.MULTIPLE_CHOICE) {
|
|
|
+ return QuesStructType.MULTIPLE_ANSWER_QUESTION;
|
|
|
+ }else if (type == QuestionType.FILL_UP) {
|
|
|
+ return QuesStructType.FILL_BLANK_QUESTION;
|
|
|
+ }else if (type == QuestionType.ESSAY) {
|
|
|
+ return QuesStructType.TEXT_ANSWER_QUESTION;
|
|
|
+ }else if (type == QuestionType.TRUE_OR_FALSE) {
|
|
|
+ return QuesStructType.BOOL_ANSWER_QUESTION;
|
|
|
+ }else {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //构建选择题选项
|
|
|
+ private List<QuesOption> buildOptions(List<DefaultQuestionOption> questionOptionList,String[] rightAnswer){
|
|
|
+ List<QuesOption> quesOptions = new ArrayList<QuesOption>();
|
|
|
+ for(int i=0;i<questionOptionList.size();i++){
|
|
|
+ DefaultQuestionOption defaultQuestionOption = questionOptionList.get(i);
|
|
|
+ QuesOption option = new QuesOption();
|
|
|
+ option.setNumber(String.valueOf(i+1));
|
|
|
+ option.setOptionBody(defaultQuestionOption.getBody());
|
|
|
+ if(Arrays.asList(rightAnswer).contains(String.valueOf(i))){
|
|
|
+ option.setIsCorrect((short)1);
|
|
|
+ }else {
|
|
|
+ option.setIsCorrect((short)0);
|
|
|
+ }
|
|
|
+ quesOptions.add(option);
|
|
|
+ }
|
|
|
+ return quesOptions;
|
|
|
+ }
|
|
|
+
|
|
|
+ //构建答案
|
|
|
+ private String buildAnswer(DefaultQuestionUnit defaultQuestionUnit){
|
|
|
+ QuestionType questionType = defaultQuestionUnit.getQuestionType();
|
|
|
+ String answer = "";
|
|
|
+ String[] answers = defaultQuestionUnit.getRightAnswer();
|
|
|
+ if(answers == null || answers.length<1){
|
|
|
+ return answer;
|
|
|
+ }
|
|
|
+ if(questionType == QuestionType.SINGLE_CHOICE || questionType == QuestionType.MULTIPLE_CHOICE){
|
|
|
+ for(int i=0;i<answers.length;i++){
|
|
|
+ int number = Integer.valueOf(answers[i]);
|
|
|
+ if(i == 0){
|
|
|
+ answer = CommonUtils.getOptionNum(number);
|
|
|
+ }else {
|
|
|
+ answer = answer + "," + CommonUtils.getOptionNum(number);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return answer;
|
|
|
+ }else if (questionType == QuestionType.FILL_UP) {
|
|
|
+ for(int i=0;i<answers.length;i++){
|
|
|
+ if(i == 0){
|
|
|
+ answer = answers[i];
|
|
|
+ }else {
|
|
|
+ answer = answer + "##" + answers[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return answer;
|
|
|
+ }else if (questionType == QuestionType.ESSAY) {
|
|
|
+ if(answers[0].equals("true")){
|
|
|
+ answer = "正确";
|
|
|
+ }else {
|
|
|
+ answer = "错误";
|
|
|
+ }
|
|
|
+ return answer;
|
|
|
+ }else {
|
|
|
+ for(int i=0;i<answers.length;i++){
|
|
|
+ answer = answer + answers[i];
|
|
|
+ }
|
|
|
+ return answer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Page<DefaultQuestion> findQustions(Long rootOrgId,Map<String, String> map,int curPage,int pageSize) {
|
|
|
+ Query query = new Query();
|
|
|
+ query.addCriteria(Criteria.where("orgId").is(rootOrgId.toString()));
|
|
|
+ query.addCriteria(Criteria.where("isolated").is(true));
|
|
|
+ if(map != null && map.size()>0){
|
|
|
+ for(Map.Entry<String, String> entry:map.entrySet()){
|
|
|
+ String key = "properties." + entry.getKey();
|
|
|
+ query.addCriteria(Criteria.where(key).is(entry.getValue()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ long count = this.mongoTemplate.count(query, Question.class);
|
|
|
+ query.limit(pageSize);
|
|
|
+ query.skip((curPage - 1) * pageSize);
|
|
|
+ List<Question> questionList = this.mongoTemplate.find(query, Question.class);
|
|
|
+ List<DefaultQuestion> defaultQuestions = buildDefaultQuestions(questionList);
|
|
|
+ Page<DefaultQuestion> questions = new PageImpl<DefaultQuestion>(defaultQuestions, new PageRequest(curPage - 1, pageSize), count);
|
|
|
+ return questions;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<DefaultQuestion> buildDefaultQuestions(List<Question> questionList){
|
|
|
+ List<DefaultQuestion> defaultQuestions = new ArrayList<DefaultQuestion>();
|
|
|
+ if(questionList != null && questionList.size()>0){
|
|
|
+ for(Question question:questionList){
|
|
|
+ DefaultQuestion defaultQuestion = getDefaultQuestion(question);
|
|
|
+ defaultQuestions.add(defaultQuestion);
|
|
|
+ }
|
|
|
+ return defaultQuestions;
|
|
|
+ }
|
|
|
+ return defaultQuestions;
|
|
|
+ }
|
|
|
+
|
|
|
+ private DefaultQuestion getDefaultQuestion(Question question){
|
|
|
+ if(question != null){
|
|
|
+ DefaultQuestionStructure defaultQuestionStructure = new DefaultQuestionStructure();
|
|
|
+ //生成新的题单元集合
|
|
|
+ List<DefaultQuestionUnit> questionUnitList = new ArrayList<DefaultQuestionUnit>();
|
|
|
+ if(question.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION){
|
|
|
+ defaultQuestionStructure.setBody(question.getQuesBody());
|
|
|
+ //获取套题下面所有子题
|
|
|
+ List<Question> subQuesList = question.getSubQuestions();
|
|
|
+ if(subQuesList!=null && subQuesList.size()>0){
|
|
|
+ for(int i=0;i<subQuesList.size();i++){
|
|
|
+ Question subQuestion = subQuesList.get(i);
|
|
|
+ DefaultQuestionUnit defaultQuestionUnit = buildQuestionUnit(subQuestion);
|
|
|
+ questionUnitList.add(defaultQuestionUnit);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ DefaultQuestionUnit defaultQuestionUnit = buildQuestionUnit(question);
|
|
|
+ questionUnitList.add(defaultQuestionUnit);
|
|
|
+ }
|
|
|
+ defaultQuestionStructure.setQuestionUnitList(questionUnitList);
|
|
|
+ DefaultQuestion defaultQuestion = new DefaultQuestion();
|
|
|
+ defaultQuestion.setId(question.getId());
|
|
|
+ defaultQuestion.setIsolated(true);
|
|
|
+ defaultQuestion.setRootOrgId(Long.valueOf(question.getOrgId()));
|
|
|
+ defaultQuestion.setProperties(question.getProperties());
|
|
|
+ defaultQuestion.setMasterVersion(defaultQuestionStructure);
|
|
|
+ return defaultQuestion;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建试题单元
|
|
|
+ * @param question
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private DefaultQuestionUnit buildQuestionUnit(Question question){
|
|
|
+ DefaultQuestionUnit defaultQuestionUnit = new DefaultQuestionUnit();
|
|
|
+ defaultQuestionUnit.setBody(question.getQuesBody());
|
|
|
+ defaultQuestionUnit.setQuestionType(getByOldType(question.getQuestionType()));
|
|
|
+ //如果是单选或者多选,添加选项和答案转换
|
|
|
+ if(question.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION || question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION){
|
|
|
+ List<DefaultQuestionOption> defaultQuestionOptions = new ArrayList<DefaultQuestionOption>();
|
|
|
+ List<QuesOption> quesOptions = question.getQuesOptions();
|
|
|
+ if(quesOptions != null && quesOptions.size()>0){
|
|
|
+ for(int i=0;i<quesOptions.size();i++){
|
|
|
+ QuesOption quesOption = quesOptions.get(i);
|
|
|
+ DefaultQuestionOption defaultQuestionOption = new DefaultQuestionOption();
|
|
|
+ defaultQuestionOption.setBody(quesOption.getOptionBody());
|
|
|
+ defaultQuestionOptions.add(defaultQuestionOption);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ defaultQuestionUnit.setQuestionOptionList(defaultQuestionOptions);
|
|
|
+ defaultQuestionUnit.setRightAnswer(getSelectQuestionAnswer(quesOptions));
|
|
|
+ }else {
|
|
|
+ defaultQuestionUnit.setRightAnswer(getAnswer(question));
|
|
|
+ }
|
|
|
+ return defaultQuestionUnit;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 题型转换方法
|
|
|
+ * @param quesStructType
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private QuestionType getByOldType(QuesStructType quesStructType){
|
|
|
+ if(quesStructType == QuesStructType.BOOL_ANSWER_QUESTION){
|
|
|
+ return QuestionType.TRUE_OR_FALSE;
|
|
|
+ }
|
|
|
+ if(quesStructType == QuesStructType.FILL_BLANK_QUESTION){
|
|
|
+ return QuestionType.FILL_UP;
|
|
|
+ }
|
|
|
+ if(quesStructType == QuesStructType.MULTIPLE_ANSWER_QUESTION){
|
|
|
+ return QuestionType.MULTIPLE_CHOICE;
|
|
|
+ }
|
|
|
+ if(quesStructType == QuesStructType.SINGLE_ANSWER_QUESTION){
|
|
|
+ return QuestionType.SINGLE_CHOICE;
|
|
|
+ }
|
|
|
+ if(quesStructType == QuesStructType.TEXT_ANSWER_QUESTION){
|
|
|
+ return QuestionType.ESSAY;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置单选题和多选题 答案
|
|
|
+ * @param quesOptions
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String[] getSelectQuestionAnswer(List<QuesOption> quesOptions){
|
|
|
+ String[] rightAnswer = null;
|
|
|
+ List<String> list = new ArrayList<String>();
|
|
|
+ if(quesOptions != null && quesOptions.size()>0){
|
|
|
+ for(int i=0;i<quesOptions.size();i++){
|
|
|
+ QuesOption quesOption = quesOptions.get(i);
|
|
|
+ if(quesOption.getIsCorrect() == 1){
|
|
|
+ list.add(String.valueOf(i));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ rightAnswer = list.toArray(new String[list.size()]);
|
|
|
+ return rightAnswer;
|
|
|
+ }
|
|
|
+ return rightAnswer;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置试题答案
|
|
|
+ * @param question
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String[] getAnswer(Question question){
|
|
|
+ String[] rightAnswer = null;
|
|
|
+ //判断题答案
|
|
|
+ if(question.getQuestionType() == QuesStructType.BOOL_ANSWER_QUESTION){
|
|
|
+ if(question.getQuesAnswer().equals("正确")){
|
|
|
+ rightAnswer = new String[1];
|
|
|
+ rightAnswer[0] = "true";
|
|
|
+ return rightAnswer;
|
|
|
+ }
|
|
|
+ if(question.getQuesAnswer().equals("错误")){
|
|
|
+ rightAnswer = new String[1];
|
|
|
+ rightAnswer[0] = "false";
|
|
|
+ return rightAnswer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //填空题答案
|
|
|
+ if(question.getQuestionType() == QuesStructType.BOOL_ANSWER_QUESTION){
|
|
|
+ rightAnswer = question.getQuesAnswer().split("##");
|
|
|
+ return rightAnswer;
|
|
|
+ }
|
|
|
+ rightAnswer = new String[1];
|
|
|
+ rightAnswer[0] = question.getQuesAnswer();
|
|
|
+ return rightAnswer;
|
|
|
+ }
|
|
|
+}
|