فهرست منبع

图片导出(原图、水印图)

xiaof 4 سال پیش
والد
کامیت
5909fedfb9

+ 7 - 0
stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/service/WorkService.java

@@ -1,5 +1,6 @@
 package cn.com.qmth.stmms.ms.admin.service;
 
+import cn.com.qmth.stmms.ms.admin.utils.BultInAccountUtil;
 import cn.com.qmth.stmms.ms.commons.config.ImageConfig;
 import cn.com.qmth.stmms.ms.core.cache.ParamCache;
 import cn.com.qmth.stmms.ms.core.domain.Level;
@@ -41,6 +42,9 @@ public class WorkService {
     @Resource
     ImageConfig imageConfig;
 
+    @Autowired
+    BultInAccountUtil bultInAccountUtil;
+
     /**
      * 删除评卷工作
      *
@@ -103,6 +107,9 @@ public class WorkService {
         Level K = new Level(work.getId(), "K", 44, 0, Level.LevelType.ADMITED, 40);
         List<Level> levels = Arrays.asList(A, B, C, D, E, F, G, H, I, J, K);
         levelRepo.save(levels);
+
+        //生成内置账号
+        bultInAccountUtil.createAccout();
     }
 
 }

+ 219 - 12
stmms-ms-collect/src/main/java/cn/com/qmth/stmms/ms/collect/api/CollectApi.java

@@ -13,6 +13,7 @@ import cn.com.qmth.stmms.ms.commons.constant.SystemConstant;
 import cn.com.qmth.stmms.ms.commons.utils.CommandUtil;
 import cn.com.qmth.stmms.ms.commons.utils.FileUtil;
 import cn.com.qmth.stmms.ms.commons.utils.MD5Util;
+import cn.com.qmth.stmms.ms.commons.utils.SqlUtil;
 import cn.com.qmth.stmms.ms.commons.utils.image.ImageCompression;
 import cn.com.qmth.stmms.ms.core.cache.ParamCache;
 import cn.com.qmth.stmms.ms.core.domain.*;
@@ -21,12 +22,16 @@ import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
 import cn.com.qmth.stmms.ms.core.domain.user.Role;
 import cn.com.qmth.stmms.ms.core.repository.*;
 import cn.com.qmth.stmms.ms.core.vo.Subject;
+import net.coobird.thumbnailator.Thumbnails;
+import net.coobird.thumbnailator.geometry.Positions;
 import net.sf.json.JSONObject;
 import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang.StringUtils;
 import org.assertj.core.util.Strings;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.util.FileCopyUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
@@ -35,11 +40,14 @@ import javax.annotation.Resource;
 import javax.imageio.ImageIO;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.awt.*;
 import java.awt.image.BufferedImage;
 import java.io.*;
 import java.security.MessageDigest;
 import java.text.SimpleDateFormat;
+import java.util.List;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
@@ -75,6 +83,9 @@ public class CollectApi {
     @Autowired
     private LevelRepo levelRepo;
 
+    @Autowired
+    private PaperRepo paperRepo;
+
     @Autowired
     private SystemConfig systemConfig;
 
@@ -87,6 +98,12 @@ public class CollectApi {
     @Resource
     AliYunOssConfig aliYunOssConfig;
 
+    @Autowired
+    SqlUtil sqlUtil;
+
+    @Autowired
+    JdbcTemplate jdbcTemplate;
+
     @RequestMapping("user/login")
     public LoginDTO login(@RequestParam String loginname, @RequestParam String password) throws Exception {
         LoginDTO loginDTO = null;
@@ -105,7 +122,7 @@ public class CollectApi {
             if (Objects.isNull(markUser)) {
                 throw new RuntimeException("账号不存在");
             }
-            if(!markUser.isEnabled()){
+            if (!markUser.isEnabled()) {
                 throw new RuntimeException("账号已禁用");
             }
             //不是采集员账号
@@ -124,7 +141,7 @@ public class CollectApi {
             loginDTO.setUserId(markUser.getId());
             loginDTO.setExamId(activeWork.getId());
             loginDTO.setExamName(activeWork.getName());
-            loginDTO.setImageEnc(ParamCache.paramMap.get(activeWork.getId()).getImageEncrypt()  == 1);
+            loginDTO.setImageEnc(ParamCache.paramMap.get(activeWork.getId()).getImageEncrypt() == 1);
         }
         List<CollectSubjectDTO> collectSubjectDTOs = new ArrayList<>();
         activeWork.getSubjects().forEach(s -> {
@@ -216,12 +233,12 @@ public class CollectApi {
         List<CollectStuDTO> list = new ArrayList<>();
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
 //        for (CollectStuDTO dto : uploadStudentArray) {
-            Student student = studentRepo.findByWorkIdAndRelateExamNumberAndTest(activeWork.getId(), dto.getExamNumber(), String.valueOf(TrialEnum.DEFAULT.getId()));
-            if (!dto.isAbsent()) {
-                dataUploadService.savePaper(student, subject, dto.isManual());
-            }
-            dto.setUploadTime(sdf.format(new Date()));
-            list.add(dto);
+        Student student = studentRepo.findByWorkIdAndRelateExamNumberAndTest(activeWork.getId(), dto.getExamNumber(), String.valueOf(TrialEnum.DEFAULT.getId()));
+        if (!dto.isAbsent()) {
+            dataUploadService.savePaper(student, subject, dto.isManual());
+        }
+        dto.setUploadTime(sdf.format(new Date()));
+        list.add(dto);
 //        }
         return list;
     }
@@ -520,7 +537,7 @@ public class CollectApi {
         }
         String fileName = student.getExamNumber();
         //0:随机码 1:考号
-        if(ParamCache.paramMap.get(student.getWorkId()).getNameRule() == 1){
+        if (ParamCache.paramMap.get(student.getWorkId()).getNameRule() == 1) {
 //            fileName = DigestUtils.md5Hex(subject.name() + fileName);
             fileName = MD5Util.getImageRuleMd5(workId, subject.ordinal(), student.getAreaCode(), student.getExamNumber(), student.getId());
         }
@@ -577,7 +594,7 @@ public class CollectApi {
         }
         String fileName = student.getExamNumber();
         //0:随机码 1:考号
-        if(ParamCache.paramMap.get(student.getWorkId()).getNameRule() == 1){
+        if (ParamCache.paramMap.get(student.getWorkId()).getNameRule() == 1) {
 //            fileName = DigestUtils.md5Hex(subject.name() + fileName);
             fileName = MD5Util.getImageRuleMd5(student.getWorkId(), subject.ordinal(), student.getAreaCode(), student.getExamNumber(), student.getId());
         }
@@ -690,13 +707,203 @@ public class CollectApi {
 
     /**
      * 查询档位
+     *
      * @param workId
      * @return
      */
     @RequestMapping(value = "level/{workId}", method = RequestMethod.GET)
     public List<String> updateConfig(@PathVariable Long workId) {
-         List<Level> levels = levelRepo.findByWorkId(workId);
-         List<String> codes = levels.stream().map(m-> m.getCode()).collect(Collectors.toList());
+        List<Level> levels = levelRepo.findByWorkId(workId);
+        List<String> codes = levels.stream().map(m -> m.getCode()).collect(Collectors.toList());
         return codes;
     }
+
+
+    /**
+     * 导出图片
+     *
+     * @param imageType
+     * @param areaId
+     * @param school
+     * @param examRoom
+     * @param subject
+     * @param nameRule   1:考号+姓名,2:流水号
+     * @param startScore
+     * @param endScore
+     * @param request
+     * @param response
+     * @return
+     * @throws IOException
+     */
+    @RequestMapping(value = "file/image/export", method = {RequestMethod.GET})
+    public String imageExamNumberExport(@RequestParam Long workId,
+                                        @RequestParam String imageType,
+                                        @RequestParam Long areaId,
+                                        @RequestParam String school,
+                                        @RequestParam String examRoom,
+                                        @RequestParam String subject,
+                                        @RequestParam String nameRule,
+                                        @RequestParam Integer startScore,
+                                        @RequestParam Integer endScore,
+                                        HttpServletRequest request,
+                                        HttpServletResponse response) throws IOException {
+        if (StringUtils.isBlank(imageType)) {
+            throw new RuntimeException("请选择图片类型");
+        }
+        if (StringUtils.isBlank(subject)) {
+            throw new RuntimeException("请选择科目");
+        }
+        if (StringUtils.isBlank(nameRule)) {
+            throw new RuntimeException("请选择命名规则");
+        }
+
+        InputStream inputStream = null;
+        OutputStream outputStream = null;
+        int count = 0;
+        try {
+            //首先根据workId和阶段去查所有试卷
+            StringBuffer sql = new StringBuffer();
+            sql.append("SELECT s.id studentId,s.name studentName, p.work_id workId, p.subject, p.area_code areaCode, p.exam_number examNumber, 0+cast(p.score as char) as score FROM paper p LEFT JOIN student s ON p.work_id = s.work_id AND p.exam_number = s.exam_number WHERE p.score is not null and p.work_id = ").append(workId).append(" AND p.subject = '").append(subject).append("'");
+            if (areaId != null) {
+                sql.append(" and p.area_code = ").append(areaId);
+            }
+            if (StringUtils.isNotBlank(school)) {
+                sql.append(" and s.school = '").append(school).append("'");
+            }
+            if (StringUtils.isNotBlank(examRoom)) {
+                sql.append(" and s.exam_room = '").append(examRoom).append("'");
+            }
+            if (startScore != null) {
+                sql.append(" and p.score > ").append(startScore);
+            }
+            if (startScore != null) {
+                sql.append(" and p.score < ").append(endScore);
+            }
+            List<Map<String, Object>> paperList = jdbcTemplate.queryForList(sql.toString());
+            AtomicInteger atomicInteger = new AtomicInteger(0);
+            for (Map map : paperList) {
+                Long studentId = Long.valueOf(map.get("studentId").toString());
+                String studentName = map.get("studentName").toString();
+                String subject0 = map.get("subject").toString();
+                Subject subject1 = Subject.valueOf(subject0);
+                String areaCode = map.get("areaCode").toString();
+                String examNumber = map.get("examNumber").toString();
+                Double score = Double.parseDouble(map.get("score").toString());
+
+                String fileName = examNumber;
+                //图片加密、命名规则为随机码的,都是需要md5
+                if (ParamCache.paramMap.get(workId).getNameRule() == 1 || ParamCache.paramMap.get(workId).getImageEncrypt() == 1) {
+                    fileName = MD5Util.getImageRuleMd5(workId, subject1.ordinal(), areaCode, examNumber, studentId);
+                }
+                String path = systemConfig.getSheetDir() + File.separator + workId + File.separator + subject1
+                        + File.separator + areaCode;
+                File file = new File(path + File.separator + fileName + ".jpg");
+                //todo  图片存放路径要改 2020-08-08
+                String exportDir = systemConfig.getLocalhostPath() + File.separator + "export" + File.separator + workId + File.separator + subject
+                        + File.separator + areaCode;
+                //原图或者水印图
+                if (Objects.equals("1", imageType)) {
+                    exportDir = exportDir + File.separator + "sheet";
+                } else if (Objects.equals("2", imageType)) {
+                    exportDir = exportDir + File.separator + "watermark";
+                }
+                File out = new File(exportDir);
+                if (!out.exists()) {
+                    out.mkdirs();
+                }
+                //输出命名
+                String outFileName;
+                if (Objects.equals("1", nameRule)) {
+                    StringJoiner sj = new StringJoiner("-");
+                    sj.add(examNumber).add(studentName);
+                    outFileName = sj.toString();
+                } else if (Objects.equals("2", nameRule)) {
+                    outFileName = String.valueOf(atomicInteger.incrementAndGet());
+                } else {
+                    throw new RuntimeException("命名参数有误");
+                }
+                File expFile = new File(exportDir + File.separator + outFileName + ".jpg");
+                //水印图片
+                if (Objects.equals("1", imageType)) {
+                    //读取指定路径下面的文件
+                    inputStream = new FileInputStream(file);
+                    outputStream = new FileOutputStream(expFile);
+                    if (ParamCache.paramMap.get(workId).getImageEncrypt() == 1) {
+                        outputStream = SystemConstant.writeStream(inputStream, outputStream);
+                    } else {
+                        outputStream = SystemConstant.writeStreamFomal(inputStream, outputStream);
+                    }
+                    inputStream.close();
+                    outputStream.flush();
+                    outputStream.close();
+                }
+                if (Objects.equals("2", imageType)) {
+                    //生成分数水印图片
+                    BufferedImage watermarkImage = createWaterImage(score.intValue() + "分");
+                    Thumbnails.of(file).scale(0.8).watermark(Positions.BOTTOM_CENTER, watermarkImage, 1f).toFile(expFile);
+                }
+                count++;
+
+                LOGGER.info("studentId:{},subjdect:{},md5:{}", studentId, subject1, fileName);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            //强制将缓存区的数据进行输出
+            if (Objects.nonNull(outputStream)) {
+                outputStream.flush();
+                //关流
+                outputStream.close();
+            }
+            if (Objects.nonNull(inputStream)) {
+                inputStream.close();
+            }
+        }
+        return "导出照片成功,共导出了" + count + "张照片";
+    }
+
+
+    /**
+     * 生成分数水印图片
+     * @param str
+     * @return
+     */
+    public static BufferedImage createWaterImage(String str) {
+        try {
+            int width = 220;
+            int height = 220;
+            Font font = new Font("宋体", Font.BOLD, 100);
+            //创建BufferedImage对象
+            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+            //在背景图片中添加入需要写入的信息,
+            Graphics2D g = image.createGraphics();
+
+            //设置透明  end
+            g.setBackground(Color.WHITE);
+            g.clearRect(0, 0, width, height);
+            g.setPaint(new Color(255, 0, 0, 0));      //设置背景颜色
+            g.fillRect(0, 0, width, height);  //填充颜色
+
+            //设置透明  start
+            image = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
+            g = image.createGraphics();
+
+            //设置字体颜色
+            g.setColor(Color.red);
+            g.setFont(font);
+            g.drawString(str, 0, 100);
+            g.dispose();
+            return image;
+        } catch (Exception e) {
+            throw new RuntimeException("生成分数水印失败");
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        String msg1 = "90分";
+        BufferedImage bi = createWaterImage(msg1);
+        // 输出png图片
+        ImageIO.write(bi, "png", new File("D:\\company\\qmth\\bat-pro\\msyj-202008\\export\\result.png"));
+    }
+
 }

+ 1 - 1
stmms-ms-commons/src/main/java/cn/com/qmth/stmms/ms/commons/config/MultipartConfig.java

@@ -8,7 +8,7 @@ import org.springframework.context.annotation.Configuration;
 import javax.servlet.MultipartConfigElement;
 import java.io.File;
 
-@Configuration
+//@Configuration
 public class MultipartConfig {
     @Value("${sys.config.locationTempDir}")
     private String locationTemp;

+ 18 - 0
stmms-ms-commons/src/main/java/cn/com/qmth/stmms/ms/commons/constant/SystemConstant.java

@@ -44,4 +44,22 @@ public class SystemConstant {
         }
         return outputStream;
     }
+
+    /**
+     * 流写入
+     *
+     * @param inputStream
+     * @param outputStream
+     * @return
+     * @throws IOException
+     */
+    public static OutputStream writeStreamFomal(InputStream inputStream, OutputStream outputStream) throws IOException {
+        int index = 0;
+        byte[] bytes = new byte[1024 * 8];
+        while ((index = inputStream.read(bytes)) != -1) {
+            //将字节数组的数据全部写入到输出流中
+            outputStream.write(bytes, 0, index);
+        }
+        return outputStream;
+    }
 }

+ 1 - 4
stmms-ms-main/src/main/java/cn/com/qmth/stmms/ms/StartRunning.java

@@ -32,8 +32,7 @@ public class StartRunning implements CommandLineRunner {
     @Autowired
     RandomUtil randomUtil;
 
-    @Autowired
-    BultInAccountUtil bultInAccountUtil;
+
 
     @Override
     public void run(String... args) {
@@ -44,8 +43,6 @@ public class StartRunning implements CommandLineRunner {
         } else {
             randomUtil.getRandom(work.getId(), false);
         }
-        //生成内置账号
-        bultInAccountUtil.createAccout();
         LOGGER.info("服务器启动时执行 end");
     }
 }