Selaa lähdekoodia

美术阅卷10月新增需求-图片加密优化

wangliang 5 vuotta sitten
vanhempi
commit
6bc140197b

+ 145 - 65
stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/service/DataUploadService.java

@@ -3,6 +3,8 @@ package cn.com.qmth.stmms.ms.admin.service;
 import cn.com.qmth.stmms.ms.admin.dto.StudentDTO;
 import cn.com.qmth.stmms.ms.commons.config.ImageCompressionConfig;
 import cn.com.qmth.stmms.ms.commons.config.SystemConfig;
+import cn.com.qmth.stmms.ms.commons.constant.SystemConstant;
+import cn.com.qmth.stmms.ms.commons.utils.MD5Util;
 import cn.com.qmth.stmms.ms.commons.utils.RandomUtil;
 import cn.com.qmth.stmms.ms.commons.utils.excel.ExcelError;
 import cn.com.qmth.stmms.ms.commons.utils.excel.ExcelReader;
@@ -17,6 +19,7 @@ import cn.com.qmth.stmms.ms.core.repository.PaperRepo;
 import cn.com.qmth.stmms.ms.core.repository.StudentRepo;
 import cn.com.qmth.stmms.ms.core.vo.Subject;
 import org.apache.commons.codec.digest.DigestUtils;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -35,6 +38,7 @@ import java.util.Random;
  */
 @Service
 public class DataUploadService {
+    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DataUploadService.class);
 
     @Autowired
     private StudentRepo studentRepo;
