|
@@ -1,33 +1,8 @@
|
|
package com.qmth.themis.business.templete.impl;
|
|
package com.qmth.themis.business.templete.impl;
|
|
|
|
|
|
-import java.io.File;
|
|
|
|
-import java.io.FilenameFilter;
|
|
|
|
-import java.io.IOException;
|
|
|
|
-import java.math.BigDecimal;
|
|
|
|
-import java.text.SimpleDateFormat;
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
-import java.util.Collections;
|
|
|
|
-import java.util.Date;
|
|
|
|
-import java.util.HashMap;
|
|
|
|
-import java.util.List;
|
|
|
|
-import java.util.Map;
|
|
|
|
-import java.util.Objects;
|
|
|
|
-import java.util.UUID;
|
|
|
|
-
|
|
|
|
-import javax.annotation.Resource;
|
|
|
|
-
|
|
|
|
-import org.apache.commons.io.FileUtils;
|
|
|
|
-import org.apache.commons.lang3.RandomStringUtils;
|
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
|
-import org.slf4j.Logger;
|
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
|
-import org.springframework.transaction.annotation.Transactional;
|
|
|
|
-
|
|
|
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
import com.alibaba.fastjson.JSONArray;
|
|
import com.alibaba.fastjson.JSONArray;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
-import com.qmth.themis.business.config.SystemConfig;
|
|
|
|
-import com.qmth.themis.business.constant.SpringContextHolder;
|
|
|
|
import com.qmth.themis.business.constant.SystemConstant;
|
|
import com.qmth.themis.business.constant.SystemConstant;
|
|
import com.qmth.themis.business.entity.TEExam;
|
|
import com.qmth.themis.business.entity.TEExam;
|
|
import com.qmth.themis.business.entity.TEExamCourse;
|
|
import com.qmth.themis.business.entity.TEExamCourse;
|
|
@@ -50,10 +25,23 @@ import com.qmth.themis.common.exception.BusinessException;
|
|
import com.qmth.themis.common.util.FileUtil;
|
|
import com.qmth.themis.common.util.FileUtil;
|
|
import com.qmth.themis.common.util.Result;
|
|
import com.qmth.themis.common.util.Result;
|
|
import com.qmth.themis.common.util.ResultUtil;
|
|
import com.qmth.themis.common.util.ResultUtil;
|
|
-
|
|
|
|
-import cn.hutool.core.date.DateUtil;
|
|
|
|
|
|
+import org.apache.commons.io.FileUtils;
|
|
|
|
+import org.apache.commons.lang3.RandomStringUtils;
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
import sun.misc.BASE64Decoder;
|
|
import sun.misc.BASE64Decoder;
|
|
|
|
|
|
|
|
+import javax.annotation.Resource;
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.io.FilenameFilter;
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
|
+import java.util.*;
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* @Description: 试卷导入
|
|
* @Description: 试卷导入
|
|
* @Author: xiatian
|
|
* @Author: xiatian
|
|
@@ -61,704 +49,696 @@ import sun.misc.BASE64Decoder;
|
|
*/
|
|
*/
|
|
@Service("taskExamPaperImportTemplete")
|
|
@Service("taskExamPaperImportTemplete")
|
|
public class TaskExamPaperImportTemplete implements TaskImportTemplete {
|
|
public class TaskExamPaperImportTemplete implements TaskImportTemplete {
|
|
- private final static Logger log = LoggerFactory.getLogger(TaskExamPaperImportTemplete.class);
|
|
|
|
- private SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
|
|
|
|
- @Resource
|
|
|
|
- TEExamService teExamService;
|
|
|
|
- @Resource
|
|
|
|
- SystemConfig systemConfig;
|
|
|
|
- @Resource
|
|
|
|
- TEExamCourseService teExamCourseService;
|
|
|
|
- @Resource
|
|
|
|
- TEExamPaperService teExamPaperService;
|
|
|
|
-
|
|
|
|
- @Resource
|
|
|
|
- TOeExamRecordService examRecordService;
|
|
|
|
-
|
|
|
|
|
|
+ private final static Logger log = LoggerFactory.getLogger(TaskExamPaperImportTemplete.class);
|
|
|
|
+ private SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
|
|
|
|
+ @Resource
|
|
|
|
+ TEExamService teExamService;
|
|
|
|
+ @Resource
|
|
|
|
+ OssUtil ossUtil;
|
|
|
|
+ @Resource
|
|
|
|
+ TEExamCourseService teExamCourseService;
|
|
|
|
+ @Resource
|
|
|
|
+ TEExamPaperService teExamPaperService;
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ TOeExamRecordService examRecordService;
|
|
|
|
+
|
|
|
|
|
|
@Resource
|
|
@Resource
|
|
RedisUtil redisUtil;
|
|
RedisUtil redisUtil;
|
|
|
|
|
|
- @Override
|
|
|
|
- @Transactional
|
|
|
|
- public Result importTask(Map<String, Object> map) throws IOException {
|
|
|
|
- long start = System.currentTimeMillis();
|
|
|
|
- TaskImportCommon taskImportCommon = new TaskImportCommon(map);
|
|
|
|
- taskImportCommon.init();
|
|
|
|
- StringBuilder result = new StringBuilder();
|
|
|
|
- String timeFormat = taskImportCommon.getTimeFormat();
|
|
|
|
- addResult(result, DateUtil.format(new Date(), timeFormat) + "处理开始");
|
|
|
|
- File file = null;
|
|
|
|
- try {
|
|
|
|
- file = taskImportCommon.getUploadFile();
|
|
|
|
- dispose(file, map, result);
|
|
|
|
- taskImportCommon.getTbTaskHistory().setSummary("处理成功");
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- taskImportCommon.setException(true);
|
|
|
|
- log.error("处理出错 ", e);
|
|
|
|
- addResult(result, "处理出错 " + e.getMessage());
|
|
|
|
- taskImportCommon.getTbTaskHistory().setSummary("处理出错");
|
|
|
|
- } finally {
|
|
|
|
- if (file != null) {
|
|
|
|
- file.delete();
|
|
|
|
- }
|
|
|
|
- addResult(result, DateUtil.format(new Date(), timeFormat) + "处理结束");
|
|
|
|
- long end = System.currentTimeMillis();
|
|
|
|
- addResult(result, "耗时(秒):" + ((end - start) / 1000));
|
|
|
|
- taskImportCommon.getTbTaskHistory().setFinishTime(System.currentTimeMillis());
|
|
|
|
- taskImportCommon.getTbTaskHistory().setStatus(TaskStatusEnum.FINISH);
|
|
|
|
- taskImportCommon.getTbTaskHistory().setProgress(100.0d);
|
|
|
|
- taskImportCommon.writeImportResultTxt(result.toString(), file);
|
|
|
|
- }
|
|
|
|
- return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void dispose(File file, Map<String, Object> map, StringBuilder result) throws IOException {
|
|
|
|
-
|
|
|
|
- Long examId = (Long) map.get("examId");
|
|
|
|
-
|
|
|
|
- TEExam teExam = teExamService.getById(examId);
|
|
|
|
- if (Objects.isNull(teExam)) {
|
|
|
|
- throw new BusinessException(ExceptionResultEnum.EXAM_NO);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- String tempDir = SystemConstant.TEMP_FILES_DIR;
|
|
|
|
- String dir = tempDir + "/" + uuid() + "/";
|
|
|
|
- File dfile = new File(dir);
|
|
|
|
-
|
|
|
|
- String lockKey = SystemConstant.REDIS_LOCK_PAPER_IMPORT_PREFIX + examId;
|
|
|
|
-
|
|
|
|
- String multLockKey = SystemConstant.REDIS_LOCK_CALCULATE_SCORE_PAPER_IMPORT_PREFIX + examId;
|
|
|
|
- try {
|
|
|
|
- int timeOutSecond = 60 * 60;
|
|
|
|
- //试卷导入锁
|
|
|
|
- Boolean lock = redisUtil.lock(lockKey, timeOutSecond);
|
|
|
|
- if (!lock) {
|
|
|
|
- throw new BusinessException("该考试批次有正在进行的试卷导入");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //重新算分和试卷导入互斥锁
|
|
|
|
- Boolean multLock = redisUtil.lock(multLockKey, timeOutSecond);
|
|
|
|
- if (!multLock) {
|
|
|
|
- throw new BusinessException("该考试批次有正在进行的重新算分");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- dfile.mkdirs();
|
|
|
|
- FileUtil.unZip(dfile, file);
|
|
|
|
- if (!hasErr(map, dir, examId, dfile, result)) {
|
|
|
|
- for (File courseDir : dfile.listFiles()) {
|
|
|
|
- if (courseDir.isDirectory()) {
|
|
|
|
- disposeCourseDir(dir, teExam, courseDir, map);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- throw new BusinessException("校验失败");
|
|
|
|
- }
|
|
|
|
- TOeExamRecord er=examRecordService.findOneByExamId(examId, null);
|
|
|
|
- Boolean processAnswer = (Boolean) map.get("processAnswer");
|
|
|
|
- if(er!=null&&processAnswer) {
|
|
|
|
- teExamService.updateScoreStatus(ScoreStatusEnum.NEED_CALCULATE, examId);
|
|
|
|
- }
|
|
|
|
- } finally {
|
|
|
|
- redisUtil.releaseLock(lockKey);
|
|
|
|
- redisUtil.releaseLock(multLockKey);
|
|
|
|
- FileUtil.deleteFolder(dir);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void disposeCourseDir(String rootDir, TEExam teExam, File courseDir, Map<String, Object> map) {
|
|
|
|
- String courseCode = courseDir.getName();
|
|
|
|
- TEExamCourse course = teExamCourseService.findByExamIdAndCourseCode(teExam.getId(), courseCode);
|
|
|
|
- if (course == null) {
|
|
|
|
- throw new BusinessException("科目编码不存在 " + courseCode);
|
|
|
|
- }
|
|
|
|
- File[] childs = courseDir.listFiles();
|
|
|
|
- for (File paperDir : childs) {
|
|
|
|
- if (paperDir.isDirectory()) {
|
|
|
|
- disposePaperDir(rootDir, teExam, course, paperDir, map);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- Boolean objectiveShuffle = (Boolean) map.get("objectiveShuffle");
|
|
|
|
- Boolean optionShuffle = (Boolean) map.get("optionShuffle");
|
|
|
|
- Integer audioPlayCount = (Integer) map.get("audioPlayCount");
|
|
|
|
- if (objectiveShuffle != null) {
|
|
|
|
- course.setObjectiveShuffle(objectiveShuffle ? 1 : 0);
|
|
|
|
- }
|
|
|
|
- if (optionShuffle != null) {
|
|
|
|
- course.setOptionShuffle(optionShuffle ? 1 : 0);
|
|
|
|
- }
|
|
|
|
- if (audioPlayCount != null) {
|
|
|
|
- course.setAudioPlayCount(audioPlayCount);
|
|
|
|
- }
|
|
|
|
- List<TEExamPaper> list = teExamPaperService.findByExamIdAndCourseCode(teExam.getId(), courseCode);
|
|
|
|
- int hasAnswer = 1;
|
|
|
|
- for (TEExamPaper p : list) {
|
|
|
|
- if (StringUtils.isBlank(p.getAnswerPath())) {
|
|
|
|
- hasAnswer = 0;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- course.setPaperCount(list.size());
|
|
|
|
- course.setHasAnswer(hasAnswer);
|
|
|
|
- int hasAudio = 0;
|
|
|
|
- for (TEExamPaper p : list) {
|
|
|
|
- if (p.getHasAudio() != null && p.getHasAudio().intValue() == 1) {
|
|
|
|
- hasAudio = 1;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- course.setHasAudio(hasAudio);
|
|
|
|
- teExamCourseService.saveOrUpdate(course);
|
|
|
|
- // 设置调卷比例
|
|
|
|
- teExamPaperService.savePaperWeight(paperWeight(list));
|
|
|
|
-
|
|
|
|
- //清除考试科目缓存
|
|
|
|
- teExamCourseService.deleteExamCourseCacheBean(teExam.getId(), courseCode);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private Map<Long, Double> paperWeight(List<TEExamPaper> list) {
|
|
|
|
- BigDecimal b1 = new BigDecimal(100.0);// 基数总数
|
|
|
|
- BigDecimal b2 = new BigDecimal(list.size());// 份数
|
|
|
|
- BigDecimal b3 = b1.divide(b2, 0, BigDecimal.ROUND_FLOOR);// 平均数
|
|
|
|
- BigDecimal b4 = b1.subtract(b3.multiply(b2).setScale(0, BigDecimal.ROUND_FLOOR));// 余数
|
|
|
|
- Map<Long, Double> map = new HashMap<Long, Double>();
|
|
|
|
- for (int i = 0; i < list.size(); i++) {
|
|
|
|
- TEExamPaper p = list.get(i);
|
|
|
|
- if (i == list.size() - 1) {
|
|
|
|
- map.put(p.getId(), b3.add(b4).doubleValue());
|
|
|
|
- } else {
|
|
|
|
- map.put(p.getId(), b3.doubleValue());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return map;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void disposePaperDir(String rootDir, TEExam teExam, TEExamCourse course, File paperDir,
|
|
|
|
- Map<String, Object> map) {
|
|
|
|
- String paperCode = paperDir.getName();
|
|
|
|
- File[] childs = paperDir.listFiles();
|
|
|
|
-
|
|
|
|
- File paperFile = null;
|
|
|
|
- File answerFile = null;
|
|
|
|
- File attachmentDir = null;
|
|
|
|
- for (File cfile : childs) {
|
|
|
|
- if ("paper.json".equals(cfile.getName()) && cfile.isFile()) {
|
|
|
|
- paperFile = cfile;
|
|
|
|
- }
|
|
|
|
- if ("answer.json".equals(cfile.getName()) && cfile.isFile()) {
|
|
|
|
- answerFile = cfile;
|
|
|
|
- }
|
|
|
|
- if ("attachment".equals(cfile.getName()) && cfile.isDirectory()) {
|
|
|
|
- if (cfile.listFiles() != null && cfile.listFiles().length != 0) {
|
|
|
|
- attachmentDir = cfile;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- TEExamPaper paper = teExamPaperService.findByExamIdAndCourseCodeAndPaperCode(teExam.getId(),
|
|
|
|
- course.getCourseCode(), paperCode);
|
|
|
|
- if (paper == null) {
|
|
|
|
- paper = new TEExamPaper();
|
|
|
|
- String createId = map.get("createId").toString();
|
|
|
|
- JSONObject paperJson = JSONObject.parseObject(FileUtil.readFileContent(paperFile));
|
|
|
|
- paper.setId(Constants.idGen.next());
|
|
|
|
- paper.setName(paperJson.getString("name"));
|
|
|
|
- paper.setTotalScore(paperJson.getDouble("totalScore"));
|
|
|
|
- paper.setDecryptSecret(RandomStringUtils.randomAlphanumeric(16));
|
|
|
|
- paper.setEncryptMode(EncryptModeEnum.AUTO);
|
|
|
|
- paper.setExamId(teExam.getId());
|
|
|
|
- paper.setCode(paperCode);
|
|
|
|
- paper.setHasAudio(paperJson.getInteger("hasAudio"));
|
|
|
|
- paper.setCreateId(Long.parseLong(createId));
|
|
|
|
- paper.setCourseCode(course.getCourseCode());
|
|
|
|
- paper.setDecryptVector(RandomStringUtils.randomAlphanumeric(16));
|
|
|
|
- }
|
|
|
|
- Boolean processPaper = (Boolean) map.get("processPaper");
|
|
|
|
- Boolean processAnswer = (Boolean) map.get("processAnswer");
|
|
|
|
- if (processPaper) {
|
|
|
|
- disposePaper(rootDir, paper, paperFile, attachmentDir);
|
|
|
|
- disposeStruct(rootDir, paper, paperFile);
|
|
|
|
- disposeViewPaper(rootDir, paper, paperFile, attachmentDir);
|
|
|
|
- }
|
|
|
|
- if (processAnswer) {
|
|
|
|
- File structFile;
|
|
|
|
- if(processPaper) {
|
|
|
|
- structFile=paperFile;
|
|
|
|
- }else {
|
|
|
|
- String structPath = paper.getStructPath();
|
|
|
|
- SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
|
|
|
|
- String url = OssUtil.getUrlForPrivateBucket(systemConfig.getOssEnv(3), structPath);
|
|
|
|
- structFile = new File(rootDir + uuid() + ".json");
|
|
|
|
- FileUtil.saveUrlAsFile(url, structFile);
|
|
|
|
- }
|
|
|
|
- disposeAnswer(rootDir, paper, answerFile,structFile,attachmentDir);
|
|
|
|
- }
|
|
|
|
- Integer audioPlayCount = (Integer) map.get("audioPlayCount");
|
|
|
|
- paper.setAudioPlayCount(audioPlayCount);
|
|
|
|
- teExamPaperService.saveOrUpdate(paper);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void disposeViewPaper(String rootDir, TEExamPaper paper, File paperFile, File attachmentDir) {
|
|
|
|
- File urlPaperFile = new File(rootDir + uuid() + ".json");
|
|
|
|
- JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(paperFile));
|
|
|
|
- JSONArray structdetails = structJson.getJSONArray("details");
|
|
|
|
- if(structdetails==null||structdetails.size()==0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- for (int i = 0; i < structdetails.size(); i++) {
|
|
|
|
- JSONArray structdetailquestions = structdetails.getJSONObject(i).getJSONArray("questions");
|
|
|
|
- if(structdetailquestions!=null&&structdetailquestions.size()>=0) {
|
|
|
|
- for (int j = 0; j < structdetailquestions.size(); j++) {
|
|
|
|
- JSONObject structquestion = structdetailquestions.getJSONObject(j);
|
|
|
|
- JSONObject body = structquestion.getJSONObject("body");
|
|
|
|
- disposeQuestionBodyUrl(rootDir, body, paper.getId(), attachmentDir);
|
|
|
|
- JSONArray options = structquestion.getJSONArray("options");
|
|
|
|
- disposeQuestionOptionsUrl(rootDir, options, paper.getId(), attachmentDir);
|
|
|
|
- if (structquestion.getInteger("structType").intValue() == 6) {
|
|
|
|
- JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
|
|
|
|
- for (int k = 0; k < structsubQuestions.size(); k++) {
|
|
|
|
- JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
|
|
|
|
- JSONObject subbody = structsubquestion.getJSONObject("body");
|
|
|
|
- disposeQuestionBodyUrl(rootDir, subbody, paper.getId(), attachmentDir);
|
|
|
|
- JSONArray suboptions = structsubquestion.getJSONArray("options");
|
|
|
|
- disposeQuestionOptionsUrl(rootDir, suboptions, paper.getId(), attachmentDir);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- FileUtil.saveAsFile(urlPaperFile.getAbsolutePath(), structJson.toJSONString());
|
|
|
|
- String filePath = sdf.format(new Date()) + "/" + uuid() + ".json";
|
|
|
|
- paper.setPaperViewPath(filePath);
|
|
|
|
- SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
|
|
|
|
- OssUtil.ossUpload(systemConfig.getOssEnv(3), filePath, urlPaperFile);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void disposeQuestionBodyUrl(String rootDir,JSONObject body,Long paperId,File attachmentDir) {
|
|
|
|
- if(body==null) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- JSONArray sections = body.getJSONArray("sections");
|
|
|
|
- if(sections==null||sections.size()==0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- for(int j=0;j<sections.size();j++) {
|
|
|
|
- JSONObject block = sections.getJSONObject(j);
|
|
|
|
- if(block!=null) {
|
|
|
|
- JSONArray blocks = block.getJSONArray("blocks");
|
|
|
|
- if(blocks!=null&&blocks.size()>0) {
|
|
|
|
- for(int m=0;m<blocks.size();m++) {
|
|
|
|
- JSONObject blockInfo = blocks.getJSONObject(m);
|
|
|
|
- uploadImageAndAudio(rootDir,blockInfo, paperId, attachmentDir);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void disposeQuestionOptionsUrl(String rootDir,JSONArray options,Long paperId,File attachmentDir) {
|
|
|
|
- if(options==null||options.size()==0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- for(int i=0;i<options.size();i++) {
|
|
|
|
- JSONObject option = options.getJSONObject(i);
|
|
|
|
- if(option!=null) {
|
|
|
|
- JSONObject body = option.getJSONObject("body");
|
|
|
|
- if(body!=null) {
|
|
|
|
- JSONArray sections = body.getJSONArray("sections");
|
|
|
|
- if(sections!=null&§ions.size()>0) {
|
|
|
|
- for(int j=0;j<sections.size();j++) {
|
|
|
|
- JSONObject block = sections.getJSONObject(j);
|
|
|
|
- if(block!=null) {
|
|
|
|
- JSONArray blocks = block.getJSONArray("blocks");
|
|
|
|
- if(blocks!=null&&blocks.size()>0) {
|
|
|
|
- for(int m=0;m<blocks.size();m++) {
|
|
|
|
- JSONObject blockInfo = blocks.getJSONObject(m);
|
|
|
|
- uploadImageAndAudio(rootDir,blockInfo, paperId, attachmentDir);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void disposePaper(String rootDir, TEExamPaper paper, File paperFile, File attachmentDir) {
|
|
|
|
- if (paperFile == null) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- File zip = new File(rootDir + uuid() + ".zip");
|
|
|
|
- List<File> files = new ArrayList<File>();
|
|
|
|
- files.add(paperFile);
|
|
|
|
- if (attachmentDir != null) {
|
|
|
|
- files.add(attachmentDir);
|
|
|
|
- }
|
|
|
|
- FileUtil.doZip(zip, files);
|
|
|
|
- File encryptZip = new File(rootDir + uuid() + ".zip");
|
|
|
|
- FileUtil.encryptFile(zip, encryptZip, paper.getDecryptSecret(), paper.getDecryptVector());
|
|
|
|
- String filePath = sdf.format(new Date()) + "/" + uuid() + ".zip";
|
|
|
|
- paper.setPaperPath(filePath);
|
|
|
|
- SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
|
|
|
|
- OssUtil.ossUpload(systemConfig.getOssEnv(3), filePath, encryptZip);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void disposeStruct(String rootDir, TEExamPaper paper, File paperFile) {
|
|
|
|
- BigDecimal obTotal = new BigDecimal(0);
|
|
|
|
- BigDecimal subTotal = new BigDecimal(0);
|
|
|
|
- if (paperFile == null) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- JSONObject paperJson = JSONObject.parseObject(FileUtil.readFileContent(paperFile));
|
|
|
|
- JSONArray details = paperJson.getJSONArray("details");
|
|
|
|
- for (int i = 0; i < details.size(); i++) {
|
|
|
|
- JSONArray questions = details.getJSONObject(i).getJSONArray("questions");
|
|
|
|
- for (int j = 0; j < questions.size(); j++) {
|
|
|
|
- JSONObject question = questions.getJSONObject(j);
|
|
|
|
- question.remove("body");
|
|
|
|
- question.remove("options");
|
|
|
|
- Double score = question.getDouble("score");
|
|
|
|
- if(score==null) {
|
|
|
|
- score=0.0;
|
|
|
|
- }
|
|
|
|
- Integer structType = question.getInteger("structType");
|
|
|
|
- if (structType.intValue() != 1
|
|
|
|
- && structType.intValue() != 2
|
|
|
|
- && structType.intValue() != 3&&structType.intValue() != 6) {//主观题
|
|
|
|
- subTotal=subTotal.add(new BigDecimal(score));
|
|
|
|
- }else {//客观题
|
|
|
|
- obTotal=obTotal.add(new BigDecimal(score));
|
|
|
|
- }
|
|
|
|
- if (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");
|
|
|
|
- Double subScore = subquestion.getDouble("score");
|
|
|
|
- if(subScore==null) {
|
|
|
|
- subScore=0.0;
|
|
|
|
- }
|
|
|
|
- Integer subStructType = subquestion.getInteger("structType");
|
|
|
|
- if (subStructType.intValue() != 1
|
|
|
|
- && subStructType.intValue() != 2
|
|
|
|
- && subStructType.intValue() != 3) {//主观题
|
|
|
|
- subTotal=subTotal.add(new BigDecimal(subScore));
|
|
|
|
- }else {//客观题
|
|
|
|
- obTotal=obTotal.add(new BigDecimal(subScore));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- File file = new File(rootDir + uuid() + ".json");
|
|
|
|
- FileUtil.saveAsFile(file.getAbsolutePath(), paperJson.toJSONString());
|
|
|
|
- String filePath = sdf.format(new Date()) + "/" + uuid() + ".json";
|
|
|
|
- paper.setStructPath(filePath);
|
|
|
|
- paper.setTotalObjectiveScore(obTotal.doubleValue());
|
|
|
|
- paper.setTotalSubjectiveScore(subTotal.doubleValue());
|
|
|
|
- SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
|
|
|
|
- OssUtil.ossUpload(systemConfig.getOssEnv(3), filePath, file);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void disposeAnswer(String rootDir, TEExamPaper paper, File answerFile,File structFile,File attachmentDir) {
|
|
|
|
- if (answerFile == null) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- File urlAnswerFile = new File(rootDir + uuid() + ".json");
|
|
|
|
- JSONObject answerJson = JSONObject.parseObject(FileUtil.readFileContent(answerFile));
|
|
|
|
- JSONArray answerdetails = answerJson.getJSONArray("details");
|
|
|
|
- JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(structFile));
|
|
|
|
- JSONArray structdetails = structJson.getJSONArray("details");
|
|
|
|
- for (int i = 0; i < answerdetails.size(); i++) {
|
|
|
|
- JSONArray answerdetailquestions = answerdetails.getJSONObject(i).getJSONArray("questions");
|
|
|
|
- JSONArray structdetailquestions = structdetails.getJSONObject(i).getJSONArray("questions");
|
|
|
|
- for (int j = 0; j < answerdetailquestions.size(); j++) {
|
|
|
|
- JSONObject answerquestion = answerdetailquestions.getJSONObject(j);
|
|
|
|
- JSONObject structquestion = structdetailquestions.getJSONObject(j);
|
|
|
|
- if (structquestion.getInteger("structType").intValue() != 1
|
|
|
|
- && structquestion.getInteger("structType").intValue() != 2
|
|
|
|
- && structquestion.getInteger("structType").intValue() != 3
|
|
|
|
- && structquestion.getInteger("structType").intValue() != 6) {
|
|
|
|
- JSONArray answer = answerquestion.getJSONArray("answer");
|
|
|
|
- disposeAnswerUrl(rootDir,answer, paper.getId(), attachmentDir);
|
|
|
|
- }
|
|
|
|
- if (structquestion.getInteger("structType").intValue() == 6) {
|
|
|
|
- JSONArray answersubQuestions = answerquestion.getJSONArray("subQuestions");
|
|
|
|
- JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
|
|
|
|
- for (int k = 0; k < answersubQuestions.size(); k++) {
|
|
|
|
- JSONObject answersubquestion = answersubQuestions.getJSONObject(k);
|
|
|
|
- JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
|
|
|
|
- if (structsubquestion.getInteger("structType").intValue() != 1
|
|
|
|
- && structsubquestion.getInteger("structType").intValue() != 2
|
|
|
|
- && structsubquestion.getInteger("structType").intValue() != 3) {
|
|
|
|
- JSONArray answer = answersubquestion.getJSONArray("answer");
|
|
|
|
- disposeAnswerUrl(rootDir,answer, paper.getId(), attachmentDir);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- FileUtil.saveAsFile(urlAnswerFile.getAbsolutePath(), answerJson.toJSONString());
|
|
|
|
- String filePath = sdf.format(new Date()) + "/" + uuid() + ".json";
|
|
|
|
- paper.setAnswerPath(filePath);
|
|
|
|
- SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
|
|
|
|
- OssUtil.ossUpload(systemConfig.getOssEnv(3), filePath, urlAnswerFile);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void disposeAnswerUrl(String rootDir,JSONArray answer,Long paperId,File attachmentDir) {
|
|
|
|
- if(answer!=null&&answer.size()>0) {
|
|
|
|
- for(int i=0;i<answer.size();i++) {
|
|
|
|
- JSONObject section = answer.getJSONObject(i);
|
|
|
|
- if(section!=null) {
|
|
|
|
- JSONArray sections = section.getJSONArray("sections");
|
|
|
|
- if(sections!=null&§ions.size()>0) {
|
|
|
|
- for(int j=0;j<sections.size();j++) {
|
|
|
|
- JSONObject block = sections.getJSONObject(j);
|
|
|
|
- if(block!=null) {
|
|
|
|
- JSONArray blocks = block.getJSONArray("blocks");
|
|
|
|
- if(blocks!=null&&blocks.size()>0) {
|
|
|
|
- for(int m=0;m<blocks.size();m++) {
|
|
|
|
- JSONObject blockInfo = blocks.getJSONObject(m);
|
|
|
|
- uploadImageAndAudio(rootDir,blockInfo, paperId, attachmentDir);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void uploadImageAndAudio(String rootDir,JSONObject blockInfo,Long paperId,File attachmentDir) {
|
|
|
|
- String type=blockInfo.getString("type");
|
|
|
|
- String value=blockInfo.getString("value");
|
|
|
|
- if(("image".equals(type)||"audio".equals(type))
|
|
|
|
- &&StringUtils.isNotBlank(value)
|
|
|
|
- &&!value.toLowerCase().startsWith("https://")
|
|
|
|
- &&!value.toLowerCase().startsWith("http://")) {
|
|
|
|
- if("image".equals(type)&&value.contains("data:image")) {
|
|
|
|
- String suff=value.substring(11, value.indexOf(";"));
|
|
|
|
- File iamgeFile = new File(rootDir+uuid()+"."+suff);
|
|
|
|
|
|
+ @Override
|
|
|
|
+ @Transactional
|
|
|
|
+ public Result importTask(Map<String, Object> map) throws IOException {
|
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
|
+ TaskImportCommon taskImportCommon = new TaskImportCommon(map);
|
|
|
|
+ taskImportCommon.init();
|
|
|
|
+ StringBuilder result = new StringBuilder();
|
|
|
|
+ String timeFormat = taskImportCommon.getTimeFormat();
|
|
|
|
+ addResult(result, DateUtil.format(new Date(), timeFormat) + "处理开始");
|
|
|
|
+ File file = null;
|
|
|
|
+ try {
|
|
|
|
+ file = taskImportCommon.getUploadFile();
|
|
|
|
+ dispose(file, map, result);
|
|
|
|
+ taskImportCommon.getTbTaskHistory().setSummary("处理成功");
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ taskImportCommon.setException(true);
|
|
|
|
+ log.error("处理出错 ", e);
|
|
|
|
+ addResult(result, "处理出错 " + e.getMessage());
|
|
|
|
+ taskImportCommon.getTbTaskHistory().setSummary("处理出错");
|
|
|
|
+ } finally {
|
|
|
|
+ if (file != null) {
|
|
|
|
+ file.delete();
|
|
|
|
+ }
|
|
|
|
+ addResult(result, DateUtil.format(new Date(), timeFormat) + "处理结束");
|
|
|
|
+ long end = System.currentTimeMillis();
|
|
|
|
+ addResult(result, "耗时(秒):" + ((end - start) / 1000));
|
|
|
|
+ taskImportCommon.getTbTaskHistory().setFinishTime(System.currentTimeMillis());
|
|
|
|
+ taskImportCommon.getTbTaskHistory().setStatus(TaskStatusEnum.FINISH);
|
|
|
|
+ taskImportCommon.getTbTaskHistory().setProgress(100.0d);
|
|
|
|
+ taskImportCommon.writeImportResultTxt(result.toString(), file);
|
|
|
|
+ }
|
|
|
|
+ return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void dispose(File file, Map<String, Object> map, StringBuilder result) throws IOException {
|
|
|
|
+
|
|
|
|
+ Long examId = (Long) map.get("examId");
|
|
|
|
+
|
|
|
|
+ TEExam teExam = teExamService.getById(examId);
|
|
|
|
+ if (Objects.isNull(teExam)) {
|
|
|
|
+ throw new BusinessException(ExceptionResultEnum.EXAM_NO);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String tempDir = SystemConstant.TEMP_FILES_DIR;
|
|
|
|
+ String dir = tempDir + "/" + uuid() + "/";
|
|
|
|
+ File dfile = new File(dir);
|
|
|
|
+
|
|
|
|
+ String lockKey = SystemConstant.REDIS_LOCK_PAPER_IMPORT_PREFIX + examId;
|
|
|
|
+
|
|
|
|
+ String multLockKey = SystemConstant.REDIS_LOCK_CALCULATE_SCORE_PAPER_IMPORT_PREFIX + examId;
|
|
|
|
+ try {
|
|
|
|
+ int timeOutSecond = 60 * 60;
|
|
|
|
+ //试卷导入锁
|
|
|
|
+ Boolean lock = redisUtil.lock(lockKey, timeOutSecond);
|
|
|
|
+ if (!lock) {
|
|
|
|
+ throw new BusinessException("该考试批次有正在进行的试卷导入");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //重新算分和试卷导入互斥锁
|
|
|
|
+ Boolean multLock = redisUtil.lock(multLockKey, timeOutSecond);
|
|
|
|
+ if (!multLock) {
|
|
|
|
+ throw new BusinessException("该考试批次有正在进行的重新算分");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dfile.mkdirs();
|
|
|
|
+ FileUtil.unZip(dfile, file);
|
|
|
|
+ if (!hasErr(map, dir, examId, dfile, result)) {
|
|
|
|
+ for (File courseDir : dfile.listFiles()) {
|
|
|
|
+ if (courseDir.isDirectory()) {
|
|
|
|
+ disposeCourseDir(dir, teExam, courseDir, map);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ throw new BusinessException("校验失败");
|
|
|
|
+ }
|
|
|
|
+ TOeExamRecord er = examRecordService.findOneByExamId(examId, null);
|
|
|
|
+ Boolean processAnswer = (Boolean) map.get("processAnswer");
|
|
|
|
+ if (er != null && processAnswer) {
|
|
|
|
+ teExamService.updateScoreStatus(ScoreStatusEnum.NEED_CALCULATE, examId);
|
|
|
|
+ }
|
|
|
|
+ } finally {
|
|
|
|
+ redisUtil.releaseLock(lockKey);
|
|
|
|
+ redisUtil.releaseLock(multLockKey);
|
|
|
|
+ FileUtil.deleteFolder(dir);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void disposeCourseDir(String rootDir, TEExam teExam, File courseDir, Map<String, Object> map) {
|
|
|
|
+ String courseCode = courseDir.getName();
|
|
|
|
+ TEExamCourse course = teExamCourseService.findByExamIdAndCourseCode(teExam.getId(), courseCode);
|
|
|
|
+ if (course == null) {
|
|
|
|
+ throw new BusinessException("科目编码不存在 " + courseCode);
|
|
|
|
+ }
|
|
|
|
+ File[] childs = courseDir.listFiles();
|
|
|
|
+ for (File paperDir : childs) {
|
|
|
|
+ if (paperDir.isDirectory()) {
|
|
|
|
+ disposePaperDir(rootDir, teExam, course, paperDir, map);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Boolean objectiveShuffle = (Boolean) map.get("objectiveShuffle");
|
|
|
|
+ Boolean optionShuffle = (Boolean) map.get("optionShuffle");
|
|
|
|
+ Integer audioPlayCount = (Integer) map.get("audioPlayCount");
|
|
|
|
+ if (objectiveShuffle != null) {
|
|
|
|
+ course.setObjectiveShuffle(objectiveShuffle ? 1 : 0);
|
|
|
|
+ }
|
|
|
|
+ if (optionShuffle != null) {
|
|
|
|
+ course.setOptionShuffle(optionShuffle ? 1 : 0);
|
|
|
|
+ }
|
|
|
|
+ if (audioPlayCount != null) {
|
|
|
|
+ course.setAudioPlayCount(audioPlayCount);
|
|
|
|
+ }
|
|
|
|
+ List<TEExamPaper> list = teExamPaperService.findByExamIdAndCourseCode(teExam.getId(), courseCode);
|
|
|
|
+ int hasAnswer = 1;
|
|
|
|
+ for (TEExamPaper p : list) {
|
|
|
|
+ if (StringUtils.isBlank(p.getAnswerPath())) {
|
|
|
|
+ hasAnswer = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ course.setPaperCount(list.size());
|
|
|
|
+ course.setHasAnswer(hasAnswer);
|
|
|
|
+ int hasAudio = 0;
|
|
|
|
+ for (TEExamPaper p : list) {
|
|
|
|
+ if (p.getHasAudio() != null && p.getHasAudio().intValue() == 1) {
|
|
|
|
+ hasAudio = 1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ course.setHasAudio(hasAudio);
|
|
|
|
+ teExamCourseService.saveOrUpdate(course);
|
|
|
|
+ // 设置调卷比例
|
|
|
|
+ teExamPaperService.savePaperWeight(paperWeight(list));
|
|
|
|
+
|
|
|
|
+ //清除考试科目缓存
|
|
|
|
+ teExamCourseService.deleteExamCourseCacheBean(teExam.getId(), courseCode);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Map<Long, Double> paperWeight(List<TEExamPaper> list) {
|
|
|
|
+ BigDecimal b1 = new BigDecimal(100.0);// 基数总数
|
|
|
|
+ BigDecimal b2 = new BigDecimal(list.size());// 份数
|
|
|
|
+ BigDecimal b3 = b1.divide(b2, 0, BigDecimal.ROUND_FLOOR);// 平均数
|
|
|
|
+ BigDecimal b4 = b1.subtract(b3.multiply(b2).setScale(0, BigDecimal.ROUND_FLOOR));// 余数
|
|
|
|
+ Map<Long, Double> map = new HashMap<Long, Double>();
|
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
|
+ TEExamPaper p = list.get(i);
|
|
|
|
+ if (i == list.size() - 1) {
|
|
|
|
+ map.put(p.getId(), b3.add(b4).doubleValue());
|
|
|
|
+ } else {
|
|
|
|
+ map.put(p.getId(), b3.doubleValue());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void disposePaperDir(String rootDir, TEExam teExam, TEExamCourse course, File paperDir,
|
|
|
|
+ Map<String, Object> map) {
|
|
|
|
+ String paperCode = paperDir.getName();
|
|
|
|
+ File[] childs = paperDir.listFiles();
|
|
|
|
+
|
|
|
|
+ File paperFile = null;
|
|
|
|
+ File answerFile = null;
|
|
|
|
+ File attachmentDir = null;
|
|
|
|
+ for (File cfile : childs) {
|
|
|
|
+ if ("paper.json".equals(cfile.getName()) && cfile.isFile()) {
|
|
|
|
+ paperFile = cfile;
|
|
|
|
+ }
|
|
|
|
+ if ("answer.json".equals(cfile.getName()) && cfile.isFile()) {
|
|
|
|
+ answerFile = cfile;
|
|
|
|
+ }
|
|
|
|
+ if ("attachment".equals(cfile.getName()) && cfile.isDirectory()) {
|
|
|
|
+ if (cfile.listFiles() != null && cfile.listFiles().length != 0) {
|
|
|
|
+ attachmentDir = cfile;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ TEExamPaper paper = teExamPaperService.findByExamIdAndCourseCodeAndPaperCode(teExam.getId(),
|
|
|
|
+ course.getCourseCode(), paperCode);
|
|
|
|
+ if (paper == null) {
|
|
|
|
+ paper = new TEExamPaper();
|
|
|
|
+ String createId = map.get("createId").toString();
|
|
|
|
+ JSONObject paperJson = JSONObject.parseObject(FileUtil.readFileContent(paperFile));
|
|
|
|
+ paper.setId(Constants.idGen.next());
|
|
|
|
+ paper.setName(paperJson.getString("name"));
|
|
|
|
+ paper.setTotalScore(paperJson.getDouble("totalScore"));
|
|
|
|
+ paper.setDecryptSecret(RandomStringUtils.randomAlphanumeric(16));
|
|
|
|
+ paper.setEncryptMode(EncryptModeEnum.AUTO);
|
|
|
|
+ paper.setExamId(teExam.getId());
|
|
|
|
+ paper.setCode(paperCode);
|
|
|
|
+ paper.setHasAudio(paperJson.getInteger("hasAudio"));
|
|
|
|
+ paper.setCreateId(Long.parseLong(createId));
|
|
|
|
+ paper.setCourseCode(course.getCourseCode());
|
|
|
|
+ paper.setDecryptVector(RandomStringUtils.randomAlphanumeric(16));
|
|
|
|
+ }
|
|
|
|
+ Boolean processPaper = (Boolean) map.get("processPaper");
|
|
|
|
+ Boolean processAnswer = (Boolean) map.get("processAnswer");
|
|
|
|
+ if (processPaper) {
|
|
|
|
+ disposePaper(rootDir, paper, paperFile, attachmentDir);
|
|
|
|
+ disposeStruct(rootDir, paper, paperFile);
|
|
|
|
+ disposeViewPaper(rootDir, paper, paperFile, attachmentDir);
|
|
|
|
+ }
|
|
|
|
+ if (processAnswer) {
|
|
|
|
+ File structFile;
|
|
|
|
+ if (processPaper) {
|
|
|
|
+ structFile = paperFile;
|
|
|
|
+ } else {
|
|
|
|
+ String structPath = paper.getStructPath();
|
|
|
|
+ String url = OssUtil.getUrlForPrivateBucket(ossUtil.getAliYunOssPrivateDomain().getMap(), structPath);
|
|
|
|
+ structFile = new File(rootDir + uuid() + ".json");
|
|
|
|
+ FileUtil.saveUrlAsFile(url, structFile);
|
|
|
|
+ }
|
|
|
|
+ disposeAnswer(rootDir, paper, answerFile, structFile, attachmentDir);
|
|
|
|
+ }
|
|
|
|
+ Integer audioPlayCount = (Integer) map.get("audioPlayCount");
|
|
|
|
+ paper.setAudioPlayCount(audioPlayCount);
|
|
|
|
+ teExamPaperService.saveOrUpdate(paper);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void disposeViewPaper(String rootDir, TEExamPaper paper, File paperFile, File attachmentDir) {
|
|
|
|
+ File urlPaperFile = new File(rootDir + uuid() + ".json");
|
|
|
|
+ JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(paperFile));
|
|
|
|
+ JSONArray structdetails = structJson.getJSONArray("details");
|
|
|
|
+ if (structdetails == null || structdetails.size() == 0) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ for (int i = 0; i < structdetails.size(); i++) {
|
|
|
|
+ JSONArray structdetailquestions = structdetails.getJSONObject(i).getJSONArray("questions");
|
|
|
|
+ if (structdetailquestions != null && structdetailquestions.size() >= 0) {
|
|
|
|
+ for (int j = 0; j < structdetailquestions.size(); j++) {
|
|
|
|
+ JSONObject structquestion = structdetailquestions.getJSONObject(j);
|
|
|
|
+ JSONObject body = structquestion.getJSONObject("body");
|
|
|
|
+ disposeQuestionBodyUrl(rootDir, body, paper.getId(), attachmentDir);
|
|
|
|
+ JSONArray options = structquestion.getJSONArray("options");
|
|
|
|
+ disposeQuestionOptionsUrl(rootDir, options, paper.getId(), attachmentDir);
|
|
|
|
+ if (structquestion.getInteger("structType").intValue() == 6) {
|
|
|
|
+ JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
|
|
|
|
+ for (int k = 0; k < structsubQuestions.size(); k++) {
|
|
|
|
+ JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
|
|
|
|
+ JSONObject subbody = structsubquestion.getJSONObject("body");
|
|
|
|
+ disposeQuestionBodyUrl(rootDir, subbody, paper.getId(), attachmentDir);
|
|
|
|
+ JSONArray suboptions = structsubquestion.getJSONArray("options");
|
|
|
|
+ disposeQuestionOptionsUrl(rootDir, suboptions, paper.getId(), attachmentDir);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ FileUtil.saveAsFile(urlPaperFile.getAbsolutePath(), structJson.toJSONString());
|
|
|
|
+ String filePath = sdf.format(new Date()) + "/" + uuid() + ".json";
|
|
|
|
+ paper.setPaperViewPath(filePath);
|
|
|
|
+ OssUtil.ossUpload(ossUtil.getAliYunOssPrivateDomain().getMap(), filePath, urlPaperFile);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void disposeQuestionBodyUrl(String rootDir, JSONObject body, Long paperId, File attachmentDir) {
|
|
|
|
+ if (body == null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ JSONArray sections = body.getJSONArray("sections");
|
|
|
|
+ if (sections == null || sections.size() == 0) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ for (int j = 0; j < sections.size(); j++) {
|
|
|
|
+ JSONObject block = sections.getJSONObject(j);
|
|
|
|
+ if (block != null) {
|
|
|
|
+ JSONArray blocks = block.getJSONArray("blocks");
|
|
|
|
+ if (blocks != null && blocks.size() > 0) {
|
|
|
|
+ for (int m = 0; m < blocks.size(); m++) {
|
|
|
|
+ JSONObject blockInfo = blocks.getJSONObject(m);
|
|
|
|
+ uploadImageAndAudio(rootDir, blockInfo, paperId, attachmentDir);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void disposeQuestionOptionsUrl(String rootDir, JSONArray options, Long paperId, File attachmentDir) {
|
|
|
|
+ if (options == null || options.size() == 0) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ for (int i = 0; i < options.size(); i++) {
|
|
|
|
+ JSONObject option = options.getJSONObject(i);
|
|
|
|
+ if (option != null) {
|
|
|
|
+ JSONObject body = option.getJSONObject("body");
|
|
|
|
+ if (body != null) {
|
|
|
|
+ JSONArray sections = body.getJSONArray("sections");
|
|
|
|
+ if (sections != null && sections.size() > 0) {
|
|
|
|
+ for (int j = 0; j < sections.size(); j++) {
|
|
|
|
+ JSONObject block = sections.getJSONObject(j);
|
|
|
|
+ if (block != null) {
|
|
|
|
+ JSONArray blocks = block.getJSONArray("blocks");
|
|
|
|
+ if (blocks != null && blocks.size() > 0) {
|
|
|
|
+ for (int m = 0; m < blocks.size(); m++) {
|
|
|
|
+ JSONObject blockInfo = blocks.getJSONObject(m);
|
|
|
|
+ uploadImageAndAudio(rootDir, blockInfo, paperId, attachmentDir);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void disposePaper(String rootDir, TEExamPaper paper, File paperFile, File attachmentDir) {
|
|
|
|
+ if (paperFile == null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ File zip = new File(rootDir + uuid() + ".zip");
|
|
|
|
+ List<File> files = new ArrayList<File>();
|
|
|
|
+ files.add(paperFile);
|
|
|
|
+ if (attachmentDir != null) {
|
|
|
|
+ files.add(attachmentDir);
|
|
|
|
+ }
|
|
|
|
+ FileUtil.doZip(zip, files);
|
|
|
|
+ File encryptZip = new File(rootDir + uuid() + ".zip");
|
|
|
|
+ FileUtil.encryptFile(zip, encryptZip, paper.getDecryptSecret(), paper.getDecryptVector());
|
|
|
|
+ String filePath = sdf.format(new Date()) + "/" + uuid() + ".zip";
|
|
|
|
+ paper.setPaperPath(filePath);
|
|
|
|
+ OssUtil.ossUpload(ossUtil.getAliYunOssPrivateDomain().getMap(), filePath, encryptZip);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void disposeStruct(String rootDir, TEExamPaper paper, File paperFile) {
|
|
|
|
+ BigDecimal obTotal = new BigDecimal(0);
|
|
|
|
+ BigDecimal subTotal = new BigDecimal(0);
|
|
|
|
+ if (paperFile == null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ JSONObject paperJson = JSONObject.parseObject(FileUtil.readFileContent(paperFile));
|
|
|
|
+ JSONArray details = paperJson.getJSONArray("details");
|
|
|
|
+ for (int i = 0; i < details.size(); i++) {
|
|
|
|
+ JSONArray questions = details.getJSONObject(i).getJSONArray("questions");
|
|
|
|
+ for (int j = 0; j < questions.size(); j++) {
|
|
|
|
+ JSONObject question = questions.getJSONObject(j);
|
|
|
|
+ question.remove("body");
|
|
|
|
+ question.remove("options");
|
|
|
|
+ Double score = question.getDouble("score");
|
|
|
|
+ if (score == null) {
|
|
|
|
+ score = 0.0;
|
|
|
|
+ }
|
|
|
|
+ Integer structType = question.getInteger("structType");
|
|
|
|
+ if (structType.intValue() != 1
|
|
|
|
+ && structType.intValue() != 2
|
|
|
|
+ && structType.intValue() != 3 && structType.intValue() != 6) {//主观题
|
|
|
|
+ subTotal = subTotal.add(new BigDecimal(score));
|
|
|
|
+ } else {//客观题
|
|
|
|
+ obTotal = obTotal.add(new BigDecimal(score));
|
|
|
|
+ }
|
|
|
|
+ if (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");
|
|
|
|
+ Double subScore = subquestion.getDouble("score");
|
|
|
|
+ if (subScore == null) {
|
|
|
|
+ subScore = 0.0;
|
|
|
|
+ }
|
|
|
|
+ Integer subStructType = subquestion.getInteger("structType");
|
|
|
|
+ if (subStructType.intValue() != 1
|
|
|
|
+ && subStructType.intValue() != 2
|
|
|
|
+ && subStructType.intValue() != 3) {//主观题
|
|
|
|
+ subTotal = subTotal.add(new BigDecimal(subScore));
|
|
|
|
+ } else {//客观题
|
|
|
|
+ obTotal = obTotal.add(new BigDecimal(subScore));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ File file = new File(rootDir + uuid() + ".json");
|
|
|
|
+ FileUtil.saveAsFile(file.getAbsolutePath(), paperJson.toJSONString());
|
|
|
|
+ String filePath = sdf.format(new Date()) + "/" + uuid() + ".json";
|
|
|
|
+ paper.setStructPath(filePath);
|
|
|
|
+ paper.setTotalObjectiveScore(obTotal.doubleValue());
|
|
|
|
+ paper.setTotalSubjectiveScore(subTotal.doubleValue());
|
|
|
|
+ OssUtil.ossUpload(ossUtil.getAliYunOssPrivateDomain().getMap(), filePath, file);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void disposeAnswer(String rootDir, TEExamPaper paper, File answerFile, File structFile, File attachmentDir) {
|
|
|
|
+ if (answerFile == null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ File urlAnswerFile = new File(rootDir + uuid() + ".json");
|
|
|
|
+ JSONObject answerJson = JSONObject.parseObject(FileUtil.readFileContent(answerFile));
|
|
|
|
+ JSONArray answerdetails = answerJson.getJSONArray("details");
|
|
|
|
+ JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(structFile));
|
|
|
|
+ JSONArray structdetails = structJson.getJSONArray("details");
|
|
|
|
+ for (int i = 0; i < answerdetails.size(); i++) {
|
|
|
|
+ JSONArray answerdetailquestions = answerdetails.getJSONObject(i).getJSONArray("questions");
|
|
|
|
+ JSONArray structdetailquestions = structdetails.getJSONObject(i).getJSONArray("questions");
|
|
|
|
+ for (int j = 0; j < answerdetailquestions.size(); j++) {
|
|
|
|
+ JSONObject answerquestion = answerdetailquestions.getJSONObject(j);
|
|
|
|
+ JSONObject structquestion = structdetailquestions.getJSONObject(j);
|
|
|
|
+ if (structquestion.getInteger("structType").intValue() != 1
|
|
|
|
+ && structquestion.getInteger("structType").intValue() != 2
|
|
|
|
+ && structquestion.getInteger("structType").intValue() != 3
|
|
|
|
+ && structquestion.getInteger("structType").intValue() != 6) {
|
|
|
|
+ JSONArray answer = answerquestion.getJSONArray("answer");
|
|
|
|
+ disposeAnswerUrl(rootDir, answer, paper.getId(), attachmentDir);
|
|
|
|
+ }
|
|
|
|
+ if (structquestion.getInteger("structType").intValue() == 6) {
|
|
|
|
+ JSONArray answersubQuestions = answerquestion.getJSONArray("subQuestions");
|
|
|
|
+ JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
|
|
|
|
+ for (int k = 0; k < answersubQuestions.size(); k++) {
|
|
|
|
+ JSONObject answersubquestion = answersubQuestions.getJSONObject(k);
|
|
|
|
+ JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
|
|
|
|
+ if (structsubquestion.getInteger("structType").intValue() != 1
|
|
|
|
+ && structsubquestion.getInteger("structType").intValue() != 2
|
|
|
|
+ && structsubquestion.getInteger("structType").intValue() != 3) {
|
|
|
|
+ JSONArray answer = answersubquestion.getJSONArray("answer");
|
|
|
|
+ disposeAnswerUrl(rootDir, answer, paper.getId(), attachmentDir);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ FileUtil.saveAsFile(urlAnswerFile.getAbsolutePath(), answerJson.toJSONString());
|
|
|
|
+ String filePath = sdf.format(new Date()) + "/" + uuid() + ".json";
|
|
|
|
+ paper.setAnswerPath(filePath);
|
|
|
|
+ OssUtil.ossUpload(ossUtil.getAliYunOssPrivateDomain().getMap(), filePath, urlAnswerFile);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void disposeAnswerUrl(String rootDir, JSONArray answer, Long paperId, File attachmentDir) {
|
|
|
|
+ if (answer != null && answer.size() > 0) {
|
|
|
|
+ for (int i = 0; i < answer.size(); i++) {
|
|
|
|
+ JSONObject section = answer.getJSONObject(i);
|
|
|
|
+ if (section != null) {
|
|
|
|
+ JSONArray sections = section.getJSONArray("sections");
|
|
|
|
+ if (sections != null && sections.size() > 0) {
|
|
|
|
+ for (int j = 0; j < sections.size(); j++) {
|
|
|
|
+ JSONObject block = sections.getJSONObject(j);
|
|
|
|
+ if (block != null) {
|
|
|
|
+ JSONArray blocks = block.getJSONArray("blocks");
|
|
|
|
+ if (blocks != null && blocks.size() > 0) {
|
|
|
|
+ for (int m = 0; m < blocks.size(); m++) {
|
|
|
|
+ JSONObject blockInfo = blocks.getJSONObject(m);
|
|
|
|
+ uploadImageAndAudio(rootDir, blockInfo, paperId, attachmentDir);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void uploadImageAndAudio(String rootDir, JSONObject blockInfo, Long paperId, File attachmentDir) {
|
|
|
|
+ String type = blockInfo.getString("type");
|
|
|
|
+ String value = blockInfo.getString("value");
|
|
|
|
+ if (("image".equals(type) || "audio".equals(type))
|
|
|
|
+ && StringUtils.isNotBlank(value)
|
|
|
|
+ && !value.toLowerCase().startsWith("https://")
|
|
|
|
+ && !value.toLowerCase().startsWith("http://")) {
|
|
|
|
+ if ("image".equals(type) && value.contains("data:image")) {
|
|
|
|
+ String suff = value.substring(11, value.indexOf(";"));
|
|
|
|
+ File iamgeFile = new File(rootDir + uuid() + "." + suff);
|
|
BASE64Decoder decoder = new BASE64Decoder();
|
|
BASE64Decoder decoder = new BASE64Decoder();
|
|
try {
|
|
try {
|
|
- byte[] bytes = decoder.decodeBuffer(value.substring(value.indexOf(",") + 1));
|
|
|
|
- FileUtils.writeByteArrayToFile(iamgeFile, bytes);
|
|
|
|
- } catch (IOException e) {
|
|
|
|
- throw new BusinessException("媒体文件上传处理出错:"+blockInfo.toJSONString()+" errmsg:"+e.getMessage() );
|
|
|
|
- }
|
|
|
|
- String filePath = "upload/paper_file/"+paperId+"/" + uuid() +"."+ suff;
|
|
|
|
- SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
|
|
|
|
- OssUtil.ossUpload(systemConfig.getOssEnv(3), filePath, iamgeFile);
|
|
|
|
- blockInfo.put("value", systemConfig.getProperty("aliyun.oss.privateUrl") + "/" +filePath);
|
|
|
|
- }else{
|
|
|
|
- String suff=value.substring(value.indexOf("."));
|
|
|
|
- String filePath = "upload/paper_file/"+paperId+"/" + uuid() + suff;
|
|
|
|
- File audioFile=new File(attachmentDir.getAbsolutePath()+"/"+value);
|
|
|
|
- SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
|
|
|
|
- OssUtil.ossUpload(systemConfig.getOssEnv(3), filePath, audioFile);
|
|
|
|
- blockInfo.put("value", systemConfig.getProperty("aliyun.oss.privateUrl") + "/" +filePath);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void addResult(StringBuilder result, String msg) {
|
|
|
|
- result.append(msg).append("\r\n");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- 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()) {
|
|
|
|
- String courseCode = courseDir.getName();
|
|
|
|
- TEExamCourse course = teExamCourseService.findByExamIdAndCourseCode(examId, courseCode);
|
|
|
|
- if (course == null) {
|
|
|
|
- addResult(result, "科目编码不存在 " + courseCode);
|
|
|
|
- hasErr = true;
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- File[] childs = courseDir.listFiles();
|
|
|
|
- if (childs == null || childs.length == 0) {
|
|
|
|
- addResult(result, "科目 " + courseCode + " 没有需要导入的文件");
|
|
|
|
- hasErr = true;
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- for (File paperDir : childs) {// 校验每一套试卷
|
|
|
|
- if (paperDir.isDirectory()) {
|
|
|
|
- String paperCode = paperDir.getName();
|
|
|
|
- File[] paperDirChilds = paperDir.listFiles();
|
|
|
|
- if (paperDirChilds == null || paperDirChilds.length == 0) {
|
|
|
|
- addResult(result, "科目 " + courseCode + " 试卷 " + paperCode + " 没有需要导入的文件");
|
|
|
|
- hasErr = true;
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- if (processPaper) {
|
|
|
|
- if(checkPaperHasExamRecord(examId, courseCode, paperCode)) {
|
|
|
|
- addResult(result, "科目 " + courseCode + " 试卷 " + paperCode + " 已有考试记录,不能再上传试卷");
|
|
|
|
- hasErr = true;
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- 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);
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- addResult(result, e.getMessage());
|
|
|
|
- hasErr = true;
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return hasErr;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private boolean checkPaperHasExamRecord(Long examId, String courseCode, String paperCode) {
|
|
|
|
- TEExamPaper paper=teExamPaperService.findByExamIdAndCourseCodeAndPaperCode(examId, courseCode, paperCode);
|
|
|
|
- if(paper==null) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- TOeExamRecord rd=examRecordService.findOneByPaperId(paper.getId());
|
|
|
|
- if(rd!=null) {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void checkAnswerFile(String rootDir, File[] paperDirChilds, Long examId, String courseCode,
|
|
|
|
- String paperCode) {
|
|
|
|
- File paperFile = null;
|
|
|
|
- File answerFile = null;
|
|
|
|
- for (File cfile : paperDirChilds) {// 校验试卷下的答案
|
|
|
|
- if ("paper.json".equals(cfile.getName()) && cfile.isFile()) {
|
|
|
|
- paperFile = cfile;
|
|
|
|
- }
|
|
|
|
- if ("answer.json".equals(cfile.getName()) && cfile.isFile()) {
|
|
|
|
- answerFile = cfile;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (answerFile != null) {
|
|
|
|
- if (paperFile == null) {// 没有试卷信息,不能先导入答案
|
|
|
|
- TEExamPaper paper = teExamPaperService.findByExamIdAndCourseCodeAndPaperCode(examId, courseCode,
|
|
|
|
- paperCode);
|
|
|
|
- if (paper == null) {
|
|
|
|
- throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 没有试卷信息,不能先导入答案");
|
|
|
|
- }
|
|
|
|
- String structPath = paper.getStructPath();
|
|
|
|
- SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
|
|
|
|
- String url = OssUtil.getUrlForPrivateBucket(systemConfig.getOssEnv(3), structPath);
|
|
|
|
- String name = structPath.substring(structPath.lastIndexOf("/") + 1);
|
|
|
|
- File structFile = new File(rootDir + name);
|
|
|
|
- try {
|
|
|
|
- FileUtil.saveUrlAsFile(url, structFile);
|
|
|
|
- compareAnswerAndPaper(courseCode, paperCode, answerFile, structFile);
|
|
|
|
- } finally {
|
|
|
|
- if (structFile.exists()) {
|
|
|
|
- structFile.delete();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- compareAnswerAndPaper(courseCode, paperCode, answerFile, paperFile);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void compareAnswerAndPaper(String courseCode, String paperCode, File answerFile, File structFile) {
|
|
|
|
- JSONObject answerJson = JSONObject.parseObject(FileUtil.readFileContent(answerFile));
|
|
|
|
- JSONArray answerdetails = answerJson.getJSONArray("details");
|
|
|
|
- JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(structFile));
|
|
|
|
- JSONArray structdetails = structJson.getJSONArray("details");
|
|
|
|
- if (answerdetails.size() != structdetails.size()) {
|
|
|
|
- throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷大题数量不一致");
|
|
|
|
- }
|
|
|
|
- for (int i = 0; i < answerdetails.size(); i++) {
|
|
|
|
- JSONArray answerdetailquestions = answerdetails.getJSONObject(i).getJSONArray("questions");
|
|
|
|
- JSONArray structdetailquestions = structdetails.getJSONObject(i).getJSONArray("questions");
|
|
|
|
- if (answerdetailquestions.size() != structdetailquestions.size()) {
|
|
|
|
- throw new BusinessException(
|
|
|
|
- "科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷第" + (i + 1) + "大题的小题数量不一致");
|
|
|
|
- }
|
|
|
|
- for (int j = 0; j < answerdetailquestions.size(); j++) {
|
|
|
|
- JSONObject answerquestion = answerdetailquestions.getJSONObject(j);
|
|
|
|
- JSONObject structquestion = structdetailquestions.getJSONObject(j);
|
|
|
|
- if (structquestion.getInteger("structType").intValue() == 1
|
|
|
|
- || structquestion.getInteger("structType").intValue() == 2) {
|
|
|
|
- JSONArray answer = answerquestion.getJSONArray("answer");
|
|
|
|
- if (answer == null || answer.size() == 0) {
|
|
|
|
- throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷第" + (i + 1)
|
|
|
|
- + "大题第" + (j + 1) + "小题没有答案");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (structquestion.getInteger("structType").intValue() == 3) {
|
|
|
|
- Boolean answer = answerquestion.getBoolean("answer");
|
|
|
|
- if (answer == null) {
|
|
|
|
- throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷第" + (i + 1)
|
|
|
|
- + "大题第" + (j + 1) + "小题没有答案");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (structquestion.getInteger("structType").intValue() == 6) {
|
|
|
|
- JSONArray answersubQuestions = answerquestion.getJSONArray("subQuestions");
|
|
|
|
- JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
|
|
|
|
- if (answersubQuestions.size() != structsubQuestions.size()) {
|
|
|
|
- throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷第" + (i + 1)
|
|
|
|
- + "大题第" + (j + 1) + "小题子题数量不一致");
|
|
|
|
- }
|
|
|
|
- for (int k = 0; k < answersubQuestions.size(); k++) {
|
|
|
|
- JSONObject answersubquestion = answersubQuestions.getJSONObject(k);
|
|
|
|
- JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
|
|
|
|
- if (structsubquestion.getInteger("structType").intValue() == 1
|
|
|
|
- || structsubquestion.getInteger("structType").intValue() == 2) {
|
|
|
|
- JSONArray answer = answersubquestion.getJSONArray("answer");
|
|
|
|
- if (answer == null || answer.size() == 0) {
|
|
|
|
- throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷第"
|
|
|
|
- + (i + 1) + "大题第" + (j + 1) + "小题第" + (k + 1) + "子题没有答案");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (structsubquestion.getInteger("structType").intValue() == 3) {
|
|
|
|
- Boolean answer = answersubquestion.getBoolean("answer");
|
|
|
|
- if (answer == null) {
|
|
|
|
- throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷第"
|
|
|
|
- + (i + 1) + "大题第" + (j + 1) + "小题第" + (k + 1) + "子题没有答案");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private String uuid() {
|
|
|
|
- return UUID.randomUUID().toString().replaceAll("-", "");
|
|
|
|
- }
|
|
|
|
|
|
+ byte[] bytes = decoder.decodeBuffer(value.substring(value.indexOf(",") + 1));
|
|
|
|
+ FileUtils.writeByteArrayToFile(iamgeFile, bytes);
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw new BusinessException("媒体文件上传处理出错:" + blockInfo.toJSONString() + " errmsg:" + e.getMessage());
|
|
|
|
+ }
|
|
|
|
+ String filePath = "upload/paper_file/" + paperId + "/" + uuid() + "." + suff;
|
|
|
|
+ OssUtil.ossUpload(ossUtil.getAliYunOssPrivateDomain().getMap(), filePath, iamgeFile);
|
|
|
|
+ blockInfo.put("value", ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + "/" + filePath);
|
|
|
|
+ } else {
|
|
|
|
+ String suff = value.substring(value.indexOf("."));
|
|
|
|
+ String filePath = "upload/paper_file/" + paperId + "/" + uuid() + suff;
|
|
|
|
+ File audioFile = new File(attachmentDir.getAbsolutePath() + "/" + value);
|
|
|
|
+ OssUtil.ossUpload(ossUtil.getAliYunOssPrivateDomain().getMap(), filePath, audioFile);
|
|
|
|
+ blockInfo.put("value", ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + "/" + filePath);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void addResult(StringBuilder result, String msg) {
|
|
|
|
+ result.append(msg).append("\r\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 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()) {
|
|
|
|
+ String courseCode = courseDir.getName();
|
|
|
|
+ TEExamCourse course = teExamCourseService.findByExamIdAndCourseCode(examId, courseCode);
|
|
|
|
+ if (course == null) {
|
|
|
|
+ addResult(result, "科目编码不存在 " + courseCode);
|
|
|
|
+ hasErr = true;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ File[] childs = courseDir.listFiles();
|
|
|
|
+ if (childs == null || childs.length == 0) {
|
|
|
|
+ addResult(result, "科目 " + courseCode + " 没有需要导入的文件");
|
|
|
|
+ hasErr = true;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ for (File paperDir : childs) {// 校验每一套试卷
|
|
|
|
+ if (paperDir.isDirectory()) {
|
|
|
|
+ String paperCode = paperDir.getName();
|
|
|
|
+ File[] paperDirChilds = paperDir.listFiles();
|
|
|
|
+ if (paperDirChilds == null || paperDirChilds.length == 0) {
|
|
|
|
+ addResult(result, "科目 " + courseCode + " 试卷 " + paperCode + " 没有需要导入的文件");
|
|
|
|
+ hasErr = true;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if (processPaper) {
|
|
|
|
+ if (checkPaperHasExamRecord(examId, courseCode, paperCode)) {
|
|
|
|
+ addResult(result, "科目 " + courseCode + " 试卷 " + paperCode + " 已有考试记录,不能再上传试卷");
|
|
|
|
+ hasErr = true;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ 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);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ addResult(result, e.getMessage());
|
|
|
|
+ hasErr = true;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return hasErr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private boolean checkPaperHasExamRecord(Long examId, String courseCode, String paperCode) {
|
|
|
|
+ TEExamPaper paper = teExamPaperService.findByExamIdAndCourseCodeAndPaperCode(examId, courseCode, paperCode);
|
|
|
|
+ if (paper == null) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ TOeExamRecord rd = examRecordService.findOneByPaperId(paper.getId());
|
|
|
|
+ if (rd != null) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void checkAnswerFile(String rootDir, File[] paperDirChilds, Long examId, String courseCode,
|
|
|
|
+ String paperCode) {
|
|
|
|
+ File paperFile = null;
|
|
|
|
+ File answerFile = null;
|
|
|
|
+ for (File cfile : paperDirChilds) {// 校验试卷下的答案
|
|
|
|
+ if ("paper.json".equals(cfile.getName()) && cfile.isFile()) {
|
|
|
|
+ paperFile = cfile;
|
|
|
|
+ }
|
|
|
|
+ if ("answer.json".equals(cfile.getName()) && cfile.isFile()) {
|
|
|
|
+ answerFile = cfile;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (answerFile != null) {
|
|
|
|
+ if (paperFile == null) {// 没有试卷信息,不能先导入答案
|
|
|
|
+ TEExamPaper paper = teExamPaperService.findByExamIdAndCourseCodeAndPaperCode(examId, courseCode,
|
|
|
|
+ paperCode);
|
|
|
|
+ if (paper == null) {
|
|
|
|
+ throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 没有试卷信息,不能先导入答案");
|
|
|
|
+ }
|
|
|
|
+ String structPath = paper.getStructPath();
|
|
|
|
+ String url = OssUtil.getUrlForPrivateBucket(ossUtil.getAliYunOssPrivateDomain().getMap(), structPath);
|
|
|
|
+ String name = structPath.substring(structPath.lastIndexOf("/") + 1);
|
|
|
|
+ File structFile = new File(rootDir + name);
|
|
|
|
+ try {
|
|
|
|
+ FileUtil.saveUrlAsFile(url, structFile);
|
|
|
|
+ compareAnswerAndPaper(courseCode, paperCode, answerFile, structFile);
|
|
|
|
+ } finally {
|
|
|
|
+ if (structFile.exists()) {
|
|
|
|
+ structFile.delete();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ compareAnswerAndPaper(courseCode, paperCode, answerFile, paperFile);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void compareAnswerAndPaper(String courseCode, String paperCode, File answerFile, File structFile) {
|
|
|
|
+ JSONObject answerJson = JSONObject.parseObject(FileUtil.readFileContent(answerFile));
|
|
|
|
+ JSONArray answerdetails = answerJson.getJSONArray("details");
|
|
|
|
+ JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(structFile));
|
|
|
|
+ JSONArray structdetails = structJson.getJSONArray("details");
|
|
|
|
+ if (answerdetails.size() != structdetails.size()) {
|
|
|
|
+ throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷大题数量不一致");
|
|
|
|
+ }
|
|
|
|
+ for (int i = 0; i < answerdetails.size(); i++) {
|
|
|
|
+ JSONArray answerdetailquestions = answerdetails.getJSONObject(i).getJSONArray("questions");
|
|
|
|
+ JSONArray structdetailquestions = structdetails.getJSONObject(i).getJSONArray("questions");
|
|
|
|
+ if (answerdetailquestions.size() != structdetailquestions.size()) {
|
|
|
|
+ throw new BusinessException(
|
|
|
|
+ "科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷第" + (i + 1) + "大题的小题数量不一致");
|
|
|
|
+ }
|
|
|
|
+ for (int j = 0; j < answerdetailquestions.size(); j++) {
|
|
|
|
+ JSONObject answerquestion = answerdetailquestions.getJSONObject(j);
|
|
|
|
+ JSONObject structquestion = structdetailquestions.getJSONObject(j);
|
|
|
|
+ if (structquestion.getInteger("structType").intValue() == 1
|
|
|
|
+ || structquestion.getInteger("structType").intValue() == 2) {
|
|
|
|
+ JSONArray answer = answerquestion.getJSONArray("answer");
|
|
|
|
+ if (answer == null || answer.size() == 0) {
|
|
|
|
+ throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷第" + (i + 1)
|
|
|
|
+ + "大题第" + (j + 1) + "小题没有答案");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (structquestion.getInteger("structType").intValue() == 3) {
|
|
|
|
+ Boolean answer = answerquestion.getBoolean("answer");
|
|
|
|
+ if (answer == null) {
|
|
|
|
+ throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷第" + (i + 1)
|
|
|
|
+ + "大题第" + (j + 1) + "小题没有答案");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (structquestion.getInteger("structType").intValue() == 6) {
|
|
|
|
+ JSONArray answersubQuestions = answerquestion.getJSONArray("subQuestions");
|
|
|
|
+ JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
|
|
|
|
+ if (answersubQuestions.size() != structsubQuestions.size()) {
|
|
|
|
+ throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷第" + (i + 1)
|
|
|
|
+ + "大题第" + (j + 1) + "小题子题数量不一致");
|
|
|
|
+ }
|
|
|
|
+ for (int k = 0; k < answersubQuestions.size(); k++) {
|
|
|
|
+ JSONObject answersubquestion = answersubQuestions.getJSONObject(k);
|
|
|
|
+ JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
|
|
|
|
+ if (structsubquestion.getInteger("structType").intValue() == 1
|
|
|
|
+ || structsubquestion.getInteger("structType").intValue() == 2) {
|
|
|
|
+ JSONArray answer = answersubquestion.getJSONArray("answer");
|
|
|
|
+ if (answer == null || answer.size() == 0) {
|
|
|
|
+ throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷第"
|
|
|
|
+ + (i + 1) + "大题第" + (j + 1) + "小题第" + (k + 1) + "子题没有答案");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (structsubquestion.getInteger("structType").intValue() == 3) {
|
|
|
|
+ Boolean answer = answersubquestion.getBoolean("answer");
|
|
|
|
+ if (answer == null) {
|
|
|
|
+ throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 答案和试卷第"
|
|
|
|
+ + (i + 1) + "大题第" + (j + 1) + "小题第" + (k + 1) + "子题没有答案");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private String uuid() {
|
|
|
|
+ return UUID.randomUUID().toString().replaceAll("-", "");
|
|
|
|
+ }
|
|
}
|
|
}
|