فهرست منبع

Merge remote-tracking branch 'origin/dev' into dev

wangliang 4 سال پیش
والد
کامیت
dabf8f8b4a

+ 31 - 12
themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamPaperController.java

@@ -1,10 +1,30 @@
 package com.qmth.themis.backend.api;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import javax.annotation.Resource;
+
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.qmth.themis.backend.util.ServletUtil;
 import com.qmth.themis.business.config.SystemConfig;
 import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.entity.*;
+import com.qmth.themis.business.entity.TBAttachment;
+import com.qmth.themis.business.entity.TBTaskHistory;
+import com.qmth.themis.business.entity.TBUser;
+import com.qmth.themis.business.entity.TEExam;
+import com.qmth.themis.business.entity.TEExamPaper;
 import com.qmth.themis.business.enums.FieldUniqueEnum;
 import com.qmth.themis.business.enums.MqEnum;
 import com.qmth.themis.business.enums.TaskStatusEnum;
@@ -23,17 +43,12 @@ import com.qmth.themis.mq.dto.MqDto;
 import com.qmth.themis.mq.enums.MqTagEnum;
 import com.qmth.themis.mq.enums.MqTopicEnum;
 import com.qmth.themis.mq.service.MqDtoService;
-import io.swagger.annotations.*;
-import org.springframework.dao.DuplicateKeyException;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
 
-import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
 
 /**
  * @Description: 考试试卷 前端控制器
@@ -125,7 +140,9 @@ public class TEExamPaperController {
             , @ApiParam(value = "批次ID", required = true) @RequestParam Long examId
             , @ApiParam(value = "客观题乱序", required = false) @RequestParam Boolean objectiveShuffle
             , @ApiParam(value = "选项乱序", required = false) @RequestParam Boolean optionShuffle
-            , @ApiParam(value = "音频播放次数", required = false) @RequestParam Integer audioPlayCount) {
+            , @ApiParam(value = "音频播放次数", required = false) @RequestParam Integer audioPlayCount
+            ,@ApiParam(value = "解析试卷", required = true) @RequestParam Boolean processPaper
+            ,@ApiParam(value = "解析标答", required = true) @RequestParam Boolean processAnswer) {
         if (file == null) {
             throw new BusinessException(ExceptionResultEnum.ATTACHMENT_IS_NULL);
         }
@@ -158,6 +175,8 @@ public class TEExamPaperController {
             transMap.put("objectiveShuffle", objectiveShuffle);
             transMap.put("optionShuffle", optionShuffle);
             transMap.put("audioPlayCount", audioPlayCount);
+            transMap.put("processPaper", processPaper);
+            transMap.put("processAnswer", processAnswer);
             //mq发送消息start
             MqDto mqDto = new MqDto(MqTopicEnum.taskTopic.getCode(), MqTagEnum.examPaperImport.name(), transMap, MqEnum.TASK_LOG, String.valueOf(tbTaskHistory.getId()), tbUser.getName());
             mqDtoService.assembleSendOneWayMsg(mqDto);

+ 50 - 0
themis-business/src/main/java/com/qmth/themis/business/cache/bean/ObjectiveAnswerCacheBean.java

@@ -0,0 +1,50 @@
+package com.qmth.themis.business.cache.bean;
+
+import java.io.Serializable;
+
+/**
+ * 客观题标答缓存
+ * 
+ * @Description:
+ * @Author: xiatian
+ * @Date: 2020-07-29
+ */
+public class ObjectiveAnswerCacheBean implements Serializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 429158666416475187L;
+	// 分数
+	private Double score;
+	// 题型
+	private Integer structType;
+
+	// 标答
+	private String rightAnswer;
+
+	public Double getScore() {
+		return score;
+	}
+
+	public void setScore(Double score) {
+		this.score = score;
+	}
+
+	public Integer getStructType() {
+		return structType;
+	}
+
+	public void setStructType(Integer structType) {
+		this.structType = structType;
+	}
+
+	public String getRightAnswer() {
+		return rightAnswer;
+	}
+
+	public void setRightAnswer(String rightAnswer) {
+		this.rightAnswer = rightAnswer;
+	}
+
+}

+ 5 - 0
themis-business/src/main/java/com/qmth/themis/business/service/TEExamPaperService.java

@@ -1,7 +1,10 @@
 package com.qmth.themis.business.service;
 
