Bladeren bron

新增武汉大学-whu分支

wangliang 2 jaren geleden
bovenliggende
commit
1600ca7e68
93 gewijzigde bestanden met toevoegingen van 9872 en 0 verwijderingen
  1. 33 0
      eds-common/.gitignore
  2. 157 0
      eds-common/pom.xml
  3. 22 0
      eds-common/src/main/java/com/qmth/eds/common/annotation/ApiJsonObject.java
  4. 28 0
      eds-common/src/main/java/com/qmth/eds/common/annotation/ApiJsonProperty.java
  5. 100 0
      eds-common/src/main/java/com/qmth/eds/common/base/BaseEntity.java
  6. 64 0
      eds-common/src/main/java/com/qmth/eds/common/base/BaseListPage.java
  7. 54 0
      eds-common/src/main/java/com/qmth/eds/common/base/BasePage.java
  8. 44 0
      eds-common/src/main/java/com/qmth/eds/common/base/CustomBaseMapper.java
  9. 32 0
      eds-common/src/main/java/com/qmth/eds/common/base/CustomizedSqlInjector.java
  10. 63 0
      eds-common/src/main/java/com/qmth/eds/common/base/method/InsertBatch.java
  11. 85 0
      eds-common/src/main/java/com/qmth/eds/common/base/method/InsertOrUpdateBath.java
  12. 30 0
      eds-common/src/main/java/com/qmth/eds/common/base/method/UpdateBatch.java
  13. 69 0
      eds-common/src/main/java/com/qmth/eds/common/contant/SpringContextHolder.java
  14. 258 0
      eds-common/src/main/java/com/qmth/eds/common/contant/SystemConstant.java
  15. 69 0
      eds-common/src/main/java/com/qmth/eds/common/domain/CloudMarkingDomain.java
  16. 26 0
      eds-common/src/main/java/com/qmth/eds/common/domain/FssLocalFileDomain.java
  17. 34 0
      eds-common/src/main/java/com/qmth/eds/common/domain/FssPrivateDomain.java
  18. 34 0
      eds-common/src/main/java/com/qmth/eds/common/domain/FssPublicDomain.java
  19. 23 0
      eds-common/src/main/java/com/qmth/eds/common/domain/PrefixUrlDomain.java
  20. 71 0
      eds-common/src/main/java/com/qmth/eds/common/domain/SmsDomain.java
  21. 125 0
      eds-common/src/main/java/com/qmth/eds/common/domain/SysDomain.java
  22. 49 0
      eds-common/src/main/java/com/qmth/eds/common/domain/WhuDomain.java
  23. 114 0
      eds-common/src/main/java/com/qmth/eds/common/entity/BasicAttachment.java
  24. 169 0
      eds-common/src/main/java/com/qmth/eds/common/entity/BasicMessage.java
  25. 140 0
      eds-common/src/main/java/com/qmth/eds/common/entity/BasicSchool.java
  26. 103 0
      eds-common/src/main/java/com/qmth/eds/common/entity/BasicVerifyCode.java
  27. 93 0
      eds-common/src/main/java/com/qmth/eds/common/entity/CloudMarkingExam.java
  28. 277 0
      eds-common/src/main/java/com/qmth/eds/common/entity/CloudMarkingScore.java
  29. 178 0
      eds-common/src/main/java/com/qmth/eds/common/entity/CloudMarkingScoreForeign.java
  30. 127 0
      eds-common/src/main/java/com/qmth/eds/common/entity/ExamCourseMapping.java
  31. 87 0
      eds-common/src/main/java/com/qmth/eds/common/entity/ExamDownloadRecord.java
  32. 127 0
      eds-common/src/main/java/com/qmth/eds/common/entity/ExamScheduleTask.java
  33. 41 0
      eds-common/src/main/java/com/qmth/eds/common/entity/ExamSemester.java
  34. 279 0
      eds-common/src/main/java/com/qmth/eds/common/entity/ExamSyncStudent.java
  35. 262 0
      eds-common/src/main/java/com/qmth/eds/common/entity/ExamSyncStudentTemp.java
  36. 194 0
      eds-common/src/main/java/com/qmth/eds/common/entity/ExamSyncTotal.java
  37. 41 0
      eds-common/src/main/java/com/qmth/eds/common/entity/ExamType.java
  38. 108 0
      eds-common/src/main/java/com/qmth/eds/common/entity/SysCollege.java
  39. 91 0
      eds-common/src/main/java/com/qmth/eds/common/entity/SysConfig.java
  40. 126 0
      eds-common/src/main/java/com/qmth/eds/common/entity/SysOrg.java
  41. 147 0
      eds-common/src/main/java/com/qmth/eds/common/entity/SysPrivilege.java
  42. 81 0
      eds-common/src/main/java/com/qmth/eds/common/entity/SysRole.java
  43. 71 0
      eds-common/src/main/java/com/qmth/eds/common/entity/SysRolePrivilege.java
  44. 167 0
      eds-common/src/main/java/com/qmth/eds/common/entity/SysUser.java
  45. 101 0
      eds-common/src/main/java/com/qmth/eds/common/entity/SysUserRole.java
  46. 216 0
      eds-common/src/main/java/com/qmth/eds/common/entity/TBSession.java
  47. 151 0
      eds-common/src/main/java/com/qmth/eds/common/entity/TBSyncTask.java
  48. 224 0
      eds-common/src/main/java/com/qmth/eds/common/entity/TBTask.java
  49. 94 0
      eds-common/src/main/java/com/qmth/eds/common/entity/TGError.java
  50. 129 0
      eds-common/src/main/java/com/qmth/eds/common/entity/TSAuth.java
  51. 42 0
      eds-common/src/main/java/com/qmth/eds/common/enums/AppSourceEnum.java
  52. 38 0
      eds-common/src/main/java/com/qmth/eds/common/enums/AuthEnum.java
  53. 59 0
      eds-common/src/main/java/com/qmth/eds/common/enums/EnumResult.java
  54. 133 0
      eds-common/src/main/java/com/qmth/eds/common/enums/ExceptionResultEnum.java
  55. 41 0
      eds-common/src/main/java/com/qmth/eds/common/enums/JobEnum.java
  56. 45 0
      eds-common/src/main/java/com/qmth/eds/common/enums/MessageEnum.java
  57. 36 0
      eds-common/src/main/java/com/qmth/eds/common/enums/OrgTypeEnum.java
  58. 67 0
      eds-common/src/main/java/com/qmth/eds/common/enums/PrivilegeEnum.java
  59. 44 0
      eds-common/src/main/java/com/qmth/eds/common/enums/PrivilegePropertyEnum.java
  60. 39 0
      eds-common/src/main/java/com/qmth/eds/common/enums/RoleTypeEnum.java
  61. 42 0
      eds-common/src/main/java/com/qmth/eds/common/enums/TaskResultEnum.java
  62. 59 0
      eds-common/src/main/java/com/qmth/eds/common/enums/TaskStatusEnum.java
  63. 53 0
      eds-common/src/main/java/com/qmth/eds/common/enums/TaskTypeEnum.java
  64. 76 0
      eds-common/src/main/java/com/qmth/eds/common/enums/UploadFileEnum.java
  65. 37 0
      eds-common/src/main/java/com/qmth/eds/common/enums/UseSceneEnum.java
  66. 66 0
      eds-common/src/main/java/com/qmth/eds/common/threadPool/MyThreadPool.java
  67. 187 0
      eds-common/src/main/java/com/qmth/eds/common/tools/CloudMarkingUtil.java
  68. 146 0
      eds-common/src/main/java/com/qmth/eds/common/tools/WuhanUniversityUtils.java
  69. 149 0
      eds-common/src/main/java/com/qmth/eds/common/util/AesUtil.java
  70. 207 0
      eds-common/src/main/java/com/qmth/eds/common/util/AuthUtil.java
  71. 16 0
      eds-common/src/main/java/com/qmth/eds/common/util/Base64Util.java
  72. 206 0
      eds-common/src/main/java/com/qmth/eds/common/util/FileStoreUtil.java
  73. 622 0
      eds-common/src/main/java/com/qmth/eds/common/util/FileUtil.java
  74. 25 0
      eds-common/src/main/java/com/qmth/eds/common/util/HexUtils.java
  75. 299 0
      eds-common/src/main/java/com/qmth/eds/common/util/HttpKit.java
  76. 228 0
      eds-common/src/main/java/com/qmth/eds/common/util/HttpUtil.java
  77. 57 0
      eds-common/src/main/java/com/qmth/eds/common/util/IpUtil.java
  78. 108 0
      eds-common/src/main/java/com/qmth/eds/common/util/JacksonUtil.java
  79. 57 0
      eds-common/src/main/java/com/qmth/eds/common/util/MD5Util.java
  80. 79 0
      eds-common/src/main/java/com/qmth/eds/common/util/RSAUtils.java
  81. 266 0
      eds-common/src/main/java/com/qmth/eds/common/util/RedisUtil.java
  82. 70 0
      eds-common/src/main/java/com/qmth/eds/common/util/Result.java
  83. 66 0
      eds-common/src/main/java/com/qmth/eds/common/util/ResultUtil.java
  84. 266 0
      eds-common/src/main/java/com/qmth/eds/common/util/ServletUtil.java
  85. 31 0
      eds-common/src/main/java/com/qmth/eds/common/util/SessionUtil.java
  86. 25 0
      eds-common/src/main/java/com/qmth/eds/common/util/ShaUtils.java
  87. 82 0
      eds-common/src/main/java/com/qmth/eds/common/util/SmsUtils.java
  88. 221 0
      eds-common/src/main/java/com/qmth/eds/common/util/excel/BasicExcelListener.java
  89. 53 0
      eds-common/src/main/java/com/qmth/eds/common/util/excel/BasicExcelRow.java
  90. 13 0
      eds-common/src/test/java/com/qmth/eds/whu/common/EdsCommonApplicationTests.java
  91. 33 0
      eds-whu/.gitignore
  92. 62 0
      eds-whu/pom.xml
  93. 13 0
      eds-whu/src/test/java/com/qmth/eds/whu/whu/EdsWhuApplicationTests.java

+ 33 - 0
eds-common/.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 157 - 0
eds-common/pom.xml

@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.qmth.eds.common</groupId>
+    <artifactId>eds-common</artifactId>
+    <version>1.0.3</version>
+    <packaging>jar</packaging>
+
+    <parent>
+        <groupId>com.qmth.eds</groupId>
+        <artifactId>eds-service</artifactId>
+        <version>1.0.3</version>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>starter-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>core-uid</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>core-cache</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>core-concurrent</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>core-fss</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>data-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>data-mybatis-plus</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>core-solar</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+        </dependency>
+        <!--            <dependency>-->
+        <!--                <groupId>com.github.xiaoymin</groupId>-->
+        <!--                <artifactId>swagger-bootstrap-ui</artifactId>-->
+        <!--                <version>${swagger2-bootstrap.version}</version>-->
+        <!--            </dependency>-->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <!--quartz-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-quartz</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jetbrains</groupId>
+            <artifactId>annotations</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-text</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>tools-poi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>tools-common</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 22 - 0
eds-common/src/main/java/com/qmth/eds/common/annotation/ApiJsonObject.java

@@ -0,0 +1,22 @@
+package com.qmth.eds.common.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @Description: swagger2 map参数说明注解
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/4/23
+ */
+@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ApiJsonObject {
+
+    ApiJsonProperty[] value(); //对象属性值
+
+    String name();  //对象名称
+}

+ 28 - 0
eds-common/src/main/java/com/qmth/eds/common/annotation/ApiJsonProperty.java

@@ -0,0 +1,28 @@
+package com.qmth.eds.common.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @Description: swagger2 map参数说明属性注解
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/4/23
+ */
+@Target(ElementType.ANNOTATION_TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ApiJsonProperty {
+
+    String key();  //key
+
+    String example() default "";
+
+    String type() default "string";
+
+    String description() default "";
+
+    boolean required() default false;
+}

+ 100 - 0
eds-common/src/main/java/com/qmth/eds/common/base/BaseEntity.java

@@ -0,0 +1,100 @@
+package com.qmth.eds.common.base;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.contant.SystemConstant;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * @Description: 基础entity
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2019/12/6
+ */
+public class BaseEntity implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id")
+    private Long id;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableField("create_id")
+    @ApiModelProperty(value = "创建人")
+    private Long createId;
+
+    @TableField(value = "create_time", fill = FieldFill.INSERT)//新增执行
+    @ApiModelProperty(value = "创建时间")
+    private Long createTime;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableField("update_id")
+    @ApiModelProperty(value = "修改人")
+    private Long updateId;
+
+    @TableField(value = "update_Time", fill = FieldFill.INSERT_UPDATE) // 新增和更新执行
+    @ApiModelProperty(value = "修改时间")
+    private Long updateTime;
+
+    public void insertInfo(Long userId) {
+        this.id = SystemConstant.getDbUuid();
+        this.createId = userId;
+        this.createTime = System.currentTimeMillis();
+    }
+
+    public void updateInfo(Long userId) {
+        this.updateId = userId;
+        this.updateTime = System.currentTimeMillis();
+    }
+
+    public static long getSerialVersionUID() {
+        return serialVersionUID;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getCreateId() {
+        return createId;
+    }
+
+    public void setCreateId(Long createId) {
+        this.createId = createId;
+    }
+
+    public Long getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
+    }
+
+    public Long getUpdateId() {
+        return updateId;
+    }
+
+    public void setUpdateId(Long updateId) {
+        this.updateId = updateId;
+    }
+
+    public Long getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Long updateTime) {
+        this.updateTime = updateTime;
+    }
+}

+ 64 - 0
eds-common/src/main/java/com/qmth/eds/common/base/BaseListPage.java

@@ -0,0 +1,64 @@
+package com.qmth.eds.common.base;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Description: 分页封装
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/8/7
+ */
+public class BaseListPage<T> implements Serializable {
+    @ApiModelProperty(value = "当前第几页(从1开始)")
+    private int current;
+
+    @ApiModelProperty(value = "每页条数")
+    private int size;
+
+    @ApiModelProperty(value = "总条数")
+    private int total;
+
+    @ApiModelProperty(value = "内容列表")
+    private List<T> records;
+
+    public BaseListPage(List<T> records, long current, long size, long total) {
+        this.current = (int) current;
+        this.size = (int) size;
+        this.total = (int) total;
+        this.records = records;
+    }
+
+    public int getCurrent() {
+        return current;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public int getTotal() {
+        return total;
+    }
+
+    public List<T> getRecords() {
+        return records;
+    }
+
+    /**
+     * 总页数
+     */
+    public int getPages() {
+        if (getSize() == 0) {
+            return 0;
+        }
+        int pages = getTotal() / getSize();
+        if (getTotal() % getSize() != 0) {
+            pages++;
+        }
+        return pages;
+    }
+}

+ 54 - 0
eds-common/src/main/java/com/qmth/eds/common/base/BasePage.java

@@ -0,0 +1,54 @@
+package com.qmth.eds.common.base;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Description: 分页封装
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/8/7
+ */
+public class BasePage {
+
+    private Long schoolId;
+
+    @ApiModelProperty(value = "分页页码")
+    private Integer pageNumber;
+
+    @ApiModelProperty(value = "分页数")
+    private Integer pageSize;
+
+    public BasePage(Integer pageNumber, Integer pageSize) {
+        this.pageNumber = (int) pageNumber;
+        this.pageSize = pageSize;
+    }
+
+    public BasePage() {
+
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Integer getPageNumber() {
+        return pageNumber;
+    }
+
+    public void setPageNumber(Integer pageNumber) {
+        this.pageNumber = pageNumber;
+    }
+
+    public Integer getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(Integer pageSize) {
+        this.pageSize = pageSize;
+    }
+}

+ 44 - 0
eds-common/src/main/java/com/qmth/eds/common/base/CustomBaseMapper.java

@@ -0,0 +1,44 @@
+package com.qmth.eds.common.base;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+/**
+ * @Description: 自定义mapper
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/5/11
+ */
+public interface CustomBaseMapper<T> extends BaseMapper<T> {
+
+    /**
+     * 自定义批量插入
+     * 如果要自动填充,@Param(xx) xx参数名必须是 list/collection/array 3个的其中之一
+     *
+     * @param list
+     * @return
+     */
+    int insertBatch(@Param("collection") Collection<? extends Serializable> list);
+
+    /**
+     * 自定义批量更新
+     * 如果要自动填充,@Param(xx) xx参数名必须是 list/collection/array 3个的其中之一
+     *
+     * @param list
+     * @return
+     */
+    int updateBatch(@Param("collection") Collection<? extends Serializable> list);
+
+    /**
+     * 自定义批量新增或更新
+     * 如果要自动填充,@Param(xx) xx参数名必须是 list/collection/array 3个的其中之一
+     *
+     * @param list
+     * @return
+     */
+    int insertOrUpdateBath(@Param("collection") Collection<? extends Serializable> list);
+}

+ 32 - 0
eds-common/src/main/java/com/qmth/eds/common/base/CustomizedSqlInjector.java

@@ -0,0 +1,32 @@
+package com.qmth.eds.common.base;
+
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
+import com.qmth.eds.common.base.method.InsertBatch;
+import com.qmth.eds.common.base.method.InsertOrUpdateBath;
+import com.qmth.eds.common.base.method.UpdateBatch;
+
+import java.util.List;
+
+/**
+ * @Description: 自定义批量sql插入、更新
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/5/11
+ */
+public class CustomizedSqlInjector extends DefaultSqlInjector {
+
+    /**
+     * 如果只需增加方法,保留mybatis plus自带方法,
+     * 可以先获取super.getMethodList(),再添加add
+     */
+    @Override
+    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
+        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
+        methodList.add(new InsertBatch());
+        methodList.add(new UpdateBatch());
+        methodList.add(new InsertOrUpdateBath());
+        return methodList;
+    }
+}

+ 63 - 0
eds-common/src/main/java/com/qmth/eds/common/base/method/InsertBatch.java

@@ -0,0 +1,63 @@
+package com.qmth.eds.common.base.method;
+
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+import org.apache.ibatis.executor.keygen.NoKeyGenerator;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @Description: 自定义批量插入
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/5/11
+ */
+public class InsertBatch extends AbstractMethod {
+    private final static Logger log = LoggerFactory.getLogger(InsertBatch.class);
+
+    /**
+     * insert into user(id, name, age) values (1, "a", 17), (2, "b", 18);
+     * <script>
+     * insert into user(id, name, age) values
+     * <foreach collection="collection" item="item" index="index" open="(" separator="),(" close=")">
+     * #{item.id}, #{item.name}, #{item.age}
+     * </foreach>
+     * </script>
+     */
+    @Override
+    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
+        final String sql = "<script>insert into %s %s values %s</script>";
+        final String fieldSql = prepareFieldSql(tableInfo);
+        final String valueSql = prepareValuesSql(tableInfo);
+        final String sqlResult = String.format(sql, tableInfo.getTableName(), fieldSql, valueSql);
+        log.debug("sqlResult----->{}", sqlResult);
+        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
+        // 第三个参数必须和RootMapper的自定义方法名一致
+        return this.addInsertMappedStatement(mapperClass, modelClass, "insertBatch", sqlSource, new NoKeyGenerator(), null, null);
+    }
+
+    private String prepareFieldSql(TableInfo tableInfo) {
+        StringBuilder fieldSql = new StringBuilder();
+        fieldSql.append(tableInfo.getKeyColumn()).append(",");
+        tableInfo.getFieldList().forEach(x -> {
+            fieldSql.append(x.getColumn()).append(",");
+        });
+        fieldSql.delete(fieldSql.length() - 1, fieldSql.length());
+        fieldSql.insert(0, "(");
+        fieldSql.append(")");
+        return fieldSql.toString();
+    }
+
+    private String prepareValuesSql(TableInfo tableInfo) {
+        final StringBuilder valueSql = new StringBuilder();
+        valueSql.append("<foreach collection=\"collection\" item=\"item\" index=\"index\" open=\"(\" separator=\"),(\" close=\")\">");
+        valueSql.append("#{item.").append(tableInfo.getKeyProperty()).append("},");
+        tableInfo.getFieldList().forEach(x -> valueSql.append("#{item.").append(x.getProperty()).append("},"));
+        valueSql.delete(valueSql.length() - 1, valueSql.length());
+        valueSql.append("</foreach>");
+        return valueSql.toString();
+    }
+}

+ 85 - 0
eds-common/src/main/java/com/qmth/eds/common/base/method/InsertOrUpdateBath.java

@@ -0,0 +1,85 @@
+package com.qmth.eds.common.base.method;
+
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+import org.apache.ibatis.executor.keygen.NoKeyGenerator;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+
+/**
+ * @Description: 自定义插入或更新
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/5/11
+ */
+public class InsertOrUpdateBath extends AbstractMethod {
+    private final static Logger log = LoggerFactory.getLogger(InsertOrUpdateBath.class);
+
+    @Override
+    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
+        final String sql = "<script>insert into %s %s values %s ON DUPLICATE KEY UPDATE %s</script>";
+        final String tableName = tableInfo.getTableName();
+        final String filedSql = prepareFieldSql(tableInfo);
+        final String modelValuesSql = prepareModelValuesSql(tableInfo);
+        final String duplicateKeySql = prepareDuplicateKeySql(tableInfo);
+        final String sqlResult = String.format(sql, tableName, filedSql, modelValuesSql, duplicateKeySql);
+        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
+        return this.addInsertMappedStatement(mapperClass, modelClass, "insertOrUpdateBath", sqlSource, new NoKeyGenerator(), null, null);
+    }
+
+    /**
+     * 准备ON DUPLICATE KEY UPDATE sql
+     *
+     * @param tableInfo
+     * @return
+     */
+    private String prepareDuplicateKeySql(TableInfo tableInfo) {
+        final StringBuilder duplicateKeySql = new StringBuilder();
+        if (!StringUtils.isEmpty(tableInfo.getKeyColumn())) {
+            duplicateKeySql.append(tableInfo.getKeyColumn()).append("=values(").append(tableInfo.getKeyColumn()).append("),");
+        }
+
+        tableInfo.getFieldList().forEach(x -> {
+            duplicateKeySql.append(x.getColumn())
+                    .append("=values(")
+                    .append(x.getColumn())
+                    .append("),");
+        });
+        duplicateKeySql.delete(duplicateKeySql.length() - 1, duplicateKeySql.length());
+        return duplicateKeySql.toString();
+    }
+
+    /**
+     * 准备属性名
+     *
+     * @param tableInfo
+     * @return
+     */
+    private String prepareFieldSql(TableInfo tableInfo) {
+        StringBuilder fieldSql = new StringBuilder();
+        fieldSql.append(tableInfo.getKeyColumn()).append(",");
+        tableInfo.getFieldList().forEach(x -> {
+            fieldSql.append(x.getColumn()).append(",");
+        });
+        fieldSql.delete(fieldSql.length() - 1, fieldSql.length());
+        fieldSql.insert(0, "(");
+        fieldSql.append(")");
+        return fieldSql.toString();
+    }
+
+    private String prepareModelValuesSql(TableInfo tableInfo) {
+        final StringBuilder valueSql = new StringBuilder();
+        valueSql.append("<foreach collection=\"collection\" item=\"item\" index=\"index\" open=\"(\" separator=\"),(\" close=\")\">");
+        if (!StringUtils.isEmpty(tableInfo.getKeyProperty())) {
+            valueSql.append("#{item.").append(tableInfo.getKeyProperty()).append("},");
+        }
+        tableInfo.getFieldList().forEach(x -> valueSql.append("#{item.").append(x.getProperty()).append("},"));
+        valueSql.delete(valueSql.length() - 1, valueSql.length());
+        valueSql.append("</foreach>");
+        return valueSql.toString();
+    }
+}

+ 30 - 0
eds-common/src/main/java/com/qmth/eds/common/base/method/UpdateBatch.java

@@ -0,0 +1,30 @@
+package com.qmth.eds.common.base.method;
+
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @Description: 自定义更新
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/5/11
+ */
+public class UpdateBatch extends AbstractMethod {
+    private final static Logger log = LoggerFactory.getLogger(UpdateBatch.class);
+
+    @Override
+    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
+        String sql = "<script>\n<foreach collection=\"collection\" item=\"item\" separator=\";\">\nupdate %s %s where %s=#{%s} %s\n</foreach>\n</script>";
+        String additional = tableInfo.isWithVersion() ? tableInfo.getVersionFieldInfo().getVersionOli("item", "item.") : "" + tableInfo.getLogicDeleteSql(true, true);
+        String setSql = sqlSet(tableInfo.isWithLogicDelete(), false, tableInfo, false, "item", "item.");
+        String sqlResult = String.format(sql, tableInfo.getTableName(), setSql, tableInfo.getKeyColumn(), "item." + tableInfo.getKeyProperty(), additional);
+        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
+        // 第三个参数必须和RootMapper的自定义方法名一致
+        return this.addUpdateMappedStatement(mapperClass, modelClass, "updateBatch", sqlSource);
+    }
+}

+ 69 - 0
eds-common/src/main/java/com/qmth/eds/common/contant/SpringContextHolder.java

@@ -0,0 +1,69 @@
+package com.qmth.eds.common.contant;
+
+import com.qmth.eds.common.enums.ExceptionResultEnum;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Description: spring上下文获取工具
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2019/10/11
+ */
+@Component
+public class SpringContextHolder implements ApplicationContextAware {
+    /**
+     * 上下文对象实例
+     */
+    private volatile static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        SpringContextHolder.applicationContext = applicationContext;
+    }
+
+    /**
+     * 获取application上下文对象
+     *
+     * @return
+     */
+    public static ApplicationContext getApplicationContext() {
+        assertApplicationContext();
+        return applicationContext;
+    }
+
+    /**
+     * 通过name获取bean
+     *
+     * @param beanName
+     * @return
+     */
+//    @SuppressWarnings("unchecked")//忽略警告
+    public static <T> T getBean(String beanName) {
+        assertApplicationContext();
+        return (T) applicationContext.getBean(beanName);
+    }
+
+    /**
+     * 通过class获取bean
+     *
+     * @param requiredType
+     * @return
+     */
+    public static <T> T getBean(Class<T> requiredType) {
+        assertApplicationContext();
+        return (T) applicationContext.getBean(requiredType);
+    }
+
+    /**
+     * 获取实例
+     */
+    private static void assertApplicationContext() {
+        if (SpringContextHolder.applicationContext == null) {
+            throw ExceptionResultEnum.ERROR.exception("applicaitonContext属性为null,请检查是否注入了SpringContextHolder!");
+        }
+    }
+}

+ 258 - 0
eds-common/src/main/java/com/qmth/eds/common/contant/SystemConstant.java

