浏览代码

采集端图片下载接口开发,多工作同时阅卷功能修复

xiaof 4 年之前
父节点
当前提交
b88b59d588

+ 2 - 1
stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/api/WorkApi.java

@@ -83,6 +83,8 @@ public class WorkApi {
     @RequestMapping(method = RequestMethod.POST)
     public void create(@RequestBody Work work) {
         workService.save(work);
+        //生成随机数
+        randomUtil.getRandom(work.getId(), false);
     }
 
     /**
@@ -116,7 +118,6 @@ public class WorkApi {
             w.setActive(false);
             if (w.getId().equals(workId)) {
                 w.setActive(true);
-                randomUtil.getRandom(w.getId(), false);
             }
         }
         workRepo.save(works);

+ 255 - 3
stmms-ms-collect/src/main/java/cn/com/qmth/stmms/ms/collect/api/CollectApi.java

@@ -39,6 +39,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.awt.*;
 import java.awt.image.BufferedImage;
 import java.io.*;
+import java.net.URLEncoder;
 import java.security.MessageDigest;
 import java.text.SimpleDateFormat;
 import java.util.List;
@@ -241,14 +242,14 @@ public class CollectApi {
     @CrossOrigin(maxAge = 3600) //支持跨域
     @RequestMapping(value = "upload/student/{subjectId}", method = RequestMethod.POST)
     public CollectStuDTO saveStudent(HttpServletRequest request, @PathVariable Integer subjectId,
-                                           CollectStuDTO dto) throws Exception {
+                                     CollectStuDTO dto) throws Exception {
         Subject subject = Subject.values()[subjectId - 1];
         Work activeWork = workRepo.findByActiveTrue();
         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()));
-        Paper paper=null;
+        Paper paper = null;
         if (!dto.isAbsent()) {
             paper = dataUploadService.savePaper(student, subject, dto.isManual(), dto.getLevel());
         }
@@ -261,7 +262,7 @@ public class CollectApi {
             }
         }
         dto.setUploadTime(sdf.format(new Date()));
-        if(paper != null){
+        if (paper != null) {
             dto.setPaperId(paper.getId());
         }
         return dto;
@@ -1168,6 +1169,257 @@ public class CollectApi {
         return stringJoiner.toString();
     }
 
+    //客户端图片导出,查询需要导出试卷
+    @RequestMapping("/file/image/getExportData")
+    public List<Map<String, Object>> getExportData(@RequestParam Long workId,
+                                                   @RequestParam String imageType,
+                                                   @RequestParam(required = false) Integer startScore,
+                                                   @RequestParam(required = false) Integer endScore) {
+        StringBuffer sql = new StringBuffer();
+        sql.append("SELECT s.id studentId,s.name studentName,s.school, 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);
+        if (startScore != null && endScore != null) {
+            sql.append(" and p.score >= ").append(startScore);
+            sql.append(" and p.score <= ").append(endScore);
+        }
+        if (startScore != null && endScore == null) {
+            sql.append(" and p.score = ").append(startScore);
+        }
+        if (startScore == null && endScore != null) {
+            sql.append(" and p.score = ").append(endScore);
+        }
+        List<Map<String, Object>> paperList = jdbcTemplate.queryForList(sql.toString());
+        //图片后缀
+        String suffix = ".jpg";
+        String dir,localUrl;
+        if (Objects.equals("1", imageType)) {
+            dir = systemConfig.getSheetDir();
+            localUrl = imageServerConfig.getImageServer() + "/sheet";
+        } else if (Objects.equals("2", imageType)) {
+            dir = systemConfig.getImageDir();
+            localUrl = imageServerConfig.getImageServer() + "/images";
+        } else {
+            throw new RuntimeException("图片类型有误");
+        }
+        if(paperList != null && paperList.size() >0){
+            paperList.stream().map(m->{
+                Long studentId = Long.valueOf(m.get("studentId").toString());
+                String subject = m.get("subject").toString();
+                Subject subject1 = Subject.valueOf(subject);
+                String areaCode = m.get("areaCode").toString();
+                String examNumber = m.get("examNumber").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 filePath = null;
+                if (imageServerConfig.isAliyunOss()) {
+                    StringJoiner ossPath = new StringJoiner("/").add(aliYunOssConfig.getUrl()).add(imageServerConfig.getDir()).add(dir.replace("\\", "/")).add(String.valueOf(workId)).add(subject).add(areaCode);
+                    filePath = ossPath.toString().concat("/").concat(fileName + suffix);
+                } else {
+                    String path = localUrl + File.separator + workId + File.separator + subject1 + File.separator + areaCode;
+                    filePath = path + File.separator + fileName + suffix;
+                }
+                //oss或者本地图片访问路径
+                m.put("url", filePath);
+                return m;
+            }).collect(Collectors.toList());
+
+        }
+        return paperList;
+    }
+
+    //客户端图片导出,单个导出
+    @RequestMapping("/file/image/exportScorePicturesFromCollect")
+    public void getExportData(@RequestParam Long workId,
+                              @RequestParam String imageType,
+                              @RequestParam String isWatermark,
+                              @RequestParam String nameRule,
+                              @RequestParam Long studentId,
+                              @RequestParam String studentName,
+                              @RequestParam String subject,
+                              @RequestParam String areaCode,
+                              @RequestParam String examNumber,
+                              @RequestParam Double score,
+                              @RequestParam Integer idx,
+                              HttpServletRequest request,
+                              HttpServletResponse response) {
+        //图片后缀
+        String suffix = ".jpg";
+
+        try {
+            if (StringUtils.isBlank(imageType)) {
+                throw new RuntimeException("请选择图片类型");
+            }
+            if (StringUtils.isBlank(nameRule)) {
+                throw new RuntimeException("请选择命名规则");
+            }
+
+            InputStream inputStream = null;
+            OutputStream outputStream = null;
+            long start = System.currentTimeMillis();
+            try {
+                Subject subject1 = Subject.valueOf(subject);
+
+                //默认命名为考号
+                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);
+                }
+
+                //组装导出目录
+                StringJoiner expSj = new StringJoiner(File.separator);
+                expSj.add(systemConfig.getLocalhostPath()).add("image-export");
+                //原图或者裁切图
+                String imageTypeStr = Objects.equals("1", imageType) ? "sheet" : Objects.equals("2", imageType) ? "images" : "default";
+                //是否水印
+                String waterTypeStr = Objects.equals("1", isWatermark) ? "y" : Objects.equals("0", isWatermark) ? "n" : "default";
+                expSj.add(imageTypeStr.concat("-").concat(waterTypeStr));
+                LOGGER.info("【{},{}】开始导出,参数:图片类型:{},是否有水印:{},命名规则:{}", examNumber, studentName, imageTypeStr, waterTypeStr, Objects.equals(nameRule, "1") ? "考号+姓名" : "流水号");
+                File out = new File(expSj.toString());
+                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(idx);
+                } else {
+                    throw new RuntimeException("命名参数有误");
+                }
+
+                String dir;
+                if (Objects.equals("1", imageType)) {
+                    dir = systemConfig.getSheetDir();
+
+                } else if (Objects.equals("2", imageType)) {
+                    dir = systemConfig.getImageDir();
+                } else {
+                    throw new RuntimeException("图片类型有误");
+                }
+
+                String outFile = expSj.toString() + File.separator + outFileName + suffix;
+                File expFile = null;
+                if (imageServerConfig.isAliyunOss()) {
+                    StringJoiner ossSavePath = new StringJoiner("/").add(imageServerConfig.getDir()).add(dir.replace("\\", "/")).add(String.valueOf(workId)).add(subject).add(areaCode);
+                    String saveFileName = fileName + suffix;
+                    String saveFile = ossSavePath.toString().concat("/").concat(saveFileName);
+                    if (Objects.equals("0", isWatermark)) {
+                        expFile = ossUtil.ossDownload(saveFile, outFile);
+                    }
+                    //下载临时原图
+                    if (Objects.equals("1", isWatermark)) {
+                        long s1 = System.currentTimeMillis();
+                        LOGGER.info("【{},{}】下载临时原图开始", examNumber, studentName);
+                        String outSheetFile = expSj.toString() + File.separator + outFileName + "_" + start + suffix;
+                        File sheetFileTemp = ossUtil.ossDownload(saveFile, outSheetFile);
+                        long s2 = System.currentTimeMillis();
+                        LOGGER.info("【{},{}】下载临时原图结束,总耗时:{}秒", examNumber, studentName, (s2 - s1) / 1000);
+                        expFile = new File(outFile);
+                        //生成分数水印图片
+                        long s3 = System.currentTimeMillis();
+                        LOGGER.info("【{},{}】加水印开始,总耗时:{}秒", examNumber, studentName, (s3 - s2) / 1000);
+                        BufferedImage watermarkImage = createWaterImage(score.intValue() + "分");
+                        Thumbnails.of(sheetFileTemp).scale(1).watermark(Positions.BOTTOM_CENTER, watermarkImage, 1f).toFile(expFile);
+                        long s4 = System.currentTimeMillis();
+                        LOGGER.info("【{},{}】加水印结束,总耗时:{}秒", examNumber, studentName, (s4 - s3) / 1000);
+                        sheetFileTemp.delete();
+                    }
+                } else {
+                    String path = dir + File.separator + workId + File.separator + subject1 + File.separator + areaCode;
+                    File file = new File(path + File.separator + fileName + suffix);
+                    expFile = new File(outFile);
+                    if (Objects.equals("0", isWatermark)) {
+                        //读取指定路径下面的文件
+                        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("1", isWatermark)) {
+                        //生成分数水印图片
+                        BufferedImage watermarkImage = createWaterImage(score.intValue() + "分");
+                        Thumbnails.of(file).scale(1).watermark(Positions.BOTTOM_CENTER, watermarkImage, 1f).toFile(expFile);
+                    }
+                }
+                //返回
+                exportImage(outFileName + suffix, expFile, response, true);
+                long end = System.currentTimeMillis();
+                LOGGER.info("【{},{}】结束导出,总耗时:{}秒", examNumber, studentName, (end - start) / 1000);
+            } catch (Exception e) {
+                e.printStackTrace();
+                LOGGER.info("导出失败:{}", e.getMessage());
+            } finally {
+                try {
+                    //强制将缓存区的数据进行输出
+                    if (Objects.nonNull(outputStream)) {
+                        outputStream.flush();
+                        //关流
+                        outputStream.close();
+                    }
+                    if (Objects.nonNull(inputStream)) {
+                        inputStream.close();
+                    }
+
+                } catch (Exception e) {
+
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    public static void exportImage(String fileName, File file, HttpServletResponse response, boolean isDeleteLocal) {
+        try {
+            try {
+                if (!file.exists()) {
+                    response.sendError(404, "File not found!");
+                }
+
+                BufferedInputStream br = new BufferedInputStream(new FileInputStream(file));
+                byte[] buf = new byte[1024];
+                int len = 0;
+
+                String fName = new String(fileName.getBytes(), "ISO-8859-1");
+
+                response.reset();
+                response.setContentType("image/jpeg");
+                response.setHeader("Content-Disposition", "attachment; filename=" + fName);
+
+                OutputStream outStream = response.getOutputStream();
+
+                while ((len = br.read(buf)) > 0) {
+                    outStream.write(buf, 0, len);
+                }
+
+                br.close();
+                outStream.close();
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                if(isDeleteLocal){
+                    file.delete();
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
     public static void main(String[] args) throws IOException {
         String msg1 = "90分";
         BufferedImage bi = createWaterImage(msg1);

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

@@ -13,6 +13,7 @@ import org.springframework.boot.CommandLineRunner;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -37,11 +38,16 @@ public class StartRunning implements CommandLineRunner {
     @Override
     public void run(String... args) {
         LOGGER.info("服务器启动时执行 start");
-        Work work = workRepo.findByActiveTrue();
+        /*Work work = workRepo.findByActiveTrue();
         if (Objects.isNull(work)) {
             LOGGER.info("没有创建工作区");
         } else {
             randomUtil.getRandom(work.getId(), false);
+        }*/
+        //对所有工作都生成随机数
+        List<Work> works = workRepo.findAll();
+        for (Work work : works) {
+            randomUtil.getRandom(work.getId(), false);
         }
         LOGGER.info("服务器启动时执行 end");
     }