@@ -54,6 +58,8 @@ public class DataUploadService {
     @Autowired
     private MarkTaskRepo markTaskRepo;
 
+    File srcFile = new File("/Users/king/stmms-ms/static/images/6/SM/1/1901040150.jpg"); //初始文件
+
     /**
      * 上传考生试卷数据
      *
@@ -65,72 +71,121 @@ public class DataUploadService {
      */
     @Transactional
     public void uploadPaper(Long studentId, Subject subject, InputStream in, boolean isManual) throws Exception {
-        Student student = studentRepo.findOne(studentId);
-        String savePath = systemConfig.getImageDir() + File.separator + student.getWorkId() + File.separator + subject
-                + File.separator + student.getAreaCode();
-        File out = new File(savePath);
-        if (!out.exists()) {
-            out.mkdirs();
-        }
-        File outFile = new File(savePath + File.separator + student.getExamNumber() + ".jpg");
-        if (!outFile.exists()) {
-            outFile.createNewFile();
-        }
-        OutputStream output = new FileOutputStream(outFile);
-        byte[] buffer = new byte[in.available()];
-        in.read(buffer);
-        output.write(buffer);
-        output.close();
+        long start = System.currentTimeMillis();
+        LOGGER.info("准备生成裁切原图和缩略图:{}", start);
+        OutputStream outputStream = null;
+        OutputStream outputStreamTemp = null;
+        try {
+            Student student = studentRepo.findOne(studentId);
+//            Subject subject = Subject.values()[subjectId - 1];
+            //保存裁切原图+文件名加密
+            String imageDir = systemConfig.getImageDir() + File.separator + student.getWorkId() + File.separator + subject
+                    + File.separator + student.getAreaCode();
+            File out = new File(imageDir);
+            if (!out.exists()) {
+                out.mkdirs();
+            }
 
-        // 生成缩略图
-        String thumbDir = systemConfig.getThumbDir() + File.separator + student.getWorkId() + File.separator + subject
-                + File.separator + student.getAreaCode();
-        File thumb = new File(thumbDir);
-        if (!thumb.exists()) {
-            thumb.mkdirs();
-        }
-        BufferedImage bufferedImage = ImageCompression.compress(outFile, compressionConfig);
-        String thumbFileName = thumbDir + File.separator + student.getExamNumber() + ".jpg";
-        ImageIO.write(bufferedImage, "jpg", new File(thumbFileName));
+            String imageMd5 = MD5Util.getImageRuleMd5(student.getWorkId(), subject.ordinal(), student.getAreaCode(), student.getExamNumber(), student.getId());
+            File imageFile = new File(imageDir + File.separator + imageMd5 + ".jpg");
+            File imageFileTemp = new File(imageDir + File.separator + imageMd5 + "temp.jpg");
+            LOGGER.info("image存放目录:{}", imageFile.getPath());
+            outputStream = new FileOutputStream(imageFile);
+            outputStreamTemp = new FileOutputStream(imageFileTemp);
+            int index = 0;
+            byte[] bytes = new byte[1024];
+            byte[] bytesEnc = new byte[1024];
+            while ((index = in.read(bytes)) != -1) {
+                //将字节数组的数据全部写入到输出流中
+                for (int i = 0; i < index; i++) {
+                    //通过异或运算加密
+                    bytesEnc[i] = (byte) (bytes[i] ^ SystemConstant.SECRET_KEY);
+                }
+                outputStream.write(bytesEnc, 0, index);
+                outputStreamTemp.write(bytes, 0, index);
+            }
+
+            //生成缩略图
+            String thumbDir = systemConfig.getThumbDir() + File.separator + student.getWorkId() + File.separator + subject
+                    + File.separator + student.getAreaCode();
+            File thumb = new File(thumbDir);
+            if (!thumb.exists()) {
+                thumb.mkdirs();
+            }
 
-        Paper exist = paperRepo.findByWorkIdAndSubjectAndExamNumber(student.getWorkId(), subject,
-                student.getExamNumber());
+            BufferedImage bufferedImage = ImageCompression.compress(imageFileTemp, compressionConfig);
+            File thumbFile = new File(thumbDir + File.separator + imageMd5 + ".jpg");
+//            File thumbFileTemp = new File(thumbDir + File.separator + imageMd5 + "temp.jpg");
+            LOGGER.info("thumb存放目录:{}", thumbFile.getPath());
+            outputStream = new FileOutputStream(thumbFile);
+//            outputStreamTemp = new FileOutputStream(thumbFileTemp);
+//            ImageIO.write(bufferedImage, "jpg", outputStreamTemp);
+            ByteArrayOutputStream os = new ByteArrayOutputStream();
+            ImageIO.write(bufferedImage, "gif", os);
+            in = new ByteArrayInputStream(os.toByteArray());
 
-        FileInputStream sheetIn = new FileInputStream(savePath + File.separator + student.getExamNumber() + ".jpg");
-        FileInputStream slicein = new FileInputStream(thumbFileName);
-        String sheetMD5 = DigestUtils.md5Hex(sheetIn);
-        String sliceMD5 = DigestUtils.md5Hex(slicein);
-        sheetIn.close();
-        slicein.close();
-        if (exist != null) {
-            exist.setManual(isManual);
-            exist.setUploadedOn(new Date());
-            exist.setSheetMD5(sheetMD5);
-            exist.setSliceMD5(sliceMD5);
-            paperRepo.save(exist);
-        } else {
-            ExamQuestion examQuestion = examQuestionRepo.findByWorkIdAndSubjectAndAreaCode(student.getWorkId(), subject,
-                    student.getAreaCode());
-            Long random = getRandom(student.getWorkId(), student.getExamNumber());
-            Paper paper = new Paper(student.getWorkId(), null, subject, examQuestion, student, false, random);
-            paper.setSheetMD5(sheetMD5);
-            paper.setSliceMD5(sliceMD5);
-            paperRepo.save(paper);
-            // 更新科目上传状态
-            /**
-             * Long count =
-             * paperRepo.countByWorkIdAndExamNumber(student.getWorkId(),student.
-             * getExamNumber()); if(count == Subject.values().length){
-             * student.setUpload(true); studentRepo.save(student); }
-             */
-            synchronized (this) {
-                String uploadStatus = student.getUploadStatus();
-                String replace = subject.toString() + ":1";
-                String regx = subject.toString() + ":[0-1]";
-                String newStatus = uploadStatus.replaceFirst(regx, replace);
-                student.setUploadStatus(newStatus);
-                student.setAbsent(false);
-                studentRepo.save(student);
+            //原图删除
+            imageFileTemp.delete();
+//            inputStream = PictureUtil.getInput(thumbFileTemp);
+            //缩略图删除
+//            thumbFileTemp.delete();
+            writeStream(in, outputStream);
+            long end = System.currentTimeMillis();
+            LOGGER.info("生成原图和缩略图耗时:{}", (end - start) / 1000 + "s");
+
+            Paper exist = paperRepo.findByWorkIdAndSubjectAndExamNumber(student.getWorkId(), subject,
+                    student.getExamNumber());
+
+            FileInputStream sheetIn = new FileInputStream(imageFile.getPath());
+            FileInputStream slicein = new FileInputStream(thumbFile.getPath());
+            String sheetMD5 = DigestUtils.md5Hex(sheetIn);
+            String sliceMD5 = DigestUtils.md5Hex(slicein);
+            sheetIn.close();
+            slicein.close();
+            if (exist != null) {
+                exist.setManual(isManual);
+                exist.setUploadedOn(new Date());
+                exist.setSheetMD5(sheetMD5);
+                exist.setSliceMD5(sliceMD5);
+                paperRepo.save(exist);
+            } else {
+                ExamQuestion examQuestion = examQuestionRepo.findByWorkIdAndSubjectAndAreaCode(student.getWorkId(), subject,
+                        student.getAreaCode());
+                Long random = getRandom(student.getWorkId(), student.getExamNumber());
+                Paper paper = new Paper(student.getWorkId(), null, subject, examQuestion, student, false, random);
+                paper.setSheetMD5(sheetMD5);
+                paper.setSliceMD5(sliceMD5);
+                paperRepo.save(paper);
+                // 更新科目上传状态
+                /**
+                 * Long count =
+                 * paperRepo.countByWorkIdAndExamNumber(student.getWorkId(),student.
+                 * getExamNumber()); if(count == Subject.values().length){
+                 * student.setUpload(true); studentRepo.save(student); }
+                 */
+                synchronized (this) {
+                    String uploadStatus = student.getUploadStatus();
+                    String replace = subject.toString() + ":1";
+                    String regx = subject.toString() + ":[0-1]";
+                    String newStatus = uploadStatus.replaceFirst(regx, replace);
+                    student.setUploadStatus(newStatus);
+                    student.setAbsent(false);
+                    studentRepo.save(student);
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (Objects.nonNull(in)) {
+                in.close();
+            }
+            if (Objects.nonNull(outputStream)) {
+                outputStream.flush();
+                outputStream.close();
+            }
+            if (Objects.nonNull(outputStreamTemp)) {
+                outputStreamTemp.flush();
+                outputStreamTemp.close();
             }
         }
     }
@@ -227,10 +282,12 @@ public class DataUploadService {
         }
         paper.setUploadedOn(new Date());
         paper.setManual(isManual);
+
+        String imageMd5 = MD5Util.getImageRuleMd5(student.getWorkId(), subject.ordinal(), student.getAreaCode(), student.getExamNumber(), student.getId());
         String sheetPath = systemConfig.getSheetDir() + File.separator + student.getWorkId() + File.separator + subject
-                + File.separator + student.getAreaCode() + File.separator + student.getExamNumber() + ".jpg";
+                + File.separator + student.getAreaCode() + File.separator + imageMd5 + ".jpg";
         String slicePath = systemConfig.getImageDir() + File.separator + student.getWorkId() + File.separator + subject
-                + File.separator + student.getAreaCode() + File.separator + student.getExamNumber() + ".jpg";
+                + File.separator + student.getAreaCode() + File.separator + imageMd5 + ".jpg";
         FileInputStream sheetIn = new FileInputStream(sheetPath);
         FileInputStream slicein = new FileInputStream(slicePath);
         String sheetMD5 = DigestUtils.md5Hex(sheetIn);
@@ -301,4 +358,27 @@ public class DataUploadService {
         }
         return true;
     }
+
+    /**
+     * 流写入
+     *
+     * @param inputStream
+     * @param outputStream
+     * @return
+     * @throws IOException
+     */
+    public OutputStream writeStream(InputStream inputStream, OutputStream outputStream) throws IOException {
+        int index = 0;
+        byte[] bytes = new byte[1024];
+        byte[] bytesEnc = new byte[1024];
+        while ((index = inputStream.read(bytes)) != -1) {
+            //将字节数组的数据全部写入到输出流中
+            for (int i = 0; i < index; i++) {
+                //通过异或运算加密
+                bytesEnc[i] = (byte) (bytes[i] ^ SystemConstant.SECRET_KEY);
+            }
+            outputStream.write(bytesEnc, 0, index);
+        }
+        return outputStream;
+    }
 }

+ 4 - 25
stmms-ms-collect/src/main/java/cn/com/qmth/stmms/ms/collect/api/CollectApi.java

@@ -64,6 +64,7 @@ public class CollectApi {
     @Autowired
     private ImageCompressionConfig compressionConfig;
 
+
     @Autowired
     private PaperRepo paperRepo;
 
@@ -174,7 +175,7 @@ public class CollectApi {
                 out.mkdirs();
             }
 
-            String imageMd5 = getImageRuleMd5(workId, subject.ordinal(), student.getAreaCode(), student.getExamNumber(), student.getId());
+            String imageMd5 = MD5Util.getImageRuleMd5(workId, subject.ordinal(), student.getAreaCode(), student.getExamNumber(), student.getId());
             File sheetFile = new File(sheetDir + File.separator + imageMd5 + ".jpg");
             LOGGER.info("sheet存放目录:{}", sheetFile.getPath());
             outputStream = new FileOutputStream(sheetFile);
@@ -233,7 +234,7 @@ public class CollectApi {
                 out.mkdirs();
             }
 
-            String imageMd5 = getImageRuleMd5(workId, subject.ordinal(), student.getAreaCode(), student.getExamNumber(), student.getId());
+            String imageMd5 = MD5Util.getImageRuleMd5(workId, subject.ordinal(), student.getAreaCode(), student.getExamNumber(), student.getId());
             File imageFile = new File(imageDir + File.separator + imageMd5 + ".jpg");
             File imageFileTemp = new File(imageDir + File.separator + imageMd5 + "temp.jpg");
             LOGGER.info("image存放目录:{}", imageFile.getPath());
@@ -349,7 +350,7 @@ public class CollectApi {
                             + File.separator + student.getAreaCode();
                     break;
             }
-            String md5 = getImageRuleMd5(workId, subject.ordinal(), student.getAreaCode(), student.getExamNumber(), student.getId());
+            String md5 = MD5Util.getImageRuleMd5(workId, subject.ordinal(), student.getAreaCode(), student.getExamNumber(), student.getId());
             File file = new File(path + File.separator + md5 + ".jpg");
             //读取指定路径下面的文件
             inputStream = new FileInputStream(file);
@@ -471,28 +472,6 @@ public class CollectApi {
         return true;
     }
 
-    /**
-     * 生成图片md5规则
-     *
-     * @param workId
-     * @param subjectId
-     * @param areaCode
-     * @param examNumber
-     * @param studentId
-     * @return
-     */
-    public String getImageRuleMd5(Long workId, int subjectId, String areaCode, String examNumber, Long studentId) {
-        //暂不用Aes解密,因为没用到反解
-        StringBuffer stringBuffer = new StringBuffer(String.valueOf(workId)).append(subjectId).append(areaCode).append(examNumber).append(studentId);
-        String rule = stringBuffer.toString();
-        LOGGER.info("rule:{},length:{}", rule, rule.length());
-        if (rule.length() < 16) {
-            rule = String.format("%016d", Long.parseLong(rule));
-            LOGGER.info("rule补零后:{},length:{}", rule, rule.length());
-        }
-        return MD5Util.encoder(rule);
-    }
-
     /**
      * 流写入
      *

+ 22 - 0
stmms-ms-commons/src/main/java/cn/com/qmth/stmms/ms/commons/utils/MD5Util.java

@@ -49,4 +49,26 @@ public class MD5Util {
         }
         return false;
     }
+
+    /**
+     * 生成图片md5规则
+     *
+     * @param workId
+     * @param subjectId
+     * @param areaCode
+     * @param examNumber
+     * @param studentId
+     * @return
+     */
+    public static String getImageRuleMd5(Long workId, int subjectId, String areaCode, String examNumber, Long studentId) {
+        //暂不用Aes解密,因为没用到反解
+        StringBuffer stringBuffer = new StringBuffer(String.valueOf(workId)).append(subjectId).append(areaCode).append(examNumber).append(studentId);
+        String rule = stringBuffer.toString();
+        LOGGER.info("rule:{},length:{}", rule, rule.length());
+        if (rule.length() < 16) {
+            rule = String.format("%016d", Long.parseLong(rule));
+            LOGGER.info("rule补零后:{},length:{}", rule, rule.length());
+        }
+        return encoder(rule);
+    }
 }