@@ -0,0 +1,258 @@
+package com.qmth.eds.common.contant;
+
+import com.qmth.boot.core.uid.service.UidService;
+import com.qmth.eds.common.entity.SysUser;
+import com.qmth.eds.common.enums.ExceptionResultEnum;
+import com.qmth.eds.common.util.Base64Util;
+import com.qmth.eds.common.util.ServletUtil;
+import org.apache.commons.io.IOUtils;
+
+import java.io.*;
+import java.net.URLEncoder;
+import java.nio.charset.Charset;
+import java.util.Objects;
+import java.util.StringJoiner;
+import java.util.UUID;
+
+/**
+ * @Description: 系统常量
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2019/10/11
+ */
+public class SystemConstant {
+
+    /**
+     * 系统常量
+     */
+    public static final String CHARSET_NAME = "UTF-8";
+    public static final Charset CHARSET = Charset.forName(CHARSET_NAME);
+    public static final String MD5 = "MD5";
+    public static final String SUCCESS = "success";
+    public static final String USER_DIR = "user.dir";
+    public static final String FILE_TEMP = "file-temp";
+    public static final String SESSION = "session:";
+    public static final String USER = "account";
+    public static final String SCHOOL_ID = "schoolId";
+    public static final String SCHOOL = "school";
+    public static final String ORG = "org";
+    public static final String ERROR = "/error";
+    public static final String METHOD = "post";
+    public static final String DEFAULT_PASSWORD = "123456";
+    public static final String UPDATE_TIME = "updateTime";
+    public static final String PATH = "path";
+    public static final String TYPE = "type";
+    public static final String LOCAL = "local";
+    public static final String OSS = "oss";
+    public static final String LOGO = "logo";
+    public static final String ADMIN_CODE = "admin";
+    public static final String UPLOAD_TYPE = "uploadType";
+    public static final String HTTP = "http://";
+    public static final String ID = "id";
+    public static final String FILE = "file";
+    public static final String SIZE = "size";
+    public static final String HTML_PREFIX = ".html";
+    public static final String PDF_PREFIX = ".pdf";
+    public static final String FTL_PREFIX = ".ftl";
+    public static final String ZIP_PREFIX = ".zip";
+    public static final String JPG_PREFIX = ".jpg";
+    public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";
+    public static final int PAGE_NUMBER = 1;
+    public static final int PAGE_NUMBER_MIN = 1;
+    public static final int PAGE_SIZE = 100;
+    public static final int PAGE_SIZE_MIN = 10;
+    public static final int PAGE_SIZE_MAX = 500;
+    public static final int IN_SIZE_MAX = 1000;
+    public static final String DELIMITER = ":";
+    public static final String COMMA = ",";
+    public static final String UNDEFINED = "_";
+    public static final String HYPHEN = "-";
+    public static final String DEFAULT_SIGN = "#";
+    public static final String AUTH = "auth";
+    public static final int FINAL_SCALE = 1;
+    public static final int CALCULATE_SCALE = 4;
+    public static final int OPER_SCALE = 8;
+    //英文字母、数字、中文括号、英文括号、下划线(_)、减号(-)、中文横线(—)
+    public static final String REGULAR_EXPRESSION_OF_CODE = "[a-zA-Z0-9](\\w+)?-?(\\w+)?—?(\\w+)?(\\((\\w+)?-?(\\w+)?—?(\\w+)?\\))?(\\((\\w+)?-?(\\w+)?—?(\\w+)?\\))?(\\w+)?";
+    public static final String REGULAR_EXPRESSION_OF_PHONE = "((\\d{3,4})|(\\(\\d{3,4}\\)-))?\\d{7,8}";
+
+    /**
+     * oss url过期时间
+     */
+    public static final int OSS_URL_EXPIRE = 5 * 60 * 1000;//过期时间5分钟
+
+    /**
+     * 缓存配置
+     */
+    public static final String USER_OAUTH_CACHE = "user:oauth:cache";
+    public static final String USER_ACCOUNT_CACHE = "user:account:cache";
+    public static final String USER_MENU_CACHE = "user:menu:cache";
+    public static final String SCHOOL_CACHE = "school:cache";
+    public static final String SCHOOL_CODE_CACHE = "school:code:cache";
+    public static final String ORG_CACHE = "org:cache";
+    public static final String PRIVILEGE_URL_CACHE = "privilege:url:cache";
+    public static final String AUTH_INFO_CACHE = "auth:info:cache";
+    public static final String ROLE_PRIVILEGE_CACHE = "role:privilege:cache";
+    public static final String USER_ROLE_PRIVILEGE_CACHE = "user:role:privilege:cache";
+    public static final String ROLE_CACHE = "role:cache";
+
+    /**
+     * 鉴权
+     */
+    public static final String HEADER_AUTHORIZATION = "Authorization";
+    public static final String HEADER_TIME = "time";
+    public static final String HEADER_PLATFORM = "platform";
+    public static final String HEADER_DEVICE_ID = "deviceId";
+    public static final String TOKEN = "token";
+
+    /**
+     * redis
+     */
+    public static final int DEFAULT_SESSION_EXPIRE = 1;//过期时间1天
+    public static final long REDIS_DEFAULT_EXPIRE_TIME = 24 * 60L * 60L;//过期时间24小时
+
+    /**
+     * redis prefix
+     */
+    public static final String REDIS_LOCK_MQ_PREFIX = "redis:lock:mq:";
+
+    /**
+     * redis lock
+     */
+    public static final long REDIS_CACHE_TIME_OUT = 60L;
+
+    /**
+     * aes相关
+     */
+    public static final String AES = "AES";
+    public static final String AES_MODE_PKCS5 = "AES/CBC/PKCS5Padding";//用这个模式,规则必须为16位
+    public static final String AES_MODE_PKCS7 = "AES/CBC/PKCS7Padding";//用这个模式,规则必须为16位
+    public static final String AES_RULE = "1234567890123456";//aes密钥
+
+    /**
+     * 变量
+     */
+    public static String TEMP_FILES_DIR;
+
+    /**
+     * excel相关
+     */
+    public static final String XLSX = "xlsx";
+    public static final String XLS = "xls";
+
+    /**
+     * 线程池配置
+     */
+    public static final String THREAD_POOL_NAME = "taskThreadPool";
+    //    public static final int THREAD_POOL_CORE_POOL_SIZE = 5;
+//    public static final int THREAD_POOL_MAX_POOL_SIZE = 100;
+    public static final int THREAD_POOL_KEEP_ALIVE_SECONDS = 10;
+    public static final int THREAD_POOL_QUEUE_CAPACITY = 500;
+
+    public static final String LOG_ERROR = "请求出错:";
+
+    /**
+     * 初始化附件文件路径
+     */
+    public static void initTempFiles() {
+        StringJoiner localPath = new StringJoiner("").add(System.getProperty(USER_DIR));
+        String mkdir = localPath.toString().substring(0, localPath.toString().lastIndexOf(File.separator));
+        File fileTempDir = new File(new StringBuffer(mkdir).append(File.separator).append(FILE_TEMP).toString());
+        if (!fileTempDir.exists()) {
+            fileTempDir.mkdirs();
+        }
+        TEMP_FILES_DIR = fileTempDir.getPath();
+    }
+
+    /**
+     * URL 编码, Encode默认为UTF-8.
+     */
+    public static String urlEncode(String part) {
+        try {
+            return URLEncoder.encode(part, SystemConstant.CHARSET_NAME);
+        } catch (UnsupportedEncodingException e) {
+            throw ExceptionResultEnum.ERROR.exception(e.getMessage());
+        }
+    }
+
+    /**
+     * 图片转换
+     *
+     * @param imgBase64
+     * @param filePath
+     * @throws IOException
+     */
+    public static void base64ToImage(String imgBase64, String filePath) throws IOException {
+        OutputStream out = null;
+        try {
+            byte[] b = Base64Util.decode(imgBase64);
+            out = new FileOutputStream(filePath);
+            IOUtils.write(b, out);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (Objects.nonNull(out)) {
+                out.flush();
+                out.close();
+            }
+        }
+    }
+
+    /**
+     * id转换为long
+     *
+     * @return
+     */
+    public static Long convertIdToLong(String id) {
+        return Objects.nonNull(id) && id.length() > 0 ? Long.parseLong(id) : null;
+    }
+
+    /**
+     * id转换为Integer
+     *
+     * @return
+     */
+    public static Integer convertIdToInteger(String id) {
+        return Objects.nonNull(id) && id.length() > 0 ? Integer.parseInt(id) : null;
+    }
+
+    /**
+     * 获取全局uuid
+     *
+     * @return
+     */
+    public static String getUuid() {
+        return String.valueOf(UUID.randomUUID()).replaceAll("-", "");
+    }
+
+    /**
+     * 获取数据库uuid
+     *
+     * @return
+     */
+    public static Long getDbUuid() {
+        UidService uidservice = SpringContextHolder.getBean(UidService.class);
+        return uidservice.getId();
+    }
+
+    /**
+     * enable转换
+     *
+     * @return
+     */
+    public static Boolean convertEnable(Boolean enable) {
+        return Objects.nonNull(enable) ? enable : true;
+    }
+
+    public static Long getHeadOrUserSchoolId() {
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        Long schoolId;
+        if (Objects.nonNull(ServletUtil.getRequestHeaderSchoolIdByNotVaild())) {
+            schoolId = Long.parseLong(ServletUtil.getRequestHeaderSchoolIdByNotVaild().toString());
+        } else {
+            schoolId = sysUser.getSchoolId();
+        }
+        return schoolId;
+    }
+}

+ 69 - 0
eds-common/src/main/java/com/qmth/eds/common/domain/CloudMarkingDomain.java

@@ -0,0 +1,69 @@
+package com.qmth.eds.common.domain;
+
+import java.io.Serializable;
+
+/**
+ * 云阅卷配置
+ */
+public class CloudMarkingDomain implements Serializable {
+
+    private String accessKey;
+
+    private String accessSecret;
+
+    private String rootUrl;
+
+    private String examUrl;
+
+    private String studentCountUrl;
+
+    private String studentScoreUrl;
+
+    public String getAccessKey() {
+        return accessKey;
+    }
+
+    public void setAccessKey(String accessKey) {
+        this.accessKey = accessKey;
+    }
+
+    public String getAccessSecret() {
+        return accessSecret;
+    }
+
+    public void setAccessSecret(String accessSecret) {
+        this.accessSecret = accessSecret;
+    }
+
+    public String getRootUrl() {
+        return rootUrl;
+    }
+
+    public void setRootUrl(String rootUrl) {
+        this.rootUrl = rootUrl;
+    }
+
+    public String getExamUrl() {
+        return examUrl;
+    }
+
+    public void setExamUrl(String examUrl) {
+        this.examUrl = examUrl;
+    }
+
+    public String getStudentCountUrl() {
+        return studentCountUrl;
+    }
+
+    public void setStudentCountUrl(String studentCountUrl) {
+        this.studentCountUrl = studentCountUrl;
+    }
+
+    public String getStudentScoreUrl() {
+        return studentScoreUrl;
+    }
+
+    public void setStudentScoreUrl(String studentScoreUrl) {
+        this.studentScoreUrl = studentScoreUrl;
+    }
+}

+ 26 - 0
eds-common/src/main/java/com/qmth/eds/common/domain/FssLocalFileDomain.java

@@ -0,0 +1,26 @@
+package com.qmth.eds.common.domain;
+
+/**
+ *
+ */
+public class FssLocalFileDomain {
+    private String config;
+
+    private String server;
+
+    public String getConfig() {
+        return config;
+    }
+
+    public void setConfig(String config) {
+        this.config = config;
+    }
+
+    public String getServer() {
+        return server;
+    }
+
+    public void setServer(String server) {
+        this.server = server;
+    }
+}

+ 34 - 0
eds-common/src/main/java/com/qmth/eds/common/domain/FssPrivateDomain.java

@@ -0,0 +1,34 @@
+package com.qmth.eds.common.domain;
+
+/**
+ * @Description: 文件存储中心配置-私有
+ * @Author: CaoZixuan
+ * @Date: 2021-08-18
+ */
+public class FssPrivateDomain {
+    private static final long serialVersionUID = 7510626406622200443L;
+
+    private String config;
+
+    private String server;
+
+    public static long getSerialVersionUID() {
+        return serialVersionUID;
+    }
+
+    public String getConfig() {
+        return config;
+    }
+
+    public void setConfig(String config) {
+        this.config = config;
+    }
+
+    public String getServer() {
+        return server;
+    }
+
+    public void setServer(String server) {
+        this.server = server;
+    }
+}

+ 34 - 0
eds-common/src/main/java/com/qmth/eds/common/domain/FssPublicDomain.java

@@ -0,0 +1,34 @@
+package com.qmth.eds.common.domain;
+
+/**
+ * @Description: 文件存储中心配置-公有
+ * @Author: CaoZixuan
+ * @Date: 2021-08-18
+ */
+public class FssPublicDomain {
+    private static final long serialVersionUID = 7510626406622200443L;
+
+    private String config;
+
+    private String server;
+
+    public static long getSerialVersionUID() {
+        return serialVersionUID;
+    }
+
+    public String getConfig() {
+        return config;
+    }
+
+    public void setConfig(String config) {
+        this.config = config;
+    }
+
+    public String getServer() {
+        return server;
+    }
+
+    public void setServer(String server) {
+        this.server = server;
+    }
+}

+ 23 - 0
eds-common/src/main/java/com/qmth/eds/common/domain/PrefixUrlDomain.java

@@ -0,0 +1,23 @@
+package com.qmth.eds.common.domain;
+
+import java.io.Serializable;
+
+/**
+ * @Description: 模块前缀
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/4/10
+ */
+public class PrefixUrlDomain implements Serializable {
+
+    String common;
+
+    public String getCommon() {
+        return common;
+    }
+
+    public void setCommon(String common) {
+        this.common = common;
+    }
+}

+ 71 - 0
eds-common/src/main/java/com/qmth/eds/common/domain/SmsDomain.java

@@ -0,0 +1,71 @@
+package com.qmth.eds.common.domain;
+
+/**
+ * 短信参数
+ */
+public class SmsDomain {
+
+    String normalCode;
+    Integer expiredTime;
+    Integer sendInterval;
+    String aliyunSMSKey;
+    String aliyunSMSSecret;
+    String aliyunSMSSignName;
+    String teachDataChangeNoticeCode;
+
+    public String getNormalCode() {
+        return normalCode;
+    }
+
+    public void setNormalCode(String normalCode) {
+        this.normalCode = normalCode;
+    }
+
+    public Integer getExpiredTime() {
+        return expiredTime;
+    }
+
+    public void setExpiredTime(Integer expiredTime) {
+        this.expiredTime = expiredTime;
+    }
+
+    public Integer getSendInterval() {
+        return sendInterval;
+    }
+
+    public void setSendInterval(Integer sendInterval) {
+        this.sendInterval = sendInterval;
+    }
+
+    public String getAliyunSMSKey() {
+        return aliyunSMSKey;
+    }
+
+    public void setAliyunSMSKey(String aliyunSMSKey) {
+        this.aliyunSMSKey = aliyunSMSKey;
+    }
+
+    public String getAliyunSMSSecret() {
+        return aliyunSMSSecret;
+    }
+
+    public void setAliyunSMSSecret(String aliyunSMSSecret) {
+        this.aliyunSMSSecret = aliyunSMSSecret;
+    }
+
+    public String getAliyunSMSSignName() {
+        return aliyunSMSSignName;
+    }
+
+    public void setAliyunSMSSignName(String aliyunSMSSignName) {
+        this.aliyunSMSSignName = aliyunSMSSignName;
+    }
+
+    public String getTeachDataChangeNoticeCode() {
+        return teachDataChangeNoticeCode;
+    }
+
+    public void setTeachDataChangeNoticeCode(String teachDataChangeNoticeCode) {
+        this.teachDataChangeNoticeCode = teachDataChangeNoticeCode;
+    }
+}

+ 125 - 0
eds-common/src/main/java/com/qmth/eds/common/domain/SysDomain.java

@@ -0,0 +1,125 @@
+package com.qmth.eds.common.domain;
+
+import java.io.Serializable;
+import java.time.Duration;
+import java.util.List;
+
+/**
+ * @Description: 系统配置
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/4/10
+ */
+public class SysDomain implements Serializable {
+
+    boolean oss;
+
+    List attachmentType;
+
+    Integer attachmentLength;
+
+    Double attachmentSize;
+
+    String serverUpload;
+
+    String fileHost;
+
+    String serverHost;
+
+    Integer autoCreatePdfResetMaxCount;
+
+    Integer threadPoolCoreSize;
+
+    boolean customThreadPoolCoreSize;
+
+    Duration sessionActive;
+
+    public Duration getSessionActive() {
+        return sessionActive;
+    }
+
+    public void setSessionActive(Duration sessionActive) {
+        this.sessionActive = sessionActive;
+    }
+
+    public boolean isCustomThreadPoolCoreSize() {
+        return customThreadPoolCoreSize;
+    }
+
+    public void setCustomThreadPoolCoreSize(boolean customThreadPoolCoreSize) {
+        this.customThreadPoolCoreSize = customThreadPoolCoreSize;
+    }
+
+    public Integer getAutoCreatePdfResetMaxCount() {
+        return autoCreatePdfResetMaxCount;
+    }
+
+    public void setAutoCreatePdfResetMaxCount(Integer autoCreatePdfResetMaxCount) {
+        this.autoCreatePdfResetMaxCount = autoCreatePdfResetMaxCount;
+    }
+
+    public Integer getThreadPoolCoreSize() {
+        return threadPoolCoreSize;
+    }
+
+    public void setThreadPoolCoreSize(Integer threadPoolCoreSize) {
+        this.threadPoolCoreSize = threadPoolCoreSize;
+    }
+
+    public String getFileHost() {
+        return fileHost;
+    }
+
+    public void setFileHost(String fileHost) {
+        this.fileHost = fileHost;
+    }
+
+    public String getServerHost() {
+        return serverHost;
+    }
+
+    public void setServerHost(String serverHost) {
+        this.serverHost = serverHost;
+    }
+
+    public Integer getAttachmentLength() {
+        return attachmentLength;
+    }
+
+    public void setAttachmentLength(Integer attachmentLength) {
+        this.attachmentLength = attachmentLength;
+    }
+
+    public Double getAttachmentSize() {
+        return attachmentSize;
+    }
+
+    public void setAttachmentSize(Double attachmentSize) {
+        this.attachmentSize = attachmentSize;
+    }
+
+    public boolean isOss() {
+        return oss;
+    }
+
+    public void setOss(boolean oss) {
+        this.oss = oss;
+    }
+
+    public List getAttachmentType() {
+        return attachmentType;
+    }
+
+    public void setAttachmentType(List attachmentType) {
+        this.attachmentType = attachmentType;
+    }
+
+    public String getServerUpload() {
+        return serverUpload;
+    }
+
+    public void setServerUpload(String serverUpload) {
+        this.serverUpload = serverUpload;
+    }
+}

+ 49 - 0
eds-common/src/main/java/com/qmth/eds/common/domain/WhuDomain.java

@@ -0,0 +1,49 @@
+package com.qmth.eds.common.domain;
+
+import java.io.Serializable;
+
+/**
+ * 武汉大学配置
+ */
+public class WhuDomain implements Serializable {
+
+    private String appKey;
+
+    private String appSecret;
+
+    private String tokenUrl;
+
+    private String kwUrl;
+
+    public String getAppKey() {
+        return appKey;
+    }
+
+    public void setAppKey(String appKey) {
+        this.appKey = appKey;
+    }
+
+    public String getAppSecret() {
+        return appSecret;
+    }
+
+    public void setAppSecret(String appSecret) {
+        this.appSecret = appSecret;
+    }
+
+    public String getTokenUrl() {
+        return tokenUrl;
+    }
+
+    public void setTokenUrl(String tokenUrl) {
+        this.tokenUrl = tokenUrl;
+    }
+
+    public String getKwUrl() {
+        return kwUrl;
+    }
+
+    public void setKwUrl(String kwUrl) {
+        this.kwUrl = kwUrl;
+    }
+}

+ 114 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/BasicAttachment.java

@@ -0,0 +1,114 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 所有附件记录表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "BasicAttachment对象", description = "所有附件记录表")
+public class BasicAttachment extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "机构id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long orgId;
+
+    @ApiModelProperty(value = "文件名")
+    private String name;
+
+    @ApiModelProperty(value = "文件类型")
+    private String type;
+
+    @ApiModelProperty(value = "单位(KB)")
+    private Integer size;
+
+    @ApiModelProperty(value = "文件md5值")
+    private String md5;
+
+    @ApiModelProperty(value = "存储路径")
+    private String path;
+
+    @ApiModelProperty(value = "关联业务id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long objId;
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(Long orgId) {
+        this.orgId = orgId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Integer getSize() {
+        return size;
+    }
+
+    public void setSize(Integer size) {
+        this.size = size;
+    }
+
+    public String getMd5() {
+        return md5;
+    }
+
+    public void setMd5(String md5) {
+        this.md5 = md5;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public Long getObjId() {
+        return objId;
+    }
+
+    public void setObjId(Long objId) {
+        this.objId = objId;
+    }
+}

+ 169 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/BasicMessage.java

@@ -0,0 +1,169 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "BasicMessage对象", description = "")
+public class BasicMessage extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "消息接收人用户")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long userId;
+
+    @ApiModelProperty(value = "用户名称")
+    private String userName;
+
+    @ApiModelProperty(value = "电话号码")
+    private String mobileNumber;
+
+    @ApiModelProperty(value = "消息类型")
+    private String messageType;
+
+    @ApiModelProperty(value = "业务操作")
+    private String businessOperate;
+
+    @ApiModelProperty(value = "业务id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long businessId;
+
+    @ApiModelProperty(value = "消息模板代码")
+    private String templateCode;
+
+    @ApiModelProperty(value = "变量参数内容")
+    private String variableParams;
+
+    @ApiModelProperty(value = "模板内容")
+    private String templateContent;
+
+    @ApiModelProperty(value = "消息发送状态")
+    private String sendStatus;
+
+    @ApiModelProperty(value = "消息发送结果")
+    private String sendResult;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getMobileNumber() {
+        return mobileNumber;
+    }
+
+    public void setMobileNumber(String mobileNumber) {
+        this.mobileNumber = mobileNumber;
+    }
+
+    public String getMessageType() {
+        return messageType;
+    }
+
+    public void setMessageType(String messageType) {
+        this.messageType = messageType;
+    }
+
+    public String getBusinessOperate() {
+        return businessOperate;
+    }
+
+    public void setBusinessOperate(String businessOperate) {
+        this.businessOperate = businessOperate;
+    }
+
+    public Long getBusinessId() {
+        return businessId;
+    }
+
+    public void setBusinessId(Long businessId) {
+        this.businessId = businessId;
+    }
+
+    public String getTemplateCode() {
+        return templateCode;
+    }
+
+    public void setTemplateCode(String templateCode) {
+        this.templateCode = templateCode;
+    }
+
+    public String getVariableParams() {
+        return variableParams;
+    }
+
+    public void setVariableParams(String variableParams) {
+        this.variableParams = variableParams;
+    }
+
+    public String getTemplateContent() {
+        return templateContent;
+    }
+
+    public void setTemplateContent(String templateContent) {
+        this.templateContent = templateContent;
+    }
+
+    public String getSendStatus() {
+        return sendStatus;
+    }
+
+    public void setSendStatus(String sendStatus) {
+        this.sendStatus = sendStatus;
+    }
+
+    public String getSendResult() {
+        return sendResult;
+    }
+
+    public void setSendResult(String sendResult) {
+        this.sendResult = sendResult;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+}

+ 140 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/BasicSchool.java

@@ -0,0 +1,140 @@
+package com.qmth.eds.common.entity;
+
+import com.qmth.eds.common.base.BaseEntity;
+import com.qmth.eds.common.contant.SystemConstant;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * <p>
+ * 学校表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "BasicSchool对象", description = "学校表")
+public class BasicSchool extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校编码")
+    private String code;
+
+    @ApiModelProperty(value = "学校名称")
+    private String name;
+
+    @ApiModelProperty(value = "是否启用,false:停用,true:启用")
+    private Boolean enable;
+
+    @ApiModelProperty(value = "访问key")
+    private String accessKey;
+
+    @ApiModelProperty(value = "访问秘钥")
+    private String accessSecret;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "学校logo")
+    private String logo;
+
+    public BasicSchool() {
+
+    }
+
+    public BasicSchool(Long id, String code, String name, String accessKey, String accessSecret) {
+        this.code = code;
+        this.name = name;
+        this.accessKey = accessKey;
+        this.accessSecret = accessSecret;
+        setId(id);
+        this.enable = true;
+    }
+
+    public BasicSchool(String code, String name, String accessKey, String accessSecret, String logo) {
+        this.code = code;
+        this.name = name;
+        this.accessKey = accessKey;
+        this.accessSecret = accessSecret;
+        this.logo = logo;
+        setId(SystemConstant.getDbUuid());
+        this.enable = true;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        BasicSchool that = (BasicSchool) o;
+        return code.equals(that.code) && name.equals(that.name) && enable.equals(that.enable) && accessKey.equals(that.accessKey) && accessSecret.equals(that.accessSecret) && remark.equals(that.remark) && logo.equals(that.logo);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(code, name, enable, accessKey, accessSecret, remark, logo);
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+
+    public String getAccessKey() {
+        return accessKey;
+    }
+
+    public void setAccessKey(String accessKey) {
+        this.accessKey = accessKey;
+    }
+
+    public String getAccessSecret() {
+        return accessSecret;
+    }
+
+    public void setAccessSecret(String accessSecret) {
+        this.accessSecret = accessSecret;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getLogo() {
+        return logo;
+    }
+
+    public void setLogo(String logo) {
+        this.logo = logo;
+    }
+}

+ 103 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/BasicVerifyCode.java

@@ -0,0 +1,103 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 短信验证码记录表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "BasicVerifyCode对象", description = "短信验证码记录表")
+public class BasicVerifyCode extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "机构id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long orgId;
+
+    @ApiModelProperty(value = "用户ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long userId;
+
+    @ApiModelProperty(value = "手机号")
+    private String mobileNumber;
+
+    @ApiModelProperty(value = "到期时间")
+    private Long expireTime;
+
+    @ApiModelProperty(value = "单位(分)")
+    private Integer validPeriod;
+
+    @ApiModelProperty(value = "4位数字")
+    private String verifyCode;
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(Long orgId) {
+        this.orgId = orgId;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getMobileNumber() {
+        return mobileNumber;
+    }
+
+    public void setMobileNumber(String mobileNumber) {
+        this.mobileNumber = mobileNumber;
+    }
+
+    public Long getExpireTime() {
+        return expireTime;
+    }
+
+    public void setExpireTime(Long expireTime) {
+        this.expireTime = expireTime;
+    }
+
+    public Integer getValidPeriod() {
+        return validPeriod;
+    }
+
+    public void setValidPeriod(Integer validPeriod) {
+        this.validPeriod = validPeriod;
+    }
+
+    public String getVerifyCode() {
+        return verifyCode;
+    }
+
+    public void setVerifyCode(String verifyCode) {
+        this.verifyCode = verifyCode;
+    }
+}

+ 93 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/CloudMarkingExam.java

@@ -0,0 +1,93 @@
+package com.qmth.eds.common.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+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.Serializable;
+
+/**
+ * 云阅卷考试表
+ */
+@ApiModel(value = "CloudMarkingExam对象", description = "云阅卷考试表")
+public class CloudMarkingExam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "学校ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "考试id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Integer examId;
+
+    @ApiModelProperty(value = "名称")
+    private String examName;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableField("create_id")
+    @ApiModelProperty(value = "创建人")
+    private Long createId;
+
+    @TableField(value = "create_time", fill = FieldFill.INSERT)//新增执行
+    @ApiModelProperty(value = "创建时间")
+    private Long createTime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Integer getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Integer examId) {
+        this.examId = examId;
+    }
+
+    public String getExamName() {
+        return examName;
+    }
+
+    public void setExamName(String examName) {
+        this.examName = examName;
+    }
+
+    public Long getCreateId() {
+        return createId;
+    }
+
+    public void setCreateId(Long createId) {
+        this.createId = createId;
+    }
+
+    public Long getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
+    }
+}

+ 277 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/CloudMarkingScore.java

