|
@@ -0,0 +1,369 @@
|
|
|
|
+/*
|
|
|
|
+ * *************************************************
|
|
|
|
+ * Copyright (c) 2018 QMTH. All Rights Reserved.
|
|
|
|
+ * Created by Deason on 2018-07-06 15:33:50.
|
|
|
|
+ * *************************************************
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+package cn.com.qmth.examcloud.core.questions.service;
|
|
|
|
+
|
|
|
|
+import cn.com.qmth.examcloud.commons.web.security.bean.User;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.base.BeanCopierUtil;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.base.CommonUtils;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.base.exception.PaperException;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.*;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.*;
|
|
|
|
+import main.java.com.UpYun;
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.util.*;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 复制试卷接口类
|
|
|
|
+ */
|
|
|
|
+@Service
|
|
|
|
+public class ClonePaperService {
|
|
|
|
+ protected static final Logger log = LoggerFactory.getLogger(ClonePaperService.class);
|
|
|
|
+ @Autowired
|
|
|
|
+ private PaperService paperService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private PaperRepo paperRepo;
|
|
|
|
+ @Autowired
|
|
|
|
+ private CourseRepo courseRepo;
|
|
|
|
+ @Autowired
|
|
|
|
+ private PaperDetailRepo paperDetailRepo;
|
|
|
|
+ @Autowired
|
|
|
|
+ private PaperDetailUnitRepo paperDetailUnitRepo;
|
|
|
|
+ @Autowired
|
|
|
|
+ private QuestionAudioService questionAudioService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private QuesPkgPathRepo quesPkgPathRepo;
|
|
|
|
+ @Autowired
|
|
|
|
+ private QuesRepo quesRepo;
|
|
|
|
+ @Autowired
|
|
|
|
+ private QuesTypeNameService quesTypeNameService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private UpYunService upYunService;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 克隆试卷
|
|
|
|
+ *
|
|
|
|
+ * @param paperId 待复制的试卷ID
|
|
|
|
+ * @param paperName 新试卷名称
|
|
|
|
+ * @param courseNo 课程编码
|
|
|
|
+ * @param user 当前用户
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public void clonePaper(String paperId, String paperName, String courseNo, User user) throws PaperException {
|
|
|
|
+ if (StringUtils.isBlank(paperId)) {
|
|
|
|
+ throw new PaperException("待复制的试卷ID不能为空!");
|
|
|
|
+ }
|
|
|
|
+ if (StringUtils.isBlank(courseNo)) {
|
|
|
|
+ throw new PaperException("课程编码不能为空!");
|
|
|
|
+ }
|
|
|
|
+ if (user == null) {
|
|
|
|
+ throw new PaperException("当前用户信息不能为空!");
|
|
|
|
+ }
|
|
|
|
+ if (user.getRootOrgId() == null) {
|
|
|
|
+ throw new PaperException("当前用户的顶级机构ID不能为空!");
|
|
|
|
+ }
|
|
|
|
+ if (StringUtils.isBlank(paperName)) {
|
|
|
|
+ throw new PaperException("新试卷名称不能为空!");
|
|
|
|
+ }
|
|
|
|
+ String existName = paperService.checkPaperName(paperName, user.getRootOrgId().toString());
|
|
|
|
+ if (existName != null) {
|
|
|
|
+ throw new PaperException("当前试卷名称重复,请重新命名!");
|
|
|
|
+ }
|
|
|
|
+ Paper oldPaper = paperRepo.findOne(paperId);
|
|
|
|
+ if (oldPaper == null) {
|
|
|
|
+ throw new PaperException("待复制的试卷不存在!");
|
|
|
|
+ }
|
|
|
|
+ Course course = courseRepo.findFirstByCodeAndOrgId(courseNo, String.valueOf(user.getRootOrgId()));
|
|
|
|
+ if (course == null) {
|
|
|
|
+ throw new PaperException("课程信息不存在!");
|
|
|
|
+ }
|
|
|
|
+ //复制原试卷的所有试题信息
|
|
|
|
+ Map<PaperDetail, List<PaperDetailUnit>> detailMaps = this.copyPaperDetails(oldPaper, user, course);
|
|
|
|
+
|
|
|
|
+ //处理试题的音频(下载上传到云存储)
|
|
|
|
+ this.dealQuestionAudios(detailMaps, user.getDisplayName());
|
|
|
|
+
|
|
|
|
+ //复制原试卷的信息
|
|
|
|
+ Paper newPaper = this.copyPaper(oldPaper, paperName, course, user);
|
|
|
|
+
|
|
|
|
+ //保存新试卷
|
|
|
|
+ paperRepo.save(newPaper);
|
|
|
|
+
|
|
|
|
+ //保存新试卷的所有试题信息
|
|
|
|
+ this.savePaperDetails(detailMaps, newPaper, user);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 保存新试卷的所有试题信息
|
|
|
|
+ */
|
|
|
|
+ private void savePaperDetails(Map<PaperDetail, List<PaperDetailUnit>> detailMaps, Paper newPaper, User user) throws PaperException {
|
|
|
|
+ log.info("new paperId:" + newPaper.getId());
|
|
|
|
+ if (StringUtils.isEmpty(newPaper.getId())) {
|
|
|
|
+ throw new PaperException("试卷保存失败!");
|
|
|
|
+ }
|
|
|
|
+ for (Map.Entry<PaperDetail, List<PaperDetailUnit>> entry : detailMaps.entrySet()) {
|
|
|
|
+ PaperDetail detail = entry.getKey();
|
|
|
|
+ detail.setPaper(newPaper);
|
|
|
|
+ }
|
|
|
|
+ //批量保存大题
|
|
|
|
+ paperDetailRepo.save(detailMaps.keySet());
|
|
|
|
+
|
|
|
|
+ for (Map.Entry<PaperDetail, List<PaperDetailUnit>> entry : detailMaps.entrySet()) {
|
|
|
|
+ PaperDetail detail = entry.getKey();
|
|
|
|
+ log.info("new paperDetailId:" + detail.getId());
|
|
|
|
+ List<PaperDetailUnit> detailUnits = entry.getValue();
|
|
|
|
+ for (PaperDetailUnit detailUnit : detailUnits) {
|
|
|
|
+ detailUnit.setPaper(newPaper);
|
|
|
|
+ detailUnit.setPaperDetail(detail);
|
|
|
|
+ Question question = detailUnit.getQuestion();
|
|
|
|
+ this.updateQuestionPkgPath(question);
|
|
|
|
+ //保存试题
|
|
|
|
+ quesRepo.save(question);
|
|
|
|
+ log.info("new questionId:" + question.getId());
|
|
|
|
+
|
|
|
|
+ //保存试题的音频信息
|
|
|
|
+ List<QuestionAudio> audioList = question.getAudioList();
|
|
|
|
+ if (audioList != null && audioList.size() > 0) {
|
|
|
|
+ for (QuestionAudio audio : audioList) {
|
|
|
|
+ audio.setQuestionId(question.getId());
|
|
|
|
+ questionAudioService.saveQuestionAudio(audio, user);
|
|
|
|
+ log.info("new questionAudioId:" + audio.getId());
|
|
|
|
+ }
|
|
|
|
+ this.updateQuestionBody(question, audioList);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //批量保存小题
|
|
|
|
+ paperDetailUnitRepo.save(detailUnits);
|
|
|
|
+ //复制来源大题的名称
|
|
|
|
+ quesTypeNameService.saveCloneQuesTypeName(detailUnits, newPaper.getCourseNo());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 更新试题题干或选项中的音频存储ID
|
|
|
|
+ */
|
|
|
|
+ private void updateQuestionBody(Question question, List<QuestionAudio> audioList) {
|
|
|
|
+ Map<String, String> audioMaps = new HashMap<>();
|
|
|
|
+ for (QuestionAudio audio : audioList) {
|
|
|
|
+ audioMaps.put(audio.getFileName(), audio.getId());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //在题干html片段中替换音频存储ID
|
|
|
|
+ String body = question.getQuesBody();
|
|
|
|
+ List<String> ids = CommonUtils.getTagANames(body);
|
|
|
|
+ List<String> names = CommonUtils.getTagANames2(body);
|
|
|
|
+ Map<String, String> oldBodyMap = new HashMap<>();
|
|
|
|
+ for (int i = 0; i < ids.size(); i++) {
|
|
|
|
+ oldBodyMap.put(names.get(i), ids.get(i));
|
|
|
|
+ }
|
|
|
|
+ for (String key : oldBodyMap.keySet()) {
|
|
|
|
+ body = body.replace(oldBodyMap.get(key), audioMaps.get(key));
|
|
|
|
+ }
|
|
|
|
+ question.setQuesBody(body);
|
|
|
|
+
|
|
|
|
+ if (question.getQuesOptions() == null || question.getQuesOptions().size() == 0) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //替换选项中的音频存储ID
|
|
|
|
+ for (QuesOption option : question.getQuesOptions()) {
|
|
|
|
+ String newOptionBody = option.getOptionBody();
|
|
|
|
+ List<String> optionIds = CommonUtils.getTagANames(newOptionBody);
|
|
|
|
+ List<String> optionNames = CommonUtils.getTagANames2(newOptionBody);
|
|
|
|
+
|
|
|
|
+ Map<String, String> oldOptionMap = new HashMap<>();
|
|
|
|
+ for (int i = 0; i < optionIds.size(); i++) {
|
|
|
|
+ oldOptionMap.put(optionNames.get(i), optionIds.get(i));
|
|
|
|
+ }
|
|
|
|
+ for (String key : oldOptionMap.keySet()) {
|
|
|
|
+ newOptionBody = newOptionBody.replace(oldOptionMap.get(key), audioMaps.get(key));
|
|
|
|
+ }
|
|
|
|
+ option.setOptionBody(newOptionBody);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 更新试题的“word package path”
|
|
|
|
+ */
|
|
|
|
+ private void updateQuestionPkgPath(Question question) {
|
|
|
|
+ QuestionPkgPath pkgPath = quesPkgPathRepo.findFirstById(question.getQuesPkgPathId());
|
|
|
|
+ pkgPath.setId(null);
|
|
|
|
+ quesPkgPathRepo.save(pkgPath);
|
|
|
|
+ question.setQuesPkgPathId(pkgPath.getId());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 处理试题的音频(下载上传到云存储)
|
|
|
|
+ */
|
|
|
|
+ private void dealQuestionAudios(Map<PaperDetail, List<PaperDetailUnit>> detailMaps, String userName) throws PaperException {
|
|
|
|
+ UpYun upYun = upYunService.getInstance();
|
|
|
|
+ String copyAudioPath = UpYunService.TEMP_FILE_EXP + File.separator + userName + "_copyAudioPath";
|
|
|
|
+ File copyAudioDir = new File(copyAudioPath);
|
|
|
|
+ if (!copyAudioDir.exists()) {
|
|
|
|
+ copyAudioDir.mkdirs();
|
|
|
|
+ }
|
|
|
|
+ for (Map.Entry<PaperDetail, List<PaperDetailUnit>> entry : detailMaps.entrySet()) {
|
|
|
|
+ List<PaperDetailUnit> detailUnits = entry.getValue();
|
|
|
|
+ for (PaperDetailUnit detailUnit : detailUnits) {
|
|
|
|
+ Question question = detailUnit.getQuestion();
|
|
|
|
+ List<QuestionAudio> audioList = question.getAudioList();
|
|
|
|
+ if (audioList == null || audioList.size() == 0) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ for (QuestionAudio audio : audioList) {
|
|
|
|
+ //定义文件下载名称,并下载音频文件
|
|
|
|
+ String newAudioFileName = upYunService.randomUUID() + "_" + audio.getFileName();
|
|
|
|
+ File audioFile = new File(copyAudioPath + File.separator + newAudioFileName);
|
|
|
|
+ upYun.readFile(audio.getFileUrl(), audioFile);
|
|
|
|
+ //重新上传新的音频文件
|
|
|
|
+ String newPath = upYunService.getUpYunRadioPath() + newAudioFileName;
|
|
|
|
+ try {
|
|
|
|
+ upYun.writeFile(newPath, audioFile, true);
|
|
|
|
+ audio.setFileUrl(newPath);//设置新路径
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new PaperException("上传音频文件失败!");
|
|
|
|
+ } finally {
|
|
|
|
+ audioFile.delete();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ copyAudioDir.delete();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 复制试卷的所有试题信息
|
|
|
|
+ */
|
|
|
|
+ private Map<PaperDetail, List<PaperDetailUnit>> copyPaperDetails(Paper oldPaper, User user, Course course) throws PaperException {
|
|
|
|
+ List<PaperDetail> oldPaperDetails = paperDetailRepo.findByPaperOrderByNumber(oldPaper);
|
|
|
|
+ if (oldPaperDetails == null || oldPaperDetails.size() == 0) {
|
|
|
|
+ throw new PaperException("原试卷的大题不存在!");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Map<PaperDetail, List<PaperDetailUnit>> detailMaps = new TreeMap<>();
|
|
|
|
+ for (PaperDetail oldPaperDetail : oldPaperDetails) {
|
|
|
|
+ //复制大题信息
|
|
|
|
+ PaperDetail paperDetail = this.copyPaperDetail(oldPaperDetail, user.getDisplayName());
|
|
|
|
+ List<PaperDetailUnit> oldDetailUnits = paperDetailUnitRepo.findByPaperDetailOrderByNumber(oldPaperDetail);
|
|
|
|
+ if (oldDetailUnits == null || oldDetailUnits.size() == 0) {
|
|
|
|
+ throw new PaperException("原试卷的大题下的试题不存在!");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //复制大题下的所有小题
|
|
|
|
+ List<PaperDetailUnit> detailUnits = new ArrayList<>();
|
|
|
|
+ for (PaperDetailUnit oldDetailUnit : oldDetailUnits) {
|
|
|
|
+ PaperDetailUnit detailUnit = this.copyPaperDetailUnit(oldDetailUnit, course, user.getDisplayName());
|
|
|
|
+ detailUnits.add(detailUnit);
|
|
|
|
+ }
|
|
|
|
+ detailMaps.put(paperDetail, detailUnits);
|
|
|
|
+ }
|
|
|
|
+ return detailMaps;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 复制试题的音频
|
|
|
|
+ */
|
|
|
|
+ private QuestionAudio copyQuestionAudio(QuestionAudio oldAudio, String createUser) {
|
|
|
|
+ QuestionAudio audio = new QuestionAudio();
|
|
|
|
+ audio.setId(null);
|
|
|
|
+ audio.setQuestionId(null);
|
|
|
|
+ audio.setFileUrl(oldAudio.getFileUrl());
|
|
|
|
+ audio.setFileName(oldAudio.getFileName());
|
|
|
|
+ audio.setFileSuffixes(oldAudio.getFileSuffixes());
|
|
|
|
+ audio.setCreateTime(new Date());
|
|
|
|
+ audio.setCreateUser(createUser);
|
|
|
|
+ return audio;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 复制试题信息
|
|
|
|
+ */
|
|
|
|
+ private Question copyQuestion(Question oldQuestion, String createUser) {
|
|
|
|
+ Question question = BeanCopierUtil.copyProperties(oldQuestion, Question.class);
|
|
|
|
+ question.setId(null);
|
|
|
|
+ question.setCourse(null);
|
|
|
|
+ question.setQuesProperties(null);
|
|
|
|
+ question.setPropertyGroup(null);
|
|
|
|
+ if (oldQuestion.getHasAudio() == null || !oldQuestion.getHasAudio()) {
|
|
|
|
+ question.setHasAudio(false);
|
|
|
|
+ return question;
|
|
|
|
+ }
|
|
|
|
+ //复制试题的音频
|
|
|
|
+ List<QuestionAudio> audioList = questionAudioService.findQuestionAudiosByQuestionId(oldQuestion.getId());
|
|
|
|
+ if (audioList != null && audioList.size() > 0) {
|
|
|
|
+ for (QuestionAudio oldAudio : audioList) {
|
|
|
|
+ QuestionAudio audio = this.copyQuestionAudio(oldAudio, createUser);
|
|
|
|
+ question.addAudio(audio);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return question;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 复制小题信息
|
|
|
|
+ */
|
|
|
|
+ private PaperDetailUnit copyPaperDetailUnit(PaperDetailUnit oldDetailUnit, Course course, String createUser) throws PaperException {
|
|
|
|
+ Question oldQuestion = oldDetailUnit.getQuestion();
|
|
|
|
+ if (oldQuestion == null) {
|
|
|
|
+ throw new PaperException("原试题详细信息不存在!");
|
|
|
|
+ }
|
|
|
|
+ PaperDetailUnit detailUnit = new PaperDetailUnit();
|
|
|
|
+ detailUnit.setNumber(oldDetailUnit.getNumber());
|
|
|
|
+ detailUnit.setScore(oldDetailUnit.getScore());
|
|
|
|
+ detailUnit.setSubScoreList(oldDetailUnit.getSubScoreList());
|
|
|
|
+ detailUnit.setQuestionType(oldDetailUnit.getQuestionType());
|
|
|
|
+ detailUnit.setOptionOrder(oldDetailUnit.getOptionOrder());
|
|
|
|
+ detailUnit.setPaperType(oldDetailUnit.getPaperType());
|
|
|
|
+ detailUnit.setCreator(createUser);
|
|
|
|
+ detailUnit.setCreateTime(CommonUtils.getCurDateTime());
|
|
|
|
+ detailUnit.setPaper(null);
|
|
|
|
+ detailUnit.setPaperDetail(null);
|
|
|
|
+ //复制试题信息
|
|
|
|
+ Question question = this.copyQuestion(oldQuestion, createUser);
|
|
|
|
+ question.setCourse(course);
|
|
|
|
+ detailUnit.setQuestion(question);
|
|
|
|
+ return detailUnit;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 复制大题信息
|
|
|
|
+ */
|
|
|
|
+ private PaperDetail copyPaperDetail(PaperDetail oldPaperDetail, String createUser) {
|
|
|
|
+ PaperDetail paperDetail = new PaperDetail();
|
|
|
|
+ paperDetail.setNumber(oldPaperDetail.getNumber());
|
|
|
|
+ paperDetail.setName(oldPaperDetail.getName());
|
|
|
|
+ paperDetail.setTitle(oldPaperDetail.getTitle());
|
|
|
|
+ paperDetail.setScore(oldPaperDetail.getScore());
|
|
|
|
+ paperDetail.setUnitCount(oldPaperDetail.getUnitCount());
|
|
|
|
+ paperDetail.setCreator(createUser);
|
|
|
|
+ paperDetail.setCreateTime(CommonUtils.getCurDateTime());
|
|
|
|
+ paperDetail.setPaper(null);
|
|
|
|
+ return paperDetail;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 复制试卷信息
|
|
|
|
+ */
|
|
|
|
+ private Paper copyPaper(Paper oldPaper, String paperName, Course course, User user) {
|
|
|
|
+ Paper newPaper = BeanCopierUtil.copyProperties(oldPaper, Paper.class);
|
|
|
|
+ newPaper.setName(paperName);
|
|
|
|
+ newPaper.setCourse(course);
|
|
|
|
+ newPaper.setCourseNo(course.getCode());
|
|
|
|
+ newPaper.setOrgId(String.valueOf(user.getRootOrgId()));
|
|
|
|
+ newPaper.setCreateTime(CommonUtils.getCurDateTime());
|
|
|
|
+ newPaper.setLastModifyName(user.getDisplayName());
|
|
|
|
+ newPaper.setId(null);
|
|
|
|
+ return newPaper;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|