+import java.util.Map;
+
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.themis.business.cache.bean.ExamPaperCacheBean;
+import com.qmth.themis.business.cache.bean.ObjectiveAnswerCacheBean;
 import com.qmth.themis.business.entity.TEExamPaper;
 
 /**
@@ -17,4 +20,6 @@ public interface TEExamPaperService extends IService<TEExamPaper> {
 
 	ExamPaperCacheBean getExamPaperCacheBean(Long paperId);
 
+	Map<String, ObjectiveAnswerCacheBean> getObjectiveAnswerCacheBean(Long paperId);
+
 }

+ 44 - 1
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamPaperServiceImpl.java

@@ -1,5 +1,10 @@
 package com.qmth.themis.business.service.impl;
 
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
 import javax.annotation.Resource;
 
 import org.apache.commons.lang3.StringUtils;
@@ -8,10 +13,14 @@ import org.springframework.stereotype.Service;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.themis.business.cache.bean.ExamPaperCacheBean;
+import com.qmth.themis.business.cache.bean.ObjectiveAnswerCacheBean;
+import com.qmth.themis.business.config.SystemConfig;
 import com.qmth.themis.business.dao.TEExamPaperMapper;
 import com.qmth.themis.business.entity.TEExamPaper;
 import com.qmth.themis.business.service.TEExamPaperService;
+import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.common.exception.BusinessException;
+import com.qmth.themis.common.util.FileUtil;
 
 /**
  * @Description: 考试试卷 服务实现类
@@ -22,7 +31,8 @@ import com.qmth.themis.common.exception.BusinessException;
  */
 @Service
 public class TEExamPaperServiceImpl extends ServiceImpl<TEExamPaperMapper, TEExamPaper> implements TEExamPaperService {
-
+    @Resource
+    SystemConfig systemConfig;
 	@Resource
 	TEExamPaperMapper teExamPaperMapper;
 
@@ -67,4 +77,37 @@ public class TEExamPaperServiceImpl extends ServiceImpl<TEExamPaperMapper, TEExa
 		ret.setAudioPlayCount(ep.getAudioPlayCount());
 		return ret;
 	}
+	
+	@Cacheable(value = "objective_answer", key = "#paperId", unless = "#result == null")
+	@Override
+	public Map<String,ObjectiveAnswerCacheBean> getObjectiveAnswerCacheBean(Long paperId) {
+		Map<String,ObjectiveAnswerCacheBean> ret = null;
+		ExamPaperCacheBean ep = getExamPaperCacheBean(paperId);
+		if (ep == null) {
+			return ret;
+		}
+		ret = new HashMap<String,ObjectiveAnswerCacheBean>();
+		String structUrl=OssUtil.getUrlForPrivateBucket(systemConfig.getOssEnv(3), ep.getStructPath());
+		String answerUrl=OssUtil.getUrlForPrivateBucket(systemConfig.getOssEnv(3), ep.getAnswerPath());
+		String tempDir = systemConfig.getProperty("sys.config.tempDataDir");
+        String dir = tempDir + "/" + uuid() + "/";
+        File dfile = new File(dir);
+        try {
+            dfile.mkdirs();
+            File structFile=new File(dir+"struct.json");
+            FileUtil.saveUrlAsFile(structUrl, structFile);
+            File answerEncryptFile=new File(dir+"answer_encrypt_file.json");
+            FileUtil.saveUrlAsFile(answerUrl, answerEncryptFile);
+            File answerFile=new File(dir+"answer_file.json");
+            FileUtil.decryptFile(answerEncryptFile, answerFile, ep.getDecryptSecret(), ep.getDecryptVector());
+            String structJson=FileUtil.readFileContent(structFile);
+            String answerjson=FileUtil.readFileContent(answerFile);
+        } finally {
+            FileUtil.deleteFolder(dir);
+        }
+		return ret;
+	}
+    private String uuid() {
+        return UUID.randomUUID().toString().replaceAll("-", "");
+    }
 }

+ 2 - 0
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -352,6 +352,8 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
 		// 更新考生作答
 		redisUtil.set(RedisKeyHelper.examAnswerKey(recordId),
 				RedisKeyHelper.examAnswerHashKey(mainNumber, subNumber, subIndex), answerCache);
+		//计算客观分
+//		calculateObjectiveScore();
 		return version;
 	}
 