@@ -0,0 +1,277 @@
+package com.qmth.eds.common.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+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.Serializable;
+
+/**
+ * 云阅卷成绩表
+ */
+@ApiModel(value = "CloudMarkingScore对象", description = "云阅卷成绩表")
+public class CloudMarkingScore implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "学校ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "学期ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long semesterId;
+
+    @ApiModelProperty(value = "考试类型ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examTypeId;
+
+    @ApiModelProperty(value = "云阅卷考试id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Integer examId;
+
+    @ApiModelProperty(value = "云阅卷考试Code")
+    private String examCode;
+
+    @ApiModelProperty(value = "准考证号")
+    private String examNumber;
+
+    @ApiModelProperty(value = "学号")
+    private String studentCode;
+
+    @ApiModelProperty(value = "学生姓名")
+    private String name;
+
+    @ApiModelProperty(value = "课程代码")
+    private String subjectCode;
+
+    @ApiModelProperty(value = "课程名称")
+    private String subjectName;
+
+    @ApiModelProperty(value = "试卷类型")
+    private String paperType;
+
+    @ApiModelProperty(value = "学院")
+    private String college;
+
+    @ApiModelProperty(value = "班级")
+    private String className;
+
+    @ApiModelProperty(value = "老师")
+    private String teacher;
+
+    @ApiModelProperty(value = "状态")
+    private Integer status;
+
+    @ApiModelProperty(value = "原卷地址")
+    private String sheetUrls;
+
+    @ApiModelProperty(value = "总分")
+    private String totalScore;
+
+    @ApiModelProperty(value = "客观题总分")
+    private String objectiveScore;
+
+    @ApiModelProperty(value = "主观题总分")
+    private String subjectiveScore;
+
+    @ApiModelProperty(value = "客观题小题分")
+    private String objectiveScoreDetail;
+
+    @ApiModelProperty(value = "主观题小题分")
+    private String subjectiveScoreDetail;
+
+    @ApiModelProperty(value = "阅卷轨迹")
+    private String markTags;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getSemesterId() {
+        return semesterId;
+    }
+
+    public void setSemesterId(Long semesterId) {
+        this.semesterId = semesterId;
+    }
+
+    public Long getExamTypeId() {
+        return examTypeId;
+    }
+
+    public void setExamTypeId(Long examTypeId) {
+        this.examTypeId = examTypeId;
+    }
+
+    public Integer getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Integer examId) {
+        this.examId = examId;
+    }
+
+    public String getExamCode() {
+        return examCode;
+    }
+
+    public void setExamCode(String examCode) {
+        this.examCode = examCode;
+    }
+
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getSubjectCode() {
+        return subjectCode;
+    }
+
+    public void setSubjectCode(String subjectCode) {
+        this.subjectCode = subjectCode;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
+    public String getPaperType() {
+        return paperType;
+    }
+
+    public void setPaperType(String paperType) {
+        this.paperType = paperType;
+    }
+
+    public String getCollege() {
+        return college;
+    }
+
+    public void setCollege(String college) {
+        this.college = college;
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public void setClassName(String className) {
+        this.className = className;
+    }
+
+    public String getTeacher() {
+        return teacher;
+    }
+
+    public void setTeacher(String teacher) {
+        this.teacher = teacher;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public String getSheetUrls() {
+        return sheetUrls;
+    }
+
+    public void setSheetUrls(String sheetUrls) {
+        this.sheetUrls = sheetUrls;
+    }
+
+    public String getTotalScore() {
+        return totalScore;
+    }
+
+    public void setTotalScore(String totalScore) {
+        this.totalScore = totalScore;
+    }
+
+    public String getObjectiveScore() {
+        return objectiveScore;
+    }
+
+    public void setObjectiveScore(String objectiveScore) {
+        this.objectiveScore = objectiveScore;
+    }
+
+    public String getSubjectiveScore() {
+        return subjectiveScore;
+    }
+
+    public void setSubjectiveScore(String subjectiveScore) {
+        this.subjectiveScore = subjectiveScore;
+    }
+
+    public String getObjectiveScoreDetail() {
+        return objectiveScoreDetail;
+    }
+
+    public void setObjectiveScoreDetail(String objectiveScoreDetail) {
+        this.objectiveScoreDetail = objectiveScoreDetail;
+    }
+
+    public String getSubjectiveScoreDetail() {
+        return subjectiveScoreDetail;
+    }
+
+    public void setSubjectiveScoreDetail(String subjectiveScoreDetail) {
+        this.subjectiveScoreDetail = subjectiveScoreDetail;
+    }
+
+    public String getMarkTags() {
+        return markTags;
+    }
+
+    public void setMarkTags(String markTags) {
+        this.markTags = markTags;
+    }
+}

+ 178 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/CloudMarkingScoreForeign.java

@@ -0,0 +1,178 @@
+package com.qmth.eds.common.entity;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.baomidou.mybatisplus.annotation.TableId;
+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.Serializable;
+
+/**
+ * 对外输出成绩表
+ */
+@ApiModel(value = "CloudMarkingScoreForeign对象", description = "对外输出成绩表")
+public class CloudMarkingScoreForeign implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ExcelIgnore
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id")
+    private Long id;
+
+    @ExcelIgnore
+    @ApiModelProperty(value = "学校ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ExcelIgnore
+    @ApiModelProperty(value = "学期ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long semesterId;
+
+    @ExcelIgnore
+    @ApiModelProperty(value = "考试类型ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examTypeId;
+
+    @ApiModelProperty(value = "云阅卷考试id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Integer examId;
+
+    @ApiModelProperty(value = "学年")
+    private String xnm;
+
+    @ApiModelProperty(value = "学期")
+    private String xqm;
+
+    @ApiModelProperty(value = "教学班ID")
+    private String jxbId;
+
+    @ApiModelProperty(value = "课程号")
+    private String kch;
+
+    @ApiModelProperty(value = "课程名称")
+    private String kcmc;
+
+    @ApiModelProperty(value = "学号")
+    private String xh;
+
+    @ApiModelProperty(value = "成绩")
+    private String xmcj;
+
+    public CloudMarkingScoreForeign() {
+    }
+
+    public CloudMarkingScoreForeign(Long schoolId, Long semesterId, Long examTypeId, Integer examId, String xnm, String xqm, String jxbId, String kch, String kcmc, String xh, String xmcj) {
+        this.schoolId = schoolId;
+        this.semesterId = semesterId;
+        this.examTypeId = examTypeId;
+        this.examId = examId;
+        this.xnm = xnm;
+        this.xqm = xqm;
+        this.jxbId = jxbId;
+        this.kch = kch;
+        this.kcmc = kcmc;
+        this.xh = xh;
+        this.xmcj = xmcj;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getSemesterId() {
+        return semesterId;
+    }
+
+    public void setSemesterId(Long semesterId) {
+        this.semesterId = semesterId;
+    }
+
+    public Long getExamTypeId() {
+        return examTypeId;
+    }
+
+    public void setExamTypeId(Long examTypeId) {
+        this.examTypeId = examTypeId;
+    }
+
+    public Integer getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Integer examId) {
+        this.examId = examId;
+    }
+
+    public String getXnm() {
+        return xnm;
+    }
+
+    public void setXnm(String xnm) {
+        this.xnm = xnm;
+    }
+
+    public String getXqm() {
+        return xqm;
+    }
+
+    public void setXqm(String xqm) {
+        this.xqm = xqm;
+    }
+
+    public String getJxbId() {
+        return jxbId;
+    }
+
+    public void setJxbId(String jxbId) {
+        this.jxbId = jxbId;
+    }
+
+    public String getKch() {
+        return kch;
+    }
+
+    public void setKch(String kch) {
+        this.kch = kch;
+    }
+
+    public String getKcmc() {
+        return kcmc;
+    }
+
+    public void setKcmc(String kcmc) {
+        this.kcmc = kcmc;
+    }
+
+    public String getXh() {
+        return xh;
+    }
+
+    public void setXh(String xh) {
+        this.xh = xh;
+    }
+
+    public String getXmcj() {
+        return xmcj;
+    }
+
+    public void setXmcj(String xmcj) {
+        this.xmcj = xmcj;
+    }
+}

+ 127 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/ExamCourseMapping.java

@@ -0,0 +1,127 @@
+package com.qmth.eds.common.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.contant.SystemConstant;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * 武大考务数据和云阅卷课程代码映射关系表
+ */
+@ApiModel(value = "BasicCourseMapping对象", description = "武大考务数据和云阅卷课程代码映射关系表")
+public class ExamCourseMapping implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "学校ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "学期ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long semesterId;
+
+    @ApiModelProperty(value = "学期名称")
+    private String semesterName;
+
+
+    @ApiModelProperty(value = "考试类型ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examTypeId;
+
+    @ApiModelProperty(value = "考试类型名称")
+    private String examTypeName;
+
+    @ApiModelProperty(value = "武大考务数据课程代码")
+    private String syncCourseCode;
+
+    @ApiModelProperty(value = "云阅卷课程代码")
+    private String cloudMarkingCourseCode;
+
+    public ExamCourseMapping() {
+    }
+
+    public ExamCourseMapping(Long schoolId, Long semesterId, String semesterName, Long examTypeId, String examTypeName, String syncCourseCode, String cloudMarkingCourseCode) {
+        this.id = SystemConstant.getDbUuid();
+        this.schoolId = schoolId;
+        this.semesterId = semesterId;
+        this.semesterName = semesterName;
+        this.examTypeId = examTypeId;
+        this.examTypeName = examTypeName;
+        this.syncCourseCode = syncCourseCode;
+        this.cloudMarkingCourseCode = cloudMarkingCourseCode;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getSemesterId() {
+        return semesterId;
+    }
+
+    public void setSemesterId(Long semesterId) {
+        this.semesterId = semesterId;
+    }
+
+    public String getSemesterName() {
+        return semesterName;
+    }
+
+    public void setSemesterName(String semesterName) {
+        this.semesterName = semesterName;
+    }
+
+    public Long getExamTypeId() {
+        return examTypeId;
+    }
+
+    public void setExamTypeId(Long examTypeId) {
+        this.examTypeId = examTypeId;
+    }
+
+    public String getExamTypeName() {
+        return examTypeName;
+    }
+
+    public void setExamTypeName(String examTypeName) {
+        this.examTypeName = examTypeName;
+    }
+
+    public String getSyncCourseCode() {
+        return syncCourseCode;
+    }
+
+    public void setSyncCourseCode(String syncCourseCode) {
+        this.syncCourseCode = syncCourseCode;
+    }
+
+    public String getCloudMarkingCourseCode() {
+        return cloudMarkingCourseCode;
+    }
+
+    public void setCloudMarkingCourseCode(String cloudMarkingCourseCode) {
+        this.cloudMarkingCourseCode = cloudMarkingCourseCode;
+    }
+}

+ 87 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/ExamDownloadRecord.java

@@ -0,0 +1,87 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * 下载记录表
+ */
+@ApiModel(value = "ExamDownloadRecord对象", description = "下载记录表")
+public class ExamDownloadRecord extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "下载日期")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long operateTime;
+
+    @ApiModelProperty(value = "用户id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long userId;
+
+    @ApiModelProperty(value = "用户名称")
+    private String userName;
+
+    @ApiModelProperty(value = "考务数据同步记录表ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long syncTotalId;
+
+    @ApiModelProperty(value = "是否使用")
+    private Boolean used;
+
+    @ApiModelProperty(value = "用途")
+    private String useScene;
+
+    public Long getOperateTime() {
+        return operateTime;
+    }
+
+    public void setOperateTime(Long operateTime) {
+        this.operateTime = operateTime;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public Long getSyncTotalId() {
+        return syncTotalId;
+    }
+
+    public void setSyncTotalId(Long syncTotalId) {
+        this.syncTotalId = syncTotalId;
+    }
+
+    public Boolean getUsed() {
+        return used;
+    }
+
+    public void setUsed(Boolean used) {
+        this.used = used;
+    }
+
+    public String getUseScene() {
+        return useScene;
+    }
+
+    public void setUseScene(String useScene) {
+        this.useScene = useScene;
+    }
+}

+ 127 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/ExamScheduleTask.java

@@ -0,0 +1,127 @@
+package com.qmth.eds.common.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * 定时任务设置表
+ */
+@ApiModel(value = "ExamScheduleTask对象", description = "定时任务设置表")
+public class ExamScheduleTask extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "学校名称")
+    private String schoolName;
+
+    @ApiModelProperty(value = "学期id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @NotNull(message = "请选择学期")
+    private Long semesterId;
+
+    @ApiModelProperty(value = "学期名称")
+    private String semesterName;
+
+    @ApiModelProperty(value = "考试类型id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @NotNull(message = "请选择考试类型")
+    private Long examTypeId;
+
+    @ApiModelProperty(value = "考试类型名称")
+    private String examTypeName;
+
+    @ApiModelProperty(value = "定时任务开始时间")
+    @NotNull(message = "请选择定时任务开始时间")
+    private Long startTime;
+
+    @ApiModelProperty(value = "定时任务截止时间")
+    @NotNull(message = "请选择定时任务截止时间")
+    private Long endTime;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "操作人")
+    private String userName;
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public String getSchoolName() {
+        return schoolName;
+    }
+
+    public void setSchoolName(String schoolName) {
+        this.schoolName = schoolName;
+    }
+
+    public Long getSemesterId() {
+        return semesterId;
+    }
+
+    public void setSemesterId(Long semesterId) {
+        this.semesterId = semesterId;
+    }
+
+    public String getSemesterName() {
+        return semesterName;
+    }
+
+    public void setSemesterName(String semesterName) {
+        this.semesterName = semesterName;
+    }
+
+    public Long getExamTypeId() {
+        return examTypeId;
+    }
+
+    public void setExamTypeId(Long examTypeId) {
+        this.examTypeId = examTypeId;
+    }
+
+    public String getExamTypeName() {
+        return examTypeName;
+    }
+
+    public void setExamTypeName(String examTypeName) {
+        this.examTypeName = examTypeName;
+    }
+
+    public Long getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Long startTime) {
+        this.startTime = startTime;
+    }
+
+    public Long getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Long endTime) {
+        this.endTime = endTime;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+}

+ 41 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/ExamSemester.java

@@ -0,0 +1,41 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * 学期表
+ */
+@ApiModel(value = "ExamSemester对象", description = "学期表")
+public class ExamSemester extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "名称")
+    private String name;
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}

+ 279 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/ExamSyncStudent.java

@@ -0,0 +1,279 @@
+package com.qmth.eds.common.entity;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+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.Serializable;
+
+/**
+ * 学期表
+ */
+@ApiModel(value = "ExamSyncStudent对象", description = "考务数据同步考生信息表")
+public class ExamSyncStudent implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ExcelIgnore
+    @ApiModelProperty(value = "id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long id;
+
+    @ExcelIgnore
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ExcelIgnore
+    @ApiModelProperty(value = "汇总表ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examSyncTotalId;
+
+    @ApiModelProperty(value = "学年")
+    private String xnm;
+
+    @ApiModelProperty(value = "学期")
+    private String xqm;
+
+    @ApiModelProperty(value = "教学班id")
+    private String jxbId;
+
+    @ApiModelProperty(value = "教学班名称")
+    private String jxbmc;
+
+    @ApiModelProperty(value = "课程号")
+    private String kch;
+
+    @ApiModelProperty(value = "课程名称")
+    private String kcmc;
+
+    @ApiModelProperty(value = "工号")
+    private String jgh;
+
+    @ApiModelProperty(value = "姓名")
+    private String xm;
+
+    @ApiModelProperty(value = "开课部门")
+    private String kkbm;
+
+    @ApiModelProperty(value = "学分")
+    private String xf;
+
+    @ApiModelProperty(value = "学号")
+    private String xh;
+
+    @ApiModelProperty(value = "学生姓名")
+    private String xsxm;
+
+    @ApiModelProperty(value = "学院")
+    private String jgmc;
+
+    @ApiModelProperty(value = "专业")
+    private String zymc;
+
+    @ApiModelProperty(value = "重修标记")
+    private String cxbj;
+
+    @ApiModelProperty(value = "年级")
+    private String njdmId;
+
+    @ApiModelProperty(value = "座位号")
+    private String zwh;
+
+    @ApiModelProperty(value = "场地名称")
+    private String cdmc;
+
+    @ApiModelProperty(value = "考试备注")
+    private String ksbz;
+
+    @ApiModelProperty(value = "对应云阅卷课程代码")
+    @TableField(exist = false)
+    private String cloudMarkingCourseCode;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getExamSyncTotalId() {
+        return examSyncTotalId;
+    }
+
+    public void setExamSyncTotalId(Long examSyncTotalId) {
+        this.examSyncTotalId = examSyncTotalId;
+    }
+
+    public String getXnm() {
+        return xnm;
+    }
+
+    public void setXnm(String xnm) {
+        this.xnm = xnm;
+    }
+
+    public String getXqm() {
+        return xqm;
+    }
+
+    public void setXqm(String xqm) {
+        this.xqm = xqm;
+    }
+
+    public String getJxbId() {
+        return jxbId;
+    }
+
+    public void setJxbId(String jxbId) {
+        this.jxbId = jxbId;
+    }
+
+    public String getJxbmc() {
+        return jxbmc;
+    }
+
+    public void setJxbmc(String jxbmc) {
+        this.jxbmc = jxbmc;
+    }
+
+    public String getKch() {
+        return kch;
+    }
+
+    public void setKch(String kch) {
+        this.kch = kch;
+    }
+
+    public String getKcmc() {
+        return kcmc;
+    }
+
+    public void setKcmc(String kcmc) {
+        this.kcmc = kcmc;
+    }
+
+    public String getJgh() {
+        return jgh;
+    }
+
+    public void setJgh(String jgh) {
+        this.jgh = jgh;
+    }
+
+    public String getXm() {
+        return xm;
+    }
+
+    public void setXm(String xm) {
+        this.xm = xm;
+    }
+
+    public String getKkbm() {
+        return kkbm;
+    }
+
+    public void setKkbm(String kkbm) {
+        this.kkbm = kkbm;
+    }
+
+    public String getXf() {
+        return xf;
+    }
+
+    public void setXf(String xf) {
+        this.xf = xf;
+    }
+
+    public String getXh() {
+        return xh;
+    }
+
+    public void setXh(String xh) {
+        this.xh = xh;
+    }
+
+    public String getXsxm() {
+        return xsxm;
+    }
+
+    public void setXsxm(String xsxm) {
+        this.xsxm = xsxm;
+    }
+
+    public String getJgmc() {
+        return jgmc;
+    }
+
+    public void setJgmc(String jgmc) {
+        this.jgmc = jgmc;
+    }
+
+    public String getZymc() {
+        return zymc;
+    }
+
+    public void setZymc(String zymc) {
+        this.zymc = zymc;
+    }
+
+    public String getCxbj() {
+        return cxbj;
+    }
+
+    public void setCxbj(String cxbj) {
+        this.cxbj = cxbj;
+    }
+
+    public String getNjdmId() {
+        return njdmId;
+    }
+
+    public void setNjdmId(String njdmId) {
+        this.njdmId = njdmId;
+    }
+
+    public String getZwh() {
+        return zwh;
+    }
+
+    public void setZwh(String zwh) {
+        this.zwh = zwh;
+    }
+
+    public String getCdmc() {
+        return cdmc;
+    }
+
+    public void setCdmc(String cdmc) {
+        this.cdmc = cdmc;
+    }
+
+    public String getKsbz() {
+        return ksbz;
+    }
+
+    public void setKsbz(String ksbz) {
+        this.ksbz = ksbz;
+    }
+
+    public String getCloudMarkingCourseCode() {
+        return cloudMarkingCourseCode;
+    }
+
+    public void setCloudMarkingCourseCode(String cloudMarkingCourseCode) {
+        this.cloudMarkingCourseCode = cloudMarkingCourseCode;
+    }
+}

+ 262 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/ExamSyncStudentTemp.java

@@ -0,0 +1,262 @@
+package com.qmth.eds.common.entity;
+
+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.Serializable;
+
+/**
+ * 学期表
+ */
+@ApiModel(value = "ExamSyncStudent对象", description = "考务数据同步考生信息表")
+public class ExamSyncStudentTemp implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long id;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "汇总表ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examSyncTotalId;
+
+    @ApiModelProperty(value = "学年")
+    private String xnm;
+
+    @ApiModelProperty(value = "学期")
+    private String xqm;
+
+    @ApiModelProperty(value = "教学班id")
+    private String jxbId;
+
+    @ApiModelProperty(value = "教学班名称")
+    private String jxbmc;
+
+    @ApiModelProperty(value = "课程号")
+    private String kch;
+
+    @ApiModelProperty(value = "课程名称")
+    private String kcmc;
+
+    @ApiModelProperty(value = "工号")
+    private String jgh;
+
+    @ApiModelProperty(value = "姓名")
+    private String xm;
+
+    @ApiModelProperty(value = "开课部门")
+    private String kkbm;
+
+    @ApiModelProperty(value = "学分")
+    private String xf;
+
+    @ApiModelProperty(value = "学号")
+    private String xh;
+
+    @ApiModelProperty(value = "学生姓名")
+    private String xsxm;
+
+    @ApiModelProperty(value = "学院")
+    private String jgmc;
+
+    @ApiModelProperty(value = "专业")
+    private String zymc;
+
+    @ApiModelProperty(value = "重修标记")
+    private String cxbj;
+
+    @ApiModelProperty(value = "年级")
+    private String njdmId;
+
+    @ApiModelProperty(value = "座位号")
+    private String zwh;
+
+    @ApiModelProperty(value = "场地名称")
+    private String cdmc;
+
+    @ApiModelProperty(value = "考试备注")
+    private String ksbz;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getExamSyncTotalId() {
+        return examSyncTotalId;
+    }
+
+    public void setExamSyncTotalId(Long examSyncTotalId) {
+        this.examSyncTotalId = examSyncTotalId;
+    }
+
+    public String getXnm() {
+        return xnm;
+    }
+
+    public void setXnm(String xnm) {
+        this.xnm = xnm;
+    }
+
+    public String getXqm() {
+        return xqm;
+    }
+
+    public void setXqm(String xqm) {
+        this.xqm = xqm;
+    }
+
+    public String getJxbId() {
+        return jxbId;
+    }
+
+    public void setJxbId(String jxbId) {
+        this.jxbId = jxbId;
+    }
+
+    public String getJxbmc() {
+        return jxbmc;
+    }
+
+    public void setJxbmc(String jxbmc) {
+        this.jxbmc = jxbmc;
+    }
+
+    public String getKch() {
+        return kch;
+    }
+
+    public void setKch(String kch) {
+        this.kch = kch;
+    }
+
+    public String getKcmc() {
+        return kcmc;
+    }
+
+    public void setKcmc(String kcmc) {
+        this.kcmc = kcmc;
+    }
+
+    public String getJgh() {
+        return jgh;
+    }
+
+    public void setJgh(String jgh) {
+        this.jgh = jgh;
+    }
+
+    public String getXm() {
+        return xm;
+    }
+
+    public void setXm(String xm) {
+        this.xm = xm;
+    }
+
+    public String getKkbm() {
+        return kkbm;
+    }
+
+    public void setKkbm(String kkbm) {
+        this.kkbm = kkbm;
+    }
+
+    public String getXf() {
+        return xf;
+    }
+
+    public void setXf(String xf) {
+        this.xf = xf;
+    }
+
+    public String getXh() {
+        return xh;
+    }
+
+    public void setXh(String xh) {
+        this.xh = xh;
+    }
+
+    public String getXsxm() {
+        return xsxm;
+    }
+
+    public void setXsxm(String xsxm) {
+        this.xsxm = xsxm;
+    }
+
+    public String getJgmc() {
+        return jgmc;
+    }
+
+    public void setJgmc(String jgmc) {
+        this.jgmc = jgmc;
+    }
+
+    public String getZymc() {
+        return zymc;
+    }
+
+    public void setZymc(String zymc) {
+        this.zymc = zymc;
+    }
+
+    public String getCxbj() {
+        return cxbj;
+    }
+
+    public void setCxbj(String cxbj) {
+        this.cxbj = cxbj;
+    }
+
+    public String getNjdmId() {
+        return njdmId;
+    }
+
+    public void setNjdmId(String njdmId) {
+        this.njdmId = njdmId;
+    }
+
+    public String getZwh() {
+        return zwh;
+    }
+
+    public void setZwh(String zwh) {
+        this.zwh = zwh;
+    }
+
+    public String getCdmc() {
+        return cdmc;
+    }
+
+    public void setCdmc(String cdmc) {
+        this.cdmc = cdmc;
+    }
+
+    public String getKsbz() {
+        return ksbz;
+    }
+
+    public void setKsbz(String ksbz) {
+        this.ksbz = ksbz;
+    }
+}

+ 194 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/ExamSyncTotal.java

@@ -0,0 +1,194 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * 学期表
+ */
+@ApiModel(value = "ExamSemester对象", description = "学期表")
+public class ExamSyncTotal extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "同步日期")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long syncDate;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "学校名称")
+    private String schoolName;
+
+    @ApiModelProperty(value = "学期id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long semesterId;
+
+    @ApiModelProperty(value = "学期名称")
+    private String semesterName;
+
+    @ApiModelProperty(value = "考试类型id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examTypeId;
+
+    @ApiModelProperty(value = "考试类型名称")
+    private String examTypeName;
+
+    @ApiModelProperty(value = "学院数量")
+    private Integer colleges;
+
+    @ApiModelProperty(value = "科目数量")
+    private Integer subjects;
+
+    @ApiModelProperty(value = "科次")
+    private Integer students;
+
+    @ApiModelProperty(value = "文件名称")
+    private String fileName;
+
+    @ApiModelProperty(value = "文件地址")
+    private String filePath;
+
+    @ApiModelProperty(value = "是否可以下载")
+    private Boolean downloadStatus;
+
+    @ApiModelProperty(value = "数据md5值")
+    private String dataMd5;
+
+    public ExamSyncTotal() {
+    }
+
+    public ExamSyncTotal(Long syncDate, Long schoolId, String schoolName, Long semesterId, String semesterName, Long examTypeId, String examTypeName, Integer colleges, Integer subjects, Integer students, String dataMd5) {
+        this.syncDate = syncDate;
+        this.schoolId = schoolId;
+        this.schoolName = schoolName;
+        this.semesterId = semesterId;
+        this.semesterName = semesterName;
+        this.examTypeId = examTypeId;
+        this.examTypeName = examTypeName;
+        this.colleges = colleges;
+        this.subjects = subjects;
+        this.students = students;
+        this.dataMd5 = dataMd5;
+        this.downloadStatus = true;
+    }
+
+    public Long getSyncDate() {
+        return syncDate;
+    }
+
+    public void setSyncDate(Long syncDate) {
+        this.syncDate = syncDate;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public String getSchoolName() {
+        return schoolName;
+    }
+
+    public void setSchoolName(String schoolName) {
+        this.schoolName = schoolName;
+    }
+
+    public Long getSemesterId() {
+        return semesterId;
+    }
+
+    public void setSemesterId(Long semesterId) {
+        this.semesterId = semesterId;
+    }
+
+    public String getSemesterName() {
+        return semesterName;
+    }
+
+    public void setSemesterName(String semesterName) {
+        this.semesterName = semesterName;
+    }
+
+    public Long getExamTypeId() {
+        return examTypeId;
+    }
+
+    public void setExamTypeId(Long examTypeId) {
+        this.examTypeId = examTypeId;
+    }
+
+    public String getExamTypeName() {
+        return examTypeName;
+    }
+
+    public void setExamTypeName(String examTypeName) {
+        this.examTypeName = examTypeName;
+    }
+
+    public Integer getColleges() {
+        return colleges;
+    }
+
+    public void setColleges(Integer colleges) {
+        this.colleges = colleges;
+    }
+
+    public Integer getSubjects() {
+        return subjects;
+    }
+
+    public void setSubjects(Integer subjects) {
+        this.subjects = subjects;
+    }
+
+    public Integer getStudents() {
+        return students;
+    }
+
+    public void setStudents(Integer students) {
+        this.students = students;
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
+    }
+
+    public String getFilePath() {
+        return filePath;
+    }
+
+    public void setFilePath(String filePath) {
+        this.filePath = filePath;
+    }
+
+    public Boolean getDownloadStatus() {
+        return downloadStatus;
+    }
+
+    public void setDownloadStatus(Boolean downloadStatus) {
+        this.downloadStatus = downloadStatus;
+    }
+
+    public String getDataMd5() {
+        return dataMd5;
+    }
+
+    public void setDataMd5(String dataMd5) {
+        this.dataMd5 = dataMd5;
+    }
+}

+ 41 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/ExamType.java

@@ -0,0 +1,41 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * 考试类型表
+ */
+@ApiModel(value = "ExamType对象", description = "考试类型表")
+public class ExamType extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "名称")
+    private String name;
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}

+ 108 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/SysCollege.java

@@ -0,0 +1,108 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * <p>
+ * 学院
+ * </p>
+ */
+@ApiModel(value = "SysCollege对象", description = "学院表")
+public class SysCollege extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "主键")
+    private Long schoolId;
+
+    @ApiModelProperty(value = "学校编码")
+    private String code;
+
+    @ApiModelProperty(value = "学校名称")
+    private String name;
+
+    @ApiModelProperty(value = "访问key")
+    private String accessKey;
+
+    @ApiModelProperty(value = "访问秘钥")
+    private String accessSecret;
+
+    public SysCollege() {
+
+    }
+
+    public SysCollege(Long id, Long schoolId, String code, String name, String accessKey, String accessSecret) {
+        this.schoolId = schoolId;
+        this.code = code;
+        this.name = name;
+        this.accessKey = accessKey;
+        this.accessSecret = accessSecret;
+        setId(id);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        SysCollege that = (SysCollege) o;
+        return code.equals(that.code) && name.equals(that.name) && accessKey.equals(that.accessKey) && accessSecret.equals(that.accessSecret);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(code, name, accessKey, accessSecret);
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getAccessKey() {
+        return accessKey;
+    }
+
+    public void setAccessKey(String accessKey) {
+        this.accessKey = accessKey;
+    }
+
+    public String getAccessSecret() {
+        return accessSecret;
+    }
+
+    public void setAccessSecret(String accessSecret) {
+        this.accessSecret = accessSecret;
+    }
+
+}

+ 91 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/SysConfig.java

@@ -0,0 +1,91 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 参数表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "SysConfig对象", description = "参数表")
+public class SysConfig extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "机构id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long orgId;
+
+    @ApiModelProperty(value = "参数键名")
+    private String configKey;
+
+    @ApiModelProperty(value = "参数名称")
+    private String configName;
+
+    @ApiModelProperty(value = "参数键值")
+    private String configValue;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(Long orgId) {
+        this.orgId = orgId;
+    }
+
+    public String getConfigKey() {
+        return configKey;
+    }
+
+    public void setConfigKey(String configKey) {
+        this.configKey = configKey;
+    }
+
+    public String getConfigName() {
+        return configName;
+    }
+
+    public void setConfigName(String configName) {
+        this.configName = configName;
+    }
+
+    public String getConfigValue() {
+        return configValue;
+    }
+
+    public void setConfigValue(String configValue) {
+        this.configValue = configValue;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+}

+ 126 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/SysOrg.java

