|
@@ -55,630 +55,642 @@ import cn.com.qmth.examcloud.question.commons.core.question.DefaultQuestionUnit;
|
|
|
import cn.com.qmth.examcloud.question.commons.core.question.QuestionType;
|
|
|
|
|
|
/**
|
|
|
- * @author weiwenhai
|
|
|
- * @date 2018.8.15
|
|
|
- * @company qmth
|
|
|
- * @describle provider中的service方法
|
|
|
- * @code 020
|
|
|
+ * @author weiwenhai
|
|
|
+ * @date 2018.8.15
|
|
|
+ * @company qmth
|
|
|
+ * @describle provider中的service方法
|
|
|
+ * @code 020
|
|
|
*/
|
|
|
@Service("extractConfigCloudService")
|
|
|
-public class ExtractConfigProviderServiceImpl implements ExtractConfigProviderService{
|
|
|
-
|
|
|
- protected ExamCloudLog log = ExamCloudLogFactory.getLog(this.getClass());
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private ExtractConfigService extractConfigService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
+public class ExtractConfigProviderServiceImpl implements ExtractConfigProviderService {
|
|
|
+
|
|
|
+ protected ExamCloudLog log = ExamCloudLogFactory.getLog(this.getClass());
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ExtractConfigService extractConfigService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
private PaperRepo paperRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private PaperDetailRepo paperDetailRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private PaperDetailRepo paperDetailRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
private PaperDetailUnitRepo paperDetailUnitRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
+
|
|
|
+ @Autowired
|
|
|
private QuesRepo quesRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
+
|
|
|
+ @Autowired
|
|
|
private AudioTimeConfigRepo audioTimeConfigRepo;
|
|
|
-
|
|
|
+
|
|
|
@Autowired
|
|
|
private QuestionAudioService questionAudioService;
|
|
|
-
|
|
|
+
|
|
|
@Autowired
|
|
|
private QuesService quesService;
|
|
|
-
|
|
|
+
|
|
|
@Autowired
|
|
|
private PaperService paperService;
|
|
|
-
|
|
|
- @Value("${upyun.downloadUrl}")
|
|
|
- private String downloadUrl;
|
|
|
-
|
|
|
- @Override
|
|
|
- public Map<String, Object> getDefaultPaper(Long examId,String courseCode,String groupCode) {
|
|
|
- Map<String,Object> map = new HashMap<String, Object>();
|
|
|
- log.debug("调卷开始...");
|
|
|
- long startTime = System.currentTimeMillis();
|
|
|
- log.debug("开始根据examId:"+ examId +"和courseCode:"+ courseCode +"获取调卷规则");
|
|
|
- ExtractConfig extractConfig = extractConfigService.findConfig(new ExtractConfig(examId,courseCode));
|
|
|
- if(extractConfig == null){
|
|
|
- log.error("该课程调卷规则未制定,请联系学校");
|
|
|
- throw new StatusException("Q-020101","该课程调卷规则未制定,请联系学校");
|
|
|
- }
|
|
|
- long configFinishTime = System.currentTimeMillis();
|
|
|
- log.debug("获取调卷规则共耗时:"+ (configFinishTime - startTime)+"ms");
|
|
|
- log.debug("根据调卷规则中设置的概率获取类型为"+ groupCode +"的试卷");
|
|
|
- Map<String,Paper> paperMap = this.getExamPaperByProbability(extractConfig.getExamPaperList());
|
|
|
- if(paperMap.isEmpty()){
|
|
|
- log.error("该考试和课程下调卷规则中试卷不存在,请检查调卷规则,调卷程序退出");
|
|
|
- throw new StatusException("Q-020109","该考试和课程下调卷规则中试卷不存在,请重新制定调卷规则");
|
|
|
- }
|
|
|
- long paperMapFinishTime = System.currentTimeMillis();
|
|
|
- log.debug("获取类型为"+ groupCode +"的试卷共耗时:"+ (paperMapFinishTime - configFinishTime)+"ms");
|
|
|
- Paper basePaper = paperMap.get(groupCode);
|
|
|
- if(basePaper==null){
|
|
|
- log.error("该考试和课程下调卷规则中该类型试卷不存在,请检查调卷规则,调卷程序退出");
|
|
|
- throw new StatusException("Q-020116","该考试和课程下调卷规则中试卷不存在,请重新制定调卷规则");
|
|
|
- }
|
|
|
- log.debug("将原始试卷:"+ basePaper.getId() +"根据规则重新组卷");
|
|
|
- Short upSetQuestionOrder = extractConfig.getScrambling_the_question_order();
|
|
|
- Short upSetOptionOrder = extractConfig.getScrambling_the_option_order();
|
|
|
- map.put("upSetQuestionOrder", upSetQuestionOrder);
|
|
|
- map.put("upSetOptionOrder", upSetOptionOrder);
|
|
|
- map.put("paperId", basePaper.getId());
|
|
|
- //构建试卷结构
|
|
|
- DefaultPaper defaultPaper = buildDefaultByBasePaper(basePaper,String.valueOf(examId),courseCode,groupCode);
|
|
|
- map.put("defaultPaper", defaultPaper);
|
|
|
- return map;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 每个试卷类型取出一套试卷
|
|
|
- * {
|
|
|
- * A:Paper,
|
|
|
- * B:Paper
|
|
|
- * }
|
|
|
- * A是试卷类型 Paper是A类型下选定的试卷
|
|
|
- * @param examPaperList
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Map<String,Paper> getExamPaperByProbability(List<ExamPaper> examPaperList){
|
|
|
- Map<String,Paper> paperByTypeMap = new HashMap<String,Paper>();
|
|
|
- if(examPaperList == null || examPaperList.size() == 0) {
|
|
|
- throw new StatusException("Q-020114","可供抽取的试卷集合为空,无法抽取试卷");
|
|
|
+
|
|
|
+ @Value("${upyun.downloadUrl}")
|
|
|
+ private String downloadUrl;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> getDefaultPaper(Long examId, String courseCode, String groupCode) {
|
|
|
+ Map<String, Object> map = new HashMap<String, Object>();
|
|
|
+ log.debug("调卷开始...");
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
+ log.debug("开始根据examId:" + examId + "和courseCode:" + courseCode + "获取调卷规则");
|
|
|
+ ExtractConfig extractConfig = extractConfigService.findConfig(new ExtractConfig(examId, courseCode));
|
|
|
+ if (extractConfig == null) {
|
|
|
+ log.error("该课程调卷规则未制定,请联系学校");
|
|
|
+ throw new StatusException("Q-020101", "该课程调卷规则未制定,请联系学校");
|
|
|
+ }
|
|
|
+ long configFinishTime = System.currentTimeMillis();
|
|
|
+ log.debug("获取调卷规则共耗时:" + (configFinishTime - startTime) + "ms");
|
|
|
+ log.debug("根据调卷规则中设置的概率获取类型为" + groupCode + "的试卷");
|
|
|
+ Map<String, Paper> paperMap = this.getExamPaperByProbability(extractConfig.getExamPaperList());
|
|
|
+ if (paperMap.isEmpty()) {
|
|
|
+ log.error("该考试和课程下调卷规则中试卷不存在,请检查调卷规则,调卷程序退出");
|
|
|
+ throw new StatusException("Q-020109", "该考试和课程下调卷规则中试卷不存在,请重新制定调卷规则");
|
|
|
+ }
|
|
|
+ long paperMapFinishTime = System.currentTimeMillis();
|
|
|
+ log.debug("获取类型为" + groupCode + "的试卷共耗时:" + (paperMapFinishTime - configFinishTime) + "ms");
|
|
|
+ Paper basePaper = paperMap.get(groupCode);
|
|
|
+ if (basePaper == null) {
|
|
|
+ log.error("该考试和课程下调卷规则中该类型试卷不存在,请检查调卷规则,调卷程序退出");
|
|
|
+ throw new StatusException("Q-020116", "该考试和课程下调卷规则中试卷不存在,请重新制定调卷规则");
|
|
|
+ }
|
|
|
+ log.debug("将原始试卷:" + basePaper.getId() + "根据规则重新组卷");
|
|
|
+ Short upSetQuestionOrder = extractConfig.getScrambling_the_question_order();
|
|
|
+ Short upSetOptionOrder = extractConfig.getScrambling_the_option_order();
|
|
|
+ map.put("upSetQuestionOrder", upSetQuestionOrder);
|
|
|
+ map.put("upSetOptionOrder", upSetOptionOrder);
|
|
|
+ map.put("paperId", basePaper.getId());
|
|
|
+ //构建试卷结构
|
|
|
+ DefaultPaper defaultPaper = buildDefaultByBasePaper(basePaper, String.valueOf(examId), courseCode, groupCode);
|
|
|
+ map.put("defaultPaper", defaultPaper);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 每个试卷类型取出一套试卷
|
|
|
+ * {
|
|
|
+ * A:Paper,
|
|
|
+ * B:Paper
|
|
|
+ * }
|
|
|
+ * A是试卷类型 Paper是A类型下选定的试卷
|
|
|
+ *
|
|
|
+ * @param examPaperList
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Map<String, Paper> getExamPaperByProbability(List<ExamPaper> examPaperList) {
|
|
|
+ Map<String, Paper> paperByTypeMap = new HashMap<String, Paper>();
|
|
|
+ if (examPaperList == null || examPaperList.size() == 0) {
|
|
|
+ throw new StatusException("Q-020114", "可供抽取的试卷集合为空,无法抽取试卷");
|
|
|
+ }
|
|
|
+ Map<String, List<ExamPaper>> examPaperMap = new HashMap<String, List<ExamPaper>>();
|
|
|
+ for (int i = 0; i < examPaperList.size(); i++) {
|
|
|
+ ExamPaper examPaper = examPaperList.get(i);
|
|
|
+ if (!examPaperMap.containsKey(examPaper.getGroupCode())) {
|
|
|
+ if (examPaper.getPaper() != null) {
|
|
|
+ List<ExamPaper> epList = new ArrayList<ExamPaper>();
|
|
|
+ epList.add(examPaper);
|
|
|
+ examPaperMap.put(examPaper.getGroupCode(), epList);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (examPaper.getPaper() != null) {
|
|
|
+ List<ExamPaper> epList = examPaperMap.get(examPaper.getGroupCode());
|
|
|
+ epList.add(examPaper);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (examPaperMap != null) {
|
|
|
+ Set<String> keys = examPaperMap.keySet();
|
|
|
+ Iterator<String> it = keys.iterator();
|
|
|
+ while (it.hasNext()) {
|
|
|
+ String key = it.next();
|
|
|
+ Paper paper = this.getPaperByProbability(examPaperMap.get(key));
|
|
|
+ //不能用原来的paper对象,否则examPaperList中的paper对象会被覆盖
|
|
|
+ Paper newPaper = Model.of(paperRepo.findById(paper.getId()));
|
|
|
+ paperByTypeMap.put(key, newPaper);
|
|
|
+ }
|
|
|
}
|
|
|
- Map<String,List<ExamPaper>> examPaperMap = new HashMap<String,List<ExamPaper>>();
|
|
|
- for(int i = 0;i<examPaperList.size();i++){
|
|
|
- ExamPaper examPaper = examPaperList.get(i);
|
|
|
- if(!examPaperMap.containsKey(examPaper.getGroupCode())){
|
|
|
- if(examPaper.getPaper()!=null){
|
|
|
- List<ExamPaper> epList = new ArrayList<ExamPaper>();
|
|
|
- epList.add(examPaper);
|
|
|
- examPaperMap.put(examPaper.getGroupCode(), epList);
|
|
|
- }
|
|
|
- }else{
|
|
|
- if(examPaper.getPaper()!=null){
|
|
|
- List<ExamPaper> epList = examPaperMap.get(examPaper.getGroupCode());
|
|
|
- epList.add(examPaper);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if(examPaperMap!=null){
|
|
|
- Set<String> keys = examPaperMap.keySet();
|
|
|
- Iterator<String> it = keys.iterator();
|
|
|
- while (it.hasNext()) {
|
|
|
- String key = it.next();
|
|
|
- Paper paper = this.getPaperByProbability(examPaperMap.get(key));
|
|
|
- //不能用原来的paper对象,否则examPaperList中的paper对象会被覆盖
|
|
|
- Paper newPaper = Model.of(paperRepo.findById(paper.getId()));
|
|
|
- paperByTypeMap.put(key,newPaper);
|
|
|
- }
|
|
|
- }
|
|
|
return paperByTypeMap;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 根据设定几率取出一套试卷
|
|
|
- * @param examPaperList
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Paper getPaperByProbability(List<ExamPaper> examPaperList){
|
|
|
- int sum = 0;
|
|
|
- for (int i = 0;i<examPaperList.size();i++) {
|
|
|
- sum += examPaperList.get(i).getWeight();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据设定几率取出一套试卷
|
|
|
+ *
|
|
|
+ * @param examPaperList
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Paper getPaperByProbability(List<ExamPaper> examPaperList) {
|
|
|
+ int sum = 0;
|
|
|
+ for (int i = 0; i < examPaperList.size(); i++) {
|
|
|
+ sum += examPaperList.get(i).getWeight();
|
|
|
}
|
|
|
// 从1开始
|
|
|
- Integer rand = new Random().nextInt(sum) + 1;
|
|
|
- for (int i = 0;i<examPaperList.size();i++) {
|
|
|
+ Integer rand = new Random().nextInt(sum) + 1;
|
|
|
+ for (int i = 0; i < examPaperList.size(); i++) {
|
|
|
rand -= examPaperList.get(i).getWeight();
|
|
|
// 选中
|
|
|
if (rand <= 0) {
|
|
|
return examPaperList.get(i).getPaper();
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
return null;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 根据paper对象构建DefaultPaper对象
|
|
|
- * @param basePaper
|
|
|
- * @return
|
|
|
- */
|
|
|
- public DefaultPaper buildDefaultByBasePaper(Paper basePaper,String examId,String courseCode,String groupCode){
|
|
|
- log.debug("开始包装网考需要的试卷结构...");
|
|
|
- long beginTime = System.currentTimeMillis();
|
|
|
- //获取大题
|
|
|
- List<PaperDetail> paperDetails = paperDetailRepo.findByPaper(basePaper);
|
|
|
- long pdTime = System.currentTimeMillis();
|
|
|
- log.debug("数据库取大题耗时:"+(pdTime - beginTime)+"ms");
|
|
|
- Collections.sort(paperDetails);
|
|
|
- long pdSortEndTime = System.currentTimeMillis();
|
|
|
- log.debug("排序大题耗时:"+(pdSortEndTime - pdTime)+"ms");
|
|
|
- //将小题全部取出来,只取一次,减少对数据库的查询
|
|
|
- List<PaperDetailUnit> allPaperDetailUnits = paperDetailUnitRepo.findByPaper(basePaper);
|
|
|
- boolean fullyObjective = checkIsAllQbjectiveQuestion(allPaperDetailUnits);
|
|
|
- long pduEndTime = System.currentTimeMillis();
|
|
|
- log.debug("数据库取所有小题耗时:"+(pduEndTime - pdSortEndTime)+"ms");
|
|
|
- //根据大题id将小题归类
|
|
|
- Map<String,List<PaperDetailUnit>> pduMap = allPaperDetailUnits.stream().collect(Collectors.groupingBy(PaperDetailUnit::getDetailId));
|
|
|
- long pduMapEndTime = System.currentTimeMillis();
|
|
|
- log.debug("获取大题与小题对应关系耗时:"+(pduMapEndTime - pduEndTime)+"ms");
|
|
|
- log.debug("循环大题,开始组装对象...");
|
|
|
- //生成新的分组集合
|
|
|
- List<DefaultQuestionGroup> questionGroupList = new ArrayList<DefaultQuestionGroup>();
|
|
|
- for(int i = 0; i < paperDetails.size(); i++){
|
|
|
- PaperDetail paperDetail = paperDetails.get(i);
|
|
|
- DefaultQuestionGroup defaultQuestionGroup = new DefaultQuestionGroup();
|
|
|
- defaultQuestionGroup.setGroupName(paperDetail.getName());
|
|
|
- defaultQuestionGroup.setGroupScore(paperDetail.getScore());
|
|
|
- //生成新的题包装器集合
|
|
|
- List<DefaultQuestionStructureWrapper> questionWrapperList = new ArrayList<DefaultQuestionStructureWrapper>();
|
|
|
- //获取原小题的集合
|
|
|
- List<PaperDetailUnit> paperDetailUnits = pduMap.get(paperDetail.getId());
|
|
|
- if(paperDetailUnits==null || paperDetailUnits.size()<1){
|
|
|
- log.error("试卷大题下面,没有小题");
|
|
|
- throw new StatusException("Q-020241","考试试卷有误,请联系老师");
|
|
|
- }
|
|
|
- for(int j =0; j<paperDetailUnits.size(); j++){
|
|
|
- PaperDetailUnit paperDetailUnit = paperDetailUnits.get(j);
|
|
|
- DefaultQuestionStructureWrapper defaultQuestionStructureWrapper = new DefaultQuestionStructureWrapper();
|
|
|
- defaultQuestionStructureWrapper.setQuestionId(paperDetailUnit.getQuestion().getId());
|
|
|
- defaultQuestionStructureWrapper.setVersion(CommonUtils.QUESTION_VERSION);
|
|
|
- defaultQuestionStructureWrapper.setQuestionScore(paperDetailUnit.getScore());
|
|
|
- defaultQuestionStructureWrapper.setTimeLimit(paperDetailUnit.getTimeLimit());
|
|
|
- if(examId != null){
|
|
|
- //设置音频播放次数
|
|
|
- if(paperDetailUnit.getQuestion().getHasAudio() != null && paperDetailUnit.getQuestion().getHasAudio() == true){
|
|
|
- AudioTimeConfig audioTimeConfig = Model.of( audioTimeConfigRepo.findOne(Example.of(new AudioTimeConfig(examId,courseCode,groupCode,paperDetailUnit.getQuestion().getId()))));
|
|
|
- if(audioTimeConfig != null){
|
|
|
- defaultQuestionStructureWrapper.setLimitedPlayTimes(audioTimeConfig.getPlayTime());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- //生成新的题单元包装器
|
|
|
- List<DefaultQuestionUnitWrapper> defaultQuestionUnitWrappers = new ArrayList<DefaultQuestionUnitWrapper>();
|
|
|
- if(paperDetailUnit.getQuestion().getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION){
|
|
|
- List<Question> subQuesList = paperDetailUnit.getQuestion().getSubQuestions();
|
|
|
- List<Double> scoreList = paperDetailUnit.getSubScoreList();
|
|
|
- if(subQuesList != null && subQuesList.size()>0){
|
|
|
- for(int k =0;k<subQuesList.size();k++){
|
|
|
- DefaultQuestionUnitWrapper defaultQuestionUnitWrapper = buildQuesUnitWrapper(subQuesList.get(k),scoreList.get(k));
|
|
|
- defaultQuestionUnitWrappers.add(defaultQuestionUnitWrapper);
|
|
|
- }
|
|
|
- }
|
|
|
- }else {
|
|
|
- DefaultQuestionUnitWrapper defaultQuestionUnitWrapper = buildQuesUnitWrapper(paperDetailUnit.getQuestion(),paperDetailUnit.getScore());
|
|
|
- defaultQuestionUnitWrappers.add(defaultQuestionUnitWrapper);
|
|
|
- }
|
|
|
- defaultQuestionStructureWrapper.setQuestionUnitWrapperList(defaultQuestionUnitWrappers);
|
|
|
- questionWrapperList.add(defaultQuestionStructureWrapper);
|
|
|
- }
|
|
|
- defaultQuestionGroup.setQuestionWrapperList(questionWrapperList);
|
|
|
- questionGroupList.add(defaultQuestionGroup);
|
|
|
- }
|
|
|
- DefaultPaper defaultPaper = new DefaultPaper();
|
|
|
- defaultPaper.setName(basePaper.getName());
|
|
|
- defaultPaper.setQuestionGroupList(questionGroupList);
|
|
|
- defaultPaper.setFullyObjective(fullyObjective);
|
|
|
- return defaultPaper;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 根据question生成题单元包装器
|
|
|
- * @param question
|
|
|
- * @param score
|
|
|
- * @return
|
|
|
- */
|
|
|
- private DefaultQuestionUnitWrapper buildQuesUnitWrapper(Question question,Double score){
|
|
|
- DefaultQuestionUnitWrapper defaultQuestionUnitWrapper = new DefaultQuestionUnitWrapper();
|
|
|
- Integer[] optionPermutation = null;
|
|
|
- if(question.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION ||
|
|
|
- question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION){
|
|
|
- int length = question.getQuesOptions().size();
|
|
|
- optionPermutation = new Integer[length];
|
|
|
- for(int i=0;i<length;i++){
|
|
|
- optionPermutation[i] = i;
|
|
|
- }
|
|
|
- }
|
|
|
- defaultQuestionUnitWrapper.setOptionPermutation(optionPermutation);
|
|
|
- defaultQuestionUnitWrapper.setQuestionScore(score);
|
|
|
- defaultQuestionUnitWrapper.setQuestionType(getByOldType(question.getQuestionType()));
|
|
|
- return defaultQuestionUnitWrapper;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 题型转换方法
|
|
|
- * @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;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @Override
|
|
|
- public DefaultQuestion getDefaultQuestion(Long examId, String courseCode, String groupCode, String questionId) {
|
|
|
- log.debug("网考根据调卷规则中试题id:"+ questionId +"获取单个试题...");
|
|
|
- long beginTime = System.currentTimeMillis();
|
|
|
- Question question = Model.of( quesRepo.findById(questionId));
|
|
|
- if(question == null){
|
|
|
- throw new StatusException("Q-020330", "question is null");
|
|
|
- }
|
|
|
- quesService.formatQues(question);
|
|
|
- long oldQuesTime = System.currentTimeMillis();
|
|
|
- log.debug("查询单个试题耗时:"+(oldQuesTime - beginTime)+"ms");
|
|
|
- DefaultQuestionStructure defaultQuestionStructure = new DefaultQuestionStructure();
|
|
|
- if(question.getHasAudio() == null || false == question.getHasAudio()){
|
|
|
- defaultQuestionStructure.setHasAudios(false);
|
|
|
- }else {
|
|
|
- defaultQuestionStructure.setHasAudios(true);
|
|
|
- }
|
|
|
- defaultQuestionStructure.setVersion(CommonUtils.QUESTION_VERSION);
|
|
|
- //生成新的题单元集合
|
|
|
- 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(questionId);
|
|
|
- defaultQuestion.setMasterVersion(defaultQuestionStructure);
|
|
|
- long newQuesTime = System.currentTimeMillis();
|
|
|
- log.debug("构建一个新的试题单元耗时:"+(newQuesTime - oldQuesTime)+"ms");
|
|
|
- //替换试题单元中的音频路径
|
|
|
- log.debug("给新的试题替换音频标签...");
|
|
|
- if(examId != null){
|
|
|
- appendAudioFlag(defaultQuestion,String.valueOf(examId),courseCode,groupCode,question);
|
|
|
- }
|
|
|
- long finishTime = System.currentTimeMillis();
|
|
|
- log.debug("给新的试题替换音频标签耗时:"+(finishTime- newQuesTime)+"ms");
|
|
|
- return defaultQuestion;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 构建试题单元
|
|
|
- * @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 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;
|
|
|
- }
|
|
|
- }
|
|
|
- //填空题答案
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据paper对象构建DefaultPaper对象
|
|
|
+ *
|
|
|
+ * @param basePaper
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public DefaultPaper buildDefaultByBasePaper(Paper basePaper, String examId, String courseCode, String groupCode) {
|
|
|
+ log.debug("开始包装网考需要的试卷结构...");
|
|
|
+ long beginTime = System.currentTimeMillis();
|
|
|
+ //获取大题
|
|
|
+ List<PaperDetail> paperDetails = paperDetailRepo.findByPaper(basePaper);
|
|
|
+ long pdTime = System.currentTimeMillis();
|
|
|
+ log.debug("数据库取大题耗时:" + (pdTime - beginTime) + "ms");
|
|
|
+ Collections.sort(paperDetails);
|
|
|
+ long pdSortEndTime = System.currentTimeMillis();
|
|
|
+ log.debug("排序大题耗时:" + (pdSortEndTime - pdTime) + "ms");
|
|
|
+ //将小题全部取出来,只取一次,减少对数据库的查询
|
|
|
+ List<PaperDetailUnit> allPaperDetailUnits = paperDetailUnitRepo.findByPaper(basePaper);
|
|
|
+ boolean fullyObjective = checkIsAllQbjectiveQuestion(allPaperDetailUnits);
|
|
|
+ long pduEndTime = System.currentTimeMillis();
|
|
|
+ log.debug("数据库取所有小题耗时:" + (pduEndTime - pdSortEndTime) + "ms");
|
|
|
+ //根据大题id将小题归类
|
|
|
+ Map<String, List<PaperDetailUnit>> pduMap = allPaperDetailUnits.stream().collect(Collectors.groupingBy(PaperDetailUnit::getDetailId));
|
|
|
+ long pduMapEndTime = System.currentTimeMillis();
|
|
|
+ log.debug("获取大题与小题对应关系耗时:" + (pduMapEndTime - pduEndTime) + "ms");
|
|
|
+ log.debug("循环大题,开始组装对象...");
|
|
|
+ //生成新的分组集合
|
|
|
+ List<DefaultQuestionGroup> questionGroupList = new ArrayList<DefaultQuestionGroup>();
|
|
|
+ for (int i = 0; i < paperDetails.size(); i++) {
|
|
|
+ PaperDetail paperDetail = paperDetails.get(i);
|
|
|
+ DefaultQuestionGroup defaultQuestionGroup = new DefaultQuestionGroup();
|
|
|
+ defaultQuestionGroup.setGroupName(paperDetail.getName());
|
|
|
+ defaultQuestionGroup.setGroupScore(paperDetail.getScore());
|
|
|
+ //生成新的题包装器集合
|
|
|
+ List<DefaultQuestionStructureWrapper> questionWrapperList = new ArrayList<DefaultQuestionStructureWrapper>();
|
|
|
+ //获取原小题的集合
|
|
|
+ List<PaperDetailUnit> paperDetailUnits = pduMap.get(paperDetail.getId());
|
|
|
+ if (paperDetailUnits == null || paperDetailUnits.size() < 1) {
|
|
|
+ log.error("试卷大题下面,没有小题");
|
|
|
+ throw new StatusException("Q-020241", "考试试卷有误,请联系老师");
|
|
|
+ }
|
|
|
+ for (int j = 0; j < paperDetailUnits.size(); j++) {
|
|
|
+ PaperDetailUnit paperDetailUnit = paperDetailUnits.get(j);
|
|
|
+ DefaultQuestionStructureWrapper defaultQuestionStructureWrapper = new DefaultQuestionStructureWrapper();
|
|
|
+ defaultQuestionStructureWrapper.setQuestionId(paperDetailUnit.getQuestion().getId());
|
|
|
+ defaultQuestionStructureWrapper.setVersion(CommonUtils.QUESTION_VERSION);
|
|
|
+ defaultQuestionStructureWrapper.setQuestionScore(paperDetailUnit.getScore());
|
|
|
+ defaultQuestionStructureWrapper.setTimeLimit(paperDetailUnit.getTimeLimit());
|
|
|
+ if (examId != null) {
|
|
|
+ //设置音频播放次数
|
|
|
+ if (paperDetailUnit.getQuestion().getHasAudio() != null && paperDetailUnit.getQuestion().getHasAudio() == true) {
|
|
|
+ AudioTimeConfig audioTimeConfig = Model.of(audioTimeConfigRepo.findOne(Example.of(new AudioTimeConfig(examId, courseCode, groupCode, paperDetailUnit.getQuestion().getId()))));
|
|
|
+ if (audioTimeConfig != null) {
|
|
|
+ defaultQuestionStructureWrapper.setLimitedPlayTimes(audioTimeConfig.getPlayTime());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //生成新的题单元包装器
|
|
|
+ List<DefaultQuestionUnitWrapper> defaultQuestionUnitWrappers = new ArrayList<DefaultQuestionUnitWrapper>();
|
|
|
+ if (paperDetailUnit.getQuestion().getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
|
|
|
+ List<Question> subQuesList = paperDetailUnit.getQuestion().getSubQuestions();
|
|
|
+ List<Double> scoreList = paperDetailUnit.getSubScoreList();
|
|
|
+ if (subQuesList != null && subQuesList.size() > 0) {
|
|
|
+ for (int k = 0; k < subQuesList.size(); k++) {
|
|
|
+ DefaultQuestionUnitWrapper defaultQuestionUnitWrapper = buildQuesUnitWrapper(subQuesList.get(k), scoreList.get(k));
|
|
|
+ defaultQuestionUnitWrappers.add(defaultQuestionUnitWrapper);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ DefaultQuestionUnitWrapper defaultQuestionUnitWrapper = buildQuesUnitWrapper(paperDetailUnit.getQuestion(), paperDetailUnit.getScore());
|
|
|
+ defaultQuestionUnitWrappers.add(defaultQuestionUnitWrapper);
|
|
|
+ }
|
|
|
+ defaultQuestionStructureWrapper.setQuestionUnitWrapperList(defaultQuestionUnitWrappers);
|
|
|
+ questionWrapperList.add(defaultQuestionStructureWrapper);
|
|
|
+ }
|
|
|
+ defaultQuestionGroup.setQuestionWrapperList(questionWrapperList);
|
|
|
+ questionGroupList.add(defaultQuestionGroup);
|
|
|
+ }
|
|
|
+ DefaultPaper defaultPaper = new DefaultPaper();
|
|
|
+ defaultPaper.setName(basePaper.getName());
|
|
|
+ defaultPaper.setQuestionGroupList(questionGroupList);
|
|
|
+ defaultPaper.setFullyObjective(fullyObjective);
|
|
|
+ return defaultPaper;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据question生成题单元包装器
|
|
|
+ *
|
|
|
+ * @param question
|
|
|
+ * @param score
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private DefaultQuestionUnitWrapper buildQuesUnitWrapper(Question question, Double score) {
|
|
|
+ DefaultQuestionUnitWrapper defaultQuestionUnitWrapper = new DefaultQuestionUnitWrapper();
|
|
|
+ Integer[] optionPermutation = null;
|
|
|
+ if (question.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION ||
|
|
|
+ question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION) {
|
|
|
+ int length = question.getQuesOptions().size();
|
|
|
+ optionPermutation = new Integer[length];
|
|
|
+ for (int i = 0; i < length; i++) {
|
|
|
+ optionPermutation[i] = i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ defaultQuestionUnitWrapper.setOptionPermutation(optionPermutation);
|
|
|
+ defaultQuestionUnitWrapper.setQuestionScore(score);
|
|
|
+ defaultQuestionUnitWrapper.setQuestionType(getByOldType(question.getQuestionType()));
|
|
|
+ return defaultQuestionUnitWrapper;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 题型转换方法
|
|
|
+ *
|
|
|
+ * @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;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public DefaultQuestion getDefaultQuestion(Long examId, String courseCode, String groupCode, String questionId) {
|
|
|
+ log.debug("网考根据调卷规则中试题id:" + questionId + "获取单个试题...");
|
|
|
+ long beginTime = System.currentTimeMillis();
|
|
|
+ Question question = Model.of(quesRepo.findById(questionId));
|
|
|
+ if (question == null) {
|
|
|
+ throw new StatusException("Q-020330", "question is null");
|
|
|
+ }
|
|
|
+ quesService.formatQues(question);
|
|
|
+ long oldQuesTime = System.currentTimeMillis();
|
|
|
+ log.debug("查询单个试题耗时:" + (oldQuesTime - beginTime) + "ms");
|
|
|
+ DefaultQuestionStructure defaultQuestionStructure = new DefaultQuestionStructure();
|
|
|
+ if (question.getHasAudio() == null || false == question.getHasAudio()) {
|
|
|
+ defaultQuestionStructure.setHasAudios(false);
|
|
|
+ } else {
|
|
|
+ defaultQuestionStructure.setHasAudios(true);
|
|
|
+ }
|
|
|
+ defaultQuestionStructure.setVersion(CommonUtils.QUESTION_VERSION);
|
|
|
+ //生成新的题单元集合
|
|
|
+ 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(questionId);
|
|
|
+ defaultQuestion.setMasterVersion(defaultQuestionStructure);
|
|
|
+ long newQuesTime = System.currentTimeMillis();
|
|
|
+ log.debug("构建一个新的试题单元耗时:" + (newQuesTime - oldQuesTime) + "ms");
|
|
|
+ //替换试题单元中的音频路径
|
|
|
+ log.debug("给新的试题替换音频标签...");
|
|
|
+ if (examId != null) {
|
|
|
+ appendAudioFlag(defaultQuestion, String.valueOf(examId), courseCode, groupCode, question);
|
|
|
+ }
|
|
|
+ long finishTime = System.currentTimeMillis();
|
|
|
+ log.debug("给新的试题替换音频标签耗时:" + (finishTime - newQuesTime) + "ms");
|
|
|
+ return defaultQuestion;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建试题单元
|
|
|
+ *
|
|
|
+ * @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 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;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * html中添加音频标签
|
|
|
- * @param defaultQuestion
|
|
|
- * @param examId
|
|
|
- * @param courseCode
|
|
|
- * @param groupCode
|
|
|
- * @param question
|
|
|
- */
|
|
|
- private void appendAudioFlag(DefaultQuestion defaultQuestion,String examId,String courseCode,String groupCode,Question question){
|
|
|
- if(question.getHasAudio() != null && question.getHasAudio() == true){
|
|
|
- //1.判断questionDto是否含有音频,如果有添加音频播放次数
|
|
|
- AudioTimeConfig audioTimeConfig = Model.of(audioTimeConfigRepo.findOne(Example.of(new AudioTimeConfig(examId,courseCode,groupCode,question.getId()))));
|
|
|
- if(audioTimeConfig != null){
|
|
|
- //2.1 取到题干,给a标签添加url
|
|
|
- String quesBody = null;
|
|
|
- if(StringUtils.isNotBlank(defaultQuestion.getMasterVersion().getBody())){
|
|
|
- //套题
|
|
|
- quesBody = defaultQuestion.getMasterVersion().getBody();
|
|
|
- defaultQuestion.getMasterVersion().setBody(buildBody(quesBody, audioTimeConfig.getPlayTime()));
|
|
|
- }else {
|
|
|
- DefaultQuestionUnit defaultQuestionUnit = (DefaultQuestionUnit) defaultQuestion.getMasterVersion().getQuestionUnitList().get(0);
|
|
|
- quesBody = defaultQuestionUnit.getBody();
|
|
|
- defaultQuestionUnit.setBody(buildBody(quesBody, audioTimeConfig.getPlayTime()));
|
|
|
- if(defaultQuestionUnit.getQuestionType() == QuestionType.SINGLE_CHOICE || defaultQuestionUnit.getQuestionType() == QuestionType.MULTIPLE_CHOICE){
|
|
|
- List<DefaultQuestionOption> questionOptionList = defaultQuestionUnit.getQuestionOptionList();
|
|
|
- if(questionOptionList != null && questionOptionList.size()>0){
|
|
|
- for(int i = 0;i<questionOptionList.size();i++){
|
|
|
- DefaultQuestionOption defaultQuestionOption = questionOptionList.get(i);
|
|
|
- defaultQuestionOption.setBody(buildBody(defaultQuestionOption.getBody(), audioTimeConfig.getPlayTime()));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }else {
|
|
|
- String quesBody = null;
|
|
|
- if(StringUtils.isNotBlank(defaultQuestion.getMasterVersion().getBody())){
|
|
|
- //套题
|
|
|
- quesBody = defaultQuestion.getMasterVersion().getBody();
|
|
|
- defaultQuestion.getMasterVersion().setBody(buildBody(quesBody, null));
|
|
|
- }else {
|
|
|
- DefaultQuestionUnit defaultQuestionUnit = (DefaultQuestionUnit) defaultQuestion.getMasterVersion().getQuestionUnitList().get(0);
|
|
|
- quesBody = defaultQuestionUnit.getBody();
|
|
|
- defaultQuestionUnit.setBody(buildBody(quesBody, null));
|
|
|
- if(defaultQuestionUnit.getQuestionType() == QuestionType.SINGLE_CHOICE || defaultQuestionUnit.getQuestionType() == QuestionType.MULTIPLE_CHOICE){
|
|
|
- List<DefaultQuestionOption> questionOptionList = defaultQuestionUnit.getQuestionOptionList();
|
|
|
- if(questionOptionList != null && questionOptionList.size()>0){
|
|
|
- for(int i = 0;i<questionOptionList.size();i++){
|
|
|
- DefaultQuestionOption defaultQuestionOption = questionOptionList.get(i);
|
|
|
- defaultQuestionOption.setBody(buildBody(defaultQuestionOption.getBody(), null));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 给题目和选项添加url
|
|
|
- * @param body
|
|
|
- * @param playTime
|
|
|
- * @return
|
|
|
- */
|
|
|
- public String buildBody(String body,Integer playTime){
|
|
|
- String[] bodyStrings = body.split("></a>");
|
|
|
- if(bodyStrings.length>1){
|
|
|
- String resultBody = "";
|
|
|
- for(int i = 0;i<bodyStrings.length;i++){
|
|
|
- String containAStr = bodyStrings[i];
|
|
|
- if(containAStr.indexOf("<a")>-1){
|
|
|
- String questionAudioId = matchAudioName(containAStr, "a", "id");
|
|
|
- QuestionAudio questionAudio = questionAudioService.findAudioById(questionAudioId);
|
|
|
- if(questionAudio!=null){
|
|
|
- String url = downloadUrl + questionAudio.getFileUrl();
|
|
|
- if(playTime!=null){
|
|
|
- containAStr += " question-audio url=\""+url+"\" playTime=\""+playTime+"\""+"></a>";
|
|
|
- }else{
|
|
|
- containAStr += " question-audio url=\""+url+"\""+"></a>";
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- resultBody+=containAStr;
|
|
|
- }
|
|
|
- return resultBody;
|
|
|
- }else{
|
|
|
- return body;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取一段html中某个标签的值
|
|
|
- * @param source
|
|
|
- * @param element
|
|
|
- * @param attr
|
|
|
- * @return
|
|
|
- */
|
|
|
- private String matchAudioName(String source, String element, String attr) {
|
|
|
- String reg = "<" + element + "[^<>]*?\\s" + attr + "=['\"]?(.*?)['\"]?(\\s.*?)";
|
|
|
- Matcher m = Pattern.compile(reg).matcher(source);
|
|
|
- while (m.find()) {
|
|
|
+ rightAnswer = new String[1];
|
|
|
+ rightAnswer[0] = question.getQuesAnswer();
|
|
|
+ return rightAnswer;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * html中添加音频标签
|
|
|
+ *
|
|
|
+ * @param defaultQuestion
|
|
|
+ * @param examId
|
|
|
+ * @param courseCode
|
|
|
+ * @param groupCode
|
|
|
+ * @param question
|
|
|
+ */
|
|
|
+ private void appendAudioFlag(DefaultQuestion defaultQuestion, String examId, String courseCode, String groupCode, Question question) {
|
|
|
+ if (question.getHasAudio() != null && question.getHasAudio() == true) {
|
|
|
+ //1.判断questionDto是否含有音频,如果有添加音频播放次数
|
|
|
+ AudioTimeConfig audioTimeConfig = Model.of(audioTimeConfigRepo.findOne(Example.of(new AudioTimeConfig(examId, courseCode, groupCode, question.getId()))));
|
|
|
+ if (audioTimeConfig != null) {
|
|
|
+ //2.1 取到题干,给a标签添加url
|
|
|
+ String quesBody = null;
|
|
|
+ if (StringUtils.isNotBlank(defaultQuestion.getMasterVersion().getBody())) {
|
|
|
+ //套题
|
|
|
+ quesBody = defaultQuestion.getMasterVersion().getBody();
|
|
|
+ defaultQuestion.getMasterVersion().setBody(buildBody(quesBody, audioTimeConfig.getPlayTime()));
|
|
|
+ } else {
|
|
|
+ DefaultQuestionUnit defaultQuestionUnit = (DefaultQuestionUnit) defaultQuestion.getMasterVersion().getQuestionUnitList().get(0);
|
|
|
+ quesBody = defaultQuestionUnit.getBody();
|
|
|
+ defaultQuestionUnit.setBody(buildBody(quesBody, audioTimeConfig.getPlayTime()));
|
|
|
+ if (defaultQuestionUnit.getQuestionType() == QuestionType.SINGLE_CHOICE || defaultQuestionUnit.getQuestionType() == QuestionType.MULTIPLE_CHOICE) {
|
|
|
+ List<DefaultQuestionOption> questionOptionList = defaultQuestionUnit.getQuestionOptionList();
|
|
|
+ if (questionOptionList != null && questionOptionList.size() > 0) {
|
|
|
+ for (int i = 0; i < questionOptionList.size(); i++) {
|
|
|
+ DefaultQuestionOption defaultQuestionOption = questionOptionList.get(i);
|
|
|
+ defaultQuestionOption.setBody(buildBody(defaultQuestionOption.getBody(), audioTimeConfig.getPlayTime()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ String quesBody = null;
|
|
|
+ if (StringUtils.isNotBlank(defaultQuestion.getMasterVersion().getBody())) {
|
|
|
+ //套题
|
|
|
+ quesBody = defaultQuestion.getMasterVersion().getBody();
|
|
|
+ defaultQuestion.getMasterVersion().setBody(buildBody(quesBody, null));
|
|
|
+ } else {
|
|
|
+ DefaultQuestionUnit defaultQuestionUnit = (DefaultQuestionUnit) defaultQuestion.getMasterVersion().getQuestionUnitList().get(0);
|
|
|
+ quesBody = defaultQuestionUnit.getBody();
|
|
|
+ defaultQuestionUnit.setBody(buildBody(quesBody, null));
|
|
|
+ if (defaultQuestionUnit.getQuestionType() == QuestionType.SINGLE_CHOICE || defaultQuestionUnit.getQuestionType() == QuestionType.MULTIPLE_CHOICE) {
|
|
|
+ List<DefaultQuestionOption> questionOptionList = defaultQuestionUnit.getQuestionOptionList();
|
|
|
+ if (questionOptionList != null && questionOptionList.size() > 0) {
|
|
|
+ for (int i = 0; i < questionOptionList.size(); i++) {
|
|
|
+ DefaultQuestionOption defaultQuestionOption = questionOptionList.get(i);
|
|
|
+ defaultQuestionOption.setBody(buildBody(defaultQuestionOption.getBody(), null));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 给题目和选项添加url
|
|
|
+ *
|
|
|
+ * @param body
|
|
|
+ * @param playTime
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String buildBody(String body, Integer playTime) {
|
|
|
+ String[] bodyStrings = body.split("></a>");
|
|
|
+ if (bodyStrings.length > 1) {
|
|
|
+ String resultBody = "";
|
|
|
+ for (int i = 0; i < bodyStrings.length; i++) {
|
|
|
+ String containAStr = bodyStrings[i];
|
|
|
+ if (containAStr.indexOf("<a") > -1) {
|
|
|
+ String questionAudioId = matchAudioName(containAStr, "a", "id");
|
|
|
+ QuestionAudio questionAudio = questionAudioService.findAudioById(questionAudioId);
|
|
|
+ if (questionAudio != null) {
|
|
|
+ String url = downloadUrl + questionAudio.getFileUrl();
|
|
|
+ if (playTime != null) {
|
|
|
+ containAStr += " question-audio url=\"" + url + "\" playTime=\"" + playTime + "\"" + "></a>";
|
|
|
+ } else {
|
|
|
+ containAStr += " question-audio url=\"" + url + "\"" + "></a>";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ resultBody += containAStr;
|
|
|
+ }
|
|
|
+ return resultBody;
|
|
|
+ } else {
|
|
|
+ return body;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取一段html中某个标签的值
|
|
|
+ *
|
|
|
+ * @param source
|
|
|
+ * @param element
|
|
|
+ * @param attr
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String matchAudioName(String source, String element, String attr) {
|
|
|
+ String reg = "<" + element + "[^<>]*?\\s" + attr + "=['\"]?(.*?)['\"]?(\\s.*?)";
|
|
|
+ Matcher m = Pattern.compile(reg).matcher(source);
|
|
|
+ while (m.find()) {
|
|
|
return m.group(1);
|
|
|
- }
|
|
|
- return "";
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查所有题目是否为客观题
|
|
|
+ *
|
|
|
+ * @param paperDetailUnits
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean checkIsAllQbjectiveQuestion(List<PaperDetailUnit> paperDetailUnits) {
|
|
|
+ for (PaperDetailUnit paperDetailUnit : paperDetailUnits) {
|
|
|
+ Question question = paperDetailUnit.getQuestion();
|
|
|
+ //填空或问答
|
|
|
+ if (question.getQuestionType() == QuesStructType.FILL_BLANK_QUESTION
|
|
|
+ || question.getQuestionType() == QuesStructType.TEXT_ANSWER_QUESTION) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (question.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
|
|
|
+ List<Question> subQuestions = question.getSubQuestions();
|
|
|
+ for (Question subQuestion : subQuestions) {
|
|
|
+ if (subQuestion.getQuestionType() == QuesStructType.FILL_BLANK_QUESTION
|
|
|
+ || subQuestion.getQuestionType() == QuesStructType.TEXT_ANSWER_QUESTION) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public DefaultPaper getBaseDefaultPaper(String paperId) {
|
|
|
+ Paper basePaper = Model.of(paperRepo.findById(paperId));
|
|
|
+ if (basePaper == null) {
|
|
|
+ log.error("该考试和课程下调卷规则中该类型试卷不存在,请检查调卷规则,调卷程序退出");
|
|
|
+ throw new StatusException("Q-020560", "该考试和课程下调卷规则中试卷不存在,请重新制定调卷规则");
|
|
|
+ }
|
|
|
+ //构建试卷结构
|
|
|
+ DefaultPaper defaultPaper = buildDefaultByBasePaper(basePaper, null, null, null);
|
|
|
+ return defaultPaper;
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * 检查所有题目是否为客观题
|
|
|
- * @param paperDetailUnits
|
|
|
- * @return
|
|
|
- */
|
|
|
- private boolean checkIsAllQbjectiveQuestion(List<PaperDetailUnit> paperDetailUnits) {
|
|
|
- for(PaperDetailUnit paperDetailUnit:paperDetailUnits){
|
|
|
- Question question = paperDetailUnit.getQuestion();
|
|
|
- //填空或问答
|
|
|
- if(question.getQuestionType()==QuesStructType.FILL_BLANK_QUESTION
|
|
|
- ||question.getQuestionType()==QuesStructType.TEXT_ANSWER_QUESTION){
|
|
|
- return false;
|
|
|
- }
|
|
|
- if(question.getQuestionType()==QuesStructType.NESTED_ANSWER_QUESTION){
|
|
|
- List<Question> subQuestions = question.getSubQuestions();
|
|
|
- for(Question subQuestion:subQuestions){
|
|
|
- if(subQuestion.getQuestionType()==QuesStructType.FILL_BLANK_QUESTION
|
|
|
- ||subQuestion.getQuestionType()==QuesStructType.TEXT_ANSWER_QUESTION){
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public DefaultPaper getBaseDefaultPaper(String paperId) {
|
|
|
- Paper basePaper = Model.of( paperRepo.findById(paperId));
|
|
|
- if(basePaper==null){
|
|
|
- log.error("该考试和课程下调卷规则中该类型试卷不存在,请检查调卷规则,调卷程序退出");
|
|
|
- throw new StatusException("Q-020560","该考试和课程下调卷规则中试卷不存在,请重新制定调卷规则");
|
|
|
- }
|
|
|
- //构建试卷结构
|
|
|
- DefaultPaper defaultPaper = buildDefaultByBasePaper(basePaper,null,null,null);
|
|
|
- return defaultPaper;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Map<String, DefaultQuestion> getDefaultQuestions(Set<String> questionIds) {
|
|
|
- Map<String, DefaultQuestion> map = new HashMap<String, DefaultQuestion>();
|
|
|
- List<Question> questions = quesRepo.findByIdIn(questionIds);
|
|
|
- if(CollectionUtils.isEmpty(questions)){
|
|
|
- log.error("根据试题id的集合没有查询到试题结合");
|
|
|
- throw new StatusException("Q-020572","根据试题id的集合没有查询到试题结合");
|
|
|
- }
|
|
|
- for(Question question:questions){
|
|
|
- DefaultQuestion defaultQuestion = getDefaultQuestion(null, null, null, question.getId());
|
|
|
- map.put(question.getId(), defaultQuestion);
|
|
|
- }
|
|
|
- return map;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<String> getAnswer(String questionId) {
|
|
|
- List<String> list = new ArrayList<String>();
|
|
|
- Question question = Model.of( quesRepo.findById(questionId));
|
|
|
- if(question.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION){
|
|
|
- List<Question> subList = question.getSubQuestions();
|
|
|
- if(subList!=null && subList.size()>0){
|
|
|
- String answer = "";
|
|
|
- for(Question subQuestion:subList){
|
|
|
- if(subQuestion.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION || subQuestion.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION){
|
|
|
- String[] answers = getSelectQuestionAnswer(subQuestion.getQuesOptions());
|
|
|
- for(int i =0;i<answers.length;i++){
|
|
|
- if(i==0){
|
|
|
- answer = answers[i];
|
|
|
- }
|
|
|
- answer = answer + "," + answers[i];
|
|
|
- }
|
|
|
- }else if(subQuestion.getQuestionType() == QuesStructType.BOOL_ANSWER_QUESTION){
|
|
|
- if(subQuestion.getQuesAnswer().endsWith("正确")){
|
|
|
- answer = "true";
|
|
|
- }else {
|
|
|
- answer = "false";
|
|
|
- }
|
|
|
- }else {
|
|
|
- answer = subQuestion.getQuesAnswer();
|
|
|
- }
|
|
|
- list.add(answer);
|
|
|
- }
|
|
|
- }
|
|
|
- }else {
|
|
|
- String answer = "";
|
|
|
- if(question.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION || question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION){
|
|
|
- String[] answers = getSelectQuestionAnswer(question.getQuesOptions());
|
|
|
- for(int i =0;i<answers.length;i++){
|
|
|
- if(i==0){
|
|
|
- answer = answers[i];
|
|
|
- }
|
|
|
- answer = answer + "," + answers[i];
|
|
|
- }
|
|
|
- }else if(question.getQuestionType() == QuesStructType.BOOL_ANSWER_QUESTION){
|
|
|
- if(question.getQuesAnswer().endsWith("正确")){
|
|
|
- answer = "true";
|
|
|
- }else {
|
|
|
- answer = "false";
|
|
|
- }
|
|
|
- }else {
|
|
|
- answer = question.getQuesAnswer();
|
|
|
- }
|
|
|
- list.add(answer);
|
|
|
- }
|
|
|
- return list;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public String getQuestionStructure(String paperId) throws Exception {
|
|
|
- String json = paperService.findQuestionStructure(paperId);
|
|
|
- return json;
|
|
|
- }
|
|
|
-
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, DefaultQuestion> getDefaultQuestions(Set<String> questionIds) {
|
|
|
+ Map<String, DefaultQuestion> map = new HashMap<String, DefaultQuestion>();
|
|
|
+ List<Question> questions = quesRepo.findByIdIn(questionIds);
|
|
|
+ if (CollectionUtils.isEmpty(questions)) {
|
|
|
+ log.error("根据试题id的集合没有查询到试题结合");
|
|
|
+ throw new StatusException("Q-020572", "根据试题id的集合没有查询到试题结合");
|
|
|
+ }
|
|
|
+ for (Question question : questions) {
|
|
|
+ DefaultQuestion defaultQuestion = getDefaultQuestion(null, null, null, question.getId());
|
|
|
+ map.put(question.getId(), defaultQuestion);
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<String> getAnswer(String questionId) {
|
|
|
+ List<String> list = new ArrayList<String>();
|
|
|
+ Question question = Model.of(quesRepo.findById(questionId));
|
|
|
+ if (question.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
|
|
|
+ List<Question> subList = question.getSubQuestions();
|
|
|
+ if (subList != null && subList.size() > 0) {
|
|
|
+ String answer = "";
|
|
|
+ for (Question subQuestion : subList) {
|
|
|
+ if (subQuestion.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION || subQuestion.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION) {
|
|
|
+ String[] answers = getSelectQuestionAnswer(subQuestion.getQuesOptions());
|
|
|
+ for (int i = 0; i < answers.length; i++) {
|
|
|
+ if (i == 0) {
|
|
|
+ answer = answers[i];
|
|
|
+ }
|
|
|
+ answer = answer + "," + answers[i];
|
|
|
+ }
|
|
|
+ } else if (subQuestion.getQuestionType() == QuesStructType.BOOL_ANSWER_QUESTION) {
|
|
|
+ if (subQuestion.getQuesAnswer().endsWith("正确")) {
|
|
|
+ answer = "true";
|
|
|
+ } else {
|
|
|
+ answer = "false";
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ answer = subQuestion.getQuesAnswer();
|
|
|
+ }
|
|
|
+ list.add(answer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ String answer = "";
|
|
|
+ if (question.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION || question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION) {
|
|
|
+ String[] answers = getSelectQuestionAnswer(question.getQuesOptions());
|
|
|
+ for (int i = 0; i < answers.length; i++) {
|
|
|
+ if (i == 0) {
|
|
|
+ answer = answers[i];
|
|
|
+ }
|
|
|
+ answer = answer + "," + answers[i];
|
|
|
+ }
|
|
|
+ } else if (question.getQuestionType() == QuesStructType.BOOL_ANSWER_QUESTION) {
|
|
|
+ if (question.getQuesAnswer().endsWith("正确")) {
|
|
|
+ answer = "true";
|
|
|
+ } else {
|
|
|
+ answer = "false";
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ answer = question.getQuesAnswer();
|
|
|
+ }
|
|
|
+ list.add(answer);
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getQuestionStructure(String paperId) throws Exception {
|
|
|
+ String json = paperService.findQuestionStructure(paperId);
|
|
|
+ return json;
|
|
|
+ }
|
|
|
+
|
|
|
}
|