|
@@ -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);
|