@@ -0,0 +1,126 @@
+package com.qmth.eds.common.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import com.qmth.eds.common.contant.SystemConstant;
+import com.qmth.eds.common.enums.OrgTypeEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * <p>
+ * 学校组织架构
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "SysOrg对象", description = "学校组织架构")
+public class SysOrg extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "类型,SCHOOL:学校,COLLEGE:学院,FACULTY:院系,TEACHING_ROOM:教研室,PRINTING_HOUSE:印刷厂")
+    @TableField(value = "type", updateStrategy = FieldStrategy.IGNORED)
+    private OrgTypeEnum type;
+
+    @ApiModelProperty(value = "机构代码")
+    private String code;
+
+    @ApiModelProperty(value = "机构名称")
+    private String name;
+
+    @ApiModelProperty(value = "上级机构id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long parentId;
+
+    @ApiModelProperty(value = "是否启用,0:停用,1:启用")
+    private Boolean enable;
+
+    public SysOrg() {
+
+    }
+
+    public SysOrg(Long schoolId, String name) {
+        setId(SystemConstant.getDbUuid());
+        this.schoolId = schoolId;
+        this.type = OrgTypeEnum.SCHOOL;
+        this.name = name;
+        this.enable = true;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        SysOrg sysOrg = (SysOrg) o;
+        return schoolId.equals(sysOrg.schoolId) && code.equals(sysOrg.code) && type == sysOrg.type && name.equals(sysOrg.name) && parentId.equals(sysOrg.parentId) && enable.equals(sysOrg.enable);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(schoolId, code, type, name, parentId, enable);
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public OrgTypeEnum getType() {
+        return type;
+    }
+
+    public void setType(OrgTypeEnum type) {
+        this.type = type;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+}

+ 147 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/SysPrivilege.java

@@ -0,0 +1,147 @@
+package com.qmth.eds.common.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+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.Serializable;
+
+/**
+ * <p>
+ * 菜单权限表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "SysPrivilege对象", description = "菜单权限表")
+public class SysPrivilege implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableId(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "菜单名称")
+    private String name;
+
+    @ApiModelProperty(value = "URL地址")
+    private String url;
+
+    @ApiModelProperty(value = "类型,MENU:菜单,BUTTON:按钮,LINK:链接,URL:接口地址,LIST:列表,CONDITION:查询条件,TAB:选项卡")
+    private String type;
+
+    @ApiModelProperty(value = "上级菜单")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long parentId;
+
+    @ApiModelProperty(value = "序号")
+    private Integer sequence;
+
+    @ApiModelProperty(value = "属性,NO_AUTH:无需鉴权,AUTH:鉴权,SYS:系统公用")
+    private String property;
+
+    @ApiModelProperty(value = "关联属性,type为URL且property为AUTH才有")
+    private String related;
+
+    @ApiModelProperty(value = "是否启用,0:停用,1:启用")
+    private Boolean enable;
+
+    @ApiModelProperty(value = "默认权限,0:否,1:是")
+    private Boolean defaultAuth;
+
+    @ApiModelProperty(value = "是否前端展示")
+    private Boolean frontDisplay;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public Integer getSequence() {
+        return sequence;
+    }
+
+    public void setSequence(Integer sequence) {
+        this.sequence = sequence;
+    }
+
+    public String getProperty() {
+        return property;
+    }
+
+    public void setProperty(String property) {
+        this.property = property;
+    }
+
+    public String getRelated() {
+        return related;
+    }
+
+    public void setRelated(String related) {
+        this.related = related;
+    }
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+
+    public Boolean getDefaultAuth() {
+        return defaultAuth;
+    }
+
+    public void setDefaultAuth(Boolean defaultAuth) {
+        this.defaultAuth = defaultAuth;
+    }
+
+    public Boolean getFrontDisplay() {
+        return frontDisplay;
+    }
+
+    public void setFrontDisplay(Boolean frontDisplay) {
+        this.frontDisplay = frontDisplay;
+    }
+}

+ 81 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/SysRole.java

@@ -0,0 +1,81 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import com.qmth.eds.common.enums.RoleTypeEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 角色表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "SysRole对象", description = "角色表")
+public class SysRole extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "机构id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long orgId;
+
+    @ApiModelProperty(value = "角色名称")
+    private String name;
+
+    @ApiModelProperty(value = "是否启用,0:停用,1:启用")
+    private Boolean enable;
+
+    @ApiModelProperty(value = "角色类别,ADMIN:超级管理员,SCHOOL_ADMIN:管理员:EXAM_TEACHER:考务老师,QUESTION_TEACHER:命题老师,CUSTOMER:客服人员,PRINTER:印刷人员,CUSTOM:自定义")
+    private RoleTypeEnum type;
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(Long orgId) {
+        this.orgId = orgId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+
+    public RoleTypeEnum getType() {
+        return type;
+    }
+
+    public void setType(RoleTypeEnum type) {
+        this.type = type;
+    }
+}

+ 71 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/SysRolePrivilege.java

@@ -0,0 +1,71 @@
+package com.qmth.eds.common.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+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.Serializable;
+
+/**
+ * <p>
+ * 角色和菜单关联表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value="SysRolePrivilege对象", description="角色和菜单关联表")
+public class SysRolePrivilege implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableId(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "角色id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long roleId;
+
+    @ApiModelProperty(value = "菜单id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long privilegeId;
+
+    @ApiModelProperty(value = "是否启用,0:停用,1:启用")
+    private Boolean enable;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
+
+    public Long getPrivilegeId() {
+        return privilegeId;
+    }
+
+    public void setPrivilegeId(Long privilegeId) {
+        this.privilegeId = privilegeId;
+    }
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+}

+ 167 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/SysUser.java

@@ -0,0 +1,167 @@
+package com.qmth.eds.common.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 用户表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "SysUser对象", description = "用户表")
+public class SysUser extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "用户名")
+    @NotBlank(message = "请输入用户名")
+    @Length(message = "用户名不能超过{max}个字符", max = 50)
+    private String loginName;
+
+    @ApiModelProperty(value = "姓名")
+    @NotBlank(message = "请输入姓名")
+    @Length(message = "姓名不能超过{max}个字符", max = 50)
+    private String realName;
+
+    @ApiModelProperty(value = "工号")
+    private String code;
+
+    @ApiModelProperty(value = "密码")
+    private String password;
+
+    @ApiModelProperty(value = "手机号")
+    @NotBlank(message = "请输入手机号码")
+    @Length(message = "手机号码不能超过{max}个字符", max = 11)
+    private String mobileNumber;
+
+    @ApiModelProperty(value = "机构id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long orgId;
+
+    @ApiModelProperty(value = "是否启用,0:停用,1:启用")
+    private Boolean enable;
+
+    @ApiModelProperty(value = "密码修改次数,默认为0")
+    private Integer pwdCount;
+
+    @ApiModelProperty(value = "密码修改时间")
+    private Long pwdUpdateTime;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @TableField(exist = false)
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long roleId;
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public String getLoginName() {
+        return loginName;
+    }
+
+    public void setLoginName(String loginName) {
+        this.loginName = loginName;
+    }
+
+    public String getRealName() {
+        return realName;
+    }
+
+    public void setRealName(String realName) {
+        this.realName = realName;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getMobileNumber() {
+        return mobileNumber;
+    }
+
+    public void setMobileNumber(String mobileNumber) {
+        this.mobileNumber = mobileNumber;
+    }
+
+    public Long getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(Long orgId) {
+        this.orgId = orgId;
+    }
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+
+    public Integer getPwdCount() {
+        return pwdCount;
+    }
+
+    public void setPwdCount(Integer pwdCount) {
+        this.pwdCount = pwdCount;
+    }
+
+    public Long getPwdUpdateTime() {
+        return pwdUpdateTime;
+    }
+
+    public void setPwdUpdateTime(Long pwdUpdateTime) {
+        this.pwdUpdateTime = pwdUpdateTime;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public Long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
+}

+ 101 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/SysUserRole.java

@@ -0,0 +1,101 @@
+package com.qmth.eds.common.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.contant.SystemConstant;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 用户和角色关联表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "SysUserRole对象", description = "用户和角色关联表")
+public class SysUserRole implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableId(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "用户id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long userId;
+
+    @ApiModelProperty(value = "角色id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long roleId;
+
+    @ApiModelProperty(value = "权限id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long privilegeId;
+
+    @ApiModelProperty(value = "是否启用,0:停用,1:启用")
+    private Boolean enable;
+
+    public SysUserRole() {
+
+    }
+
+    public SysUserRole(Long userId, Long roleId) {
+        this.id = SystemConstant.getDbUuid();
+        this.userId = userId;
+        this.roleId = roleId;
+    }
+
+    public SysUserRole(Long userId, Long roleId, Long privilegeId) {
+        this.id = SystemConstant.getDbUuid();
+        this.userId = userId;
+        this.roleId = roleId;
+        this.privilegeId = privilegeId;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public Long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
+
+    public Long getPrivilegeId() {
+        return privilegeId;
+    }
+
+    public void setPrivilegeId(Long privilegeId) {
+        this.privilegeId = privilegeId;
+    }
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+}

+ 216 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/TBSession.java

@@ -0,0 +1,216 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.enums.AppSourceEnum;
+import com.qmth.eds.common.util.ServletUtil;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 会话表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "TBSession对象", description = "会话表")
+public class TBSession implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键")
+    private String id;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "机构id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long orgId;
+
+    @ApiModelProperty(value = "用户标识")
+    private String identity;
+
+    @ApiModelProperty(value = "用户类型")
+    private String type;
+
+    @ApiModelProperty(value = "访问来源")
+    private String source;
+
+    @ApiModelProperty(value = "设备分类")
+    private String platform;
+
+    @ApiModelProperty(value = "设备标识")
+    private String deviceId;
+
+    @ApiModelProperty(value = "登录IP地址")
+    private String address;
+
+    @ApiModelProperty(value = "访问令牌")
+    private String accessToken;
+
+    @ApiModelProperty(value = "最近访问时间")
+    private Long lastAccessTime;
+
+    @ApiModelProperty(value = "最近访问IP地址")
+    private String lastAccessIp;
+
+    @ApiModelProperty(value = "令牌更新时间")
+    private Long updateTime;
+
+    @ApiModelProperty(value = "令牌强制失效时间")
+    private Long expireTime;
+
+    @ApiModelProperty(value = "应用来源")
+    private AppSourceEnum appSource;
+
+    public TBSession() {
+
+    }
+
+    public TBSession(Long schoolId, String id, String identity, String type, String source, String platform, String deviceId, String address, String accessToken, Long expireTime, AppSourceEnum appSource) {
+        this.schoolId = schoolId;
+        this.id = id;
+        this.identity = identity;
+        this.type = type;
+        this.source = source;
+        this.platform = platform;
+        this.deviceId = deviceId;
+        this.address = address;
+        this.accessToken = accessToken;
+        this.expireTime = expireTime;
+        this.lastAccessTime = System.currentTimeMillis();
+        this.lastAccessIp = address;
+        this.appSource = appSource;
+    }
+
+    public void setLastInfo() {
+        this.lastAccessTime = System.currentTimeMillis();
+        this.lastAccessIp = ServletUtil.getRequest().getLocalAddr();
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(Long orgId) {
+        this.orgId = orgId;
+    }
+
+    public String getIdentity() {
+        return identity;
+    }
+
+    public void setIdentity(String identity) {
+        this.identity = identity;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getSource() {
+        return source;
+    }
+
+    public void setSource(String source) {
+        this.source = source;
+    }
+
+    public String getPlatform() {
+        return platform;
+    }
+
+    public void setPlatform(String platform) {
+        this.platform = platform;
+    }
+
+    public String getDeviceId() {
+        return deviceId;
+    }
+
+    public void setDeviceId(String deviceId) {
+        this.deviceId = deviceId;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public String getAccessToken() {
+        return accessToken;
+    }
+
+    public void setAccessToken(String accessToken) {
+        this.accessToken = accessToken;
+    }
+
+    public Long getLastAccessTime() {
+        return lastAccessTime;
+    }
+
+    public void setLastAccessTime(Long lastAccessTime) {
+        this.lastAccessTime = lastAccessTime;
+    }
+
+    public String getLastAccessIp() {
+        return lastAccessIp;
+    }
+
+    public void setLastAccessIp(String lastAccessIp) {
+        this.lastAccessIp = lastAccessIp;
+    }
+
+    public Long getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Long updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public Long getExpireTime() {
+        return expireTime;
+    }
+
+    public void setExpireTime(Long expireTime) {
+        this.expireTime = expireTime;
+    }
+
+    public AppSourceEnum getAppSource() {
+        return appSource;
+    }
+
+    public void setAppSource(AppSourceEnum appSource) {
+        this.appSource = appSource;
+    }
+}

+ 151 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/TBSyncTask.java

@@ -0,0 +1,151 @@
+package com.qmth.eds.common.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import com.qmth.eds.common.enums.TaskResultEnum;
+import com.qmth.eds.common.enums.TaskStatusEnum;
+import com.qmth.eds.common.enums.TaskTypeEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 同步任务表
+ * </p>
+ */
+@ApiModel(value = "TBSyncTask对象", description = "同步任务表")
+public class TBSyncTask extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableField("school_id")
+    private Long schoolId;
+
+    @ApiModelProperty(value = "学期ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableField(value = "semester_id")
+    private Long semesterId;
+
+    @ApiModelProperty(value = "考试类型ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableField("exam_type_id")
+    private Long examTypeId;
+
+    @ApiModelProperty(value = "任务类型")
+    @TableField(value = "type")
+    private TaskTypeEnum type;
+
+    @ApiModelProperty(value = "执行时间")
+    @TableField(value = "sync_time")
+    private Long syncTime;
+
+    @ApiModelProperty(value = "任务状态,INIT:未开始,RUNNING:进行中,FINISH:已完成")
+    @TableField(value = "status")
+    private TaskStatusEnum status;
+
+    @ApiModelProperty(value = "数据结果,SUCCESS:成功,ERROR:失败")
+    @TableField(value = "result")
+    private TaskResultEnum result;
+
+    @ApiModelProperty(value = "备注")
+    @TableField(value = "remark")
+    private String remark;
+
+    @ApiModelProperty(value = "错误原因")
+    @TableField(value = "error_message", updateStrategy = FieldStrategy.IGNORED)
+    private String errorMessage;
+
+    public TBSyncTask() {
+    }
+
+    public TBSyncTask(Long schoolId, Long semesterId, Long examTypeId, TaskTypeEnum type, String remark, Long createId) {
+        this.schoolId = schoolId;
+        this.semesterId = semesterId;
+        this.examTypeId = examTypeId;
+        this.type = type;
+        this.remark = remark;
+        this.status = TaskStatusEnum.INIT;
+        this.syncTime = System.currentTimeMillis();
+        this.setCreateId(createId);
+        this.setCreateTime(System.currentTimeMillis());
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getSemesterId() {
+        return semesterId;
+    }
+
+    public void setSemesterId(Long semesterId) {
+        this.semesterId = semesterId;
+    }
+
+    public Long getExamTypeId() {
+        return examTypeId;
+    }
+
+    public void setExamTypeId(Long examTypeId) {
+        this.examTypeId = examTypeId;
+    }
+
+    public TaskTypeEnum getType() {
+        return type;
+    }
+
+    public void setType(TaskTypeEnum type) {
+        this.type = type;
+    }
+
+    public Long getSyncTime() {
+        return syncTime;
+    }
+
+    public void setSyncTime(Long syncTime) {
+        this.syncTime = syncTime;
+    }
+
+    public TaskStatusEnum getStatus() {
+        return status;
+    }
+
+    public void setStatus(TaskStatusEnum status) {
+        this.status = status;
+    }
+
+    public TaskResultEnum getResult() {
+        return result;
+    }
+
+    public void setResult(TaskResultEnum result) {
+        this.result = result;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage) {
+        this.errorMessage = errorMessage;
+    }
+}

+ 224 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/TBTask.java

@@ -0,0 +1,224 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 导入导出任务表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "TBTask对象", description = "导入导出任务表")
+public class TBTask extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "任务类型")
+    private String type;
+
+    @ApiModelProperty(value = "关联业务对象id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long entityId;
+
+    @ApiModelProperty(value = "任务状态,INIT:未开始,RUNNING:进行中,FINISH:已完成")
+    private String status;
+
+    @ApiModelProperty(value = "实时摘要信息")
+    private String summary;
+
+    @ApiModelProperty(value = "执行进度")
+    private Double progress;
+
+    @ApiModelProperty(value = "数据结果,SUCCESS:成功,ERROR:失败")
+    private String result;
+
+    @ApiModelProperty(value = "是否启用,false:停用,true:启用")
+    private Boolean enable;
+
+    @ApiModelProperty(value = "导入文件名")
+    private String importFileName;
+
+    @ApiModelProperty(value = "导入文件路径")
+    private String importFilePath;
+
+    @ApiModelProperty(value = "导出文件路径")
+    private String resultFilePath;
+
+    @ApiModelProperty(value = "报告路径")
+    private String reportFilePath;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "机构id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long orgId;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "实体名称")
+    private String objName;
+
+    @ApiModelProperty(value = "重试次数")
+    private Integer resetCount;
+
+    @ApiModelProperty(value = "更新版本号")
+    private Integer version;
+
+    @ApiModelProperty(value = "人工错误原因")
+    private String errorMessage;
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getSummary() {
+        return summary;
+    }
+
+    public void setSummary(String summary) {
+        this.summary = summary;
+    }
+
+    public Double getProgress() {
+        return progress;
+    }
+
+    public void setProgress(Double progress) {
+        this.progress = progress;
+    }
+
+    public String getResult() {
+        return result;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+
+    public String getImportFileName() {
+        return importFileName;
+    }
+
+    public void setImportFileName(String importFileName) {
+        this.importFileName = importFileName;
+    }
+
+    public String getImportFilePath() {
+        return importFilePath;
+    }
+
+    public void setImportFilePath(String importFilePath) {
+        this.importFilePath = importFilePath;
+    }
+
+    public String getResultFilePath() {
+        return resultFilePath;
+    }
+
+    public void setResultFilePath(String resultFilePath) {
+        this.resultFilePath = resultFilePath;
+    }
+
+    public String getReportFilePath() {
+        return reportFilePath;
+    }
+
+    public void setReportFilePath(String reportFilePath) {
+        this.reportFilePath = reportFilePath;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(Long orgId) {
+        this.orgId = orgId;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getObjName() {
+        return objName;
+    }
+
+    public void setObjName(String objName) {
+        this.objName = objName;
+    }
+
+    public Integer getResetCount() {
+        return resetCount;
+    }
+
+    public void setResetCount(Integer resetCount) {
+        this.resetCount = resetCount;
+    }
+
+    public Integer getVersion() {
+        return version;
+    }
+
+    public void setVersion(Integer version) {
+        this.version = version;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage) {
+        this.errorMessage = errorMessage;
+    }
+}

+ 94 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/TGError.java

@@ -0,0 +1,94 @@
+package com.qmth.eds.common.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+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.Serializable;
+
+/**
+ * <p>
+ * 全局异常错误信息表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-05-14
+ */
+@ApiModel(value = "TGError对象", description = "全局异常错误信息表")
+public class TGError implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableId(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "机构id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long orgId;
+
+    @ApiModelProperty(value = "实体id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long objId;
+
+    @ApiModelProperty(value = "实时摘要信息")
+    private String summary;
+
+    @ApiModelProperty(value = "创建时间")
+    private Long createTime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(Long orgId) {
+        this.orgId = orgId;
+    }
+
+    public Long getObjId() {
+        return objId;
+    }
+
+    public void setObjId(Long objId) {
+        this.objId = objId;
+    }
+
+    public String getSummary() {
+        return summary;
+    }
+
+    public void setSummary(String summary) {
+        this.summary = summary;
+    }
+
+    public Long getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
+    }
+}

+ 129 - 0
eds-common/src/main/java/com/qmth/eds/common/entity/TSAuth.java

@@ -0,0 +1,129 @@
+package com.qmth.eds.common.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.base.BaseEntity;
+import com.qmth.eds.common.contant.SystemConstant;
+import com.qmth.eds.common.enums.AuthEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 激活授权配置表
+ * </p>
+ */
+@ApiModel(value = "TSAuth对象", description = "激活授权配置表")
+public class TSAuth extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "accessKey")
+    private String accessKey;
+
+    @ApiModelProperty(value = "accessSecret")
+    private String accessSecret;
+
+    @ApiModelProperty(value = "离线授权证书")
+    private String description;
+
+    @ApiModelProperty(value = "授权类型")
+    private AuthEnum type;
+
+    @ApiModelProperty(value = "过期时间")
+    private Long expireTime;
+
+    @ApiModelProperty(value = "文件数据")
+    private byte[] file;
+
+    public TSAuth() {
+
+    }
+
+    public TSAuth(Long schoolId, String accessKey, String accessSecret, AuthEnum type, Long expireTime) {
+        setId(SystemConstant.getDbUuid());
+        this.schoolId = schoolId;
+        this.accessKey = accessKey;
+        this.accessSecret = accessSecret;
+        this.type = type;
+        this.expireTime = expireTime;
+    }
+
+    public TSAuth(Long schoolId, String description, AuthEnum type, Long expireTime) {
+        setId(SystemConstant.getDbUuid());
+        this.schoolId = schoolId;
+        this.description = description;
+        this.type = type;
+        this.expireTime = expireTime;
+    }
+
+    public TSAuth(Long schoolId, byte[] file, AuthEnum type, Long expireTime) {
+        setId(SystemConstant.getDbUuid());
+        this.schoolId = schoolId;
+        this.file = file;
+        this.type = type;
+        this.expireTime = expireTime;
+    }
+
+    public byte[] getFile() {
+        return file;
+    }
+
+    public void setFile(byte[] file) {
+        this.file = file;
+    }
+
+    public Long getExpireTime() {
+        return expireTime;
+    }
+
+    public void setExpireTime(Long expireTime) {
+        this.expireTime = expireTime;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public String getAccessKey() {
+        return accessKey;
+    }
+
+    public void setAccessKey(String accessKey) {
+        this.accessKey = accessKey;
+    }
+
+    public String getAccessSecret() {
+        return accessSecret;
+    }
+
+    public void setAccessSecret(String accessSecret) {
+        this.accessSecret = accessSecret;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public AuthEnum getType() {
+        return type;
+    }
+
+    public void setType(AuthEnum type) {
+        this.type = type;
+    }
+}

+ 42 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/AppSourceEnum.java

@@ -0,0 +1,42 @@
+package com.qmth.eds.common.enums;
+
+import java.util.Objects;
+
+/**
+ * @Description: app应用来源
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/6/29
+ */
+public enum AppSourceEnum {
+
+    SYSTEM("自身应用系统"),
+
+    WHU_THIRD("武汉大学");
+
+    private String title;
+
+    private AppSourceEnum(String title) {
+        this.title = title;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param title
+     * @return
+     */
+    public static String convertToName(String title) {
+        for (AppSourceEnum e : AppSourceEnum.values()) {
+            if (Objects.equals(title, e.getTitle())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+}

+ 38 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/AuthEnum.java

@@ -0,0 +1,38 @@
+package com.qmth.eds.common.enums;
+
+import java.util.Objects;
+
+/**
+ * 授权配置类型
+ */
+public enum AuthEnum {
+
+    ON_LINE("在线激活"),
+
+    OFF_LINE("离线激活");
+
+    AuthEnum(String title) {
+        this.title = title;
+    }
+
+    private String title;
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param value
+     * @return
+     */
+    public static String convertToName(String value) {
+        for (AuthEnum e : AuthEnum.values()) {
+            if (Objects.equals(value.trim(), e.getTitle())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+}

+ 59 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/EnumResult.java

@@ -0,0 +1,59 @@
+package com.qmth.eds.common.enums;
+
+/**
+ * @Date: 2021/3/23.
+ */
+public class EnumResult {
+
+    /**
+     * enum name()
+     */
+    private String name;
+
+    /**
+     * enum ordinal
+     */
+    private Integer ordinal;
+
+    /**
+     * enum 自定义code
+     */
+    private String code;
+
+    /**
+     * enum 自定义描述
+     */
+    private String desc;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getOrdinal() {
+        return ordinal;
+    }
+
+    public void setOrdinal(Integer ordinal) {
+        this.ordinal = ordinal;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}

+ 133 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/ExceptionResultEnum.java

@@ -0,0 +1,133 @@
+package com.qmth.eds.common.enums;
+
+import com.qmth.boot.api.exception.ApiException;
+import org.springframework.http.HttpStatus;
+
+/**
+ * @Description: 自定义异常消息枚举
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2019/10/11
+ */
+public enum ExceptionResultEnum {
+    /**
+     * 系统预置
+     */
+    SUCCESS(HttpStatus.OK, 200, "成功"),
+
+    ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 5000001, "失败"),
+
+    PARAMS_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 5000002, "参数错误"),
+
+    SQL_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 5000003, "sql异常:"),
+
+    INVOCATIONTARGET_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 5000004, "反射异常:"),
+
+    SERVICE_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR, 5000005, "服务器错误"),
+
+    UNKONW_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 5000006, "未知错误:请联系管理员"),
+
+    EXCEPTION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 5000007, "系统异常:请联系管理员"),
+
+    /**
+     * 500
+     */
+    EXCEL_NO_DATA(HttpStatus.INTERNAL_SERVER_ERROR, 5000008, "excel没有数据"),
+
+    USER_NO_DATA(HttpStatus.INTERNAL_SERVER_ERROR, 5000009, "用户或密码不正确"),
+
+    PASSWORD_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 5000010, "密码不正确"),
+
+    USER_ENABLE(HttpStatus.INTERNAL_SERVER_ERROR, 5000011, "用户已停用"),
+
+    NOT_LOGIN(HttpStatus.INTERNAL_SERVER_ERROR, 5000012, "请先登录"),
+
+    ROLE_NO_DATA(HttpStatus.INTERNAL_SERVER_ERROR, 5000013, "没有角色数据"),
+
+    ATTACHMENT_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 5000014, "上传文件失败"),
+
+    MD5_EMPTY(HttpStatus.INTERNAL_SERVER_ERROR, 5000015, "md5为空"),
+
+    MD5_EQUALS_FALSE(HttpStatus.INTERNAL_SERVER_ERROR, 5000016, "md5不一致"),
+
+    ATTACHMENT_TYPE_EMPTY(HttpStatus.INTERNAL_SERVER_ERROR, 5000017, "请上传文件类型"),
+
+    TASK_NO_DATA(HttpStatus.INTERNAL_SERVER_ERROR, 5000018, "任务不存在"),
+
+    PATH_NO_DATA(HttpStatus.INTERNAL_SERVER_ERROR, 5000019, "文件地址不存在"),
+
+    SCHOOL_NO_DATA(HttpStatus.INTERNAL_SERVER_ERROR, 5000020, "学校信息不存在"),
+
+    SCHOOL_ENABLE(HttpStatus.INTERNAL_SERVER_ERROR, 5000021, "学校已停用"),
+
+    ATTACHMENT_IS_NULL(HttpStatus.INTERNAL_SERVER_ERROR, 50000024, "找不到附件"),
+
+    NO_DATA(HttpStatus.INTERNAL_SERVER_ERROR, 5000025, "没有数据"),
+
+    DATA_COUNT_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, 5000026, "得到的数据条数异常,应该有且仅有一条数据"),
+
+    DATA_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 5000027, "数据异常"),
+
+    SYNC_TASK_NO_DATA(HttpStatus.INTERNAL_SERVER_ERROR, 5000028, "同步任务不存在"),
+
+    /**
+     * 401
+     */
+    PLATFORM_INVALID(HttpStatus.UNAUTHORIZED, 4010001, "platform无效"),
+
+    DEVICE_ID_INVALID(HttpStatus.UNAUTHORIZED, 4010002, "deviceId无效"),
+
+    TOKEN_INVALID(HttpStatus.UNAUTHORIZED, 4010003, "token无效"),
+
+    TIME_INVALID(HttpStatus.UNAUTHORIZED, 4010004, "time无效"),
+
+    AUTHORIZATION_INVALID(HttpStatus.UNAUTHORIZED, 4010005, "authorization无效"),
+
+    AUTHORIZATION_ERROR(HttpStatus.UNAUTHORIZED, 4010006, "签名验证失败"),
+
+    UN_AUTHORIZATION(HttpStatus.UNAUTHORIZED, 4010007, "没有权限"),
+
+    ROLE_ENABLE_AUTHORIZATION(HttpStatus.UNAUTHORIZED, 4010008, "角色被禁用或没有权限"),
+
+    AUTH_INFO_ERROR(HttpStatus.UNAUTHORIZED, 4010009, "系统授权信息已过期,请联系系统管理员激活!"),
+
+    /**
+     * 404
+     */
+    NOT_FOUND(HttpStatus.NOT_FOUND, 4040003, "请求地址错误");
+
+    private HttpStatus status;
+    private int code;
+    private String message;
+
+    private ExceptionResultEnum(HttpStatus status, int code, String message) {
+        this.status = status;
+        this.code = code;
+        this.message = message;
+    }
+
+    public HttpStatus getStatus() {
+        return status;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public ApiException exception() {
+        return new ApiException(status, code, message, message);
+    }
+
+    public ApiException exception(int code, String message) {
+        return new ApiException(status, code, message, message);
+    }
+
+    public ApiException exception(String message) {
+        return new ApiException(status, code, message, message);
+    }
+}

+ 41 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/JobEnum.java

@@ -0,0 +1,41 @@
+package com.qmth.eds.common.enums;
+
+import java.util.Objects;
+
+/**
+ * @Description: job enum
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/3/31
+ */
+public enum JobEnum {
+
+    TIMED_SYNC_SCHOOL_JOB("学校信息同步定时任务"),
+    TIMED_SYNC_TASK_JOB("同步武大考务数据");
+
+    private String title;
+
+    private JobEnum(String title) {
+        this.title = title;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param value
+     * @return
+     */
+    public static String convertToName(String value) {
+        for (JobEnum e : JobEnum.values()) {
+            if (Objects.equals(value.trim(), e.getTitle())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+}

+ 45 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/MessageEnum.java

@@ -0,0 +1,45 @@
+package com.qmth.eds.common.enums;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 发送消息枚举类
+ */
+public enum MessageEnum {
+
+    /**
+     * 数据变动通知
+     */
+    NOTICE_OF_TEACH_DATA_CHANGE("考务数据变动通知", "${userName}您好,${courseName}相关命题任务已经提交,由${auditUserNames}负责审核,请您查看!");
+
+    MessageEnum(String name, String template) {
+        this.name = name;
+        this.template = template;
+    }
+
+    private final String name;
+    private final String template;
+
+
+    public static List<EnumResult> listTypes() {
+        List<EnumResult> list = new ArrayList<>();
+        for (MessageEnum value : MessageEnum.values()) {
+            EnumResult result = new EnumResult();
+            result.setName(value.name());
+            result.setOrdinal(value.ordinal());
+            result.setCode(null);
+            result.setDesc(value.getName());
+            list.add(result);
+        }
+        return list;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getTemplate() {
+        return template;
+    }
+}

+ 36 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/OrgTypeEnum.java

@@ -0,0 +1,36 @@
+package com.qmth.eds.common.enums;
+
+import java.util.Objects;
+
+/**
+ * 机构类型enum
+ */
+public enum OrgTypeEnum {
+
+    SCHOOL("学校");
+
+    private String title;
+
+    private OrgTypeEnum(String title) {
+        this.title = title;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param title
+     * @return
+     */
+    public static String convertToName(String title) {
+        for (OrgTypeEnum e : OrgTypeEnum.values()) {
+            if (Objects.equals(title, e.getTitle())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+}

+ 67 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/PrivilegeEnum.java

@@ -0,0 +1,67 @@
+package com.qmth.eds.common.enums;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 菜单类型
+ *
+ * @Date: 2021/3/23.
+ */
+public enum PrivilegeEnum {
+
+    MENU("菜单"),
+
+    BUTTON("按钮"),
+
+    LINK("链接"),
+
+    URL("接口地址"),
+
+    LIST("列表"),
+
+    CONDITION("查询条件");
+
+    private String desc;
+
+    private PrivilegeEnum(String desc) {
+        this.desc = desc;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param title
+     * @return
+     */
+    public static String convertToName(String title) {
+        for (PrivilegeEnum e : PrivilegeEnum.values()) {
+            if (Objects.equals(title, e.getDesc())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @return
+     */
+    public static List<EnumResult> listTypes() {
+        List<EnumResult> list = new ArrayList<EnumResult>();
+        for (PrivilegeEnum value : PrivilegeEnum.values()) {
+            EnumResult result = new EnumResult();
+            result.setName(value.name());
+            result.setOrdinal(value.ordinal());
+            result.setCode(null);
+            result.setDesc(value.getDesc());
+            list.add(result);
+        }
+        return list;
+    }
+
+}

+ 44 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/PrivilegePropertyEnum.java

@@ -0,0 +1,44 @@
+package com.qmth.eds.common.enums;
+
+import java.util.Objects;
+
+/**
+ * @Description: 系统鉴权属性 enum
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/3/25
+ */
+public enum PrivilegePropertyEnum {
+
+    NO_AUTH("无需鉴权"),
+
+    AUTH("鉴权"),
+
+    SYS("系统公用");
+
+    private String title;
+
+    private PrivilegePropertyEnum(String title) {
+        this.title = title;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param title
+     * @return
+     */
+    public static String convertToName(String title) {
+        for (PrivilegePropertyEnum e : PrivilegePropertyEnum.values()) {
+            if (Objects.equals(title, e.getTitle())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+}

+ 39 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/RoleTypeEnum.java

@@ -0,0 +1,39 @@
+package com.qmth.eds.common.enums;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 角色类型
+ *
+ * @Date: 2021/3/23.
+ */
+public enum RoleTypeEnum {
+
+    ADMIN("管理员"),
+    IMPLEMENT("实施人员");
+
+    RoleTypeEnum(String desc) {
+        this.desc = desc;
+    }
+
+    private String desc;
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public static List<EnumResult> listTypes() {
+        List<EnumResult> list = new ArrayList<>();
+        for (RoleTypeEnum value : RoleTypeEnum.values()) {
+            EnumResult result = new EnumResult();
+            result.setName(value.name());
+            result.setOrdinal(value.ordinal());
+            result.setCode(null);
+            result.setDesc(value.getDesc());
+            list.add(result);
+        }
+        return list;
+    }
+
+}

+ 42 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/TaskResultEnum.java

@@ -0,0 +1,42 @@
+package com.qmth.eds.common.enums;
+
+import java.util.Objects;
+
+/**
+ * @Description: 任务结果enum
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/3/29
+ */
+public enum TaskResultEnum {
+
+    SUCCESS("成功"),
+
+    ERROR("失败");
+
+    private String title;
+
+    private TaskResultEnum(String title) {
+        this.title = title;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param title
+     * @return
+     */
+    public static String convertToName(String title) {
+        for (TaskResultEnum e : TaskResultEnum.values()) {
+            if (Objects.equals(title, e.getTitle())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+}

+ 59 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/TaskStatusEnum.java

@@ -0,0 +1,59 @@
+package com.qmth.eds.common.enums;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @Description: 任务状态enum
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/3/29
+ */
+public enum TaskStatusEnum {
+
+    INIT("未开始"),
+
+    RUNNING("进行中"),
+
+    FINISH("已完成");
+
+    private String title;
+
+    private TaskStatusEnum(String title) {
+        this.title = title;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param title
+     * @return
+     */
+    public static String convertToName(String title) {
+        for (TaskStatusEnum e : TaskStatusEnum.values()) {
+            if (Objects.equals(title, e.getTitle())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+
+    public static List<EnumResult> listTypes() {
+        List<EnumResult> list = new ArrayList<>();
+        for (TaskStatusEnum value : TaskStatusEnum.values()) {
+            EnumResult result = new EnumResult();
+            result.setName(value.name());
+            result.setOrdinal(value.ordinal());
+            result.setCode(null);
+            result.setDesc(value.getTitle());
+            list.add(result);
+        }
+        return list;
+    }
+}

+ 53 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/TaskTypeEnum.java

@@ -0,0 +1,53 @@
+package com.qmth.eds.common.enums;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 任务类型enum
+ */
+public enum TaskTypeEnum {
+
+    WHU_TEACH_DATA("同步武大考务数据"),
+
+    CLOUD_MARKING_STUDENT_SCORE("同步云阅卷考生成绩");
+
+    private String title;
+
+    private TaskTypeEnum(String title) {
+        this.title = title;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param title
+     * @return
+     */
+    public static String convertToName(String title) {
+        for (TaskTypeEnum e : TaskTypeEnum.values()) {
+            if (Objects.equals(title, e.getTitle())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+
+    public static List<EnumResult> listTypes() {
+        List<EnumResult> list = new ArrayList<>();
+        for (TaskTypeEnum value : TaskTypeEnum.values()) {
+            EnumResult result = new EnumResult();
+            result.setName(value.name());
+            result.setOrdinal(value.ordinal());
+            result.setCode(null);
+            result.setDesc(value.getTitle());
+            list.add(result);
+        }
+        return list;
+    }
+}

+ 76 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/UploadFileEnum.java

@@ -0,0 +1,76 @@
+package com.qmth.eds.common.enums;
+
+import java.util.Objects;
+
+/**
+ * @Description: 上传文件类型
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/7/15
+ */
+public enum UploadFileEnum {
+    /**
+     * 客户端
+     */
+    PAPER("paper","private"),
+    /**
+     * 系统相关
+     */
+    UPLOAD("upload","private"),
+    /**
+     * 导入导出
+     */
+    FILE("file","public"),
+
+    PDF("pdf","private"),
+
+    HTML("html","private");
+
+    private String title;
+    private String fssType;
+
+    UploadFileEnum(String title, String fssType) {
+        this.title = title;
+        this.fssType = fssType;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public String getFssType() {
+        return fssType;
+    }
+
+
+    /**
+     * 状态转换 toName
+     *
+     * @param title
+     * @return
+     */
+    public static String convertToName(String title) {
+        for (UploadFileEnum e : UploadFileEnum.values()) {
+            if (Objects.equals(title, e.getTitle())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param title
+     * @return
+     */
+    public static String convertToFssType(String title) {
+        for (UploadFileEnum e : UploadFileEnum.values()) {
+            if (Objects.equals(title.toLowerCase(), e.getTitle())) {
+                return e.getFssType();
+            }
+        }
+        return null;
+    }
+}

+ 37 - 0
eds-common/src/main/java/com/qmth/eds/common/enums/UseSceneEnum.java

@@ -0,0 +1,37 @@
+package com.qmth.eds.common.enums;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 用途类型
+ */
+public enum UseSceneEnum {
+
+    PRINT("变量印刷"),
+    SCAN_MARK("扫描阅卷"),
+    TEACH_ANALYSIS("教研分析");
+
+    UseSceneEnum(String desc) {
+        this.desc = desc;
+    }
+
+    private String desc;
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public static List<EnumResult> listTypes() {
+        List<EnumResult> list = new ArrayList<>();
+        for (UseSceneEnum value : UseSceneEnum.values()) {
+            EnumResult result = new EnumResult();
+            result.setName(value.name());
+            result.setOrdinal(value.ordinal());
+            result.setCode(null);
+            result.setDesc(value.getDesc());
+            list.add(result);
+        }
+        return list;
+    }
+}

+ 66 - 0
eds-common/src/main/java/com/qmth/eds/common/threadPool/MyThreadPool.java

@@ -0,0 +1,66 @@
+package com.qmth.eds.common.threadPool;//package com.qmth.themis.business.threadPool;
+
+import com.qmth.eds.common.contant.SystemConstant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.Objects;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+/**
+ * @Description: 线程池应用配置
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2019/3/21
+ */
+@Configuration
+public class MyThreadPool extends ThreadPoolTaskExecutor {
+    private final static Logger log = LoggerFactory.getLogger(MyThreadPool.class);
+    private MyThreadPool threadPoolTaskExecutor = null;
+    static final int cpuNum = Runtime.getRuntime().availableProcessors();
+
+    @Value("${sys.config.threadPoolCoreSize}")
+    Integer threadPoolCoreSize;
+
+    @Value("${sys.config.customThreadPoolCoreSize}")
+    boolean customThreadPoolCoreSize;
+
+    /**
+     * 线程池
+     *
+     * @return
+     */
+    @Bean
+    @Primary
+    public Executor taskThreadPool() {
+        if (Objects.isNull(threadPoolTaskExecutor)) {
+            log.info("cpuNum:{}", cpuNum);
+            threadPoolTaskExecutor = new MyThreadPool();
+            if (!customThreadPoolCoreSize && cpuNum > 0) {
+                threadPoolTaskExecutor.setCorePoolSize(cpuNum);//核心线程数
+                threadPoolTaskExecutor.setMaxPoolSize(cpuNum * 2);//最大线程数
+            } else {
+                threadPoolTaskExecutor.setCorePoolSize(threadPoolCoreSize);//核心线程数
+                threadPoolTaskExecutor.setMaxPoolSize(threadPoolCoreSize * 2);//最大线程数
+            }
+            threadPoolTaskExecutor.setKeepAliveSeconds(SystemConstant.THREAD_POOL_KEEP_ALIVE_SECONDS);//线程空闲时间
+            threadPoolTaskExecutor.setQueueCapacity(SystemConstant.THREAD_POOL_QUEUE_CAPACITY);//队列容量
+            threadPoolTaskExecutor.setThreadNamePrefix(SystemConstant.THREAD_POOL_NAME);
+            threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);//设置是否允许核心线程超时。若允许,核心线程超时后,会被销毁。默认为不允许(fasle)
+            threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);//设置shutdown时是否等到所有任务完成再真正关闭
+            threadPoolTaskExecutor.setAwaitTerminationSeconds(60);//当setWaitForTasksToCompleteOnShutdown(true)时,setAwaitTerminationSeconds 设置在 shutdown 之后最多等待多长时间后再真正关闭线程池
+            // rejection-policy:当pool已经达到max size的时候,如何处理新任务
+            // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
+            threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+            threadPoolTaskExecutor.initialize();
+        }
+        return threadPoolTaskExecutor;
+    }
+}

+ 187 - 0
eds-common/src/main/java/com/qmth/eds/common/tools/CloudMarkingUtil.java

@@ -0,0 +1,187 @@
+package com.qmth.eds.common.tools;
+
+import com.alibaba.fastjson.JSONObject;
+import com.qmth.boot.tools.signature.SignatureEntity;
+import com.qmth.boot.tools.signature.SignatureType;
+import com.qmth.eds.common.config.DictionaryConfig;
+import com.qmth.eds.common.contant.SystemConstant;
+import com.qmth.eds.common.entity.SysCollege;
+import com.qmth.eds.common.enums.ExceptionResultEnum;
+import com.qmth.eds.common.service.CommonCacheService;
+import com.qmth.eds.common.service.SysCollegeService;
+import com.qmth.eds.common.util.HttpKit;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 云阅卷接口工具类
+ */
+@Service
+public class CloudMarkingUtil {
+
+    private static final String SUCCESS = "success";
+
+    private static final String EXAMID = "examId";
+    private static final String EXAM_NUMBER = "examNumber";
+    private static final String STUDENT_CODE = "studentCode";
+    private static final String COLLEGE = "college";
+    private static final String CLASS_NAME = "className";
+    private static final String TEACHER = "teacher";
+    private static final String SUBJECT_CODE = "subjectCode";
+
+
+    @Resource
+    DictionaryConfig dictionaryConfig;
+
+    @Resource
+    CommonCacheService commonCacheService;
+
+    @Resource
+    SysCollegeService sysCollegeService;
+
+    /**
+     * 考试成绩考生查询接口
+     *
+     * @param pageNo   分页参数
+     * @param pageSize 分页参数
+     */
+    public List<JSONObject> getExam(Long collegeId, int pageNo, int pageSize) {
+        Map<String, String> paramMap = new HashMap<>();
+        paramMap.put("pageNumber", String.valueOf(pageNo));
+        paramMap.put("pageSize", String.valueOf(pageSize));
+
+        String yyjRootUrl = dictionaryConfig.cloudMarkingDomain().getRootUrl();
+        String examUrl = dictionaryConfig.cloudMarkingDomain().getExamUrl();
+
+        if (StringUtils.isAnyBlank(yyjRootUrl, examUrl)) {
+            throw ExceptionResultEnum.ERROR.exception("考试查询接口url未设置");
+        }
+
+        Map<String, String> header = createHeader(examUrl, collegeId);
+        //请求
+        String examObject = HttpKit.sendPost(yyjRootUrl + examUrl, paramMap, header);
+        return JSONObject.parseArray(JSONObject.toJSON(examObject).toString(), JSONObject.class);
+    }
+
+    /**
+     * 考试成绩考生数量查询接口
+     *
+     * @param mapSource 参数
+     * @param collegeId
+     */
+    public int getStudentCount(Map<String, String> mapSource, Long collegeId) {
+        Map<String, String> map = paramMap(mapSource);
+
+        String yyjRootUrl = dictionaryConfig.cloudMarkingDomain().getRootUrl();
+        String studentCountUrl = dictionaryConfig.cloudMarkingDomain().getStudentCountUrl();
+
+        if (StringUtils.isAnyBlank(yyjRootUrl, studentCountUrl)) {
+            throw ExceptionResultEnum.ERROR.exception("考试成绩考生数量查询接口url未设置");
+        }
+
+        //header
+        Map<String, String> headerMap = createHeader(studentCountUrl, collegeId);
+        //请求
+        String res = HttpKit.sendPost(yyjRootUrl + studentCountUrl, map, headerMap);
+        if (StringUtils.isNotBlank(res)) {
+            JSONObject object = JSONObject.parseObject(res);
+            return Integer.parseInt(object.get("totalCount").toString());
+        }
+        return 0;
+    }
+
+    /**
+     * 考试成绩考生查询接口
+     *
+     * @param map       参数
+     * @param collegeId
+     * @param pageNo    分页参数
+     * @param pageSize  分页参数
+     */
+    public List<JSONObject> getStudentScore(Map<String, String> map, Long collegeId, int pageNo, int pageSize) {
+        Map<String, String> paramMap = paramMap(map);
+
+        paramMap.put("pageNumber", String.valueOf(pageNo));
+        paramMap.put("pageSize", String.valueOf(pageSize));
+
+        String yyjRootUrl = dictionaryConfig.cloudMarkingDomain().getRootUrl();
+        String studentScoreUrl = dictionaryConfig.cloudMarkingDomain().getStudentScoreUrl();
+
+        if (StringUtils.isAnyBlank(yyjRootUrl, studentScoreUrl)) {
+            throw ExceptionResultEnum.ERROR.exception("考试成绩查询接口url未设置");
+        }
+
+        Map<String, String> header = createHeader(studentScoreUrl, collegeId);
+        //请求
+        String studentObject = HttpKit.sendPost(yyjRootUrl + studentScoreUrl, paramMap, header);
+        return JSONObject.parseArray(JSONObject.toJSON(studentObject).toString(), JSONObject.class);
+    }
+
+    /**
+     * 云阅卷接口请求header
+     *
+     * @param url url
+     */
+    private Map<String, String> createHeader(String url, Long collegeId) {
+        SysCollege sysCollege = sysCollegeService.getById(collegeId);
+        String accessKey = null;
+        String accessSecret = null;
+        if (sysCollege != null) {
+            accessKey = sysCollege.getAccessKey();
+            accessSecret = sysCollege.getAccessSecret();
+        } else {
+            accessKey = dictionaryConfig.cloudMarkingDomain().getAccessKey();
+            accessSecret = dictionaryConfig.cloudMarkingDomain().getAccessSecret();
+        }
+        long time = System.currentTimeMillis();
+        Map<String, String> headerMap = new HashMap<>();
+        headerMap.put(SystemConstant.HEADER_TIME, String.valueOf(time));
+        String signature = SignatureEntity.build(SignatureType.SECRET, "POST", url, time, accessKey, accessSecret);
+        headerMap.put(SystemConstant.HEADER_AUTHORIZATION, signature);
+
+        return headerMap;
+    }
+
+    private Map<String, String> paramMap(Map<String, String> mapSource) {
+        Map<String, String> map = new HashMap<>();
+        Integer examId = Integer.valueOf(mapSource.get(EXAMID));
+        if (Objects.nonNull(examId)) {
+            map.put(EXAMID, String.valueOf(examId));
+        }
+        String examCode = mapSource.get("examCode");
+        if (StringUtils.isNotBlank(examCode)) {
+            map.put("examCode", examCode);
+        }
+        String examNumber = mapSource.get(EXAM_NUMBER);
+        if (StringUtils.isNotBlank(examNumber)) {
+            map.put(EXAM_NUMBER, examNumber);
+        }
+        String studentCode = mapSource.get(STUDENT_CODE);
+        if (StringUtils.isNotBlank(studentCode)) {
+            map.put(STUDENT_CODE, studentCode);
+        }
+        String subjectCode = mapSource.get(SUBJECT_CODE);
+        if (StringUtils.isNotBlank(subjectCode)) {
+            map.put(SUBJECT_CODE, subjectCode);
+        }
+        String college = mapSource.get(COLLEGE);
+        if (StringUtils.isNotBlank(college)) {
+            map.put(COLLEGE, college);
+        }
+        String className = mapSource.get(CLASS_NAME);
+        if (StringUtils.isNotBlank(className)) {
+            map.put(CLASS_NAME, className);
+        }
+        String teacher = mapSource.get(TEACHER);
+        if (StringUtils.isNotBlank(teacher)) {
+            map.put(TEACHER, teacher);
+        }
+        return map;
+    }
+}

+ 146 - 0
eds-common/src/main/java/com/qmth/eds/common/tools/WuhanUniversityUtils.java

@@ -0,0 +1,146 @@
+package com.qmth.eds.common.tools;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.qmth.eds.common.config.DictionaryConfig;
+import com.qmth.eds.common.entity.ExamSyncStudentTemp;
+import com.qmth.eds.common.enums.ExceptionResultEnum;
+import com.qmth.eds.common.service.impl.DataSyncServiceImpl;
+import com.qmth.eds.common.util.HttpKit;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 武汉大学工具类
+ */
+@Component
+public class WuhanUniversityUtils {
+
+    private static final Logger log = LoggerFactory.getLogger(DataSyncServiceImpl.class);
+
+    @Resource
+    private DictionaryConfig dictionaryConfig;
+
+    /**
+     * 获取token
+     */
+    public String getAccessToken() {
+        String appKey = dictionaryConfig.whuDomain().getAppKey();
+        String appSecret = dictionaryConfig.whuDomain().getAppSecret();
+        String tokenUrl = dictionaryConfig.whuDomain().getTokenUrl();
+        validUrl(appKey, appSecret, tokenUrl);
+        try {
+            //参数
+            Map<String, String> paramMap = new HashMap<>();
+            paramMap.put("appKey", appKey);
+            paramMap.put("appSecret", appSecret);
+
+            String result = HttpKit.sendPost(tokenUrl, paramMap, null);
+            JSONObject jsonResult = JSON.parseObject(result);
+            log.info("参数:{}", JSONObject.toJSONString(paramMap));
+            log.info("结果:{}", result);
+            if (jsonResult.containsKey("status") && "success".equals(jsonResult.getString("status"))) {
+                String token = jsonResult.getString("token");
+                JSONObject jsonToken = JSON.parseObject(token);
+                if (jsonToken.containsKey("accessToken")) {
+                    return jsonToken.getString("accessToken");
+                }
+            }
+            return null;
+        } catch (Exception e) {
+            throw ExceptionResultEnum.ERROR.exception(e.getMessage());
+        }
+    }
+
+    /**
+     * 获取考务数据
+     */
+    public List<ExamSyncStudentTemp> getKwData(String token) {
+        String kwUrl = dictionaryConfig.whuDomain().getKwUrl();
+        validUrl(kwUrl);
+        try {
+            //参数
+            Map<String, String> headerMap = new HashMap<>();
+            headerMap.put("Authorization", "Bearer " + token);
+
+            // 循环查
+            AtomicInteger offset = new AtomicInteger(0);
+            int limit = 1000;
+            int totalCount = 0;
+            List<ExamSyncStudentTemp> subExamSyncStudentTemps;
+            List<ExamSyncStudentTemp> examSyncStudentTemps = new ArrayList<>();
+            do {
+                Map<String, String> paramMap;
+                paramMap = new HashMap<>();
+                paramMap.putIfAbsent("limit", String.valueOf(limit));
+                paramMap.put("offset", String.valueOf(offset.getAndIncrement() * limit));
+
+                String result = HttpKit.sendGet(kwUrl, paramMap, headerMap);
+                JSONObject jsonResult = JSON.parseObject(result);
+                String rows = jsonResult.getString("rows");
+                totalCount = totalCount == 0 ? jsonResult.getInteger("totalCount") : totalCount;
+                subExamSyncStudentTemps = JSON.parseArray(rows, ExamSyncStudentTemp.class);
+                if (!subExamSyncStudentTemps.isEmpty()) {
+                    examSyncStudentTemps.addAll(subExamSyncStudentTemps);
+                }
+            } while (!subExamSyncStudentTemps.isEmpty());
+
+            if (totalCount != examSyncStudentTemps.size()) {
+                throw ExceptionResultEnum.ERROR.exception("获取考务数据数量与总数不一致");
+            }
+
+            return examSyncStudentTemps;
+//            return listTemps();
+        } catch (Exception e) {
+            throw ExceptionResultEnum.ERROR.exception(e.getMessage());
+        }
+    }
+
+    /**
+     * 校验url是否配置
+     *
+     * @param urls URL数组
+     */
+    private void validUrl(String... urls) {
+        if (StringUtils.isAnyBlank(urls)) {
+            throw ExceptionResultEnum.ERROR.exception("接口参数未配置");
+        }
+    }
+
+    private List<ExamSyncStudentTemp> listTemps() {
+        List<ExamSyncStudentTemp> examSyncStudentTemps = new ArrayList<>();
+        for (int i = 0; i < 4; i++) {
+            ExamSyncStudentTemp examSyncStudentTemp = new ExamSyncStudentTemp();
+            examSyncStudentTemp.setXnm("100" + i);
+            examSyncStudentTemp.setXqm("200" + i);
+            examSyncStudentTemp.setJxbId("300" + i);
+            examSyncStudentTemp.setJxbmc("教学班" + i);
+            examSyncStudentTemp.setKch("400" + i);
+            examSyncStudentTemp.setKcmc("课程" + i);
+            examSyncStudentTemp.setJgh("500" + i);
+            examSyncStudentTemp.setXm("姓名" + i);
+            examSyncStudentTemp.setKkbm("开课学院" + i);
+            examSyncStudentTemp.setXf("35");
+            examSyncStudentTemp.setXh("100000100" + i);
+            examSyncStudentTemp.setXsxm("学生" + i);
+            examSyncStudentTemp.setJgmc("机构" + i);
+            examSyncStudentTemp.setZymc("专业" + i);
+            examSyncStudentTemp.setCxbj("0");
+            examSyncStudentTemp.setNjdmId("年级" + i);
+            examSyncStudentTemp.setZwh("1" + i);
+            examSyncStudentTemp.setCdmc("考场" + i);
+            examSyncStudentTemp.setKsbz("无");
+            examSyncStudentTemps.add(examSyncStudentTemp);
+        }
+        return examSyncStudentTemps;
+    }
+}

+ 149 - 0
eds-common/src/main/java/com/qmth/eds/common/util/AesUtil.java

@@ -0,0 +1,149 @@
+package com.qmth.eds.common.util;
+
+import com.qmth.eds.common.contant.SystemConstant;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Base64;
+
+/**
+ * @Description: AES对称加密
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2019/10/11
+ */
+public class AesUtil {
+    private final static Logger log = LoggerFactory.getLogger(AesUtil.class);
+
+    /**
+     * 加密
+     *
+     * @param content
+     * @param strKey
+     * @return
+     * @throws Exception
+     */
+    private static byte[] encrypt(String content, String strKey) throws Exception {
+        SecretKeySpec skeySpec = getKey(strKey);
+        Cipher cipher = Cipher.getInstance(SystemConstant.AES_MODE_PKCS5);
+        IvParameterSpec iv = new IvParameterSpec(SystemConstant.AES_RULE.getBytes());//AES规则,可自定义,例如A-Z排序
+        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
+        return cipher.doFinal(content.getBytes());
+    }
+
+    /**
+     * 解密
+     *
+     * @param content
+     * @param strKey
+     * @return
+     * @throws Exception
+     */
+    private static String decrypt(byte[] content, String strKey) throws Exception {
+        SecretKeySpec skeySpec = getKey(strKey);
+        Cipher cipher = Cipher.getInstance(SystemConstant.AES_MODE_PKCS5);
+        IvParameterSpec iv = new IvParameterSpec(SystemConstant.AES_RULE.getBytes());//AES规则,可自定义,例如A-Z排序
+        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
+        byte[] original = cipher.doFinal(content);
+        return new String(original);
+    }
+
+    /**
+     * 公钥
+     *
+     * @param strKey
+     * @return
+     * @throws Exception
+     */
+    private static SecretKeySpec getKey(String strKey) throws Exception {
+        byte[] arrBTmp = strKey.getBytes();
+        byte[] arrB = new byte[16]; // 创建一个空的16位字节数组(默认值为0)
+        for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
+            arrB[i] = arrBTmp[i];
+        }
+        return new SecretKeySpec(arrB, SystemConstant.AES);
+    }
+
+    /**
+     * AES加密
+     *
+     * @param content
+     * @param encryptKey
+     * @return
+     * @throws Exception
+     */
+    public static String encoder(String content, String encryptKey) throws Exception {
+        String encoderText = Base64.getEncoder().encodeToString(encrypt(content, encryptKey));
+        return encoderText;
+    }
+
+    /**
+     * AES解密
+     *
+     * @param encryptStr
+     * @param decryptKey
+     * @return
+     * @throws Exception
+     */
+    public static String decoder(String encryptStr, String decryptKey) throws Exception {
+        String decoderText = decrypt(Base64.getDecoder().decode(encryptStr), decryptKey);
+        return decoderText;
+    }
+
+    /**
+     * cs7加密/解密用
+     */
+    static {
+        Security.addProvider(new BouncyCastleProvider());
+    }
+
+    /**
+     * cs7加密
+     *
+     * @param content
+     * @param key
+     * @return
+     */
+    public static String encryptCs7(String content, String key) {
+        String encoderText = null;
+        try {
+            Cipher cipher = Cipher.getInstance(SystemConstant.AES_MODE_PKCS7);
+            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(SystemConstant.CHARSET_NAME), SystemConstant.AES);
+            AlgorithmParameterSpec paramSpec = new IvParameterSpec(SystemConstant.AES_RULE.getBytes());
+            cipher.init(Cipher.ENCRYPT_MODE, keySpec, paramSpec);
+            byte[] result = cipher.doFinal(content.getBytes(SystemConstant.CHARSET_NAME));
+            encoderText = Base64.getEncoder().encodeToString(result);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+        return encoderText;
+    }
+
+    /**
+     * cs7解密
+     *
+     * @param content
+     * @param key
+     * @return
+     */
+    public static String decryptCs7(String content, String key) {
+        String decoderText = null;
+        try {
+            Cipher cipher = Cipher.getInstance(SystemConstant.AES_MODE_PKCS7);
+            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(SystemConstant.CHARSET_NAME), SystemConstant.AES);
+            AlgorithmParameterSpec paramSpec = new IvParameterSpec(SystemConstant.AES_RULE.getBytes());
+            cipher.init(Cipher.DECRYPT_MODE, keySpec, paramSpec);
+            decoderText = new String(cipher.doFinal(Base64.getDecoder().decode(content)), SystemConstant.CHARSET_NAME);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+        return decoderText;
+    }
+}

+ 207 - 0
eds-common/src/main/java/com/qmth/eds/common/util/AuthUtil.java

@@ -0,0 +1,207 @@
+package com.qmth.eds.common.util;//package com.qmth.teachcloud.data.store.util;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.core.enums.Platform;
+import com.qmth.boot.tools.signature.SignatureEntity;
+import com.qmth.boot.tools.signature.SignatureType;
+import com.qmth.eds.common.bean.auth.AuthBean;
+import com.qmth.eds.common.bean.auth.ExpireTimeBean;
+import com.qmth.eds.common.contant.SpringContextHolder;
+import com.qmth.eds.common.contant.SystemConstant;
+import com.qmth.eds.common.entity.SysUser;
+import com.qmth.eds.common.entity.TBSession;
+import com.qmth.eds.common.enums.ExceptionResultEnum;
+import com.qmth.eds.common.enums.PrivilegePropertyEnum;
+import com.qmth.eds.common.enums.RoleTypeEnum;
+import com.qmth.eds.common.service.CommonCacheService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.method.HandlerMethod;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
+
+/**
+ * @Description: 鉴权工具类util
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/11/12
+ */
+public class AuthUtil {
+    private final static Logger log = LoggerFactory.getLogger(AuthUtil.class);
+
+    static CommonCacheService commonCacheService = null;
+
+    /**
+     * admin鉴权
+     *
+     * @param request
+     * @param response
+     * @param handler
+     * @return
+     */
+    public static boolean adminAuthInterceptor(HttpServletRequest request, HttpServletResponse response, Object handler) {
+        String url = request.getServletPath();
+        commonCacheService = SpringContextHolder.getBean(CommonCacheService.class);
+        Set<String> privilegeUrl = commonCacheService.privilegeUrlCache(PrivilegePropertyEnum.NO_AUTH);
+        //无需鉴权的url
+        int noAuthCount = Objects.nonNull(privilegeUrl) ? (int) privilegeUrl.stream().filter(s -> s.equalsIgnoreCase(url)).count() : 0;
+        if (noAuthCount > 0) {
+            return true;
+        }
+        String method = request.getMethod();
+        if (url.equalsIgnoreCase(SystemConstant.ERROR)) {
+            throw ExceptionResultEnum.NOT_FOUND.exception();
+        }
+        Platform platform = ServletUtil.getRequestPlatform();
+        String deviceId = ServletUtil.getRequestDeviceId();
+        String authorization = ServletUtil.getRequestAuthorization();
+        Long time = ServletUtil.getRequestTime();
+        log.info("Start authorization: url:{}, method:{}, platform:{}, deviceId:{}, authorization:{}, time:{}", url,
+                method, platform, deviceId, authorization, time);
+
+        TBSession tbSession = authHeadCommon(platform, deviceId, authorization, time, method, url);
+        Long userId = Long.parseLong(tbSession.getIdentity());
+        SysUser sysUser = commonCacheService.userCache(userId);
+        request.setAttribute(SystemConstant.SESSION, tbSession);
+        request.setAttribute(SystemConstant.USER, sysUser);
+        return authFootCommon(userId, SystemConstant.USER_OAUTH_CACHE, request, response, handler);
+    }
+
+    /**
+     * 鉴权头公用
+     *
+     * @param platform
+     * @param deviceId
+     * @param authorization
+     * @param time
+     * @return
+     */
+    static TBSession authHeadCommon(Platform platform,
+                                    String deviceId,
+                                    String authorization,
+                                    long time,
+                                    String method,
+                                    String url) {
+        RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);
+//        if (SystemConstant.expire(time)) {
+//            log.warn("Authorization faile: time expired, server time=" + System.currentTimeMillis());
+//            throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
+//        }
+        //测试
+//        final SignatureEntityTest info = SignatureEntityTest.parse(authorization);
+        //校验签名信息
+        final SignatureEntity info = SignatureEntity.parse(authorization, method.toLowerCase(), url, time);
+        if (info == null) {
+            log.warn("Authorization faile: signature decode error");
+            throw ExceptionResultEnum.AUTHORIZATION_ERROR.exception();
+        }
+        if (SignatureType.TOKEN != info.getType()) {
+            log.warn("Authorization faile: signature type is not Token");
+            throw ExceptionResultEnum.AUTHORIZATION_ERROR.exception();
+        }
+        //校验session
+        String sessionId = info.getInvoker();
+        TBSession tbSession = (TBSession) redisUtil.getUserSession(sessionId);
+        if (Objects.isNull(tbSession)) {
+            log.warn("Authorization faile: session id not exists: " + sessionId);
+            throw ExceptionResultEnum.NOT_LOGIN.exception();
+        }
+        if (tbSession.getExpireTime() <= System.currentTimeMillis() || info.getTimestamp() > tbSession.getExpireTime()) {
+            log.warn("Authorization faile: session has expired, expire time=" + tbSession.getExpireTime());
+            throw ExceptionResultEnum.NOT_LOGIN.exception();
+        }
+        if (!info.validate(tbSession.getAccessToken())) {
+            log.warn("Authorization faile: access token invalid, session token is " + tbSession.getAccessToken());
+            throw ExceptionResultEnum.AUTHORIZATION_ERROR.exception();
+        }
+        if (!tbSession.getPlatform().equalsIgnoreCase(platform.name())) {
+            log.warn("Authorization faile: platform invalid, session platform is " + tbSession.getPlatform());
+            throw ExceptionResultEnum.AUTHORIZATION_ERROR.exception();
+        }
+        if (!tbSession.getDeviceId().equalsIgnoreCase(deviceId)) {
+            log.warn("Authorization faile: deviceId invalid, session deviceId is " + tbSession.getDeviceId());
+            throw ExceptionResultEnum.AUTHORIZATION_ERROR.exception();
+        }
+        return tbSession;
+    }
+
+    /**
+     * 鉴权尾公用
+     *
+     * @param userId
+     * @param type
+     * @param request
+     * @param response
+     * @param handler
+     * @return
+     */
+    static boolean authFootCommon(long userId,
+                                  String type,
+                                  HttpServletRequest request,
+                                  HttpServletResponse response,
+                                  Object handler) {
+        String url = request.getServletPath();
+        //验证权限
+        AuthBean authBean = type.contains(SystemConstant.USER_OAUTH_CACHE) ? authBean = commonCacheService.userAuthCache(userId) : null;
+        if (Objects.isNull(authBean)) {
+            throw ExceptionResultEnum.ROLE_ENABLE_AUTHORIZATION.exception();
+        }
+        request.setAttribute(SystemConstant.SCHOOL, authBean.getSchool());
+        request.setAttribute(SystemConstant.ORG, authBean.getOrg());
+
+        //超级系统管理员拥有所有权限
+        int count = Objects.nonNull(authBean) ? (int) authBean.getRoleList().stream().filter(s -> Objects.equals(s.getName(), RoleTypeEnum.ADMIN.getDesc())).count() : 0;
+        if (count > 0) {
+            return true;
+        }
+        //系统公用接口不拦截
+        Set<String> sysUrls = commonCacheService.privilegeUrlCache(PrivilegePropertyEnum.SYS, SystemConstant.getHeadOrUserSchoolId());
+        int sysCount = Objects.nonNull(sysUrls) ? (int) sysUrls.stream().filter(s -> s.equalsIgnoreCase(url)).count() : 0;
+        if (sysCount > 0) {
+            return true;
+        }
+        HandlerMethod handlerMethod = (HandlerMethod) handler;
+        Map<String, Boolean> map = new HashMap<>();
+        Aac beanTypeAac = handlerMethod.getBeanType().getAnnotation(Aac.class);
+        Aac classAac = handlerMethod.getMethodAnnotation(Aac.class);
+        if (Objects.nonNull(beanTypeAac)) {
+            map.computeIfAbsent(SystemConstant.AUTH, v -> beanTypeAac.auth() == BOOL.TRUE ? true : false);
+        }
+        if (Objects.nonNull(classAac)) {
+            map.computeIfAbsent(SystemConstant.AUTH, v -> classAac.auth() == BOOL.TRUE ? true : false);
+        }
+
+        if (Objects.nonNull(map.get(SystemConstant.AUTH)) && !map.get(SystemConstant.AUTH)) {
+            return true;
+        }
+        Set<String> urls = authBean.getUrls();
+        int privilegeCount = Objects.nonNull(urls) ? (int) urls.stream().filter(s -> s.equalsIgnoreCase(url)).count() : 0;
+        if (privilegeCount == 0) {
+            log.warn("Authorization faile: url cannot access");
+            throw ExceptionResultEnum.UN_AUTHORIZATION.exception();
+        }
+        response.setStatus(ExceptionResultEnum.SUCCESS.getCode());
+        return true;
+    }
+
+    /**
+     * 获取过期时间
+     *
+     * @param platform
+     * @return
+     */
+    public static ExpireTimeBean getExpireTime(Platform platform) {
+        ExpireTimeBean expireTimeBean = new ExpireTimeBean();
+        Date now = new Date();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(now);
+        calendar.add(Calendar.DAY_OF_YEAR, SystemConstant.DEFAULT_SESSION_EXPIRE);
+        expireTimeBean.setDate(calendar.getTime());
+        expireTimeBean.setExpireSeconds(SystemConstant.REDIS_DEFAULT_EXPIRE_TIME);
+        return expireTimeBean;
+    }
+}

+ 16 - 0
eds-common/src/main/java/com/qmth/eds/common/util/Base64Util.java

@@ -0,0 +1,16 @@
+package com.qmth.eds.common.util;
+
+import com.qmth.eds.common.contant.SystemConstant;
+
+import java.util.Base64;
+
+public class Base64Util {
+
+    public static String encode(byte[] input) {
+        return new String(Base64.getEncoder().encode(input), SystemConstant.CHARSET);
+    }
+
+    public static byte[] decode(String input) {
+        return Base64.getDecoder().decode(input.getBytes(SystemConstant.CHARSET));
+    }
+}

+ 206 - 0
eds-common/src/main/java/com/qmth/eds/common/util/FileStoreUtil.java

@@ -0,0 +1,206 @@
+package com.qmth.eds.common.util;
+
+import com.qmth.boot.core.fss.service.FileService;
+import com.qmth.boot.core.fss.store.FileStore;
+import com.qmth.eds.common.config.DictionaryConfig;
+import com.qmth.eds.common.enums.ExceptionResultEnum;
+import com.qmth.eds.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;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.*;
+import java.time.Duration;
+import java.util.Objects;
+
+/**
+ * @Description: 文件存储工具类
+ * @Author: CaoZixuan
+ * @Date: 2021-08-17
+ */
+@Component
+public class FileStoreUtil {
+    private final static Logger log = LoggerFactory.getLogger(FileStoreUtil.class);
+
+    @Resource
+    private FileService fileService;
+
+    @Resource
+    private DictionaryConfig dictionaryConfig;
+
+    /**
+     * 上传文件
+     *
+     * @param dirName     上传到地址
+     * @param inputStream 流
+     * @param type        fileStore类型
+     */
+    public void ossUpload(String dirName, InputStream inputStream, String md5, String type) throws Exception {
+        log.info("ossUpload is come in");
+        fileService.getFileStore(type).write(dirName, inputStream, md5);
+        log.info("dirName:{}", dirName);
+    }
+
+    /**
+     * 上传文件
+     *
+     * @param dirName 上传到地址
+     * @param file    文件
+     * @param type    fileStore类型
+     */
+    public void ossUpload(String dirName, File file, String md5, String type) throws Exception {
+        log.info("ossUpload is come in");
+        fileService.getFileStore(type).write(dirName, new FileInputStream(file), md5);
+        log.info("dirName:{}", dirName);
+    }
+
+    /**
+     * 上传文件
+     *
+     * @param dirName 上传到地址
+     * @param content 文件
+     * @param type    fileStore类型
+     */
+    public void ossUpload(String dirName, String content, String type) throws Exception {
+        log.info("ossUpload is come in");
+        fileService.getFileStore(type).write(dirName, new ByteArrayInputStream(content.getBytes()), DigestUtils.md5Hex(new ByteArrayInputStream(content.getBytes())));
+        log.info("dirName:{}", dirName);
+    }
+
+    /**
+     * 从文件存储上下载文件到本地
+     *
+     * @param dirName   文件地址
+     * @param localPath 本地路径
+     * @param type      fileStore类型
+     * @throws Exception 异常
+     */
+    public File ossDownload(String dirName, String localPath, String type) throws Exception {
+        log.info("ossDownload is come in");
+        return this.saveLocal(fileService.getFileStore(type).read(dirName), localPath);
+    }
+
+
+    /**
+     * 从文件存储上下载文件到byte[]
+     *
+     * @param objectName 文件地址
+     * @param type       fileStore类型
+     * @throws Exception 异常
+     */
+    public byte[] ossDownload(String objectName, String type) throws Exception {
+        log.info("oss Download is come in");
+        return IOUtils.toByteArray(fileService.getFileStore(type).read(objectName));
+    }
+
+    /**
+     * 从文件存储上下载文件到InputStream
+     *
+     * @param objectName 文件地址
+     * @param type       fileStore类型
+     * @throws Exception 异常
+     */
+    public InputStream ossDownloadIs(String objectName, String type) throws Exception {
+        log.info("oss Download is come in");
+        return fileService.getFileStore(type).read(objectName);
+    }
+
+
+    /**
+     * 获取文件访问url
+     *
+     * @param objectPath 文件路径
+     * @param type       文件上传的类型
+     * @return
+     */
+    public String getPrivateUrl(String objectPath, String type) {
+        String server = null;
+        if ("public".equals(type)) {
+            server = dictionaryConfig.fssPublicDomain().getServer();
+            return server + "/" + objectPath;
+        } else if ("private".equals(type)) {
+            Boolean oss = dictionaryConfig.sysDomain().isOss();
+            if (Objects.nonNull(oss) && oss) {
+                FileStore fileStore = fileService.getFileStore(type);
+                return fileStore.getPresignedUrl(objectPath, Duration.ofMinutes(5L));
+            } else {
+                return dictionaryConfig.fssPrivateDomain().getServer() + "/" + objectPath;
+            }
+        } else {
+            throw ExceptionResultEnum.ERROR.exception("文件存储store类型不存在");
+        }
+    }
+
+    /**
+     * 根据数据库文件路径判断文件上传类型
+     *
+     * @param path 路径
+     * @return 类型
+     */
+    public UploadFileEnum getUploadEnumByPath(String path) {
+        path = path.replaceAll("\\\\", "/");
+        String target = path.substring(0, path.indexOf('/'));
+        return UploadFileEnum.valueOf(target.toUpperCase());
+    }
+
+    /**
+     * 文件存在某本地路径
+     *
+     * @param inputStream 输入流
+     * @param dirPath     本地路径
+     * @return 存好的文件
+     * @throws IOException 异常
+     */
+    public File saveLocal(InputStream inputStream, String dirPath) throws IOException {
+        String fileName = dirPath.substring(dirPath.lastIndexOf(File.separator) + 1);
+        String parentPath = dirPath.substring(0, dirPath.lastIndexOf(File.separator)) + File.separator;
+        String name = fileName.substring(0, fileName.lastIndexOf('.'));
+        String suffix = fileName.substring(fileName.lastIndexOf('.'));
+
+        File desFile = buildSingleFileName(parentPath, name, suffix, 0);
+        if (!desFile.exists()) {
+            desFile.getParentFile().mkdirs(); //目标文件目录不存在的话需要创建目录
+            desFile.createNewFile();
+        }
+//        if (desFile.length() > 0) {
+//            return desFile;
+//        }
+        try {
+            FileUtils.copyInputStreamToFile(inputStream, desFile);
+            return desFile;
+        } finally {
+            if (inputStream != null) {
+                inputStream.close();
+            }
+        }
+    }
+
+    /**
+     * 构建唯一的文件名称
+     *
+     * @param path     文件路径
+     * @param fileName 文件名称
+     * @param suffix   文件后缀
+     * @param index    当前下标,初次为0
+     * @return 唯一的文件名称
+     */
+    public static File buildSingleFileName(String path, String fileName, String suffix, Integer index) {
+        File file;
+        //下标不等于0开始拼后缀
+        if (index != 0) {
+            file = new File(path + fileName + "(" + index + ")" + suffix);
+        } else {
+            file = new File(path + fileName + suffix);
+        }
+        //判断文件是否存在 文件不存在退出递归
+        if (file.isFile()) {
+            //每次递归给下标加1
+            file = buildSingleFileName(path, fileName, suffix, ++index);
+        }
+        return file;
+    }
+}

+ 622 - 0
eds-common/src/main/java/com/qmth/eds/common/util/FileUtil.java

@@ -0,0 +1,622 @@
+package com.qmth.eds.common.util;
+
+import com.qmth.eds.common.contant.SystemConstant;
+import com.qmth.eds.common.enums.ExceptionResultEnum;
+import org.apache.tomcat.util.http.fileupload.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+public class FileUtil {
+    private final static Logger log = LoggerFactory.getLogger(FileUtil.class);
+
+    /**
+     * 将网络文件保存到本地
+     *
+     * @param fileUrl       网络文件URL
+     * @param localFilePath 例如D:/123.txt
+     * @throws IOException
+     */
+    public static void saveUrlAsFile(String fileUrl, String localFilePath) {
+        HttpURLConnection connection = null;
+        DataOutputStream dataOutputStream = null;
+        DataInputStream dataInputStream = null;
+        try {
+            URL url = new URL(fileUrl);
+
+            connection = (HttpURLConnection) url.openConnection();
+
+            dataInputStream = new DataInputStream(connection.getInputStream());
+            FileOutputStream fileOutputStream = new FileOutputStream(localFilePath);
+            dataOutputStream = new DataOutputStream(fileOutputStream);
+
+            byte[] buffer = new byte[4096];
+            int count;
+            while ((count = dataInputStream.read(buffer)) > 0) {
+                dataOutputStream.write(buffer, 0, count);
+            }
+            fileOutputStream.flush();
+            dataOutputStream.flush();
+        } catch (IOException e) {
+            throw ExceptionResultEnum.ERROR.exception("下载文件出错" + e.getMessage());
+        } finally {
+            if (connection != null) {
+                connection.disconnect();
+            }
+            if (dataOutputStream != null) {
+                try {
+                    dataOutputStream.close();
+                } catch (IOException e) {
+                }
+            }
+            if (dataInputStream != null) {
+                try {
+                    dataInputStream.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * 将网络文件保存到本地
+     *
+     * @param fileUrl   网络文件URL
+     * @param localFile 本地文件对象
+     * @throws IOException
+     */
+    public static void saveUrlAsFile(String fileUrl, File localFile) {
+        saveUrlAsFile(fileUrl, localFile.getAbsolutePath());
+    }
+
+    /**
+     * 读取文件内容
+     *
+     * @param file
+     * @return
+     * @throws IOException
+     */
+    public static String readFileContent(File file) {
+        StringBuilder content = new StringBuilder();
+        InputStreamReader streamReader = null;
+        BufferedReader bufferedReader = null;
+        try {
+            String encoding = SystemConstant.CHARSET_NAME;
+            if (file.exists() && file.isFile()) {
+                streamReader = new InputStreamReader(new FileInputStream(file), encoding);
+                bufferedReader = new BufferedReader(streamReader);
+                String line;
+                while ((line = bufferedReader.readLine()) != null) {
+                    content.append(line);
+                }
+            }
+        } catch (IOException e) {
+            throw ExceptionResultEnum.ERROR.exception("读取文件出错" + e.getMessage());
+        } finally {
+            if (streamReader != null) {
+                try {
+                    streamReader.close();
+                } catch (IOException e) {
+                }
+            }
+            if (bufferedReader != null) {
+                try {
+                    bufferedReader.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+        return content.toString();
+    }
+
+    /**
+     * 创建文件目录
+     */
+    public static boolean makeDirs(String path) {
+        if (path == null || "".equals(path)) {
+            return false;
+        }
+        File folder = new File(path);
+        if (!folder.exists()) {
+            return folder.mkdirs();
+        }
+        return true;
+    }
+
+    /**
+     * 保存字符串到文件中 @throws IOException @throws
+     */
+    public static void saveAsFile(String path, String content) {
+        saveAsFile(path, content, null);
+    }
+
+    public static void saveAsFile(String path, String content, String encoding) {
+        if (path == null || content == null) {
+            return;
+        }
+
+        if (encoding == null) {
+            encoding = SystemConstant.CHARSET_NAME;
+        }
+        BufferedWriter bw = null;
+        try {
+            File file = new File(path);
+            if (!file.exists()) {
+                if (makeDirs(file.getParent())) {
+                    boolean ok = file.createNewFile();
+                    if (!ok) {
+                        throw ExceptionResultEnum.ERROR.exception("文件创建失败!");
+                    }
+                }
+            }
+
+            FileOutputStream fos = new FileOutputStream(file);
+            OutputStreamWriter write = new OutputStreamWriter(fos, encoding);
+            bw = new BufferedWriter(write);
+            bw.write(content);
+            bw.flush();
+        } catch (IOException e) {
+            throw ExceptionResultEnum.ERROR.exception("保存文件出错" + e.getMessage());
+        } finally {
+            if (bw != null) {
+                try {
+                    bw.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * 解压文件
+     *
+     * @param targetDir 解压目录
+     * @param zipFile   待解压的ZIP文件
+     * @throws IOException
+     */
+    public static List<File> unZip(File targetDir, File zipFile) throws IOException {
+        if (targetDir == null) {
+            throw ExceptionResultEnum.ERROR.exception("解压目录不能为空!");
+        }
+
+        if (zipFile == null) {
+            throw ExceptionResultEnum.ERROR.exception("待解压的文件不能为空!");
+        }
+
+        if (!zipFile.exists()) {
+            throw ExceptionResultEnum.ERROR.exception("待解压的文件不存在!" + zipFile.getAbsolutePath());
+        }
+
+        String zipName = zipFile.getName().toLowerCase();
+        if (zipFile.isDirectory() || zipName.indexOf(".zip") < 0) {
+            throw ExceptionResultEnum.ERROR.exception("待解压的文件格式错误!");
+        }
+
+        if (!targetDir.exists()) {
+            targetDir.mkdir();
+        }
+
+        List<File> result = new LinkedList<>();
+
+        try (ZipFile zip = new ZipFile(zipFile, StandardCharsets.UTF_8);) {
+
+            Enumeration entries = zip.entries();
+            while (entries.hasMoreElements()) {
+                ZipEntry entry = (ZipEntry) entries.nextElement();
+
+                // Linux中需要替换掉路径的反斜杠
+                String entryName = (File.separator + entry.getName()).replaceAll("\\\\", "/");
+
+                String filePath = targetDir.getAbsolutePath() + entryName;
+                File target = new File(filePath);
+                if (entry.isDirectory()) {
+                    target.mkdirs();
+                } else {
+                    File dir = target.getParentFile();
+                    if (!dir.exists()) {
+                        dir.mkdirs();
+                    }
+
+                    try (OutputStream os = new FileOutputStream(target); InputStream is = zip.getInputStream(entry);) {
+                        IOUtils.copy(is, os);
+                        os.flush();
+                    }
+                    result.add(target);
+                }
+            }
+
+        }
+
+        return result;
+    }
+
+    /**
+     * 文件压缩
+     *
+     * @param target 目录或文件 @param zipFile 压缩后的ZIP文件 @throws IOException @throws
+     */
+    public static boolean doZip(File target, File zipFile) throws IOException {
+        if (target == null || !target.exists()) {
+            throw ExceptionResultEnum.ERROR.exception("目录或文件不能为空!");
+        }
+
+        if (zipFile == null) {
+            throw ExceptionResultEnum.ERROR.exception("待压缩的文件不能为空!");
+        }
+
+        try (OutputStream outStream = new FileOutputStream(zipFile);
+             ZipOutputStream zipOutStream = new ZipOutputStream(outStream, StandardCharsets.UTF_8);) {
+            if (!zipFile.exists()) {
+                boolean ok = zipFile.createNewFile();
+                if (!ok) {
+                    throw ExceptionResultEnum.ERROR.exception("压缩的文件创建失败!");
+                }
+            }
+
+            if (target.isDirectory()) {
+                File[] files = target.listFiles();
+                if (files.length == 0) {
+                    throw ExceptionResultEnum.ERROR.exception("文件夹内未找到任何文件!");
+                }
+
+                for (File file : files) {
+                    doZip(zipOutStream, file, null);
+                }
+            } else {
+                doZip(zipOutStream, target, null);
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * @param resultFile
+     * @param sourseFiles
+     * @return
+     * @throws IOException
+     */
+    public static boolean doZip(File resultFile, List<File> sourseFiles) {
+        if (sourseFiles == null || sourseFiles.size() == 0) {
+            throw ExceptionResultEnum.ERROR.exception("待压缩的文件不能为空!");
+        }
+
+        if (resultFile == null) {
+            throw ExceptionResultEnum.ERROR.exception("压缩后的文件不能为空!");
+        }
+        ZipOutputStream zipOutStream = null;
+        try {
+            OutputStream outStream = new FileOutputStream(resultFile);
+            zipOutStream = new ZipOutputStream(outStream, StandardCharsets.UTF_8);
+            if (!resultFile.exists()) {
+                boolean ok = resultFile.createNewFile();
+                if (!ok) {
+                    throw ExceptionResultEnum.ERROR.exception("压缩的文件创建失败!");
+                }
+            }
+
+            for (File file : sourseFiles) {
+                doZip(zipOutStream, file, null);
+            }
+        } catch (IOException e) {
+            throw ExceptionResultEnum.ERROR.exception("压缩的文件创建失败!" + e.getMessage());
+        } finally {
+            if (zipOutStream != null) {
+                try {
+                    zipOutStream.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private static void doZip(ZipOutputStream zipOutStream, File target, String parentDir) throws IOException {
+        if (parentDir == null) {
+            parentDir = "";
+        }
+
+        if (!"".equals(parentDir) && !parentDir.endsWith(File.separator)) {
+            parentDir += File.separator;
+        }
+
+        if (target.isDirectory()) {
+            File[] files = target.listFiles();
+            if (files.length > 0) {
+                for (File file : files) {
+                    doZip(zipOutStream, file, parentDir + target.getName());
+                }
+            } else {
+                zipOutStream.putNextEntry(new ZipEntry(parentDir + target.getName()));
+                zipOutStream.closeEntry();
+            }
+        } else {
+            try (InputStream is = new FileInputStream(target);) {
+                zipOutStream.putNextEntry(new ZipEntry(parentDir + target.getName()));
+                int len;
+                byte[] bytes = new byte[1024];
+                while ((len = is.read(bytes)) > 0) {
+                    zipOutStream.write(bytes, 0, len);
+                }
+            }
+            zipOutStream.closeEntry();
+        }
+    }
+
+    public static void deleteFolder(String path) {
+
+        File file = new File(path);
+        if (file.exists()) {
+            if (file.isFile()) {
+                deleteFile(path);
+            } else {
+                deleteDirectory(path);
+            }
+        }
+    }
+
+    public static void deleteFile(String path) {
+        File file = new File(path);
+        deleteFile(file);
+    }
+
+    public static void deleteFile(File file) {
+        if (file.isFile() && file.exists()) {
+            file.delete();
+        }
+    }
+
+    public static void deleteDirectory(File dirFile) {
+        if (!dirFile.exists() || !dirFile.isDirectory()) {
+            return;
+        }
+        File[] files = dirFile.listFiles();
+        if (files != null) {
+            for (int i = 0; i < files.length; i++) {
+                if (files[i].isFile()) {
+                    deleteFile(files[i]);
+                } else {
+                    deleteDirectory(files[i]);
+                }
+            }
+        }
+
+        dirFile.delete();
+    }
+
+    public static void deleteDirectory(String path) {
+        if (!path.endsWith(File.separator)) {
+            path = path + File.separator;
+        }
+        File dirFile = new File(path);
+        deleteDirectory(dirFile);
+    }
+
+    private static Cipher initAESCipher(String sKey, String vector, int cipherMode) throws Exception {
+        byte[] raw;
+        raw = sKey.getBytes();
+        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+        IvParameterSpec iv = new IvParameterSpec(vector.getBytes());
+        cipher.init(cipherMode, skeySpec, iv);
+        return cipher;
+    }
+
+    /**
+     * 解密文件
+     *
+     * @param sourceFile  源文件
+     * @param decryptFile 解密后的文件
+     * @param sKey        密钥
+     * @param vc          向量
+     * @throws Exception
+     */
+    public static void decryptFile(File sourceFile, File decryptFile, String sKey, String vc) {
+        decryptOrEncryptFile(Cipher.DECRYPT_MODE, sourceFile, decryptFile, sKey, vc);
+    }
+
+    /**
+     * 加密文件
+     *
+     * @param sourceFile  源文件
+     * @param encryptFile 加密后的文件
+     * @param sKey        密钥
+     * @param vc          向量
+     * @throws Exception
+     */
+    public static void encryptFile(File sourceFile, File encryptFile, String sKey, String vc) {
+        decryptOrEncryptFile(Cipher.ENCRYPT_MODE, sourceFile, encryptFile, sKey, vc);
+    }
+
+    private static void decryptOrEncryptFile(int cipherMode, File sourceFile, File targetFile, String sKey, String vc) {
+        InputStream inputStream = null;
+        OutputStream outputStream = null;
+        try {
+            Cipher cipher = initAESCipher(sKey, vc, cipherMode);
+            inputStream = new FileInputStream(sourceFile);
+            outputStream = new FileOutputStream(targetFile);
+            CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher);
+            byte[] buffer = new byte[1024];
+            int r;
+            while ((r = inputStream.read(buffer)) >= 0) {
+                cipherOutputStream.write(buffer, 0, r);
+            }
+            cipherOutputStream.close();
+        } catch (Exception e) {
+            throw ExceptionResultEnum.ERROR.exception("加解密文件失败!" + e.getMessage());
+        } finally {
+            try {
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+            } catch (IOException e) {
+            }
+            try {
+                if (outputStream != null) {
+                    outputStream.close();
+                }
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * 文件转数组
+     *
+     * @param file
+     * @return
+     * @throws IOException
+     */
+    public static byte[] fileConvertToByteArray(File file) throws IOException {
+        byte[] data = null;
+        FileInputStream fis = null;
+        ByteArrayOutputStream baos = null;
+        try {
+            fis = new FileInputStream(file);
+            baos = new ByteArrayOutputStream();
+            int len;
+            byte[] buffer = new byte[1024];
+            while ((len = fis.read(buffer)) != -1) {
+                baos.write(buffer, 0, len);
+            }
+            data = baos.toByteArray();
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        } finally {
+            if (Objects.nonNull(fis)) {
+                fis.close();
+            }
+            if (Objects.nonNull(baos)) {
+                baos.flush();
+                baos.close();
+            }
+        }
+        return data;
+    }
+
+    public static File multipartFileToFile(MultipartFile file) throws Exception {
+
+        File toFile = null;
+        if (file.equals("") || file.getSize() <= 0) {
+            file = null;
+        } else {
+            InputStream ins = null;
+            ins = file.getInputStream();
+            toFile = new File(file.getOriginalFilename());
+            inputStreamToFile(ins, toFile);
+            ins.close();
+        }
+        return toFile;
+    }
+
+    //获取流文件
+    private static void inputStreamToFile(InputStream ins, File file) {
+        try {
+            OutputStream os = new FileOutputStream(file);
+            int bytesRead = 0;
+            byte[] buffer = new byte[8192];
+            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
+                os.write(buffer, 0, bytesRead);
+            }
+            os.close();
+            ins.close();
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+    }
+
+    /**
+     * 生成txt文件
+     *
+     * @param fileName 文件名
+     * @param list     内容集合
+     */
+    public static File writeTxt(String fileName, List<String> list) throws IOException {
+        File file = new File(fileName);
+        File parentFile = file.getParentFile();
+        if (!parentFile.exists()) {
+            parentFile.mkdirs();
+        }
+        if (!file.exists()) {
+            file.createNewFile();
+        }
+        FileWriter write = null;
+        BufferedWriter bw = null;
+        try {
+            write = new FileWriter(file);
+            bw = new BufferedWriter(write);
+            for (String s : list) {
+                bw.write(s.trim());
+                bw.newLine();
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (bw != null) {
+                bw.close();
+            }
+            if (write != null) {
+                write.close();
+            }
+        }
+        return file;
+    }
+
+    /**
+     * 输出流
+     *
+     * @param response response
+     * @param file     源文件
+     * @param fileName 文件名
+     */
+    public static void outputFile(HttpServletResponse response, File file, String fileName) {
+        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("application/x-msdownload");
+            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 (FileNotFoundException e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        } catch (IOException e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+    }
+}

+ 25 - 0
eds-common/src/main/java/com/qmth/eds/common/util/HexUtils.java

@@ -0,0 +1,25 @@
+package com.qmth.eds.common.util;
+
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Hex;
+
+public class HexUtils {
+
+    /**
+     * Hex编码.
+     */
+    public static String encodeHex(byte[] input) {
+        return Hex.encodeHexString(input);
+    }
+
+    /**
+     * Hex解码.
+     */
+    public static byte[] decodeHex(String input) {
+        try {
+            return Hex.decodeHex(input.toCharArray());
+        } catch (DecoderException e) {
+            return null;
+        }
+    }
+}

+ 299 - 0
eds-common/src/main/java/com/qmth/eds/common/util/HttpKit.java

@@ -0,0 +1,299 @@
+package com.qmth.eds.common.util;
+
+import com.qmth.eds.common.contant.SystemConstant;
+import com.qmth.eds.common.enums.ExceptionResultEnum;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.List;
+import java.util.Map;
+
+public class HttpKit {
+    private final static Logger log = LoggerFactory.getLogger(HttpKit.class);
+
+
+    /**
+     * 向指定URL发送GET方法的请求
+     * @param url:发送请求的URL
+     * @param params:请求参数,请求参数应该是 name1=value1&name2=value2&name3=value3 的形式。
+     * @return String[result]:所代表远程资源的响应结果
+     */
+    public static String sendGet(String url,  Map<String, String> params, Map<String, String> requestHeader) {
+        String result = "";
+        BufferedReader in = null;
+        try {
+            String urlNameString = url;
+            // 发送请求参数
+            if (params != null) {
+                StringBuilder param = new StringBuilder();
+                for (Map.Entry<String, String> entry : params.entrySet()) {
+                    if (param.length() > 0) {
+                        param.append("&");
+                    }
+                    param.append(entry.getKey());
+                    param.append("=");
+                    param.append(entry.getValue());
+                }
+                urlNameString = urlNameString.concat("?").concat(param.toString());
+            }
+            URL realUrl = new URL(urlNameString);
+
+            // 打开和URL之间的连接
+            URLConnection connection = realUrl.openConnection();
+
+            // 设置通用的请求属性
+            connection.setRequestProperty("accept", "*/*");
+            connection.setRequestProperty("connection", "Keep-Alive");
+            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+
+            if (requestHeader != null && requestHeader.size() > 0) {
+                for (Map.Entry<String, String> entry : requestHeader.entrySet()) {
+                    connection.setRequestProperty(entry.getKey(), entry.getValue());
+                }
+            }
+            // 建立实际的连接
+            connection.connect();
+
+            // 定义 BufferedReader输入流来读取URL的响应
+            in = new BufferedReader(new InputStreamReader(
+                    connection.getInputStream()));
+            String line;
+            while ((line = in.readLine()) != null) {
+                result += line;
+            }
+        } catch (Exception e) {
+            throw ExceptionResultEnum.ERROR.exception(e.getMessage());
+        }
+
+        // 使用finally块来关闭输入流
+        finally {
+            try {
+                if (in != null) {
+                    in.close();
+                }
+            } catch (Exception e2) {
+                throw ExceptionResultEnum.ERROR.exception(e2.getMessage());
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 向指定 URL 发送POST方法的请求
+     *
+     * @param url    发送请求的 URL
+     * @param params 请求的参数集合
+     * @return 远程资源的响应结果
+     */
+    @SuppressWarnings("unused")
+    public static String sendPost(String url, Map<String, String> params, Map<String, String> requestHeader) {
+        OutputStreamWriter out = null;
+        BufferedReader reader = null;
+        int responseCode = 200;
+        StringBuilder result = new StringBuilder();
+        try {
+            URL realUrl = new URL(url);
+            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
+            // 发送POST请求必须设置如下两行
+            connection.setDoOutput(true);
+            connection.setDoInput(true);
+            // POST方法
+            connection.setRequestMethod("POST");
+            // 设置通用的请求属性
+            connection.setRequestProperty("accept", "*/*");
+            connection.setRequestProperty("connection", "Keep-Alive");
+            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+            if (requestHeader != null && requestHeader.size() > 0) {
+                for (Map.Entry<String, String> entry : requestHeader.entrySet()) {
+                    connection.setRequestProperty(entry.getKey(), entry.getValue());
+                }
+            }
+            connection.connect();
+            // 获取URLConnection对象对应的输出流
+            out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
+            // 发送请求参数
+            if (params != null) {
+                StringBuilder param = new StringBuilder();
+                for (Map.Entry<String, String> entry : params.entrySet()) {
+                    if (param.length() > 0) {
+                        param.append("&");
+                    }
+                    param.append(entry.getKey());
+                    param.append("=");
+                    param.append(entry.getValue());
+                }
+                out.write(param.toString());
+            }
+            // flush输出流的缓冲
+            out.flush();
+            // 定义BufferedReader输入流来读取URL的响应
+            responseCode = connection.getResponseCode();
+            if (responseCode >= 400) {
+                Map<String, List<String>> responseProperties = connection.getHeaderFields();
+                if (responseProperties.containsKey("error-info")) {
+                    List<String> strings = responseProperties.get("error-info");
+                    if (!strings.isEmpty()) {
+                        String message = String.join(";", strings);
+                        throw ExceptionResultEnum.ERROR.exception(message);
+                    }
+                }
+                throw ExceptionResultEnum.ERROR.exception("接口调用错误");
+            } else {
+                reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
+            }
+            String line;
+            while ((line = reader.readLine()) != null) {
+                result.append(line);
+            }
+        } catch (Exception e) {
+            throw ExceptionResultEnum.ERROR.exception("调用接口异常:错误码[" + responseCode + "],错误原因[" + e.getMessage() + "]");
+        }
+        //使用finally块来关闭输出流、输入流
+        finally {
+            try {
+                if (out != null) {
+                    out.close();
+                }
+                if (reader != null) {
+                    reader.close();
+                }
+            } catch (IOException ex) {
+                log.error(SystemConstant.LOG_ERROR, ex);
+            }
+        }
+        return result.toString();
+    }
+
+
+    /**
+     * 发送post请求
+     *
+     * @param requestUrl       请求url
+     * @param requestHeader    请求头
+     * @param formTexts        表单数据
+     * @param files            上传文件
+     * @param requestEncoding  请求编码
+     * @param responseEncoding 响应编码
+     * @return 页面响应html
+     */
+    public static String sendPost(String requestUrl, Map<String, String> requestHeader, Map<String, Object> formTexts, Map<String, String> files, String requestEncoding, String responseEncoding) {
+        OutputStream out = null;
+        BufferedReader reader = null;
+        StringBuilder result = new StringBuilder();
+        int responseCode = 200;
+        try {
+            if (requestUrl == null || requestUrl.isEmpty()) {
+                return result.toString();
+            }
+            URL realUrl = new URL(requestUrl);
+            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
+            connection.setRequestProperty("accept", "text/html, application/xhtml+xml, image/jxr, */*");
+            connection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0");
+            if (requestHeader != null && requestHeader.size() > 0) {
+                for (Map.Entry<String, String> entry : requestHeader.entrySet()) {
+                    connection.setRequestProperty(entry.getKey(), entry.getValue());
+                }
+            }
+            connection.setDoOutput(true);
+            connection.setDoInput(true);
+            connection.setRequestMethod("POST");
+            if (requestEncoding == null || requestEncoding.isEmpty()) {
+                requestEncoding = "UTF-8";
+            }
+            if (responseEncoding == null || responseEncoding.isEmpty()) {
+                responseEncoding = "UTF-8";
+            }
+            if (files == null || files.size() == 0) {
+                connection.setRequestProperty("content-type", "application/x-www-form-urlencoded");
+                out = new DataOutputStream(connection.getOutputStream());
+                if (formTexts != null && formTexts.size() > 0) {
+                    String formData = "";
+                    for (Map.Entry<String, Object> entry : formTexts.entrySet()) {
+                        formData += entry.getKey() + "=" + entry.getValue() + "&";
+                    }
+                    formData = formData.substring(0, formData.length() - 1);
+                    out.write(formData.getBytes(requestEncoding));
+                }
+            } else {
+                String boundary = "-----------------------------" + System.currentTimeMillis();
+                connection.setRequestProperty("content-type", "multipart/form-data; boundary=" + boundary);
+                out = new DataOutputStream(connection.getOutputStream());
+                if (formTexts != null && formTexts.size() > 0) {
+                    StringBuilder sbFormData = new StringBuilder();
+                    for (Map.Entry<String, Object> entry : formTexts.entrySet()) {
+                        sbFormData.append("--" + boundary + "\r\n");
+                        sbFormData.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"\r\n\r\n");
+                        sbFormData.append(entry.getValue() + "\r\n");
+                    }
+                    out.write(sbFormData.toString().getBytes(requestEncoding));
+                }
+                for (Map.Entry<String, String> entry : files.entrySet()) {
+                    String fileName = entry.getKey();
+                    String filePath = entry.getValue();
+                    if (fileName == null || fileName.isEmpty() || filePath == null || filePath.isEmpty()) {
+                        continue;
+                    }
+                    File file = new File(filePath);
+                    if (!file.exists()) {
+                        continue;
+                    }
+                    out.write(("--" + boundary + "\r\n").getBytes(requestEncoding));
+                    out.write(("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"\r\n").getBytes(requestEncoding));
+                    out.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes(requestEncoding));
+                    DataInputStream in = new DataInputStream(new FileInputStream(file));
+                    int bytes = 0;
+                    byte[] bufferOut = new byte[1024];
+                    while ((bytes = in.read(bufferOut)) != -1) {
+                        out.write(bufferOut, 0, bytes);
+                    }
+                    in.close();
+                    out.write(("\r\n").getBytes(requestEncoding));
+                }
+                out.write(("--" + boundary + "--").getBytes(requestEncoding));
+            }
+            out.flush();
+            out.close();
+
+
+            responseCode = connection.getResponseCode();
+            if (responseCode >= 400) {
+//                reader = new BufferedReader(new InputStreamReader(connection.getErrorStream(), responseEncoding));
+                Map<String, List<String>> responseProperties = connection.getHeaderFields();
+                if (responseProperties.containsKey("error-info")) {
+                    List<String> strings = responseProperties.get("error-info");
+                    if (!strings.isEmpty()) {
+                        String message = String.join(";", strings);
+                        throw ExceptionResultEnum.ERROR.exception(message);
+                    }
+                }
+                throw ExceptionResultEnum.ERROR.exception("接口调用错误");
+            } else {
+                reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), responseEncoding));
+            }
+            String line;
+            while ((line = reader.readLine()) != null) {
+                result.append(line);
+            }
+        } catch (Exception e) {
+            throw ExceptionResultEnum.ERROR.exception("调用接口异常:错误码[" + responseCode + "],错误原因[" + e.getMessage() + "]");
+        } finally {
+            try {
+                if (out != null) {
+                    out.close();
+                }
+                if (reader != null) {
+                    reader.close();
+                }
+            } catch (IOException ex) {
+                log.error(SystemConstant.LOG_ERROR, ex);
+            }
+        }
+        return result.toString();
+    }
+
+}

+ 228 - 0
eds-common/src/main/java/com/qmth/eds/common/util/HttpUtil.java

@@ -0,0 +1,228 @@
+package com.qmth.eds.common.util;
+
+import com.qmth.eds.common.contant.SystemConstant;
+import com.qmth.eds.common.enums.ExceptionResultEnum;
+import org.apache.commons.io.FileUtils;
+import org.apache.http.Consts;
+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;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.util.EntityUtils;
+import org.apache.tomcat.util.http.fileupload.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+/**
+ * @Description: http util
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/12/11
+ */
+public class HttpUtil {
+    private final static Logger log = LoggerFactory.getLogger(HttpUtil.class);
+
+    /**
+     * post json
+     *
+     * @param url
+     * @param json
+     * @param secret
+     * @param timestamp
+     * @return
+     * @throws IOException
+     */
+    public static String postJson(String url, String json, String secret, Long timestamp) throws IOException {
+        // 构建post请求
+        HttpPost post = new HttpPost(url);
+        post.setHeader("authorization-token", secret);
+        post.setHeader(SystemConstant.HEADER_TIME, String.valueOf(timestamp));
+        post.setHeader(HTTP.CONTENT_TYPE, "application/json; charset=utf-8");
+        post.setHeader("Accept", "application/json");
+
+        String encoderJson = URLEncoder.encode(json, SystemConstant.CHARSET_NAME);
+        StringEntity se = new StringEntity(encoderJson);
+        se.setContentType("text/json");
+        se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
+        post.setEntity(se);
+        // 执行请求,获取响应
+        return getRespString(post);
+    }
+
+    /**
+     * post 请求
+     *
+     * @param url
+     * @param params
+     * @param secret
+     * @param timestamp
+     * @return
+     */
+    public static String post(String url, Map<String, Object> params, String secret, Long timestamp) throws IOException {
+        // 构建post请求
+        HttpPost post = new HttpPost(url);
+        if (Objects.nonNull(secret)) {
+            post.setHeader(SystemConstant.HEADER_AUTHORIZATION, secret);
+        }
+        if (Objects.nonNull(timestamp)) {
+            post.setHeader(SystemConstant.HEADER_TIME, String.valueOf(timestamp));
+        }
+
+        post.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
+        // 构建请求参数
+        List<BasicNameValuePair> pairs = new ArrayList<BasicNameValuePair>();
+        if (params != null) {
+            for (String key : params.keySet()) {
+                pairs.add(new BasicNameValuePair(key, String.valueOf(params.get(key))));
+            }
+        }
+        HttpEntity entity = null;
+        try {
+            entity = new UrlEncodedFormEntity(pairs, SystemConstant.CHARSET_NAME);
+        } catch (UnsupportedEncodingException e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+        post.setEntity(entity);
+        log.info("pairs:{}", JacksonUtil.parseJson(pairs));
+        // 执行请求,获取响应
+        return getRespString(post);
+    }
+
+    /**
+     * get 请求
+     *
+     * @param url
+     * @param params
+     * @param secret
+     * @param timestamp
+     * @return
+     */
+    public static String get(String url, Map<String, Object> params, String secret, Long timestamp) throws IOException {
+        // 构建请求参数
+        List<BasicNameValuePair> pairs = new ArrayList<BasicNameValuePair>();
+        if (params != null) {
+            for (String key : params.keySet()) {
+                pairs.add(new BasicNameValuePair(key, String.valueOf(params.get(key))));
+            }
+        }
+        String str = EntityUtils.toString(new UrlEncodedFormEntity(pairs, Consts.UTF_8));//转换为键值对
+        HttpGet get = new HttpGet(url + "?" + str);
+        if (Objects.nonNull(secret)) {
+            get.setHeader(SystemConstant.HEADER_AUTHORIZATION, secret);
+        }
+        if (Objects.nonNull(timestamp)) {
+            get.setHeader(SystemConstant.HEADER_TIME, String.valueOf(timestamp));
+        }
+        // 执行请求,获取响应
+        return getRespString(get);
+    }
+
+    /**
+     * 获取响应信息
+     *
+     * @param request
+     * @return
+     */
+    public static String getRespString(HttpUriRequest request) throws IOException {
+        // 获取响应流
+        InputStream in = null;
+        ByteArrayOutputStream ou = null;
+        try {
+            in = getRespInputStream(request);
+            ou = new ByteArrayOutputStream();
+            IOUtils.copy(in, ou);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        } finally {
+            if (Objects.nonNull(in)) {
+                in.close();
+            }
+            if (Objects.nonNull(ou)) {
+                ou.close();
+            }
+        }
+        return Objects.nonNull(ou) ? new String(ou.toByteArray(), StandardCharsets.UTF_8) : null;
+    }
+
+    /**
+     * 获取输入流
+     *
+     * @param request
+     * @return
+     */
+    public static InputStream getRespInputStream(HttpUriRequest request) {
+        // 获取响应对象
+        HttpResponse response = null;
+        try {
+            log.info("request:{}", request.getURI());
+            log.info("request.getMethod:{}", request.getMethod());
+            response = HttpClients.createDefault().execute(request);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+        if (response == null) {
+            return null;
+        }
+        // 获取Entity对象
+        HttpEntity entity = response.getEntity();
+        // 获取响应信息流
+        InputStream in = null;
+        if (entity != null) {
+            try {
+                in = entity.getContent();
+            } catch (Exception e) {
+                log.error(SystemConstant.LOG_ERROR, e);
+            }
+        }
+        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) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        } finally {
+            if (Objects.nonNull(is)) {
+                is.close();
+            }
+        }
+        return file;
+    }
+}

+ 57 - 0
eds-common/src/main/java/com/qmth/eds/common/util/IpUtil.java

@@ -0,0 +1,57 @@
+package com.qmth.eds.common.util;
+
+import org.apache.commons.lang3.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class IpUtil {
+
+    /**
+     * 获取过程ip(默认不包含代理ip)
+     *
+     * @param request
+     * @return
+     */
+    public static String getRemoteIp(HttpServletRequest request) {
+        return getRemoteIp(request, true);
+    }
+
+    /**
+     * excludeProxyIp
+     *
+     * @param request
+     * @param excludeProxyIp 是否排除代理ip
+     * @return
+     */
+    public static String getRemoteIp(HttpServletRequest request, boolean excludeProxyIp) {
+        String ip = request.getHeader("X-Forwarded-For");
+        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("x-real-ip");
+        }
+        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_CLIENT_IP");
+        }
+        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+        }
+        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+
+        if (excludeProxyIp) {
+            //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
+            if (ip != null && ip.length() > 15) { //"***.***.***.***".length() = 15
+                if (ip.indexOf(",") > 0) {
+                    ip = ip.substring(0, ip.indexOf(","));
+                }
+            }
+        }
+        return ip;
+    }
+}

+ 108 - 0
eds-common/src/main/java/com/qmth/eds/common/util/JacksonUtil.java

@@ -0,0 +1,108 @@
+package com.qmth.eds.common.util;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.qmth.eds.common.contant.SystemConstant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * @Description: jackson util
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/7/6
+ */
+public class JacksonUtil {
+    private final static Logger log = LoggerFactory.getLogger(JacksonUtil.class);
+    private volatile static ObjectMapper objectMapper = null;
+
+    static {
+        getInstance();
+    }
+
+    public static ObjectMapper getInstance() {
+        if (Objects.isNull(objectMapper)) {
+            synchronized (ObjectMapper.class) {
+                if (Objects.isNull(objectMapper)) {
+//                    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);//排除json字符串中实体类没有的字段
+                    objectMapper = new ObjectMapper();
+                }
+            }
+        }
+        return objectMapper;
+    }
+
+    /**
+     * 解析json
+     *
+     * @param o
+     * @return
+     */
+    public static String parseJson(Object o) {
+        try {
+            return objectMapper.writeValueAsString(o);
+        } catch (JsonProcessingException e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+        return null;
+    }
+
+    /**
+     * 读取json
+     *
+     * @param o
+     * @param valueType
+     * @param <T>
+     * @return
+     */
+    public static <T> T readJson(String o, Class<T> valueType) {
+        try {
+            return objectMapper.readValue(o, valueType);
+        } catch (JsonProcessingException e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+        return null;
+    }
+
+    /**
+     * 读取json list
+     *
+     * @param o
+     * @param cla
+     * @param <T>
+     * @return
+     */
+    public static <T> T readJsonList(String o, Class<T> cla) {
+        try {
+            JavaType javaType = objectMapper.getTypeFactory().constructCollectionType(List.class, cla);
+            return objectMapper.readValue(o, javaType);
+        } catch (JsonProcessingException e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+        return null;
+    }
+
+    /**
+     * 读取json set
+     *
+     * @param o
+     * @param cla
+     * @param <T>
+     * @return
+     */
+    public static <T> T readJsonSet(String o, Class<T> cla) {
+        try {
+            JavaType javaType = objectMapper.getTypeFactory().constructCollectionType(Set.class, cla);
+            return objectMapper.readValue(o, javaType);
+        } catch (JsonProcessingException e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+        return null;
+    }
+}

+ 57 - 0
eds-common/src/main/java/com/qmth/eds/common/util/MD5Util.java

@@ -0,0 +1,57 @@
+package com.qmth.eds.common.util;
+
+import com.qmth.eds.common.contant.SystemConstant;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Optional;
+import java.util.StringJoiner;
+
+/**
+ * @Description: MD5加密工具类
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2019/10/11
+ */
+public class MD5Util {
+
+    /**
+     * MD5加密
+     *
+     * @param text
+     * @return
+     * @throws Exception
+     */
+    public static String encoder(String text) throws NoSuchAlgorithmException {
+        text = Optional.of(text).get();
+        MessageDigest digest = MessageDigest.getInstance(SystemConstant.MD5);
+        digest.update(text.getBytes(SystemConstant.CHARSET));
+        byte s[] = digest.digest();
+        StringJoiner result = new StringJoiner("");
+        for (int i = 0; i < s.length; i++) {
+            result.add(Integer.toHexString((0x000000FF & s[i]) | 0xFFFFFF00).substring(6));
+        }
+        return result.toString();
+    }
+
+    /**
+     * MD5校验
+     *
+     * @param text
+     * @param md5
+     * @return
+     * @throws Exception
+     */
+    public static boolean verify(String text, String md5) throws NoSuchAlgorithmException {
+        text = Optional.of(text).get();
+        md5 = Optional.of(md5).get();
+        //根据传入的密钥进行验证
+        String md5Text = encoder(text);
+        if (md5Text.equalsIgnoreCase(md5)) {
+            return true;
+        }
+        return false;
+    }
+}
+

+ 79 - 0
eds-common/src/main/java/com/qmth/eds/common/util/RSAUtils.java

@@ -0,0 +1,79 @@
+package com.qmth.eds.common.util;
+
+import com.qmth.eds.common.contant.SystemConstant;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import java.io.UnsupportedEncodingException;
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+public class RSAUtils {
+
+    private static final String ALGORITHM_NAME = "RSA";
+
+    public static RSAPrivateKey buildPrivateKey(String key)
+            throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException {
+        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_NAME);
+        PKCS8EncodedKeySpec pkcs8eks = new PKCS8EncodedKeySpec(Base64Util.decode(key));
+        return (RSAPrivateKey) keyFactory.generatePrivate(pkcs8eks);
+    }
+
+    public static RSAPublicKey buildPublicKey(String key)
+            throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException {
+        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_NAME);
+        X509EncodedKeySpec x509eks = new X509EncodedKeySpec(Base64Util.decode(key));
+        return (RSAPublicKey) keyFactory.generatePublic(x509eks);
+    }
+
+    public static String encrypt(String input, RSAPrivateKey privateKey)
+            throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException,
+            IllegalBlockSizeException, BadPaddingException {
+        Cipher cipher = Cipher.getInstance(ALGORITHM_NAME);
+        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
+        return Base64Util.encode(cipher.doFinal(input.getBytes(SystemConstant.CHARSET_NAME)));
+    }
+
+    public static String encrypt(byte[] input, RSAPrivateKey privateKey)
+            throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException,
+            IllegalBlockSizeException, BadPaddingException {
+        Cipher cipher = Cipher.getInstance(ALGORITHM_NAME);
+        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
+        return Base64Util.encode(cipher.doFinal(input));
+    }
+
+    public static String decrypt(String input, RSAPublicKey publicKey)
+            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
+            UnsupportedEncodingException {
+        Cipher cipher = Cipher.getInstance(ALGORITHM_NAME);
+        cipher.init(Cipher.DECRYPT_MODE, publicKey);
+        return new String(cipher.doFinal(Base64Util.decode(input)), SystemConstant.CHARSET_NAME);
+    }
+
+    public static byte[] decrypt2byte(String input, RSAPublicKey publicKey)
+            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
+            UnsupportedEncodingException {
+        Cipher cipher = Cipher.getInstance(ALGORITHM_NAME);
+        cipher.init(Cipher.DECRYPT_MODE, publicKey);
+        return cipher.doFinal(Base64Util.decode(input));
+    }
+
+    public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
+        // RSA加密算法
+        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM_NAME);
+        // 创建密钥对,长度采用1024
+        keyPairGenerator.initialize(1024);
+        KeyPair keyPair = keyPairGenerator.generateKeyPair();
+        // 分别得到公钥和私钥
+        String publicKey = Base64Util.encode(((RSAPublicKey) keyPair.getPublic()).getEncoded());
+        String privateKey = Base64Util.encode(((RSAPrivateKey) keyPair.getPrivate()).getEncoded());
+        System.out.println("publicKey:" + publicKey);
+        System.out.println("privateKey:" + privateKey);
+    }
+}

+ 266 - 0
eds-common/src/main/java/com/qmth/eds/common/util/RedisUtil.java

@@ -0,0 +1,266 @@
+package com.qmth.eds.common.util;
+
+import com.qmth.eds.common.contant.SystemConstant;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @Description: redis util
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/4/15
+ */
+@Component
+public class RedisUtil {
+
+    @Resource
+    RedisTemplate<String, Object> redisTemplate;
+
+    /**
+     * 获取用户会话信息
+     *
+     * @param sessionId
+     * @return
+     */
+    public Object getUserSession(String sessionId) {
+        return redisTemplate.opsForValue().get(SystemConstant.SESSION + sessionId);
+    }
+
+    /**
+     * 删除用户会话缓存
+     *
+     * @param sessionId
+     */
+    public void deleteUserSession(String sessionId) {
+        redisTemplate.delete(SystemConstant.SESSION + sessionId);
+    }
+
+    /**
+     * 设置用户session信息
+     *
+     * @param sessionId
+     * @param o
+     * @param time
+     */
+    public void setUserSession(String sessionId, Object o, long time) {
+        redisTemplate.opsForValue().set(SystemConstant.SESSION + sessionId, o, time, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 获取过期时间
+     *
+     * @param sessionId
+     * @return
+     */
+    public Long getUserSessionExpire(String sessionId) {
+        return redisTemplate.opsForValue().getOperations().getExpire(SystemConstant.SESSION + sessionId);
+    }
+
+    /**
+     * 批量获取key的value
+     *
+     * @param keys
+     * @return
+     */
+    public List<?> multiGet(Set keys) {
+        return redisTemplate.opsForValue().multiGet(keys);
+    }
+
+    /**
+     * 获取key like
+     *
+     * @param key
+     * @return
+     */
+    public Set<?> getKeyPatterns(String key) {
+        if (Objects.nonNull(key)) {
+            return redisTemplate.keys(key);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * 设置hash
+     *
+     * @param key
+     * @param hashKey
+     * @param hashValue
+     */
+    public void set(String key, String hashKey, Object hashValue) {
+        redisTemplate.opsForHash().put(key, hashKey, hashValue);
+    }
+
+    /**
+     * 获取hash
+     *
+     * @param key
+     * @param hashKey
+     * @return
+     */
+    public Object get(String key, String hashKey) {
+        return redisTemplate.opsForHash().get(key, hashKey);
+    }
+
+    /**
+     * hash删除
+     *
+     * @param key
+     * @param hashKey
+     */
+    public void delete(String key, String hashKey) {
+        redisTemplate.opsForHash().delete(key, hashKey);
+    }
+
+    /**
+     * 获取hash大小
+     *
+     * @param key
+     * @return
+     */
+    public Long getHashSize(String key) {
+        return redisTemplate.opsForHash().size(key);
+    }
+
+    /**
+     * 获取hash map
+     *
+     * @param key
+     * @return
+     */
+    public Map getHashEntries(String key) {
+        return redisTemplate.opsForHash().entries(key);
+    }
+
+    /**
+     * 分布式锁
+     *
+     * @param key
+     * @param timeout SECONDS
+     * @return
+     */
+    public boolean lock(String key, long timeout) {
+        long expireAt = System.currentTimeMillis() + (timeout * 1000) + 1;
+        return redisTemplate.opsForValue().setIfAbsent(key, expireAt, timeout, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 删除锁
+     *
+     * @param key
+     * @return
+     */
+    public void releaseLock(String key) {
+        redisTemplate.expire(key, 100, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * 设置缓存
+     *
+     * @param key
+     * @param o
+     */
+    public void set(String key, Object o) {
+        redisTemplate.opsForValue().set(key, o);
+    }
+
+    /**
+     * 设置缓存
+     *
+     * @param key
+     * @param o
+     * @param time
+     * @param timeUnit
+     */
+    public void set(String key, Object o, long time, TimeUnit timeUnit) {
+        redisTemplate.opsForValue().set(key, o, time, timeUnit);
+    }
+
+    /**
+     * 设置缓存
+     *
+     * @param key
+     * @param o
+     * @param time SECONDS
+     */
+    public void set(String key, Object o, long time) {
+        set(key, o, time, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 获取缓存
+     *
+     * @param key
+     * @return
+     */
+    public Object get(String key) {
+        return redisTemplate.opsForValue().get(key);
+    }
+
+    /**
+     * 删除缓存
+     *
+     * @param key
+     * @return
+     */
+    public void delete(String key) {
+        redisTemplate.expire(key, 0, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 保存hash结构
+     *
+     * @param key
+     * @param map
+     */
+    public void setForHash(String key, Map<String, Object> map) {
+        redisTemplate.opsForHash().putAll(key, map);
+    }
+
+    /**
+     * 保存list
+     *
+     * @param key
+     * @param Object
+     */
+    public void setForLeftList(String key, Object Object) {
+        redisTemplate.opsForList().leftPush(key, Object);
+    }
+
+    /**
+     * 获取list
+     *
+     * @param key
+     */
+    public Object getForRightList(String key) {
+        return redisTemplate.opsForList().rightPop(key, 0, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 设置过期时间(秒)
+     *
+     * @param key
+     * @param timeOutSecond
+     */
+    public void expire(String key, int timeOutSecond) {
+        redisTemplate.expire(key, timeOutSecond, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 设置过期时间
+     *
+     * @param key
+     * @param timeOut
+     */
+    public void expire(String key, long timeOut, TimeUnit timeUnit) {
+        redisTemplate.expire(key, timeOut, timeUnit);
+    }
+}

+ 70 - 0
eds-common/src/main/java/com/qmth/eds/common/util/Result.java

@@ -0,0 +1,70 @@
+package com.qmth.eds.common.util;
+
+import java.io.Serializable;
+
+/**
+ * @Description: 自定义处理消息
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2019/10/11
+ */
+//@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Result implements Serializable {
+    private int code;
+    private String message;
+    private Object data;
+
+    public Result() {
+
+    }
+
+    public Result(int code) {
+        this.code = code;
+    }
+
+    public Result(String message) {
+        this.message = message;
+    }
+
+    public Result(int code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Result(int code, String message, Object data) {
+        this.code = code;
+        this.message = message;
+        this.data = data;
+    }
+
+    public Result(int code, Object data, String message) {
+        this.code = code;
+        this.data = data;
+        this.message = message;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+}

+ 66 - 0
eds-common/src/main/java/com/qmth/eds/common/util/ResultUtil.java

@@ -0,0 +1,66 @@
+package com.qmth.eds.common.util;
+
+import cn.hutool.http.HttpStatus;
+import com.qmth.boot.api.exception.ApiException;
+import com.qmth.eds.common.contant.SystemConstant;
+import com.qmth.eds.common.enums.ExceptionResultEnum;
+
+import java.util.Collections;
+
+/**
+ * @Description: 自定义消息工具
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2019/10/11
+ */
+public class ResultUtil {
+
+    public static Result success(Object object) {
+        return new Result(ExceptionResultEnum.SUCCESS.getStatus().value(), ExceptionResultEnum.SUCCESS.getMessage(), object);
+    }
+
+    public static Result success() {
+        return success(null);
+    }
+
+    public static Result error(int code, String message) {
+        return new Result(code, message);
+    }
+
+    public static Result error() {
+        throw ExceptionResultEnum.EXCEPTION_ERROR.exception();
+    }
+
+    public static Result error(ApiException e, String message) {
+        throw new ApiException(e.getStatus(), e.getCode(), message, message);
+    }
+
+    public static Result error(ExceptionResultEnum e, int code, String message) {
+        throw e.exception(code, message);
+    }
+
+    public static Result error(String message) {
+        throw ExceptionResultEnum.ERROR.exception(message);
+    }
+
+    public static Result ok(String message) {
+        return new Result(ExceptionResultEnum.SUCCESS.getStatus().value(), message);
+    }
+
+    public static Result ok(Object data) {
+        return new Result(ExceptionResultEnum.SUCCESS.getStatus().value(), data, ExceptionResultEnum.SUCCESS.getMessage());
+    }
+
+    public static Result ok(boolean success) {
+        return new Result(ExceptionResultEnum.SUCCESS.getStatus().value(), Collections.singletonMap(SystemConstant.SUCCESS, success), ExceptionResultEnum.SUCCESS.getMessage());
+    }
+
+    public static Result ok(Object data, String message) {
+        return new Result(ExceptionResultEnum.SUCCESS.getStatus().value(), data, message);
+    }
+
+    public static Result ok() {
+        return new Result(HttpStatus.HTTP_OK, Collections.singletonMap(SystemConstant.UPDATE_TIME, System.currentTimeMillis()), ExceptionResultEnum.SUCCESS.getMessage());
+    }
+}

+ 266 - 0
eds-common/src/main/java/com/qmth/eds/common/util/ServletUtil.java

@@ -0,0 +1,266 @@
+package com.qmth.eds.common.util;
+
+import com.alibaba.fastjson.JSONObject;
+import com.qmth.boot.core.enums.Platform;
+import com.qmth.eds.common.contant.SystemConstant;
+import com.qmth.eds.common.enums.ExceptionResultEnum;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @Description: http工具
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/4/10
+ */
+public class ServletUtil {
+    private final static Logger log = LoggerFactory.getLogger(ServletUtil.class);
+
+    /**
+     * 输出错误
+     *
+     * @param response
+     * @param code
+     * @param message
+     * @throws IOException
+     */
+    public static void responseError(ServletResponse response, int code, String message) throws IOException {
+        HttpServletResponse httpResponse = (HttpServletResponse) response;
+        Result result = ResultUtil.error(code, message);
+        String json = JSONObject.toJSONString(result);
+        httpResponse.getWriter().print(json);
+    }
+
+    /**
+     * 获取请求的token
+     *
+     * @return
+     */
+    public static String getRequestToken() {
+        try {
+            HttpServletRequest request = getRequest();
+            return Objects.isNull(request.getHeader(SystemConstant.TOKEN)) ? request.getParameter(SystemConstant.TOKEN) : request.getHeader(SystemConstant.TOKEN);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            throw ExceptionResultEnum.TOKEN_INVALID.exception();
+        }
+    }
+
+    /**
+     * 获取请求的platform
+     *
+     * @return
+     */
+    public static Platform getRequestPlatform() {
+        try {
+            HttpServletRequest request = getRequest();
+            String value = Objects.isNull(request.getHeader(SystemConstant.HEADER_PLATFORM)) ? request.getParameter(SystemConstant.HEADER_PLATFORM) : request.getHeader(SystemConstant.HEADER_PLATFORM);
+            return Platform.valueOf(value);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            throw ExceptionResultEnum.PLATFORM_INVALID.exception();
+        }
+    }
+
+    /**
+     * 获取请求的deviceId
+     *
+     * @return
+     */
+    public static String getRequestDeviceId() {
+        try {
+            HttpServletRequest request = getRequest();
+            return Objects.isNull(request.getHeader(SystemConstant.HEADER_DEVICE_ID)) ? request.getParameter(SystemConstant.HEADER_DEVICE_ID) : request.getHeader(SystemConstant.HEADER_DEVICE_ID);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            throw ExceptionResultEnum.DEVICE_ID_INVALID.exception();
+        }
+    }
+
+    /**
+     * 获取请求的Authorization
+     *
+     * @return
+     */
+    public static String getRequestAuthorization() {
+        try {
+            HttpServletRequest request = getRequest();
+            return Objects.isNull(request.getHeader(SystemConstant.HEADER_AUTHORIZATION)) ? request.getParameter(SystemConstant.HEADER_AUTHORIZATION) : request.getHeader(SystemConstant.HEADER_AUTHORIZATION);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            throw ExceptionResultEnum.AUTHORIZATION_INVALID.exception();
+        }
+    }
+
+    /**
+     * 获取请求的Authorization
+     *
+     * @return
+     */
+    public static Long getRequestTime() {
+        try {
+            HttpServletRequest request = getRequest();
+            String time = Objects.isNull(request.getHeader(SystemConstant.HEADER_TIME)) ? request.getParameter(SystemConstant.HEADER_TIME) : request.getHeader(SystemConstant.HEADER_TIME);
+            return Objects.nonNull(time) ? Long.parseLong(time) : null;
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            throw ExceptionResultEnum.TIME_INVALID.exception();
+        }
+    }
+
+    /**
+     * 获取请求的Session
+     *
+     * @return
+     */
+    public static Object getRequestSession() {
+        Object object = getRequest().getAttribute(SystemConstant.SESSION);
+        if (Objects.isNull(object)) {
+            throw ExceptionResultEnum.NOT_LOGIN.exception();
+        }
+        return object;
+    }
+
+    /**
+     * 获取请求的用户
+     *
+     * @return
+     */
+    public static Object getRequestUser() {
+        Object object = getRequest().getAttribute(SystemConstant.USER);
+        if (Objects.isNull(object)) {
+            throw ExceptionResultEnum.NOT_LOGIN.exception();
+        }
+        return object;
+    }
+
+    public static Long getRequestUserId() {
+        Object object = getRequest().getHeader("userId");
+        if (Objects.isNull(object)) {
+            throw ExceptionResultEnum.NOT_LOGIN.exception();
+        }
+        return Long.parseLong(object.toString());
+    }
+
+    /**
+     * 获取header中schoolId
+     *
+     * @return
+     */
+    public static Object getRequestHeaderSchoolId() {
+//        BasicSchool basicSchool = (BasicSchool) getRequestSchool();
+//        return basicSchool.getId();
+        Object object = getRequest().getHeader(SystemConstant.SCHOOL_ID);
+        if (Objects.isNull(object)) {
+            throw ExceptionResultEnum.NOT_LOGIN.exception();
+        }
+        return object;
+    }
+
+    /**
+     * 获取header中schoolId
+     *
+     * @return
+     */
+    public static Object getRequestHeaderSchoolIdByNotVaild() {
+        return getRequest().getHeader(SystemConstant.SCHOOL_ID);
+    }
+
+    /**
+     * 获取请求的学校
+     *
+     * @return
+     */
+    public static Object getRequestSchool() {
+        Object object = getRequest().getAttribute(SystemConstant.SCHOOL);
+        if (Objects.isNull(object)) {
+            throw ExceptionResultEnum.NOT_LOGIN.exception();
+        }
+        return object;
+    }
+
+    /**
+     * 获取请求的学校
+     *
+     * @return
+     */
+    public static Object getRequestSchoolByNotVaild() {
+        return getRequest().getAttribute(SystemConstant.SCHOOL);
+    }
+
+    /**
+     * 获取请求的机构
+     *
+     * @return
+     */
+    public static Object getRequestOrg() {
+        Object object = getRequest().getAttribute(SystemConstant.ORG);
+        if (Objects.isNull(object)) {
+            throw ExceptionResultEnum.NOT_LOGIN.exception();
+        }
+        return object;
+    }
+
+    /**
+     * 获取请求的md5
+     *
+     * @return
+     */
+    public static String getRequestMd5() {
+        String md5 = getRequest().getHeader(SystemConstant.MD5.toLowerCase());
+        if (Objects.isNull(md5)) {
+            throw ExceptionResultEnum.MD5_EMPTY.exception();
+        }
+        return md5;
+    }
+
+    /**
+     * 设置id
+     *
+     * @param ids
+     * @return
+     */
+    public static void setRequestId(List<Long> ids) {
+        HttpServletRequest request = getRequest();
+        request.setAttribute(SystemConstant.ID, ids);
+    }
+
+    /**
+     * 获取id
+     *
+     * @return
+     */
+    public static List<Long> getRequestId() {
+        return Objects.nonNull(getRequest().getAttribute(SystemConstant.ID)) ? (List<Long>) getRequest().getAttribute(SystemConstant.ID) : null;
+    }
+
+    /**
+     * 获取HttpServletRequest
+     *
+     * @return
+     */
+    public static HttpServletRequest getRequest() {
+        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        return servletRequestAttributes.getRequest();
+    }
+
+    /**
+     * 获取HttpServletResponse
+     *
+     * @return
+     */
+    public static HttpServletResponse getResponse() {
+        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        return servletRequestAttributes.getResponse();
+    }
+}

+ 31 - 0
eds-common/src/main/java/com/qmth/eds/common/util/SessionUtil.java

@@ -0,0 +1,31 @@
+package com.qmth.eds.common.util;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.Objects;
+import java.util.StringJoiner;
+
+/**
+ * @Description: sessionId util
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/6/28
+ */
+public class SessionUtil {
+
+    /**
+     * 生成sessionId
+     *
+     * @param o
+     * @return
+     */
+    public static String digest(Object... o) throws NoSuchAlgorithmException {
+        StringJoiner stringJoiner = new StringJoiner("");
+        if (Objects.nonNull(o) && o.length > 0) {
+            for (int i = 0; i < o.length; i++) {
+                stringJoiner.add(String.valueOf(o[i])).add("-");
+            }
+        }
+        return MD5Util.encoder(stringJoiner.toString().substring(0, stringJoiner.length() - 1));
+    }
+}

+ 25 - 0
eds-common/src/main/java/com/qmth/eds/common/util/ShaUtils.java

@@ -0,0 +1,25 @@
+package com.qmth.eds.common.util;
+
+import com.qmth.eds.common.contant.SystemConstant;
+
+import java.security.MessageDigest;
+
+public class ShaUtils {
+
+    public static byte[] sha1(String input) {
+        try {
+            return MessageDigest.getInstance("SHA1").digest(input.getBytes(SystemConstant.CHARSET));
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static byte[] sha256(String input) {
+        try {
+            return MessageDigest.getInstance("SHA256").digest(input.getBytes(SystemConstant.CHARSET));
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+}

+ 82 - 0
eds-common/src/main/java/com/qmth/eds/common/util/SmsUtils.java

@@ -0,0 +1,82 @@
+package com.qmth.eds.common.util;
+
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
+import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
+import com.aliyuncs.exceptions.ClientException;
+import com.aliyuncs.http.MethodType;
+import com.aliyuncs.profile.DefaultProfile;
+import com.aliyuncs.profile.IClientProfile;
+import com.qmth.eds.common.config.DictionaryConfig;
+import com.qmth.eds.common.enums.MessageEnum;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 短信发送公共方法
+ */
+@Component
+public class SmsUtils {
+
+    @Resource
+    private DictionaryConfig dictionaryConfig;
+
+    /**
+     * 发送短信
+     *
+     * @param mobileNumber   手机号
+     * @param templateCode   短信模板Code
+     * @param variableParams 参数值
+     */
+    public SendSmsResponse sendSms(String mobileNumber, String templateCode, String variableParams) throws ClientException {
+        System.setProperty("sun.net.client.defaultConnectTimeout", "180000");
+        System.setProperty("sun.net.client.defaultReadTimeout", "18000");
+        // 初始化ascClient需要的几个参数
+        final String product = "Dysmsapi";// 短信API产品名称(短信产品名固定,无需修改)
+        final String domain = "dysmsapi.aliyuncs.com";// 短信API产品域名(接口地址固定,无需修改)
+        // 替换成你的AK
+        final String accessKeyId = dictionaryConfig.smsDomain().getAliyunSMSKey();// 你的accessKeyId,参考本文档步骤2
+        final String accessKeySecret = dictionaryConfig.smsDomain().getAliyunSMSSecret();// 你的accessKeySecret,参考本文档步骤2
+        // 初始化ascClient,暂时不支持多region(请勿修改)
+        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
+        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
+        IAcsClient acsClient = new DefaultAcsClient(profile);
+        // 组装请求对象
+        SendSmsRequest request = new SendSmsRequest();
+        // 使用post提交
+        request.setMethod(MethodType.POST);
+        // 必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为00+国际区号+号码,如“0085200000000”
+        request.setPhoneNumbers(mobileNumber);
+        // 必填:短信签名-可在短信控制台中找到
+        request.setSignName(dictionaryConfig.smsDomain().getAliyunSMSSignName());
+        // 必填:短信模板-可在短信控制台中找到
+        request.setTemplateCode(templateCode);
+        // 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
+        // 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
+        request.setTemplateParam(variableParams);
+        // 可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
+        // request.setSmsUpExtendCode("90997");
+        // 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
+//             request.setOutId("yourOutId");
+        // 请求失败这里会抛ClientException异常
+
+        return acsClient.getAcsResponse(request);
+    }
+
+    public Map<String, String> getCodeAndContentByEnum(MessageEnum messageEnum) {
+        Map<String, String> result = new HashMap<>();
+        String templateContent = null;
+        String templateCode = null;
+        if (messageEnum.equals(MessageEnum.NOTICE_OF_TEACH_DATA_CHANGE)) {
+            templateCode = dictionaryConfig.smsDomain().getTeachDataChangeNoticeCode();
+            templateContent = messageEnum.getTemplate();
+        }
+        result.put("templateContent", templateContent);
+        result.put("templateCode", templateCode);
+        return result;
+    }
+}

+ 221 - 0
eds-common/src/main/java/com/qmth/eds/common/util/excel/BasicExcelListener.java

@@ -0,0 +1,221 @@
+package com.qmth.eds.common.util.excel;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.alibaba.excel.metadata.CellExtra;
+import com.alibaba.fastjson.JSONObject;
+import org.hibernate.validator.constraints.Length;
+import org.hibernate.validator.constraints.Range;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.LinkedMultiValueMap;
+
+import javax.validation.constraints.*;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @Description: easyexcel监听
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/5/14
+ */
+public abstract class BasicExcelListener<T> extends AnalysisEventListener<T> {
+    private final static Logger log = LoggerFactory.getLogger(BasicExcelListener.class);
+
+    /**
+     * 批处理阈值2000
+     */
+    private static int BATCH_COUNT = 2000;
+    public static final String SUCCESS = "success";
+    public static final String ERROR = "error";
+    private LinkedMultiValueMap<String, T> list;
+
+    public BasicExcelListener() {
+        this.list = new LinkedMultiValueMap<>(BATCH_COUNT);
+    }
+
+    public BasicExcelListener(int batchCount) {
+        BATCH_COUNT = batchCount;
+        this.list = new LinkedMultiValueMap<>(BATCH_COUNT);
+    }
+
+    public abstract void handle(LinkedMultiValueMap<String, T> dataList);
+
+    @Override
+    public void invoke(T o, AnalysisContext analysisContext) {
+//        if (validData(o, analysisContext) || (analysisContext.readRowHolder().getRowIndex() == 2001 || analysisContext.readRowHolder().getRowIndex() == 7001)) {
+        if (validData(o, analysisContext)) {
+            list.add(ERROR, o);
+        } else {
+            list.add(SUCCESS, o);
+        }
+        if (list.size() >= BATCH_COUNT) {
+            handle(list);
+            list.clear();
+        }
+    }
+
+//    @Override
+//    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
+//        log.info("表头:{}", JSONObject.toJSONString(headMap));
+//    }
+
+    @Override
+    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
+        log.info("表头:{}", JSONObject.toJSONString(headMap));
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        log.info("所有数据解析完成!");
+        handle(list);
+    }
+
+    @Override
+    public void onException(Exception exception, AnalysisContext context) {
+        log.info("onException is come in!");
+    }
+
+    @Override
+    public void extra(CellExtra extra, AnalysisContext context) {
+        log.info("extra is come in!");
+    }
+
+    private void extendBasicExcelField(T o, AnalysisContext analysisContext, List<String> errorMessage) {
+        try {
+            Field rowField = o.getClass().getField("row");
+            rowField.setAccessible(true);
+            rowField.set(o, analysisContext.readRowHolder().getRowIndex());
+
+            Field sheetField = o.getClass().getField("sheet");
+            sheetField.setAccessible(true);
+            sheetField.set(o, analysisContext.readSheetHolder().getSheetNo() + 1);
+
+            Field errorMessageMapField = o.getClass().getField("errorMessage");
+            errorMessageMapField.setAccessible(true);
+            errorMessageMapField.set(o, errorMessage);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            log.error("请求出错:", e);
+        }
+    }
+
+    private boolean validData(T o, AnalysisContext analysisContext) {
+        List<String> errorMessage = new ArrayList<>();
+        Field[] fields = o.getClass().getDeclaredFields();
+        Object object = null;
+        for (int i = 0; i < fields.length; i++) {
+            fields[i].setAccessible(true);
+            try {
+                object = fields[i].get(o);
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+            ExcelProperty excelProperty = fields[i].getDeclaredAnnotation(ExcelProperty.class);
+            if (Objects.isNull(excelProperty)) {
+                continue;
+            }
+            Annotation[] annotations = fields[i].getDeclaredAnnotations();
+            NotBlank notBlank = null;
+            Length length = null;
+            Min min = null;
+            Max max = null;
+            DecimalMin decimalMin = null;
+            DecimalMax decimalMax = null;
+            NotNull notNull = null;
+            Null isnull = null;
+            NotEmpty notEmpty = null;
+            Size size = null;
+            Range range = null;
+            AssertTrue assertTrue = null;
+            AssertFalse assertFalse = null;
+            for (Annotation annotation : annotations) {
+                if (annotation instanceof NotBlank) {
+                    notBlank = (NotBlank) annotation;
+                    if (Objects.isNull(object) || Objects.equals(object, " ")) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + notBlank.message());
+                    }
+                } else if (annotation instanceof Length) {
+                    length = (Length) annotation;
+                    if (Objects.nonNull(object) && (object.toString().length() < length.min() || object.toString().length() > length.max())) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + length.message());
+                    }
+                } else if (annotation instanceof Min) {
+                    min = (Min) annotation;
+                    if (Objects.nonNull(object) && Long.parseLong(object.toString()) < min.value()) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + min.message());
+                    }
+                } else if (annotation instanceof Max) {
+                    max = (Max) annotation;
+                    if (Objects.nonNull(object) && Long.parseLong(object.toString()) > max.value()) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + max.message());
+                    }
+                } else if (annotation instanceof DecimalMin) {
+                    decimalMin = (DecimalMin) annotation;
+                    if (Objects.nonNull(object) && new BigDecimal(object.toString()).compareTo(new BigDecimal(decimalMin.value())) == -1) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + decimalMin.message());
+                    }
+                } else if (annotation instanceof DecimalMax) {
+                    decimalMax = (DecimalMax) annotation;
+                    if (Objects.nonNull(object) && new BigDecimal(object.toString()).compareTo(new BigDecimal(decimalMax.value())) == 1) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + decimalMax.message());
+                    }
+                } else if (annotation instanceof NotNull) {
+                    notNull = (NotNull) annotation;
+                    if (Objects.isNull(object)) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + notNull.message());
+                    }
+                } else if (annotation instanceof Null) {
+                    isnull = (Null) annotation;
+                    if (Objects.nonNull(object)) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + isnull.message());
+                    }
+                } else if (annotation instanceof NotEmpty) {
+                    notEmpty = (NotEmpty) annotation;
+                    if (Objects.isNull(object)) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + notEmpty.message());
+                    }
+                } else if (annotation instanceof Size) {
+                    size = (Size) annotation;
+                    if (Objects.nonNull(object) && (object.toString().length() < size.min() || object.toString().length() > size.max())) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + size.message());
+                    }
+                } else if (annotation instanceof Range) {
+                    range = (Range) annotation;
+                    if (Objects.nonNull(object) && (Long.parseLong(object.toString()) < range.min() || Long.parseLong(object.toString()) > range.max())) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + range.message());
+                    }
+                } else if (annotation instanceof AssertTrue) {
+                    assertTrue = (AssertTrue) annotation;
+                    if (Objects.nonNull(object) && Boolean.valueOf(object.toString())) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + assertTrue.message());
+                    }
+                } else if (annotation instanceof AssertFalse) {
+                    assertFalse = (AssertFalse) annotation;
+                    if (Objects.nonNull(object) && !Boolean.valueOf(object.toString())) {
+                        errorMessage.add("列名[" + excelProperty.value()[0] + "]:" + assertFalse.message());
+                    }
+                }
+            }
+            if (errorMessage.size() > 0) {
+                extendBasicExcelField(o, analysisContext, errorMessage);
+            }
+        }
+        return errorMessage.size() > 0 ? true : false;
+    }
+
+    //可重写的方法:
+//	void invoke(T data, AnalysisContext context); //处理一行数据
+//	void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) //处理表头的一行数据
+//	void extra(CellExtra extra, AnalysisContext context); //获取单元格的额外信息
+//	void doAfterAllAnalysed(AnalysisContext context) //全部读取结束后的操作
+//	boolean hasNext(AnalysisContext context); //是否读取下一行
+//	void onException(Exception exception, AnalysisContext context) //发生异常时调用
+}

+ 53 - 0
eds-common/src/main/java/com/qmth/eds/common/util/excel/BasicExcelRow.java

@@ -0,0 +1,53 @@
+package com.qmth.eds.common.util.excel;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Description: easyexcel基础列
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/5/14
+ */
+public class BasicExcelRow implements Serializable {
+
+    @ApiModelProperty(value = "sheet页")
+    @ExcelIgnore
+    public Integer sheet;
+
+    @ApiModelProperty(value = "行号")
+    @ExcelIgnore
+    public Integer row;
+
+    @ApiModelProperty(value = "列名和错误原因")
+    @ExcelIgnore
+    public List<String> errorMessage;
+
+    public Integer getSheet() {
+        return sheet;
+    }
+
+    public void setSheet(Integer sheet) {
+        this.sheet = sheet;
+    }
+
+    public Integer getRow() {
+        return row;
+    }
+
+    public void setRow(Integer row) {
+        this.row = row;
+    }
+
+    public List<String> getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(List<String> errorMessage) {
+        this.errorMessage = errorMessage;
+    }
+}

+ 13 - 0
eds-common/src/test/java/com/qmth/eds/whu/common/EdsCommonApplicationTests.java

@@ -0,0 +1,13 @@
+package com.qmth.eds.whu.common;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class EdsCommonApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}

+ 33 - 0
eds-whu/.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 62 - 0
eds-whu/pom.xml

@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.qmth.eds.whu</groupId>
+    <artifactId>eds-whu</artifactId>
+    <version>1.0.3</version>
+    <packaging>jar</packaging>
+
+    <parent>
+        <groupId>com.qmth.eds</groupId>
+        <artifactId>eds-service</artifactId>
+        <version>1.0.3</version>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.qmth.eds.common</groupId>
+            <artifactId>eds-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <version>${spring-boot.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.6.2</version>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <version>1.4.12</version>
+                <configuration>
+                    <repository>registry.cn-shenzhen.aliyuncs.com/teachcloud_task</repository>
+                    <tag>${project.version}</tag>
+                    <contextDirectory>${project.baseDir}</contextDirectory>
+                    <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
+                    <pullNewerImage>true</pullNewerImage>
+                    <buildArgs>
+                        <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
+                    </buildArgs>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 13 - 0
eds-whu/src/test/java/com/qmth/eds/whu/whu/EdsWhuApplicationTests.java

@@ -0,0 +1,13 @@
+package com.qmth.eds.whu.whu;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class EdsWhuApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}