|
@@ -1,608 +1,630 @@
|
|
-package cn.com.qmth.examcloud.core.questions.service.consumer;
|
|
|
|
-
|
|
|
|
-import java.io.File;
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
-import java.util.Date;
|
|
|
|
-import java.util.HashMap;
|
|
|
|
-import java.util.List;
|
|
|
|
-import java.util.Map;
|
|
|
|
-import java.util.TreeMap;
|
|
|
|
-import java.util.UUID;
|
|
|
|
-
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.base.FileConstants;
|
|
|
|
-import cn.com.qmth.examcloud.support.fss.FssFactory;
|
|
|
|
-import cn.com.qmth.examcloud.support.fss.FssHelper;
|
|
|
|
-import cn.com.qmth.examcloud.support.fss.model.FssFileInfo;
|
|
|
|
-import org.apache.commons.collections4.CollectionUtils;
|
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
|
-import org.slf4j.Logger;
|
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
-import org.springframework.context.annotation.Scope;
|
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
|
-import org.springframework.transaction.annotation.Transactional;
|
|
|
|
-
|
|
|
|
-import cn.com.qmth.examcloud.api.commons.security.bean.User;
|
|
|
|
-import cn.com.qmth.examcloud.commons.exception.StatusException;
|
|
|
|
-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.IoUtils;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.base.enums.PaperType;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.base.multithread.Consumer;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.CoursePropertyRepo;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.PaperDetailRepo;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.PaperDetailUnitRepo;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.PaperRepo;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.PropertyRepo;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.QuesRepo;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.CourseProperty;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.Paper;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetail;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetailUnit;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.Property;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.QuesOption;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.QuesProperty;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.Question;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.dao.entity.QuestionAudio;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.CoursePropertyService;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.PaperService;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.PropertyService;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.QuesService;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.QuestionAudioService;
|
|
|
|
-import cn.com.qmth.examcloud.core.questions.service.bean.CopyDataDto;
|
|
|
|
-import cn.com.qmth.examcloud.web.redis.RedisClient;
|
|
|
|
-
|
|
|
|
-@Scope("prototype")
|
|
|
|
-@Service
|
|
|
|
-public class CopyDataConsumer extends Consumer<CopyDataDto> {
|
|
|
|
- private static final Logger log = LoggerFactory.getLogger(CopyDataConsumer.class);
|
|
|
|
- private static int cacheLockTimeout = 60 * 10;
|
|
|
|
- private static String copyQuestionDataLock = "$_COPY_QUESTION_DATA_LOCK";
|
|
|
|
- @Autowired
|
|
|
|
- private PaperRepo paperRepo;
|
|
|
|
- @Autowired
|
|
|
|
- private CoursePropertyService coursePropertyService;
|
|
|
|
- @Autowired
|
|
|
|
- private CoursePropertyRepo coursePropertyRepo;
|
|
|
|
- @Autowired
|
|
|
|
- private PropertyService propertyService;
|
|
|
|
- @Autowired
|
|
|
|
- private PropertyRepo propertyRepo;
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- private PaperDetailRepo paperDetailRepo;
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- private PaperDetailUnitRepo paperDetailUnitRepo;
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- private QuestionAudioService questionAudioService;
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- private PaperService paperService;
|
|
|
|
- @Autowired
|
|
|
|
- private QuesRepo quesRepo;
|
|
|
|
- @Autowired
|
|
|
|
- private QuesService quesService;
|
|
|
|
- @Autowired
|
|
|
|
- private RedisClient redisClient;
|
|
|
|
-
|
|
|
|
- @Transactional
|
|
|
|
- @Override
|
|
|
|
- public int consume(CopyDataDto dto) {
|
|
|
|
- disposeCourse(dto);
|
|
|
|
- dto.setSouceIdMap(null);
|
|
|
|
- dto.setPaperType(PaperType.GENERATE);
|
|
|
|
- disposeCourse(dto);
|
|
|
|
- return 1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void disposeCourse(CopyDataDto dto) {
|
|
|
|
- redisClient.expire(copyQuestionDataLock, cacheLockTimeout);
|
|
|
|
-
|
|
|
|
- if (PaperType.IMPORT.equals(dto.getPaperType())) {
|
|
|
|
- copyCourseProperty(dto);
|
|
|
|
- }
|
|
|
|
- List<Paper> papers = paperService.getPapersByCourse(dto.getFromRootOrgId(), dto.getCourse().getCourseCode(),
|
|
|
|
- dto.getPaperType());
|
|
|
|
-
|
|
|
|
- redisClient.expire(copyQuestionDataLock, cacheLockTimeout);
|
|
|
|
-
|
|
|
|
- if (CollectionUtils.isEmpty(papers)) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- if (PaperType.IMPORT.equals(dto.getPaperType())) {
|
|
|
|
- fillSouceIdMap(dto);
|
|
|
|
- }
|
|
|
|
- for (Paper paper : papers) {
|
|
|
|
- if (!paperService.existsPaperBySourceId(dto.getToRootOrgId(), dto.getCourse().getCourseCode(),
|
|
|
|
- dto.getPaperType(), paper.getId())) {
|
|
|
|
- clonePaper(paper, dto);
|
|
|
|
- }
|
|
|
|
- redisClient.expire(copyQuestionDataLock, cacheLockTimeout);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void fillSouceIdMap(CopyDataDto dto) {
|
|
|
|
- List<CourseProperty> cps = coursePropertyService.findAllByOrgIdCourseCode(dto.getToRootOrgId(),
|
|
|
|
- dto.getCourse().getCourseCode());
|
|
|
|
- if (CollectionUtils.isEmpty(cps)) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- for (CourseProperty cp : cps) {
|
|
|
|
- List<Property> ps = propertyService.findByOrgIdAndCoursePropertyId(dto.getToRootOrgId(), cp.getId());
|
|
|
|
- if (CollectionUtils.isEmpty(ps)) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- for (Property p : ps) {
|
|
|
|
- dto.getSouceIdMap().put(p.getSourceId(), p);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void copyCourseProperty(CopyDataDto dto) {
|
|
|
|
- List<CourseProperty> cps = coursePropertyService.findAllByOrgIdCourseCode(dto.getFromRootOrgId(),
|
|
|
|
- dto.getCourse().getCourseCode());
|
|
|
|
- if (CollectionUtils.isEmpty(cps)) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- for (CourseProperty cp : cps) {
|
|
|
|
- CourseProperty targetCourseProper = null;
|
|
|
|
- List<CourseProperty> targetFirstPropers = coursePropertyService
|
|
|
|
- .findByOrgIdAndCourseIdAndSourceId(dto.getToRootOrgId(), dto.getCourse().getCourseId(), cp.getId());
|
|
|
|
- if (CollectionUtils.isEmpty(targetFirstPropers)) {
|
|
|
|
- targetCourseProper = BeanCopierUtil.copyProperties(cp, CourseProperty.class);
|
|
|
|
- targetCourseProper.setId(null);
|
|
|
|
- targetCourseProper.setOrgId(dto.getToRootOrgId());
|
|
|
|
- targetCourseProper.setCourseId(dto.getCourse().getCourseId());
|
|
|
|
- targetCourseProper.setUpdateTime(new Date());
|
|
|
|
- targetCourseProper.setSourceId(cp.getId());
|
|
|
|
- coursePropertyRepo.save(targetCourseProper);
|
|
|
|
- } else {
|
|
|
|
- targetCourseProper = targetFirstPropers.get(0);
|
|
|
|
- }
|
|
|
|
- // 处理一级属性
|
|
|
|
- List<Property> fps = propertyService.findParentProperties(cp.getId(), dto.getFromRootOrgId());
|
|
|
|
- if (CollectionUtils.isEmpty(fps)) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- List<Property> targetFps = propertyService.findParentProperties(targetCourseProper.getId(),
|
|
|
|
- dto.getToRootOrgId());
|
|
|
|
- int firstNum = 0;
|
|
|
|
- if (CollectionUtils.isNotEmpty(targetFps)) {
|
|
|
|
- firstNum = targetFps.size();
|
|
|
|
- }
|
|
|
|
- Map<String, Property> targetsouceIds = getSourceIds(targetFps);
|
|
|
|
- for (Property fp : fps) {
|
|
|
|
- Property targetFp = null;
|
|
|
|
- if (targetsouceIds.get(fp.getId()) == null) {
|
|
|
|
- firstNum++;
|
|
|
|
- targetFp = BeanCopierUtil.copyProperties(fp, Property.class);
|
|
|
|
- targetFp.setId(null);
|
|
|
|
- targetFp.setOrgId(dto.getToRootOrgId());
|
|
|
|
- targetFp.setCoursePropertyId(targetCourseProper.getId());
|
|
|
|
- targetFp.setParentId(Property.ROOT_PARENT_ID);
|
|
|
|
- targetFp.setNumber(firstNum);
|
|
|
|
- targetFp.setSourceId(fp.getId());
|
|
|
|
- propertyRepo.save(targetFp);
|
|
|
|
- } else {
|
|
|
|
- targetFp = targetsouceIds.get(fp.getId());
|
|
|
|
- }
|
|
|
|
- // 处理二级属性
|
|
|
|
- List<Property> sps = propertyService.findSonProperties(fp.getId());
|
|
|
|
- if (CollectionUtils.isEmpty(sps)) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- List<Property> targetSps = propertyService.findSonProperties(targetFp.getId());
|
|
|
|
- int secondNum = 0;
|
|
|
|
- if (CollectionUtils.isNotEmpty(targetSps)) {
|
|
|
|
- secondNum = targetSps.size();
|
|
|
|
- }
|
|
|
|
- Map<String, Property> targetSecondSouceIds = getSourceIds(targetSps);
|
|
|
|
- for (Property sp : sps) {
|
|
|
|
- Property targetSp = null;
|
|
|
|
- if (targetSecondSouceIds.get(sp.getId()) == null) {
|
|
|
|
- secondNum++;
|
|
|
|
- targetSp = BeanCopierUtil.copyProperties(sp, Property.class);
|
|
|
|
- targetSp.setId(null);
|
|
|
|
- targetSp.setOrgId(dto.getToRootOrgId());
|
|
|
|
- targetSp.setCoursePropertyId(targetCourseProper.getId());
|
|
|
|
- targetSp.setParentId(targetFp.getId());
|
|
|
|
- targetSp.setNumber(secondNum);
|
|
|
|
- targetSp.setSourceId(sp.getId());
|
|
|
|
- propertyRepo.save(targetSp);
|
|
|
|
- } else {
|
|
|
|
- targetFp = targetsouceIds.get(fp.getId());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private Map<String, Property> getSourceIds(List<Property> targetFps) {
|
|
|
|
- Map<String, Property> set = new HashMap<>();
|
|
|
|
- if (CollectionUtils.isEmpty(targetFps)) {
|
|
|
|
- return set;
|
|
|
|
- }
|
|
|
|
- for (Property p : targetFps) {
|
|
|
|
- set.put(p.getSourceId(), p);
|
|
|
|
- }
|
|
|
|
- return set;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void clonePaper(Paper oldPaper, CopyDataDto dto) {
|
|
|
|
- User user = dto.getUser();
|
|
|
|
-
|
|
|
|
- if (user == null) {
|
|
|
|
- throw new StatusException("当前用户信息不能为空!");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (user.getRootOrgId() == null) {
|
|
|
|
- throw new StatusException("当前用户的顶级机构ID不能为空!");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 复制原试卷的所有试题信息
|
|
|
|
- Map<PaperDetail, List<PaperDetailUnit>> detailMaps = this.copyPaperDetails(oldPaper, dto);
|
|
|
|
- if(detailMaps==null) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- if (PaperType.IMPORT.equals(dto.getPaperType())) {// 复制原卷才处理音频
|
|
|
|
- // 处理试题的音频(下载上传到云存储)
|
|
|
|
- try {
|
|
|
|
- this.dealQuestionAudios(detailMaps, user.getDisplayName());
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- throw new StatusException("500", "复制音频失败!", e);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 复制原试卷的信息
|
|
|
|
- Paper newPaper = this.copyPaper(oldPaper, dto);
|
|
|
|
- // 保存新试卷
|
|
|
|
- paperRepo.save(newPaper);
|
|
|
|
- try {
|
|
|
|
- // 保存新试卷的所有试题信息
|
|
|
|
- this.savePaperDetails(detailMaps, newPaper, user);
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- throw new StatusException("500", "克隆试卷失败!", e);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void savePaperDetails(Map<PaperDetail, List<PaperDetailUnit>> detailMaps, Paper newPaper, User user) {
|
|
|
|
- if (StringUtils.isEmpty(newPaper.getId())) {
|
|
|
|
- throw new StatusException("试卷保存失败!");
|
|
|
|
- }
|
|
|
|
- for (Map.Entry<PaperDetail, List<PaperDetailUnit>> entry : detailMaps.entrySet()) {
|
|
|
|
- PaperDetail detail = entry.getKey();
|
|
|
|
- detail.setPaper(newPaper);
|
|
|
|
- }
|
|
|
|
- // 批量保存大题
|
|
|
|
- paperDetailRepo.saveAll(detailMaps.keySet());
|
|
|
|
- List<PaperDetailUnit> newDetailUnits = new ArrayList<>();
|
|
|
|
- List<Question> newQuestions = new ArrayList<>();
|
|
|
|
- for (Map.Entry<PaperDetail, List<PaperDetailUnit>> entry : detailMaps.entrySet()) {
|
|
|
|
- PaperDetail detail = entry.getKey();
|
|
|
|
- List<PaperDetailUnit> detailUnits = entry.getValue();
|
|
|
|
- for (PaperDetailUnit detailUnit : detailUnits) {
|
|
|
|
- detailUnit.setPaper(newPaper);
|
|
|
|
- detailUnit.setPaperDetail(detail);
|
|
|
|
- newDetailUnits.add(detailUnit);
|
|
|
|
- newQuestions.add(detailUnit.getQuestion());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (PaperType.IMPORT.equals(newPaper.getPaperType())) {// 复制原卷才处理
|
|
|
|
- // 批量新增试题
|
|
|
|
- quesRepo.saveAll(newQuestions);
|
|
|
|
-
|
|
|
|
- for (Question question : newQuestions) {
|
|
|
|
- List<QuestionAudio> audioList = question.getAudioList();
|
|
|
|
- if (audioList != null && audioList.size() > 0) {
|
|
|
|
- for (QuestionAudio audio : audioList) {
|
|
|
|
- audio.setQuestionId(question.getId());
|
|
|
|
- questionAudioService.saveQuestionAudio(audio, user);
|
|
|
|
- }
|
|
|
|
- this.updateQuestionBody(question, audioList);
|
|
|
|
- // 如果试题存在音频,则更新试题的音频信息
|
|
|
|
- quesRepo.save(question);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 批量保存试题单元
|
|
|
|
- paperDetailUnitRepo.saveAll(newDetailUnits);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 更新试题题干或选项中的音频存储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);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 处理试题的音频(下载上传到云存储)
|
|
|
|
- */
|
|
|
|
- private void dealQuestionAudios(Map<PaperDetail, List<PaperDetailUnit>> detailMaps, String userName) {
|
|
|
|
- String copyAudioPath = FileConstants.TEMP_FILE_EXPORT + File.separator + randomUUID();
|
|
|
|
- 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 = randomUUID() + "_" + audio.getFileName();
|
|
|
|
- File audioFile = new File(copyAudioPath + File.separator + newAudioFileName);
|
|
|
|
-
|
|
|
|
- // 通用存储
|
|
|
|
- String filePath = FssHelper.fixFilePath(audio.getFileUrl());
|
|
|
|
- FssFactory.getInstance().readFile(filePath, audioFile);
|
|
|
|
-
|
|
|
|
- // 重新上传新的音频文件
|
|
|
|
- String newPath = String.format(FileConstants.RADIO_UPLOAD_PATH, newAudioFileName);
|
|
|
|
- try {
|
|
|
|
- // 通用存储
|
|
|
|
- FssFileInfo result = FssFactory.getInstance().writeFile(newPath, audioFile, null);
|
|
|
|
- audio.setFileUrl(result.getFileUrl());//设置新路径
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- throw new StatusException("上传音频文件失败!");
|
|
|
|
- } finally {
|
|
|
|
- IoUtils.removeFile(audioFile);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- IoUtils.removeFile(copyAudioDir);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 复制试卷的所有试题信息
|
|
|
|
- */
|
|
|
|
- private Map<PaperDetail, List<PaperDetailUnit>> copyPaperDetails(Paper oldPaper, CopyDataDto dto) {
|
|
|
|
- // 批量查询原试卷的所有试题
|
|
|
|
- List<PaperDetailUnit> allDetailUnits = paperDetailUnitRepo.findByPaperOrderByNumber(oldPaper);
|
|
|
|
- if (allDetailUnits == null || allDetailUnits.size() == 0) {
|
|
|
|
- log.warn("忽略试卷复制,原试卷的试题不存在,courseCode:"+dto.getCourse().getCourseCode()+"|paperName:"+oldPaper.getName());
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
- // 按大题有序封装对应的试题列表
|
|
|
|
- Map<PaperDetail, List<PaperDetailUnit>> oldDetailMaps = new TreeMap<>();
|
|
|
|
- for (PaperDetailUnit detailUnit : allDetailUnits) {
|
|
|
|
- PaperDetail detail = detailUnit.getPaperDetail();
|
|
|
|
- if (!oldDetailMaps.containsKey(detail)) {
|
|
|
|
- oldDetailMaps.put(detail, new ArrayList<>());
|
|
|
|
- }
|
|
|
|
- List<PaperDetailUnit> detailUnits = oldDetailMaps.get(detail);
|
|
|
|
- detailUnits.add(detailUnit);
|
|
|
|
- }
|
|
|
|
- // 开始复制
|
|
|
|
- Map<PaperDetail, List<PaperDetailUnit>> detailMaps = new TreeMap<>();
|
|
|
|
- for (Map.Entry<PaperDetail, List<PaperDetailUnit>> entry : oldDetailMaps.entrySet()) {
|
|
|
|
- // 复制大题信息
|
|
|
|
- PaperDetail oldPaperDetail = entry.getKey();
|
|
|
|
- PaperDetail paperDetail = this.copyPaperDetail(oldPaperDetail, dto);
|
|
|
|
- // 复制大题下的所有试题单元
|
|
|
|
- List<PaperDetailUnit> oldDetailUnits = entry.getValue();
|
|
|
|
- List<PaperDetailUnit> detailUnits = new ArrayList<>();
|
|
|
|
- for (PaperDetailUnit oldDetailUnit : oldDetailUnits) {
|
|
|
|
- PaperDetailUnit detailUnit = this.copyPaperDetailUnit(oldDetailUnit, dto);
|
|
|
|
- detailUnits.add(detailUnit);
|
|
|
|
- }
|
|
|
|
- detailMaps.put(paperDetail, detailUnits);
|
|
|
|
- }
|
|
|
|
- return detailMaps;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 复制试题的音频
|
|
|
|
- */
|
|
|
|
- private QuestionAudio copyQuestionAudio(QuestionAudio oldAudio, CopyDataDto dto) {
|
|
|
|
- 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(dto.getUser().getDisplayName());
|
|
|
|
- audio.setOrgId(dto.getToRootOrgId());
|
|
|
|
- audio.setCreationBy(dto.getUser().getUserId());
|
|
|
|
- audio.setUpdateBy(dto.getUser().getUserId());
|
|
|
|
- return audio;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 复制试题信息
|
|
|
|
- */
|
|
|
|
- private Question copyQuestion(Question oldQuestion, CopyDataDto dto) {
|
|
|
|
- Question question = BeanCopierUtil.copyProperties(oldQuestion, Question.class);
|
|
|
|
- question.setId(null);
|
|
|
|
- question.getCourse().setId(dto.getCourse().getCourseId().toString());
|
|
|
|
- question.getCourse().setOrgId(dto.getToRootOrgId().toString());
|
|
|
|
- question.setOrgId(dto.getToRootOrgId().toString());
|
|
|
|
- disposeProperty(question, dto);
|
|
|
|
- question.setCreateTime(CommonUtils.getCurDateTime());
|
|
|
|
- question.setUpdateTime(CommonUtils.getCurDateTime());
|
|
|
|
- question.setPropertyGroup(null);
|
|
|
|
- question.setCreationBy(dto.getUser().getUserId());
|
|
|
|
- question.setUpdateBy(dto.getUser().getUserId());
|
|
|
|
- question.setSourceId(oldQuestion.getId());
|
|
|
|
- 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, dto);
|
|
|
|
- question.addAudio(audio);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return question;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void disposeProperty(Question question, CopyDataDto dto) {
|
|
|
|
- if (CollectionUtils.isNotEmpty(question.getQuesProperties())) {
|
|
|
|
- for (QuesProperty qp : question.getQuesProperties()) {
|
|
|
|
- if (qp != null) {
|
|
|
|
- if (qp.getFirstProperty() != null && qp.getFirstProperty().getId() != null) {
|
|
|
|
- Property p = dto.getSouceIdMap().get(qp.getFirstProperty().getId());
|
|
|
|
- if (p == null) {
|
|
|
|
- throw new StatusException("未找到试题属性 CourseCode:" + dto.getCourse().getCourseCode()
|
|
|
|
- + " | PropertyId:" + qp.getFirstProperty().getId());
|
|
|
|
- }
|
|
|
|
- qp.setFirstProperty(p);
|
|
|
|
- }
|
|
|
|
- if (qp.getSecondProperty() != null && qp.getSecondProperty().getId() != null) {
|
|
|
|
- Property p = dto.getSouceIdMap().get(qp.getSecondProperty().getId());
|
|
|
|
- if (p == null) {
|
|
|
|
- throw new StatusException("未找到试题属性 CourseCode:" + dto.getCourse().getCourseCode()
|
|
|
|
- + " | PropertyId:" + qp.getSecondProperty().getId());
|
|
|
|
- }
|
|
|
|
- qp.setSecondProperty(p);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (CollectionUtils.isNotEmpty(question.getSubQuestions())) {
|
|
|
|
- for (Question sub : question.getSubQuestions()) {
|
|
|
|
- disposeProperty(sub, dto);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 复制试题单元信息
|
|
|
|
- */
|
|
|
|
- private PaperDetailUnit copyPaperDetailUnit(PaperDetailUnit oldDetailUnit, CopyDataDto dto) {
|
|
|
|
- Question oldQuestion = oldDetailUnit.getQuestion();
|
|
|
|
- if (oldQuestion == null) {
|
|
|
|
- throw new StatusException("原试题详细信息不存在!");
|
|
|
|
- }
|
|
|
|
- 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(dto.getUser().getDisplayName());
|
|
|
|
- detailUnit.setCreateTime(CommonUtils.getCurDateTime());
|
|
|
|
- detailUnit.setOrgId(dto.getToRootOrgId());
|
|
|
|
- detailUnit.setCreationBy(dto.getUser().getUserId());
|
|
|
|
- detailUnit.setUpdateBy(dto.getUser().getUserId());
|
|
|
|
- detailUnit.setPaper(null);
|
|
|
|
- detailUnit.setPaperDetail(null);
|
|
|
|
- if (PaperType.IMPORT.equals(dto.getPaperType())) {// 原卷才处理
|
|
|
|
- // 复制试题信息
|
|
|
|
- Question question = this.copyQuestion(oldQuestion, dto);
|
|
|
|
- detailUnit.setQuestion(question);
|
|
|
|
- } else {
|
|
|
|
- List<Question> qs = quesService.findByOrgIdAndCourseCodeAndSourceId(dto.getToRootOrgId(),
|
|
|
|
- dto.getCourse().getCourseCode(), oldQuestion.getId());
|
|
|
|
- if (CollectionUtils.isEmpty(qs)) {
|
|
|
|
- throw new StatusException("原试题信息不存在:courseCode" + dto.getCourse().getCourseCode() + "|" + "sourceId:"
|
|
|
|
- + oldQuestion.getId());
|
|
|
|
- }
|
|
|
|
- if (qs.size() > 1) {
|
|
|
|
- throw new StatusException("原试题信息存在多个:courseCode" + dto.getCourse().getCourseCode() + "|" + "sourceId:"
|
|
|
|
- + oldQuestion.getId());
|
|
|
|
- }
|
|
|
|
- detailUnit.setQuestion(qs.get(0));
|
|
|
|
- }
|
|
|
|
- return detailUnit;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 复制大题信息
|
|
|
|
- */
|
|
|
|
- private PaperDetail copyPaperDetail(PaperDetail oldPaperDetail, CopyDataDto dto) {
|
|
|
|
- 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(dto.getUser().getDisplayName());
|
|
|
|
- paperDetail.setCreateTime(CommonUtils.getCurDateTime());
|
|
|
|
- paperDetail.setPaper(null);
|
|
|
|
- paperDetail.setOrgId(dto.getToRootOrgId());
|
|
|
|
- paperDetail.setCreationBy(dto.getUser().getUserId());
|
|
|
|
- paperDetail.setUpdateBy(dto.getUser().getUserId());
|
|
|
|
- return paperDetail;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 复制试卷信息
|
|
|
|
- */
|
|
|
|
- private Paper copyPaper(Paper oldPaper, CopyDataDto dto) {
|
|
|
|
- Paper newPaper = BeanCopierUtil.copyProperties(oldPaper, Paper.class);
|
|
|
|
- newPaper.getCourse().setId(dto.getCourse().getCourseId().toString());
|
|
|
|
- newPaper.getCourse().setOrgId(dto.getToRootOrgId().toString());
|
|
|
|
- newPaper.setOrgId(String.valueOf(dto.getToRootOrgId()));
|
|
|
|
- newPaper.setCreateTime(CommonUtils.getCurDateTime());
|
|
|
|
- newPaper.setLastModifyName(dto.getUser().getDisplayName());
|
|
|
|
- newPaper.setCreator(dto.getUser().getDisplayName());
|
|
|
|
- newPaper.setCreationBy(dto.getUser().getUserId());
|
|
|
|
- newPaper.setUpdateBy(dto.getUser().getUserId());
|
|
|
|
- newPaper.setInUse(0);
|
|
|
|
- newPaper.setId(null);
|
|
|
|
- newPaper.setSourceId(oldPaper.getId());
|
|
|
|
- return newPaper;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private String randomUUID() {
|
|
|
|
- return UUID.randomUUID().toString().replaceAll("-", "");
|
|
|
|
- }
|
|
|
|
-// private Long getCourseId(Map<String,Long> courses,String code) {
|
|
|
|
-// Long id=courses.get(code);
|
|
|
|
-// if(id==null) {
|
|
|
|
-// throw new StatusException("没有课程信息code="+code);
|
|
|
|
-// }
|
|
|
|
-// return id;
|
|
|
|
-// }
|
|
|
|
-}
|
|
|
|
|
|
+package cn.com.qmth.examcloud.core.questions.service.consumer;
|
|
|
|
+
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.Date;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+import java.util.TreeMap;
|
|
|
|
+import java.util.UUID;
|
|
|
|
+
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.base.FileConstants;
|
|
|
|
+import cn.com.qmth.examcloud.support.fss.FssFactory;
|
|
|
|
+import cn.com.qmth.examcloud.support.fss.FssHelper;
|
|
|
|
+import cn.com.qmth.examcloud.support.fss.model.FssFileInfo;
|
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.context.annotation.Scope;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
+
|
|
|
|
+import cn.com.qmth.examcloud.api.commons.security.bean.User;
|
|
|
|
+import cn.com.qmth.examcloud.commons.exception.StatusException;
|
|
|
|
+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.IoUtils;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.base.enums.PaperType;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.base.multithread.Consumer;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.CoursePropertyRepo;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.PaperDetailRepo;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.PaperDetailUnitRepo;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.PaperRepo;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.PropertyRepo;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.QuesRepo;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.CourseProperty;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.Paper;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetail;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetailUnit;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.Property;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.QuesOption;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.QuesProperty;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.Question;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.dao.entity.QuestionAudio;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.CoursePropertyService;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.PaperService;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.PropertyService;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.QuesService;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.QuestionAudioService;
|
|
|
|
+import cn.com.qmth.examcloud.core.questions.service.bean.CopyDataDto;
|
|
|
|
+import cn.com.qmth.examcloud.web.redis.RedisClient;
|
|
|
|
+
|
|
|
|
+@Scope("prototype")
|
|
|
|
+@Service
|
|
|
|
+public class CopyDataConsumer extends Consumer<CopyDataDto> {
|
|
|
|
+
|
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(CopyDataConsumer.class);
|
|
|
|
+
|
|
|
|
+ private static int cacheLockTimeout = 60 * 10;
|
|
|
|
+
|
|
|
|
+ private static String copyQuestionDataLock = "$_COPY_QUESTION_DATA_LOCK";
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private PaperRepo paperRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private CoursePropertyService coursePropertyService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private CoursePropertyRepo coursePropertyRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private PropertyService propertyService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private PropertyRepo propertyRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private PaperDetailRepo paperDetailRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private PaperDetailUnitRepo paperDetailUnitRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private QuestionAudioService questionAudioService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private PaperService paperService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private QuesRepo quesRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private QuesService quesService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private RedisClient redisClient;
|
|
|
|
+
|
|
|
|
+ @Transactional
|
|
|
|
+ @Override
|
|
|
|
+ public int consume(CopyDataDto dto) {
|
|
|
|
+ // 先处理原卷
|
|
|
|
+ disposeCourse(dto);
|
|
|
|
+ // 成卷不需要处理属性,可先清空
|
|
|
|
+ dto.setSouceIdMap(null);
|
|
|
|
+ // 处理成卷
|
|
|
|
+ dto.setPaperType(PaperType.GENERATE);
|
|
|
|
+ disposeCourse(dto);
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void disposeCourse(CopyDataDto dto) {
|
|
|
|
+ redisClient.expire(copyQuestionDataLock, cacheLockTimeout);
|
|
|
|
+
|
|
|
|
+ if (PaperType.IMPORT.equals(dto.getPaperType())) {
|
|
|
|
+ copyCourseProperty(dto);
|
|
|
|
+ }
|
|
|
|
+ List<Paper> papers = paperService.getPapersByCourse(dto.getFromRootOrgId(), dto.getCourse().getCourseCode(),
|
|
|
|
+ dto.getPaperType());
|
|
|
|
+
|
|
|
|
+ redisClient.expire(copyQuestionDataLock, cacheLockTimeout);
|
|
|
|
+
|
|
|
|
+ if (CollectionUtils.isEmpty(papers)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (PaperType.IMPORT.equals(dto.getPaperType())) {
|
|
|
|
+ fillSouceIdMap(dto);
|
|
|
|
+ }
|
|
|
|
+ for (Paper paper : papers) {
|
|
|
|
+ if (dto.getCopyAll()) {
|
|
|
|
+ clonePaper(paper, dto);
|
|
|
|
+ } else {
|
|
|
|
+ if (!paperService.existsPaperBySourceId(dto.getToRootOrgId(), dto.getCourse().getCourseCode(),
|
|
|
|
+ dto.getPaperType(), paper.getId())) {
|
|
|
|
+ clonePaper(paper, dto);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ redisClient.expire(copyQuestionDataLock, cacheLockTimeout);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void fillSouceIdMap(CopyDataDto dto) {
|
|
|
|
+ List<CourseProperty> cps = coursePropertyService.findAllByOrgIdCourseCode(dto.getToRootOrgId(),
|
|
|
|
+ dto.getCourse().getCourseCode());
|
|
|
|
+ if (CollectionUtils.isEmpty(cps)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ for (CourseProperty cp : cps) {
|
|
|
|
+ List<Property> ps = propertyService.findByOrgIdAndCoursePropertyId(dto.getToRootOrgId(), cp.getId());
|
|
|
|
+ if (CollectionUtils.isEmpty(ps)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ for (Property p : ps) {
|
|
|
|
+ dto.getSouceIdMap().put(p.getSourceId(), p);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void copyCourseProperty(CopyDataDto dto) {
|
|
|
|
+ List<CourseProperty> cps = coursePropertyService.findAllByOrgIdCourseCode(dto.getFromRootOrgId(),
|
|
|
|
+ dto.getCourse().getCourseCode());
|
|
|
|
+ if (CollectionUtils.isEmpty(cps)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ for (CourseProperty cp : cps) {
|
|
|
|
+ CourseProperty targetCourseProper = null;
|
|
|
|
+ List<CourseProperty> targetFirstPropers = coursePropertyService
|
|
|
|
+ .findByOrgIdAndCourseIdAndSourceId(dto.getToRootOrgId(), dto.getCourse().getCourseId(), cp.getId());
|
|
|
|
+ if (CollectionUtils.isEmpty(targetFirstPropers)) {
|
|
|
|
+ targetCourseProper = BeanCopierUtil.copyProperties(cp, CourseProperty.class);
|
|
|
|
+ targetCourseProper.setId(null);
|
|
|
|
+ targetCourseProper.setOrgId(dto.getToRootOrgId());
|
|
|
|
+ targetCourseProper.setCourseId(dto.getCourse().getCourseId());
|
|
|
|
+ targetCourseProper.setUpdateTime(new Date());
|
|
|
|
+ targetCourseProper.setSourceId(cp.getId());
|
|
|
|
+ coursePropertyRepo.save(targetCourseProper);
|
|
|
|
+ } else {
|
|
|
|
+ targetCourseProper = targetFirstPropers.get(0);
|
|
|
|
+ }
|
|
|
|
+ // 处理一级属性
|
|
|
|
+ List<Property> fps = propertyService.findParentProperties(cp.getId(), dto.getFromRootOrgId());
|
|
|
|
+ if (CollectionUtils.isEmpty(fps)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ List<Property> targetFps = propertyService.findParentProperties(targetCourseProper.getId(),
|
|
|
|
+ dto.getToRootOrgId());
|
|
|
|
+ int firstNum = 0;
|
|
|
|
+ if (CollectionUtils.isNotEmpty(targetFps)) {
|
|
|
|
+ firstNum = targetFps.size();
|
|
|
|
+ }
|
|
|
|
+ Map<String, Property> targetsouceIds = getSourceIds(targetFps);
|
|
|
|
+ for (Property fp : fps) {
|
|
|
|
+ Property targetFp = null;
|
|
|
|
+ if (targetsouceIds.get(fp.getId()) == null) {
|
|
|
|
+ firstNum++;
|
|
|
|
+ targetFp = BeanCopierUtil.copyProperties(fp, Property.class);
|
|
|
|
+ targetFp.setId(null);
|
|
|
|
+ targetFp.setOrgId(dto.getToRootOrgId());
|
|
|
|
+ targetFp.setCoursePropertyId(targetCourseProper.getId());
|
|
|
|
+ targetFp.setParentId(Property.ROOT_PARENT_ID);
|
|
|
|
+ targetFp.setNumber(firstNum);
|
|
|
|
+ targetFp.setSourceId(fp.getId());
|
|
|
|
+ propertyRepo.save(targetFp);
|
|
|
|
+ } else {
|
|
|
|
+ targetFp = targetsouceIds.get(fp.getId());
|
|
|
|
+ }
|
|
|
|
+ // 处理二级属性
|
|
|
|
+ List<Property> sps = propertyService.findSonProperties(fp.getId());
|
|
|
|
+ if (CollectionUtils.isEmpty(sps)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ List<Property> targetSps = propertyService.findSonProperties(targetFp.getId());
|
|
|
|
+ int secondNum = 0;
|
|
|
|
+ if (CollectionUtils.isNotEmpty(targetSps)) {
|
|
|
|
+ secondNum = targetSps.size();
|
|
|
|
+ }
|
|
|
|
+ Map<String, Property> targetSecondSouceIds = getSourceIds(targetSps);
|
|
|
|
+ for (Property sp : sps) {
|
|
|
|
+ Property targetSp = null;
|
|
|
|
+ if (targetSecondSouceIds.get(sp.getId()) == null) {
|
|
|
|
+ secondNum++;
|
|
|
|
+ targetSp = BeanCopierUtil.copyProperties(sp, Property.class);
|
|
|
|
+ targetSp.setId(null);
|
|
|
|
+ targetSp.setOrgId(dto.getToRootOrgId());
|
|
|
|
+ targetSp.setCoursePropertyId(targetCourseProper.getId());
|
|
|
|
+ targetSp.setParentId(targetFp.getId());
|
|
|
|
+ targetSp.setNumber(secondNum);
|
|
|
|
+ targetSp.setSourceId(sp.getId());
|
|
|
|
+ propertyRepo.save(targetSp);
|
|
|
|
+ } else {
|
|
|
|
+ targetFp = targetsouceIds.get(fp.getId());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Map<String, Property> getSourceIds(List<Property> targetFps) {
|
|
|
|
+ Map<String, Property> set = new HashMap<>();
|
|
|
|
+ if (CollectionUtils.isEmpty(targetFps)) {
|
|
|
|
+ return set;
|
|
|
|
+ }
|
|
|
|
+ for (Property p : targetFps) {
|
|
|
|
+ set.put(p.getSourceId(), p);
|
|
|
|
+ }
|
|
|
|
+ return set;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void clonePaper(Paper oldPaper, CopyDataDto dto) {
|
|
|
|
+ User user = dto.getUser();
|
|
|
|
+
|
|
|
|
+ if (user == null) {
|
|
|
|
+ throw new StatusException("当前用户信息不能为空!");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (user.getRootOrgId() == null) {
|
|
|
|
+ throw new StatusException("当前用户的顶级机构ID不能为空!");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 复制原试卷的所有试题信息
|
|
|
|
+ Map<PaperDetail, List<PaperDetailUnit>> detailMaps = this.copyPaperDetails(oldPaper, dto);
|
|
|
|
+ if (detailMaps == null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (PaperType.IMPORT.equals(dto.getPaperType())) {// 复制原卷才处理音频
|
|
|
|
+ // 处理试题的音频(下载上传到云存储)
|
|
|
|
+ try {
|
|
|
|
+ this.dealQuestionAudios(detailMaps, user.getDisplayName());
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new StatusException("500", "复制音频失败!", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 复制原试卷的信息
|
|
|
|
+ Paper newPaper = this.copyPaper(oldPaper, dto);
|
|
|
|
+ // 保存新试卷
|
|
|
|
+ paperRepo.save(newPaper);
|
|
|
|
+ try {
|
|
|
|
+ // 保存新试卷的所有试题信息
|
|
|
|
+ this.savePaperDetails(detailMaps, newPaper, user, dto);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new StatusException("500", "克隆试卷失败!", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void savePaperDetails(Map<PaperDetail, List<PaperDetailUnit>> detailMaps, Paper newPaper, User user,
|
|
|
|
+ CopyDataDto dto) {
|
|
|
|
+ if (StringUtils.isEmpty(newPaper.getId())) {
|
|
|
|
+ throw new StatusException("试卷保存失败!");
|
|
|
|
+ }
|
|
|
|
+ for (Map.Entry<PaperDetail, List<PaperDetailUnit>> entry : detailMaps.entrySet()) {
|
|
|
|
+ PaperDetail detail = entry.getKey();
|
|
|
|
+ detail.setPaper(newPaper);
|
|
|
|
+ }
|
|
|
|
+ // 批量保存大题
|
|
|
|
+ paperDetailRepo.saveAll(detailMaps.keySet());
|
|
|
|
+ List<PaperDetailUnit> newDetailUnits = new ArrayList<>();
|
|
|
|
+ List<Question> newQuestions = new ArrayList<>();
|
|
|
|
+ for (Map.Entry<PaperDetail, List<PaperDetailUnit>> entry : detailMaps.entrySet()) {
|
|
|
|
+ PaperDetail detail = entry.getKey();
|
|
|
|
+ List<PaperDetailUnit> detailUnits = entry.getValue();
|
|
|
|
+ for (PaperDetailUnit detailUnit : detailUnits) {
|
|
|
|
+ detailUnit.setPaper(newPaper);
|
|
|
|
+ detailUnit.setPaperDetail(detail);
|
|
|
|
+ newDetailUnits.add(detailUnit);
|
|
|
|
+ newQuestions.add(detailUnit.getQuestion());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (PaperType.IMPORT.equals(newPaper.getPaperType())) {// 复制原卷才处理
|
|
|
|
+ // 批量新增试题
|
|
|
|
+ quesRepo.saveAll(newQuestions);
|
|
|
|
+
|
|
|
|
+ for (Question question : newQuestions) {
|
|
|
|
+ dto.getSouceIdToQuestionMap().put(question.getSourceId(), 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);
|
|
|
|
+ }
|
|
|
|
+ this.updateQuestionBody(question, audioList);
|
|
|
|
+ // 如果试题存在音频,则更新试题的音频信息
|
|
|
|
+ quesRepo.save(question);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 批量保存试题单元
|
|
|
|
+ paperDetailUnitRepo.saveAll(newDetailUnits);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 更新试题题干或选项中的音频存储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);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 处理试题的音频(下载上传到云存储)
|
|
|
|
+ */
|
|
|
|
+ private void dealQuestionAudios(Map<PaperDetail, List<PaperDetailUnit>> detailMaps, String userName) {
|
|
|
|
+ String copyAudioPath = FileConstants.TEMP_FILE_EXPORT + File.separator + randomUUID();
|
|
|
|
+ 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 = randomUUID() + "_" + audio.getFileName();
|
|
|
|
+ File audioFile = new File(copyAudioPath + File.separator + newAudioFileName);
|
|
|
|
+
|
|
|
|
+ // 通用存储
|
|
|
|
+ String filePath = FssHelper.fixFilePath(audio.getFileUrl());
|
|
|
|
+ FssFactory.getInstance().readFile(filePath, audioFile);
|
|
|
|
+
|
|
|
|
+ // 重新上传新的音频文件
|
|
|
|
+ String newPath = String.format(FileConstants.RADIO_UPLOAD_PATH, newAudioFileName);
|
|
|
|
+ try {
|
|
|
|
+ // 通用存储
|
|
|
|
+ FssFileInfo result = FssFactory.getInstance().writeFile(newPath, audioFile, null);
|
|
|
|
+ audio.setFileUrl(result.getFileUrl());// 设置新路径
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new StatusException("上传音频文件失败!");
|
|
|
|
+ } finally {
|
|
|
|
+ IoUtils.removeFile(audioFile);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ IoUtils.removeFile(copyAudioDir);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 复制试卷的所有试题信息
|
|
|
|
+ */
|
|
|
|
+ private Map<PaperDetail, List<PaperDetailUnit>> copyPaperDetails(Paper oldPaper, CopyDataDto dto) {
|
|
|
|
+ // 批量查询原试卷的所有试题
|
|
|
|
+ List<PaperDetailUnit> allDetailUnits = paperDetailUnitRepo.findByPaperOrderByNumber(oldPaper);
|
|
|
|
+ if (allDetailUnits == null || allDetailUnits.size() == 0) {
|
|
|
|
+ log.warn("忽略试卷复制,原试卷的试题不存在,courseCode:" + dto.getCourse().getCourseCode() + "|paperName:"
|
|
|
|
+ + oldPaper.getName());
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ // 按大题有序封装对应的试题列表
|
|
|
|
+ Map<PaperDetail, List<PaperDetailUnit>> oldDetailMaps = new TreeMap<>();
|
|
|
|
+ for (PaperDetailUnit detailUnit : allDetailUnits) {
|
|
|
|
+ PaperDetail detail = detailUnit.getPaperDetail();
|
|
|
|
+ if (!oldDetailMaps.containsKey(detail)) {
|
|
|
|
+ oldDetailMaps.put(detail, new ArrayList<>());
|
|
|
|
+ }
|
|
|
|
+ List<PaperDetailUnit> detailUnits = oldDetailMaps.get(detail);
|
|
|
|
+ detailUnits.add(detailUnit);
|
|
|
|
+ }
|
|
|
|
+ // 开始复制
|
|
|
|
+ Map<PaperDetail, List<PaperDetailUnit>> detailMaps = new TreeMap<>();
|
|
|
|
+ for (Map.Entry<PaperDetail, List<PaperDetailUnit>> entry : oldDetailMaps.entrySet()) {
|
|
|
|
+ // 复制大题信息
|
|
|
|
+ PaperDetail oldPaperDetail = entry.getKey();
|
|
|
|
+ PaperDetail paperDetail = this.copyPaperDetail(oldPaperDetail, dto);
|
|
|
|
+ // 复制大题下的所有试题单元
|
|
|
|
+ List<PaperDetailUnit> oldDetailUnits = entry.getValue();
|
|
|
|
+ List<PaperDetailUnit> detailUnits = new ArrayList<>();
|
|
|
|
+ for (PaperDetailUnit oldDetailUnit : oldDetailUnits) {
|
|
|
|
+ PaperDetailUnit detailUnit = this.copyPaperDetailUnit(oldDetailUnit, dto);
|
|
|
|
+ detailUnits.add(detailUnit);
|
|
|
|
+ }
|
|
|
|
+ detailMaps.put(paperDetail, detailUnits);
|
|
|
|
+ }
|
|
|
|
+ return detailMaps;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 复制试题的音频
|
|
|
|
+ */
|
|
|
|
+ private QuestionAudio copyQuestionAudio(QuestionAudio oldAudio, CopyDataDto dto) {
|
|
|
|
+ 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(dto.getUser().getDisplayName());
|
|
|
|
+ audio.setOrgId(dto.getToRootOrgId());
|
|
|
|
+ audio.setCreationBy(dto.getUser().getUserId());
|
|
|
|
+ audio.setUpdateBy(dto.getUser().getUserId());
|
|
|
|
+ return audio;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 复制试题信息
|
|
|
|
+ */
|
|
|
|
+ private Question copyQuestion(Question oldQuestion, CopyDataDto dto) {
|
|
|
|
+ Question question = BeanCopierUtil.copyProperties(oldQuestion, Question.class);
|
|
|
|
+ question.setId(null);
|
|
|
|
+ question.getCourse().setId(dto.getCourse().getCourseId().toString());
|
|
|
|
+ question.getCourse().setOrgId(dto.getToRootOrgId().toString());
|
|
|
|
+ question.setOrgId(dto.getToRootOrgId().toString());
|
|
|
|
+ disposeProperty(question, dto);
|
|
|
|
+ question.setCreateTime(CommonUtils.getCurDateTime());
|
|
|
|
+ question.setUpdateTime(CommonUtils.getCurDateTime());
|
|
|
|
+ question.setPropertyGroup(null);
|
|
|
|
+ question.setCreationBy(dto.getUser().getUserId());
|
|
|
|
+ question.setUpdateBy(dto.getUser().getUserId());
|
|
|
|
+ question.setSourceId(oldQuestion.getId());
|
|
|
|
+ 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, dto);
|
|
|
|
+ question.addAudio(audio);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return question;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void disposeProperty(Question question, CopyDataDto dto) {
|
|
|
|
+ if (CollectionUtils.isNotEmpty(question.getQuesProperties())) {
|
|
|
|
+ for (QuesProperty qp : question.getQuesProperties()) {
|
|
|
|
+ if (qp != null) {
|
|
|
|
+ if (qp.getFirstProperty() != null && qp.getFirstProperty().getId() != null) {
|
|
|
|
+ Property p = dto.getSouceIdMap().get(qp.getFirstProperty().getId());
|
|
|
|
+ if (p == null) {
|
|
|
|
+ throw new StatusException("未找到试题属性 CourseCode:" + dto.getCourse().getCourseCode()
|
|
|
|
+ + " | PropertyId:" + qp.getFirstProperty().getId());
|
|
|
|
+ }
|
|
|
|
+ qp.setFirstProperty(p);
|
|
|
|
+ }
|
|
|
|
+ if (qp.getSecondProperty() != null && qp.getSecondProperty().getId() != null) {
|
|
|
|
+ Property p = dto.getSouceIdMap().get(qp.getSecondProperty().getId());
|
|
|
|
+ if (p == null) {
|
|
|
|
+ throw new StatusException("未找到试题属性 CourseCode:" + dto.getCourse().getCourseCode()
|
|
|
|
+ + " | PropertyId:" + qp.getSecondProperty().getId());
|
|
|
|
+ }
|
|
|
|
+ qp.setSecondProperty(p);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (CollectionUtils.isNotEmpty(question.getSubQuestions())) {
|
|
|
|
+ for (Question sub : question.getSubQuestions()) {
|
|
|
|
+ disposeProperty(sub, dto);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 复制试题单元信息
|
|
|
|
+ */
|
|
|
|
+ private PaperDetailUnit copyPaperDetailUnit(PaperDetailUnit oldDetailUnit, CopyDataDto dto) {
|
|
|
|
+ Question oldQuestion = oldDetailUnit.getQuestion();
|
|
|
|
+ if (oldQuestion == null) {
|
|
|
|
+ throw new StatusException("原试题详细信息不存在!");
|
|
|
|
+ }
|
|
|
|
+ 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(dto.getUser().getDisplayName());
|
|
|
|
+ detailUnit.setCreateTime(CommonUtils.getCurDateTime());
|
|
|
|
+ detailUnit.setOrgId(dto.getToRootOrgId());
|
|
|
|
+ detailUnit.setCreationBy(dto.getUser().getUserId());
|
|
|
|
+ detailUnit.setUpdateBy(dto.getUser().getUserId());
|
|
|
|
+ detailUnit.setPaper(null);
|
|
|
|
+ detailUnit.setPaperDetail(null);
|
|
|
|
+ if (PaperType.IMPORT.equals(dto.getPaperType())) {// 原卷才处理
|
|
|
|
+ // 复制试题信息
|
|
|
|
+ Question question = this.copyQuestion(oldQuestion, dto);
|
|
|
|
+ detailUnit.setQuestion(question);
|
|
|
|
+ } else {
|
|
|
|
+ String newQuestionId = dto.getSouceIdToQuestionMap().get(oldQuestion.getId());
|
|
|
|
+ if (StringUtils.isBlank(newQuestionId)) {
|
|
|
|
+ throw new StatusException("原试题信息不存在:courseCode" + dto.getCourse().getCourseCode() + "|" + "sourceId:"
|
|
|
|
+ + oldQuestion.getId());
|
|
|
|
+ }
|
|
|
|
+ Question newqs = quesService.findById(newQuestionId);
|
|
|
|
+ if (newqs == null) {
|
|
|
|
+ throw new StatusException("原试题信息未保存:courseCode" + dto.getCourse().getCourseCode() + "|" + "sourceId:"
|
|
|
|
+ + oldQuestion.getId() + " | newQuestionId:" + newQuestionId);
|
|
|
|
+ }
|
|
|
|
+ detailUnit.setQuestion(newqs);
|
|
|
|
+ }
|
|
|
|
+ return detailUnit;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 复制大题信息
|
|
|
|
+ */
|
|
|
|
+ private PaperDetail copyPaperDetail(PaperDetail oldPaperDetail, CopyDataDto dto) {
|
|
|
|
+ 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(dto.getUser().getDisplayName());
|
|
|
|
+ paperDetail.setCreateTime(CommonUtils.getCurDateTime());
|
|
|
|
+ paperDetail.setPaper(null);
|
|
|
|
+ paperDetail.setOrgId(dto.getToRootOrgId());
|
|
|
|
+ paperDetail.setCreationBy(dto.getUser().getUserId());
|
|
|
|
+ paperDetail.setUpdateBy(dto.getUser().getUserId());
|
|
|
|
+ return paperDetail;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 复制试卷信息
|
|
|
|
+ */
|
|
|
|
+ private Paper copyPaper(Paper oldPaper, CopyDataDto dto) {
|
|
|
|
+ Paper newPaper = BeanCopierUtil.copyProperties(oldPaper, Paper.class);
|
|
|
|
+ newPaper.setName(newPaper.getName() + "-" + dto.getPaperSuff());
|
|
|
|
+ newPaper.getCourse().setId(dto.getCourse().getCourseId().toString());
|
|
|
|
+ newPaper.getCourse().setOrgId(dto.getToRootOrgId().toString());
|
|
|
|
+ newPaper.setOrgId(String.valueOf(dto.getToRootOrgId()));
|
|
|
|
+ newPaper.setCreateTime(CommonUtils.getCurDateTime());
|
|
|
|
+ newPaper.setLastModifyName(dto.getUser().getDisplayName());
|
|
|
|
+ newPaper.setCreator(dto.getUser().getDisplayName());
|
|
|
|
+ newPaper.setCreationBy(dto.getUser().getUserId());
|
|
|
|
+ newPaper.setUpdateBy(dto.getUser().getUserId());
|
|
|
|
+ newPaper.setInUse(0);
|
|
|
|
+ newPaper.setId(null);
|
|
|
|
+ newPaper.setSourceId(oldPaper.getId());
|
|
|
|
+ return newPaper;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private String randomUUID() {
|
|
|
|
+ return UUID.randomUUID().toString().replaceAll("-", "");
|
|
|
|
+ }
|
|
|
|
+ // private Long getCourseId(Map<String,Long> courses,String code) {
|
|
|
|
+ // Long id=courses.get(code);
|
|
|
|
+ // if(id==null) {
|
|
|
|
+ // throw new StatusException("没有课程信息code="+code);
|
|
|
|
+ // }
|
|
|
|
+ // return id;
|
|
|
|
+ // }
|
|
|
|
+}
|