+ 62 - 15
themis-business/src/main/java/com/qmth/themis/business/templete/impl/TaskExamPaperImportTemplete.java

@@ -1,6 +1,22 @@
 package com.qmth.themis.business.templete.impl;
 
-import cn.hutool.core.date.DateUtil;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.qmth.themis.business.config.SystemConfig;
@@ -22,15 +38,8 @@ import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.FileUtil;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
-import javax.annotation.Resource;
-import java.io.File;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.*;
+import cn.hutool.core.date.DateUtil;
 
 /**
  * @Description: 试卷导入
@@ -91,7 +100,7 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         try {
             dfile.mkdirs();
             FileUtil.unZip(dfile, file);
-            if (!hasErr(dir, examId, dfile, result)) {
+            if (!hasErr(map,dir, examId, dfile, result)) {
                 for (File courseDir : dfile.listFiles()) {
                     if (courseDir.isDirectory()) {
                         disposeCourseDir(dir, teExam, courseDir, map);
@@ -170,9 +179,15 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
             paper.setCourseCode(course.getCourseCode());
             paper.setDecryptVector(RandomStringUtils.randomAlphanumeric(16));
         }
-        disposePaper(rootDir, paper, paperFile, attachmentDir);
-        disposeStruct(rootDir, paper, paperFile);
-        disposeAnswer(rootDir, paper, answerFile);
+        Boolean processPaper = (Boolean) map.get("processPaper");
+        Boolean processAnswer = (Boolean) map.get("processAnswer");
+        if(processPaper) {
+	        disposePaper(rootDir, paper, paperFile, attachmentDir);
+	        disposeStruct(rootDir, paper, paperFile);
+        }
+        if(processAnswer) {
+        	disposeAnswer(rootDir, paper, answerFile);
+        }
 
         teExamPaperService.saveOrUpdate(paper);
     }
@@ -207,11 +222,13 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
             for (int j = 0; j < questions.size(); j++) {
                 JSONObject question = questions.getJSONObject(j);
                 question.remove("body");
+                question.remove("options");
                 if (question.getInteger("structType").intValue() == 6) {
                     JSONArray subQuestions = question.getJSONArray("subQuestions");
                     for (int k = 0; k < subQuestions.size(); k++) {
                         JSONObject subquestion = subQuestions.getJSONObject(k);
                         subquestion.remove("body");
+                        subquestion.remove("options");
                     }
                 }
             }
@@ -241,7 +258,9 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         result.append(msg).append("\r\n");
     }
 
-    private boolean hasErr(String rootDir, Long examId, File dfile, StringBuilder result) {
+    private boolean hasErr(Map<String, Object> map,String rootDir, Long examId, File dfile, StringBuilder result) {
+    	Boolean processPaper = (Boolean) map.get("processPaper");
+        Boolean processAnswer = (Boolean) map.get("processAnswer");
         boolean hasErr = false;
         for (File courseDir : dfile.listFiles()) {// 校验每一个科目
             if (courseDir.isDirectory()) {
@@ -267,6 +286,34 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
                             hasErr = true;
                             continue;
                         }
+                        if(processPaper) {
+                        	String[] ps=paperDir.list(new FilenameFilter() {
+								
+								@Override
+								public boolean accept(File dir, String name) {
+									return name.equals("paper.json");
+								}
+							});
+                        	if(ps==null||ps.length==0) {
+                        		addResult(result, "科目 " + courseCode + " 试卷 " + paperCode + " 没有试卷文件");
+                                hasErr = true;
+                                continue;
+                        	}
+                        }
+                        if(processAnswer) {
+                        	String[] ps=paperDir.list(new FilenameFilter() {
+								
+								@Override
+								public boolean accept(File dir, String name) {
+									return name.equals("answer.json");
+								}
+							});
+                        	if(ps==null||ps.length==0) {
+                        		addResult(result, "科目 " + courseCode + " 试卷 " + paperCode + " 没有答案文件");
+                                hasErr = true;
+                                continue;
+                        	}
+                        }
                         try {
                             // 校验答案
                             checkAnswerFile(rootDir, paperDirChilds, examId, courseCode, paperCode);
@@ -281,7 +328,7 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         }
         return hasErr;
     }
-
+    
     private void checkAnswerFile(String rootDir, File[] paperDirChilds, Long examId, String courseCode,
                                  String paperCode) {
         File paperFile = null;