Bladeren bron

Merge branch 'dev_v2.2.1' of http://git.qmth.com.cn/wangliang/distributed-print-service into dev_v2.2.1

xiaof 3 jaren geleden
bovenliggende
commit
557a2469b9
28 gewijzigde bestanden met toevoegingen van 561 en 266 verwijderingen
  1. 8 28
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/result/TSyncExamStudentScoreResult.java
  2. 26 35
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/TSyncExamStudentScore.java
  3. 2 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/DictionaryEnum.java
  4. 42 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/ImageTrajectoryEnum.java
  5. 10 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/TSyncExamStudentScoreService.java
  6. 2 3
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/PrintCommonServiceServiceImpl.java
  7. 112 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/TSyncExamStudentScoreServiceImpl.java
  8. 3 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncScoreBatchDownloadService.java
  9. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/export/AsyncExportTaskTemplete.java
  10. 51 36
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/TaskLogicServiceImpl.java
  11. 9 9
      distributed-print-business/src/main/resources/mapper/TSyncExamStudentScoreMapper.xml
  12. 44 11
      distributed-print/src/main/java/com/qmth/distributed/print/api/SysController.java
  13. 18 56
      distributed-print/src/main/java/com/qmth/distributed/print/api/TSyncExamStudentScoreController.java
  14. 1 1
      distributed-print/src/main/resources/application-dev.properties
  15. 3 4
      distributed-print/src/test/java/com/qmth/distributed/print/SyncHelpTest.java
  16. 61 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/entity/PushUserTrack.java
  17. 1 1
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/TaskTypeEnum.java
  18. 11 5
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/userPush/SpecialPrivilegeEnum.java
  19. 16 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/mapper/PushUserTrackMapper.java
  20. 0 12
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/CallApiOrgCenterService.java
  21. 16 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/PushUserTrackService.java
  22. 0 39
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/CallApiOrgCenterServiceImpl.java
  23. 20 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/PushUserTrackServiceImpl.java
  24. 7 6
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/SysUserServiceImpl.java
  25. 43 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/sync/StmmsUtils.java
  26. 8 8
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/util/FileStoreUtil.java
  27. 41 8
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/util/HttpUtil.java
  28. 5 0
      teachcloud-common/src/main/resources/mapper/PushUserTrackMapper.xml

+ 8 - 28
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/result/TSyncExamStudentScoreResult.java

@@ -1,10 +1,12 @@
 package com.qmth.distributed.print.business.bean.result;
 
+import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import com.qmth.teachcloud.common.annotation.ExcelProperty;
 import io.swagger.annotations.ApiModelProperty;
 
+import java.io.File;
 import java.io.Serializable;
 import java.util.Objects;
 
@@ -15,6 +17,7 @@ import java.util.Objects;
  * @Author: wangliang
  * @Date: 2021/11/1
  */
