deason před 5 roky
rodič
revize
c9edcec37d

+ 70 - 42
examcloud-core-questions-service/src/main/java/cn/com/qmth/examcloud/core/questions/service/impl/PaperServiceImpl.java

@@ -1,6 +1,7 @@
 package cn.com.qmth.examcloud.core.questions.service.impl;
 
 import cn.com.qmth.examcloud.api.commons.security.bean.User;
+import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
 import cn.com.qmth.examcloud.commons.util.JsonUtil;
@@ -48,10 +49,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.Assert;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
+import java.io.*;
 import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
 import java.util.*;
@@ -126,6 +124,8 @@ public class PaperServiceImpl implements PaperService {
     @Autowired
     private CourseService courseService;
 
+    private Random random = new Random();
+
     public static final String TEMP_FILE_EXP = "docxExport/";
 
     /**
@@ -1148,16 +1148,19 @@ public class PaperServiceImpl implements PaperService {
             //判断文件大小
             long fileSize = file.getSize();
             int size = Integer.parseInt(upYunProperty.getAudioMaxsize());
-            if (fileSize > size * 1048576) {
-                throw new IllegalArgumentException("音频文件大小超过5M,不能上传");
+            if (fileSize > (size * 1048576L)) {
+                throw new StatusException("400", "音频文件过大,限制5M内!");
             }
 
             //根据试卷查询所有的小题,根据文件名匹配出当前小题ID
             String numbers[] = file.getOriginalFilename().split("_");
+            if (numbers.length < 3) {
+                throw new StatusException("400", "音频文件命名格式错误!");
+            }
 
             PaperDetailUnit unit = paperDetailUnitRepo.findByPaperAndNumber(paper, Integer.valueOf(numbers[0]));
             if (unit == null || unit.getQuestion() == null) {
-                throw new IllegalArgumentException("音频文件大小超过5M,不能上传");
+                throw new StatusException("400", "对应试题不存在!");
             }
 
             Question question = unit.getQuestion();
@@ -1178,36 +1181,53 @@ public class PaperServiceImpl implements PaperService {
      * 上传音频文件至又拍云
      */
     private void uploadAudioFile(String paperId, String questionId, MultipartFile file, User user) {
+        //文件夹不存在则新建
+        final String mp3DirectoryPath = TEMP_FILE_EXP + File.separator + paperId;
+        File mp3Directory = new File(mp3DirectoryPath);
+        if (!mp3Directory.exists()) {
+            mp3Directory.mkdirs();
+        }
+
+        //文件名包含随机数,防止缓存
+        int randomNumber = random.nextInt(1000);
+        final String mp3FileName = questionId + "_" + randomNumber + "_" + file.getOriginalFilename();
+        File mp3File = new File(mp3DirectoryPath + File.separator + mp3FileName);
+
+        FileOutputStream outputStream = null;
         try {
-            String mp3DirectoryPath = TEMP_FILE_EXP + File.separator + paperId;
-            //新建文件夹
-            File mp3Directory = new File(mp3DirectoryPath);
-            if (!mp3Directory.exists()) {
-                mp3Directory.mkdirs();
+            outputStream = new FileOutputStream(mp3File);
+        } catch (FileNotFoundException e) {
+            log.error(e.getMessage(), e);
+            throw new StatusException("500", "音频文件处理失败!");
+        } finally {
+            try {
+                if (outputStream != null) {
+                    outputStream.close();
+                }
+            } catch (IOException e) {
+                //ignore
             }
-            byte[] bufs = new byte[1024 * 4];
-            //使用随机数,防止缓存
-            Random random = new Random();
-            int randomNumber = random.nextInt(1000);
-            String mp3FileNameString = questionId + "_" + randomNumber + "_" + file.getOriginalFilename();
-            File mp3File = new File(mp3DirectoryPath + File.separator + mp3FileNameString);
-            FileOutputStream outputStream = new FileOutputStream(mp3File);
-            BufferedInputStream bis = new BufferedInputStream(file.getInputStream(), 1024 * 10);
-            int read = 0;
-            while ((read = bis.read(bufs, 0, 1024 * 4)) != -1) {
-                outputStream.write(bufs, 0, read);
+        }
+
+        try (InputStream is = file.getInputStream();
+             BufferedInputStream bis = new BufferedInputStream(is, 1024 * 10);) {
+            int read;
+            byte[] bytes = new byte[1024 * 4];
+            while ((read = bis.read(bytes, 0, 1024 * 4)) != -1) {
+                outputStream.write(bytes, 0, read);
             }
-            bis.close();
-            outputStream.flush();
-            outputStream.close();
+
             //上传到又拍云
             UpYun upYun = new UpYun(upYunProperty.getBucketName(), upYunProperty.getUserName(), upYunProperty.getPassword());
-            upYun.writeFile(upYunProperty.getRadioUploadPath() + mp3FileNameString, mp3File, true);
+            upYun.writeFile(upYunProperty.getRadioUploadPath() + mp3FileName, mp3File, true);
             mp3File.delete();
+
             //保存记录
-            questionAudioService.saveQuestionAudio(new QuestionAudio(questionId, file.getOriginalFilename(), upYunProperty.getRadioUploadPath() + mp3FileNameString), user);
-        } catch (IOException e) {
+            QuestionAudio audio = new QuestionAudio(questionId, file.getOriginalFilename(), upYunProperty.getRadioUploadPath() + mp3FileName);
+            questionAudioService.saveQuestionAudio(audio, user);
+        } catch (Exception e) {
             log.error(e.getMessage(), e);
+            throw new StatusException("500", "音频文件保存失败!");
         }
     }
 
@@ -1222,20 +1242,28 @@ public class PaperServiceImpl implements PaperService {
 
         Question question = Model.of(quesRepo.findById(questionAudio.getQuestionId()));
 
+        //正则匹配音频标签
+        Pattern audioPattern = Pattern.compile(String.format("<a.*name=\"%s\"></a>", fileName));
         final String audioTag = String.format("<a id=\"%s\" name=\"%s\"></a>", questionAudio.getId(), fileName);
-        String numbers[] = fileName.split("_");
 
+        String numbers[] = fileName.split("_");
         if (numbers[1].equals("1")) {
+            //处理题干
             String quesBody = question.getQuesBody();
-            if (!quesBody.contains(audioTag)) {
-                int lastTagIndex = quesBody.lastIndexOf("</p>");
-                if (lastTagIndex > 0) {
-                    question.setQuesBody(quesBody.substring(0, lastTagIndex) + audioTag + "</p>");
+            if (StringUtils.isBlank(quesBody)) {
+                question.setQuesBody("<p>" + audioTag + "</p>");
+            } else {
+                Matcher matcher = audioPattern.matcher(quesBody);
+                if (matcher.find()) {
+                    //已存在音频标签则直接替换
+                    question.setQuesBody(matcher.replaceAll(audioTag));
                 } else {
-                    question.setQuesBody(quesBody + audioTag);
+                    //不存在音频标签则添加
+                    question.setQuesBody(quesBody + "<p>" + audioTag + "</p>");
                 }
             }
         } else {
+            //处理选项
             for (QuesOption quesOption : question.getQuesOptions()) {
                 Integer optNumber = CommonUtils.characterToNumber(numbers[2]);
                 if (!quesOption.getNumber().equals(optNumber)) {
@@ -1248,13 +1276,13 @@ public class PaperServiceImpl implements PaperService {
                     continue;
                 }
 
-                if (!optionBody.contains(audioTag)) {
-                    int lastTagIndex = optionBody.lastIndexOf("</p>");
-                    if (lastTagIndex > 0) {
-                        quesOption.setOptionBody(optionBody.substring(0, lastTagIndex) + audioTag + "</p>");
-                    } else {
-                        quesOption.setOptionBody(optionBody + audioTag);
-                    }
+                Matcher matcher = audioPattern.matcher(optionBody);
+                if (matcher.find()) {
+                    //已存在音频标签则直接替换
+                    quesOption.setOptionBody(matcher.replaceAll(audioTag));
+                } else {
+                    //不存在音频标签则添加
+                    quesOption.setOptionBody(optionBody + "<p>" + audioTag + "</p>");
                 }
             }
         }