+@JsonInclude(JsonInclude.Include.NON_NULL)
 public class TSyncExamStudentScoreResult implements Serializable {
 
     @ApiModelProperty(value = "主键")
@@ -36,13 +39,9 @@ public class TSyncExamStudentScoreResult implements Serializable {
     @ApiModelProperty(value = "云阅卷考试编码")
     String examCode;
 
-    @ApiModelProperty(value = "考生id")
-    @JsonSerialize(using = ToStringSerializer.class)
-    Long examStudentId;
-
     @ExcelProperty(name = "姓名", width = 30, index = 2)
     @ApiModelProperty(value = "考生姓名")
-    String examStudentName;
+    String name;
 
     @ExcelProperty(name = "学号", width = 30, index = 3)
     @ApiModelProperty(value = "学号")
@@ -107,9 +106,6 @@ public class TSyncExamStudentScoreResult implements Serializable {
     @ApiModelProperty(value = "主观题分数")
     private Double subjectiveScore;
 
-    @ApiModelProperty(value = "轨迹图是否生成,1:已生成,0:未生成")
-    private Boolean trajectory;
-
     public Long getExamId() {
         return examId;
     }
@@ -126,14 +122,6 @@ public class TSyncExamStudentScoreResult implements Serializable {
         this.examCode = examCode;
     }
 
-    public Long getExamStudentId() {
-        return examStudentId;
-    }
-
-    public void setExamStudentId(Long examStudentId) {
-        this.examStudentId = examStudentId;
-    }
-
     public String getSemesterName() {
         return semesterName;
     }
@@ -142,12 +130,12 @@ public class TSyncExamStudentScoreResult implements Serializable {
         this.semesterName = semesterName;
     }
 
-    public String getExamStudentName() {
-        return examStudentName;
+    public String getName() {
+        return name;
     }
 
-    public void setExamStudentName(String examStudentName) {
-        this.examStudentName = examStudentName;
+    public void setName(String name) {
+        this.name = name;
     }
 
     public String getStatusStr() {
@@ -325,12 +313,4 @@ public class TSyncExamStudentScoreResult implements Serializable {
     public void setSubjectiveScore(Double subjectiveScore) {
         this.subjectiveScore = subjectiveScore;
     }
-
-    public Boolean getTrajectory() {
-        return trajectory;
-    }
-
-    public void setTrajectory(Boolean trajectory) {
-        this.trajectory = trajectory;
-    }
 }

+ 26 - 35
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/TSyncExamStudentScore.java

@@ -1,10 +1,12 @@
 package com.qmth.distributed.print.business.entity;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+import java.io.File;
 import java.io.Serializable;
 
 /**
@@ -32,14 +34,6 @@ public class TSyncExamStudentScore implements Serializable {
     @JsonSerialize(using = ToStringSerializer.class)
     private Long orgId;
 
-    @ApiModelProperty(value = "学生id")
-    @JsonSerialize(using = ToStringSerializer.class)
-    private Long studentId;
-
-    @ApiModelProperty(value = "考生id")
-    @JsonSerialize(using = ToStringSerializer.class)
-    private Long examStudentId;
-
     @ApiModelProperty(value = "学期id")
     @JsonSerialize(using = ToStringSerializer.class)
     private Long semesterId;
@@ -96,9 +90,6 @@ public class TSyncExamStudentScore implements Serializable {
     @ApiModelProperty(value = "同步数据json")
     private String syncData;
 
-    @ApiModelProperty(value = "轨迹图是否生成,1:已生成,0:未生成")
-    private Boolean trajectory;
-
     @ApiModelProperty(value = "轨迹图地址")
     private String trajectoryUrls;
 
@@ -109,6 +100,30 @@ public class TSyncExamStudentScore implements Serializable {
     @ApiModelProperty(value = "创建时间")
     private Long createTime;
 
+    @ApiModelProperty(value = "轨迹图路径")
+    @TableField(exist = false)
+    private String path;
+
+    @ApiModelProperty(value = "轨迹图文件")
+    @TableField(exist = false)
+    private File trajectoryFile;
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public File getTrajectoryFile() {
+        return trajectoryFile;
+    }
+
+    public void setTrajectoryFile(File trajectoryFile) {
+        this.trajectoryFile = trajectoryFile;
+    }
+
     public Long getSemesterId() {
         return semesterId;
     }
@@ -145,22 +160,6 @@ public class TSyncExamStudentScore implements Serializable {
         this.orgId = orgId;
     }
 
-    public Long getStudentId() {
-        return studentId;
-    }
-
-    public void setStudentId(Long studentId) {
-        this.studentId = studentId;
-    }
-
-    public Long getExamStudentId() {
-        return examStudentId;
-    }
-
-    public void setExamStudentId(Long examStudentId) {
-        this.examStudentId = examStudentId;
-    }
-
     public Long getExamId() {
         return examId;
     }
@@ -297,14 +296,6 @@ public class TSyncExamStudentScore implements Serializable {
         this.syncData = syncData;
     }
 
-    public Boolean getTrajectory() {
-        return trajectory;
-    }
-
-    public void setTrajectory(Boolean trajectory) {
-        this.trajectory = trajectory;
-    }
-
     public String getTrajectoryUrls() {
         return trajectoryUrls;
     }

+ 2 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/DictionaryEnum.java

@@ -8,11 +8,11 @@ import java.util.Objects;
  * @Date: 2021-11-02
  */
 public enum DictionaryEnum {
+    SEMESTER("学期"),
     COLLEGE("学院"),
     MAJOR("专业"),
     CLAZZ("班级"),
-    STUDENT("学生"),
-    ;
+    STUDENT("学生");
     private final String desc;
 
     DictionaryEnum(String desc) {

+ 42 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/ImageTrajectoryEnum.java

@@ -0,0 +1,42 @@
+package com.qmth.distributed.print.business.enums;
+
+import java.util.Objects;
+
+/**
+ * @Description: 生成原卷动态轨迹图 enum
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/11/3
+ */
+public enum ImageTrajectoryEnum {
+
+    PREVIEW("预览"),
+
+    DOWNLOAD("下载");
+
+    private String title;
+
+    private ImageTrajectoryEnum(String title) {
+        this.title = title;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param title
+     * @return
+     */
+    public static String convertToName(String title) {
+        for (ImageTrajectoryEnum e : ImageTrajectoryEnum.values()) {
+            if (Objects.equals(title, e.getTitle())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+}

+ 10 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/TSyncExamStudentScoreService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.distributed.print.business.bean.result.TSyncExamStudentScoreResult;
 import com.qmth.distributed.print.business.entity.TSyncExamStudentScore;
+import com.qmth.distributed.print.business.enums.ImageTrajectoryEnum;
 
 import java.util.List;
 import java.util.Map;
@@ -53,4 +54,13 @@ public interface TSyncExamStudentScoreService extends IService<TSyncExamStudentS
                                                     Long majorId,
                                                     Long clazzId,
                                                     String courseCode);
+
+    /**
+     * 创建动态轨迹图
+     *
+     * @param tSyncExamStudentScore
+     * @param imageTrajectoryEnum
+     * @return
+     */
+    public TSyncExamStudentScore createImageTrajectory(TSyncExamStudentScore tSyncExamStudentScore, ImageTrajectoryEnum imageTrajectoryEnum);
 }

+ 2 - 3
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/PrintCommonServiceServiceImpl.java

@@ -1082,11 +1082,10 @@ public class PrintCommonServiceServiceImpl implements PrintCommonService {
                     .add(String.format("%02d", nowTime.getDayOfMonth()))
                     .add(File.separator).add(SystemConstant.getUuid()).add(".").add(SystemConstant.XLSX);
             jsonObject = new JSONObject();
+            String dirName = stringJoiner.toString().replaceAll("\\\\", "/");
             if (oss) {//上传至oss
-                String dirName = stringJoiner.toString().replaceAll("\\\\", "/");
                 fileStoreUtil.ossUpload(dirName, inputStream, DigestUtils.md5Hex(new ByteArrayInputStream(fos.toByteArray())), UploadFileEnum.FILE.getFssType());
                 jsonObject.put(SystemConstant.TYPE, SystemConstant.OSS);
-                jsonObject.put(SystemConstant.PATH, dirName);
             } else {
                 File finalFile = new File(stringJoiner.toString());
                 if (!finalFile.exists()) {
@@ -1095,8 +1094,8 @@ public class PrintCommonServiceServiceImpl implements PrintCommonService {
                 }
                 FileUtils.copyInputStreamToFile(inputStream, finalFile);
                 jsonObject.put(SystemConstant.TYPE, SystemConstant.LOCAL);
-                jsonObject.put(SystemConstant.PATH, stringJoiner.toString());
             }
+            jsonObject.put(SystemConstant.PATH, dirName);
             jsonObject.put(SystemConstant.UPLOAD_TYPE, UploadFileEnum.FILE);
         } catch (Exception e) {
             e.printStackTrace();

+ 112 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/TSyncExamStudentScoreServiceImpl.java

@@ -1,18 +1,33 @@
 package com.qmth.distributed.print.business.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.distributed.print.business.bean.result.TSyncExamStudentScoreResult;
 import com.qmth.distributed.print.business.entity.TSyncExamStudentScore;
+import com.qmth.distributed.print.business.enums.ImageTrajectoryEnum;
 import com.qmth.distributed.print.business.mapper.TSyncExamStudentScoreMapper;
 import com.qmth.distributed.print.business.service.TSyncExamStudentScoreService;
+import com.qmth.teachcloud.common.config.DictionaryConfig;
+import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.SysUser;
+import com.qmth.teachcloud.common.enums.UploadFileEnum;
+import com.qmth.teachcloud.common.service.TeachcloudCommonService;
+import com.qmth.teachcloud.common.util.FileStoreUtil;
+import com.qmth.teachcloud.common.util.HttpUtil;
+import com.qmth.teachcloud.common.util.ImageTrajectoryUtil;
 import com.qmth.teachcloud.common.util.ServletUtil;
+import org.apache.commons.codec.digest.DigestUtils;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.io.File;
+import java.io.FileInputStream;
+import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
+import java.util.StringJoiner;
 
 /**
  * <p>
@@ -28,6 +43,15 @@ public class TSyncExamStudentScoreServiceImpl extends ServiceImpl<TSyncExamStude
     @Resource
     TSyncExamStudentScoreMapper tSyncExamStudentScoreMapper;
 
+    @Resource
+    DictionaryConfig dictionaryConfig;
+
+    @Resource
+    FileStoreUtil fileStoreUtil;
+
+    @Resource
+    TeachcloudCommonService teachcloudCommonService;
+
     /**
      * 同步成绩查询列表
      *
@@ -60,4 +84,92 @@ public class TSyncExamStudentScoreServiceImpl extends ServiceImpl<TSyncExamStude
     public List<TSyncExamStudentScoreResult> export(Long schoolId, Long semesterId, Long orgId, Long majorId, Long clazzId, String courseCode) {
         return tSyncExamStudentScoreMapper.export(schoolId, semesterId, orgId, majorId, clazzId, courseCode);
     }
+
+    /**
+     * 创建动态轨迹图
+     *
+     * @param tSyncExamStudentScore
+     * @param imageTrajectoryEnum
+     * @return
+     */
+    @Override
+    public TSyncExamStudentScore createImageTrajectory(TSyncExamStudentScore tSyncExamStudentScore, ImageTrajectoryEnum imageTrajectoryEnum) {
+        File fileSource = null, fileTarget = null;
+        String ossType = null;
+        JSONObject jsonObject = null;
+        try {
+            StringJoiner stringJoiner = new StringJoiner("");
+            stringJoiner.add(SystemConstant.TEMP_FILES_DIR).add(File.separator);
+            if (Objects.isNull(tSyncExamStudentScore.getTrajectoryUrls())) {
+                boolean oss = dictionaryConfig.sysDomain().isOss();
+                String format = tSyncExamStudentScore.getSheetUrls().substring(tSyncExamStudentScore.getSheetUrls().lastIndexOf("."), tSyncExamStudentScore.getSheetUrls().length());
+                LocalDateTime nowTime = LocalDateTime.now();
+                StringJoiner dirJpgName = new StringJoiner("");
+                dirJpgName.add(UploadFileEnum.FILE.getTitle()).add(File.separator)
+                        .add(String.valueOf(nowTime.getYear())).add(File.separator)
+                        .add(String.format("%02d", nowTime.getMonthValue())).add(File.separator)
+                        .add(String.format("%02d", nowTime.getDayOfMonth()))
+                        .add(File.separator).add(SystemConstant.getUuid()).add(format);
+                fileSource = new File(stringJoiner.toString() + dirJpgName.toString());
+                if (!fileSource.exists()) {
+                    fileSource.getParentFile().mkdirs();
+                    fileSource.createNewFile();
+                }
+                fileSource = HttpUtil.httpDownload(tSyncExamStudentScore.getSheetUrls(), fileSource.getPath());
+
+                StringJoiner dirTargetJpgName = new StringJoiner("");
+                dirTargetJpgName.add(UploadFileEnum.FILE.getTitle()).add(File.separator)
+                        .add(String.valueOf(nowTime.getYear())).add(File.separator)
+                        .add(String.format("%02d", nowTime.getMonthValue())).add(File.separator)
+                        .add(String.format("%02d", nowTime.getDayOfMonth()))
+                        .add(File.separator).add(SystemConstant.getUuid()).add(format);
+                fileTarget = new File(stringJoiner.toString() + dirTargetJpgName.toString());
+                if (!fileTarget.exists()) {
+                    fileTarget.getParentFile().mkdirs();
+                    fileTarget.createNewFile();
+                }
+
+                ImageTrajectoryUtil.createImage(fileSource, fileTarget, 10, 10);
+                jsonObject = new JSONObject();
+                jsonObject.put(SystemConstant.UPLOAD_TYPE, UploadFileEnum.FILE);
+                if (oss) {
+                    fileStoreUtil.ossUpload(dirTargetJpgName.toString(), fileTarget, DigestUtils.md5Hex(new FileInputStream(fileTarget)), UploadFileEnum.FILE.getFssType());
+                    jsonObject.put(SystemConstant.TYPE, SystemConstant.OSS);
+                    jsonObject.put(SystemConstant.PATH, dirTargetJpgName.toString());
+                    tSyncExamStudentScore.setPath(teachcloudCommonService.filePreview(jsonObject.toJSONString()));
+                } else {
+                    jsonObject.put(SystemConstant.TYPE, SystemConstant.LOCAL);
+                    jsonObject.put(SystemConstant.PATH, dirTargetJpgName.toString());
+                    tSyncExamStudentScore.setPath(stringJoiner.toString() + dirTargetJpgName.toString());
+                }
+                tSyncExamStudentScore.setTrajectoryUrls(jsonObject.toJSONString());
+                tSyncExamStudentScore.setTrajectoryFile(fileTarget);
+            } else {
+                jsonObject = JSONObject.parseObject(tSyncExamStudentScore.getTrajectoryUrls());
+                ossType = (String) jsonObject.get(SystemConstant.TYPE);
+                if (Objects.equals(ossType, SystemConstant.OSS)) {
+                    tSyncExamStudentScore.setPath(teachcloudCommonService.filePreview(jsonObject.toJSONString()));
+                } else {
+                    tSyncExamStudentScore.setPath(stringJoiner.toString() + jsonObject.get(SystemConstant.PATH));
+                }
+            }
+            if (imageTrajectoryEnum == ImageTrajectoryEnum.DOWNLOAD && Objects.isNull(fileTarget)) {
+                ossType = (String) jsonObject.get(SystemConstant.TYPE);
+                if (Objects.equals(ossType, SystemConstant.OSS)) {
+                    fileTarget = fileStoreUtil.ossDownload(jsonObject.get(SystemConstant.PATH).toString(), stringJoiner.toString() + jsonObject.get(SystemConstant.PATH).toString(), UploadFileEnum.FILE.getFssType());
+                } else {
+                    fileTarget = new File(stringJoiner.toString() + jsonObject.get(SystemConstant.PATH).toString());
+                }
+                tSyncExamStudentScore.setTrajectoryFile(fileTarget);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            tSyncExamStudentScore.setTrajectoryUrls(null);
+        } finally {
+            if (Objects.nonNull(fileSource)) {
+                fileSource.delete();
+            }
+        }
+        return tSyncExamStudentScore;
+    }
 }

+ 3 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncScoreBatchDownloadService.java

@@ -19,6 +19,7 @@ import org.springframework.stereotype.Service;
 import java.text.MessageFormat;
 import java.util.Date;
 import java.util.Map;
+import java.util.Objects;
 import java.util.StringJoiner;
 
 /**
@@ -32,6 +33,7 @@ import java.util.StringJoiner;
 public class AsyncScoreBatchDownloadService extends AsyncExportTaskTemplete {
 
     public static final String OBJ_TITLE = "成绩轨迹";
+    public static final String BEGIN_TITLE = "->开始准备处理下载的";
     private final static Logger log = LoggerFactory.getLogger(AsyncScoreBatchDownloadService.class);
 
     @Override
@@ -45,7 +47,7 @@ public class AsyncScoreBatchDownloadService extends AsyncExportTaskTemplete {
         try {
             TaskLogicService taskLogicService = SpringContextHolder.getBean(TaskLogicService.class);
             Map<String, Object> result = taskLogicService.executeDownloadScoreLogic(map);
-            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get("count"))), FINISH_SIZE));
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}{4}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get("count"))), FINISH_SIZE, Objects.nonNull(result.get("error")) ? (String) result.get("error") : ""));
             tbTask.setResult(TaskResultEnum.SUCCESS);
         } catch (Exception e) {
             log.error("请求出错", e);

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/export/AsyncExportTaskTemplete.java

@@ -41,7 +41,7 @@ public abstract class AsyncExportTaskTemplete {
     private final static Logger log = LoggerFactory.getLogger(AsyncImportTaskTemplete.class);
     public static final String BEGIN_TITLE = "->开始准备处理导出的";
     public static final String FINISH_TITLE = "->数据处理结束,共处理了";
-    public static final String FINISH_SIZE = "条数据";
+    public static final String FINISH_SIZE = "条数据";
     public static final String EXCEPTION_TITLE = "->数据处理发生异常!";
     public static final String EXCEPTION_DATA = "错误信息:";
     public static final String TXT_PREFIX = ".txt";

+ 51 - 36
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/TaskLogicServiceImpl.java

@@ -9,6 +9,8 @@ import com.aliyun.oss.common.utils.BinaryUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.google.common.collect.Lists;
+import com.google.common.reflect.TypeToken;
+import com.google.gson.Gson;
 import com.itextpdf.text.DocumentException;
 import com.qmth.boot.api.exception.ApiException;
 import com.qmth.distributed.print.business.bean.dto.*;
@@ -1448,7 +1450,11 @@ public class TaskLogicServiceImpl implements TaskLogicService {
      * @throws Exception
      */
     @Override
+    @Transactional
     public Map<String, Object> executeDownloadScoreLogic(Map<String, Object> map) throws Exception {
+        File zipFile = null;
+        List<File> sourceFiles = null;
+        List<TSyncExamStudentScore> errorTSyncExamStudentScoreList = null;
         try {
             SysUser sysUser = (SysUser) map.get(SystemConstant.USER);
             Long semesterId = null, orgId = null, majorId = null, clazzId = null;
@@ -1461,6 +1467,8 @@ public class TaskLogicServiceImpl implements TaskLogicService {
 
             List<TSyncExamStudentScoreResult> tSyncExamStudentScoreResultList = tSyncExamStudentScoreService.export(sysUser.getSchoolId(), semesterId, orgId, majorId, clazzId, courseCode);
             if (Objects.nonNull(tSyncExamStudentScoreResultList) && tSyncExamStudentScoreResultList.size() > 0) {
+                List<TSyncExamStudentScore> tSyncExamStudentScoreList = new Gson().fromJson(JacksonUtil.parseJson(tSyncExamStudentScoreResultList), new TypeToken<List<TSyncExamStudentScore>>() {
+                }.getType());
                 LocalDateTime nowTime = LocalDateTime.now();
                 StringJoiner stringJoiner = new StringJoiner("");
                 stringJoiner.add(SystemConstant.TEMP_FILES_DIR).add(File.separator);
@@ -1470,54 +1478,61 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                         .add(String.format("%02d", nowTime.getMonthValue())).add(File.separator)
                         .add(String.format("%02d", nowTime.getDayOfMonth()))
                         .add(File.separator).add(SystemConstant.getUuid()).add(SystemConstant.ZIP_PREFIX);
-                File zipFile = new File(stringJoiner.toString() + dirZipName.toString());
-                if (!zipFile.getParentFile().exists()) {
+                zipFile = new File(stringJoiner.toString() + dirZipName.toString());
+                if (!zipFile.exists()) {
                     zipFile.getParentFile().mkdirs();
                     zipFile.createNewFile();
                 }
-                List<File> sourceFiles = new ArrayList<>();
-
-                for (TSyncExamStudentScoreResult t : tSyncExamStudentScoreResultList) {
+                sourceFiles = new ArrayList<>();
+                List<TSyncExamStudentScore> updateTSyncExamStudentScoreList = new ArrayList<>();
+                errorTSyncExamStudentScoreList = new ArrayList<>();
+                for (TSyncExamStudentScore t : tSyncExamStudentScoreList) {
+                    boolean update = Objects.isNull(t.getTrajectoryUrls()) ? true : false;
+                    t = tSyncExamStudentScoreService.createImageTrajectory(t, ImageTrajectoryEnum.DOWNLOAD);
                     if (Objects.nonNull(t.getTrajectoryUrls())) {
-                        sourceFiles.add(fileStoreUtil.ossDownload(t.getTrajectoryUrls(), stringJoiner.toString() + t.getTrajectoryUrls(), UploadFileEnum.FILE.getFssType()));
+                        sourceFiles.add(t.getTrajectoryFile());
                     } else {
-                        if (Objects.nonNull(t.getSheetUrls())) {
-                            String format = t.getSheetUrls().substring(t.getSheetUrls().lastIndexOf("."), t.getSheetUrls().length());
-                            File file = new File(t.getSheetUrls());
-                            StringJoiner dirImageName = new StringJoiner("");
-                            dirImageName.add(UploadFileEnum.FILE.getTitle()).add(File.separator);
-                            dirImageName.add(String.valueOf(nowTime.getYear())).add(File.separator)
-                                    .add(String.format("%02d", nowTime.getMonthValue())).add(File.separator)
-                                    .add(String.format("%02d", nowTime.getDayOfMonth()))
-                                    .add(File.separator).add(SystemConstant.getUuid()).add(format);
-                            File fileTarget = new File(stringJoiner.toString() + dirImageName.toString());
-                            ImageTrajectoryUtil.createImage(file, fileTarget, 10, 10);
-                            sourceFiles.add(fileTarget);
-                            fileStoreUtil.ossUpload(dirImageName.toString(), fileTarget, DigestUtils.md5Hex(new FileInputStream(fileTarget)), UploadFileEnum.FILE.getFssType());
-                            t.setTrajectoryUrls(dirImageName.toString());
-                        }
+                        errorTSyncExamStudentScoreList.add(t);
+                    }
+                    if (update || Objects.isNull(t.getTrajectoryUrls())) {
+                        updateTSyncExamStudentScoreList.add(t);
                     }
                 }
-                FileUtil.doZip(zipFile, sourceFiles);
-
-                boolean oss = (boolean) map.get(SystemConstant.OSS);
-                JSONObject jsonObject = new JSONObject();
-                if (oss) {//上传至oss
-                    fileStoreUtil.ossUpload(dirZipName.toString(), zipFile, DigestUtils.md5Hex(new FileInputStream(zipFile)), UploadFileEnum.FILE.getFssType());
-                    jsonObject.put(SystemConstant.TYPE, SystemConstant.OSS);
-                    jsonObject.put(SystemConstant.PATH, dirZipName.toString());
-                } else {
-                    jsonObject.put(SystemConstant.TYPE, SystemConstant.LOCAL);
-                    jsonObject.put(SystemConstant.PATH, stringJoiner.toString() + dirZipName.toString());
+                tSyncExamStudentScoreService.saveOrUpdateBatch(updateTSyncExamStudentScoreList);
+                if (Objects.nonNull(sourceFiles) && sourceFiles.size() > 0) {
+                    FileUtil.doZip(zipFile, sourceFiles);
+                    boolean oss = (boolean) map.get(SystemConstant.OSS);
+                    JSONObject jsonObject = new JSONObject();
+                    if (oss) {//上传至oss
+                        fileStoreUtil.ossUpload(dirZipName.toString(), zipFile, DigestUtils.md5Hex(new FileInputStream(zipFile)), UploadFileEnum.FILE.getFssType());
+                        jsonObject.put(SystemConstant.TYPE, SystemConstant.OSS);
+                        jsonObject.put(SystemConstant.PATH, dirZipName.toString());
+                    } else {
+                        jsonObject.put(SystemConstant.TYPE, SystemConstant.LOCAL);
+                        jsonObject.put(SystemConstant.PATH, stringJoiner.toString() + dirZipName.toString());
+                    }
+                    jsonObject.put(SystemConstant.UPLOAD_TYPE, UploadFileEnum.FILE);
+                    TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
+                    tbTask.setResultFilePath(jsonObject.toJSONString());
                 }
-                fileStoreUtil.ossUpload(dirZipName.toString(), zipFile, DigestUtils.md5Hex(new FileInputStream(zipFile)), UploadFileEnum.FILE.getFssType());
-                TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
-                tbTask.setResultFilePath(jsonObject.toJSONString());
             }
-            map.computeIfAbsent("count", v -> Objects.isNull(tSyncExamStudentScoreResultList) ? 0 : tSyncExamStudentScoreResultList.size());
+            List<File> finalSourceFiles = sourceFiles;
+            map.computeIfAbsent("count", v -> Objects.isNull(finalSourceFiles) ? 0 : finalSourceFiles.size());
+            if (Objects.nonNull(errorTSyncExamStudentScoreList) && errorTSyncExamStudentScoreList.size() > 0) {
+                StringJoiner stringJoiner = new StringJoiner("").add("\r\n");
+                for (TSyncExamStudentScore t : errorTSyncExamStudentScoreList) {
+                    stringJoiner.add("[").add(t.getStudentCode()).add(",").add(t.getName()).add("]\r\n");
+                }
+                List<TSyncExamStudentScore> finalErrorTSyncExamStudentScoreList = errorTSyncExamStudentScoreList;
+                map.computeIfAbsent("error", v -> "其中未下载成功数据" + finalErrorTSyncExamStudentScoreList.size() + "条:" + stringJoiner.toString());
+            }
         } catch (Exception e) {
             log.error("请求出错", e);
             e.printStackTrace();
+        } finally {
+            if (Objects.nonNull(zipFile)) {
+                zipFile.delete();
+            }
         }
         return map;
     }

+ 9 - 9
distributed-print-business/src/main/resources/mapper/TSyncExamStudentScoreMapper.xml

@@ -9,8 +9,7 @@
             bs.name as semesterName,
             tsess.exam_id as examId,
             tsess.exam_code as examCode,
-            tsess.exam_student_id as examStudentId,
-            tsess.name as examStudentName,
+            tsess.name,
             tsess.student_code as studentCode,
             so.id as orgId,
             so.name as orgName,
@@ -25,23 +24,18 @@
             tsess.subjective_score as subjectiveScore,
             tsess.sheet_urls as sheetUrls,
             tsess.status,
-            tsess.trajectory,
-            tsess.trajectory_urls as trajectoryUrls,
-            tsess.sync_data as trajectoryCoordinate,
             tsess.create_time as syncTime
-        from
-            t_sync_exam_student_score tsess
     </sql>
 
     <sql id="middleCommonSql">
         join basic_semester bs on
             bs.id = tsess.semester_id
         join basic_student bs2 on
-            bs2.id = tsess.student_id
+            bs2.student_code = tsess.student_code
         join basic_clazz bc on
             bc.id = bs2.clazz_id
         join exam_student es on
-            es.id = tsess.exam_student_id
+            es.student_code = tsess.student_code
         join basic_major bm on
             bm.id = bs2.major_id
         join sys_org so on
@@ -73,12 +67,18 @@
 
     <select id="list" resultType="com.qmth.distributed.print.business.bean.result.TSyncExamStudentScoreResult">
         <include refid="headCommonSql"/>
+        from
+        t_sync_exam_student_score tsess
         <include refid="middleCommonSql"/>
         <include refid="footCommonSql"/>
     </select>
 
     <select id="export" resultType="com.qmth.distributed.print.business.bean.result.TSyncExamStudentScoreResult">
         <include refid="headCommonSql"/>
+        ,tsess.trajectory_urls as trajectoryUrls,
+        tsess.sync_data as trajectoryCoordinate
+        from
+        t_sync_exam_student_score tsess
         <include refid="middleCommonSql"/>
         <include refid="footCommonSql"/>
     </select>

+ 44 - 11
distributed-print/src/main/java/com/qmth/distributed/print/api/SysController.java

@@ -8,8 +8,10 @@ import com.qmth.boot.api.exception.ApiException;
 import com.qmth.distributed.print.business.bean.params.LoginParam;
 import com.qmth.distributed.print.business.bean.result.DictionaryResult;
 import com.qmth.distributed.print.business.bean.result.EditResult;
+import com.qmth.distributed.print.business.entity.ExamPrintPlan;
 import com.qmth.distributed.print.business.enums.DictionaryEnum;
 import com.qmth.distributed.print.business.service.BasicVerifyCodeService;
+import com.qmth.distributed.print.business.service.ExamPrintPlanService;
 import com.qmth.distributed.print.business.service.PrintCommonService;
 import com.qmth.teachcloud.common.bean.auth.AuthBean;
 import com.qmth.teachcloud.common.bean.result.LoginResult;
@@ -75,12 +77,6 @@ public class SysController {
     @Resource
     TeachcloudCommonService teachcloudCommonService;
 
-    @Resource
-    BasicCampusService basicCampusService;
-
-    @Resource
-    BasicCourseService basicCourseService;
-
     @Resource
     SysOrgService sysOrgService;
 
@@ -93,6 +89,12 @@ public class SysController {
     @Resource
     BasicStudentService basicStudentService;
 
+    @Resource
+    BasicSemesterService basicSemesterService;
+
+    @Resource
+    ExamPrintPlanService examPrintPlanService;
+
     /**
      * 登录
      *
@@ -320,14 +322,15 @@ public class SysController {
 //    @Aac(auth = BOOL.FALSE)
     public Result getCode(@ApiParam(value = "编码类型", required = true) @RequestParam SystemCodeEnum type) {
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
-        String number = teachcloudCommonService.getSysIncrCode(type,sysUser);
+        String number = teachcloudCommonService.getSysIncrCode(type, sysUser);
         return ResultUtil.ok((Object) number);
     }
 
     @ApiOperation(value = "共用接口-查询字典")
     @RequestMapping(value = "/get_dictionary", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
-    public Result findDictionaryList(@ApiParam(value = "学院id") @RequestParam(required = false) String collegeId,
+    public Result findDictionaryList(@ApiParam(value = "学期id") @RequestParam(required = false) String semesterId,
+                                     @ApiParam(value = "学院id") @RequestParam(required = false) String collegeId,
                                      @ApiParam(value = "专业id") @RequestParam(required = false) String majorId,
                                      @ApiParam(value = "班级id") @RequestParam(required = false) String clazzId,
                                      @ApiParam(value = "学生id") @RequestParam(required = false) String studentId,
@@ -335,9 +338,9 @@ public class SysController {
         Long schoolId = SystemConstant.convertIdToLong(ServletUtil.getRequestHeaderSchoolId().toString());
         List<DictionaryResult> dictionaryResultList = new ArrayList<>();
         switch (dictionaryEnum) {
-            case COLLEGE:
-                List<SysOrg> sysOrgList = sysOrgService.list(new QueryWrapper<SysOrg>().lambda().eq(SysOrg::getSchoolId, schoolId).eq(SysOrg::getEnable, true));
-                dictionaryResultList = sysOrgList.stream().map(e -> {
+            case SEMESTER:
+                List<BasicSemester> basicSemesterList = basicSemesterService.list(new QueryWrapper<BasicSemester>().lambda().eq(BasicSemester::getSchoolId, schoolId).eq(BasicSemester::getEnable, true));
+                dictionaryResultList = basicSemesterList.stream().map(e -> {
                     DictionaryResult dictionaryResult = new DictionaryResult();
                     dictionaryResult.setId(e.getId());
                     dictionaryResult.setCode(e.getCode());
@@ -345,6 +348,35 @@ public class SysController {
                     return dictionaryResult;
                 }).collect(Collectors.toList());
                 break;
+            case COLLEGE:
+                if (Objects.nonNull(semesterId)) {
+                    QueryWrapper<ExamPrintPlan> examPrintPlanQueryWrapper = new QueryWrapper<>();
+                    examPrintPlanQueryWrapper.select(" DISTINCT org_id as orgId ")
+                            .eq("semester_id", SystemConstant.convertIdToLong(semesterId));
+                    List<ExamPrintPlan> examPrintPlanList = examPrintPlanService.list(examPrintPlanQueryWrapper);
+                    Set<Long> orgIdSet = examPrintPlanList.stream().map(s -> s.getOrgId()).collect(Collectors.toSet());
+
+                    QueryWrapper<SysOrg> sysOrgQueryWrapper = new QueryWrapper<>();
+                    sysOrgQueryWrapper.lambda().in(SysOrg::getId, orgIdSet);
+                    List<SysOrg> sysOrgList = sysOrgService.list(sysOrgQueryWrapper);
+                    dictionaryResultList = sysOrgList.stream().map(e -> {
+                        DictionaryResult dictionaryResult = new DictionaryResult();
+                        dictionaryResult.setId(e.getId());
+                        dictionaryResult.setCode(e.getCode());
+                        dictionaryResult.setName(e.getName());
+                        return dictionaryResult;
+                    }).collect(Collectors.toList());
+                } else {
+                    List<SysOrg> sysOrgList = sysOrgService.list(new QueryWrapper<SysOrg>().lambda().eq(SysOrg::getSchoolId, schoolId).eq(SysOrg::getEnable, true));
+                    dictionaryResultList = sysOrgList.stream().map(e -> {
+                        DictionaryResult dictionaryResult = new DictionaryResult();
+                        dictionaryResult.setId(e.getId());
+                        dictionaryResult.setCode(e.getCode());
+                        dictionaryResult.setName(e.getName());
+                        return dictionaryResult;
+                    }).collect(Collectors.toList());
+                }
+                break;
             case MAJOR:
                 QueryWrapper<BasicMajor> majorQueryWrapper = new QueryWrapper<>();
                 majorQueryWrapper.lambda()
@@ -408,6 +440,7 @@ public class SysController {
 
     /**
      * 获取用户阅卷角色
+     *
      * @return
      */
     @ApiOperation(value = "获取用户阅卷角色")

+ 18 - 56
distributed-print/src/main/java/com/qmth/distributed/print/api/TSyncExamStudentScoreController.java

@@ -1,7 +1,6 @@
 package com.qmth.distributed.print.api;
 
 
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.boot.api.annotation.Aac;
@@ -11,6 +10,7 @@ import com.qmth.distributed.print.business.bean.result.EditResult;
 import com.qmth.distributed.print.business.bean.result.TSyncExamStudentScoreResult;
 import com.qmth.distributed.print.business.entity.TBSyncTask;
 import com.qmth.distributed.print.business.entity.TSyncExamStudentScore;
+import com.qmth.distributed.print.business.enums.ImageTrajectoryEnum;
 import com.qmth.distributed.print.business.service.PrintCommonService;
 import com.qmth.distributed.print.business.service.TSyncExamStudentScoreService;
 import com.qmth.distributed.print.business.templete.execute.AsyncScoreBatchDownloadService;
@@ -18,18 +18,16 @@ import com.qmth.distributed.print.business.templete.execute.AsyncScoreExportServ
 import com.qmth.distributed.print.business.templete.execute.AsyncScorePushService;
 import com.qmth.teachcloud.common.config.DictionaryConfig;
 import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.entity.TBTask;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.enums.PushTypeEnum;
 import com.qmth.teachcloud.common.enums.TaskTypeEnum;
-import com.qmth.teachcloud.common.enums.UploadFileEnum;
-import com.qmth.teachcloud.common.service.TeachcloudCommonService;
-import com.qmth.teachcloud.common.util.FileStoreUtil;
-import com.qmth.teachcloud.common.util.ImageTrajectoryUtil;
 import com.qmth.teachcloud.common.util.Result;
 import com.qmth.teachcloud.common.util.ResultUtil;
+import com.qmth.teachcloud.common.util.ServletUtil;
 import io.swagger.annotations.*;
-import org.apache.commons.codec.digest.DigestUtils;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
@@ -39,13 +37,9 @@ import org.springframework.web.bind.annotation.RestController;
 import javax.annotation.Resource;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
-import java.io.File;
-import java.io.FileInputStream;
-import java.time.LocalDateTime;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
-import java.util.StringJoiner;
 
 /**
  * <p>
@@ -58,7 +52,7 @@ import java.util.StringJoiner;
 @Api(tags = "成绩归档Controller")
 @RestController
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/${prefix.url.sync}")
-@Aac(auth = BOOL.FALSE, strict = BOOL.FALSE)
+//@Aac(auth = BOOL.FALSE, strict = BOOL.FALSE)
 @Validated
 public class TSyncExamStudentScoreController {
 
@@ -80,12 +74,6 @@ public class TSyncExamStudentScoreController {
     @Resource
     AsyncScoreBatchDownloadService asyncScoreBatchDownloadService;
 
-    @Resource
-    TeachcloudCommonService teachcloudCommonService;
-
-    @Resource
-    FileStoreUtil fileStoreUtil;
-
     @ApiOperation(value = "成绩归档查询列表")
     @ApiResponses({@ApiResponse(code = 200, message = "成绩查询信息", response = TSyncExamStudentScoreResult.class)})
     @RequestMapping(value = "/score/list", method = RequestMethod.POST)
@@ -138,50 +126,24 @@ public class TSyncExamStudentScoreController {
     }
 
     @ApiOperation(value = "成绩动态轨迹图下载")
-    @ApiResponses({@ApiResponse(code = 200, message = "常规信息", response = Result.class)})
+    @ApiResponses({@ApiResponse(code = 200, message = "常规信息", response = EditResult.class)})
     @RequestMapping(value = "/score/download", method = RequestMethod.POST)
-    public Result download(@ApiParam(value = "考试id", required = true) @RequestParam String examStudentId) throws Exception {
+    @Transactional
+    public Result download(@ApiParam(value = "学号", required = true) @RequestParam String studentCode) throws Exception {
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
         QueryWrapper<TSyncExamStudentScore> tSyncExamStudentScoreQueryWrapper = new QueryWrapper<>();
-        tSyncExamStudentScoreQueryWrapper.lambda().eq(TSyncExamStudentScore::getExamStudentId, SystemConstant.convertIdToLong(examStudentId));
+        tSyncExamStudentScoreQueryWrapper.lambda().eq(TSyncExamStudentScore::getSchoolId, sysUser.getSchoolId())
+                .eq(TSyncExamStudentScore::getStudentCode, studentCode);
         TSyncExamStudentScore tSyncExamStudentScore = tSyncExamStudentScoreService.getOne(tSyncExamStudentScoreQueryWrapper);
         Optional.ofNullable(tSyncExamStudentScore).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("考生不存在"));
-
-        JSONObject jsonObject = null;
-        String path = null;
-        if (Objects.isNull(tSyncExamStudentScore.getTrajectoryUrls())) {
-            String format = tSyncExamStudentScore.getSheetUrls().substring(tSyncExamStudentScore.getSheetUrls().lastIndexOf("."), tSyncExamStudentScore.getSheetUrls().length());
-            boolean oss = dictionaryConfig.sysDomain().isOss();
-            LocalDateTime nowTime = LocalDateTime.now();
-            StringJoiner stringJoiner = new StringJoiner("");
-            stringJoiner.add(SystemConstant.TEMP_FILES_DIR).add(File.separator);
-            StringJoiner dirJpgName = new StringJoiner("");
-            dirJpgName.add(UploadFileEnum.FILE.getTitle()).add(File.separator)
-                    .add(String.valueOf(nowTime.getYear())).add(File.separator)
-                    .add(String.format("%02d", nowTime.getMonthValue())).add(File.separator)
-                    .add(String.format("%02d", nowTime.getDayOfMonth()))
-                    .add(File.separator).add(SystemConstant.getUuid()).add(format);
-            File fileTarget = new File(stringJoiner.toString() + dirJpgName.toString());
-            if (!fileTarget.exists()) {
-                fileTarget.getParentFile().mkdirs();
-                fileTarget.createNewFile();
-            }
-            File sheetFile = new File(tSyncExamStudentScore.getSheetUrls());
-            ImageTrajectoryUtil.createImage(sheetFile, fileTarget, 10, 10);
-            if (oss) {
-                fileStoreUtil.ossUpload(dirJpgName.toString(), fileTarget, DigestUtils.md5Hex(new FileInputStream(fileTarget)), UploadFileEnum.FILE.getFssType());
-                jsonObject.put(SystemConstant.TYPE, SystemConstant.OSS);
-                jsonObject.put(SystemConstant.PATH, dirJpgName.toString());
-                path = teachcloudCommonService.filePreview(dirJpgName.toString());
-            } else {
-                jsonObject.put(SystemConstant.TYPE, SystemConstant.LOCAL);
-                jsonObject.put(SystemConstant.PATH, stringJoiner.toString() + dirJpgName.toString());
-                path = stringJoiner.toString() + dirJpgName.toString();
-            }
-        } else {
-            jsonObject = JSONObject.parseObject(tSyncExamStudentScore.getTrajectoryUrls());
-            path = teachcloudCommonService.filePreview((String) jsonObject.get(SystemConstant.PATH));
+        tSyncExamStudentScore = tSyncExamStudentScoreService.createImageTrajectory(tSyncExamStudentScore, ImageTrajectoryEnum.PREVIEW);
+        boolean update = Objects.isNull(tSyncExamStudentScore.getTrajectoryUrls()) ? true : false;
+        tSyncExamStudentScore = tSyncExamStudentScoreService.createImageTrajectory(tSyncExamStudentScore, ImageTrajectoryEnum.PREVIEW);
+        Optional.ofNullable(tSyncExamStudentScore.getTrajectoryUrls()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("资源未获取到,请稍候再试"));
+        if (update || Objects.isNull(tSyncExamStudentScore.getTrajectoryUrls())) {
+            tSyncExamStudentScoreService.updateById(tSyncExamStudentScore);
         }
-        return ResultUtil.ok(new EditResult(path));
+        return ResultUtil.ok(new EditResult(tSyncExamStudentScore.getPath()));
     }
 
     @ApiOperation(value = "成绩动态轨迹图一键下载")

+ 1 - 1
distributed-print/src/main/resources/application-dev.properties

@@ -144,7 +144,7 @@ sync.config.studentScoreUrl=/api/exam/student/score
 # ͬ²½ÊÔ¾í½á¹¹
 sync.config.structureUrl=/api/exam/paper/save
 # Óû§Í¬²½
-sync.config.userSaveUrl=/api/user/save
+sync.config.userSaveUrl=/api/user/external/save
 
 
 sms.config.smsNormalCode=qmth

+ 3 - 4
distributed-print/src/test/java/com/qmth/distributed/print/SyncHelpTest.java

@@ -1,10 +1,9 @@
 package com.qmth.distributed.print;
 
 import com.qmth.teachcloud.common.bean.params.UserPushParam;
-import com.qmth.distributed.print.business.service.DataSyncService;
 import com.qmth.teachcloud.common.enums.userPush.SpecialPrivilegeEnum;
-import com.qmth.teachcloud.common.service.CallApiOrgCenterService;
 import com.qmth.teachcloud.common.service.SysUserService;
+import com.qmth.teachcloud.common.sync.StmmsUtils;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -22,7 +21,7 @@ import javax.annotation.Resource;
 public class SyncHelpTest {
 
     @Resource
-    private CallApiOrgCenterService callApiOrgCenterService;
+    private StmmsUtils stmmsUtils;
     @Resource
     private SysUserService sysUserService;
 
@@ -40,7 +39,7 @@ public class SyncHelpTest {
             }else {
                 userPushParam.setRole(SpecialPrivilegeEnum.SUBJECT_HEADER);
             }
-            callApiOrgCenterService.basicSyncUser(userPushParam,2L);
+            stmmsUtils.syncUser(userPushParam,2L);
         }
     }
 

+ 61 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/entity/PushUserTrack.java

@@ -0,0 +1,61 @@
+package com.qmth.teachcloud.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.teachcloud.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 用户推送轨迹表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2021-11-04
+ */
+@ApiModel(value = "PushUserTrack对象", description = "用户推送轨迹表")
+public class PushUserTrack extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "用户id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long userId;
+
+    @ApiModelProperty(value = "身份 SpecialPrivilegeEnum: SUBJECT_HEADER('科组长权限','SubjectHeader','S_', 4), MARKER('评卷员权限','Marker','M_', 5),")
+    private String identify;
+
+    @ApiModelProperty(value = "操作 UserPushTrackEnum: BIND('绑定') UNBIND('解绑') ")
+    private String operate;
+
+    public static long getSerialVersionUID() {
+        return serialVersionUID;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getIdentify() {
+        return identify;
+    }
+
+    public void setIdentify(String identify) {
+        this.identify = identify;
+    }
+
+    public String getOperate() {
+        return operate;
+    }
+
+    public void setOperate(String operate) {
+        this.operate = operate;
+    }
+}

+ 1 - 1
teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/TaskTypeEnum.java

@@ -41,7 +41,7 @@ public enum TaskTypeEnum {
 
     SCORE_EXPORT("成绩导出"),
 
-    SCORE_DOWNLOAD("成绩轨迹下载");
+    SCORE_DOWNLOAD("成绩轨迹下载");
 
     private String title;
 

+ 11 - 5
teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/userPush/SpecialPrivilegeEnum.java

@@ -6,21 +6,23 @@ package com.qmth.teachcloud.common.enums.userPush;
  * @Date: 2021-10-27
  */
 public enum SpecialPrivilegeEnum {
-    MARKER("评卷员权限","Marker","M_"),
-    SUBJECT_HEADER("科组长权限","SubjectHeader","S_"),
-    COMPOSITE("复合权限","Composite",null),
-    UNIDENTIFIED("无特殊权限","Unidentified",null),
+    SUBJECT_HEADER("科组长权限","SubjectHeader","S_", 4),
+    MARKER("评卷员权限","Marker","M_", 5),
+    COMPOSITE("复合权限","Composite",null, 0),
+    UNIDENTIFIED("无特殊权限","Unidentified",null, 0),
     ;
 
-    SpecialPrivilegeEnum(String title, String id, String prefix) {
+    SpecialPrivilegeEnum(String title, String id, String prefix, int value) {
         this.title = title;
         this.id = id;
         this.prefix = prefix;
+        this.value = value;
     }
 
     private final String title;
     private final String id;
     private final String prefix;
+    private final int value;
 
     public String getTitle() {
         return title;
@@ -33,4 +35,8 @@ public enum SpecialPrivilegeEnum {
     public String getPrefix() {
         return prefix;
     }
+
+    public int getValue() {
+        return value;
+    }
 }

+ 16 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/mapper/PushUserTrackMapper.java

@@ -0,0 +1,16 @@
+package com.qmth.teachcloud.common.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qmth.teachcloud.common.entity.PushUserTrack;
+
+/**
+ * <p>
+ * 用户推送轨迹表 Mapper 接口
+ * </p>
+ *
+ * @author wangliang
+ * @since 2021-11-04
+ */
+public interface PushUserTrackMapper extends BaseMapper<PushUserTrack> {
+
+}

+ 0 - 12
teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/CallApiOrgCenterService.java

@@ -1,7 +1,5 @@
 package com.qmth.teachcloud.common.service;
 
-import com.qmth.teachcloud.common.bean.params.UserPushParam;
-
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
@@ -19,14 +17,4 @@ public interface CallApiOrgCenterService {
      * @throws IOException 异常
      */
     List<Map> callOrgInfo() throws IOException;
-
-
-    /**
-     * 基础用户同步(推送)云阅卷接口
-     *
-     * @param userPushParam 用户推送参数
-     * @param schoolId 学校主键
-     * @return 是否成功
-     */
-    boolean basicSyncUser(UserPushParam userPushParam, Long schoolId) throws IllegalAccessException;
 }

+ 16 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/PushUserTrackService.java

@@ -0,0 +1,16 @@
+package com.qmth.teachcloud.common.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.teachcloud.common.entity.PushUserTrack;
+
+/**
+ * <p>
+ * 用户推送轨迹表 服务类
+ * </p>
+ *
+ * @author wangliang
+ * @since 2021-11-04
+ */
+public interface PushUserTrackService extends IService<PushUserTrack> {
+
+}

+ 0 - 39
teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/CallApiOrgCenterServiceImpl.java

@@ -1,11 +1,8 @@
 package com.qmth.teachcloud.common.service.impl;
 
-import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.qmth.boot.tools.signature.SignatureEntity;
 import com.qmth.boot.tools.signature.SignatureType;
-import com.qmth.teachcloud.common.bean.params.UserPushParam;
-import com.qmth.teachcloud.common.bean.result.DBVerifyResult;
 import com.qmth.teachcloud.common.config.DictionaryConfig;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
@@ -72,40 +69,4 @@ public class CallApiOrgCenterServiceImpl implements CallApiOrgCenterService {
         }
         return orgList;
     }
-
-
-    @Override
-    public boolean basicSyncUser(UserPushParam userPushParam, Long schoolId) throws IllegalAccessException {
-        DBVerifyResult dbVerifyResult = SystemConstant.verifyDBFields(userPushParam, userPushParam.getClass());
-        boolean result = dbVerifyResult.getStatus();
-        if (!result) {
-            log.warn(dbVerifyResult.getMessage());
-            return false;
-        }
-//        String hostUrl = dictionaryConfig.syncDataDomain().getHostUrl();
-//        String userSaveUrl = dictionaryConfig.syncDataDomain().getUserSaveUrl();
-//        String postUrl = hostUrl.concat(userSaveUrl);
-//        // 参数
-//        Map paramMap = JSON.parseObject(JSON.toJSONString(userPushParam), Map.class);
-//
-//        String httpResult = HttpKit.sendPost(postUrl, getHeaders(schoolId, userSaveUrl), paramMap, null, null, null);
-//        JSONObject jsonObject = JSONObject.parseObject(httpResult);
-//        if (jsonObject.containsKey("updateTime")) {
-//            return true;
-//        } else {
-//            log.warn("用户推送(同步)失败");
-//            return false;
-//        }
-        {
-            // 模拟云阅卷返回结果 3/5的成功率
-            int x = (int) (Math.random() * 10);
-            if (x > 0) {
-                // 失败
-                log.warn("x = " + x + ",云阅卷用户同步失败 \n" + JSON.toJSONString(userPushParam));
-                return false;
-            } else {
-                return true;
-            }
-        }
-    }
 }

+ 20 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/PushUserTrackServiceImpl.java

@@ -0,0 +1,20 @@
+package com.qmth.teachcloud.common.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.teachcloud.common.entity.PushUserTrack;
+import com.qmth.teachcloud.common.mapper.PushUserTrackMapper;
+import com.qmth.teachcloud.common.service.PushUserTrackService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 用户推送轨迹表 服务实现类
+ * </p>
+ *
+ * @author wangliang
+ * @since 2021-11-04
+ */
+@Service
+public class PushUserTrackServiceImpl extends ServiceImpl<PushUserTrackMapper, PushUserTrack> implements PushUserTrackService {
+
+}

+ 7 - 6
teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/SysUserServiceImpl.java

@@ -32,13 +32,11 @@ import com.qmth.teachcloud.common.enums.userPush.SpecialPrivilegeEnum;
 import com.qmth.teachcloud.common.enums.userPush.SyncStatusEnum;
 import com.qmth.teachcloud.common.mapper.SysUserMapper;
 import com.qmth.teachcloud.common.service.*;
+import com.qmth.teachcloud.common.sync.StmmsUtils;
 import com.qmth.teachcloud.common.util.Base64Util;
 import com.qmth.teachcloud.common.util.ResultUtil;
 import com.qmth.teachcloud.common.util.ServletUtil;
-import javassist.bytecode.stackmap.BasicBlock;
 import org.apache.commons.lang3.StringUtils;
-import org.redisson.api.ExpiredObjectListener;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Service;
@@ -109,6 +107,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Resource
     PushUserErrorService pushUserErrorService;
 
+    @Resource
+    StmmsUtils stmmsUtils;
+
 
     @Override
     public IPage<UserDto> list(String loginName, String roleId, Boolean enable, String realName, Integer pageNumber, Integer pageSize) {
@@ -934,10 +935,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
     @Transactional
     @Override
-    public boolean userPushService(List<UserPushParam> userPushParamList, SysUser requestUser) throws IllegalAccessException {
+    public boolean userPushService(List<UserPushParam> userPushParamList, SysUser requestUser) {
         boolean result = true;
         for (UserPushParam userPushParam : userPushParamList) {
-            boolean syncResult = callApiOrgCenterService.basicSyncUser(userPushParam, requestUser.getSchoolId());
+            boolean syncResult = stmmsUtils.syncUser(userPushParam, requestUser.getSchoolId());
             if (!syncResult) {
                 log.warn("-----------------------------用户同步推送失败----------------------------");
                 result = false;
@@ -1249,6 +1250,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         String code = dbUser.getCode();
         Set<Long> roleIdList = new HashSet<>(sysRoleService.getUserRoles(userId));
         PushBeforeRoleParam pushBeforeRoleParam = new PushBeforeRoleParam(null, BeforeJudgeEnum.FORBIDDEN_NECESSARY);
-        return this.analyzeUserPushSpecialPrivilege(userId, schoolId, code, null, null, roleIdList, pushBeforeRoleParam, enable);
+        return this.analyzeUserPushSpecialPrivilege(userId, schoolId, code, dbUser.getRealName(), dbUser.getPassword(), roleIdList, pushBeforeRoleParam, enable);
     }
 }

+ 43 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/sync/StmmsUtils.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.qmth.boot.tools.signature.SignatureType;
 import com.qmth.teachcloud.common.SignatureEntityTest;
 import com.qmth.teachcloud.common.bean.dto.SyncStructureData;
+import com.qmth.teachcloud.common.bean.params.UserPushParam;
 import com.qmth.teachcloud.common.config.DictionaryConfig;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.BasicSchool;
@@ -77,6 +78,48 @@ public class StmmsUtils {
         }
     }
 
+    public boolean syncUser(UserPushParam userPushParam,Long schoolId) {
+        String account = userPushParam.getAccount();
+        String name = userPushParam.getName();
+        String password = userPushParam.getPassword();
+        int roleValue = userPushParam.getRole().getValue();
+        Boolean enable = userPushParam.getEnable();
+
+
+        String hostUrl = dictionaryConfig.syncDataDomain().getHostUrl();
+        String userSaveUrl = dictionaryConfig.syncDataDomain().getUserSaveUrl();
+        String postUrl = hostUrl.concat(userSaveUrl);
+        // 参数
+        Map<String, Object> map = new HashMap<>();
+        map.put("account", validParam(account, null, true, "关联名称(唯一标识)"));
+        map.put("name", validParam(name, null, false, "名称"));
+        map.put("password", validParam(password, null, false, "密码"));
+        map.put("role", validParam(String.valueOf(roleValue), null, true, "类型:MARKER、SUBJECT_HEADER"));
+        map.put("enable", validParam(enable, true, false, "是否启用"));
+
+
+        String result = HttpKit.sendPost(postUrl, getHeaders(schoolId, userSaveUrl), map, null, null, null);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        if (jsonObject.containsKey("updateTime")) {
+            return true;
+        } else {
+            log.warn("用户推送(同步)失败");
+            return false;
+        }
+
+//        {
+//            // 模拟云阅卷返回结果 3/5的成功率
+//            int x = (int) (Math.random() * 10);
+//            if (x > 0) {
+//                // 失败
+//                log.warn("x = " + x + ",云阅卷用户同步失败 \n");
+//                return false;
+//            } else {
+//                return true;
+//            }
+//        }
+    }
+
     /**
      * 考生创建/更新接口
      *

+ 8 - 8
teachcloud-common/src/main/java/com/qmth/teachcloud/common/util/FileStoreUtil.java

@@ -5,6 +5,7 @@ import com.qmth.teachcloud.common.config.DictionaryConfig;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.enums.UploadFileEnum;
 import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -122,7 +123,6 @@ public class FileStoreUtil {
         } else {
             throw ExceptionResultEnum.ERROR.exception("文件存储store类型不存在");
         }
-
         return server + "/" + objectPath;
     }
 
@@ -148,15 +148,15 @@ public class FileStoreUtil {
      */
     private File saveLocal(InputStream inputStream, String dirPath) throws IOException {
         File desFile = new File(dirPath);
-        if (!desFile.getParentFile().exists()) {
+        if (!desFile.exists()) {
             desFile.getParentFile().mkdirs(); //目标文件目录不存在的话需要创建目录
+            desFile.createNewFile();
         }
-        byte[] bytes = new byte[1024]; // 开辟一个拷贝缓冲区
-        try (OutputStream outputStream = new FileOutputStream(desFile)) {
-            int length;
-            while ((length = inputStream.read(bytes)) != -1) { //当读到尽头后,返回值为-1这个时候停止输出,拷贝结束
-                outputStream.write(bytes, 0, length);
-            }
+        if (desFile.length() > 0) {
+            return desFile;
+        }
+        try {
+            FileUtils.copyInputStreamToFile(inputStream, desFile);
             return desFile;
         } finally {
             if (inputStream != null) {

+ 41 - 8
teachcloud-common/src/main/java/com/qmth/teachcloud/common/util/HttpUtil.java

@@ -1,9 +1,13 @@
 package com.qmth.teachcloud.common.util;
 
 import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import org.apache.commons.io.FileUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.entity.StringEntity;
@@ -15,16 +19,10 @@ import org.apache.tomcat.util.http.fileupload.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
+import java.io.*;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 
 /**
  * @Description: http util
@@ -153,4 +151,39 @@ public class HttpUtil {
         }
         return in;
     }
+
+    /**
+     * 根据url下载文件,保存到filePath中
+     *
+     * @param url
+     * @param filePath
+     * @return
+     */
+    public static File httpDownload(String url, String filePath) throws IOException {
+        InputStream is = null;
+        File file = null;
+        try {
+            HttpClient client = HttpClients.createDefault();
+            HttpGet httpget = new HttpGet(url);
+            HttpResponse response = client.execute(httpget);
+
+            HttpEntity entity = response.getEntity();
+            is = entity.getContent();
+
+            Optional.ofNullable(is).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("所在路径不存在"));
+            file = new File(filePath);
+            if (!file.exists()) {
+                file.getParentFile().mkdirs();
+                file.createNewFile();
+            }
+            FileUtils.copyInputStreamToFile(is, file);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (Objects.nonNull(is)) {
+                is.close();
+            }
+        }
+        return file;
+    }
 }

+ 5 - 0
teachcloud-common/src/main/resources/mapper/PushUserTrackMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qmth.teachcloud.common.mapper.PushUserTrackMapper">
+
+</mapper>