xiatian 6 months ago
parent
commit
d736ea80fa
100 changed files with 5530 additions and 5348 deletions
  1. 21 15
      src/main/java/cn/com/qmth/mps/bean/CourseInfo.java
  2. 21 15
      src/main/java/cn/com/qmth/mps/bean/ImportMsg.java
  3. 34 26
      src/main/java/cn/com/qmth/mps/bean/PaperDetail.java
  4. 45 33
      src/main/java/cn/com/qmth/mps/bean/PaperDetailUnit.java
  5. 48 48
      src/main/java/cn/com/qmth/mps/bean/PaperGroup.java
  6. 24 24
      src/main/java/cn/com/qmth/mps/bean/PaperGroupUnit.java
  7. 9 9
      src/main/java/cn/com/qmth/mps/bean/TreeNode.java
  8. 74 72
      src/main/java/cn/com/qmth/mps/bean/User.java
  9. 41 29
      src/main/java/cn/com/qmth/mps/bean/WxappAccessToken.java
  10. 19 19
      src/main/java/cn/com/qmth/mps/config/FillMetaObjectHandler.java
  11. 0 1
      src/main/java/cn/com/qmth/mps/config/MyBatisPlusConfig.java
  12. 0 1
      src/main/java/cn/com/qmth/mps/config/ScanWebMvcConfigurer.java
  13. 4 11
      src/main/java/cn/com/qmth/mps/config/SwaggerConfig.java
  14. 27 27
      src/main/java/cn/com/qmth/mps/config/SysProperty.java
  15. 35 33
      src/main/java/cn/com/qmth/mps/controller/AuthController.java
  16. 1 2
      src/main/java/cn/com/qmth/mps/controller/BaseController.java
  17. 11 10
      src/main/java/cn/com/qmth/mps/controller/ExamController.java
  18. 165 165
      src/main/java/cn/com/qmth/mps/controller/PaperController.java
  19. 11 10
      src/main/java/cn/com/qmth/mps/controller/SchoolController.java
  20. 56 55
      src/main/java/cn/com/qmth/mps/controller/UserController.java
  21. 2 2
      src/main/java/cn/com/qmth/mps/dao/ExamDao.java
  22. 5 4
      src/main/java/cn/com/qmth/mps/dao/PaperDao.java
  23. 0 1
      src/main/java/cn/com/qmth/mps/dao/PaperDetailDao.java
  24. 1 1
      src/main/java/cn/com/qmth/mps/dao/PaperGroupDao.java
  25. 1 1
      src/main/java/cn/com/qmth/mps/dao/SchoolDao.java
  26. 2 2
      src/main/java/cn/com/qmth/mps/dao/UserCourseRelationDao.java
  27. 1 1
      src/main/java/cn/com/qmth/mps/dao/UserDao.java
  28. 24 23
      src/main/java/cn/com/qmth/mps/entity/CourseEntity.java
  29. 44 33
      src/main/java/cn/com/qmth/mps/entity/ExamEntity.java
  30. 37 27
      src/main/java/cn/com/qmth/mps/entity/PaperDetailEntity.java
  31. 75 67
      src/main/java/cn/com/qmth/mps/entity/PaperDetailUnitEntity.java
  32. 76 76
      src/main/java/cn/com/qmth/mps/entity/PaperEntity.java
  33. 50 50
      src/main/java/cn/com/qmth/mps/entity/PaperGroupEntity.java
  34. 40 40
      src/main/java/cn/com/qmth/mps/entity/PaperGroupUnitEntity.java
  35. 195 197
      src/main/java/cn/com/qmth/mps/entity/PrivilegeEntity.java
  36. 40 44
      src/main/java/cn/com/qmth/mps/entity/RoleEntity.java
  37. 27 25
      src/main/java/cn/com/qmth/mps/entity/RolePrivilegeRelationEntity.java
  38. 64 60
      src/main/java/cn/com/qmth/mps/entity/SchoolEntity.java
  39. 17 18
      src/main/java/cn/com/qmth/mps/entity/UserCourseRelationEntity.java
  40. 49 45
      src/main/java/cn/com/qmth/mps/entity/UserEntity.java
  41. 27 20
      src/main/java/cn/com/qmth/mps/entity/WxappAccessTokenEntity.java
  42. 22 19
      src/main/java/cn/com/qmth/mps/entity/WxappInfoEntity.java
  43. 0 1
      src/main/java/cn/com/qmth/mps/entity/base/AuditingEntity.java
  44. 0 1
      src/main/java/cn/com/qmth/mps/entity/base/AuditingWithoutIdEntity.java
  45. 0 2
      src/main/java/cn/com/qmth/mps/entity/base/IdEntity.java
  46. 1 0
      src/main/java/cn/com/qmth/mps/enums/ArbitrateMethod.java
  47. 1 1
      src/main/java/cn/com/qmth/mps/enums/ExamStatus.java
  48. 13 11
      src/main/java/cn/com/qmth/mps/enums/Role.java
  49. 44 0
      src/main/java/cn/com/qmth/mps/exception/DisruptedException.java
  50. 73 73
      src/main/java/cn/com/qmth/mps/interceptor/FirstInterceptor.java
  51. 6 4
      src/main/java/cn/com/qmth/mps/job/ClearTimeOutUserJob.java
  52. 6 4
      src/main/java/cn/com/qmth/mps/job/WxappAccessTokenJob.java
  53. 7 7
      src/main/java/cn/com/qmth/mps/service/AuthService.java
  54. 3 4
      src/main/java/cn/com/qmth/mps/service/CourseService.java
  55. 7 7
      src/main/java/cn/com/qmth/mps/service/ExamService.java
  56. 6 7
      src/main/java/cn/com/qmth/mps/service/PaperDetailService.java
  57. 5 6
      src/main/java/cn/com/qmth/mps/service/PaperDetailUnitService.java
  58. 9 9
      src/main/java/cn/com/qmth/mps/service/PaperGroupService.java
  59. 7 7
      src/main/java/cn/com/qmth/mps/service/PaperGroupUnitService.java
  60. 9 9
      src/main/java/cn/com/qmth/mps/service/PaperService.java
  61. 6 6
      src/main/java/cn/com/qmth/mps/service/SchoolService.java
  62. 6 6
      src/main/java/cn/com/qmth/mps/service/SessionService.java
  63. 5 5
      src/main/java/cn/com/qmth/mps/service/UserCourseRelationService.java
  64. 10 11
      src/main/java/cn/com/qmth/mps/service/UserService.java
  65. 3 3
      src/main/java/cn/com/qmth/mps/service/WxappAccessTokenService.java
  66. 2 3
      src/main/java/cn/com/qmth/mps/service/WxappInfoService.java
  67. 287 279
      src/main/java/cn/com/qmth/mps/service/impl/AuthServiceImpl.java
  68. 17 17
      src/main/java/cn/com/qmth/mps/service/impl/CourseServiceImpl.java
  69. 143 142
      src/main/java/cn/com/qmth/mps/service/impl/ExamServiceImpl.java
  70. 291 286
      src/main/java/cn/com/qmth/mps/service/impl/PaperDetailServiceImpl.java
  71. 61 61
      src/main/java/cn/com/qmth/mps/service/impl/PaperDetailUnitServiceImpl.java
  72. 380 370
      src/main/java/cn/com/qmth/mps/service/impl/PaperGroupServiceImpl.java
  73. 72 71
      src/main/java/cn/com/qmth/mps/service/impl/PaperGroupUnitServiceImpl.java
  74. 741 735
      src/main/java/cn/com/qmth/mps/service/impl/PaperServiceImpl.java
  75. 133 130
      src/main/java/cn/com/qmth/mps/service/impl/SchoolServiceImpl.java
  76. 42 41
      src/main/java/cn/com/qmth/mps/service/impl/SessionServiceImpl.java
  77. 38 38
      src/main/java/cn/com/qmth/mps/service/impl/UserCourseRelationServiceImpl.java
  78. 333 330
      src/main/java/cn/com/qmth/mps/service/impl/UserServiceImpl.java
  79. 27 26
      src/main/java/cn/com/qmth/mps/service/impl/WxappAccessTokenServiceImpl.java
  80. 4 5
      src/main/java/cn/com/qmth/mps/service/impl/WxappInfoServiceImpl.java
  81. 105 105
      src/main/java/cn/com/qmth/mps/support/ApiInfo.java
  82. 110 116
      src/main/java/cn/com/qmth/mps/support/ApiInfoHolder.java
  83. 13 13
      src/main/java/cn/com/qmth/mps/support/BaseResponse.java
  84. 2 2
      src/main/java/cn/com/qmth/mps/support/ExchangeBean.java
  85. 26 26
      src/main/java/cn/com/qmth/mps/support/HttpMethodProcessor.java
  86. 9 9
      src/main/java/cn/com/qmth/mps/support/HttpMethodProcessorImpl.java
  87. 25 25
      src/main/java/cn/com/qmth/mps/support/LogProperties.java
  88. 44 44
      src/main/java/cn/com/qmth/mps/support/SpringContextHolder.java
  89. 43 43
      src/main/java/cn/com/qmth/mps/support/StatusResponse.java
  90. 1 1
      src/main/java/cn/com/qmth/mps/support/WithoutStackTrace.java
  91. 8 9
      src/main/java/cn/com/qmth/mps/util/AuthorizationCreateUtil.java
  92. 51 41
      src/main/java/cn/com/qmth/mps/util/BatchGetDataUtil.java
  93. 24 21
      src/main/java/cn/com/qmth/mps/util/BatchSetDataUtil.java
  94. 103 102
      src/main/java/cn/com/qmth/mps/util/ByteUtil.java
  95. 56 49
      src/main/java/cn/com/qmth/mps/util/Calculator.java
  96. 195 196
      src/main/java/cn/com/qmth/mps/util/DateUtil.java
  97. 70 70
      src/main/java/cn/com/qmth/mps/util/FileUtil.java
  98. 378 372
      src/main/java/cn/com/qmth/mps/util/HttpUtil.java
  99. 7 5
      src/main/java/cn/com/qmth/mps/util/IpUtil.java
  100. 17 20
      src/main/java/cn/com/qmth/mps/util/JsonMapper.java

+ 21 - 15
src/main/java/cn/com/qmth/mps/bean/CourseInfo.java

@@ -1,19 +1,25 @@
 package cn.com.qmth.mps.bean;
 
 public class CourseInfo {
-	private String code;
-	private String name;
-	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;
-	}
-	
+
+    private String code;
+
+    private String name;
+
+    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;
+    }
+
 }

+ 21 - 15
src/main/java/cn/com/qmth/mps/bean/ImportMsg.java

@@ -3,19 +3,25 @@ package cn.com.qmth.mps.bean;
 import java.util.List;
 
 public class ImportMsg {
-	private Boolean hasError;
-	private List<String> errMsg;
-	public Boolean getHasError() {
-		return hasError;
-	}
-	public void setHasError(Boolean hasError) {
-		this.hasError = hasError;
-	}
-	public List<String> getErrMsg() {
-		return errMsg;
-	}
-	public void setErrMsg(List<String> errMsg) {
-		this.errMsg = errMsg;
-	}
-	
+
+    private Boolean hasError;
+
+    private List<String> errMsg;
+
+    public Boolean getHasError() {
+        return hasError;
+    }
+
+    public void setHasError(Boolean hasError) {
+        this.hasError = hasError;
+    }
+
+    public List<String> getErrMsg() {
+        return errMsg;
+    }
+
+    public void setErrMsg(List<String> errMsg) {
+        this.errMsg = errMsg;
+    }
+
 }

+ 34 - 26
src/main/java/cn/com/qmth/mps/bean/PaperDetail.java

@@ -5,30 +5,38 @@ import java.util.List;
 import io.swagger.annotations.ApiModelProperty;
 
 public class PaperDetail {
-	@ApiModelProperty("大题名称")
-	private String name;
-	@ApiModelProperty("大题号")
-	private Integer number;
-	@ApiModelProperty("小题信息")
-	private List<PaperDetailUnit> units;
-	public String getName() {
-		return name;
-	}
-	public void setName(String name) {
-		this.name = name;
-	}
-	public Integer getNumber() {
-		return number;
-	}
-	public void setNumber(Integer number) {
-		this.number = number;
-	}
-	public List<PaperDetailUnit> getUnits() {
-		return units;
-	}
-	public void setUnits(List<PaperDetailUnit> units) {
-		this.units = units;
-	}
-	
-	
+
+    @ApiModelProperty("大题名称")
+    private String name;
+
+    @ApiModelProperty("大题号")
+    private Integer number;
+
+    @ApiModelProperty("小题信息")
+    private List<PaperDetailUnit> units;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public List<PaperDetailUnit> getUnits() {
+        return units;
+    }
+
+    public void setUnits(List<PaperDetailUnit> units) {
+        this.units = units;
+    }
+
 }

+ 45 - 33
src/main/java/cn/com/qmth/mps/bean/PaperDetailUnit.java

@@ -3,37 +3,49 @@ package cn.com.qmth.mps.bean;
 import io.swagger.annotations.ApiModelProperty;
 
 public class PaperDetailUnit {
-	@ApiModelProperty("小题号")
-	private Integer number;
-	@ApiModelProperty("小题满分")
-	private Double score;
-	@ApiModelProperty("给分间隔")
-	private Double scoreStep;
-	@ApiModelProperty("是否在分组")
-	private Boolean inGroup;
-	public Integer getNumber() {
-		return number;
-	}
-	public void setNumber(Integer number) {
-		this.number = number;
-	}
-	public Double getScore() {
-		return score;
-	}
-	public void setScore(Double score) {
-		this.score = score;
-	}
-	public Double getScoreStep() {
-		return scoreStep;
-	}
-	public void setScoreStep(Double scoreStep) {
-		this.scoreStep = scoreStep;
-	}
-	public Boolean getInGroup() {
-		return inGroup;
-	}
-	public void setInGroup(Boolean inGroup) {
-		this.inGroup = inGroup;
-	}
-	
+
+    @ApiModelProperty("小题号")
+    private Integer number;
+
+    @ApiModelProperty("小题满分")
+    private Double score;
+
+    @ApiModelProperty("给分间隔")
+    private Double scoreStep;
+
+    @ApiModelProperty("是否在分组")
+    private Boolean inGroup;
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public Double getScore() {
+        return score;
+    }
+
+    public void setScore(Double score) {
+        this.score = score;
+    }
+
+    public Double getScoreStep() {
+        return scoreStep;
+    }
+
+    public void setScoreStep(Double scoreStep) {
+        this.scoreStep = scoreStep;
+    }
+
+    public Boolean getInGroup() {
+        return inGroup;
+    }
+
+    public void setInGroup(Boolean inGroup) {
+        this.inGroup = inGroup;
+    }
+
 }

+ 48 - 48
src/main/java/cn/com/qmth/mps/bean/PaperGroup.java

@@ -7,69 +7,69 @@ import java.util.List;
 
 public class PaperGroup {
 
-	@ApiModelProperty("分组序号")
-	private Integer number;
+    @ApiModelProperty("分组序号")
+    private Integer number;
 
-	@ApiModelProperty(value = "是否开启双评")
-	private Boolean doubleEnable;
+    @ApiModelProperty(value = "是否开启双评")
+    private Boolean doubleEnable;
 
-	@ApiModelProperty(value = "双评比例")
-	private Double doubleRate;
+    @ApiModelProperty(value = "双评比例")
+    private Double doubleRate;
 
-	@ApiModelProperty(value = "仲裁阈值")
-	private Double arbitrateThreshold;
+    @ApiModelProperty(value = "仲裁阈值")
+    private Double arbitrateThreshold;
 
-	@ApiModelProperty(value = "仲裁方式")
-	private ArbitrateMethod arbitrateMethod;
+    @ApiModelProperty(value = "仲裁方式")
+    private ArbitrateMethod arbitrateMethod;
 
-	@ApiModelProperty("分组信息")
-	private List<PaperGroupUnit> groupUnits;
+    @ApiModelProperty("分组信息")
+    private List<PaperGroupUnit> groupUnits;
 
-	public Integer getNumber() {
-		return number;
-	}
+    public Integer getNumber() {
+        return number;
+    }
 
-	public void setNumber(Integer number) {
-		this.number = number;
-	}
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
 
-	public Boolean getDoubleEnable() {
-		return doubleEnable;
-	}
+    public Boolean getDoubleEnable() {
+        return doubleEnable;
+    }
 
-	public void setDoubleEnable(Boolean doubleEnable) {
-		this.doubleEnable = doubleEnable;
-	}
+    public void setDoubleEnable(Boolean doubleEnable) {
+        this.doubleEnable = doubleEnable;
+    }
 
-	public Double getDoubleRate() {
-		return doubleRate;
-	}
+    public Double getDoubleRate() {
+        return doubleRate;
+    }
 
-	public void setDoubleRate(Double doubleRate) {
-		this.doubleRate = doubleRate;
-	}
+    public void setDoubleRate(Double doubleRate) {
+        this.doubleRate = doubleRate;
+    }
 
-	public Double getArbitrateThreshold() {
-		return arbitrateThreshold;
-	}
+    public Double getArbitrateThreshold() {
+        return arbitrateThreshold;
+    }
 
-	public void setArbitrateThreshold(Double arbitrateThreshold) {
-		this.arbitrateThreshold = arbitrateThreshold;
-	}
+    public void setArbitrateThreshold(Double arbitrateThreshold) {
+        this.arbitrateThreshold = arbitrateThreshold;
+    }
 
-	public ArbitrateMethod getArbitrateMethod() {
-		return arbitrateMethod;
-	}
+    public ArbitrateMethod getArbitrateMethod() {
+        return arbitrateMethod;
+    }
 
-	public void setArbitrateMethod(ArbitrateMethod arbitrateMethod) {
-		this.arbitrateMethod = arbitrateMethod;
-	}
+    public void setArbitrateMethod(ArbitrateMethod arbitrateMethod) {
+        this.arbitrateMethod = arbitrateMethod;
+    }
 
-	public List<PaperGroupUnit> getGroupUnits() {
-		return groupUnits;
-	}
+    public List<PaperGroupUnit> getGroupUnits() {
+        return groupUnits;
+    }
 
-	public void setGroupUnits(List<PaperGroupUnit> groupUnits) {
-		this.groupUnits = groupUnits;
-	}
+    public void setGroupUnits(List<PaperGroupUnit> groupUnits) {
+        this.groupUnits = groupUnits;
+    }
 }

+ 24 - 24
src/main/java/cn/com/qmth/mps/bean/PaperGroupUnit.java

@@ -4,36 +4,36 @@ import io.swagger.annotations.ApiModelProperty;
 
 public class PaperGroupUnit {
 
-	@ApiModelProperty("大题号")
-	private Integer detailNumber;
+    @ApiModelProperty("大题号")
+    private Integer detailNumber;
 
-	@ApiModelProperty("小题号")
-	private Integer detailUnitNumber;
+    @ApiModelProperty("小题号")
+    private Integer detailUnitNumber;
 
-	@ApiModelProperty(value = "仲裁阈值")
-	private Double arbitrateThreshold;
+    @ApiModelProperty(value = "仲裁阈值")
+    private Double arbitrateThreshold;
 
-	public Integer getDetailNumber() {
-		return detailNumber;
-	}
+    public Integer getDetailNumber() {
+        return detailNumber;
+    }
 
-	public void setDetailNumber(Integer detailNumber) {
-		this.detailNumber = detailNumber;
-	}
+    public void setDetailNumber(Integer detailNumber) {
+        this.detailNumber = detailNumber;
+    }
 
-	public Integer getDetailUnitNumber() {
-		return detailUnitNumber;
-	}
+    public Integer getDetailUnitNumber() {
+        return detailUnitNumber;
+    }
 
-	public void setDetailUnitNumber(Integer detailUnitNumber) {
-		this.detailUnitNumber = detailUnitNumber;
-	}
+    public void setDetailUnitNumber(Integer detailUnitNumber) {
+        this.detailUnitNumber = detailUnitNumber;
+    }
 
-	public Double getArbitrateThreshold() {
-		return arbitrateThreshold;
-	}
+    public Double getArbitrateThreshold() {
+        return arbitrateThreshold;
+    }
 
-	public void setArbitrateThreshold(Double arbitrateThreshold) {
-		this.arbitrateThreshold = arbitrateThreshold;
-	}
+    public void setArbitrateThreshold(Double arbitrateThreshold) {
+        this.arbitrateThreshold = arbitrateThreshold;
+    }
 }

+ 9 - 9
src/main/java/cn/com/qmth/mps/bean/TreeNode.java

@@ -3,25 +3,25 @@ package cn.com.qmth.mps.bean;
 /**
  * 树节点接口
  *
- * @author 
+ * @author
  * @date 201827
  */
 public interface TreeNode {
 
-	String getNodeId();
+    String getNodeId();
 
-	void setNodeId(String nodeId);
+    void setNodeId(String nodeId);
 
-	String getNodeName();
+    String getNodeName();
 
-	void setNodeName(String nodeName);
+    void setNodeName(String nodeName);
 
-	String getNodeCode();
+    String getNodeCode();
 
-	void setNodeCode(String nodeCode);
+    void setNodeCode(String nodeCode);
 
-	String getParentNodeId();
+    String getParentNodeId();
 
-	void setParentNodeId(String parentNodeId);
+    void setParentNodeId(String parentNodeId);
 
 }

+ 74 - 72
src/main/java/cn/com/qmth/mps/bean/User.java

@@ -6,102 +6,104 @@ import cn.com.qmth.mps.enums.Role;
 
 public class User implements AccessEntity {
 
-	private Long id;
+    private Long id;
 
-	private String name;
-	private String loginName;
-	private String sessionId;
+    private String name;
 
-	private String accessToken;
+    private String loginName;
 
-	private Role role;
+    private String sessionId;
 
-	private Long activeTime;
+    private String accessToken;
 
-	private Long schoolId;
+    private Role role;
 
-	public String buildKey() {
-		this.sessionId = new StringBuilder().append(role.name()).append("_").append(id).toString();
-		return this.sessionId;
-	}
+    private Long activeTime;
 
-	public String getName() {
-		return name;
-	}
+    private Long schoolId;
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public String buildKey() {
+        this.sessionId = new StringBuilder().append(role.name()).append("_").append(id).toString();
+        return this.sessionId;
+    }
 
-	public String getSessionId() {
-		return sessionId;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public void setSessionId(String sessionId) {
-		this.sessionId = sessionId;
-	}
+    public void setName(String name) {
+        this.name = name;
+    }
 
-	public String getAccessToken() {
-		return accessToken;
-	}
+    public String getSessionId() {
+        return sessionId;
+    }
 
-	public void setAccessToken(String accessToken) {
-		this.accessToken = accessToken;
-	}
+    public void setSessionId(String sessionId) {
+        this.sessionId = sessionId;
+    }
 
-	public Role getRole() {
-		return role;
-	}
+    public String getAccessToken() {
+        return accessToken;
+    }
 
-	public void setRole(Role role) {
-		this.role = role;
-	}
+    public void setAccessToken(String accessToken) {
+        this.accessToken = accessToken;
+    }
 
-	public Long getActiveTime() {
-		return activeTime;
-	}
+    public Role getRole() {
+        return role;
+    }
 
-	public void setActiveTime(Long activeTime) {
-		this.activeTime = activeTime;
-	}
+    public void setRole(Role role) {
+        this.role = role;
+    }
 
-	public Long getId() {
-		return id;
-	}
+    public Long getActiveTime() {
+        return activeTime;
+    }
 
-	public void setId(Long id) {
-		this.id = id;
-	}
+    public void setActiveTime(Long activeTime) {
+        this.activeTime = activeTime;
+    }
 
-	public Long getSchoolId() {
-		return schoolId;
-	}
+    public Long getId() {
+        return id;
+    }
 
-	public void setSchoolId(Long schoolId) {
-		this.schoolId = schoolId;
-	}
+    public void setId(Long id) {
+        this.id = id;
+    }
 
-	@Override
-	public String getIdentity() {
-		return sessionId;
-	}
+    public Long getSchoolId() {
+        return schoolId;
+    }
 
-	@Override
-	public String getSecret() {
-		return accessToken;
-	}
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
 
-	public String getLoginName() {
-		return loginName;
-	}
+    @Override
+    public String getIdentity() {
+        return sessionId;
+    }
 
-	public void setLoginName(String loginName) {
-		this.loginName = loginName;
-	}
+    @Override
+    public String getSecret() {
+        return accessToken;
+    }
 
-	@Override
-	public String getLogName() {
-		return role + " | " + loginName + " | uid_" + id + " | sid_" + schoolId;
-	}
+    public String getLoginName() {
+        return loginName;
+    }
+
+    public void setLoginName(String loginName) {
+        this.loginName = loginName;
+    }
+
+    @Override
+    public String getLogName() {
+        return role + " | " + loginName + " | uid_" + id + " | sid_" + schoolId;
+    }
 
 }

+ 41 - 29
src/main/java/cn/com/qmth/mps/bean/WxappAccessToken.java

@@ -1,33 +1,45 @@
 package cn.com.qmth.mps.bean;
 
 public class WxappAccessToken {
-	private String access_token;
-	private Integer expires_in;
-	private Integer errcode;
-	private String errmsg;
-	public String getAccess_token() {
-		return access_token;
-	}
-	public void setAccess_token(String access_token) {
-		this.access_token = access_token;
-	}
-	public Integer getExpires_in() {
-		return expires_in;
-	}
-	public void setExpires_in(Integer expires_in) {
-		this.expires_in = expires_in;
-	}
-	public Integer getErrcode() {
-		return errcode;
-	}
-	public void setErrcode(Integer errcode) {
-		this.errcode = errcode;
-	}
-	public String getErrmsg() {
-		return errmsg;
-	}
-	public void setErrmsg(String errmsg) {
-		this.errmsg = errmsg;
-	}
-	
+
+    private String access_token;
+
+    private Integer expires_in;
+
+    private Integer errcode;
+
+    private String errmsg;
+
+    public String getAccess_token() {
+        return access_token;
+    }
+
+    public void setAccess_token(String access_token) {
+        this.access_token = access_token;
+    }
+
+    public Integer getExpires_in() {
+        return expires_in;
+    }
+
+    public void setExpires_in(Integer expires_in) {
+        this.expires_in = expires_in;
+    }
+
+    public Integer getErrcode() {
+        return errcode;
+    }
+
+    public void setErrcode(Integer errcode) {
+        this.errcode = errcode;
+    }
+
+    public String getErrmsg() {
+        return errmsg;
+    }
+
+    public void setErrmsg(String errmsg) {
+        this.errmsg = errmsg;
+    }
+
 }

+ 19 - 19
src/main/java/cn/com/qmth/mps/config/FillMetaObjectHandler.java

@@ -11,24 +11,24 @@ import cn.com.qmth.mps.util.ServletUtil;
 
 public class FillMetaObjectHandler implements MetaObjectHandler {
 
-	@Override
-	public void insertFill(MetaObject metaObject) {
-		User user = ServletUtil.getSessionUser();
-		if (user != null) {
-			this.setFieldValByName("creatorId", user.getId(), metaObject);
-		}
-		if(this.getFieldValByName("createTime", metaObject)==null) {
-			this.setFieldValByName("createTime", new Date(), metaObject);
-		}
-	}
-
-	@Override
-	public void updateFill(MetaObject metaObject) {
-		User user = ServletUtil.getSessionUser();
-		if (user != null) {
-			this.setFieldValByName("updaterId", user.getId(), metaObject);
-		}
-		this.setFieldValByName("updateTime", new Date(), metaObject);
-	}
+    @Override
+    public void insertFill(MetaObject metaObject) {
+        User user = ServletUtil.getSessionUser();
+        if (user != null) {
+            this.setFieldValByName("creatorId", user.getId(), metaObject);
+        }
+        if (this.getFieldValByName("createTime", metaObject) == null) {
+            this.setFieldValByName("createTime", new Date(), metaObject);
+        }
+    }
+
+    @Override
+    public void updateFill(MetaObject metaObject) {
+        User user = ServletUtil.getSessionUser();
+        if (user != null) {
+            this.setFieldValByName("updaterId", user.getId(), metaObject);
+        }
+        this.setFieldValByName("updateTime", new Date(), metaObject);
+    }
 
 }

+ 0 - 1
src/main/java/cn/com/qmth/mps/config/MyBatisPlusConfig.java

@@ -6,7 +6,6 @@ import org.springframework.context.annotation.Configuration;
 @Configuration
 public class MyBatisPlusConfig {
 
-
     @Bean
     public FillMetaObjectHandler metaObjectHandler() {
         return new FillMetaObjectHandler();

+ 0 - 1
src/main/java/cn/com/qmth/mps/config/ScanWebMvcConfigurer.java

@@ -24,4 +24,3 @@ public class ScanWebMvcConfigurer implements WebMvcConfigurer {
     }
 
 }
-

+ 4 - 11
src/main/java/cn/com/qmth/mps/config/SwaggerConfig.java

@@ -22,21 +22,14 @@ public class SwaggerConfig {
     @Bean
     public Docket buildDocket() {
         log.info("swagger init...");
-        return new Docket(DocumentationType.SWAGGER_2)
-                .groupName("default")
-                .apiInfo(buildApiInfo())
-                .useDefaultResponseMessages(false)
-                .select()
-                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
-                .paths(PathSelectors.any())
+        return new Docket(DocumentationType.SWAGGER_2).groupName("default").apiInfo(buildApiInfo())
+                .useDefaultResponseMessages(false).select()
+                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any())
                 .build();
     }
 
     public ApiInfo buildApiInfo() {
-        return new ApiInfoBuilder()
-                .title("接口文档")
-                .version("v1.0.0")
-                .build();
+        return new ApiInfoBuilder().title("接口文档").version("v1.0.0").build();
     }
 
 }

+ 27 - 27
src/main/java/cn/com/qmth/mps/config/SysProperty.java

@@ -6,40 +6,40 @@ import org.springframework.stereotype.Component;
 @Component
 public class SysProperty {
 
-	/**
-	 * 会话超时时间(秒)
-	 */
-	@Value("${session-timeout}")
+    /**
+     * 会话超时时间(秒)
+     */
+    @Value("${session-timeout}")
     private Integer sessionTimeout;
-	@Value("${wxapp-url}")
+
+    @Value("${wxapp-url}")
     private String wxappUrl;
-	@Value("${wxapp-appid}")
+
+    @Value("${wxapp-appid}")
     private String wxappAppid;
-	
-	public Integer getSessionTimeout() {
-		return sessionTimeout;
-	}
 
-	public void setSessionTimeout(Integer sessionTimeout) {
-		this.sessionTimeout = sessionTimeout;
-	}
+    public Integer getSessionTimeout() {
+        return sessionTimeout;
+    }
+
+    public void setSessionTimeout(Integer sessionTimeout) {
+        this.sessionTimeout = sessionTimeout;
+    }
 
-	public String getWxappAppid() {
-		return wxappAppid;
-	}
+    public String getWxappAppid() {
+        return wxappAppid;
+    }
 
-	public void setWxappAppid(String wxappAppid) {
-		this.wxappAppid = wxappAppid;
-	}
+    public void setWxappAppid(String wxappAppid) {
+        this.wxappAppid = wxappAppid;
+    }
 
-	public String getWxappUrl() {
-		return wxappUrl;
-	}
+    public String getWxappUrl() {
+        return wxappUrl;
+    }
 
-	public void setWxappUrl(String wxappUrl) {
-		this.wxappUrl = wxappUrl;
-	}
-    
+    public void setWxappUrl(String wxappUrl) {
+        this.wxappUrl = wxappUrl;
+    }
 
-	
 }

+ 35 - 33
src/main/java/cn/com/qmth/mps/controller/AuthController.java

@@ -20,39 +20,41 @@ import io.swagger.annotations.ApiOperation;
 @Api(tags = "登录相关接口")
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/auth")
 public class AuthController extends BaseController {
-	@Autowired
-	private AuthService authService;
-
-	@ApiOperation(value = "管理端登录")
-	@PostMapping("login/admin")
-	public AdminLoginVo loginAdmin(@RequestParam String loginName, @RequestParam String password) {
-		return authService.loginAdmin(loginName,password);
-	}
-
-	@ApiOperation(value = "微信小程序登录")
-	@PostMapping("login/wxapp/login-code")
-	public AdminLoginVo loginWxApp(@RequestParam String loginCode) {
-		return authService.loginWxAppCode(loginCode);
-	}
-	
-	@ApiOperation(value = "绑定微信手机号并登录(新api)")
-	@PostMapping("login/wxapp/phone-code")
-	public AdminLoginVo loginWxAppByPhoneCode(@RequestParam String loginCode,@RequestParam String phoneCode) {
-		return authService.loginWxAppByPhoneCode(loginCode,phoneCode);
-	}
-	
-	@ApiOperation(value = "绑定微信手机号并登录(旧api)")
-	@PostMapping("login/wxapp/encrypted-data")
-	public AdminLoginVo loginWxAppByEncryptedData(@RequestParam String loginCode,@RequestParam String encryptedData,@RequestParam String iv) {
-		return authService.loginWxAppByEncryptedData(loginCode,encryptedData,iv);
-	}
-
-	@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
-	@ApiOperation(value = "登出")
-	@PostMapping("logout")
-	public void logout() {
-		User user = getAccessUser();
+
+    @Autowired
+    private AuthService authService;
+
+    @ApiOperation(value = "管理端登录")
+    @PostMapping("login/admin")
+    public AdminLoginVo loginAdmin(@RequestParam String loginName, @RequestParam String password) {
+        return authService.loginAdmin(loginName, password);
+    }
+
+    @ApiOperation(value = "微信小程序登录")
+    @PostMapping("login/wxapp/login-code")
+    public AdminLoginVo loginWxApp(@RequestParam String loginCode) {
+        return authService.loginWxAppCode(loginCode);
+    }
+
+    @ApiOperation(value = "绑定微信手机号并登录(新api)")
+    @PostMapping("login/wxapp/phone-code")
+    public AdminLoginVo loginWxAppByPhoneCode(@RequestParam String loginCode, @RequestParam String phoneCode) {
+        return authService.loginWxAppByPhoneCode(loginCode, phoneCode);
+    }
+
+    @ApiOperation(value = "绑定微信手机号并登录(旧api)")
+    @PostMapping("login/wxapp/encrypted-data")
+    public AdminLoginVo loginWxAppByEncryptedData(@RequestParam String loginCode, @RequestParam String encryptedData,
+            @RequestParam String iv) {
+        return authService.loginWxAppByEncryptedData(loginCode, encryptedData, iv);
+    }
+
+    @Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+    @ApiOperation(value = "登出")
+    @PostMapping("logout")
+    public void logout() {
+        User user = getAccessUser();
         authService.logout(user);
-	}
+    }
 
 }

+ 1 - 2
src/main/java/cn/com/qmth/mps/controller/BaseController.java

@@ -109,14 +109,13 @@ public class BaseController {
         trim(bean, false);
     }
 
-
     protected HttpServletResponse getResponse() {
         ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
                 .getRequestAttributes();
         HttpServletResponse response = requestAttributes.getResponse();
         return response;
     }
-    
+
     protected void exportFile(String fileName, InputStream in) {
         OutputStream out = null;
         try {

+ 11 - 10
src/main/java/cn/com/qmth/mps/controller/ExamController.java

@@ -26,37 +26,38 @@ import io.swagger.annotations.ApiOperation;
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/exam")
 @Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
 public class ExamController extends BaseController {
-	@Autowired
-	private ExamService examService;
+
+    @Autowired
+    private ExamService examService;
 
     @ApiOperation(value = "新增/修改")
     @RequestMapping(value = "save", method = RequestMethod.POST)
     public void save(ExamDomain domain) {
-    	examService.saveExam(domain,getAccessUser());
+        examService.saveExam(domain, getAccessUser());
     }
 
     @ApiOperation(value = "获取分页")
     @RequestMapping(value = "page", method = RequestMethod.POST)
     public PageResult<ExamVo> page(ExamQuery query) {
-        return examService.page(query,getAccessUser());
+        return examService.page(query, getAccessUser());
     }
-    
+
     @ApiOperation(value = "获取未关闭列表")
     @RequestMapping(value = "list", method = RequestMethod.POST)
     public List<ExamVo> unClose() {
         return examService.unClose(getAccessUser());
     }
-    
+
     @ApiOperation(value = "获取信息")
     @RequestMapping(value = "info", method = RequestMethod.POST)
     public ExamVo info(@RequestParam Long id) {
-        return examService.info(id,getAccessUser());
+        return examService.info(id, getAccessUser());
     }
-    
+
     @ApiOperation(value = "同步")
     @PostMapping("sync")
     public void sync(@RequestParam Long schoolId) {
-    	examService.syncExam(schoolId,getAccessUser());
+        examService.syncExam(schoolId, getAccessUser());
     }
-    
+
 }

+ 165 - 165
src/main/java/cn/com/qmth/mps/controller/PaperController.java

@@ -52,169 +52,169 @@ import io.swagger.annotations.ApiOperation;
 @Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
 public class PaperController extends BaseController {
 
-	@Autowired
-	private PaperService paperService;
-	
-	@Autowired
-	private PaperGroupService paperGroupService;
-	
-	@Autowired
-	private PaperDetailService paperDetailService;
-
-	@PostMapping("import-course")
-	@ApiOperation(value = "导入科目")
-	public ImportMsg importPaper(@RequestParam Long examId, @RequestParam MultipartFile file) {
-		List<String> failRecords = paperService.importPaper(examId, getAccessUser(), file);
-		ImportMsg msg = new ImportMsg();
-		msg.setHasError(CollectionUtils.isNotEmpty(failRecords));
-		msg.setErrMsg(failRecords);
-		return msg;
-	}
-
-	@PostMapping("import-struct-subject")
-	@ApiOperation(value = "导入主观题试卷结构")
-	public ImportMsg importSubjectStruct(@RequestParam Long examId, @RequestParam MultipartFile file) {
-		List<String> failRecords = paperService.importSubjectStruct(examId, getAccessUser(), file);
-		ImportMsg msg = new ImportMsg();
-		msg.setHasError(CollectionUtils.isNotEmpty(failRecords));
-		msg.setErrMsg(failRecords);
-		return msg;
-	}
-
-	@ApiOperation(value = "下载科目导入模板")
-	@PostMapping("template-course")
-	public void getImportTemplate() {
-		exportFile("科目导入模板.xlsx", ResouceUtil.getStream("importtemplates/courseImport.xlsx"));
-	}
-
-	@ApiOperation(value = "下载试卷结构导入模板")
-	@PostMapping("template-struct")
-	public void getStructImportTemplate() {
-		exportFile("试卷结构导入模板.xlsx", ResouceUtil.getStream("importtemplates/structImport.xlsx"));
-	}
-
-	@ApiOperation(value = "导出主观题")
-	@PostMapping("export-subjective")
-	public void exportSubjective(PaperQuery query, HttpServletResponse response) throws IOException {
-		String fileName = URLEncoder.encode("主观题", "UTF-8");
-		response.setHeader("Content-Disposition", "inline; filename=" + fileName + ".xlsx");
-		response.setContentType("application/vnd.ms-excel");
-
-		List<PaperStructInfoVo> list = paperService.subjectiveList(query, getAccessUser());
-		Workbook wb = null;
-		OutputStream out = null;
-		try {
-			wb = new XSSFWorkbook(ResouceUtil.getStream("importtemplates/structImport.xlsx"));
-			if (CollectionUtils.isNotEmpty(list)) {
-				CellStyle style = wb.createCellStyle();
-				style.setAlignment(HorizontalAlignment.CENTER);
-				Sheet sheet = wb.getSheetAt(0);
-				int rowIndex = 1;
-				for (PaperStructInfoVo vo : list) {
-					rowIndex++;
-					Row row = sheet.createRow(rowIndex);
-					row.createCell(0, CellType.STRING).setCellValue(getStringVal(vo.getCourseCode()));
-					row.createCell(1, CellType.STRING).setCellValue(getStringVal(vo.getCourseName()));
-					row.createCell(2, CellType.STRING).setCellValue(getStringVal(vo.getDetailName()));
-					row.createCell(3, CellType.STRING).setCellValue("");
-					row.createCell(4, CellType.STRING).setCellValue(getStringVal(vo.getDetailNumber()));
-					row.createCell(5, CellType.STRING).setCellValue(getStringVal(vo.getUnitNumber()));
-					row.createCell(6, CellType.STRING).setCellValue(getStringVal(vo.getScore()));
-					row.createCell(7, CellType.STRING).setCellValue(getStringVal(vo.getScoreStep()));
-					row.createCell(8, CellType.STRING).setCellValue(getStringVal(vo.getGroupNumber()));
-					row.createCell(9, CellType.STRING).setCellValue("");
-					ArbitrateMethod arbitrateMethod = vo.getArbitrateMethod();
-					String arbitrateMethodStr = "";
-					if (arbitrateMethod != null) {
-						arbitrateMethodStr = getStringVal(arbitrateMethod.getValue());
-					}
-					row.createCell(10, CellType.STRING).setCellValue(arbitrateMethodStr);
-					Double doubleRate = vo.getDoubleRate();
-					row.createCell(11, CellType.STRING).setCellValue(getStringVal(doubleRate));
-					row.createCell(12, CellType.STRING).setCellValue(getStringVal(vo.getArbitrateThreshold()));
-					row.createCell(13, CellType.STRING).setCellValue(doubleRate == null ? "" : "1");
-					row.createCell(14, CellType.STRING).setCellValue("track");
-					for (int i = 0; i < 15; i++) {
-						row.getCell(i).setCellStyle(style);
-					}
-				}
-			}
-			out = response.getOutputStream();
-			wb.write(out);
-		} finally {
-			if (wb != null) {
-				wb.close();
-			}
-			if (out != null) {
-				out.close();
-			}
-		}
-	}
-	
-	private String getStringVal(Object o) {
-		if(o==null) {
-			return "";
-		}
-		return o.toString();
-	}
-
-	@ApiOperation(value = "获取分页")
-	@RequestMapping(value = "page", method = RequestMethod.POST)
-	public PageResult<PaperVo> page(PaperQuery query) {
-		return paperService.page(query, getAccessUser());
-	}
-
-	@ApiOperation(value = "获取列表")
-	@RequestMapping(value = "list", method = RequestMethod.POST)
-	public List<PaperVo> list(@RequestParam Long examId) {
-		return paperService.list(examId, getAccessUser());
-	}
-
-	@ApiOperation(value = "获取信息")
-	@RequestMapping(value = "info", method = RequestMethod.POST)
-	public PaperInfoVo info(@RequestParam Long paperId) {
-		return paperService.info(paperId, getAccessUser());
-	}
-
-	@ApiOperation(value = "试卷结构提交")
-	@RequestMapping(value = "struct/submit", method = RequestMethod.POST)
-	public void structSubmit(@RequestBody StructDomain domain) {
-		paperDetailService.structSubmit(domain,getAccessUser());
-	}
-
-	@ApiOperation(value = "试卷结构暂存")
-	@RequestMapping(value = "struct/save", method = RequestMethod.POST)
-	public void structSave(@RequestBody StructDomain domain) {
-		paperDetailService.structSave(domain,getAccessUser());
-	}
-
-	@ApiOperation(value = "获取分组列表")
-	@RequestMapping(value = "group/list", method = RequestMethod.POST)
-	public List<GroupVo> groupList(@RequestParam Long paperId) {
-		return paperGroupService.groupList(paperId,getAccessUser());
-	}
-
-	@ApiOperation(value = "获取分组信息")
-	@RequestMapping(value = "group/info", method = RequestMethod.POST)
-	public GroupInfoVo groupInfo(@RequestParam Long paperId, @RequestParam Integer groupNumber) {
-		return paperGroupService.groupInfo(paperId,groupNumber,getAccessUser());
-	}
-
-	@ApiOperation(value = "保存分组信息")
-	@RequestMapping(value = "group/save", method = RequestMethod.POST)
-	public void groupSave(@RequestBody PaperGroupDomain domain) {
-		paperGroupService.groupSave(domain,getAccessUser());
-	}
-	
-	@ApiOperation(value = "删除分组信息")
-	@RequestMapping(value = "group/delete", method = RequestMethod.POST)
-	public void groupDelete(@RequestParam Long groupId) {
-		paperGroupService.groupDelete(groupId,getAccessUser());
-	}
-	
-	@ApiOperation(value = "清空分组信息")
-	@RequestMapping(value = "group/clear", method = RequestMethod.POST)
-	public void groupClear(@RequestParam Long paperId) {
-		paperGroupService.groupClear(paperId,getAccessUser());
-	}
+    @Autowired
+    private PaperService paperService;
+
+    @Autowired
+    private PaperGroupService paperGroupService;
+
+    @Autowired
+    private PaperDetailService paperDetailService;
+
+    @PostMapping("import-course")
+    @ApiOperation(value = "导入科目")
+    public ImportMsg importPaper(@RequestParam Long examId, @RequestParam MultipartFile file) {
+        List<String> failRecords = paperService.importPaper(examId, getAccessUser(), file);
+        ImportMsg msg = new ImportMsg();
+        msg.setHasError(CollectionUtils.isNotEmpty(failRecords));
+        msg.setErrMsg(failRecords);
+        return msg;
+    }
+
+    @PostMapping("import-struct-subject")
+    @ApiOperation(value = "导入主观题试卷结构")
+    public ImportMsg importSubjectStruct(@RequestParam Long examId, @RequestParam MultipartFile file) {
+        List<String> failRecords = paperService.importSubjectStruct(examId, getAccessUser(), file);
+        ImportMsg msg = new ImportMsg();
+        msg.setHasError(CollectionUtils.isNotEmpty(failRecords));
+        msg.setErrMsg(failRecords);
+        return msg;
+    }
+
+    @ApiOperation(value = "下载科目导入模板")
+    @PostMapping("template-course")
+    public void getImportTemplate() {
+        exportFile("科目导入模板.xlsx", ResouceUtil.getStream("importtemplates/courseImport.xlsx"));
+    }
+
+    @ApiOperation(value = "下载试卷结构导入模板")
+    @PostMapping("template-struct")
+    public void getStructImportTemplate() {
+        exportFile("试卷结构导入模板.xlsx", ResouceUtil.getStream("importtemplates/structImport.xlsx"));
+    }
+
+    @ApiOperation(value = "导出主观题")
+    @PostMapping("export-subjective")
+    public void exportSubjective(PaperQuery query, HttpServletResponse response) throws IOException {
+        String fileName = URLEncoder.encode("主观题", "UTF-8");
+        response.setHeader("Content-Disposition", "inline; filename=" + fileName + ".xlsx");
+        response.setContentType("application/vnd.ms-excel");
+
+        List<PaperStructInfoVo> list = paperService.subjectiveList(query, getAccessUser());
+        Workbook wb = null;
+        OutputStream out = null;
+        try {
+            wb = new XSSFWorkbook(ResouceUtil.getStream("importtemplates/structImport.xlsx"));
+            if (CollectionUtils.isNotEmpty(list)) {
+                CellStyle style = wb.createCellStyle();
+                style.setAlignment(HorizontalAlignment.CENTER);
+                Sheet sheet = wb.getSheetAt(0);
+                int rowIndex = 1;
+                for (PaperStructInfoVo vo : list) {
+                    rowIndex++;
+                    Row row = sheet.createRow(rowIndex);
+                    row.createCell(0, CellType.STRING).setCellValue(getStringVal(vo.getCourseCode()));
+                    row.createCell(1, CellType.STRING).setCellValue(getStringVal(vo.getCourseName()));
+                    row.createCell(2, CellType.STRING).setCellValue(getStringVal(vo.getDetailName()));
+                    row.createCell(3, CellType.STRING).setCellValue("");
+                    row.createCell(4, CellType.STRING).setCellValue(getStringVal(vo.getDetailNumber()));
+                    row.createCell(5, CellType.STRING).setCellValue(getStringVal(vo.getUnitNumber()));
+                    row.createCell(6, CellType.STRING).setCellValue(getStringVal(vo.getScore()));
+                    row.createCell(7, CellType.STRING).setCellValue(getStringVal(vo.getScoreStep()));
+                    row.createCell(8, CellType.STRING).setCellValue(getStringVal(vo.getGroupNumber()));
+                    row.createCell(9, CellType.STRING).setCellValue("");
+                    ArbitrateMethod arbitrateMethod = vo.getArbitrateMethod();
+                    String arbitrateMethodStr = "";
+                    if (arbitrateMethod != null) {
+                        arbitrateMethodStr = getStringVal(arbitrateMethod.getValue());
+                    }
+                    row.createCell(10, CellType.STRING).setCellValue(arbitrateMethodStr);
+                    Double doubleRate = vo.getDoubleRate();
+                    row.createCell(11, CellType.STRING).setCellValue(getStringVal(doubleRate));
+                    row.createCell(12, CellType.STRING).setCellValue(getStringVal(vo.getArbitrateThreshold()));
+                    row.createCell(13, CellType.STRING).setCellValue(doubleRate == null ? "" : "1");
+                    row.createCell(14, CellType.STRING).setCellValue("track");
+                    for (int i = 0; i < 15; i++) {
+                        row.getCell(i).setCellStyle(style);
+                    }
+                }
+            }
+            out = response.getOutputStream();
+            wb.write(out);
+        } finally {
+            if (wb != null) {
+                wb.close();
+            }
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+
+    private String getStringVal(Object o) {
+        if (o == null) {
+            return "";
+        }
+        return o.toString();
+    }
+
+    @ApiOperation(value = "获取分页")
+    @RequestMapping(value = "page", method = RequestMethod.POST)
+    public PageResult<PaperVo> page(PaperQuery query) {
+        return paperService.page(query, getAccessUser());
+    }
+
+    @ApiOperation(value = "获取列表")
+    @RequestMapping(value = "list", method = RequestMethod.POST)
+    public List<PaperVo> list(@RequestParam Long examId) {
+        return paperService.list(examId, getAccessUser());
+    }
+
+    @ApiOperation(value = "获取信息")
+    @RequestMapping(value = "info", method = RequestMethod.POST)
+    public PaperInfoVo info(@RequestParam Long paperId) {
+        return paperService.info(paperId, getAccessUser());
+    }
+
+    @ApiOperation(value = "试卷结构提交")
+    @RequestMapping(value = "struct/submit", method = RequestMethod.POST)
+    public void structSubmit(@RequestBody StructDomain domain) {
+        paperDetailService.structSubmit(domain, getAccessUser());
+    }
+
+    @ApiOperation(value = "试卷结构暂存")
+    @RequestMapping(value = "struct/save", method = RequestMethod.POST)
+    public void structSave(@RequestBody StructDomain domain) {
+        paperDetailService.structSave(domain, getAccessUser());
+    }
+
+    @ApiOperation(value = "获取分组列表")
+    @RequestMapping(value = "group/list", method = RequestMethod.POST)
+    public List<GroupVo> groupList(@RequestParam Long paperId) {
+        return paperGroupService.groupList(paperId, getAccessUser());
+    }
+
+    @ApiOperation(value = "获取分组信息")
+    @RequestMapping(value = "group/info", method = RequestMethod.POST)
+    public GroupInfoVo groupInfo(@RequestParam Long paperId, @RequestParam Integer groupNumber) {
+        return paperGroupService.groupInfo(paperId, groupNumber, getAccessUser());
+    }
+
+    @ApiOperation(value = "保存分组信息")
+    @RequestMapping(value = "group/save", method = RequestMethod.POST)
+    public void groupSave(@RequestBody PaperGroupDomain domain) {
+        paperGroupService.groupSave(domain, getAccessUser());
+    }
+
+    @ApiOperation(value = "删除分组信息")
+    @RequestMapping(value = "group/delete", method = RequestMethod.POST)
+    public void groupDelete(@RequestParam Long groupId) {
+        paperGroupService.groupDelete(groupId, getAccessUser());
+    }
+
+    @ApiOperation(value = "清空分组信息")
+    @RequestMapping(value = "group/clear", method = RequestMethod.POST)
+    public void groupClear(@RequestParam Long paperId) {
+        paperGroupService.groupClear(paperId, getAccessUser());
+    }
 }

+ 11 - 10
src/main/java/cn/com/qmth/mps/controller/SchoolController.java

@@ -26,37 +26,38 @@ import io.swagger.annotations.ApiOperation;
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/school")
 @Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
 public class SchoolController extends BaseController {
-	@Autowired
-	private SchoolService schoolService;
+
+    @Autowired
+    private SchoolService schoolService;
 
     @ApiOperation(value = "新增/修改")
     @RequestMapping(value = "save", method = RequestMethod.POST)
     public void save(SchoolDomain domain) {
-    	schoolService.saveSchool(getAccessUser(),domain);
+        schoolService.saveSchool(getAccessUser(), domain);
     }
 
     @ApiOperation(value = "获取分页")
     @RequestMapping(value = "page", method = RequestMethod.POST)
     public PageResult<SchoolVo> page(SchoolQuery query) {
-        return schoolService.page(query,getAccessUser());
+        return schoolService.page(query, getAccessUser());
     }
-    
+
     @ApiOperation(value = "获取信息")
     @RequestMapping(value = "info", method = RequestMethod.POST)
     public SchoolVo info(@RequestParam Long id) {
-        return schoolService.info(id,getAccessUser());
+        return schoolService.info(id, getAccessUser());
     }
-    
+
     @ApiOperation(value = "启用/禁用")
     @RequestMapping(value = "toggle", method = RequestMethod.POST)
     public void enable(@RequestParam List<Long> ids, @RequestParam Boolean enable) {
-    	schoolService.toggle(ids,enable,getAccessUser());
+        schoolService.toggle(ids, enable, getAccessUser());
     }
-    
+
     @ApiOperation(value = "同步")
     @PostMapping("sync")
     public void sync() {
-    	schoolService.syncSchool(getAccessUser());
+        schoolService.syncSchool(getAccessUser());
     }
 
 }

+ 56 - 55
src/main/java/cn/com/qmth/mps/controller/UserController.java

@@ -31,65 +31,66 @@ import io.swagger.annotations.ApiOperation;
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/user")
 @Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
 public class UserController extends BaseController {
-	@Autowired
-	private UserService userService;
 
-	@ApiOperation(value = "新增/修改")
-	@RequestMapping(value = "save", method = RequestMethod.POST)
-	public void save(UserDomain domain) {
-		userService.saveUser(domain, getAccessUser());
-	}
+    @Autowired
+    private UserService userService;
 
-	@PostMapping("import")
-	@ApiOperation(value = "导入")
-	public ImportMsg importUser(@RequestParam Long schoolId, @RequestParam MultipartFile file) {
-		User user = getAccessUser();
-		List<String> failRecords = userService.importUser(schoolId,user, file);
-		ImportMsg msg = new ImportMsg();
-		msg.setHasError(CollectionUtils.isNotEmpty(failRecords));
-		msg.setErrMsg(failRecords);
-		return msg;
-	}
+    @ApiOperation(value = "新增/修改")
+    @RequestMapping(value = "save", method = RequestMethod.POST)
+    public void save(UserDomain domain) {
+        userService.saveUser(domain, getAccessUser());
+    }
 
-	@ApiOperation(value = "下载导入模板")
-	@PostMapping("template")
-	public void getImportTemplate() {
-		exportFile("用户导入模板.xlsx", ResouceUtil.getStream("importtemplates/userImport.xlsx"));
-	}
+    @PostMapping("import")
+    @ApiOperation(value = "导入")
+    public ImportMsg importUser(@RequestParam Long schoolId, @RequestParam MultipartFile file) {
+        User user = getAccessUser();
+        List<String> failRecords = userService.importUser(schoolId, user, file);
+        ImportMsg msg = new ImportMsg();
+        msg.setHasError(CollectionUtils.isNotEmpty(failRecords));
+        msg.setErrMsg(failRecords);
+        return msg;
+    }
 
-	@ApiOperation(value = "获取分页")
-	@RequestMapping(value = "page", method = RequestMethod.POST)
-	public PageResult<UserVo> page(UserQuery query) {
-		return userService.page(query,getAccessUser());
-	}
+    @ApiOperation(value = "下载导入模板")
+    @PostMapping("template")
+    public void getImportTemplate() {
+        exportFile("用户导入模板.xlsx", ResouceUtil.getStream("importtemplates/userImport.xlsx"));
+    }
 
-	@ApiOperation(value = "获取指定用户信息")
-	@RequestMapping(value = "info", method = RequestMethod.POST)
-	public UserVo info(@RequestParam Long id) {
-		return userService.info(id);
-	}
-	
-	@ApiOperation(value = "获取当前用户信息")
-	@RequestMapping(value = "my/info", method = RequestMethod.POST)
-	public UserVo myInfo() {
-		return userService.myInfo(getAccessUser());
-	}
+    @ApiOperation(value = "获取分页")
+    @RequestMapping(value = "page", method = RequestMethod.POST)
+    public PageResult<UserVo> page(UserQuery query) {
+        return userService.page(query, getAccessUser());
+    }
 
-	@ApiOperation(value = "启用/禁用")
-	@RequestMapping(value = "toggle", method = RequestMethod.POST)
-	public void toggle(@RequestParam List<Long> ids, @RequestParam Boolean enable) {
-		userService.toggle(ids,enable,getAccessUser());
-	}
-	
-	@ApiOperation(value = "重置指定用户密码")
-	@PostMapping("reset-passwd")
-	public void resetPass(@RequestParam Long userId,@RequestParam String passwd) {
-		userService.resetPass(userId,passwd,getAccessUser());
-	}
-	
-	@ApiOperation(value = "修改当前用户密码")
-	@PostMapping("password")
-	public void updatePass(@RequestParam String password) {
-		userService.updatePass(password,getAccessUser());
-	}
+    @ApiOperation(value = "获取指定用户信息")
+    @RequestMapping(value = "info", method = RequestMethod.POST)
+    public UserVo info(@RequestParam Long id) {
+        return userService.info(id);
+    }
+
+    @ApiOperation(value = "获取当前用户信息")
+    @RequestMapping(value = "my/info", method = RequestMethod.POST)
+    public UserVo myInfo() {
+        return userService.myInfo(getAccessUser());
+    }
+
+    @ApiOperation(value = "启用/禁用")
+    @RequestMapping(value = "toggle", method = RequestMethod.POST)
+    public void toggle(@RequestParam List<Long> ids, @RequestParam Boolean enable) {
+        userService.toggle(ids, enable, getAccessUser());
+    }
+
+    @ApiOperation(value = "重置指定用户密码")
+    @PostMapping("reset-passwd")
+    public void resetPass(@RequestParam Long userId, @RequestParam String passwd) {
+        userService.resetPass(userId, passwd, getAccessUser());
+    }
+
+    @ApiOperation(value = "修改当前用户密码")
+    @PostMapping("password")
+    public void updatePass(@RequestParam String password) {
+        userService.updatePass(password, getAccessUser());
+    }
 }

+ 2 - 2
src/main/java/cn/com/qmth/mps/dao/ExamDao.java

@@ -14,8 +14,8 @@ import cn.com.qmth.mps.vo.exam.ExamVo;
 
 public interface ExamDao extends BaseMapper<ExamEntity> {
 
-	IPage<ExamVo> page(Page<ExamVo> page,@Param("req") ExamQuery query);
+    IPage<ExamVo> page(Page<ExamVo> page, @Param("req") ExamQuery query);
 
-	List<ExamVo> unClose(@Param("schoolId")Long schoolId);
+    List<ExamVo> unClose(@Param("schoolId") Long schoolId);
 
 }

+ 5 - 4
src/main/java/cn/com/qmth/mps/dao/PaperDao.java

@@ -17,12 +17,13 @@ import cn.com.qmth.mps.vo.paper.PaperVo;
 
 public interface PaperDao extends BaseMapper<PaperEntity> {
 
-	List<ExamPaperCountVo> findPaperCount(@Param(value = "examIds") List<Long> examIds);
+    List<ExamPaperCountVo> findPaperCount(@Param(value = "examIds") List<Long> examIds);
 
-	IPage<PaperVo> page(Page<PaperVo> page,@Param(value = "req") PaperQuery query);
+    IPage<PaperVo> page(Page<PaperVo> page, @Param(value = "req") PaperQuery query);
 
-	List<PaperVo> myPaperlist(@Param(value = "examId")Long examId,@Param(value = "userId")Long userId);
+    List<PaperVo> myPaperlist(@Param(value = "examId") Long examId, @Param(value = "userId") Long userId);
 
-	List<PaperStructInfoVo> subjectiveList(@Param(value = "req")PaperQuery query,@Param(value = "arbitrateMethod")ArbitrateMethod arbitrateMethod);
+    List<PaperStructInfoVo> subjectiveList(@Param(value = "req") PaperQuery query,
+            @Param(value = "arbitrateMethod") ArbitrateMethod arbitrateMethod);
 
 }

+ 0 - 1
src/main/java/cn/com/qmth/mps/dao/PaperDetailDao.java

@@ -6,5 +6,4 @@ import cn.com.qmth.mps.entity.PaperDetailEntity;
 
 public interface PaperDetailDao extends BaseMapper<PaperDetailEntity> {
 
-
 }

+ 1 - 1
src/main/java/cn/com/qmth/mps/dao/PaperGroupDao.java

@@ -9,6 +9,6 @@ import cn.com.qmth.mps.vo.paper.GroupCountVo;
 
 public interface PaperGroupDao extends BaseMapper<PaperGroupEntity> {
 
-	List<GroupCountVo> findGroupCount(List<Long> paperIds);
+    List<GroupCountVo> findGroupCount(List<Long> paperIds);
 
 }

+ 1 - 1
src/main/java/cn/com/qmth/mps/dao/SchoolDao.java

@@ -12,6 +12,6 @@ import cn.com.qmth.mps.vo.school.SchoolVo;
 
 public interface SchoolDao extends BaseMapper<SchoolEntity> {
 
-	IPage<SchoolVo> page(Page<SchoolVo> page,@Param("req") SchoolQuery query,@Param("schoolId") Long schoolId);
+    IPage<SchoolVo> page(Page<SchoolVo> page, @Param("req") SchoolQuery query, @Param("schoolId") Long schoolId);
 
 }

+ 2 - 2
src/main/java/cn/com/qmth/mps/dao/UserCourseRelationDao.java

@@ -11,8 +11,8 @@ import cn.com.qmth.mps.entity.UserCourseRelationEntity;
 
 public interface UserCourseRelationDao extends MppBaseMapper<UserCourseRelationEntity> {
 
-	List<CourseInfo> getCourses(@Param("userId")Long userId);
+    List<CourseInfo> getCourses(@Param("userId") Long userId);
 
-	void clearBySchool(@Param("schoolId")Long schoolId);
+    void clearBySchool(@Param("schoolId") Long schoolId);
 
 }

+ 1 - 1
src/main/java/cn/com/qmth/mps/dao/UserDao.java

@@ -12,6 +12,6 @@ import cn.com.qmth.mps.vo.user.UserVo;
 
 public interface UserDao extends BaseMapper<UserEntity> {
 
-	IPage<UserVo> page(Page<UserVo> page,@Param("req") UserQuery query);
+    IPage<UserVo> page(Page<UserVo> page, @Param("req") UserQuery query);
 
 }

+ 24 - 23
src/main/java/cn/com/qmth/mps/entity/CourseEntity.java

@@ -3,39 +3,40 @@ package cn.com.qmth.mps.entity;
 import com.baomidou.mybatisplus.annotation.TableName;
 
 import cn.com.qmth.mps.entity.base.AuditingEntity;
+
 @TableName("mps_course")
 public class CourseEntity extends AuditingEntity {
 
-	private static final long serialVersionUID = -6261302618070108336L;
+    private static final long serialVersionUID = -6261302618070108336L;
+
+    private Long schoolId;
 
-	private Long schoolId;
-	private String code;
-	private String name;
+    private String code;
 
+    private String name;
 
-	
-	public Long getSchoolId() {
-		return schoolId;
-	}
+    public Long getSchoolId() {
+        return schoolId;
+    }
 
-	public void setSchoolId(Long schoolId) {
-		this.schoolId = schoolId;
-	}
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
 
-	public String getCode() {
-		return code;
-	}
+    public String getCode() {
+        return code;
+    }
 
-	public void setCode(String code) {
-		this.code = code;
-	}
+    public void setCode(String code) {
+        this.code = code;
+    }
 
-	public String getName() {
-		return name;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public void setName(String name) {
+        this.name = name;
+    }
 
 }

+ 44 - 33
src/main/java/cn/com/qmth/mps/entity/ExamEntity.java

@@ -4,39 +4,50 @@ import com.baomidou.mybatisplus.annotation.TableName;
 
 import cn.com.qmth.mps.entity.base.AuditingEntity;
 import cn.com.qmth.mps.enums.ExamStatus;
+
 @TableName("mps_exam")
 public class ExamEntity extends AuditingEntity {
-	private static final long serialVersionUID = 3104183197745226731L;
-	private Long schoolId;
-	private String code;
-	private String name;
-	private ExamStatus examStatus;
-	
-	
-	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;
-	}
-	public ExamStatus getExamStatus() {
-		return examStatus;
-	}
-	public void setExamStatus(ExamStatus examStatus) {
-		this.examStatus = examStatus;
-	}
-	public String getCode() {
-		return code;
-	}
-	public void setCode(String code) {
-		this.code = code;
-	}
-
-	
+
+    private static final long serialVersionUID = 3104183197745226731L;
+
+    private Long schoolId;
+
+    private String code;
+
+    private String name;
+
+    private ExamStatus examStatus;
+
+    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;
+    }
+
+    public ExamStatus getExamStatus() {
+        return examStatus;
+    }
+
+    public void setExamStatus(ExamStatus examStatus) {
+        this.examStatus = examStatus;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
 }

+ 37 - 27
src/main/java/cn/com/qmth/mps/entity/PaperDetailEntity.java

@@ -5,31 +5,41 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import cn.com.qmth.mps.entity.base.AuditingEntity;
 
 @TableName("mps_paper_detail")
-public class PaperDetailEntity extends AuditingEntity{
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -5581039038244553146L;
-	private Long paperId;
-	private String name;
-	private Integer number;
-	public String getName() {
-		return name;
-	}
-	public void setName(String name) {
-		this.name = name;
-	}
-	public Integer getNumber() {
-		return number;
-	}
-	public void setNumber(Integer number) {
-		this.number = number;
-	}
-	public Long getPaperId() {
-		return paperId;
-	}
-	public void setPaperId(Long paperId) {
-		this.paperId = paperId;
-	}
-	
+public class PaperDetailEntity extends AuditingEntity {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -5581039038244553146L;
+
+    private Long paperId;
+
+    private String name;
+
+    private Integer number;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public Long getPaperId() {
+        return paperId;
+    }
+
+    public void setPaperId(Long paperId) {
+        this.paperId = paperId;
+    }
+
 }

+ 75 - 67
src/main/java/cn/com/qmth/mps/entity/PaperDetailUnitEntity.java

@@ -6,72 +6,80 @@ import cn.com.qmth.mps.entity.base.AuditingEntity;
 
 @TableName("mps_paper_detail_unit")
 public class PaperDetailUnitEntity extends AuditingEntity {
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -2626652229749411040L;
-	private Long paperId;
-	private Long detailId;
-	private Integer detailNumber;
-	private Integer number;
-	private Double score;
-	private Double scoreStep;
-	private Boolean objective;
-
-	public Integer getNumber() {
-		return number;
-	}
-
-	public void setNumber(Integer number) {
-		this.number = number;
-	}
-
-	public Double getScore() {
-		return score;
-	}
-
-	public void setScore(Double score) {
-		this.score = score;
-	}
-
-	public Double getScoreStep() {
-		return scoreStep;
-	}
-
-	public void setScoreStep(Double scoreStep) {
-		this.scoreStep = scoreStep;
-	}
-
-	public Long getPaperId() {
-		return paperId;
-	}
-
-	public void setPaperId(Long paperId) {
-		this.paperId = paperId;
-	}
-
-	public Long getDetailId() {
-		return detailId;
-	}
-
-	public void setDetailId(Long detailId) {
-		this.detailId = detailId;
-	}
-
-	public Integer getDetailNumber() {
-		return detailNumber;
-	}
-
-	public void setDetailNumber(Integer detailNumber) {
-		this.detailNumber = detailNumber;
-	}
-
-	public Boolean getObjective() {
-		return objective;
-	}
-
-	public void setObjective(Boolean objective) {
-		this.objective = objective;
-	}
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -2626652229749411040L;
+
+    private Long paperId;
+
+    private Long detailId;
+
+    private Integer detailNumber;
+
+    private Integer number;
+
+    private Double score;
+
+    private Double scoreStep;
+
+    private Boolean objective;
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public Double getScore() {
+        return score;
+    }
+
+    public void setScore(Double score) {
+        this.score = score;
+    }
+
+    public Double getScoreStep() {
+        return scoreStep;
+    }
+
+    public void setScoreStep(Double scoreStep) {
+        this.scoreStep = scoreStep;
+    }
+
+    public Long getPaperId() {
+        return paperId;
+    }
+
+    public void setPaperId(Long paperId) {
+        this.paperId = paperId;
+    }
+
+    public Long getDetailId() {
+        return detailId;
+    }
+
+    public void setDetailId(Long detailId) {
+        this.detailId = detailId;
+    }
+
+    public Integer getDetailNumber() {
+        return detailNumber;
+    }
+
+    public void setDetailNumber(Integer detailNumber) {
+        this.detailNumber = detailNumber;
+    }
+
+    public Boolean getObjective() {
+        return objective;
+    }
+
+    public void setObjective(Boolean objective) {
+        this.objective = objective;
+    }
 
 }

+ 76 - 76
src/main/java/cn/com/qmth/mps/entity/PaperEntity.java

@@ -4,112 +4,112 @@ import cn.com.qmth.mps.entity.base.AuditingEntity;
 import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.annotations.ApiModelProperty;
 
-@TableName(value="mps_paper",autoResultMap = true)
+@TableName(value = "mps_paper", autoResultMap = true)
 public class PaperEntity extends AuditingEntity {
 
-	/**
-	 *
-	 */
-	private static final long serialVersionUID = -8681575737341326402L;
+    /**
+     *
+     */
+    private static final long serialVersionUID = -8681575737341326402L;
 
-	private Long schoolId;
+    private Long schoolId;
 
-	private Long examId;
+    private Long examId;
 
-	private Long courseId;
+    private Long courseId;
 
-	private Double totalScore;
+    private Double totalScore;
 
-	private Double objectiveScore;
+    private Double objectiveScore;
 
-	private Double subjectiveScore;
+    private Double subjectiveScore;
 
-	private String paperType;
+    private String paperType;
 
-	private Boolean structFinish;
+    private Boolean structFinish;
 
-	private Boolean groupFinish;
+    private Boolean groupFinish;
 
-	@ApiModelProperty("默认双评设置")
-	private String defaultDoubleSet;
+    @ApiModelProperty("默认双评设置")
+    private String defaultDoubleSet;
 
-	public Long getSchoolId() {
-		return schoolId;
-	}
+    public Long getSchoolId() {
+        return schoolId;
+    }
 
-	public void setSchoolId(Long schoolId) {
-		this.schoolId = schoolId;
-	}
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
 
-	public Long getExamId() {
-		return examId;
-	}
+    public Long getExamId() {
+        return examId;
+    }
 
-	public void setExamId(Long examId) {
-		this.examId = examId;
-	}
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
 
-	public Long getCourseId() {
-		return courseId;
-	}
+    public Long getCourseId() {
+        return courseId;
+    }
 
-	public void setCourseId(Long courseId) {
-		this.courseId = courseId;
-	}
+    public void setCourseId(Long courseId) {
+        this.courseId = courseId;
+    }
 
-	public Double getTotalScore() {
-		return totalScore;
-	}
+    public Double getTotalScore() {
+        return totalScore;
+    }
 
-	public void setTotalScore(Double totalScore) {
-		this.totalScore = totalScore;
-	}
+    public void setTotalScore(Double totalScore) {
+        this.totalScore = totalScore;
+    }
 
-	public Double getObjectiveScore() {
-		return objectiveScore;
-	}
+    public Double getObjectiveScore() {
+        return objectiveScore;
+    }
 
-	public void setObjectiveScore(Double objectiveScore) {
-		this.objectiveScore = objectiveScore;
-	}
+    public void setObjectiveScore(Double objectiveScore) {
+        this.objectiveScore = objectiveScore;
+    }
 
-	public Double getSubjectiveScore() {
-		return subjectiveScore;
-	}
+    public Double getSubjectiveScore() {
+        return subjectiveScore;
+    }
 
-	public void setSubjectiveScore(Double subjectiveScore) {
-		this.subjectiveScore = subjectiveScore;
-	}
+    public void setSubjectiveScore(Double subjectiveScore) {
+        this.subjectiveScore = subjectiveScore;
+    }
 
-	public String getPaperType() {
-		return paperType;
-	}
+    public String getPaperType() {
+        return paperType;
+    }
 
-	public void setPaperType(String paperType) {
-		this.paperType = paperType;
-	}
+    public void setPaperType(String paperType) {
+        this.paperType = paperType;
+    }
 
-	public Boolean getGroupFinish() {
-		return groupFinish;
-	}
+    public Boolean getGroupFinish() {
+        return groupFinish;
+    }
 
-	public void setGroupFinish(Boolean groupFinish) {
-		this.groupFinish = groupFinish;
-	}
+    public void setGroupFinish(Boolean groupFinish) {
+        this.groupFinish = groupFinish;
+    }
 
-	public Boolean getStructFinish() {
-		return structFinish;
-	}
+    public Boolean getStructFinish() {
+        return structFinish;
+    }
 
-	public void setStructFinish(Boolean structFinish) {
-		this.structFinish = structFinish;
-	}
+    public void setStructFinish(Boolean structFinish) {
+        this.structFinish = structFinish;
+    }
 
-	public String getDefaultDoubleSet() {
-		return defaultDoubleSet;
-	}
+    public String getDefaultDoubleSet() {
+        return defaultDoubleSet;
+    }
 
-	public void setDefaultDoubleSet(String defaultDoubleSet) {
-		this.defaultDoubleSet = defaultDoubleSet;
-	}
+    public void setDefaultDoubleSet(String defaultDoubleSet) {
+        this.defaultDoubleSet = defaultDoubleSet;
+    }
 }

+ 50 - 50
src/main/java/cn/com/qmth/mps/entity/PaperGroupEntity.java

@@ -8,72 +8,72 @@ import io.swagger.annotations.ApiModelProperty;
 @TableName("mps_paper_group")
 public class PaperGroupEntity extends AuditingEntity {
 
-	/**
-	 *
-	 */
-	private static final long serialVersionUID = -8843551391313294436L;
+    /**
+     *
+     */
+    private static final long serialVersionUID = -8843551391313294436L;
 
-	private Long paperId;
+    private Long paperId;
 
-	private Integer number;
+    private Integer number;
 
-	@ApiModelProperty(value = "是否开启双评")
-	private Boolean doubleEnable;
+    @ApiModelProperty(value = "是否开启双评")
+    private Boolean doubleEnable;
 
-	@ApiModelProperty(value = "双评比例")
-	private Double doubleRate;
+    @ApiModelProperty(value = "双评比例")
+    private Double doubleRate;
 
-	@ApiModelProperty(value = "仲裁阈值")
-	private Double arbitrateThreshold;
+    @ApiModelProperty(value = "仲裁阈值")
+    private Double arbitrateThreshold;
 
-	@ApiModelProperty(value = "仲裁方式")
-	private ArbitrateMethod arbitrateMethod;
+    @ApiModelProperty(value = "仲裁方式")
+    private ArbitrateMethod arbitrateMethod;
 
-	public Integer getNumber() {
-		return number;
-	}
+    public Integer getNumber() {
+        return number;
+    }
 
-	public void setNumber(Integer number) {
-		this.number = number;
-	}
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
 
-	public Long getPaperId() {
-		return paperId;
-	}
+    public Long getPaperId() {
+        return paperId;
+    }
 
-	public void setPaperId(Long paperId) {
-		this.paperId = paperId;
-	}
+    public void setPaperId(Long paperId) {
+        this.paperId = paperId;
+    }
 
-	public Boolean getDoubleEnable() {
-		return doubleEnable;
-	}
+    public Boolean getDoubleEnable() {
+        return doubleEnable;
+    }
 
-	public void setDoubleEnable(Boolean doubleEnable) {
-		this.doubleEnable = doubleEnable;
-	}
+    public void setDoubleEnable(Boolean doubleEnable) {
+        this.doubleEnable = doubleEnable;
+    }
 
-	public Double getDoubleRate() {
-		return doubleRate;
-	}
+    public Double getDoubleRate() {
+        return doubleRate;
+    }
 
-	public void setDoubleRate(Double doubleRate) {
-		this.doubleRate = doubleRate;
-	}
+    public void setDoubleRate(Double doubleRate) {
+        this.doubleRate = doubleRate;
+    }
 
-	public Double getArbitrateThreshold() {
-		return arbitrateThreshold;
-	}
+    public Double getArbitrateThreshold() {
+        return arbitrateThreshold;
+    }
 
-	public void setArbitrateThreshold(Double arbitrateThreshold) {
-		this.arbitrateThreshold = arbitrateThreshold;
-	}
+    public void setArbitrateThreshold(Double arbitrateThreshold) {
+        this.arbitrateThreshold = arbitrateThreshold;
+    }
 
-	public ArbitrateMethod getArbitrateMethod() {
-		return arbitrateMethod;
-	}
+    public ArbitrateMethod getArbitrateMethod() {
+        return arbitrateMethod;
+    }
 
-	public void setArbitrateMethod(ArbitrateMethod arbitrateMethod) {
-		this.arbitrateMethod = arbitrateMethod;
-	}
+    public void setArbitrateMethod(ArbitrateMethod arbitrateMethod) {
+        this.arbitrateMethod = arbitrateMethod;
+    }
 }

+ 40 - 40
src/main/java/cn/com/qmth/mps/entity/PaperGroupUnitEntity.java

@@ -8,59 +8,59 @@ import io.swagger.annotations.ApiModelProperty;
 @TableName("mps_paper_group_unit")
 public class PaperGroupUnitEntity extends AuditingEntity {
 
-	/**
-	 *
-	 */
-	private static final long serialVersionUID = 5657687276637032291L;
+    /**
+     *
+     */
+    private static final long serialVersionUID = 5657687276637032291L;
 
-	private Long paperId;
+    private Long paperId;
 
-	private Long groupId;
+    private Long groupId;
 
-	private Integer detailNumber;
+    private Integer detailNumber;
 
-	private Integer detailUnitNumber;
+    private Integer detailUnitNumber;
 
-	@ApiModelProperty(value = "仲裁阈值")
-	private Double arbitrateThreshold;
+    @ApiModelProperty(value = "仲裁阈值")
+    private Double arbitrateThreshold;
 
-	public Long getPaperId() {
-		return paperId;
-	}
+    public Long getPaperId() {
+        return paperId;
+    }
 
-	public void setPaperId(Long paperId) {
-		this.paperId = paperId;
-	}
+    public void setPaperId(Long paperId) {
+        this.paperId = paperId;
+    }
 
-	public Long getGroupId() {
-		return groupId;
-	}
+    public Long getGroupId() {
+        return groupId;
+    }
 
-	public void setGroupId(Long groupId) {
-		this.groupId = groupId;
-	}
+    public void setGroupId(Long groupId) {
+        this.groupId = groupId;
+    }
 
-	public Integer getDetailNumber() {
-		return detailNumber;
-	}
+    public Integer getDetailNumber() {
+        return detailNumber;
+    }
 
-	public void setDetailNumber(Integer detailNumber) {
-		this.detailNumber = detailNumber;
-	}
+    public void setDetailNumber(Integer detailNumber) {
+        this.detailNumber = detailNumber;
+    }
 
-	public Integer getDetailUnitNumber() {
-		return detailUnitNumber;
-	}
+    public Integer getDetailUnitNumber() {
+        return detailUnitNumber;
+    }
 
-	public void setDetailUnitNumber(Integer detailUnitNumber) {
-		this.detailUnitNumber = detailUnitNumber;
-	}
+    public void setDetailUnitNumber(Integer detailUnitNumber) {
+        this.detailUnitNumber = detailUnitNumber;
+    }
 
-	public Double getArbitrateThreshold() {
-		return arbitrateThreshold;
-	}
+    public Double getArbitrateThreshold() {
+        return arbitrateThreshold;
+    }
 
-	public void setArbitrateThreshold(Double arbitrateThreshold) {
-		this.arbitrateThreshold = arbitrateThreshold;
-	}
+    public void setArbitrateThreshold(Double arbitrateThreshold) {
+        this.arbitrateThreshold = arbitrateThreshold;
+    }
 }

+ 195 - 197
src/main/java/cn/com/qmth/mps/entity/PrivilegeEntity.java

@@ -4,205 +4,203 @@ import com.baomidou.mybatisplus.annotation.TableName;
 
 import cn.com.qmth.mps.bean.TreeNode;
 import cn.com.qmth.mps.entity.base.AuditingEntity;
+
 @TableName("mps_privilege")
 public class PrivilegeEntity extends AuditingEntity implements TreeNode {
 
-	private static final long serialVersionUID = -6288949236298877031L;
-	
-	/**
-	 * 权限码
-	 */
-	private String code;
-
-	/**
-	 * 权限名称
-	 */
-	private String name;
-
-	/**
-	 * 父权限ID
-	 */
-	private Long parentId;
-
-
-	/**
-	 * 描述
-	 */
-	private String description;
-
-	/**
-	 * 排序
-	 */
-	private Integer seq = 0;
-
-	/**
-	 * 扩展属性
-	 */
-	private String ext1;
-
-	/**
-	 * 扩展属性
-	 */
-	private String ext2;
-
-	/**
-	 * 扩展属性
-	 */
-	private String ext3;
-
-	/**
-	 * 扩展属性
-	 */
-	private String ext4;
-
-	/**
-	 * 扩展属性
-	 */
-	private String ext5;
-
-
-	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 String getDescription() {
-		return description;
-	}
-
-	public void setDescription(String description) {
-		this.description = description;
-	}
-
-
-	public Integer getSeq() {
-		return seq;
-	}
-
-	public void setSeq(Integer seq) {
-		this.seq = seq;
-	}
-
-	public String getExt1() {
-		return ext1;
-	}
-
-	public void setExt1(String ext1) {
-		this.ext1 = ext1;
-	}
-
-	public String getExt2() {
-		return ext2;
-	}
-
-	public void setExt2(String ext2) {
-		this.ext2 = ext2;
-	}
-
-	public String getExt3() {
-		return ext3;
-	}
-
-	public void setExt3(String ext3) {
-		this.ext3 = ext3;
-	}
-
-	public String getExt4() {
-		return ext4;
-	}
-
-	public void setExt4(String ext4) {
-		this.ext4 = ext4;
-	}
-
-	public String getExt5() {
-		return ext5;
-	}
-
-	public void setExt5(String ext5) {
-		this.ext5 = ext5;
-	}
-
-	@Override
-	public String getNodeId() {
-		if (null == this.id) {
-			return null;
-		}
-		return String.valueOf(this.id);
-	}
-
-	@Override
-	public void setNodeId(String nodeId) {
-		if (null == nodeId) {
-			this.id = null;
-		}
-		this.id = Long.parseLong(nodeId);
-	}
-
-	@Override
-	public String getNodeName() {
-		if (null == this.name) {
-			return null;
-		}
-		return String.valueOf(this.name);
-	}
-
-	@Override
-	public void setNodeName(String nodeName) {
-		this.name = nodeName;
-	}
-
-	@Override
-	public String getParentNodeId() {
-		if (null == this.parentId) {
-			return null;
-		}
-		return String.valueOf(this.parentId);
-	}
-
-	@Override
-	public void setParentNodeId(String parentNodeId) {
-		if (null == parentNodeId) {
-			this.parentId = null;
-		}
-		this.parentId = Long.parseLong(parentNodeId);
-	}
-
-	@Override
-	public String getNodeCode() {
-		return this.code;
-	}
-
-	@Override
-	public void setNodeCode(String code) {
-		this.code = code;
-	}
-
-	public Long getId() {
-		return id;
-	}
-
-	public void setId(Long id) {
-		this.id = id;
-	}
+    private static final long serialVersionUID = -6288949236298877031L;
+
+    /**
+     * 权限码
+     */
+    private String code;
+
+    /**
+     * 权限名称
+     */
+    private String name;
+
+    /**
+     * 父权限ID
+     */
+    private Long parentId;
+
+    /**
+     * 描述
+     */
+    private String description;
+
+    /**
+     * 排序
+     */
+    private Integer seq = 0;
+
+    /**
+     * 扩展属性
+     */
+    private String ext1;
+
+    /**
+     * 扩展属性
+     */
+    private String ext2;
+
+    /**
+     * 扩展属性
+     */
+    private String ext3;
+
+    /**
+     * 扩展属性
+     */
+    private String ext4;
+
+    /**
+     * 扩展属性
+     */
+    private String ext5;
+
+    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 String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Integer getSeq() {
+        return seq;
+    }
+
+    public void setSeq(Integer seq) {
+        this.seq = seq;
+    }
+
+    public String getExt1() {
+        return ext1;
+    }
+
+    public void setExt1(String ext1) {
+        this.ext1 = ext1;
+    }
+
+    public String getExt2() {
+        return ext2;
+    }
+
+    public void setExt2(String ext2) {
+        this.ext2 = ext2;
+    }
+
+    public String getExt3() {
+        return ext3;
+    }
+
+    public void setExt3(String ext3) {
+        this.ext3 = ext3;
+    }
+
+    public String getExt4() {
+        return ext4;
+    }
+
+    public void setExt4(String ext4) {
+        this.ext4 = ext4;
+    }
+
+    public String getExt5() {
+        return ext5;
+    }
+
+    public void setExt5(String ext5) {
+        this.ext5 = ext5;
+    }
+
+    @Override
+    public String getNodeId() {
+        if (null == this.id) {
+            return null;
+        }
+        return String.valueOf(this.id);
+    }
+
+    @Override
+    public void setNodeId(String nodeId) {
+        if (null == nodeId) {
+            this.id = null;
+        }
+        this.id = Long.parseLong(nodeId);
+    }
+
+    @Override
+    public String getNodeName() {
+        if (null == this.name) {
+            return null;
+        }
+        return String.valueOf(this.name);
+    }
+
+    @Override
+    public void setNodeName(String nodeName) {
+        this.name = nodeName;
+    }
+
+    @Override
+    public String getParentNodeId() {
+        if (null == this.parentId) {
+            return null;
+        }
+        return String.valueOf(this.parentId);
+    }
+
+    @Override
+    public void setParentNodeId(String parentNodeId) {
+        if (null == parentNodeId) {
+            this.parentId = null;
+        }
+        this.parentId = Long.parseLong(parentNodeId);
+    }
+
+    @Override
+    public String getNodeCode() {
+        return this.code;
+    }
+
+    @Override
+    public void setNodeCode(String code) {
+        this.code = code;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
 
 }

+ 40 - 44
src/main/java/cn/com/qmth/mps/entity/RoleEntity.java

@@ -7,49 +7,45 @@ import cn.com.qmth.mps.entity.base.AuditingEntity;
 @TableName("mps_role")
 public class RoleEntity extends AuditingEntity {
 
-	private static final long serialVersionUID = -2167420238674588632L;
-
-
-	/**
-	 * 角色码(全局唯一)
-	 */
-	private String code;
-
-	/**
-	 * 角色名称
-	 */
-	private String name;
-
-	/**
-	 * 顶级机构.为null时,为全局角色
-	 */
-	private Long 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 Long getSchoolId() {
-		return schoolId;
-	}
-
-	public void setSchoolId(Long schoolId) {
-		this.schoolId = schoolId;
-	}
-
-	
+    private static final long serialVersionUID = -2167420238674588632L;
+
+    /**
+     * 角色码(全局唯一)
+     */
+    private String code;
+
+    /**
+     * 角色名称
+     */
+    private String name;
+
+    /**
+     * 顶级机构.为null时,为全局角色
+     */
+    private Long 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 Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
 
 }

+ 27 - 25
src/main/java/cn/com/qmth/mps/entity/RolePrivilegeRelationEntity.java

@@ -4,41 +4,43 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import com.github.jeffreyning.mybatisplus.anno.MppMultiId;
 
 import cn.com.qmth.mps.entity.base.AuditingWithoutIdEntity;
+
 @TableName("mps_role_privilege_relation")
 public class RolePrivilegeRelationEntity extends AuditingWithoutIdEntity {
 
-	private static final long serialVersionUID = 8849214483955278647L;
+    private static final long serialVersionUID = 8849214483955278647L;
+
+    @MppMultiId
+    private Long schoolId;
 
-	@MppMultiId
-	private Long schoolId;
-	@MppMultiId
-	private Long roleId;
+    @MppMultiId
+    private Long roleId;
 
-	@MppMultiId
-	private Long privilegeId;
+    @MppMultiId
+    private Long privilegeId;
 
-	public Long getPrivilegeId() {
-		return privilegeId;
-	}
+    public Long getPrivilegeId() {
+        return privilegeId;
+    }
 
-	public void setPrivilegeId(Long privilegeId) {
-		this.privilegeId = privilegeId;
-	}
+    public void setPrivilegeId(Long privilegeId) {
+        this.privilegeId = privilegeId;
+    }
 
-	public Long getSchoolId() {
-		return schoolId;
-	}
+    public Long getSchoolId() {
+        return schoolId;
+    }
 
-	public void setSchoolId(Long schoolId) {
-		this.schoolId = schoolId;
-	}
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
 
-	public Long getRoleId() {
-		return roleId;
-	}
+    public Long getRoleId() {
+        return roleId;
+    }
 
-	public void setRoleId(Long roleId) {
-		this.roleId = roleId;
-	}
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
 
 }

+ 64 - 60
src/main/java/cn/com/qmth/mps/entity/SchoolEntity.java

@@ -3,86 +3,90 @@ package cn.com.qmth.mps.entity;
 import com.baomidou.mybatisplus.annotation.TableName;
 
 import cn.com.qmth.mps.entity.base.AuditingEntity;
+
 @TableName("mps_school")
 public class SchoolEntity extends AuditingEntity {
 
-	private static final long serialVersionUID = -592353272256492483L;
-	private String code;
-	private String name;
-	private Boolean enable;
+    private static final long serialVersionUID = -592353272256492483L;
+
+    private String code;
+
+    private String name;
+
+    private Boolean enable;
+
+    private String telephone;
+
+    private String contacts;
+
+    private String region;
 
-	private String telephone;
+    private String accessKey;
 
-	private String contacts;
-	
-	private String region;
-	
-	private String accessKey;
-	private String accessSecret;
+    private String accessSecret;
 
-	public String getName() {
-		return name;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public void setName(String name) {
+        this.name = name;
+    }
 
-	public Boolean getEnable() {
-		return enable;
-	}
+    public Boolean getEnable() {
+        return enable;
+    }
 
-	public void setEnable(Boolean enable) {
-		this.enable = enable;
-	}
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
 
-	public String getTelephone() {
-		return telephone;
-	}
+    public String getTelephone() {
+        return telephone;
+    }
 
-	public void setTelephone(String telephone) {
-		this.telephone = telephone;
-	}
+    public void setTelephone(String telephone) {
+        this.telephone = telephone;
+    }
 
-	public String getContacts() {
-		return contacts;
-	}
+    public String getContacts() {
+        return contacts;
+    }
 
-	public void setContacts(String contacts) {
-		this.contacts = contacts;
-	}
+    public void setContacts(String contacts) {
+        this.contacts = contacts;
+    }
 
-	public String getRegion() {
-		return region;
-	}
+    public String getRegion() {
+        return region;
+    }
 
-	public void setRegion(String region) {
-		this.region = region;
-	}
+    public void setRegion(String region) {
+        this.region = region;
+    }
 
-	public String getCode() {
-		return code;
-	}
+    public String getCode() {
+        return code;
+    }
 
-	public void setCode(String code) {
-		this.code = code;
-	}
+    public void setCode(String code) {
+        this.code = code;
+    }
 
-	public String getAccessKey() {
-		return accessKey;
-	}
+    public String getAccessKey() {
+        return accessKey;
+    }
 
-	public void setAccessKey(String accessKey) {
-		this.accessKey = accessKey;
-	}
+    public void setAccessKey(String accessKey) {
+        this.accessKey = accessKey;
+    }
 
-	public String getAccessSecret() {
-		return accessSecret;
-	}
+    public String getAccessSecret() {
+        return accessSecret;
+    }
 
-	public void setAccessSecret(String accessSecret) {
-		this.accessSecret = accessSecret;
-	}
+    public void setAccessSecret(String accessSecret) {
+        this.accessSecret = accessSecret;
+    }
 
-	
 }

+ 17 - 18
src/main/java/cn/com/qmth/mps/entity/UserCourseRelationEntity.java

@@ -8,29 +8,28 @@ import cn.com.qmth.mps.entity.base.AuditingWithoutIdEntity;
 @TableName("mps_user_course_relation")
 public class UserCourseRelationEntity extends AuditingWithoutIdEntity {
 
-	private static final long serialVersionUID = 8849214483955278647L;
+    private static final long serialVersionUID = 8849214483955278647L;
 
-	@MppMultiId
-	private Long userId;
+    @MppMultiId
+    private Long userId;
 
-	@MppMultiId
-	private Long courseId;
+    @MppMultiId
+    private Long courseId;
 
-	public Long getUserId() {
-		return userId;
-	}
+    public Long getUserId() {
+        return userId;
+    }
 
-	public void setUserId(Long userId) {
-		this.userId = userId;
-	}
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
 
-	public Long getCourseId() {
-		return courseId;
-	}
-
-	public void setCourseId(Long courseId) {
-		this.courseId = courseId;
-	}
+    public Long getCourseId() {
+        return courseId;
+    }
 
+    public void setCourseId(Long courseId) {
+        this.courseId = courseId;
+    }
 
 }

+ 49 - 45
src/main/java/cn/com/qmth/mps/entity/UserEntity.java

@@ -3,66 +3,70 @@ package cn.com.qmth.mps.entity;
 import com.baomidou.mybatisplus.annotation.TableName;
 
 import cn.com.qmth.mps.entity.base.AuditingEntity;
-@TableName(value="mps_user",autoResultMap = true)
+
+@TableName(value = "mps_user", autoResultMap = true)
 public class UserEntity extends AuditingEntity {
 
-	private static final long serialVersionUID = 6770398649449396459L;
-	private Long schoolId;
-	private String name;
-	private String loginName;
+    private static final long serialVersionUID = 6770398649449396459L;
+
+    private Long schoolId;
+
+    private String name;
+
+    private String loginName;
+
+    private String password;
 
-	private String password;
-	private Boolean enable;
-	private Long roleId;
+    private Boolean enable;
 
-	public Long getSchoolId() {
-		return schoolId;
-	}
+    private Long roleId;
 
-	public void setSchoolId(Long schoolId) {
-		this.schoolId = schoolId;
-	}
+    public Long getSchoolId() {
+        return schoolId;
+    }
 
-	public String getName() {
-		return name;
-	}
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public String getLoginName() {
-		return loginName;
-	}
+    public void setName(String name) {
+        this.name = name;
+    }
 
-	public void setLoginName(String loginName) {
-		this.loginName = loginName;
-	}
+    public String getLoginName() {
+        return loginName;
+    }
 
-	public String getPassword() {
-		return password;
-	}
+    public void setLoginName(String loginName) {
+        this.loginName = loginName;
+    }
 
-	public void setPassword(String password) {
-		this.password = password;
-	}
+    public String getPassword() {
+        return password;
+    }
 
-	public Boolean getEnable() {
-		return enable;
-	}
+    public void setPassword(String password) {
+        this.password = password;
+    }
 
-	public void setEnable(Boolean enable) {
-		this.enable = enable;
-	}
+    public Boolean getEnable() {
+        return enable;
+    }
 
-	public Long getRoleId() {
-		return roleId;
-	}
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
 
-	public void setRoleId(Long roleId) {
-		this.roleId = roleId;
-	}
+    public Long getRoleId() {
+        return roleId;
+    }
 
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
 
-	
 }

+ 27 - 20
src/main/java/cn/com/qmth/mps/entity/WxappAccessTokenEntity.java

@@ -4,25 +4,32 @@ import com.baomidou.mybatisplus.annotation.TableName;
 
 import cn.com.qmth.mps.entity.base.AuditingEntity;
 
-@TableName(value="mps_wxapp_access_token")
+@TableName(value = "mps_wxapp_access_token")
 public class WxappAccessTokenEntity extends AuditingEntity {
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 4999809253841553953L;
-	private String accessToken;
-	private Long expiresTime;
-	public String getAccessToken() {
-		return accessToken;
-	}
-	public void setAccessToken(String accessToken) {
-		this.accessToken = accessToken;
-	}
-	public Long getExpiresTime() {
-		return expiresTime;
-	}
-	public void setExpiresTime(Long expiresTime) {
-		this.expiresTime = expiresTime;
-	}
-	
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 4999809253841553953L;
+
+    private String accessToken;
+
+    private Long expiresTime;
+
+    public String getAccessToken() {
+        return accessToken;
+    }
+
+    public void setAccessToken(String accessToken) {
+        this.accessToken = accessToken;
+    }
+
+    public Long getExpiresTime() {
+        return expiresTime;
+    }
+
+    public void setExpiresTime(Long expiresTime) {
+        this.expiresTime = expiresTime;
+    }
+
 }

+ 22 - 19
src/main/java/cn/com/qmth/mps/entity/WxappInfoEntity.java

@@ -3,27 +3,30 @@ package cn.com.qmth.mps.entity;
 import com.baomidou.mybatisplus.annotation.TableName;
 
 import cn.com.qmth.mps.entity.base.AuditingEntity;
+
 @TableName("mps_wxapp_info")
 public class WxappInfoEntity extends AuditingEntity {
 
-	private static final long serialVersionUID = -6261302618070108336L;
-
-	private String openid;
-	private String phone;
-	public String getOpenid() {
-		return openid;
-	}
-	public void setOpenid(String openid) {
-		this.openid = openid;
-	}
-	public String getPhone() {
-		return phone;
-	}
-	public void setPhone(String phone) {
-		this.phone = phone;
-	}
-
-
-	
+    private static final long serialVersionUID = -6261302618070108336L;
+
+    private String openid;
+
+    private String phone;
+
+    public String getOpenid() {
+        return openid;
+    }
+
+    public void setOpenid(String openid) {
+        this.openid = openid;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
 
 }

+ 0 - 1
src/main/java/cn/com/qmth/mps/entity/base/AuditingEntity.java

@@ -22,7 +22,6 @@ public abstract class AuditingEntity extends IdEntity {
     @TableField(fill = FieldFill.INSERT_UPDATE)
     private Long updaterId;
 
-
     public Long getCreatorId() {
         return creatorId;
     }

+ 0 - 1
src/main/java/cn/com/qmth/mps/entity/base/AuditingWithoutIdEntity.java

@@ -22,7 +22,6 @@ public abstract class AuditingWithoutIdEntity extends BaseEntity {
     @TableField(fill = FieldFill.INSERT_UPDATE)
     private Long updaterId;
 
-
     public Long getCreatorId() {
         return creatorId;
     }

+ 0 - 2
src/main/java/cn/com/qmth/mps/entity/base/IdEntity.java

@@ -13,7 +13,6 @@ public abstract class IdEntity extends BaseEntity {
     @TableId(type = IdType.AUTO)
     protected Long id;
 
-
     public Long getId() {
         return id;
     }
@@ -22,5 +21,4 @@ public abstract class IdEntity extends BaseEntity {
         this.id = id;
     }
 
-
 }

+ 1 - 0
src/main/java/cn/com/qmth/mps/enums/ArbitrateMethod.java

@@ -6,6 +6,7 @@ package cn.com.qmth.mps.enums;
  * @Date: 2024-08-14
  */
 public enum ArbitrateMethod {
+
     GROUP_ARBITRATE("分组仲裁", 0), QUESTION_ARBITRATE("小题仲裁", 1);
 
     private final String name;

+ 1 - 1
src/main/java/cn/com/qmth/mps/enums/ExamStatus.java

@@ -2,7 +2,7 @@ package cn.com.qmth.mps.enums;
 
 public enum ExamStatus {
 
-	EDIT("开放上报"),
+    EDIT("开放上报"),
 
     FINISH("停止上报"),
 

+ 13 - 11
src/main/java/cn/com/qmth/mps/enums/Role.java

@@ -2,18 +2,20 @@ package cn.com.qmth.mps.enums;
 
 public enum Role {
 
-    SUPER_ADMIN(1L,"超级管理员"),
+    SUPER_ADMIN(1L, "超级管理员"),
 
-    SCHOOL_ADMIN(2L,"机构管理员"),
+    SCHOOL_ADMIN(2L, "机构管理员"),
 
-    SECTION_LEADER(3L,"科组长"),
+    SECTION_LEADER(3L, "科组长"),
 
     ;
-	private Long id;
+
+    private Long id;
+
     private String name;
 
-    Role(Long id,String name) {
-    	this.id = id;
+    Role(Long id, String name) {
+        this.id = id;
         this.name = name;
     }
 
@@ -21,12 +23,11 @@ public enum Role {
         return name;
     }
 
-    
     public Long getId() {
-		return id;
-	}
+        return id;
+    }
 
-	public static Role getByName(String name) {
+    public static Role getByName(String name) {
         for (Role r : Role.values()) {
             if (r.getName().equals(name)) {
                 return r;
@@ -34,7 +35,8 @@ public enum Role {
         }
         return null;
     }
-	public static Role getById(Long id) {
+
+    public static Role getById(Long id) {
         for (Role r : Role.values()) {
             if (r.getId().equals(id)) {
                 return r;

+ 44 - 0
src/main/java/cn/com/qmth/mps/exception/DisruptedException.java

@@ -0,0 +1,44 @@
+package cn.com.qmth.mps.exception;
+
+import com.qmth.boot.core.exception.CodeNameException;
+
+/**
+ * 中断异常,捕获异常后不继续业务代码
+ */
+public class DisruptedException extends RuntimeException implements CodeNameException {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 8998356815982621954L;
+
+    private Integer code;
+
+    private String name;
+
+    public DisruptedException(String message) {
+        super(message);
+    }
+
+    public DisruptedException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public DisruptedException(Integer code, String name, String message, Throwable cause) {
+        super(message, cause);
+        if (code == null || code >= 100 && code <= 999) {
+            this.code = code;
+            this.name = name;
+        } else {
+            throw new IllegalArgumentException("DisruptedException.code should between 100~999");
+        }
+    }
+
+    public Integer getCode() {
+        return this.code;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+}

+ 73 - 73
src/main/java/cn/com/qmth/mps/interceptor/FirstInterceptor.java

@@ -33,78 +33,78 @@ import cn.com.qmth.mps.util.ThreadLocalUtil;
  */
 public class FirstInterceptor implements HandlerInterceptor {
 
-	private static final Logger LOG = LoggerFactory.getLogger(FirstInterceptor.class);
-
-	@Override
-	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
-			throws Exception {
-		ThreadLocalUtil.clearAll();
-		String traceId = request.getHeader("Trace-Id");
-		if (StringUtils.isBlank(traceId)) {
-			traceId = ThreadLocalUtil.next();
-		} else {
-			ThreadLocalUtil.setTraceId(traceId);
-		}
-
-		// 设置log4j线程上下文
-		ThreadContext.put("TRACE_ID", traceId);
-		ThreadContext.put("CALLER", "$$$$$");
-
-		String path = request.getServletPath();
-		String method = request.getMethod();
-
-		Set<String> headerNames = new HashSet<>(20);
-
-		if (LOG.isDebugEnabled()) {
-			Map<String, String> headers = Maps.newHashMap();
-			Enumeration<String> e = request.getHeaderNames();
-			while (e.hasMoreElements()) {
-				String name = e.nextElement();
-				String value = request.getHeader(name);
-				headers.put(name, value);
-				headerNames.add(name);
-			}
-
-			LOG.debug(String.format("[%s] - %s, headers = %s", method, path, JsonUtil.toJson(headers)));
-		}
-
-		if (path.equals("/error")) {
-			response.setStatus(HttpStatus.NOT_FOUND.value());
-			ServletUtil.returnJson(new StatusResponse(HttpStatus.NOT_FOUND.value(),
-					HttpStatus.NOT_FOUND.getReasonPhrase()), response);
-			return false;
-		}
-
-		if ((!org.springframework.http.HttpMethod.OPTIONS.matches(method)) && handler instanceof HandlerMethod) {
-			HandlerMethod handlerMethod = (HandlerMethod) handler;
-
-			ApiInfo apiInfo = ApiInfoHolder.getApiInfo(handlerMethod.getMethod());
-
-			String mapping = apiInfo.getMapping();
-			request.setAttribute(HttpServletRequestAttribute.$_API_INFO.name(), apiInfo);
-
-			LOG.debug("[mapping] ==> " + mapping);
-			request.setAttribute(HttpServletRequestAttribute.$_MAPPING.name(), mapping);
-		} else {
-			String mapping = StringUtils.join("_[", path, "][", method, "]");
-
-			LOG.debug("[mapping] --> " + mapping);
-			request.setAttribute(HttpServletRequestAttribute.$_MAPPING.name(), mapping);
-		}
-
-		return true;
-	}
-
-	@Override
-	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
-			ModelAndView modelAndView) throws Exception {
-	}
-
-	@Override
-	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
-			throws Exception {
-		// 清理log4j线程上下文
-		ThreadContext.clearAll();
-	}
+    private static final Logger LOG = LoggerFactory.getLogger(FirstInterceptor.class);
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+            throws Exception {
+        ThreadLocalUtil.clearAll();
+        String traceId = request.getHeader("Trace-Id");
+        if (StringUtils.isBlank(traceId)) {
+            traceId = ThreadLocalUtil.next();
+        } else {
+            ThreadLocalUtil.setTraceId(traceId);
+        }
+
+        // 设置log4j线程上下文
+        ThreadContext.put("TRACE_ID", traceId);
+        ThreadContext.put("CALLER", "$$$$$");
+
+        String path = request.getServletPath();
+        String method = request.getMethod();
+
+        Set<String> headerNames = new HashSet<>(20);
+
+        if (LOG.isDebugEnabled()) {
+            Map<String, String> headers = Maps.newHashMap();
+            Enumeration<String> e = request.getHeaderNames();
+            while (e.hasMoreElements()) {
+                String name = e.nextElement();
+                String value = request.getHeader(name);
+                headers.put(name, value);
+                headerNames.add(name);
+            }
+
+            LOG.debug(String.format("[%s] - %s, headers = %s", method, path, JsonUtil.toJson(headers)));
+        }
+
+        if (path.equals("/error")) {
+            response.setStatus(HttpStatus.NOT_FOUND.value());
+            ServletUtil.returnJson(
+                    new StatusResponse(HttpStatus.NOT_FOUND.value(), HttpStatus.NOT_FOUND.getReasonPhrase()), response);
+            return false;
+        }
+
+        if ((!org.springframework.http.HttpMethod.OPTIONS.matches(method)) && handler instanceof HandlerMethod) {
+            HandlerMethod handlerMethod = (HandlerMethod) handler;
+
+            ApiInfo apiInfo = ApiInfoHolder.getApiInfo(handlerMethod.getMethod());
+
+            String mapping = apiInfo.getMapping();
+            request.setAttribute(HttpServletRequestAttribute.$_API_INFO.name(), apiInfo);
+
+            LOG.debug("[mapping] ==> " + mapping);
+            request.setAttribute(HttpServletRequestAttribute.$_MAPPING.name(), mapping);
+        } else {
+            String mapping = StringUtils.join("_[", path, "][", method, "]");
+
+            LOG.debug("[mapping] --> " + mapping);
+            request.setAttribute(HttpServletRequestAttribute.$_MAPPING.name(), mapping);
+        }
+
+        return true;
+    }
+
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
+            ModelAndView modelAndView) throws Exception {
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
+            throws Exception {
+        // 清理log4j线程上下文
+        ThreadContext.clearAll();
+    }
 
 }

+ 6 - 4
src/main/java/cn/com/qmth/mps/job/ClearTimeOutUserJob.java

@@ -8,11 +8,13 @@ import cn.com.qmth.mps.service.SessionService;
 
 @Service
 public class ClearTimeOutUserJob {
-	@Autowired
-	private SessionService sessionService;
-	@Scheduled(cron = "0/30 * * * * ?")
+
+    @Autowired
+    private SessionService sessionService;
+
+    @Scheduled(cron = "0/30 * * * * ?")
     public void clearTimeOutUser() {
-		sessionService.clearTimeOutUser();
+        sessionService.clearTimeOutUser();
     }
 
 }

+ 6 - 4
src/main/java/cn/com/qmth/mps/job/WxappAccessTokenJob.java

@@ -8,11 +8,13 @@ import cn.com.qmth.mps.service.AuthService;
 
 @Service
 public class WxappAccessTokenJob {
-	@Autowired
-	private AuthService authService;
-	@Scheduled(cron = "0/10 * * * * ?")
+
+    @Autowired
+    private AuthService authService;
+
+    @Scheduled(cron = "0/10 * * * * ?")
     public void modifyWxappAccessToken() {
-		authService.modifyWxappAccessToken();
+        authService.modifyWxappAccessToken();
     }
 
 }

+ 7 - 7
src/main/java/cn/com/qmth/mps/service/AuthService.java

@@ -5,16 +5,16 @@ import cn.com.qmth.mps.vo.AdminLoginVo;
 
 public interface AuthService {
 
-	AdminLoginVo loginWxAppCode(String wxappCode);
+    AdminLoginVo loginWxAppCode(String wxappCode);
 
-	AdminLoginVo loginAdmin(String loginName, String password);
+    AdminLoginVo loginAdmin(String loginName, String password);
 
-	void logout(User user);
+    void logout(User user);
 
-	void modifyWxappAccessToken();
+    void modifyWxappAccessToken();
 
-	AdminLoginVo loginWxAppByEncryptedData(String loginCode, String encryptedData, String iv);
-	
-	AdminLoginVo loginWxAppByPhoneCode(String loginCode,String phoneCode);
+    AdminLoginVo loginWxAppByEncryptedData(String loginCode, String encryptedData, String iv);
+
+    AdminLoginVo loginWxAppByPhoneCode(String loginCode, String phoneCode);
 
 }

+ 3 - 4
src/main/java/cn/com/qmth/mps/service/CourseService.java

@@ -4,11 +4,10 @@ import com.baomidou.mybatisplus.extension.service.IService;
 
 import cn.com.qmth.mps.entity.CourseEntity;
 
-public interface CourseService  extends IService<CourseEntity> {
+public interface CourseService extends IService<CourseEntity> {
 
-	CourseEntity getByCode(Long schoolId, String code);
-
-	CourseEntity saveOrGet(Long schoolId, String code, String name);
+    CourseEntity getByCode(Long schoolId, String code);
 
+    CourseEntity saveOrGet(Long schoolId, String code, String name);
 
 }

+ 7 - 7
src/main/java/cn/com/qmth/mps/service/ExamService.java

@@ -11,18 +11,18 @@ import cn.com.qmth.mps.vo.exam.ExamDomain;
 import cn.com.qmth.mps.vo.exam.ExamQuery;
 import cn.com.qmth.mps.vo.exam.ExamVo;
 
-public interface ExamService  extends IService<ExamEntity> {
+public interface ExamService extends IService<ExamEntity> {
 
-	void syncExam(Long schoolId, User accessUser);
+    void syncExam(Long schoolId, User accessUser);
 
-	void saveExam(ExamDomain domain, User accessUser);
+    void saveExam(ExamDomain domain, User accessUser);
 
-	PageResult<ExamVo> page(ExamQuery query, User accessUser);
+    PageResult<ExamVo> page(ExamQuery query, User accessUser);
 
-	List<ExamVo> unClose(User accessUser);
+    List<ExamVo> unClose(User accessUser);
 
-	ExamVo info(Long id, User accessUser);
+    ExamVo info(Long id, User accessUser);
 
-	void checkExamStatus(Long examId);
+    void checkExamStatus(Long examId);
 
 }

+ 6 - 7
src/main/java/cn/com/qmth/mps/service/PaperDetailService.java

@@ -9,17 +9,16 @@ import cn.com.qmth.mps.bean.User;
 import cn.com.qmth.mps.entity.PaperDetailEntity;
 import cn.com.qmth.mps.vo.paper.StructDomain;
 
-public interface PaperDetailService  extends IService<PaperDetailEntity> {
+public interface PaperDetailService extends IService<PaperDetailEntity> {
 
-	List<PaperDetail> getStructInfo(Long paperId);
+    List<PaperDetail> getStructInfo(Long paperId);
 
-	List<PaperDetailEntity> getByPaperId(Long paperId);
+    List<PaperDetailEntity> getByPaperId(Long paperId);
 
-	void structSave(StructDomain domain, User accessUser);
+    void structSave(StructDomain domain, User accessUser);
 
-	void structSubmit(StructDomain domain, User accessUser);
-
-	void structImport(StructDomain domain, User user);
+    void structSubmit(StructDomain domain, User accessUser);
 
+    void structImport(StructDomain domain, User user);
 
 }

+ 5 - 6
src/main/java/cn/com/qmth/mps/service/PaperDetailUnitService.java

@@ -9,15 +9,14 @@ import cn.com.qmth.mps.bean.PaperDetailUnit;
 import cn.com.qmth.mps.entity.PaperDetailEntity;
 import cn.com.qmth.mps.entity.PaperDetailUnitEntity;
 
-public interface PaperDetailUnitService  extends IService<PaperDetailUnitEntity> {
+public interface PaperDetailUnitService extends IService<PaperDetailUnitEntity> {
 
-	Map<Long, List<PaperDetailUnit>> getStructInfo(Long paperId);
+    Map<Long, List<PaperDetailUnit>> getStructInfo(Long paperId);
 
-	Integer countByPaperId(Long paperId);
+    Integer countByPaperId(Long paperId);
 
-	void clearByPaperId(Long paperId);
-
-	void saveUnit(PaperDetailEntity e, List<PaperDetailUnit> units);
+    void clearByPaperId(Long paperId);
 
+    void saveUnit(PaperDetailEntity e, List<PaperDetailUnit> units);
 
 }

+ 9 - 9
src/main/java/cn/com/qmth/mps/service/PaperGroupService.java

@@ -14,22 +14,22 @@ import cn.com.qmth.mps.vo.paper.GroupInfoVo;
 import cn.com.qmth.mps.vo.paper.GroupVo;
 import cn.com.qmth.mps.vo.paper.PaperGroupDomain;
 
-public interface PaperGroupService  extends IService<PaperGroupEntity> {
+public interface PaperGroupService extends IService<PaperGroupEntity> {
 
-	List<GroupCountVo> findGroupCount(@Param(value = "paperIds")List<Long> paperIds);
+    List<GroupCountVo> findGroupCount(@Param(value = "paperIds") List<Long> paperIds);
 
-	List<PaperGroup> getGroupInfo(Long paperId);
+    List<PaperGroup> getGroupInfo(Long paperId);
 
-	List<GroupVo> groupList(Long paperId, User accessUser);
+    List<GroupVo> groupList(Long paperId, User accessUser);
 
-	GroupInfoVo groupInfo(Long paperId, Integer groupNumber, User accessUser);
+    GroupInfoVo groupInfo(Long paperId, Integer groupNumber, User accessUser);
 
-	void groupSave(PaperGroupDomain domain, User accessUser);
+    void groupSave(PaperGroupDomain domain, User accessUser);
 
-	void groupDelete(Long groupId, User accessUser);
+    void groupDelete(Long groupId, User accessUser);
 
-	Boolean existsGroup(Long paperId);
+    Boolean existsGroup(Long paperId);
 
-	void groupClear(Long paperId, User accessUser);
+    void groupClear(Long paperId, User accessUser);
 
 }

+ 7 - 7
src/main/java/cn/com/qmth/mps/service/PaperGroupUnitService.java

@@ -9,18 +9,18 @@ import cn.com.qmth.mps.bean.PaperGroupUnit;
 import cn.com.qmth.mps.entity.PaperGroupEntity;
 import cn.com.qmth.mps.entity.PaperGroupUnitEntity;
 
-public interface PaperGroupUnitService  extends IService<PaperGroupUnitEntity> {
+public interface PaperGroupUnitService extends IService<PaperGroupUnitEntity> {
 
-	Map<Long, List<PaperGroupUnit>> getGroupInfo(Long paperId);
+    Map<Long, List<PaperGroupUnit>> getGroupInfo(Long paperId);
 
-	void removeByGroupId(Long groupId);
+    void removeByGroupId(Long groupId);
 
-	void saveUnit(Long groupId, Long paperId, List<PaperGroupUnit> groupUnits);
+    void saveUnit(Long groupId, Long paperId, List<PaperGroupUnit> groupUnits);
 
-	Integer countByPaperId(Long paperId);
+    Integer countByPaperId(Long paperId);
 
-	void clearByPaperId(Long paperId);
+    void clearByPaperId(Long paperId);
 
-	List<PaperGroupUnitEntity> getByPaperId(Long paperId);
+    List<PaperGroupUnitEntity> getByPaperId(Long paperId);
 
 }

+ 9 - 9
src/main/java/cn/com/qmth/mps/service/PaperService.java

@@ -15,22 +15,22 @@ import cn.com.qmth.mps.vo.paper.PaperQuery;
 import cn.com.qmth.mps.vo.paper.PaperStructInfoVo;
 import cn.com.qmth.mps.vo.paper.PaperVo;
 
-public interface PaperService  extends IService<PaperEntity> {
+public interface PaperService extends IService<PaperEntity> {
 
-	List<String> importPaper(Long examId, User accessUser, MultipartFile file);
+    List<String> importPaper(Long examId, User accessUser, MultipartFile file);
 
-	List<ExamPaperCountVo> findPaperCount(List<Long> examIds);
+    List<ExamPaperCountVo> findPaperCount(List<Long> examIds);
 
-	Integer findPaperCount(Long examId);
+    Integer findPaperCount(Long examId);
 
-	PageResult<PaperVo> page(PaperQuery query, User accessUser);
+    PageResult<PaperVo> page(PaperQuery query, User accessUser);
 
-	List<PaperVo> list(Long examId, User accessUser);
+    List<PaperVo> list(Long examId, User accessUser);
 
-	PaperInfoVo info(Long id, User accessUser);
+    PaperInfoVo info(Long id, User accessUser);
 
-	List<String> importSubjectStruct(Long examId, User accessUser, MultipartFile file);
+    List<String> importSubjectStruct(Long examId, User accessUser, MultipartFile file);
 
-	List<PaperStructInfoVo> subjectiveList(PaperQuery query,User user);
+    List<PaperStructInfoVo> subjectiveList(PaperQuery query, User user);
 
 }

+ 6 - 6
src/main/java/cn/com/qmth/mps/service/SchoolService.java

@@ -11,16 +11,16 @@ import cn.com.qmth.mps.vo.school.SchoolDomain;
 import cn.com.qmth.mps.vo.school.SchoolQuery;
 import cn.com.qmth.mps.vo.school.SchoolVo;
 
-public interface SchoolService  extends IService<SchoolEntity> {
+public interface SchoolService extends IService<SchoolEntity> {
 
-	void syncSchool(User accessUser);
+    void syncSchool(User accessUser);
 
-	void saveSchool(User accessUser, SchoolDomain domain);
+    void saveSchool(User accessUser, SchoolDomain domain);
 
-	PageResult<SchoolVo> page(SchoolQuery query, User accessUser);
+    PageResult<SchoolVo> page(SchoolQuery query, User accessUser);
 
-	SchoolVo info(Long id, User accessUser);
+    SchoolVo info(Long id, User accessUser);
 
-	void toggle(List<Long> ids, Boolean enable, User accessUser);
+    void toggle(List<Long> ids, Boolean enable, User accessUser);
 
 }

+ 6 - 6
src/main/java/cn/com/qmth/mps/service/SessionService.java

@@ -4,16 +4,16 @@ import cn.com.qmth.mps.bean.User;
 
 public interface SessionService {
 
-	Long updateUserSession(User user);
+    Long updateUserSession(User user);
 
-	void clearTimeOutUser();
+    void clearTimeOutUser();
 
-	void userLogout(User user);
+    void userLogout(User user);
 
-	void userLogin(User user);
+    void userLogin(User user);
 
-	User getSessionUser(String sessionId);
+    User getSessionUser(String sessionId);
 
-	int getOnlineCount();
+    int getOnlineCount();
 
 }

+ 5 - 5
src/main/java/cn/com/qmth/mps/service/UserCourseRelationService.java

@@ -7,14 +7,14 @@ import com.github.jeffreyning.mybatisplus.service.IMppService;
 import cn.com.qmth.mps.bean.CourseInfo;
 import cn.com.qmth.mps.entity.UserCourseRelationEntity;
 
-public interface UserCourseRelationService  extends IMppService<UserCourseRelationEntity> {
+public interface UserCourseRelationService extends IMppService<UserCourseRelationEntity> {
 
-	void saveCourse(Long schoolId,Long userId, List<String> course);
+    void saveCourse(Long schoolId, Long userId, List<String> course);
 
-	void removeCourse(Long id);
+    void removeCourse(Long id);
 
-	List<CourseInfo> getCourses(Long userId);
+    List<CourseInfo> getCourses(Long userId);
 
-	void clearBySchool(Long schoolId);
+    void clearBySchool(Long schoolId);
 
 }

+ 10 - 11
src/main/java/cn/com/qmth/mps/service/UserService.java

@@ -13,25 +13,24 @@ import cn.com.qmth.mps.vo.user.UserDomain;
 import cn.com.qmth.mps.vo.user.UserQuery;
 import cn.com.qmth.mps.vo.user.UserVo;
 
-public interface UserService  extends IService<UserEntity> {
+public interface UserService extends IService<UserEntity> {
 
-	UserEntity getByLoginName(String phone);
+    UserEntity getByLoginName(String phone);
 
-	void saveUser(UserDomain domain,User user);
+    void saveUser(UserDomain domain, User user);
 
-	List<String> importUser(Long schoolId,User user, MultipartFile file);
+    List<String> importUser(Long schoolId, User user, MultipartFile file);
 
-	PageResult<UserVo> page(UserQuery query, User user);
+    PageResult<UserVo> page(UserQuery query, User user);
 
-	UserVo info(Long id);
+    UserVo info(Long id);
 
-	void toggle(List<Long> ids, Boolean enable, User user);
+    void toggle(List<Long> ids, Boolean enable, User user);
 
-	void updatePass(String password, User accessUser);
+    void updatePass(String password, User accessUser);
 
-	void resetPass(Long userId, String passwd, User accessUser);
-
-	UserVo myInfo(User accessUser);
+    void resetPass(Long userId, String passwd, User accessUser);
 
+    UserVo myInfo(User accessUser);
 
 }

+ 3 - 3
src/main/java/cn/com/qmth/mps/service/WxappAccessTokenService.java

@@ -5,10 +5,10 @@ import com.qmth.boot.core.solar.model.WxappAccessToken;
 
 import cn.com.qmth.mps.entity.WxappAccessTokenEntity;
 
-public interface WxappAccessTokenService  extends IService<WxappAccessTokenEntity> {
+public interface WxappAccessTokenService extends IService<WxappAccessTokenEntity> {
 
-	WxappAccessToken getWxappAccessToken();
+    WxappAccessToken getWxappAccessToken();
 
-	void saveWxappAccessToken(String accessToken, Long expiresTime);
+    void saveWxappAccessToken(String accessToken, Long expiresTime);
 
 }

+ 2 - 3
src/main/java/cn/com/qmth/mps/service/WxappInfoService.java

@@ -4,9 +4,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 
 import cn.com.qmth.mps.entity.WxappInfoEntity;
 
-public interface WxappInfoService  extends IService<WxappInfoEntity> {
-
-	WxappInfoEntity getByOpenId(String openid);
+public interface WxappInfoService extends IService<WxappInfoEntity> {
 
+    WxappInfoEntity getByOpenId(String openid);
 
 }

+ 287 - 279
src/main/java/cn/com/qmth/mps/service/impl/AuthServiceImpl.java

@@ -44,292 +44,300 @@ import sun.misc.BASE64Decoder;
 @AuthorizationComponent
 @Service
 public class AuthServiceImpl implements AuthorizationService<User>, AuthService {
-	@Autowired
-	private SchoolService schoolService;
-	@Autowired
-	private UserService userService;
-	@Autowired
-	private SessionService sessionService;
-	@Autowired
-	private WxappAccessTokenService wxappAccessTokenService;
-	@Autowired
-	private SysProperty sysProperty;
-	@Autowired
-	private WxappInfoService wxappInfoService;
-	@Autowired
-	private SolarService solarService;
 
-	
-	@Override
-	public AdminLoginVo loginWxAppCode(String loginCode) {
-		WxappSession ws=solarService.getWxappSessionByCode(sysProperty.getWxappAppid(), loginCode);
-		String openid=ByteUtil.toHexAscii(SHA256.encode(ws.getOpenId()));
-		WxappInfoEntity wi=wxappInfoService.getByOpenId(openid);
-		if(wi==null) {
-			throw ParameterExceptions.OPENID_NOT_FOUND;
-		}
-		UserEntity userEntity = userService.getByLoginName(wi.getPhone());
-		if (userEntity == null) {
-			throw new StatusException("微信所绑定手机号系统中不存在");
-		}
-		if (!userEntity.getEnable()) {
-			throw new StatusException("该用户已禁用");
-		}
-		if (!userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
-			throw new StatusException("该用户不是科组长");
-		}
-		SchoolEntity school=schoolService.getById(userEntity.getSchoolId());
-		if (!school.getEnable()) {
-			throw new StatusException("该学校已禁用");
-		}
-		User user = new User();
-		user.setLoginName(userEntity.getLoginName());
-		user.setName(userEntity.getName());
-		user.setSchoolId(userEntity.getSchoolId());
-		user.setId(userEntity.getId());
-		user.setRole(Role.getById(userEntity.getRoleId()));
-		user.setAccessToken(FastUUID.get());
-		user.buildKey();
-		sessionService.userLogin(user);
-		AdminLoginVo vo = new AdminLoginVo();
-		vo.setAccessToken(user.getAccessToken());
-		vo.setName(user.getName());
-		vo.setSessionId(user.getSessionId());
-		vo.setSchoolId(user.getSchoolId());
-		vo.setRole(user.getRole());
-		vo.setSchoolName(school.getName());
-		return vo;
-	}
+    @Autowired
+    private SchoolService schoolService;
 
-	@Override
-	public AdminLoginVo loginAdmin(String loginName, String password) {
-		UserEntity userEntity = userService.getByLoginName(loginName);
-		if (userEntity == null) {
-			throw new StatusException("账号不存在");
-		}
-		if (!userEntity.getEnable()) {
-			throw new StatusException("该用户已禁用");
-		}
-		if (userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
-			throw new StatusException("科组长无权限登录");
-		}
-		SchoolEntity school=schoolService.getById(userEntity.getSchoolId());
-		if (!school.getEnable()) {
-			throw new StatusException("该学校已禁用");
-		}
-		byte[] bytes = SHA256.encode(password);
-		String encodePassword = ByteUtil.toHexAscii(bytes);
-		if (!encodePassword.equals(userEntity.getPassword())) {
-			throw new StatusException("密码错误");
-		}
-		User user = new User();
-		user.setLoginName(userEntity.getLoginName());
-		user.setName(userEntity.getName());
-		user.setSchoolId(userEntity.getSchoolId());
-		user.setId(userEntity.getId());
-		user.setRole(Role.getById(userEntity.getRoleId()));
-		user.setAccessToken(FastUUID.get());
-		user.buildKey();
-		sessionService.userLogin(user);
-		AdminLoginVo vo = new AdminLoginVo();
-		vo.setAccessToken(user.getAccessToken());
-		vo.setName(user.getName());
-		vo.setSessionId(user.getSessionId());
-		vo.setSchoolId(user.getSchoolId());
-		vo.setRole(user.getRole());
-		vo.setSchoolName(school.getName());
-		return vo;
-	}
+    @Autowired
+    private UserService userService;
 
-	@Override
-	public void logout(User user) {
-		sessionService.userLogout(user);
-	}
+    @Autowired
+    private SessionService sessionService;
 
-	@Override
-	public User findByIdentity(String identity, SignatureType type, String path) {
-		User user = sessionService.getSessionUser(identity);
-		return user;
-	}
+    @Autowired
+    private WxappAccessTokenService wxappAccessTokenService;
 
-	@Override
-	public boolean hasPermission(User user, String path) {
-		sessionService.updateUserSession(user);
-		return true;
-	}
-	
-	@Override
-	public void modifyWxappAccessToken() {
-		WxappAccessToken token = wxappAccessTokenService.getWxappAccessToken();
-		long now = System.currentTimeMillis();
-		if (StringUtils.isEmpty(token.getAccessToken()) || token.getExpireTime() - now <= 0) {
-			WxappAccessToken wt=solarService.getWxappAccessToken(sysProperty.getWxappAppid());
-			wxappAccessTokenService.saveWxappAccessToken(wt.getAccessToken(),wt.getExpireTime());
-		}
-	}
-	
-//	@Override
-//	public void modifyWxappAccessToken() {
-//		WxappAccessTokenEntity token = wxappAccessTokenService.getWxappAccessToken();
-//		long now = System.currentTimeMillis();
-//		if (StringUtils.isEmpty(token.getAccessToken()) || token.getExpiresTime() - now <= 15 * 60 * 1000) {
-//			Map<String, String> params = new HashMap<>();
-//			params.put("appid", sysProperty.getWxappAppid());
-//			params.put("secret", sysProperty.getWxappSecret());
-//			params.put("grant_type", "client_credential");
-//			String ret;
-//			try {
-//				ret = HttpUtil.httpsActionGet("https://api.weixin.qq.com/cgi-bin/token", null, params);
-//			} catch (Exception e) {
-//				throw new StatusException("获取失败", e);
-//			}
-//			JSONObject jo = JSONObject.fromObject(ret);
-//			if (jo.containsKey("errcode")) {
-//				throw new StatusException("获取失败," + jo.getString("errmsg"));
-//			}
-//			int ex = jo.getInt("expires_in");
-//			String at = jo.getString("access_token");
-//			token.setAccessToken(at);
-//			token.setExpiresTime(now + ex * 1000);
-//			wxappAccessTokenService.updateById(token);
-//		}
-//	}
+    @Autowired
+    private SysProperty sysProperty;
 
-	@Transactional
-	@Override
-	public AdminLoginVo loginWxAppByEncryptedData(String loginCode, String encryptedData, String iv) {
-		WxappSession ws=solarService.getWxappSessionByCode(sysProperty.getWxappAppid(), loginCode);
-		String openid=ByteUtil.toHexAscii(SHA256.encode(ws.getOpenId()));
-		JSONObject jo=decrypt(encryptedData, iv, ws.getSessionKey());
-		String phone=jo.getString("purePhoneNumber");
-		UserEntity userEntity = userService.getByLoginName(phone);
-		if (userEntity == null) {
-			throw new StatusException("微信所绑定手机号系统中不存在");
-		}
-		if (!userEntity.getEnable()) {
-			throw new StatusException("该用户已禁用");
-		}
-		if (!userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
-			throw new StatusException("该用户不是科组长");
-		}
-		SchoolEntity school=schoolService.getById(userEntity.getSchoolId());
-		if (!school.getEnable()) {
-			throw new StatusException("该学校已禁用");
-		}
-		WxappInfoEntity wi=wxappInfoService.getByOpenId(openid);
-		if(wi==null) {
-			wi=new WxappInfoEntity();
-			wi.setOpenid(openid);
-		}
-		wi.setPhone(phone);
-		wxappInfoService.saveOrUpdate(wi);
-		User user = new User();
-		user.setLoginName(userEntity.getLoginName());
-		user.setName(userEntity.getName());
-		user.setSchoolId(userEntity.getSchoolId());
-		user.setId(userEntity.getId());
-		user.setRole(Role.getById(userEntity.getRoleId()));
-		user.setAccessToken(FastUUID.get());
-		user.buildKey();
-		sessionService.userLogin(user);
-		AdminLoginVo vo = new AdminLoginVo();
-		vo.setAccessToken(user.getAccessToken());
-		vo.setName(user.getName());
-		vo.setSessionId(user.getSessionId());
-		vo.setSchoolId(user.getSchoolId());
-		vo.setRole(user.getRole());
-		vo.setSchoolName(school.getName());
-		return vo;
-	}
+    @Autowired
+    private WxappInfoService wxappInfoService;
 
+    @Autowired
+    private SolarService solarService;
 
-	private JSONObject decrypt(String encryptedData, String iv, String sessionKey){
-		String cipherString = "AES/CBC/PKCS5Padding";
-		String jsonStr;
-		try {
-			BASE64Decoder base64Decoder = new BASE64Decoder();
-			/**
-			 * 小程序加密数据解密算法
-			 * https://developers.weixin.qq.com/miniprogram/dev/api/signature.html#wxchecksessionobject
-			 * 1.对称解密的目标密文为 Base64_Decode(encryptedData)。 2.对称解密秘钥 aeskey =
-			 * Base64_Decode(session_key), aeskey 是16字节。 3.对称解密算法初始向量
-			 * 为Base64_Decode(iv),其中iv由数据接口返回。
-			 */
-			byte[] encryptedByte = base64Decoder.decodeBuffer(encryptedData);
-			byte[] sessionKeyByte = base64Decoder.decodeBuffer(sessionKey);
-			byte[] ivByte = base64Decoder.decodeBuffer(iv);
-			/**
-			 * 以下为AES-128-CBC解密算法
-			 */
-			SecretKeySpec skeySpec = new SecretKeySpec(sessionKeyByte, "AES");
-			Cipher cipher = Cipher.getInstance(cipherString);
-			IvParameterSpec ivParameterSpec = new IvParameterSpec(ivByte);
-			cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);
-			byte[] original = cipher.doFinal(encryptedByte);
-			jsonStr = new String(original);
-		} catch (Exception e) {
-			throw new StatusException("登录失败,信息有误 ",e);
-		}
-		JSONObject jsonObject = JSONObject.fromObject(jsonStr);
-		return jsonObject;
-	}
+    @Override
+    public AdminLoginVo loginWxAppCode(String loginCode) {
+        WxappSession ws = solarService.getWxappSessionByCode(sysProperty.getWxappAppid(), loginCode);
+        String openid = ByteUtil.toHexAscii(SHA256.encode(ws.getOpenId()));
+        WxappInfoEntity wi = wxappInfoService.getByOpenId(openid);
+        if (wi == null) {
+            throw ParameterExceptions.OPENID_NOT_FOUND;
+        }
+        UserEntity userEntity = userService.getByLoginName(wi.getPhone());
+        if (userEntity == null) {
+            throw new StatusException("微信所绑定手机号系统中不存在");
+        }
+        if (!userEntity.getEnable()) {
+            throw new StatusException("该用户已禁用");
+        }
+        if (!userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
+            throw new StatusException("该用户不是科组长");
+        }
+        SchoolEntity school = schoolService.getById(userEntity.getSchoolId());
+        if (!school.getEnable()) {
+            throw new StatusException("该学校已禁用");
+        }
+        User user = new User();
+        user.setLoginName(userEntity.getLoginName());
+        user.setName(userEntity.getName());
+        user.setSchoolId(userEntity.getSchoolId());
+        user.setId(userEntity.getId());
+        user.setRole(Role.getById(userEntity.getRoleId()));
+        user.setAccessToken(FastUUID.get());
+        user.buildKey();
+        sessionService.userLogin(user);
+        AdminLoginVo vo = new AdminLoginVo();
+        vo.setAccessToken(user.getAccessToken());
+        vo.setName(user.getName());
+        vo.setSessionId(user.getSessionId());
+        vo.setSchoolId(user.getSchoolId());
+        vo.setRole(user.getRole());
+        vo.setSchoolName(school.getName());
+        return vo;
+    }
 
-	@Transactional
-	@Override
-	public AdminLoginVo loginWxAppByPhoneCode(String loginCode,String phoneCode) {
-		Map<String, String> params = new HashMap<>();
-		params.put("code", phoneCode);
-		String ret;
-		try {
-			ret = HttpUtil.httpsActionPost("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="
-					+ wxappAccessTokenService.getWxappAccessToken().getAccessToken(), null, params);
-		} catch (Exception e) {
-			throw new StatusException("登录失败", e);
-		}
-		JSONObject jo = JSONObject.fromObject(ret);
-		if (jo.getInt("errcode") != 0) {
-			throw new StatusException("登录失败," + jo.getString("errmsg"));
-		}
-		String phone=jo.getJSONObject("phone_info").getString("purePhoneNumber");
-		UserEntity userEntity = userService.getByLoginName(phone);
-		if (userEntity == null) {
-			throw new StatusException("微信所绑定手机号系统中不存在");
-		}
-		if (!userEntity.getEnable()) {
-			throw new StatusException("该用户已禁用");
-		}
-		if (!userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
-			throw new StatusException("该用户不是科组长");
-		}
-		SchoolEntity school=schoolService.getById(userEntity.getSchoolId());
-		if (!school.getEnable()) {
-			throw new StatusException("该学校已禁用");
-		}
-		WxappSession ws=solarService.getWxappSessionByCode(sysProperty.getWxappAppid(), loginCode);
-		String openid=ByteUtil.toHexAscii(SHA256.encode(ws.getOpenId()));
-		WxappInfoEntity wi=wxappInfoService.getByOpenId(openid);
-		if(wi==null) {
-			wi=new WxappInfoEntity();
-			wi.setOpenid(openid);
-		}
-		wi.setPhone(phone);
-		wxappInfoService.saveOrUpdate(wi);
-		User user = new User();
-		user.setLoginName(userEntity.getLoginName());
-		user.setName(userEntity.getName());
-		user.setSchoolId(userEntity.getSchoolId());
-		user.setId(userEntity.getId());
-		user.setRole(Role.getById(userEntity.getRoleId()));
-		user.setAccessToken(FastUUID.get());
-		user.buildKey();
-		sessionService.userLogin(user);
-		AdminLoginVo vo = new AdminLoginVo();
-		vo.setAccessToken(user.getAccessToken());
-		vo.setName(user.getName());
-		vo.setSessionId(user.getSessionId());
-		vo.setSchoolId(user.getSchoolId());
-		vo.setRole(user.getRole());
-		vo.setSchoolName(school.getName());
-		return vo;
-	}
+    @Override
+    public AdminLoginVo loginAdmin(String loginName, String password) {
+        UserEntity userEntity = userService.getByLoginName(loginName);
+        if (userEntity == null) {
+            throw new StatusException("账号不存在");
+        }
+        if (!userEntity.getEnable()) {
+            throw new StatusException("该用户已禁用");
+        }
+        if (userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
+            throw new StatusException("科组长无权限登录");
+        }
+        SchoolEntity school = schoolService.getById(userEntity.getSchoolId());
+        if (!school.getEnable()) {
+            throw new StatusException("该学校已禁用");
+        }
+        byte[] bytes = SHA256.encode(password);
+        String encodePassword = ByteUtil.toHexAscii(bytes);
+        if (!encodePassword.equals(userEntity.getPassword())) {
+            throw new StatusException("密码错误");
+        }
+        User user = new User();
+        user.setLoginName(userEntity.getLoginName());
+        user.setName(userEntity.getName());
+        user.setSchoolId(userEntity.getSchoolId());
+        user.setId(userEntity.getId());
+        user.setRole(Role.getById(userEntity.getRoleId()));
+        user.setAccessToken(FastUUID.get());
+        user.buildKey();
+        sessionService.userLogin(user);
+        AdminLoginVo vo = new AdminLoginVo();
+        vo.setAccessToken(user.getAccessToken());
+        vo.setName(user.getName());
+        vo.setSessionId(user.getSessionId());
+        vo.setSchoolId(user.getSchoolId());
+        vo.setRole(user.getRole());
+        vo.setSchoolName(school.getName());
+        return vo;
+    }
+
+    @Override
+    public void logout(User user) {
+        sessionService.userLogout(user);
+    }
+
+    @Override
+    public User findByIdentity(String identity, SignatureType type, String path) {
+        User user = sessionService.getSessionUser(identity);
+        return user;
+    }
+
+    @Override
+    public boolean hasPermission(User user, String path) {
+        sessionService.updateUserSession(user);
+        return true;
+    }
+
+    @Override
+    public void modifyWxappAccessToken() {
+        WxappAccessToken token = wxappAccessTokenService.getWxappAccessToken();
+        long now = System.currentTimeMillis();
+        if (StringUtils.isEmpty(token.getAccessToken()) || token.getExpireTime() - now <= 0) {
+            WxappAccessToken wt = solarService.getWxappAccessToken(sysProperty.getWxappAppid());
+            wxappAccessTokenService.saveWxappAccessToken(wt.getAccessToken(), wt.getExpireTime());
+        }
+    }
+
+    // @Override
+    // public void modifyWxappAccessToken() {
+    // WxappAccessTokenEntity token =
+    // wxappAccessTokenService.getWxappAccessToken();
+    // long now = System.currentTimeMillis();
+    // if (StringUtils.isEmpty(token.getAccessToken()) || token.getExpiresTime()
+    // - now <= 15 * 60 * 1000) {
+    // Map<String, String> params = new HashMap<>();
+    // params.put("appid", sysProperty.getWxappAppid());
+    // params.put("secret", sysProperty.getWxappSecret());
+    // params.put("grant_type", "client_credential");
+    // String ret;
+    // try {
+    // ret = HttpUtil.httpsActionGet("https://api.weixin.qq.com/cgi-bin/token",
+    // null, params);
+    // } catch (Exception e) {
+    // throw new StatusException("获取失败", e);
+    // }
+    // JSONObject jo = JSONObject.fromObject(ret);
+    // if (jo.containsKey("errcode")) {
+    // throw new StatusException("获取失败," + jo.getString("errmsg"));
+    // }
+    // int ex = jo.getInt("expires_in");
+    // String at = jo.getString("access_token");
+    // token.setAccessToken(at);
+    // token.setExpiresTime(now + ex * 1000);
+    // wxappAccessTokenService.updateById(token);
+    // }
+    // }
+
+    @Transactional
+    @Override
+    public AdminLoginVo loginWxAppByEncryptedData(String loginCode, String encryptedData, String iv) {
+        WxappSession ws = solarService.getWxappSessionByCode(sysProperty.getWxappAppid(), loginCode);
+        String openid = ByteUtil.toHexAscii(SHA256.encode(ws.getOpenId()));
+        JSONObject jo = decrypt(encryptedData, iv, ws.getSessionKey());
+        String phone = jo.getString("purePhoneNumber");
+        UserEntity userEntity = userService.getByLoginName(phone);
+        if (userEntity == null) {
+            throw new StatusException("微信所绑定手机号系统中不存在");
+        }
+        if (!userEntity.getEnable()) {
+            throw new StatusException("该用户已禁用");
+        }
+        if (!userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
+            throw new StatusException("该用户不是科组长");
+        }
+        SchoolEntity school = schoolService.getById(userEntity.getSchoolId());
+        if (!school.getEnable()) {
+            throw new StatusException("该学校已禁用");
+        }
+        WxappInfoEntity wi = wxappInfoService.getByOpenId(openid);
+        if (wi == null) {
+            wi = new WxappInfoEntity();
+            wi.setOpenid(openid);
+        }
+        wi.setPhone(phone);
+        wxappInfoService.saveOrUpdate(wi);
+        User user = new User();
+        user.setLoginName(userEntity.getLoginName());
+        user.setName(userEntity.getName());
+        user.setSchoolId(userEntity.getSchoolId());
+        user.setId(userEntity.getId());
+        user.setRole(Role.getById(userEntity.getRoleId()));
+        user.setAccessToken(FastUUID.get());
+        user.buildKey();
+        sessionService.userLogin(user);
+        AdminLoginVo vo = new AdminLoginVo();
+        vo.setAccessToken(user.getAccessToken());
+        vo.setName(user.getName());
+        vo.setSessionId(user.getSessionId());
+        vo.setSchoolId(user.getSchoolId());
+        vo.setRole(user.getRole());
+        vo.setSchoolName(school.getName());
+        return vo;
+    }
+
+    private JSONObject decrypt(String encryptedData, String iv, String sessionKey) {
+        String cipherString = "AES/CBC/PKCS5Padding";
+        String jsonStr;
+        try {
+            BASE64Decoder base64Decoder = new BASE64Decoder();
+            /**
+             * 小程序加密数据解密算法
+             * https://developers.weixin.qq.com/miniprogram/dev/api/signature.html#wxchecksessionobject
+             * 1.对称解密的目标密文为 Base64_Decode(encryptedData)。 2.对称解密秘钥 aeskey =
+             * Base64_Decode(session_key), aeskey 是16字节。 3.对称解密算法初始向量
+             * 为Base64_Decode(iv),其中iv由数据接口返回。
+             */
+            byte[] encryptedByte = base64Decoder.decodeBuffer(encryptedData);
+            byte[] sessionKeyByte = base64Decoder.decodeBuffer(sessionKey);
+            byte[] ivByte = base64Decoder.decodeBuffer(iv);
+            /**
+             * 以下为AES-128-CBC解密算法
+             */
+            SecretKeySpec skeySpec = new SecretKeySpec(sessionKeyByte, "AES");
+            Cipher cipher = Cipher.getInstance(cipherString);
+            IvParameterSpec ivParameterSpec = new IvParameterSpec(ivByte);
+            cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);
+            byte[] original = cipher.doFinal(encryptedByte);
+            jsonStr = new String(original);
+        } catch (Exception e) {
+            throw new StatusException("登录失败,信息有误 ", e);
+        }
+        JSONObject jsonObject = JSONObject.fromObject(jsonStr);
+        return jsonObject;
+    }
+
+    @Transactional
+    @Override
+    public AdminLoginVo loginWxAppByPhoneCode(String loginCode, String phoneCode) {
+        Map<String, String> params = new HashMap<>();
+        params.put("code", phoneCode);
+        String ret;
+        try {
+            ret = HttpUtil.httpsActionPost("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="
+                    + wxappAccessTokenService.getWxappAccessToken().getAccessToken(), null, params);
+        } catch (Exception e) {
+            throw new StatusException("登录失败", e);
+        }
+        JSONObject jo = JSONObject.fromObject(ret);
+        if (jo.getInt("errcode") != 0) {
+            throw new StatusException("登录失败," + jo.getString("errmsg"));
+        }
+        String phone = jo.getJSONObject("phone_info").getString("purePhoneNumber");
+        UserEntity userEntity = userService.getByLoginName(phone);
+        if (userEntity == null) {
+            throw new StatusException("微信所绑定手机号系统中不存在");
+        }
+        if (!userEntity.getEnable()) {
+            throw new StatusException("该用户已禁用");
+        }
+        if (!userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
+            throw new StatusException("该用户不是科组长");
+        }
+        SchoolEntity school = schoolService.getById(userEntity.getSchoolId());
+        if (!school.getEnable()) {
+            throw new StatusException("该学校已禁用");
+        }
+        WxappSession ws = solarService.getWxappSessionByCode(sysProperty.getWxappAppid(), loginCode);
+        String openid = ByteUtil.toHexAscii(SHA256.encode(ws.getOpenId()));
+        WxappInfoEntity wi = wxappInfoService.getByOpenId(openid);
+        if (wi == null) {
+            wi = new WxappInfoEntity();
+            wi.setOpenid(openid);
+        }
+        wi.setPhone(phone);
+        wxappInfoService.saveOrUpdate(wi);
+        User user = new User();
+        user.setLoginName(userEntity.getLoginName());
+        user.setName(userEntity.getName());
+        user.setSchoolId(userEntity.getSchoolId());
+        user.setId(userEntity.getId());
+        user.setRole(Role.getById(userEntity.getRoleId()));
+        user.setAccessToken(FastUUID.get());
+        user.buildKey();
+        sessionService.userLogin(user);
+        AdminLoginVo vo = new AdminLoginVo();
+        vo.setAccessToken(user.getAccessToken());
+        vo.setName(user.getName());
+        vo.setSessionId(user.getSessionId());
+        vo.setSchoolId(user.getSchoolId());
+        vo.setRole(user.getRole());
+        vo.setSchoolName(school.getName());
+        return vo;
+    }
 }

+ 17 - 17
src/main/java/cn/com/qmth/mps/service/impl/CourseServiceImpl.java

@@ -14,27 +14,27 @@ import cn.com.qmth.mps.service.CourseService;
 @Service
 public class CourseServiceImpl extends ServiceImpl<CourseDao, CourseEntity> implements CourseService {
 
-	@Override
-	public CourseEntity getByCode(Long schoolId, String code) {
-		QueryWrapper<CourseEntity> wrapper = new QueryWrapper<>();
+    @Override
+    public CourseEntity getByCode(Long schoolId, String code) {
+        QueryWrapper<CourseEntity> wrapper = new QueryWrapper<>();
         LambdaQueryWrapper<CourseEntity> lw = wrapper.lambda();
         lw.eq(CourseEntity::getSchoolId, schoolId);
         lw.eq(CourseEntity::getCode, code);
         return this.getOne(wrapper);
-	}
+    }
 
-	@Transactional
-	@Override
-	public CourseEntity saveOrGet(Long schoolId, String code,String name) {
-		CourseEntity c=getByCode(schoolId, code);
-		if(c==null) {
-			c=new CourseEntity();
-			c.setSchoolId(schoolId);
-			c.setCode(code);
-		}
-		c.setName(name);
-		this.saveOrUpdate(c);
-		return c;
-	}
+    @Transactional
+    @Override
+    public CourseEntity saveOrGet(Long schoolId, String code, String name) {
+        CourseEntity c = getByCode(schoolId, code);
+        if (c == null) {
+            c = new CourseEntity();
+            c.setSchoolId(schoolId);
+            c.setCode(code);
+        }
+        c.setName(name);
+        this.saveOrUpdate(c);
+        return c;
+    }
 
 }

+ 143 - 142
src/main/java/cn/com/qmth/mps/service/impl/ExamServiceImpl.java

@@ -43,121 +43,122 @@ import cn.com.qmth.mps.vo.exam.ExamVo;
 
 @Service
 public class ExamServiceImpl extends ServiceImpl<ExamDao, ExamEntity> implements ExamService {
-	@Value("${markingcloud.server}")
-	private String markingcloudServer;
-	@Autowired
-	private SchoolService schoolService;
-	
-	@Autowired
-	private PaperService paperService;
-
-	@Override
-	public void checkExamStatus(Long examId) {
-		ExamEntity exam=this.getById(examId);
-		if(exam==null) {
-			throw new StatusException("未找到考试信息");
-		}
-		if(!ExamStatus.EDIT.equals(exam.getExamStatus())) {
-			throw new StatusException("考试未开放上报,不能设置结构信息或分组信息");
-		}
-	}
-	
-	
-	@Transactional
-	@Override
-	public void syncExam(Long schoolId, User user) {
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(schoolId)) {
-			throw new StatusException("没有权限");
-		}
-		SchoolEntity school = schoolService.getById(schoolId);
-		if (school == null) {
-			throw new StatusException("未找到学校");
-		}
-		if (StringUtils.isBlank(school.getAccessKey()) || StringUtils.isBlank(school.getAccessSecret())) {
-			throw new StatusException("该学校不是同步数据,无法同步考试");
-		}
-		int pageNumber = 1;
-		int pageSize = 100;
-		String uri="/api/exams";
-		for (;;) {
-			long time = System.currentTimeMillis();
-			String signature = SignatureEntity.build(SignatureType.SECRET, "POST", uri, time, school.getAccessKey(),
-					school.getAccessSecret());
-			Map<String, String> heads = new HashMap<>();
-			heads.put("Authorization", signature.toString());
-			heads.put("time", String.valueOf(time));
-			Map<String, Object> params = new HashMap<>();
-			params.put("pageNumber", pageNumber);
-			params.put("pageSize", pageSize);
-			String str = HttpUtil.actionPostForm(markingcloudServer+uri, heads, params);
-			JSONArray examArray = JSONArray.parseArray(str);
-			for (int i = 0; i < examArray.size(); i++) {
-				ExamEntity exam = JSONObject.parseObject(examArray.getString(i), ExamEntity.class);
-				ExamEntity old=findByCode(schoolId, String.valueOf(exam.getId()));
-				if(old==null) {
-					exam.setSchoolId(schoolId);
-					exam.setCode(String.valueOf(exam.getId()));
-					exam.setId(null);
-					exam.setExamStatus(ExamStatus.EDIT);
-					this.save(exam);
-				}
-			}
-			if (examArray.size() != pageSize) {
-				break;
-			}
-			pageNumber++;
-		}
-	}
-	
-	private ExamEntity findByCode(Long schoolId,String code) {
-		QueryWrapper<ExamEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<ExamEntity> lw = wrapper.lambda();
-		lw.eq(ExamEntity::getSchoolId, schoolId);
-		lw.eq(ExamEntity::getCode, code);
-		return this.getOne(wrapper);
-	}
-
-	@Transactional
-	@Override
-	public void saveExam(ExamDomain domain, User user) {
-		if (domain.getSchoolId() == null) {
-			throw new StatusException("学校不能为空");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(domain.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		if (StringUtils.isBlank(domain.getName())) {
-			throw new StatusException("考试名称不能为空");
-		}
-		if (domain.getExamStatus()==null) {
-			throw new StatusException("状态不能为空");
-		}
-		ExamEntity ue = null;
-		if (domain.getId() != null) {
-			ue = this.getById(domain.getId());
-			if (ue == null) {
-				throw new StatusException("未找到考试");
-			}
-		} else {
-			ue = new ExamEntity();
-			ue.setSchoolId(domain.getSchoolId());
-		}
-		ue.setExamStatus(domain.getExamStatus());
-		ue.setName(domain.getName());
-		this.saveOrUpdate(ue);
-	}
-
-	@Override
-	public PageResult<ExamVo> page(ExamQuery query, User user) {
-		if (query.getSchoolId() == null) {
-			throw new StatusException("学校不能为空");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(query.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		IPage<ExamVo> iPage = this.baseMapper.page(new Page<ExamVo>(query.getPageNumber(), query.getPageSize()), query);
-		if(CollectionUtils.isNotEmpty(iPage.getRecords())) {
-			new BatchSetDataUtil<ExamVo>() {
+
+    @Value("${markingcloud.server}")
+    private String markingcloudServer;
+
+    @Autowired
+    private SchoolService schoolService;
+
+    @Autowired
+    private PaperService paperService;
+
+    @Override
+    public void checkExamStatus(Long examId) {
+        ExamEntity exam = this.getById(examId);
+        if (exam == null) {
+            throw new StatusException("未找到考试信息");
+        }
+        if (!ExamStatus.EDIT.equals(exam.getExamStatus())) {
+            throw new StatusException("考试未开放上报,不能设置结构信息或分组信息");
+        }
+    }
+
+    @Transactional
+    @Override
+    public void syncExam(Long schoolId, User user) {
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(schoolId)) {
+            throw new StatusException("没有权限");
+        }
+        SchoolEntity school = schoolService.getById(schoolId);
+        if (school == null) {
+            throw new StatusException("未找到学校");
+        }
+        if (StringUtils.isBlank(school.getAccessKey()) || StringUtils.isBlank(school.getAccessSecret())) {
+            throw new StatusException("该学校不是同步数据,无法同步考试");
+        }
+        int pageNumber = 1;
+        int pageSize = 100;
+        String uri = "/api/exams";
+        for (;;) {
+            long time = System.currentTimeMillis();
+            String signature = SignatureEntity.build(SignatureType.SECRET, "POST", uri, time, school.getAccessKey(),
+                    school.getAccessSecret());
+            Map<String, String> heads = new HashMap<>();
+            heads.put("Authorization", signature.toString());
+            heads.put("time", String.valueOf(time));
+            Map<String, Object> params = new HashMap<>();
+            params.put("pageNumber", pageNumber);
+            params.put("pageSize", pageSize);
+            String str = HttpUtil.actionPostForm(markingcloudServer + uri, heads, params);
+            JSONArray examArray = JSONArray.parseArray(str);
+            for (int i = 0; i < examArray.size(); i++) {
+                ExamEntity exam = JSONObject.parseObject(examArray.getString(i), ExamEntity.class);
+                ExamEntity old = findByCode(schoolId, String.valueOf(exam.getId()));
+                if (old == null) {
+                    exam.setSchoolId(schoolId);
+                    exam.setCode(String.valueOf(exam.getId()));
+                    exam.setId(null);
+                    exam.setExamStatus(ExamStatus.EDIT);
+                    this.save(exam);
+                }
+            }
+            if (examArray.size() != pageSize) {
+                break;
+            }
+            pageNumber++;
+        }
+    }
+
+    private ExamEntity findByCode(Long schoolId, String code) {
+        QueryWrapper<ExamEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<ExamEntity> lw = wrapper.lambda();
+        lw.eq(ExamEntity::getSchoolId, schoolId);
+        lw.eq(ExamEntity::getCode, code);
+        return this.getOne(wrapper);
+    }
+
+    @Transactional
+    @Override
+    public void saveExam(ExamDomain domain, User user) {
+        if (domain.getSchoolId() == null) {
+            throw new StatusException("学校不能为空");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(domain.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        if (StringUtils.isBlank(domain.getName())) {
+            throw new StatusException("考试名称不能为空");
+        }
+        if (domain.getExamStatus() == null) {
+            throw new StatusException("状态不能为空");
+        }
+        ExamEntity ue = null;
+        if (domain.getId() != null) {
+            ue = this.getById(domain.getId());
+            if (ue == null) {
+                throw new StatusException("未找到考试");
+            }
+        } else {
+            ue = new ExamEntity();
+            ue.setSchoolId(domain.getSchoolId());
+        }
+        ue.setExamStatus(domain.getExamStatus());
+        ue.setName(domain.getName());
+        this.saveOrUpdate(ue);
+    }
+
+    @Override
+    public PageResult<ExamVo> page(ExamQuery query, User user) {
+        if (query.getSchoolId() == null) {
+            throw new StatusException("学校不能为空");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(query.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        IPage<ExamVo> iPage = this.baseMapper.page(new Page<ExamVo>(query.getPageNumber(), query.getPageSize()), query);
+        if (CollectionUtils.isNotEmpty(iPage.getRecords())) {
+            new BatchSetDataUtil<ExamVo>() {
 
                 @Override
                 protected void setData(List<ExamVo> dataList) {
@@ -175,15 +176,15 @@ public class ExamServiceImpl extends ServiceImpl<ExamDao, ExamEntity> implements
                     }
                 }
             }.setDataForBatch(iPage.getRecords(), 20);
-		}
-		return PageUtil.of(iPage);
-	}
+        }
+        return PageUtil.of(iPage);
+    }
 
-	@Override
-	public List<ExamVo> unClose(User user) {
-		List<ExamVo> ret=this.baseMapper.unClose(user.getSchoolId());
-		if(CollectionUtils.isNotEmpty(ret)) {
-			new BatchSetDataUtil<ExamVo>() {
+    @Override
+    public List<ExamVo> unClose(User user) {
+        List<ExamVo> ret = this.baseMapper.unClose(user.getSchoolId());
+        if (CollectionUtils.isNotEmpty(ret)) {
+            new BatchSetDataUtil<ExamVo>() {
 
                 @Override
                 protected void setData(List<ExamVo> dataList) {
@@ -201,24 +202,24 @@ public class ExamServiceImpl extends ServiceImpl<ExamDao, ExamEntity> implements
                     }
                 }
             }.setDataForBatch(ret, 20);
-		}
-		return ret;
-	}
-
-	@Override
-	public ExamVo info(Long id, User accessUser) {
-		ExamEntity ue = this.getById(id);
-		if (ue == null) {
-			throw new StatusException("未找到考试信息");
-		}
-		ExamVo vo = new ExamVo();
-		vo.setId(ue.getId());
-		vo.setName(ue.getName());
-		vo.setSchoolId(ue.getSchoolId());
-		vo.setCode(ue.getCode());
-		vo.setExamStatus(ue.getExamStatus());
-		vo.setPaperCount(paperService.findPaperCount(ue.getId()));
-		return vo;
-	}
+        }
+        return ret;
+    }
+
+    @Override
+    public ExamVo info(Long id, User accessUser) {
+        ExamEntity ue = this.getById(id);
+        if (ue == null) {
+            throw new StatusException("未找到考试信息");
+        }
+        ExamVo vo = new ExamVo();
+        vo.setId(ue.getId());
+        vo.setName(ue.getName());
+        vo.setSchoolId(ue.getSchoolId());
+        vo.setCode(ue.getCode());
+        vo.setExamStatus(ue.getExamStatus());
+        vo.setPaperCount(paperService.findPaperCount(ue.getId()));
+        return vo;
+    }
 
 }

+ 291 - 286
src/main/java/cn/com/qmth/mps/service/impl/PaperDetailServiceImpl.java

@@ -27,299 +27,304 @@ import cn.com.qmth.mps.vo.paper.StructDomain;
 
 @Service
 public class PaperDetailServiceImpl extends ServiceImpl<PaperDetailDao, PaperDetailEntity>
-		implements PaperDetailService {
-	@Autowired
-	private PaperGroupService paperGroupService;
-	@Autowired
-	private PaperGroupUnitService paperGroupUnitService;
-	@Autowired
-	private PaperDetailUnitService paperDetailUnitService;
-	@Autowired
-	private PaperService paperService;
-	@Autowired
-	private ExamService examService;
+        implements PaperDetailService {
 
-	@Override
-	public List<PaperDetail> getStructInfo(Long paperId) {
-		List<PaperDetail> ret = new ArrayList<>();
-		List<PaperDetailEntity> es = getByPaperId(paperId);
-		if (CollectionUtils.isEmpty(es)) {
-			return ret;
-		}
-		Map<Long, PaperDetail> map = new HashMap<>();
-		for (PaperDetailEntity e : es) {
-			PaperDetail vo = new PaperDetail();
-			vo.setName(e.getName());
-			vo.setNumber(e.getNumber());
-			map.put(e.getId(), vo);
-			ret.add(vo);
-		}
-		Map<Long, List<PaperDetailUnit>> units = paperDetailUnitService.getStructInfo(paperId);
-		if (units == null || units.size() == 0) {
-			return ret;
-		}
-		for (Long key : units.keySet()) {
-			map.get(key).setUnits(units.get(key));
-		}
-		List<PaperGroupUnitEntity> gs = paperGroupUnitService.getByPaperId(paperId);
-		Set<String> unitSet = new HashSet<>();
-		for (PaperGroupUnitEntity u : gs) {
-			unitSet.add(u.getDetailNumber() + "-" + u.getDetailUnitNumber());
-		}
-		for (PaperDetail pd : ret) {
-			if (CollectionUtils.isNotEmpty(pd.getUnits())) {
-				for (PaperDetailUnit u : pd.getUnits()) {
-					if (unitSet.contains(pd.getNumber() + "-" + u.getNumber())) {
-						u.setInGroup(true);
-					} else {
-						u.setInGroup(false);
-					}
-				}
-			}
-		}
-		return ret;
-	}
+    @Autowired
+    private PaperGroupService paperGroupService;
 
-	@Override
-	public List<PaperDetailEntity> getByPaperId(Long paperId) {
-		QueryWrapper<PaperDetailEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperDetailEntity> lw = wrapper.lambda();
-		lw.eq(PaperDetailEntity::getPaperId, paperId);
-		return this.list(wrapper);
-	}
+    @Autowired
+    private PaperGroupUnitService paperGroupUnitService;
 
-	@Transactional
-	@Override
-	public void structSave(StructDomain domain, User user) {
-		if (domain.getPaperId() == null) {
-			throw new StatusException("试卷结构ID不能为空");
-		}
-		if (domain.getTotalScore() == null) {
-			throw new StatusException("试卷满分不能为空");
-		}
-		if (domain.getTotalScore() <= 0) {
-			throw new StatusException("试卷满分必须大于0");
-		}
-		String total = domain.getTotalScore().toString();
-		if (total.indexOf(".") >= 0 && total.indexOf(".") < total.length() - 2) {
-			throw new StatusException("试卷满分只能有一位小数");
-		}
-		if (CollectionUtils.isNotEmpty(domain.getStructInfo())) {
-			for (PaperDetail u : domain.getStructInfo()) {
-				if (u.getNumber() == null || StringUtils.isBlank(u.getName())) {
-					throw new StatusException("大题号、大题名称不能为空");
-				}
-				if (u.getNumber() <= 0) {
-					throw new StatusException("大题号必须大于0");
-				}
-				if (CollectionUtils.isNotEmpty(u.getUnits())) {
-					for (PaperDetailUnit unit : u.getUnits()) {
-						if (unit.getNumber() == null || unit.getScore() == null || unit.getScoreStep() == null) {
-							throw new StatusException("小题号、小题满分、给分间隔不能为空");
-						}
-						if (unit.getNumber() <= 0) {
-							throw new StatusException("小题号必须大于0");
-						}
-						String score = unit.getScore().toString();
-						if (score.indexOf(".") >= 0 && score.indexOf(".") < score.length() - 2) {
-							throw new StatusException("小题满分只能有一位小数");
-						}
-						String scoreStep = unit.getScoreStep().toString();
-						if (scoreStep.indexOf(".") >= 0 && scoreStep.indexOf(".") < scoreStep.length() - 2) {
-							throw new StatusException("给分间隔只能有一位小数");
-						}
-					}
-				}
-			}
-		}
-		PaperEntity paper = paperService.getById(domain.getPaperId());
-		if (paper == null) {
-			throw new StatusException("未找到试卷结构");
-		}
-		examService.checkExamStatus(paper.getExamId());
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		if (paper.getStructFinish()) {
-			throw new StatusException("试卷结构已提交,不能暂存");
-		}
-		clearPaperSruct(domain.getPaperId());
-		paper.setTotalScore(domain.getTotalScore());
-		paper.setSubjectiveScore(domain.getTotalScore());
-		paperService.updateById(paper);
-		if (CollectionUtils.isNotEmpty(domain.getStructInfo())) {
-			for (PaperDetail pd : domain.getStructInfo()) {
-				PaperDetailEntity e = new PaperDetailEntity();
-				e.setName(pd.getName());
-				e.setNumber(pd.getNumber());
-				e.setPaperId(domain.getPaperId());
-				this.save(e);
-				if (CollectionUtils.isNotEmpty(pd.getUnits())) {
-					paperDetailUnitService.saveUnit(e, pd.getUnits());
-				}
-			}
-		}
-	}
+    @Autowired
+    private PaperDetailUnitService paperDetailUnitService;
 
-	private void clearPaperSruct(Long paperId) {
-		clearByPaperId(paperId);
-		paperDetailUnitService.clearByPaperId(paperId);
-	}
+    @Autowired
+    private PaperService paperService;
 
-	private void clearByPaperId(Long paperId) {
-		QueryWrapper<PaperDetailEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperDetailEntity> lw = wrapper.lambda();
-		lw.eq(PaperDetailEntity::getPaperId, paperId);
-		this.remove(wrapper);
-	}
+    @Autowired
+    private ExamService examService;
 
-	@Override
-	public void structImport(StructDomain domain, User user) {
-		if (domain.getPaperId() == null) {
-			throw new StatusException("试卷结构ID不能为空");
-		}
-		if (domain.getTotalScore() == null) {
-			throw new StatusException("试卷满分不能为空");
-		}
-		if (domain.getTotalScore() <= 0) {
-			throw new StatusException("试卷满分必须大于0");
-		}
-		String total = domain.getTotalScore().toString();
-		if (total.indexOf(".") >= 0 && total.indexOf(".") < total.length() - 2) {
-			throw new StatusException("试卷满分只能有一位小数");
-		}
-		if (CollectionUtils.isEmpty(domain.getStructInfo())) {
-			throw new StatusException("大题信息不能为空");
-		}
-		for (PaperDetail u : domain.getStructInfo()) {
-			if (u.getNumber() == null || StringUtils.isBlank(u.getName())) {
-				throw new StatusException("大题号、大题名称不能为空");
-			}
-			if (CollectionUtils.isEmpty(u.getUnits())) {
-				throw new StatusException("小题信息不能为空");
-			}
-			for (PaperDetailUnit unit : u.getUnits()) {
-				if (unit.getNumber() == null || unit.getScore() == null || unit.getScoreStep() == null) {
-					throw new StatusException("小题号、小题满分、给分间隔不能为空");
-				}
-				if (unit.getNumber() <= 0) {
-					throw new StatusException("小题号必须大于0");
-				}
-				String score = unit.getScore().toString();
-				if (score.indexOf(".") >= 0 && score.indexOf(".") < score.length() - 2) {
-					throw new StatusException("小题满分只能有一位小数");
-				}
-				String scoreStep = unit.getScoreStep().toString();
-				if (scoreStep.indexOf(".") >= 0 && scoreStep.indexOf(".") < scoreStep.length() - 2) {
-					throw new StatusException("给分间隔只能有一位小数");
-				}
-			}
-		}
-		checkTotalScore(domain);
-		PaperEntity paper = paperService.getById(domain.getPaperId());
-		if (paper == null) {
-			throw new StatusException("未找到试卷结构");
-		}
-		examService.checkExamStatus(paper.getExamId());
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		paperGroupService.groupClear(domain.getPaperId(), user);
-		clearPaperSruct(domain.getPaperId());
-		paper.setTotalScore(domain.getTotalScore());
-		paper.setSubjectiveScore(domain.getTotalScore());
-		paper.setStructFinish(true);
-		for (PaperDetail pd : domain.getStructInfo()) {
-			PaperDetailEntity e = new PaperDetailEntity();
-			e.setName(pd.getName());
-			e.setNumber(pd.getNumber());
-			e.setPaperId(domain.getPaperId());
-			this.save(e);
-			paperDetailUnitService.saveUnit(e, pd.getUnits());
-		}
-		paperService.updateById(paper);
-	}
+    @Override
+    public List<PaperDetail> getStructInfo(Long paperId) {
+        List<PaperDetail> ret = new ArrayList<>();
+        List<PaperDetailEntity> es = getByPaperId(paperId);
+        if (CollectionUtils.isEmpty(es)) {
+            return ret;
+        }
+        Map<Long, PaperDetail> map = new HashMap<>();
+        for (PaperDetailEntity e : es) {
+            PaperDetail vo = new PaperDetail();
+            vo.setName(e.getName());
+            vo.setNumber(e.getNumber());
+            map.put(e.getId(), vo);
+            ret.add(vo);
+        }
+        Map<Long, List<PaperDetailUnit>> units = paperDetailUnitService.getStructInfo(paperId);
+        if (units == null || units.size() == 0) {
+            return ret;
+        }
+        for (Long key : units.keySet()) {
+            map.get(key).setUnits(units.get(key));
+        }
+        List<PaperGroupUnitEntity> gs = paperGroupUnitService.getByPaperId(paperId);
+        Set<String> unitSet = new HashSet<>();
+        for (PaperGroupUnitEntity u : gs) {
+            unitSet.add(u.getDetailNumber() + "-" + u.getDetailUnitNumber());
+        }
+        for (PaperDetail pd : ret) {
+            if (CollectionUtils.isNotEmpty(pd.getUnits())) {
+                for (PaperDetailUnit u : pd.getUnits()) {
+                    if (unitSet.contains(pd.getNumber() + "-" + u.getNumber())) {
+                        u.setInGroup(true);
+                    } else {
+                        u.setInGroup(false);
+                    }
+                }
+            }
+        }
+        return ret;
+    }
 
-	@Transactional
-	@Override
-	public void structSubmit(StructDomain domain, User user) {
-		if (domain.getPaperId() == null) {
-			throw new StatusException("试卷结构ID不能为空");
-		}
-		if (domain.getTotalScore() == null) {
-			throw new StatusException("试卷满分不能为空");
-		}
-		if (domain.getTotalScore() <= 0) {
-			throw new StatusException("试卷满分必须大于0");
-		}
-		String total = domain.getTotalScore().toString();
-		if (total.indexOf(".") >= 0 && total.indexOf(".") < total.length() - 2) {
-			throw new StatusException("试卷满分只能有一位小数");
-		}
-		if (CollectionUtils.isEmpty(domain.getStructInfo())) {
-			throw new StatusException("大题信息不能为空");
-		}
-		for (PaperDetail u : domain.getStructInfo()) {
-			if (u.getNumber() == null || StringUtils.isBlank(u.getName())) {
-				throw new StatusException("大题号、大题名称不能为空");
-			}
-			if (CollectionUtils.isEmpty(u.getUnits())) {
-				throw new StatusException("小题信息不能为空");
-			}
-			for (PaperDetailUnit unit : u.getUnits()) {
-				if (unit.getNumber() == null || unit.getScore() == null || unit.getScoreStep() == null) {
-					throw new StatusException("小题号、小题满分、给分间隔不能为空");
-				}
-				if (unit.getNumber() <= 0) {
-					throw new StatusException("小题号必须大于0");
-				}
-				String score = unit.getScore().toString();
-				if (score.indexOf(".") >= 0 && score.indexOf(".") < score.length() - 2) {
-					throw new StatusException("小题满分只能有一位小数");
-				}
-				String scoreStep = unit.getScoreStep().toString();
-				if (scoreStep.indexOf(".") >= 0 && scoreStep.indexOf(".") < scoreStep.length() - 2) {
-					throw new StatusException("给分间隔只能有一位小数");
-				}
-			}
-		}
-		checkTotalScore(domain);
-		PaperEntity paper = paperService.getById(domain.getPaperId());
-		if (paper == null) {
-			throw new StatusException("未找到试卷结构");
-		}
-		examService.checkExamStatus(paper.getExamId());
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		if (paperGroupService.existsGroup(domain.getPaperId())) {
-			throw new StatusException("有分组信息,不能修改试卷结构");
-		}
-		clearPaperSruct(domain.getPaperId());
-		paper.setTotalScore(domain.getTotalScore());
-		paper.setSubjectiveScore(domain.getTotalScore());
-		paper.setStructFinish(true);
-		paperService.updateById(paper);
-		for (PaperDetail pd : domain.getStructInfo()) {
-			PaperDetailEntity e = new PaperDetailEntity();
-			e.setName(pd.getName());
-			e.setNumber(pd.getNumber());
-			e.setPaperId(domain.getPaperId());
-			this.save(e);
-			paperDetailUnitService.saveUnit(e, pd.getUnits());
-		}
-	}
+    @Override
+    public List<PaperDetailEntity> getByPaperId(Long paperId) {
+        QueryWrapper<PaperDetailEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperDetailEntity> lw = wrapper.lambda();
+        lw.eq(PaperDetailEntity::getPaperId, paperId);
+        return this.list(wrapper);
+    }
 
-	private void checkTotalScore(StructDomain domain) {
-		double total = 0.0;
-		for (PaperDetail detial : domain.getStructInfo()) {
-			for (PaperDetailUnit unit : detial.getUnits()) {
-				total = Calculator.add(total, unit.getScore(), 1);
-			}
-		}
-		if (total != domain.getTotalScore()) {
-			throw new StatusException("试卷满分与小题分不一致");
-		}
-	}
+    @Transactional
+    @Override
+    public void structSave(StructDomain domain, User user) {
+        if (domain.getPaperId() == null) {
+            throw new StatusException("试卷结构ID不能为空");
+        }
+        if (domain.getTotalScore() == null) {
+            throw new StatusException("试卷满分不能为空");
+        }
+        if (domain.getTotalScore() <= 0) {
+            throw new StatusException("试卷满分必须大于0");
+        }
+        String total = domain.getTotalScore().toString();
+        if (total.indexOf(".") >= 0 && total.indexOf(".") < total.length() - 2) {
+            throw new StatusException("试卷满分只能有一位小数");
+        }
+        if (CollectionUtils.isNotEmpty(domain.getStructInfo())) {
+            for (PaperDetail u : domain.getStructInfo()) {
+                if (u.getNumber() == null || StringUtils.isBlank(u.getName())) {
+                    throw new StatusException("大题号、大题名称不能为空");
+                }
+                if (u.getNumber() <= 0) {
+                    throw new StatusException("大题号必须大于0");
+                }
+                if (CollectionUtils.isNotEmpty(u.getUnits())) {
+                    for (PaperDetailUnit unit : u.getUnits()) {
+                        if (unit.getNumber() == null || unit.getScore() == null || unit.getScoreStep() == null) {
+                            throw new StatusException("小题号、小题满分、给分间隔不能为空");
+                        }
+                        if (unit.getNumber() <= 0) {
+                            throw new StatusException("小题号必须大于0");
+                        }
+                        String score = unit.getScore().toString();
+                        if (score.indexOf(".") >= 0 && score.indexOf(".") < score.length() - 2) {
+                            throw new StatusException("小题满分只能有一位小数");
+                        }
+                        String scoreStep = unit.getScoreStep().toString();
+                        if (scoreStep.indexOf(".") >= 0 && scoreStep.indexOf(".") < scoreStep.length() - 2) {
+                            throw new StatusException("给分间隔只能有一位小数");
+                        }
+                    }
+                }
+            }
+        }
+        PaperEntity paper = paperService.getById(domain.getPaperId());
+        if (paper == null) {
+            throw new StatusException("未找到试卷结构");
+        }
+        examService.checkExamStatus(paper.getExamId());
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        if (paper.getStructFinish()) {
+            throw new StatusException("试卷结构已提交,不能暂存");
+        }
+        clearPaperSruct(domain.getPaperId());
+        paper.setTotalScore(domain.getTotalScore());
+        paper.setSubjectiveScore(domain.getTotalScore());
+        paperService.updateById(paper);
+        if (CollectionUtils.isNotEmpty(domain.getStructInfo())) {
+            for (PaperDetail pd : domain.getStructInfo()) {
+                PaperDetailEntity e = new PaperDetailEntity();
+                e.setName(pd.getName());
+                e.setNumber(pd.getNumber());
+                e.setPaperId(domain.getPaperId());
+                this.save(e);
+                if (CollectionUtils.isNotEmpty(pd.getUnits())) {
+                    paperDetailUnitService.saveUnit(e, pd.getUnits());
+                }
+            }
+        }
+    }
+
+    private void clearPaperSruct(Long paperId) {
+        clearByPaperId(paperId);
+        paperDetailUnitService.clearByPaperId(paperId);
+    }
+
+    private void clearByPaperId(Long paperId) {
+        QueryWrapper<PaperDetailEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperDetailEntity> lw = wrapper.lambda();
+        lw.eq(PaperDetailEntity::getPaperId, paperId);
+        this.remove(wrapper);
+    }
+
+    @Override
+    public void structImport(StructDomain domain, User user) {
+        if (domain.getPaperId() == null) {
+            throw new StatusException("试卷结构ID不能为空");
+        }
+        if (domain.getTotalScore() == null) {
+            throw new StatusException("试卷满分不能为空");
+        }
+        if (domain.getTotalScore() <= 0) {
+            throw new StatusException("试卷满分必须大于0");
+        }
+        String total = domain.getTotalScore().toString();
+        if (total.indexOf(".") >= 0 && total.indexOf(".") < total.length() - 2) {
+            throw new StatusException("试卷满分只能有一位小数");
+        }
+        if (CollectionUtils.isEmpty(domain.getStructInfo())) {
+            throw new StatusException("大题信息不能为空");
+        }
+        for (PaperDetail u : domain.getStructInfo()) {
+            if (u.getNumber() == null || StringUtils.isBlank(u.getName())) {
+                throw new StatusException("大题号、大题名称不能为空");
+            }
+            if (CollectionUtils.isEmpty(u.getUnits())) {
+                throw new StatusException("小题信息不能为空");
+            }
+            for (PaperDetailUnit unit : u.getUnits()) {
+                if (unit.getNumber() == null || unit.getScore() == null || unit.getScoreStep() == null) {
+                    throw new StatusException("小题号、小题满分、给分间隔不能为空");
+                }
+                if (unit.getNumber() <= 0) {
+                    throw new StatusException("小题号必须大于0");
+                }
+                String score = unit.getScore().toString();
+                if (score.indexOf(".") >= 0 && score.indexOf(".") < score.length() - 2) {
+                    throw new StatusException("小题满分只能有一位小数");
+                }
+                String scoreStep = unit.getScoreStep().toString();
+                if (scoreStep.indexOf(".") >= 0 && scoreStep.indexOf(".") < scoreStep.length() - 2) {
+                    throw new StatusException("给分间隔只能有一位小数");
+                }
+            }
+        }
+        checkTotalScore(domain);
+        PaperEntity paper = paperService.getById(domain.getPaperId());
+        if (paper == null) {
+            throw new StatusException("未找到试卷结构");
+        }
+        examService.checkExamStatus(paper.getExamId());
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        paperGroupService.groupClear(domain.getPaperId(), user);
+        clearPaperSruct(domain.getPaperId());
+        paper.setTotalScore(domain.getTotalScore());
+        paper.setSubjectiveScore(domain.getTotalScore());
+        paper.setStructFinish(true);
+        for (PaperDetail pd : domain.getStructInfo()) {
+            PaperDetailEntity e = new PaperDetailEntity();
+            e.setName(pd.getName());
+            e.setNumber(pd.getNumber());
+            e.setPaperId(domain.getPaperId());
+            this.save(e);
+            paperDetailUnitService.saveUnit(e, pd.getUnits());
+        }
+        paperService.updateById(paper);
+    }
+
+    @Transactional
+    @Override
+    public void structSubmit(StructDomain domain, User user) {
+        if (domain.getPaperId() == null) {
+            throw new StatusException("试卷结构ID不能为空");
+        }
+        if (domain.getTotalScore() == null) {
+            throw new StatusException("试卷满分不能为空");
+        }
+        if (domain.getTotalScore() <= 0) {
+            throw new StatusException("试卷满分必须大于0");
+        }
+        String total = domain.getTotalScore().toString();
+        if (total.indexOf(".") >= 0 && total.indexOf(".") < total.length() - 2) {
+            throw new StatusException("试卷满分只能有一位小数");
+        }
+        if (CollectionUtils.isEmpty(domain.getStructInfo())) {
+            throw new StatusException("大题信息不能为空");
+        }
+        for (PaperDetail u : domain.getStructInfo()) {
+            if (u.getNumber() == null || StringUtils.isBlank(u.getName())) {
+                throw new StatusException("大题号、大题名称不能为空");
+            }
+            if (CollectionUtils.isEmpty(u.getUnits())) {
+                throw new StatusException("小题信息不能为空");
+            }
+            for (PaperDetailUnit unit : u.getUnits()) {
+                if (unit.getNumber() == null || unit.getScore() == null || unit.getScoreStep() == null) {
+                    throw new StatusException("小题号、小题满分、给分间隔不能为空");
+                }
+                if (unit.getNumber() <= 0) {
+                    throw new StatusException("小题号必须大于0");
+                }
+                String score = unit.getScore().toString();
+                if (score.indexOf(".") >= 0 && score.indexOf(".") < score.length() - 2) {
+                    throw new StatusException("小题满分只能有一位小数");
+                }
+                String scoreStep = unit.getScoreStep().toString();
+                if (scoreStep.indexOf(".") >= 0 && scoreStep.indexOf(".") < scoreStep.length() - 2) {
+                    throw new StatusException("给分间隔只能有一位小数");
+                }
+            }
+        }
+        checkTotalScore(domain);
+        PaperEntity paper = paperService.getById(domain.getPaperId());
+        if (paper == null) {
+            throw new StatusException("未找到试卷结构");
+        }
+        examService.checkExamStatus(paper.getExamId());
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        if (paperGroupService.existsGroup(domain.getPaperId())) {
+            throw new StatusException("有分组信息,不能修改试卷结构");
+        }
+        clearPaperSruct(domain.getPaperId());
+        paper.setTotalScore(domain.getTotalScore());
+        paper.setSubjectiveScore(domain.getTotalScore());
+        paper.setStructFinish(true);
+        paperService.updateById(paper);
+        for (PaperDetail pd : domain.getStructInfo()) {
+            PaperDetailEntity e = new PaperDetailEntity();
+            e.setName(pd.getName());
+            e.setNumber(pd.getNumber());
+            e.setPaperId(domain.getPaperId());
+            this.save(e);
+            paperDetailUnitService.saveUnit(e, pd.getUnits());
+        }
+    }
+
+    private void checkTotalScore(StructDomain domain) {
+        double total = 0.0;
+        for (PaperDetail detial : domain.getStructInfo()) {
+            for (PaperDetailUnit unit : detial.getUnits()) {
+                total = Calculator.add(total, unit.getScore(), 1);
+            }
+        }
+        if (total != domain.getTotalScore()) {
+            throw new StatusException("试卷满分与小题分不一致");
+        }
+    }
 
 }

+ 61 - 61
src/main/java/cn/com/qmth/mps/service/impl/PaperDetailUnitServiceImpl.java

@@ -21,71 +21,71 @@ import cn.com.qmth.mps.service.PaperDetailUnitService;
 
 @Service
 public class PaperDetailUnitServiceImpl extends ServiceImpl<PaperDetailUnitDao, PaperDetailUnitEntity>
-		implements PaperDetailUnitService {
+        implements PaperDetailUnitService {
 
-	@Override
-	public Map<Long, List<PaperDetailUnit>> getStructInfo(Long paperId) {
-		List<PaperDetailUnitEntity> list = getStructUnitInfo(paperId);
-		if (CollectionUtils.isEmpty(list)) {
-			return null;
-		}
-		Map<Long, List<PaperDetailUnit>> ret = new HashMap<>();
-		for (PaperDetailUnitEntity e : list) {
-			List<PaperDetailUnit> tem = ret.get(e.getDetailId());
-			if (tem == null) {
-				tem = new ArrayList<>();
-				ret.put(e.getDetailId(), tem);
-			}
-			PaperDetailUnit vo = new PaperDetailUnit();
-			vo.setNumber(e.getNumber());
-			vo.setScore(e.getScore());
-			vo.setScoreStep(e.getScoreStep());
-			tem.add(vo);
-		}
-		return ret;
-	}
+    @Override
+    public Map<Long, List<PaperDetailUnit>> getStructInfo(Long paperId) {
+        List<PaperDetailUnitEntity> list = getStructUnitInfo(paperId);
+        if (CollectionUtils.isEmpty(list)) {
+            return null;
+        }
+        Map<Long, List<PaperDetailUnit>> ret = new HashMap<>();
+        for (PaperDetailUnitEntity e : list) {
+            List<PaperDetailUnit> tem = ret.get(e.getDetailId());
+            if (tem == null) {
+                tem = new ArrayList<>();
+                ret.put(e.getDetailId(), tem);
+            }
+            PaperDetailUnit vo = new PaperDetailUnit();
+            vo.setNumber(e.getNumber());
+            vo.setScore(e.getScore());
+            vo.setScoreStep(e.getScoreStep());
+            tem.add(vo);
+        }
+        return ret;
+    }
 
-	private List<PaperDetailUnitEntity> getStructUnitInfo(Long paperId) {
-		QueryWrapper<PaperDetailUnitEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperDetailUnitEntity> lw = wrapper.lambda();
-		lw.eq(PaperDetailUnitEntity::getPaperId, paperId);
-		lw.orderByAsc(PaperDetailUnitEntity::getNumber);
-		return this.list(wrapper);
-	}
+    private List<PaperDetailUnitEntity> getStructUnitInfo(Long paperId) {
+        QueryWrapper<PaperDetailUnitEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperDetailUnitEntity> lw = wrapper.lambda();
+        lw.eq(PaperDetailUnitEntity::getPaperId, paperId);
+        lw.orderByAsc(PaperDetailUnitEntity::getNumber);
+        return this.list(wrapper);
+    }
 
-	@Override
-	public Integer countByPaperId(Long paperId) {
-		QueryWrapper<PaperDetailUnitEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperDetailUnitEntity> lw = wrapper.lambda();
-		lw.eq(PaperDetailUnitEntity::getPaperId, paperId);
-		return this.count(wrapper);
-	}
+    @Override
+    public Integer countByPaperId(Long paperId) {
+        QueryWrapper<PaperDetailUnitEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperDetailUnitEntity> lw = wrapper.lambda();
+        lw.eq(PaperDetailUnitEntity::getPaperId, paperId);
+        return this.count(wrapper);
+    }
 
-	@Transactional
-	@Override
-	public void clearByPaperId(Long paperId) {
-		QueryWrapper<PaperDetailUnitEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperDetailUnitEntity> lw = wrapper.lambda();
-		lw.eq(PaperDetailUnitEntity::getPaperId, paperId);
-		this.remove(wrapper);
+    @Transactional
+    @Override
+    public void clearByPaperId(Long paperId) {
+        QueryWrapper<PaperDetailUnitEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperDetailUnitEntity> lw = wrapper.lambda();
+        lw.eq(PaperDetailUnitEntity::getPaperId, paperId);
+        this.remove(wrapper);
 
-	}
+    }
 
-	@Transactional
-	@Override
-	public void saveUnit(PaperDetailEntity detail, List<PaperDetailUnit> units) {
-		List<PaperDetailUnitEntity> ret=new ArrayList<>();
-		for(PaperDetailUnit u:units) {
-			PaperDetailUnitEntity e=new PaperDetailUnitEntity();
-			e.setDetailId(detail.getId());
-			e.setDetailNumber(detail.getNumber());
-			e.setObjective(false);
-			e.setNumber(u.getNumber());
-			e.setScore(u.getScore());
-			e.setScoreStep(u.getScoreStep());
-			e.setPaperId(detail.getPaperId());
-			ret.add(e);
-		}
-		this.saveBatch(ret);
-	}
+    @Transactional
+    @Override
+    public void saveUnit(PaperDetailEntity detail, List<PaperDetailUnit> units) {
+        List<PaperDetailUnitEntity> ret = new ArrayList<>();
+        for (PaperDetailUnit u : units) {
+            PaperDetailUnitEntity e = new PaperDetailUnitEntity();
+            e.setDetailId(detail.getId());
+            e.setDetailNumber(detail.getNumber());
+            e.setObjective(false);
+            e.setNumber(u.getNumber());
+            e.setScore(u.getScore());
+            e.setScoreStep(u.getScoreStep());
+            e.setPaperId(detail.getPaperId());
+            ret.add(e);
+        }
+        this.saveBatch(ret);
+    }
 }

+ 380 - 370
src/main/java/cn/com/qmth/mps/service/impl/PaperGroupServiceImpl.java

@@ -39,374 +39,384 @@ import javax.annotation.Resource;
 
 @Service
 public class PaperGroupServiceImpl extends ServiceImpl<PaperGroupDao, PaperGroupEntity> implements PaperGroupService {
-	@Autowired
-	private PaperGroupUnitService paperGroupUnitService;
-	@Autowired
-	private PaperService paperService;
-	@Autowired
-	private PaperDetailService paperDetailService;
-	@Autowired
-	private PaperDetailUnitService paperDetailUnitService;
-	
-	@Autowired
-	private CourseService courseService;
-	@Autowired
-	private ExamService examService;
-
-	@Override
-	public List<GroupCountVo> findGroupCount(List<Long> paperIds) {
-		return this.baseMapper.findGroupCount(paperIds);
-	}
-
-	@Override
-	public List<PaperGroup> getGroupInfo(Long paperId) {
-		List<PaperGroup> ret = new ArrayList<>();
-		List<PaperGroupEntity> es = getByPaperId(paperId);
-		if (CollectionUtils.isEmpty(es)) {
-			return ret;
-		}
-		Map<Long, PaperGroup> map = new HashMap<>();
-		for (PaperGroupEntity e : es) {
-			PaperGroup vo = new PaperGroup();
-			vo.setNumber(e.getNumber());
-			vo.setDoubleEnable(e.getDoubleEnable());
-			vo.setDoubleRate(e.getDoubleRate());
-			vo.setArbitrateThreshold(e.getArbitrateThreshold());
-			vo.setArbitrateMethod(e.getArbitrateMethod());
-			map.put(e.getId(), vo);
-			ret.add(vo);
-		}
-		Map<Long, List<PaperGroupUnit>> units = paperGroupUnitService.getGroupInfo(paperId);
-		if (units == null || units.size() == 0) {
-			return ret;
-		}
-		for (Long key : units.keySet()) {
-			map.get(key).setGroupUnits(units.get(key));
-		}
-		return ret;
-	}
-
-	private List<PaperGroupEntity> getByPaperId(Long paperId) {
-		QueryWrapper<PaperGroupEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperGroupEntity> lw = wrapper.lambda();
-		lw.eq(PaperGroupEntity::getPaperId, paperId);
-		return this.list(wrapper);
-	}
-
-	@Override
-	public List<GroupVo> groupList(Long paperId, User user) {
-		PaperEntity paper = paperService.getById(paperId);
-		if (paper == null) {
-			throw new StatusException("未找到试卷结构");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		List<GroupVo> ret = new ArrayList<>();
-		List<PaperGroupEntity> es = getByPaperId(paperId);
-		if (CollectionUtils.isEmpty(es)) {
-			return ret;
-		}
-		Map<Long, GroupVo> map = new HashMap<>();
-		for (PaperGroupEntity e : es) {
-			GroupVo vo = new GroupVo();
-			vo.setNumber(e.getNumber());
-			vo.setGroupId(e.getId());
-			map.put(e.getId(), vo);
-			ret.add(vo);
-		}
-		Map<Long, List<PaperGroupUnit>> units = paperGroupUnitService.getGroupInfo(paperId);
-		List<PaperDetailEntity> des = paperDetailService.getByPaperId(paperId);
-		Map<Integer, PaperDetailEntity> detailMap = new HashMap<>();
-		for (PaperDetailEntity de : des) {
-			detailMap.put(de.getNumber(), de);
-		}
-		for (GroupVo vo : ret) {
-			List<PaperGroupUnit> unit = units.get(vo.getGroupId());
-			if (CollectionUtils.isNotEmpty(unit)) {
-				Set<Integer> set = new LinkedHashSet<>();
-				for (PaperGroupUnit u : unit) {
-					set.add(u.getDetailNumber());
-				}
-				StringBuilder numSb = new StringBuilder();
-				StringBuilder nameSb = new StringBuilder();
-				for (Integer num : set) {
-					numSb.append(num).append(",");
-					nameSb.append(detailMap.get(num).getName()).append(",");
-				}
-				vo.setDetailNumbers(numSb.substring(0, numSb.length() - 1));
-				vo.setDetailNames(nameSb.substring(0, nameSb.length() - 1));
-			}
-		}
-		return ret;
-	}
-
-	@Override
-	public GroupInfoVo groupInfo(Long paperId, Integer groupNumber, User user) {
-		PaperEntity paper = paperService.getById(paperId);
-		if (paper == null) {
-			throw new StatusException("未找到试卷结构");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		PaperGroupEntity e = this.getByPaperIdAndNumber(paperId, groupNumber);
-		if (e == null) {
-			return null;
-		}
-		GroupInfoVo vo = new GroupInfoVo();
-		vo.setNumber(e.getNumber());
-		List<PaperDetail> pds=paperDetailService.getStructInfo(paperId);
-		Map<Long, List<PaperGroupUnit>> units = paperGroupUnitService.getGroupInfo(paperId);
-		vo.setStructInfo(getGroupInfo(pds,units.get(e.getId())));
-		vo.setCourseName(courseService.getById(paper.getCourseId()).getName());
-		return vo;
-	}
-	
-	private List<PaperDetail> getGroupInfo(List<PaperDetail> pds,List<PaperGroupUnit> units){
-		List<PaperDetail> ret=new ArrayList<>();
-		Set<Integer> detailSet=new HashSet<>();
-		Set<String> unitSet=new HashSet<>();
-		for(PaperGroupUnit unit:units) {
-			detailSet.add(unit.getDetailNumber());
-			unitSet.add(unit.getDetailNumber()+"-"+unit.getDetailUnitNumber());
-		}
-		for(PaperDetail pd:pds) {
-			if(detailSet.contains(pd.getNumber())) {
-				ret.add(pd);
-				List<PaperDetailUnit> us=new ArrayList<>();
-				for(PaperDetailUnit u:pd.getUnits()) {
-					if(unitSet.contains(pd.getNumber()+"-"+u.getNumber())) {
-						us.add(u);
-					}
-				}
-				pd.setUnits(us);
-			}
-		}
-		return ret;
-	}
-
-	private PaperGroupEntity getByPaperIdAndNumber(Long paperId, Integer groupNumber) {
-		QueryWrapper<PaperGroupEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperGroupEntity> lw = wrapper.lambda();
-		lw.eq(PaperGroupEntity::getPaperId, paperId);
-		lw.eq(PaperGroupEntity::getNumber, groupNumber);
-		return this.getOne(wrapper);
-	}
-
-	@Transactional
-	@Override
-	public void groupSave(PaperGroupDomain domain, User user) {
-
-		Long paperId = domain.getPaperId();
-		if (Objects.isNull(paperId)) {
-			throw new StatusException("试卷结构ID不能为空");
-		}
-		List<PaperDetailUnitEntity> questionDatasource = paperDetailUnitService.list(
-				new QueryWrapper<PaperDetailUnitEntity>().lambda().eq(PaperDetailUnitEntity::getPaperId, paperId));
-
-		Integer groupNumber = domain.getNumber();
-		if (Objects.isNull(groupNumber)) {
-			throw new StatusException("分组号不能为空");
-		}
-		if (CollectionUtils.isEmpty(domain.getGroupUnits())) {
-			throw new StatusException("分组信息不能为空");
-		}
-
-		Boolean doubleEnable = domain.getDoubleEnable();
-		if (Objects.isNull(doubleEnable)) {
-			throw new StatusException("是否开启双评未设置");
-		}
-		Double doubleRate = domain.getDoubleRate();
-		ArbitrateMethod arbitrateMethod = domain.getArbitrateMethod();
-		Double arbitrateThreshold = domain.getArbitrateThreshold();
-		if (doubleEnable) {
-			// 如果开启双评
-
-			if (Objects.isNull(doubleRate) || doubleRate < 0 || doubleRate > 1) {
-				throw new StatusException("双评比例未正确设置");
-			}
-			if (doubleRate == 0) {
-				throw new StatusException("双评比例不能设置为0");
-			}
-			if (Objects.isNull(arbitrateMethod)) {
-				throw new StatusException("仲裁方式未设置");
-			}
-			if (ArbitrateMethod.GROUP_ARBITRATE.equals(arbitrateMethod)) {
-				if (Objects.isNull(arbitrateThreshold) || (arbitrateThreshold < 0)) {
-					throw new StatusException("仲裁值未正确设置");
-				}
-			}
-		}
-
-		double totalScore = 0.0;
-		for (PaperGroupUnit u : domain.getGroupUnits()) {
-			// 小题仲裁阈值
-			Double questionArbitrateThreshold = u.getArbitrateThreshold();
-			if (u.getDetailNumber() == null || u.getDetailUnitNumber() == null) {
-				throw new StatusException("大题号、小题号不能为空");
-			}
-
-			List<PaperDetailUnitEntity> questionList = questionDatasource.stream()
-					.filter(e -> e.getDetailNumber().equals(u.getDetailNumber()) && e.getNumber().equals(u.getDetailUnitNumber())).collect(Collectors.toList());
-			if (questionList.size() != 1) {
-				throw new StatusException(String.format("题目%d-%d不存在,或存在多个", u.getDetailNumber(), u.getDetailUnitNumber()));
-			}
-			double questionScore = questionList.get(0).getScore();
-			totalScore = totalScore + questionScore;
-			if (ArbitrateMethod.QUESTION_ARBITRATE.equals(arbitrateMethod)) {
-				if (Objects.isNull(questionArbitrateThreshold) || questionArbitrateThreshold < 0) {
-					throw new StatusException("仲裁值未正确设置");
-				}
-				if (questionArbitrateThreshold > questionScore) {
-					throw new StatusException(String.format("题目%d-%d仲裁值大于题目分数", u.getDetailNumber(), u.getDetailUnitNumber()));
-				}
-			}
-			if (!doubleEnable || ArbitrateMethod.GROUP_ARBITRATE.equals(arbitrateMethod)) {
-				u.setArbitrateThreshold(null);
-			}
-		}
-		if (ArbitrateMethod.GROUP_ARBITRATE.equals(arbitrateMethod) && arbitrateThreshold > totalScore) {
-			throw new StatusException("仲裁值大于分组总分");
-		}
-
-		PaperEntity paper = paperService.getById(paperId);
-		if (paper == null) {
-			throw new StatusException("未找到试卷结构");
-		}
-		examService.checkExamStatus(paper.getExamId());
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		if (!paper.getStructFinish()) {
-			throw new StatusException("试卷结构未提交,不能设置分组");
-		}
-		Long groupId = domain.getGroupId();
-		// 参数处理
-		if (!doubleEnable) {
-			// 未开启双评
-			doubleRate = null;
-			arbitrateThreshold = null;
-			arbitrateMethod = null;
-		} else {
-			if (ArbitrateMethod.QUESTION_ARBITRATE.equals(arbitrateMethod)) {
-				arbitrateThreshold = null;
-			}
-		}
-		if (Objects.nonNull(groupId)) {
-			// 编辑
-			paperGroupUnitService.removeByGroupId(groupId);
-			UpdateWrapper<PaperGroupEntity> paperGroupEntityUpdateWrapper = new UpdateWrapper<>();
-			paperGroupEntityUpdateWrapper.lambda().eq(PaperGroupEntity::getId, groupId)
-					.set(PaperGroupEntity::getNumber, groupNumber).set(PaperGroupEntity::getDoubleEnable, doubleEnable)
-					.set(PaperGroupEntity::getDoubleRate, doubleRate)
-					.set(PaperGroupEntity::getArbitrateThreshold, arbitrateThreshold)
-					.set(PaperGroupEntity::getArbitrateMethod, arbitrateMethod);
-			this.update(paperGroupEntityUpdateWrapper);
-		} else {
-			// 新增
-			PaperGroupEntity paperGroupEntity = new PaperGroupEntity();
-			paperGroupEntity.setPaperId(paperId);
-			paperGroupEntity.setNumber(groupNumber);
-			paperGroupEntity.setDoubleEnable(doubleEnable);
-			paperGroupEntity.setDoubleRate(doubleRate);
-			paperGroupEntity.setArbitrateMethod(arbitrateMethod);
-			paperGroupEntity.setArbitrateThreshold(arbitrateThreshold);
-			this.save(paperGroupEntity);
-			groupId = paperGroupEntity.getId();
-		}
-
-		List<PaperDetail> pds = paperDetailService.getStructInfo(paperId);
-		if (CollectionUtils.isEmpty(pds)) {
-			throw new StatusException("试卷结构小题信息为空");
-		}
-		checkStruct(pds, domain.getGroupUnits());
-		paperGroupUnitService.saveUnit(groupId, paperId, domain.getGroupUnits());
-		paper.setGroupFinish(
-				paperGroupUnitService.countByPaperId(paperId).equals(paperDetailUnitService.countByPaperId(paperId)));
-
-		DefaultDoubleSet defaultDoubleSet = domain.getDefaultDoubleSet();
-		if (Objects.nonNull(defaultDoubleSet)) {
-			paper.setDefaultDoubleSet(JSON.toJSONString(defaultDoubleSet));
-		}
-		paperService.updateById(paper);
-	}
-
-	private void checkStruct(List<PaperDetail> pds, List<PaperGroupUnit> groupUnits) {
-		for (PaperGroupUnit groupUnit : groupUnits) {
-			checkStructExists(pds, groupUnit);
-		}
-	}
-
-	private void checkStructExists(List<PaperDetail> pds, PaperGroupUnit groupUnit) {
-		for (PaperDetail pd : pds) {
-			if (pd.getNumber().equals(groupUnit.getDetailNumber())) {
-				for (PaperDetailUnit u : pd.getUnits()) {
-					if (u.getNumber().equals(groupUnit.getDetailUnitNumber())) {
-						return;
-					}
-				}
-			}
-		}
-		throw new StatusException(
-				"试卷结构中大题号:" + groupUnit.getDetailNumber() + " 小题号:" + groupUnit.getDetailUnitNumber() + "不存在");
-	}
-
-	@Transactional
-	@Override
-	public void groupDelete(Long groupId, User user) {
-		PaperGroupEntity group = this.getById(groupId);
-		if (group == null) {
-			throw new StatusException("未找到分组信息");
-		}
-		PaperEntity paper = paperService.getById(group.getPaperId());
-		if (paper == null) {
-			throw new StatusException("未找到试卷结构");
-		}
-		examService.checkExamStatus(paper.getExamId());
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		this.removeById(groupId);
-		paperGroupUnitService.removeByGroupId(groupId);
-
-		UpdateWrapper<PaperEntity> paperEntityUpdateWrapper = new UpdateWrapper<>();
-		paperEntityUpdateWrapper.lambda().set(PaperEntity::getGroupFinish, false).eq(PaperEntity::getId, paper.getId());
-		if (this.count(new QueryWrapper<PaperGroupEntity>().lambda().eq(PaperGroupEntity::getPaperId, paper.getId()))
-				== 0) {
-			paperEntityUpdateWrapper.lambda().set(PaperEntity::getDefaultDoubleSet, null);
-		}
-		paperService.update(paperEntityUpdateWrapper);
-	}
-
-	@Override
-	public Boolean existsGroup(Long paperId) {
-		QueryWrapper<PaperGroupEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperGroupEntity> lw = wrapper.lambda();
-		lw.eq(PaperGroupEntity::getPaperId, paperId);
-		return this.count(wrapper)>0;
-	}
-
-	@Transactional
-	@Override
-	public void groupClear(Long paperId, User user) {
-		PaperEntity paper = paperService.getById(paperId);
-		if (paper == null) {
-			throw new StatusException("未找到试卷结构");
-		}
-		examService.checkExamStatus(paper.getExamId());
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		paperGroupUnitService.clearByPaperId(paperId);
-		clearByPaperId(paperId);
-		paper.setGroupFinish(false);
-		paperService.updateById(paper);
-	}
-	private void clearByPaperId(Long paperId) {
-		QueryWrapper<PaperGroupEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperGroupEntity> lw = wrapper.lambda();
-		lw.eq(PaperGroupEntity::getPaperId, paperId);
-		this.remove(wrapper);
-	}
+
+    @Autowired
+    private PaperGroupUnitService paperGroupUnitService;
+
+    @Autowired
+    private PaperService paperService;
+
+    @Autowired
+    private PaperDetailService paperDetailService;
+
+    @Autowired
+    private PaperDetailUnitService paperDetailUnitService;
+
+    @Autowired
+    private CourseService courseService;
+
+    @Autowired
+    private ExamService examService;
+
+    @Override
+    public List<GroupCountVo> findGroupCount(List<Long> paperIds) {
+        return this.baseMapper.findGroupCount(paperIds);
+    }
+
+    @Override
+    public List<PaperGroup> getGroupInfo(Long paperId) {
+        List<PaperGroup> ret = new ArrayList<>();
+        List<PaperGroupEntity> es = getByPaperId(paperId);
+        if (CollectionUtils.isEmpty(es)) {
+            return ret;
+        }
+        Map<Long, PaperGroup> map = new HashMap<>();
+        for (PaperGroupEntity e : es) {
+            PaperGroup vo = new PaperGroup();
+            vo.setNumber(e.getNumber());
+            vo.setDoubleEnable(e.getDoubleEnable());
+            vo.setDoubleRate(e.getDoubleRate());
+            vo.setArbitrateThreshold(e.getArbitrateThreshold());
+            vo.setArbitrateMethod(e.getArbitrateMethod());
+            map.put(e.getId(), vo);
+            ret.add(vo);
+        }
+        Map<Long, List<PaperGroupUnit>> units = paperGroupUnitService.getGroupInfo(paperId);
+        if (units == null || units.size() == 0) {
+            return ret;
+        }
+        for (Long key : units.keySet()) {
+            map.get(key).setGroupUnits(units.get(key));
+        }
+        return ret;
+    }
+
+    private List<PaperGroupEntity> getByPaperId(Long paperId) {
+        QueryWrapper<PaperGroupEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperGroupEntity> lw = wrapper.lambda();
+        lw.eq(PaperGroupEntity::getPaperId, paperId);
+        return this.list(wrapper);
+    }
+
+    @Override
+    public List<GroupVo> groupList(Long paperId, User user) {
+        PaperEntity paper = paperService.getById(paperId);
+        if (paper == null) {
+            throw new StatusException("未找到试卷结构");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        List<GroupVo> ret = new ArrayList<>();
+        List<PaperGroupEntity> es = getByPaperId(paperId);
+        if (CollectionUtils.isEmpty(es)) {
+            return ret;
+        }
+        Map<Long, GroupVo> map = new HashMap<>();
+        for (PaperGroupEntity e : es) {
+            GroupVo vo = new GroupVo();
+            vo.setNumber(e.getNumber());
+            vo.setGroupId(e.getId());
+            map.put(e.getId(), vo);
+            ret.add(vo);
+        }
+        Map<Long, List<PaperGroupUnit>> units = paperGroupUnitService.getGroupInfo(paperId);
+        List<PaperDetailEntity> des = paperDetailService.getByPaperId(paperId);
+        Map<Integer, PaperDetailEntity> detailMap = new HashMap<>();
+        for (PaperDetailEntity de : des) {
+            detailMap.put(de.getNumber(), de);
+        }
+        for (GroupVo vo : ret) {
+            List<PaperGroupUnit> unit = units.get(vo.getGroupId());
+            if (CollectionUtils.isNotEmpty(unit)) {
+                Set<Integer> set = new LinkedHashSet<>();
+                for (PaperGroupUnit u : unit) {
+                    set.add(u.getDetailNumber());
+                }
+                StringBuilder numSb = new StringBuilder();
+                StringBuilder nameSb = new StringBuilder();
+                for (Integer num : set) {
+                    numSb.append(num).append(",");
+                    nameSb.append(detailMap.get(num).getName()).append(",");
+                }
+                vo.setDetailNumbers(numSb.substring(0, numSb.length() - 1));
+                vo.setDetailNames(nameSb.substring(0, nameSb.length() - 1));
+            }
+        }
+        return ret;
+    }
+
+    @Override
+    public GroupInfoVo groupInfo(Long paperId, Integer groupNumber, User user) {
+        PaperEntity paper = paperService.getById(paperId);
+        if (paper == null) {
+            throw new StatusException("未找到试卷结构");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        PaperGroupEntity e = this.getByPaperIdAndNumber(paperId, groupNumber);
+        if (e == null) {
+            return null;
+        }
+        GroupInfoVo vo = new GroupInfoVo();
+        vo.setNumber(e.getNumber());
+        List<PaperDetail> pds = paperDetailService.getStructInfo(paperId);
+        Map<Long, List<PaperGroupUnit>> units = paperGroupUnitService.getGroupInfo(paperId);
+        vo.setStructInfo(getGroupInfo(pds, units.get(e.getId())));
+        vo.setCourseName(courseService.getById(paper.getCourseId()).getName());
+        return vo;
+    }
+
+    private List<PaperDetail> getGroupInfo(List<PaperDetail> pds, List<PaperGroupUnit> units) {
+        List<PaperDetail> ret = new ArrayList<>();
+        Set<Integer> detailSet = new HashSet<>();
+        Set<String> unitSet = new HashSet<>();
+        for (PaperGroupUnit unit : units) {
+            detailSet.add(unit.getDetailNumber());
+            unitSet.add(unit.getDetailNumber() + "-" + unit.getDetailUnitNumber());
+        }
+        for (PaperDetail pd : pds) {
+            if (detailSet.contains(pd.getNumber())) {
+                ret.add(pd);
+                List<PaperDetailUnit> us = new ArrayList<>();
+                for (PaperDetailUnit u : pd.getUnits()) {
+                    if (unitSet.contains(pd.getNumber() + "-" + u.getNumber())) {
+                        us.add(u);
+                    }
+                }
+                pd.setUnits(us);
+            }
+        }
+        return ret;
+    }
+
+    private PaperGroupEntity getByPaperIdAndNumber(Long paperId, Integer groupNumber) {
+        QueryWrapper<PaperGroupEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperGroupEntity> lw = wrapper.lambda();
+        lw.eq(PaperGroupEntity::getPaperId, paperId);
+        lw.eq(PaperGroupEntity::getNumber, groupNumber);
+        return this.getOne(wrapper);
+    }
+
+    @Transactional
+    @Override
+    public void groupSave(PaperGroupDomain domain, User user) {
+
+        Long paperId = domain.getPaperId();
+        if (Objects.isNull(paperId)) {
+            throw new StatusException("试卷结构ID不能为空");
+        }
+        List<PaperDetailUnitEntity> questionDatasource = paperDetailUnitService.list(
+                new QueryWrapper<PaperDetailUnitEntity>().lambda().eq(PaperDetailUnitEntity::getPaperId, paperId));
+
+        Integer groupNumber = domain.getNumber();
+        if (Objects.isNull(groupNumber)) {
+            throw new StatusException("分组号不能为空");
+        }
+        if (CollectionUtils.isEmpty(domain.getGroupUnits())) {
+            throw new StatusException("分组信息不能为空");
+        }
+
+        Boolean doubleEnable = domain.getDoubleEnable();
+        if (Objects.isNull(doubleEnable)) {
+            throw new StatusException("是否开启双评未设置");
+        }
+        Double doubleRate = domain.getDoubleRate();
+        ArbitrateMethod arbitrateMethod = domain.getArbitrateMethod();
+        Double arbitrateThreshold = domain.getArbitrateThreshold();
+        if (doubleEnable) {
+            // 如果开启双评
+
+            if (Objects.isNull(doubleRate) || doubleRate < 0 || doubleRate > 1) {
+                throw new StatusException("双评比例未正确设置");
+            }
+            if (doubleRate == 0) {
+                throw new StatusException("双评比例不能设置为0");
+            }
+            if (Objects.isNull(arbitrateMethod)) {
+                throw new StatusException("仲裁方式未设置");
+            }
+            if (ArbitrateMethod.GROUP_ARBITRATE.equals(arbitrateMethod)) {
+                if (Objects.isNull(arbitrateThreshold) || (arbitrateThreshold < 0)) {
+                    throw new StatusException("仲裁值未正确设置");
+                }
+            }
+        }
+
+        double totalScore = 0.0;
+        for (PaperGroupUnit u : domain.getGroupUnits()) {
+            // 小题仲裁阈值
+            Double questionArbitrateThreshold = u.getArbitrateThreshold();
+            if (u.getDetailNumber() == null || u.getDetailUnitNumber() == null) {
+                throw new StatusException("大题号、小题号不能为空");
+            }
+
+            List<PaperDetailUnitEntity> questionList = questionDatasource.stream()
+                    .filter(e -> e.getDetailNumber().equals(u.getDetailNumber())
+                            && e.getNumber().equals(u.getDetailUnitNumber()))
+                    .collect(Collectors.toList());
+            if (questionList.size() != 1) {
+                throw new StatusException(
+                        String.format("题目%d-%d不存在,或存在多个", u.getDetailNumber(), u.getDetailUnitNumber()));
+            }
+            double questionScore = questionList.get(0).getScore();
+            totalScore = totalScore + questionScore;
+            if (ArbitrateMethod.QUESTION_ARBITRATE.equals(arbitrateMethod)) {
+                if (Objects.isNull(questionArbitrateThreshold) || questionArbitrateThreshold < 0) {
+                    throw new StatusException("仲裁值未正确设置");
+                }
+                if (questionArbitrateThreshold > questionScore) {
+                    throw new StatusException(
+                            String.format("题目%d-%d仲裁值大于题目分数", u.getDetailNumber(), u.getDetailUnitNumber()));
+                }
+            }
+            if (!doubleEnable || ArbitrateMethod.GROUP_ARBITRATE.equals(arbitrateMethod)) {
+                u.setArbitrateThreshold(null);
+            }
+        }
+        if (ArbitrateMethod.GROUP_ARBITRATE.equals(arbitrateMethod) && arbitrateThreshold > totalScore) {
+            throw new StatusException("仲裁值大于分组总分");
+        }
+
+        PaperEntity paper = paperService.getById(paperId);
+        if (paper == null) {
+            throw new StatusException("未找到试卷结构");
+        }
+        examService.checkExamStatus(paper.getExamId());
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        if (!paper.getStructFinish()) {
+            throw new StatusException("试卷结构未提交,不能设置分组");
+        }
+        Long groupId = domain.getGroupId();
+        // 参数处理
+        if (!doubleEnable) {
+            // 未开启双评
+            doubleRate = null;
+            arbitrateThreshold = null;
+            arbitrateMethod = null;
+        } else {
+            if (ArbitrateMethod.QUESTION_ARBITRATE.equals(arbitrateMethod)) {
+                arbitrateThreshold = null;
+            }
+        }
+        if (Objects.nonNull(groupId)) {
+            // 编辑
+            paperGroupUnitService.removeByGroupId(groupId);
+            UpdateWrapper<PaperGroupEntity> paperGroupEntityUpdateWrapper = new UpdateWrapper<>();
+            paperGroupEntityUpdateWrapper.lambda().eq(PaperGroupEntity::getId, groupId)
+                    .set(PaperGroupEntity::getNumber, groupNumber).set(PaperGroupEntity::getDoubleEnable, doubleEnable)
+                    .set(PaperGroupEntity::getDoubleRate, doubleRate)
+                    .set(PaperGroupEntity::getArbitrateThreshold, arbitrateThreshold)
+                    .set(PaperGroupEntity::getArbitrateMethod, arbitrateMethod);
+            this.update(paperGroupEntityUpdateWrapper);
+        } else {
+            // 新增
+            PaperGroupEntity paperGroupEntity = new PaperGroupEntity();
+            paperGroupEntity.setPaperId(paperId);
+            paperGroupEntity.setNumber(groupNumber);
+            paperGroupEntity.setDoubleEnable(doubleEnable);
+            paperGroupEntity.setDoubleRate(doubleRate);
+            paperGroupEntity.setArbitrateMethod(arbitrateMethod);
+            paperGroupEntity.setArbitrateThreshold(arbitrateThreshold);
+            this.save(paperGroupEntity);
+            groupId = paperGroupEntity.getId();
+        }
+
+        List<PaperDetail> pds = paperDetailService.getStructInfo(paperId);
+        if (CollectionUtils.isEmpty(pds)) {
+            throw new StatusException("试卷结构小题信息为空");
+        }
+        checkStruct(pds, domain.getGroupUnits());
+        paperGroupUnitService.saveUnit(groupId, paperId, domain.getGroupUnits());
+        paper.setGroupFinish(
+                paperGroupUnitService.countByPaperId(paperId).equals(paperDetailUnitService.countByPaperId(paperId)));
+
+        DefaultDoubleSet defaultDoubleSet = domain.getDefaultDoubleSet();
+        if (Objects.nonNull(defaultDoubleSet)) {
+            paper.setDefaultDoubleSet(JSON.toJSONString(defaultDoubleSet));
+        }
+        paperService.updateById(paper);
+    }
+
+    private void checkStruct(List<PaperDetail> pds, List<PaperGroupUnit> groupUnits) {
+        for (PaperGroupUnit groupUnit : groupUnits) {
+            checkStructExists(pds, groupUnit);
+        }
+    }
+
+    private void checkStructExists(List<PaperDetail> pds, PaperGroupUnit groupUnit) {
+        for (PaperDetail pd : pds) {
+            if (pd.getNumber().equals(groupUnit.getDetailNumber())) {
+                for (PaperDetailUnit u : pd.getUnits()) {
+                    if (u.getNumber().equals(groupUnit.getDetailUnitNumber())) {
+                        return;
+                    }
+                }
+            }
+        }
+        throw new StatusException(
+                "试卷结构中大题号:" + groupUnit.getDetailNumber() + " 小题号:" + groupUnit.getDetailUnitNumber() + "不存在");
+    }
+
+    @Transactional
+    @Override
+    public void groupDelete(Long groupId, User user) {
+        PaperGroupEntity group = this.getById(groupId);
+        if (group == null) {
+            throw new StatusException("未找到分组信息");
+        }
+        PaperEntity paper = paperService.getById(group.getPaperId());
+        if (paper == null) {
+            throw new StatusException("未找到试卷结构");
+        }
+        examService.checkExamStatus(paper.getExamId());
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        this.removeById(groupId);
+        paperGroupUnitService.removeByGroupId(groupId);
+
+        UpdateWrapper<PaperEntity> paperEntityUpdateWrapper = new UpdateWrapper<>();
+        paperEntityUpdateWrapper.lambda().set(PaperEntity::getGroupFinish, false).eq(PaperEntity::getId, paper.getId());
+        if (this.count(
+                new QueryWrapper<PaperGroupEntity>().lambda().eq(PaperGroupEntity::getPaperId, paper.getId())) == 0) {
+            paperEntityUpdateWrapper.lambda().set(PaperEntity::getDefaultDoubleSet, null);
+        }
+        paperService.update(paperEntityUpdateWrapper);
+    }
+
+    @Override
+    public Boolean existsGroup(Long paperId) {
+        QueryWrapper<PaperGroupEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperGroupEntity> lw = wrapper.lambda();
+        lw.eq(PaperGroupEntity::getPaperId, paperId);
+        return this.count(wrapper) > 0;
+    }
+
+    @Transactional
+    @Override
+    public void groupClear(Long paperId, User user) {
+        PaperEntity paper = paperService.getById(paperId);
+        if (paper == null) {
+            throw new StatusException("未找到试卷结构");
+        }
+        examService.checkExamStatus(paper.getExamId());
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        paperGroupUnitService.clearByPaperId(paperId);
+        clearByPaperId(paperId);
+        paper.setGroupFinish(false);
+        paperService.updateById(paper);
+    }
+
+    private void clearByPaperId(Long paperId) {
+        QueryWrapper<PaperGroupEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperGroupEntity> lw = wrapper.lambda();
+        lw.eq(PaperGroupEntity::getPaperId, paperId);
+        this.remove(wrapper);
+    }
 }

+ 72 - 71
src/main/java/cn/com/qmth/mps/service/impl/PaperGroupUnitServiceImpl.java

@@ -17,81 +17,82 @@ import cn.com.qmth.mps.entity.PaperGroupUnitEntity;
 import cn.com.qmth.mps.service.PaperGroupUnitService;
 
 @Service
-public class PaperGroupUnitServiceImpl extends ServiceImpl<PaperGroupUnitDao, PaperGroupUnitEntity> implements PaperGroupUnitService {
+public class PaperGroupUnitServiceImpl extends ServiceImpl<PaperGroupUnitDao, PaperGroupUnitEntity>
+        implements PaperGroupUnitService {
 
-	@Override
-	public Map<Long, List<PaperGroupUnit>> getGroupInfo(Long paperId) {
-		List<PaperGroupUnitEntity> list = getByPaperId(paperId);
-		if (CollectionUtils.isEmpty(list)) {
-			return null;
-		}
-		Map<Long, List<PaperGroupUnit>> ret = new HashMap<>();
-		for (PaperGroupUnitEntity e : list) {
-			List<PaperGroupUnit> tem = ret.get(e.getGroupId());
-			if (tem == null) {
-				tem = new ArrayList<>();
-				ret.put(e.getGroupId(), tem);
-			}
-			PaperGroupUnit vo = new PaperGroupUnit();
-			vo.setDetailNumber(e.getDetailNumber());
-			vo.setDetailUnitNumber(e.getDetailUnitNumber());
-			vo.setArbitrateThreshold(e.getArbitrateThreshold());
-			tem.add(vo);
-		}
-		return ret;
-	}
+    @Override
+    public Map<Long, List<PaperGroupUnit>> getGroupInfo(Long paperId) {
+        List<PaperGroupUnitEntity> list = getByPaperId(paperId);
+        if (CollectionUtils.isEmpty(list)) {
+            return null;
+        }
+        Map<Long, List<PaperGroupUnit>> ret = new HashMap<>();
+        for (PaperGroupUnitEntity e : list) {
+            List<PaperGroupUnit> tem = ret.get(e.getGroupId());
+            if (tem == null) {
+                tem = new ArrayList<>();
+                ret.put(e.getGroupId(), tem);
+            }
+            PaperGroupUnit vo = new PaperGroupUnit();
+            vo.setDetailNumber(e.getDetailNumber());
+            vo.setDetailUnitNumber(e.getDetailUnitNumber());
+            vo.setArbitrateThreshold(e.getArbitrateThreshold());
+            tem.add(vo);
+        }
+        return ret;
+    }
 
-	@Override
-	public List<PaperGroupUnitEntity> getByPaperId(Long paperId) {
-		QueryWrapper<PaperGroupUnitEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperGroupUnitEntity> lw = wrapper.lambda();
-		lw.eq(PaperGroupUnitEntity::getPaperId, paperId);
-		lw.orderByAsc(PaperGroupUnitEntity::getDetailNumber);
-		lw.orderByAsc(PaperGroupUnitEntity::getDetailUnitNumber);
-		return this.list(wrapper);
-	}
+    @Override
+    public List<PaperGroupUnitEntity> getByPaperId(Long paperId) {
+        QueryWrapper<PaperGroupUnitEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperGroupUnitEntity> lw = wrapper.lambda();
+        lw.eq(PaperGroupUnitEntity::getPaperId, paperId);
+        lw.orderByAsc(PaperGroupUnitEntity::getDetailNumber);
+        lw.orderByAsc(PaperGroupUnitEntity::getDetailUnitNumber);
+        return this.list(wrapper);
+    }
 
-	@Transactional
-	@Override
-	public void removeByGroupId(Long groupId) {
-		QueryWrapper<PaperGroupUnitEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperGroupUnitEntity> lw = wrapper.lambda();
-		lw.eq(PaperGroupUnitEntity::getGroupId, groupId);
-		this.remove(wrapper);
-	}
+    @Transactional
+    @Override
+    public void removeByGroupId(Long groupId) {
+        QueryWrapper<PaperGroupUnitEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperGroupUnitEntity> lw = wrapper.lambda();
+        lw.eq(PaperGroupUnitEntity::getGroupId, groupId);
+        this.remove(wrapper);
+    }
 
-	@Transactional
-	@Override
-	public void saveUnit(Long groupId, Long paperId, List<PaperGroupUnit> groupUnits) {
-		List<PaperGroupUnitEntity> ret = new ArrayList<>();
-		for (PaperGroupUnit unit : groupUnits) {
-			PaperGroupUnitEntity e = new PaperGroupUnitEntity();
-			e.setPaperId(paperId);
-			e.setGroupId(groupId);
-			e.setDetailNumber(unit.getDetailNumber());
-			e.setDetailUnitNumber(unit.getDetailUnitNumber());
-			if (Objects.nonNull(unit.getArbitrateThreshold())){
-				e.setArbitrateThreshold(unit.getArbitrateThreshold());
-			}
-			ret.add(e);
-		}
-		this.saveBatch(ret);
-	}
+    @Transactional
+    @Override
+    public void saveUnit(Long groupId, Long paperId, List<PaperGroupUnit> groupUnits) {
+        List<PaperGroupUnitEntity> ret = new ArrayList<>();
+        for (PaperGroupUnit unit : groupUnits) {
+            PaperGroupUnitEntity e = new PaperGroupUnitEntity();
+            e.setPaperId(paperId);
+            e.setGroupId(groupId);
+            e.setDetailNumber(unit.getDetailNumber());
+            e.setDetailUnitNumber(unit.getDetailUnitNumber());
+            if (Objects.nonNull(unit.getArbitrateThreshold())) {
+                e.setArbitrateThreshold(unit.getArbitrateThreshold());
+            }
+            ret.add(e);
+        }
+        this.saveBatch(ret);
+    }
 
-	@Override
-	public Integer countByPaperId(Long paperId) {
-		QueryWrapper<PaperGroupUnitEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperGroupUnitEntity> lw = wrapper.lambda();
-		lw.eq(PaperGroupUnitEntity::getPaperId, paperId);
-		return this.count(wrapper);
-	}
+    @Override
+    public Integer countByPaperId(Long paperId) {
+        QueryWrapper<PaperGroupUnitEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperGroupUnitEntity> lw = wrapper.lambda();
+        lw.eq(PaperGroupUnitEntity::getPaperId, paperId);
+        return this.count(wrapper);
+    }
 
-	@Transactional
-	@Override
-	public void clearByPaperId(Long paperId) {
-		QueryWrapper<PaperGroupUnitEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperGroupUnitEntity> lw = wrapper.lambda();
-		lw.eq(PaperGroupUnitEntity::getPaperId, paperId);
-		this.remove(wrapper);
-	}
+    @Transactional
+    @Override
+    public void clearByPaperId(Long paperId) {
+        QueryWrapper<PaperGroupUnitEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperGroupUnitEntity> lw = wrapper.lambda();
+        lw.eq(PaperGroupUnitEntity::getPaperId, paperId);
+        this.remove(wrapper);
+    }
 }

+ 741 - 735
src/main/java/cn/com/qmth/mps/service/impl/PaperServiceImpl.java

@@ -44,740 +44,746 @@ import cn.com.qmth.mps.vo.paper.*;
 
 @Service
 public class PaperServiceImpl extends ServiceImpl<PaperDao, PaperEntity> implements PaperService {
-	private static final String[] SUBJECT_EXCEL_HEADER = new String[] {"科目代码", "科目名称"};
-
-	private static final String[] SUBJECT_STRUCT_EXCEL_HEADER = new String[] {"科目代码*","科目名称","大题名称*","题目昵称","大题号(只能用小写数字)*","小题号(只能用小写数字)*","小题满分*","间隔分*","评卷分组(只能用小写数字)*","图片序号(用英文逗号分割)","仲裁方式(0-分组,1-小题)","双评比例(0~1)","仲裁阀值","合分策略(1-平均,2-最高,3-最低)","评卷模式(common-普通,track-轨迹)","试评数量(0-跳过试评)","选做题数量"};
-
-	@Autowired
-	private ExamService examService;
-
-	@Autowired
-	private CourseService courseService;
-	@Autowired
-	private PaperGroupService paperGroupService;
-	@Autowired
-	private PaperDetailService paperDetailService;
-
-	@Transactional
-	@Override
-	public List<String> importPaper(Long examId, User user, MultipartFile file) {
-		ExamEntity exam = examService.getById(examId);
-		if (exam == null) {
-			throw new StatusException("未找到考试批次");
-		}
-		if(!ExamStatus.EDIT.equals(exam.getExamStatus())) {
-			throw new StatusException("考试未开放上报,不能设置结构信息或分组信息");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(exam.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		InputStream inputStream = null;
-		try {
-			inputStream = file.getInputStream();
-			ExcelReader reader=ExcelReader.create(ExcelType.XLSX, inputStream, 0);
-			List<DataMap> lineList = reader.getDataMapList();
-			if(!Arrays.equals(SUBJECT_EXCEL_HEADER,reader.getColumnNames())) {
-				throw new StatusException("Excel表头错误");
-			}
-			if (CollectionUtils.isEmpty(lineList)) {
-				throw new StatusException("Excel无内容");
-			}
-			if (1001 < lineList.size()) {
-				throw new StatusException("数据行数不能超过1000");
-			}
-			List<String> failRecords = new ArrayList<>();
-			List<PaperEntity> ret = new ArrayList<>();
-			for (int i = 0; i < lineList.size(); i++) {
-				DataMap line = lineList.get(i);
-
-				StringBuilder msg = new StringBuilder();
-
-				PaperEntity imp = new PaperEntity();
-				imp.setTotalScore(0.0);
-				imp.setObjectiveScore(0.0);
-				imp.setSubjectiveScore(0.0);
-				imp.setSchoolId(exam.getSchoolId());
-				imp.setGroupFinish(false);
-				imp.setStructFinish(false);
-				imp.setExamId(examId);
-				String code = trimAndNullIfBlank(line.get(SUBJECT_EXCEL_HEADER[0]));
-				if (StringUtils.isBlank(code)) {
-					msg.append("  科目代码不能为空");
-				} else if (code.length() > 50) {
-					msg.append("  科目代码不能超过50个字符");
-				}
-
-				String name = trimAndNullIfBlank(line.get(SUBJECT_EXCEL_HEADER[1]));
-				if (StringUtils.isBlank(name)) {
-					msg.append("  科目名称不能为空");
-				} else if (name.length() > 50) {
-					msg.append("  科目名称不能超过50个字符");
-				}
-				if (msg.length() == 0) {
-					CourseEntity course = courseService.saveOrGet(exam.getSchoolId(), code, name);
-					imp.setCourseId(course.getId());
-				}
-
-				if (msg.length() > 0) {
-					failRecords.add(newError(i + 1, msg.toString()));
-				} else {
-					ret.add(imp);
-				}
-
-			}
-			if (CollectionUtils.isNotEmpty(failRecords)) {
-				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-				return failRecords;
-			}
-			for (int i = 0; i < ret.size(); i++) {
-				PaperEntity cur = ret.get(i);
-				try {
-					this.save(cur);
-				} catch (DuplicateKeyException e) {
-//					failRecords.add(newError(i + 1, "科目已存在"));
-				} catch (Exception e) {
-					failRecords.add(newError(i + 1, "系统异常"));
-					log.error("科目导入系统异常", e);
-				}
-			}
-			if (CollectionUtils.isNotEmpty(failRecords)) {
-				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-			}
-			return failRecords;
-		} catch (StatusException e) {
-			throw e;
-		} catch (Exception e) {
-			throw new RuntimeException("系统错误", e);
-		} finally {
-			if (inputStream != null) {
-				try {
-					inputStream.close();
-				} catch (IOException e) {
-				}
-			}
-		}
-	}
-	
-
-	private String trimAndNullIfBlank(String s) {
-		if (StringUtils.isBlank(s)) {
-			return null;
-		}
-		return s.trim();
-	}
-
-	private String newError(int lineNum, String msg) {
-		return "第" + lineNum + "行" + msg;
-	}
-
-	@Override
-	public List<ExamPaperCountVo> findPaperCount(List<Long> examIds) {
-		return this.baseMapper.findPaperCount(examIds);
-	}
-
-	@Override
-	public Integer findPaperCount(Long examId) {
-		QueryWrapper<PaperEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperEntity> lw = wrapper.lambda();
-		lw.eq(PaperEntity::getExamId, examId);
-		return this.count(wrapper);
-	}
-
-	private PaperEntity findByExamAndCourse(Long examId, Long courseId) {
-		QueryWrapper<PaperEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<PaperEntity> lw = wrapper.lambda();
-		lw.eq(PaperEntity::getExamId, examId);
-		lw.eq(PaperEntity::getCourseId, courseId);
-		return this.getOne(wrapper);
-	}
-
-	private PaperEntity saveOrGet(Long schoolId, Long examId, Long courseId) {
-		PaperEntity ret = findByExamAndCourse(examId, courseId);
-		if (ret != null) {
-			return ret;
-		}
-		PaperEntity imp = new PaperEntity();
-		imp.setTotalScore(0.0);
-		imp.setObjectiveScore(0.0);
-		imp.setSubjectiveScore(0.0);
-		imp.setSchoolId(schoolId);
-		imp.setGroupFinish(false);
-		imp.setCourseId(courseId);
-		imp.setExamId(examId);
-		imp.setStructFinish(true);
-		this.save(imp);
-		return imp;
-	}
-
-	@Override
-	public PageResult<PaperVo> page(PaperQuery query, User user) {
-		if (query.getSchoolId() == null) {
-			throw new StatusException("学校不能为空");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(query.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		IPage<PaperVo> iPage = this.baseMapper.page(new Page<>(query.getPageNumber(), query.getPageSize()),
-				query);
-		if (CollectionUtils.isNotEmpty(iPage.getRecords())) {
-			new BatchSetDataUtil<PaperVo>() {
-
-				@Override
-				protected void setData(List<PaperVo> dataList) {
-					List<Long> paperIds = dataList.stream().map(PaperVo::getId).distinct()
-							.collect(Collectors.toList());
-					List<GroupCountVo> ret = paperGroupService.findGroupCount(paperIds);
-					if (ret != null && ret.size() > 0) {
-						Map<Long, Integer> countMap = new HashMap<>();
-						Map<Long, Boolean> doubleEnableMap = new HashMap<>();
-						for (GroupCountVo item : ret) {
-							countMap.put(item.getPaperId(), item.getGroupCount());
-							doubleEnableMap.put(item.getPaperId(), item.getDoubleEnable());
-						}
-						for (PaperVo vo : dataList) {
-							vo.setGroupCount(countMap.get(vo.getId()));
-							vo.setDoubleEnable(doubleEnableMap.get(vo.getId()));
-						}
-					}
-				}
-			}.setDataForBatch(iPage.getRecords(), 20);
-			for (PaperVo vo : iPage.getRecords()) {
-				if (vo.getGroupCount() == null) {
-					vo.setGroupCount(0);
-				}
-			}
-		}
-		return PageUtil.of(iPage);
-	}
-
-	@Override
-	public List<PaperVo> list(Long examId, User user) {
-		ExamEntity exam = examService.getById(examId);
-		if (exam == null) {
-			throw new StatusException("未找到考试批次");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(exam.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		List<PaperVo> ret=this.baseMapper.myPaperlist(examId,user.getId());
-		if (CollectionUtils.isNotEmpty(ret)) {
-			new BatchSetDataUtil<PaperVo>() {
-
-				@Override
-				protected void setData(List<PaperVo> dataList) {
-					List<Long> paperIds = dataList.stream().map(dto -> dto.getId()).distinct()
-							.collect(Collectors.toList());
-					List<GroupCountVo> ret = paperGroupService.findGroupCount(paperIds);
-					if (ret != null && ret.size() > 0) {
-						Map<Long, Integer> countMap = new HashMap<>();
-						for (GroupCountVo item : ret) {
-							countMap.put(item.getPaperId(), item.getGroupCount());
-						}
-						for (PaperVo vo : dataList) {
-							vo.setGroupCount(countMap.get(vo.getId()));
-						}
-					}
-				}
-			}.setDataForBatch(ret, 20);
-		}
-		return ret;
-	}
-
-	@Override
-	public PaperInfoVo info(Long id, User user) {
-		PaperEntity paper = this.getById(id);
-		if (paper == null) {
-			throw new StatusException("未找到试卷结构信息");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		PaperInfoVo vo = new PaperInfoVo();
-		BeanUtils.copyProperties(paper, vo);
-		CourseEntity course = courseService.getById(vo.getCourseId());
-		vo.setCourseCode(course.getCode());
-		vo.setCourseName(course.getName());
-		vo.setStructInfo(paperDetailService.getStructInfo(vo.getId()));
-		vo.setGroupInfo(paperGroupService.getGroupInfo(vo.getId()));
-
-		String defaultDoubleSetStr = paper.getDefaultDoubleSet();
-		if (!StringUtils.isBlank(defaultDoubleSetStr)) {
-			vo.setDefaultDoubleSet(JSON.parseObject(defaultDoubleSetStr, DefaultDoubleSet.class));
-		}
-		return vo;
-	}
-
-	@Transactional
-	@Override
-	public List<String> importSubjectStruct(Long examId, User user, MultipartFile file) {
-		ExamEntity exam = examService.getById(examId);
-		if (exam == null) {
-			throw new StatusException("未找到考试批次");
-		}
-		if(!ExamStatus.EDIT.equals(exam.getExamStatus())) {
-			throw new StatusException("考试未开放上报,不能设置结构信息或分组信息");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(exam.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		InputStream inputStream = null;
-		try {
-			inputStream = file.getInputStream();
-			ExcelReader reader=ExcelReader.create(ExcelType.XLSX, inputStream, 1);
-			List<DataMap> lineList = reader.getDataMapList();
-			if(!Arrays.equals(SUBJECT_STRUCT_EXCEL_HEADER,reader.getColumnNames())) {
-				throw new StatusException("Excel表头错误");
-			}
-			if (CollectionUtils.isEmpty(lineList)) {
-				throw new StatusException("Excel无内容");
-			}
-			if (10001 < lineList.size()) {
-				throw new StatusException("数据行数不能超过10000");
-			}
-			List<String> failRecords = new ArrayList<>();
-			List<PaperStructInfoVo> ret = new ArrayList<>();
-			// 双评设置
-			Map<String, DoubleMarkImportParam> doubleMarkSettingMap = new HashMap<>();
-			for (int i = 0; i < lineList.size(); i++) {
-				DataMap line = lineList.get(i);
-
-				StringBuilder msg = new StringBuilder();
-
-				PaperStructInfoVo imp = new PaperStructInfoVo();
-				String code = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[0]));
-				if (StringUtils.isBlank(code)) {
-					msg.append("  科目代码不能为空");
-				} else if (code.length() > 50) {
-					msg.append("  科目代码不能超过50个字符");
-				}
-				imp.setCourseCode(code);
-
-				String name = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[1]));
-				if (StringUtils.isBlank(name)) {
-					msg.append("  科目名称不能为空");
-				} else if (name.length() > 50) {
-					msg.append("  科目名称不能超过50个字符");
-				}
-				if (msg.length() == 0) {
-					CourseEntity course = courseService.saveOrGet(exam.getSchoolId(), code, name);
-					PaperEntity paper = saveOrGet(exam.getSchoolId(), examId, course.getId());
-					imp.setPaperId(paper.getId());
-				}
-
-				String detailName = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[2]));
-				if (StringUtils.isBlank(detailName)) {
-					msg.append("  大题名称不能为空");
-				} else if (detailName.length() > 50) {
-					msg.append("  大题名称不能超过50个字符");
-				}
-				imp.setDetailName(detailName);
-				//第4列不处理
-				String detailNumber = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[4]));
-				if (StringUtils.isBlank(detailNumber)) {
-					msg.append("  大题号不能为空");
-				} else {
-					try {
-						int n = Integer.valueOf(detailNumber);
-						if (n <= 0) {
-							msg.append("  大题号不能小于0");
-						} else {
-							imp.setDetailNumber(n);
-						}
-					} catch (Exception e) {
-						msg.append("  大题号只能是整数");
-					}
-
-				}
-
-				String unitNumber = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[5]));
-				if (StringUtils.isBlank(unitNumber)) {
-					msg.append("  小题号不能为空");
-				} else {
-					try {
-						int n = Integer.valueOf(unitNumber);
-						if (n <= 0) {
-							msg.append("  小题号不能小于0");
-						} else {
-							imp.setUnitNumber(n);
-						}
-					} catch (Exception e) {
-						msg.append("  小题号只能是整数");
-					}
-
-				}
-
-				String score = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[6]));
-				if (StringUtils.isBlank(score)) {
-					msg.append("  小题满分不能为空");
-				} else {
-					try {
-						Double n = Double.valueOf(score);
-						if (n <= 0) {
-							msg.append("  小题满分不能小于0");
-						} else {
-							if (score.indexOf(".")>=0&&score.indexOf(".") < score.length() - 2) {
-								msg.append("小题满分只能有一位小数");
-							} else {
-								imp.setScore(n);
-							}
-						}
-					} catch (Exception e) {
-						msg.append("  小题满分格式错误");
-					}
-
-				}
-
-				String scoreStep = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[7]));
-				if (StringUtils.isBlank(scoreStep)) {
-					msg.append("  间隔分不能为空");
-				} else {
-					try {
-						Double n = Double.valueOf(scoreStep);
-						if (n <= 0) {
-							msg.append("  间隔分不能小于0");
-						} else {
-							if (scoreStep.indexOf(".")>=0&&scoreStep.indexOf(".") < scoreStep.length() - 2) {
-								msg.append("小间隔分只能有一位小数");
-							} else {
-								imp.setScoreStep(n);
-							}
-						}
-					} catch (Exception e) {
-						msg.append("  间隔分格式错误");
-					}
-
-				}
-
-				String groupNumberStr = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[8]));
-				if (StringUtils.isNotBlank(groupNumberStr)) {
-					try {
-						Integer n = Integer.valueOf(groupNumberStr);
-						if (n <= 0) {
-							msg.append("  评卷分组不能小于0");
-						} else {
-							imp.setGroupNumber(n);
-						}
-					} catch (Exception e) {
-						msg.append("  评卷分组格式错误");
-					}
-				}
-
-				Long paperId = imp.getPaperId();
-				Integer groupNumber = imp.getGroupNumber();
-				Double questionScore = imp.getScore();
-				if (Objects.nonNull(paperId) && Objects.nonNull(groupNumber) && Objects.nonNull(questionScore)) {
-					// 有分组信息才解析双评信息
-					String groupKey = paperId + "-" + groupNumber;
-					ArbitrateMethod arbitrateMethod = null;
-					Double doubleRate = null;
-					Double arbitrateThreshold = null;
-
-					if (doubleMarkSettingMap.containsKey(groupKey)) {
-						DoubleMarkImportParam doubleMarkImportParam = doubleMarkSettingMap.get(groupKey);
-						arbitrateMethod = doubleMarkImportParam.getArbitrateMethod();
-						doubleRate = doubleMarkImportParam.getDoubleRate();
-						arbitrateThreshold = doubleMarkImportParam.getArbitrateThreshold();
-					}
-
-					String arbitrateMethodStr = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[10]));
-					String doubleRateStr = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[11]));
-					String arbitrateThresholdStr = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[12]));
-
-					// 双评比例
-					if (StringUtils.isNotBlank(doubleRateStr)) {
-						try {
-							double n = Double.parseDouble(doubleRateStr);
-
-							if (n < 0 || n > 1) {
-								msg.append("  双评比例只能在(0~1)");
-							} else {
-								if (Objects.nonNull(doubleRate) && !doubleRate.equals(n)) {
-									msg.append("  同分组的双评比例必须相同");
-								} else {
-									doubleRate = n;
-									imp.setDoubleRate(doubleRate);
-								}
-							}
-						} catch (Exception e) {
-							msg.append("  双评比例格式错误");
-						}
-					}
-
-					if (Objects.nonNull(doubleRate) && doubleRate > 0) {
-						// 开启双评才继续解析 仲裁方式和仲裁值
-						// 仲裁方式(0-分组,1-小题)
-						if (StringUtils.isNotBlank(arbitrateMethodStr)) {
-							try {
-								int n = Integer.parseInt(arbitrateMethodStr);
-								List<ArbitrateMethod> arbitrateMethodList = Arrays.stream(ArbitrateMethod.values())
-										.filter(e -> e.getValue().equals(n)).collect(Collectors.toList());
-								if (arbitrateMethodList.size() != 1) {
-									msg.append("  仲裁方式只能选择0或1");
-								} else {
-									if (Objects.nonNull(arbitrateMethod) && !arbitrateMethod.equals(
-											arbitrateMethodList.get(0))) {
-										msg.append("  同分组的仲裁方式必须相同");
-									} else {
-										arbitrateMethod = arbitrateMethodList.get(0);
-										imp.setArbitrateMethod(arbitrateMethod);
-									}
-								}
-							} catch (Exception e) {
-								msg.append("  仲裁方式格式错误");
-							}
-						} else {
-							msg.append("  仲裁方式不能为空");
-						}
-
-						if (Objects.nonNull(arbitrateMethod)) {
-							// 仲裁方式不为空才解析
-							// 仲裁阀值
-							if (StringUtils.isNotBlank(arbitrateThresholdStr)) {
-								try {
-									double n = Double.parseDouble(arbitrateThresholdStr);
-									if (n < 0) {
-										msg.append("  仲裁阀值不能小于0");
-									}
-									if (ArbitrateMethod.QUESTION_ARBITRATE.equals(arbitrateMethod)) {
-										if (n > questionScore) {
-											msg.append("  仲裁阀值不能超过小题满分");
-										}
-									} else if (ArbitrateMethod.GROUP_ARBITRATE.equals(arbitrateMethod)) {
-										if (Objects.nonNull(arbitrateThreshold) && !arbitrateThreshold.equals(n)) {
-											msg.append("  同分组的仲裁阀值必须相同");
-										}
-									}
-									arbitrateThreshold = n;
-									imp.setArbitrateThreshold(n);
-								} catch (Exception e) {
-									msg.append("  仲裁阀值格式错误");
-								}
-							} else {
-								msg.append("  仲裁阀值不能为空");
-							}
-						}
-					}
-					if (!doubleMarkSettingMap.containsKey(groupKey)) {
-						List<Integer> indexList = new ArrayList<>();
-						indexList.add(i + 3);
-						doubleMarkSettingMap.put(groupKey,
-								new DoubleMarkImportParam(arbitrateMethod, doubleRate, arbitrateThreshold, indexList,
-										questionScore));
-					} else {
-						DoubleMarkImportParam cellMap = doubleMarkSettingMap.get(groupKey);
-						cellMap.getIndexes().add(i + 3);
-						cellMap.setTotalScore(cellMap.getTotalScore() + questionScore);
-					}
-				}
-				if (msg.length() > 0) {
-					failRecords.add(newError(i + 3, msg.toString()));
-				} else {
-					ret.add(imp);
-				}
-			}
-			// 检测分组仲裁的分组 分组阈值设置是否超过整组分数
-			doubleMarkSettingMap.forEach((k, v) -> {
-				if (v.getArbitrateMethod() != null && v.getArbitrateMethod().equals(ArbitrateMethod.GROUP_ARBITRATE)) {
-					if (v.getArbitrateThreshold() > v.getTotalScore()) {
-						failRecords.add(newError(v.getIndexes().get(0), " 分组仲裁阀值不能超过分组满分"));
-					}
-				}
-			});
-			if (CollectionUtils.isNotEmpty(failRecords)) {
-				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-				return failRecords;
-			}
-			this.saveStruct(ret, user, failRecords);
-			if (CollectionUtils.isNotEmpty(failRecords)) {
-				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-			}
-			return failRecords;
-		} catch (StatusException e) {
-			throw e;
-		} catch (Exception e) {
-			throw new RuntimeException("系统错误", e);
-		} finally {
-			if (inputStream != null) {
-				try {
-					inputStream.close();
-				} catch (IOException e) {
-				}
-			}
-		}
-	}
-
-	private void saveStruct(List<PaperStructInfoVo> cards, User user, List<String> failRecords) {
-		Map<Long,String> map=new HashMap<>();
-		for(PaperStructInfoVo vo:cards) {
-			map.put(vo.getPaperId(), vo.getCourseCode());
-		}
-		List<StructDomain> ces = getBeans(cards);
-//		checkStruct(ces, failRecords,map);
-		if (CollectionUtils.isNotEmpty(failRecords)) {
-			return;
-		}
-		for (StructDomain domain : ces) {
-			try {
-				paperDetailService.structImport(domain, user);
-			} catch (StatusException e) {
-				failRecords.add("科目:"+map.get(domain.getPaperId())+" "+e.getMessage());
-			} catch (Exception e) {
-				throw new RuntimeException("系统错误", e);
-			}
-		}
-		List<PaperGroupDomain> list = getPaperGroups(cards);
-		for (PaperGroupDomain domain : list) {
-			try {
-				paperGroupService.groupSave(domain, user);
-			} catch (StatusException e) {
-				failRecords.add("科目:"+map.get(domain.getPaperId())+" "+e.getMessage());
-			} catch (Exception e) {
-				throw new RuntimeException("系统错误", e);
-			}
-		}
-
-	}
-
-	private List<PaperGroupDomain> getPaperGroups(List<PaperStructInfoVo> cards) {
-		Map<String,PaperGroupDomain> map = new HashMap<>();
-		for (PaperStructInfoVo info : cards) {
-			if(info.getGroupNumber()!=null){
-				PaperGroupDomain curGroup =map.get(getKey(info));
-				if(curGroup==null){
-					curGroup = 	new PaperGroupDomain();
-					curGroup.setPaperId(info.getPaperId());
-					curGroup.setNumber(info.getGroupNumber());
-					if (Objects.nonNull(info.getDoubleRate()) && info.getDoubleRate()>0){
-						curGroup.setDoubleEnable(true);
-						curGroup.setDoubleRate(info.getDoubleRate());
-						if (Objects.nonNull(info.getArbitrateMethod())){
-							curGroup.setArbitrateMethod(info.getArbitrateMethod());
-						}
-						if (Objects.nonNull(info.getArbitrateThreshold())){
-							curGroup.setArbitrateThreshold(info.getArbitrateThreshold());
-						}
-					} else {
-						curGroup.setDoubleEnable(false);
-					}
-					curGroup.setGroupUnits(new ArrayList<>());
-				}
-				PaperGroupUnit unit = new PaperGroupUnit();
-				unit.setDetailNumber(info.getDetailNumber());
-				unit.setDetailUnitNumber(info.getUnitNumber());
-				if (Objects.equals(ArbitrateMethod.QUESTION_ARBITRATE, info.getArbitrateMethod()) && Objects.nonNull(info.getArbitrateThreshold())){
-					unit.setArbitrateThreshold(info.getArbitrateThreshold());
-				}
-				curGroup.getGroupUnits().add(unit);
-				map.put(getKey(info),curGroup);
-			}
-		}
-		List<PaperGroupDomain> list = map.values().stream().collect(Collectors.toList());
-		return list;
-	}
-	private String getKey(PaperStructInfoVo p) {
-		return p.getPaperId()+"-"+p.getCourseCode()+"-"+p.getGroupNumber();
-	}
-//	private void checkStruct(List<StructDomain> ces, List<String> failRecords,Map<Long,String> courseMap) {
-//		for (StructDomain card : ces) {
-//			int lastDetailNum = 0;
-//			for (PaperDetail detail : card.getStructInfo()) {
-//				if (detail.getNumber() - lastDetailNum != 1) {
-//					failRecords.add(
-//							"科目:" + courseMap.get(card.getPaperId()) + ",大题号" + detail.getNumber() + "错误");
-//				}
-//				lastDetailNum = detail.getNumber();
-//				int lastUnitNum = 0;
-//				for (PaperDetailUnit unit : detail.getUnits()) {
-//					if (unit.getNumber() - lastUnitNum != 1) {
-//						failRecords.add("科目:" + courseMap.get(card.getPaperId()) + ",大题号:"
-//								+ detail.getNumber() + ",小题号" + unit.getNumber() + "错误");
-//					}
-//					lastUnitNum = unit.getNumber();
-//				}
-//			}
-//		}
-//	}
-
-	private List<StructDomain> getBeans(List<PaperStructInfoVo> cards) {
-		cards.sort(new Comparator<PaperStructInfoVo>() {
-			@Override
-			public int compare(PaperStructInfoVo o1, PaperStructInfoVo o2) {
-				long c1 = o1.getPaperId();
-				long c2 = o2.getPaperId();
-				if (c1 < c2) {
-					return -1;
-				} else if (c1 > c2) {
-					return 1;
-				} else {
-					int indx1 = o1.getDetailNumber();
-					int indx2 = o2.getDetailNumber();
-					if (indx1 < indx2) {
-						return -1;
-					} else if (indx1 > indx2) {
-						return 1;
-					} else {
-						int u1 = o1.getUnitNumber();
-						int u2 = o2.getUnitNumber();
-						if (u1 < u2) {
-							return -1;
-						} else if (u1 > u2) {
-							return 1;
-						} else {
-							return 0;
-						}
-					}
-				}
-			}
-		});
-		List<StructDomain> ces = new ArrayList<>();
-		StructDomain curCard = null;
-		PaperDetail curDetail = null;
-		for (PaperStructInfoVo info : cards) {
-			if (curCard == null || !info.getPaperId().equals(curCard.getPaperId())) {
-				curCard = new StructDomain();
-				curCard.setPaperId(info.getPaperId());
-				curCard.setStructInfo(new ArrayList<>());
-				ces.add(curCard);
-				curDetail = null;
-			}
-			if (curDetail == null || !info.getDetailNumber().equals(curDetail.getNumber())) {
-				curDetail = new PaperDetail();
-				curDetail.setName(info.getDetailName());
-				curDetail.setNumber(info.getDetailNumber());
-				curDetail.setUnits(new ArrayList<>());
-				curCard.getStructInfo().add(curDetail);
-			}
-			PaperDetailUnit unit = new PaperDetailUnit();
-			curDetail.getUnits().add(unit);
-			unit.setNumber(info.getUnitNumber());
-			unit.setScore(info.getScore());
-			unit.setScoreStep(info.getScoreStep());
-		}
-		for (StructDomain sd : ces) {
-			setTotalScore(sd);
-		}
-		return ces;
-	}
-
-	private void setTotalScore(StructDomain domain) {
-		double total = 0.0;
-		for (PaperDetail detial : domain.getStructInfo()) {
-			for (PaperDetailUnit unit : detial.getUnits()) {
-				total = Calculator.add(total, unit.getScore(), 1);
-			}
-		}
-		domain.setTotalScore(total);
-	}
-
-	@Override
-	public List<PaperStructInfoVo> subjectiveList(PaperQuery query, User user) {
-		if (query.getSchoolId() == null) {
-			throw new StatusException("学校不能为空");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(query.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		return this.baseMapper.subjectiveList(query,ArbitrateMethod.GROUP_ARBITRATE);
-	}
+
+    private static final String[] SUBJECT_EXCEL_HEADER = new String[] { "科目代码", "科目名称" };
+
+    private static final String[] SUBJECT_STRUCT_EXCEL_HEADER = new String[] { "科目代码*", "科目名称", "大题名称*", "题目昵称",
+            "大题号(只能用小写数字)*", "小题号(只能用小写数字)*", "小题满分*", "间隔分*", "评卷分组(只能用小写数字)*", "图片序号(用英文逗号分割)", "仲裁方式(0-分组,1-小题)",
+            "双评比例(0~1)", "仲裁阀值", "合分策略(1-平均,2-最高,3-最低)", "评卷模式(common-普通,track-轨迹)", "试评数量(0-跳过试评)", "选做题数量" };
+
+    @Autowired
+    private ExamService examService;
+
+    @Autowired
+    private CourseService courseService;
+
+    @Autowired
+    private PaperGroupService paperGroupService;
+
+    @Autowired
+    private PaperDetailService paperDetailService;
+
+    @Transactional
+    @Override
+    public List<String> importPaper(Long examId, User user, MultipartFile file) {
+        ExamEntity exam = examService.getById(examId);
+        if (exam == null) {
+            throw new StatusException("未找到考试批次");
+        }
+        if (!ExamStatus.EDIT.equals(exam.getExamStatus())) {
+            throw new StatusException("考试未开放上报,不能设置结构信息或分组信息");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(exam.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        InputStream inputStream = null;
+        try {
+            inputStream = file.getInputStream();
+            ExcelReader reader = ExcelReader.create(ExcelType.XLSX, inputStream, 0);
+            List<DataMap> lineList = reader.getDataMapList();
+            if (!Arrays.equals(SUBJECT_EXCEL_HEADER, reader.getColumnNames())) {
+                throw new StatusException("Excel表头错误");
+            }
+            if (CollectionUtils.isEmpty(lineList)) {
+                throw new StatusException("Excel无内容");
+            }
+            if (1001 < lineList.size()) {
+                throw new StatusException("数据行数不能超过1000");
+            }
+            List<String> failRecords = new ArrayList<>();
+            List<PaperEntity> ret = new ArrayList<>();
+            for (int i = 0; i < lineList.size(); i++) {
+                DataMap line = lineList.get(i);
+
+                StringBuilder msg = new StringBuilder();
+
+                PaperEntity imp = new PaperEntity();
+                imp.setTotalScore(0.0);
+                imp.setObjectiveScore(0.0);
+                imp.setSubjectiveScore(0.0);
+                imp.setSchoolId(exam.getSchoolId());
+                imp.setGroupFinish(false);
+                imp.setStructFinish(false);
+                imp.setExamId(examId);
+                String code = trimAndNullIfBlank(line.get(SUBJECT_EXCEL_HEADER[0]));
+                if (StringUtils.isBlank(code)) {
+                    msg.append("  科目代码不能为空");
+                } else if (code.length() > 50) {
+                    msg.append("  科目代码不能超过50个字符");
+                }
+
+                String name = trimAndNullIfBlank(line.get(SUBJECT_EXCEL_HEADER[1]));
+                if (StringUtils.isBlank(name)) {
+                    msg.append("  科目名称不能为空");
+                } else if (name.length() > 50) {
+                    msg.append("  科目名称不能超过50个字符");
+                }
+                if (msg.length() == 0) {
+                    CourseEntity course = courseService.saveOrGet(exam.getSchoolId(), code, name);
+                    imp.setCourseId(course.getId());
+                }
+
+                if (msg.length() > 0) {
+                    failRecords.add(newError(i + 1, msg.toString()));
+                } else {
+                    ret.add(imp);
+                }
+
+            }
+            if (CollectionUtils.isNotEmpty(failRecords)) {
+                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                return failRecords;
+            }
+            for (int i = 0; i < ret.size(); i++) {
+                PaperEntity cur = ret.get(i);
+                try {
+                    this.save(cur);
+                } catch (DuplicateKeyException e) {
+                    // failRecords.add(newError(i + 1, "科目已存在"));
+                } catch (Exception e) {
+                    failRecords.add(newError(i + 1, "系统异常"));
+                    log.error("科目导入系统异常", e);
+                }
+            }
+            if (CollectionUtils.isNotEmpty(failRecords)) {
+                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            }
+            return failRecords;
+        } catch (StatusException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new RuntimeException("系统错误", e);
+        } finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    private String trimAndNullIfBlank(String s) {
+        if (StringUtils.isBlank(s)) {
+            return null;
+        }
+        return s.trim();
+    }
+
+    private String newError(int lineNum, String msg) {
+        return "第" + lineNum + "行" + msg;
+    }
+
+    @Override
+    public List<ExamPaperCountVo> findPaperCount(List<Long> examIds) {
+        return this.baseMapper.findPaperCount(examIds);
+    }
+
+    @Override
+    public Integer findPaperCount(Long examId) {
+        QueryWrapper<PaperEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperEntity> lw = wrapper.lambda();
+        lw.eq(PaperEntity::getExamId, examId);
+        return this.count(wrapper);
+    }
+
+    private PaperEntity findByExamAndCourse(Long examId, Long courseId) {
+        QueryWrapper<PaperEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<PaperEntity> lw = wrapper.lambda();
+        lw.eq(PaperEntity::getExamId, examId);
+        lw.eq(PaperEntity::getCourseId, courseId);
+        return this.getOne(wrapper);
+    }
+
+    private PaperEntity saveOrGet(Long schoolId, Long examId, Long courseId) {
+        PaperEntity ret = findByExamAndCourse(examId, courseId);
+        if (ret != null) {
+            return ret;
+        }
+        PaperEntity imp = new PaperEntity();
+        imp.setTotalScore(0.0);
+        imp.setObjectiveScore(0.0);
+        imp.setSubjectiveScore(0.0);
+        imp.setSchoolId(schoolId);
+        imp.setGroupFinish(false);
+        imp.setCourseId(courseId);
+        imp.setExamId(examId);
+        imp.setStructFinish(true);
+        this.save(imp);
+        return imp;
+    }
+
+    @Override
+    public PageResult<PaperVo> page(PaperQuery query, User user) {
+        if (query.getSchoolId() == null) {
+            throw new StatusException("学校不能为空");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(query.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        IPage<PaperVo> iPage = this.baseMapper.page(new Page<>(query.getPageNumber(), query.getPageSize()), query);
+        if (CollectionUtils.isNotEmpty(iPage.getRecords())) {
+            new BatchSetDataUtil<PaperVo>() {
+
+                @Override
+                protected void setData(List<PaperVo> dataList) {
+                    List<Long> paperIds = dataList.stream().map(PaperVo::getId).distinct().collect(Collectors.toList());
+                    List<GroupCountVo> ret = paperGroupService.findGroupCount(paperIds);
+                    if (ret != null && ret.size() > 0) {
+                        Map<Long, Integer> countMap = new HashMap<>();
+                        Map<Long, Boolean> doubleEnableMap = new HashMap<>();
+                        for (GroupCountVo item : ret) {
+                            countMap.put(item.getPaperId(), item.getGroupCount());
+                            doubleEnableMap.put(item.getPaperId(), item.getDoubleEnable());
+                        }
+                        for (PaperVo vo : dataList) {
+                            vo.setGroupCount(countMap.get(vo.getId()));
+                            vo.setDoubleEnable(doubleEnableMap.get(vo.getId()));
+                        }
+                    }
+                }
+            }.setDataForBatch(iPage.getRecords(), 20);
+            for (PaperVo vo : iPage.getRecords()) {
+                if (vo.getGroupCount() == null) {
+                    vo.setGroupCount(0);
+                }
+            }
+        }
+        return PageUtil.of(iPage);
+    }
+
+    @Override
+    public List<PaperVo> list(Long examId, User user) {
+        ExamEntity exam = examService.getById(examId);
+        if (exam == null) {
+            throw new StatusException("未找到考试批次");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(exam.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        List<PaperVo> ret = this.baseMapper.myPaperlist(examId, user.getId());
+        if (CollectionUtils.isNotEmpty(ret)) {
+            new BatchSetDataUtil<PaperVo>() {
+
+                @Override
+                protected void setData(List<PaperVo> dataList) {
+                    List<Long> paperIds = dataList.stream().map(dto -> dto.getId()).distinct()
+                            .collect(Collectors.toList());
+                    List<GroupCountVo> ret = paperGroupService.findGroupCount(paperIds);
+                    if (ret != null && ret.size() > 0) {
+                        Map<Long, Integer> countMap = new HashMap<>();
+                        for (GroupCountVo item : ret) {
+                            countMap.put(item.getPaperId(), item.getGroupCount());
+                        }
+                        for (PaperVo vo : dataList) {
+                            vo.setGroupCount(countMap.get(vo.getId()));
+                        }
+                    }
+                }
+            }.setDataForBatch(ret, 20);
+        }
+        return ret;
+    }
+
+    @Override
+    public PaperInfoVo info(Long id, User user) {
+        PaperEntity paper = this.getById(id);
+        if (paper == null) {
+            throw new StatusException("未找到试卷结构信息");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(paper.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        PaperInfoVo vo = new PaperInfoVo();
+        BeanUtils.copyProperties(paper, vo);
+        CourseEntity course = courseService.getById(vo.getCourseId());
+        vo.setCourseCode(course.getCode());
+        vo.setCourseName(course.getName());
+        vo.setStructInfo(paperDetailService.getStructInfo(vo.getId()));
+        vo.setGroupInfo(paperGroupService.getGroupInfo(vo.getId()));
+
+        String defaultDoubleSetStr = paper.getDefaultDoubleSet();
+        if (!StringUtils.isBlank(defaultDoubleSetStr)) {
+            vo.setDefaultDoubleSet(JSON.parseObject(defaultDoubleSetStr, DefaultDoubleSet.class));
+        }
+        return vo;
+    }
+
+    @Transactional
+    @Override
+    public List<String> importSubjectStruct(Long examId, User user, MultipartFile file) {
+        ExamEntity exam = examService.getById(examId);
+        if (exam == null) {
+            throw new StatusException("未找到考试批次");
+        }
+        if (!ExamStatus.EDIT.equals(exam.getExamStatus())) {
+            throw new StatusException("考试未开放上报,不能设置结构信息或分组信息");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(exam.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        InputStream inputStream = null;
+        try {
+            inputStream = file.getInputStream();
+            ExcelReader reader = ExcelReader.create(ExcelType.XLSX, inputStream, 1);
+            List<DataMap> lineList = reader.getDataMapList();
+            if (!Arrays.equals(SUBJECT_STRUCT_EXCEL_HEADER, reader.getColumnNames())) {
+                throw new StatusException("Excel表头错误");
+            }
+            if (CollectionUtils.isEmpty(lineList)) {
+                throw new StatusException("Excel无内容");
+            }
+            if (10001 < lineList.size()) {
+                throw new StatusException("数据行数不能超过10000");
+            }
+            List<String> failRecords = new ArrayList<>();
+            List<PaperStructInfoVo> ret = new ArrayList<>();
+            // 双评设置
+            Map<String, DoubleMarkImportParam> doubleMarkSettingMap = new HashMap<>();
+            for (int i = 0; i < lineList.size(); i++) {
+                DataMap line = lineList.get(i);
+
+                StringBuilder msg = new StringBuilder();
+
+                PaperStructInfoVo imp = new PaperStructInfoVo();
+                String code = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[0]));
+                if (StringUtils.isBlank(code)) {
+                    msg.append("  科目代码不能为空");
+                } else if (code.length() > 50) {
+                    msg.append("  科目代码不能超过50个字符");
+                }
+                imp.setCourseCode(code);
+
+                String name = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[1]));
+                if (StringUtils.isBlank(name)) {
+                    msg.append("  科目名称不能为空");
+                } else if (name.length() > 50) {
+                    msg.append("  科目名称不能超过50个字符");
+                }
+                if (msg.length() == 0) {
+                    CourseEntity course = courseService.saveOrGet(exam.getSchoolId(), code, name);
+                    PaperEntity paper = saveOrGet(exam.getSchoolId(), examId, course.getId());
+                    imp.setPaperId(paper.getId());
+                }
+
+                String detailName = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[2]));
+                if (StringUtils.isBlank(detailName)) {
+                    msg.append("  大题名称不能为空");
+                } else if (detailName.length() > 50) {
+                    msg.append("  大题名称不能超过50个字符");
+                }
+                imp.setDetailName(detailName);
+                // 第4列不处理
+                String detailNumber = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[4]));
+                if (StringUtils.isBlank(detailNumber)) {
+                    msg.append("  大题号不能为空");
+                } else {
+                    try {
+                        int n = Integer.valueOf(detailNumber);
+                        if (n <= 0) {
+                            msg.append("  大题号不能小于0");
+                        } else {
+                            imp.setDetailNumber(n);
+                        }
+                    } catch (Exception e) {
+                        msg.append("  大题号只能是整数");
+                    }
+
+                }
+
+                String unitNumber = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[5]));
+                if (StringUtils.isBlank(unitNumber)) {
+                    msg.append("  小题号不能为空");
+                } else {
+                    try {
+                        int n = Integer.valueOf(unitNumber);
+                        if (n <= 0) {
+                            msg.append("  小题号不能小于0");
+                        } else {
+                            imp.setUnitNumber(n);
+                        }
+                    } catch (Exception e) {
+                        msg.append("  小题号只能是整数");
+                    }
+
+                }
+
+                String score = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[6]));
+                if (StringUtils.isBlank(score)) {
+                    msg.append("  小题满分不能为空");
+                } else {
+                    try {
+                        Double n = Double.valueOf(score);
+                        if (n <= 0) {
+                            msg.append("  小题满分不能小于0");
+                        } else {
+                            if (score.indexOf(".") >= 0 && score.indexOf(".") < score.length() - 2) {
+                                msg.append("小题满分只能有一位小数");
+                            } else {
+                                imp.setScore(n);
+                            }
+                        }
+                    } catch (Exception e) {
+                        msg.append("  小题满分格式错误");
+                    }
+
+                }
+
+                String scoreStep = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[7]));
+                if (StringUtils.isBlank(scoreStep)) {
+                    msg.append("  间隔分不能为空");
+                } else {
+                    try {
+                        Double n = Double.valueOf(scoreStep);
+                        if (n <= 0) {
+                            msg.append("  间隔分不能小于0");
+                        } else {
+                            if (scoreStep.indexOf(".") >= 0 && scoreStep.indexOf(".") < scoreStep.length() - 2) {
+                                msg.append("小间隔分只能有一位小数");
+                            } else {
+                                imp.setScoreStep(n);
+                            }
+                        }
+                    } catch (Exception e) {
+                        msg.append("  间隔分格式错误");
+                    }
+
+                }
+
+                String groupNumberStr = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[8]));
+                if (StringUtils.isNotBlank(groupNumberStr)) {
+                    try {
+                        Integer n = Integer.valueOf(groupNumberStr);
+                        if (n <= 0) {
+                            msg.append("  评卷分组不能小于0");
+                        } else {
+                            imp.setGroupNumber(n);
+                        }
+                    } catch (Exception e) {
+                        msg.append("  评卷分组格式错误");
+                    }
+                }
+
+                Long paperId = imp.getPaperId();
+                Integer groupNumber = imp.getGroupNumber();
+                Double questionScore = imp.getScore();
+                if (Objects.nonNull(paperId) && Objects.nonNull(groupNumber) && Objects.nonNull(questionScore)) {
+                    // 有分组信息才解析双评信息
+                    String groupKey = paperId + "-" + groupNumber;
+                    ArbitrateMethod arbitrateMethod = null;
+                    Double doubleRate = null;
+                    Double arbitrateThreshold = null;
+
+                    if (doubleMarkSettingMap.containsKey(groupKey)) {
+                        DoubleMarkImportParam doubleMarkImportParam = doubleMarkSettingMap.get(groupKey);
+                        arbitrateMethod = doubleMarkImportParam.getArbitrateMethod();
+                        doubleRate = doubleMarkImportParam.getDoubleRate();
+                        arbitrateThreshold = doubleMarkImportParam.getArbitrateThreshold();
+                    }
+
+                    String arbitrateMethodStr = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[10]));
+                    String doubleRateStr = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[11]));
+                    String arbitrateThresholdStr = trimAndNullIfBlank(line.get(SUBJECT_STRUCT_EXCEL_HEADER[12]));
+
+                    // 双评比例
+                    if (StringUtils.isNotBlank(doubleRateStr)) {
+                        try {
+                            double n = Double.parseDouble(doubleRateStr);
+
+                            if (n < 0 || n > 1) {
+                                msg.append("  双评比例只能在(0~1)");
+                            } else {
+                                if (Objects.nonNull(doubleRate) && !doubleRate.equals(n)) {
+                                    msg.append("  同分组的双评比例必须相同");
+                                } else {
+                                    doubleRate = n;
+                                    imp.setDoubleRate(doubleRate);
+                                }
+                            }
+                        } catch (Exception e) {
+                            msg.append("  双评比例格式错误");
+                        }
+                    }
+
+                    if (Objects.nonNull(doubleRate) && doubleRate > 0) {
+                        // 开启双评才继续解析 仲裁方式和仲裁值
+                        // 仲裁方式(0-分组,1-小题)
+                        if (StringUtils.isNotBlank(arbitrateMethodStr)) {
+                            try {
+                                int n = Integer.parseInt(arbitrateMethodStr);
+                                List<ArbitrateMethod> arbitrateMethodList = Arrays.stream(ArbitrateMethod.values())
+                                        .filter(e -> e.getValue().equals(n)).collect(Collectors.toList());
+                                if (arbitrateMethodList.size() != 1) {
+                                    msg.append("  仲裁方式只能选择0或1");
+                                } else {
+                                    if (Objects.nonNull(arbitrateMethod)
+                                            && !arbitrateMethod.equals(arbitrateMethodList.get(0))) {
+                                        msg.append("  同分组的仲裁方式必须相同");
+                                    } else {
+                                        arbitrateMethod = arbitrateMethodList.get(0);
+                                        imp.setArbitrateMethod(arbitrateMethod);
+                                    }
+                                }
+                            } catch (Exception e) {
+                                msg.append("  仲裁方式格式错误");
+                            }
+                        } else {
+                            msg.append("  仲裁方式不能为空");
+                        }
+
+                        if (Objects.nonNull(arbitrateMethod)) {
+                            // 仲裁方式不为空才解析
+                            // 仲裁阀值
+                            if (StringUtils.isNotBlank(arbitrateThresholdStr)) {
+                                try {
+                                    double n = Double.parseDouble(arbitrateThresholdStr);
+                                    if (n < 0) {
+                                        msg.append("  仲裁阀值不能小于0");
+                                    }
+                                    if (ArbitrateMethod.QUESTION_ARBITRATE.equals(arbitrateMethod)) {
+                                        if (n > questionScore) {
+                                            msg.append("  仲裁阀值不能超过小题满分");
+                                        }
+                                    } else if (ArbitrateMethod.GROUP_ARBITRATE.equals(arbitrateMethod)) {
+                                        if (Objects.nonNull(arbitrateThreshold) && !arbitrateThreshold.equals(n)) {
+                                            msg.append("  同分组的仲裁阀值必须相同");
+                                        }
+                                    }
+                                    arbitrateThreshold = n;
+                                    imp.setArbitrateThreshold(n);
+                                } catch (Exception e) {
+                                    msg.append("  仲裁阀值格式错误");
+                                }
+                            } else {
+                                msg.append("  仲裁阀值不能为空");
+                            }
+                        }
+                    }
+                    if (!doubleMarkSettingMap.containsKey(groupKey)) {
+                        List<Integer> indexList = new ArrayList<>();
+                        indexList.add(i + 3);
+                        doubleMarkSettingMap.put(groupKey, new DoubleMarkImportParam(arbitrateMethod, doubleRate,
+                                arbitrateThreshold, indexList, questionScore));
+                    } else {
+                        DoubleMarkImportParam cellMap = doubleMarkSettingMap.get(groupKey);
+                        cellMap.getIndexes().add(i + 3);
+                        cellMap.setTotalScore(cellMap.getTotalScore() + questionScore);
+                    }
+                }
+                if (msg.length() > 0) {
+                    failRecords.add(newError(i + 3, msg.toString()));
+                } else {
+                    ret.add(imp);
+                }
+            }
+            // 检测分组仲裁的分组 分组阈值设置是否超过整组分数
+            doubleMarkSettingMap.forEach((k, v) -> {
+                if (v.getArbitrateMethod() != null && v.getArbitrateMethod().equals(ArbitrateMethod.GROUP_ARBITRATE)) {
+                    if (v.getArbitrateThreshold() > v.getTotalScore()) {
+                        failRecords.add(newError(v.getIndexes().get(0), " 分组仲裁阀值不能超过分组满分"));
+                    }
+                }
+            });
+            if (CollectionUtils.isNotEmpty(failRecords)) {
+                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                return failRecords;
+            }
+            this.saveStruct(ret, user, failRecords);
+            if (CollectionUtils.isNotEmpty(failRecords)) {
+                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            }
+            return failRecords;
+        } catch (StatusException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new RuntimeException("系统错误", e);
+        } finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    private void saveStruct(List<PaperStructInfoVo> cards, User user, List<String> failRecords) {
+        Map<Long, String> map = new HashMap<>();
+        for (PaperStructInfoVo vo : cards) {
+            map.put(vo.getPaperId(), vo.getCourseCode());
+        }
+        List<StructDomain> ces = getBeans(cards);
+        // checkStruct(ces, failRecords,map);
+        if (CollectionUtils.isNotEmpty(failRecords)) {
+            return;
+        }
+        for (StructDomain domain : ces) {
+            try {
+                paperDetailService.structImport(domain, user);
+            } catch (StatusException e) {
+                failRecords.add("科目:" + map.get(domain.getPaperId()) + " " + e.getMessage());
+            } catch (Exception e) {
+                throw new RuntimeException("系统错误", e);
+            }
+        }
+        List<PaperGroupDomain> list = getPaperGroups(cards);
+        for (PaperGroupDomain domain : list) {
+            try {
+                paperGroupService.groupSave(domain, user);
+            } catch (StatusException e) {
+                failRecords.add("科目:" + map.get(domain.getPaperId()) + " " + e.getMessage());
+            } catch (Exception e) {
+                throw new RuntimeException("系统错误", e);
+            }
+        }
+
+    }
+
+    private List<PaperGroupDomain> getPaperGroups(List<PaperStructInfoVo> cards) {
+        Map<String, PaperGroupDomain> map = new HashMap<>();
+        for (PaperStructInfoVo info : cards) {
+            if (info.getGroupNumber() != null) {
+                PaperGroupDomain curGroup = map.get(getKey(info));
+                if (curGroup == null) {
+                    curGroup = new PaperGroupDomain();
+                    curGroup.setPaperId(info.getPaperId());
+                    curGroup.setNumber(info.getGroupNumber());
+                    if (Objects.nonNull(info.getDoubleRate()) && info.getDoubleRate() > 0) {
+                        curGroup.setDoubleEnable(true);
+                        curGroup.setDoubleRate(info.getDoubleRate());
+                        if (Objects.nonNull(info.getArbitrateMethod())) {
+                            curGroup.setArbitrateMethod(info.getArbitrateMethod());
+                        }
+                        if (Objects.nonNull(info.getArbitrateThreshold())) {
+                            curGroup.setArbitrateThreshold(info.getArbitrateThreshold());
+                        }
+                    } else {
+                        curGroup.setDoubleEnable(false);
+                    }
+                    curGroup.setGroupUnits(new ArrayList<>());
+                }
+                PaperGroupUnit unit = new PaperGroupUnit();
+                unit.setDetailNumber(info.getDetailNumber());
+                unit.setDetailUnitNumber(info.getUnitNumber());
+                if (Objects.equals(ArbitrateMethod.QUESTION_ARBITRATE, info.getArbitrateMethod())
+                        && Objects.nonNull(info.getArbitrateThreshold())) {
+                    unit.setArbitrateThreshold(info.getArbitrateThreshold());
+                }
+                curGroup.getGroupUnits().add(unit);
+                map.put(getKey(info), curGroup);
+            }
+        }
+        List<PaperGroupDomain> list = map.values().stream().collect(Collectors.toList());
+        return list;
+    }
+
+    private String getKey(PaperStructInfoVo p) {
+        return p.getPaperId() + "-" + p.getCourseCode() + "-" + p.getGroupNumber();
+    }
+    // private void checkStruct(List<StructDomain> ces, List<String>
+    // failRecords,Map<Long,String> courseMap) {
+    // for (StructDomain card : ces) {
+    // int lastDetailNum = 0;
+    // for (PaperDetail detail : card.getStructInfo()) {
+    // if (detail.getNumber() - lastDetailNum != 1) {
+    // failRecords.add(
+    // "科目:" + courseMap.get(card.getPaperId()) + ",大题号" + detail.getNumber() +
+    // "错误");
+    // }
+    // lastDetailNum = detail.getNumber();
+    // int lastUnitNum = 0;
+    // for (PaperDetailUnit unit : detail.getUnits()) {
+    // if (unit.getNumber() - lastUnitNum != 1) {
+    // failRecords.add("科目:" + courseMap.get(card.getPaperId()) + ",大题号:"
+    // + detail.getNumber() + ",小题号" + unit.getNumber() + "错误");
+    // }
+    // lastUnitNum = unit.getNumber();
+    // }
+    // }
+    // }
+    // }
+
+    private List<StructDomain> getBeans(List<PaperStructInfoVo> cards) {
+        cards.sort(new Comparator<PaperStructInfoVo>() {
+
+            @Override
+            public int compare(PaperStructInfoVo o1, PaperStructInfoVo o2) {
+                long c1 = o1.getPaperId();
+                long c2 = o2.getPaperId();
+                if (c1 < c2) {
+                    return -1;
+                } else if (c1 > c2) {
+                    return 1;
+                } else {
+                    int indx1 = o1.getDetailNumber();
+                    int indx2 = o2.getDetailNumber();
+                    if (indx1 < indx2) {
+                        return -1;
+                    } else if (indx1 > indx2) {
+                        return 1;
+                    } else {
+                        int u1 = o1.getUnitNumber();
+                        int u2 = o2.getUnitNumber();
+                        if (u1 < u2) {
+                            return -1;
+                        } else if (u1 > u2) {
+                            return 1;
+                        } else {
+                            return 0;
+                        }
+                    }
+                }
+            }
+        });
+        List<StructDomain> ces = new ArrayList<>();
+        StructDomain curCard = null;
+        PaperDetail curDetail = null;
+        for (PaperStructInfoVo info : cards) {
+            if (curCard == null || !info.getPaperId().equals(curCard.getPaperId())) {
+                curCard = new StructDomain();
+                curCard.setPaperId(info.getPaperId());
+                curCard.setStructInfo(new ArrayList<>());
+                ces.add(curCard);
+                curDetail = null;
+            }
+            if (curDetail == null || !info.getDetailNumber().equals(curDetail.getNumber())) {
+                curDetail = new PaperDetail();
+                curDetail.setName(info.getDetailName());
+                curDetail.setNumber(info.getDetailNumber());
+                curDetail.setUnits(new ArrayList<>());
+                curCard.getStructInfo().add(curDetail);
+            }
+            PaperDetailUnit unit = new PaperDetailUnit();
+            curDetail.getUnits().add(unit);
+            unit.setNumber(info.getUnitNumber());
+            unit.setScore(info.getScore());
+            unit.setScoreStep(info.getScoreStep());
+        }
+        for (StructDomain sd : ces) {
+            setTotalScore(sd);
+        }
+        return ces;
+    }
+
+    private void setTotalScore(StructDomain domain) {
+        double total = 0.0;
+        for (PaperDetail detial : domain.getStructInfo()) {
+            for (PaperDetailUnit unit : detial.getUnits()) {
+                total = Calculator.add(total, unit.getScore(), 1);
+            }
+        }
+        domain.setTotalScore(total);
+    }
+
+    @Override
+    public List<PaperStructInfoVo> subjectiveList(PaperQuery query, User user) {
+        if (query.getSchoolId() == null) {
+            throw new StatusException("学校不能为空");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(query.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        return this.baseMapper.subjectiveList(query, ArbitrateMethod.GROUP_ARBITRATE);
+    }
 
 }

+ 133 - 130
src/main/java/cn/com/qmth/mps/service/impl/SchoolServiceImpl.java

@@ -34,140 +34,143 @@ import cn.com.qmth.mps.vo.school.SchoolVo;
 
 @Service
 public class SchoolServiceImpl extends ServiceImpl<SchoolDao, SchoolEntity> implements SchoolService {
-	@Value("${wxapp-url}")
-	private String wxappUrl;
-	
-	@Autowired
-	private SolarService solarService;
 
-	@Transactional
-	@Override
-	public void syncSchool(User user) {
-		if (!user.getRole().equals(Role.SUPER_ADMIN)) {
-			throw new StatusException("没有权限");
-		}
-		List<OrgInfo> orgs=solarService.getOrgList();
-		if (CollectionUtils.isEmpty(orgs)) {
-			return;
-		}
-		for (OrgInfo org : orgs) {
-			addSchoolForSync(user, org);
-		}
-	}
+    @Value("${wxapp-url}")
+    private String wxappUrl;
 
-	private void addSchoolForSync(User user, OrgInfo org) {
-		SchoolEntity school=of(org);
-		SchoolEntity old = this.findSchoolByCode(school.getCode());
-		if (old != null) {
-			old.setAccessKey(school.getAccessKey());
-			old.setAccessSecret(school.getAccessSecret());
-			this.updateById(old);
-		} else {
-			school.setId(null);
-			school.setEnable(true);
-			this.save(school);
-		}
-	}
-	private SchoolEntity of(OrgInfo info) {
-		SchoolEntity org=new SchoolEntity();
-		org.setCode(info.getCode());
-		org.setName(info.getName());
-		org.setAccessKey(info.getAccessKey());
-		org.setAccessSecret(info.getAccessSecret());
-		org.setEnable(true);
-		return org;
-	}
-	private SchoolEntity findSchoolByCode(String code) {
-		QueryWrapper<SchoolEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<SchoolEntity> lw = wrapper.lambda();
-		lw.eq(SchoolEntity::getCode, code);
-		return this.getOne(wrapper);
-	}
+    @Autowired
+    private SolarService solarService;
 
-	@Transactional
-	@Override
-	public void saveSchool(User user, SchoolDomain domain) {
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && domain.getId() == null) {
-			throw new StatusException("没有权限");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && domain.getId() != null
-				&& !user.getSchoolId().equals(domain.getId())) {
-			throw new StatusException("没有权限");
-		}
-		if (domain.getId() == null && StringUtils.isBlank(domain.getCode())) {
-			throw new StatusException("学校编码不能为空");
-		}
-		if (StringUtils.isBlank(domain.getName())) {
-			throw new StatusException("学校名称不能为空");
-		}
-		if (domain.getEnable()==null) {
-			throw new StatusException("启用禁用不能为空");
-		}
-		SchoolEntity ue = null;
-		if (domain.getId() != null) {
-			ue = this.getById(domain.getId());
-			if (ue == null) {
-				throw new StatusException("未找到学校");
-			}
-		} else {
-			if (findSchoolByCode(domain.getCode()) != null) {
-				throw new StatusException("学校编码已存在");
-			}
-			ue = new SchoolEntity();
-			ue.setCode(domain.getCode());
-		}
-		ue.setEnable(domain.getEnable());
-		ue.setName(domain.getName());
-		ue.setContacts(domain.getContacts());
-		ue.setTelephone(domain.getTelephone());
-		ue.setRegion(domain.getRegion());
-		this.saveOrUpdate(ue);
-	}
+    @Transactional
+    @Override
+    public void syncSchool(User user) {
+        if (!user.getRole().equals(Role.SUPER_ADMIN)) {
+            throw new StatusException("没有权限");
+        }
+        List<OrgInfo> orgs = solarService.getOrgList();
+        if (CollectionUtils.isEmpty(orgs)) {
+            return;
+        }
+        for (OrgInfo org : orgs) {
+            addSchoolForSync(user, org);
+        }
+    }
 
-	@Override
-	public PageResult<SchoolVo> page(SchoolQuery query, User user) {
-		Long schoolId = null;
-		if (!user.getRole().equals(Role.SUPER_ADMIN)) {
-			schoolId = user.getSchoolId();
-		}
-		IPage<SchoolVo> iPage = this.baseMapper.page(new Page<SchoolVo>(query.getPageNumber(), query.getPageSize()),
-				query, schoolId);
-		if (CollectionUtils.isNotEmpty(iPage.getRecords())) {
-			for (SchoolVo vo : iPage.getRecords()) {
-				vo.setQrCode(wxappUrl);
-			}
-		}
-		return PageUtil.of(iPage);
-	}
+    private void addSchoolForSync(User user, OrgInfo org) {
+        SchoolEntity school = of(org);
+        SchoolEntity old = this.findSchoolByCode(school.getCode());
+        if (old != null) {
+            old.setAccessKey(school.getAccessKey());
+            old.setAccessSecret(school.getAccessSecret());
+            this.updateById(old);
+        } else {
+            school.setId(null);
+            school.setEnable(true);
+            this.save(school);
+        }
+    }
 
-	@Override
-	public SchoolVo info(Long id, User user) {
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(id)) {
-			return null;
-		}
-		SchoolEntity ue = this.getById(id);
-		if (ue == null) {
-			throw new StatusException("未找到学校");
-		}
-		SchoolVo vo = new SchoolVo();
-		BeanUtils.copyProperties(ue, vo);
-		vo.setQrCode(wxappUrl);
-		return vo;
-	}
+    private SchoolEntity of(OrgInfo info) {
+        SchoolEntity org = new SchoolEntity();
+        org.setCode(info.getCode());
+        org.setName(info.getName());
+        org.setAccessKey(info.getAccessKey());
+        org.setAccessSecret(info.getAccessSecret());
+        org.setEnable(true);
+        return org;
+    }
 
-	@Transactional
-	@Override
-	public void toggle(List<Long> ids, Boolean enable, User user) {
-		if (!user.getRole().equals(Role.SUPER_ADMIN)) {
-			throw new StatusException("没有权限");
-		}
-		if (ids.contains(1L)) {
-			throw new StatusException("默认学校不能禁用(ID:1)");
-		}
-		UpdateWrapper<SchoolEntity> wrapper = new UpdateWrapper<>();
-		LambdaUpdateWrapper<SchoolEntity> lw = wrapper.lambda();
-		lw.set(SchoolEntity::getEnable, enable);
-		lw.in(SchoolEntity::getId, ids);
-		this.update(wrapper);
-	}
+    private SchoolEntity findSchoolByCode(String code) {
+        QueryWrapper<SchoolEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<SchoolEntity> lw = wrapper.lambda();
+        lw.eq(SchoolEntity::getCode, code);
+        return this.getOne(wrapper);
+    }
+
+    @Transactional
+    @Override
+    public void saveSchool(User user, SchoolDomain domain) {
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && domain.getId() == null) {
+            throw new StatusException("没有权限");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && domain.getId() != null
+                && !user.getSchoolId().equals(domain.getId())) {
+            throw new StatusException("没有权限");
+        }
+        if (domain.getId() == null && StringUtils.isBlank(domain.getCode())) {
+            throw new StatusException("学校编码不能为空");
+        }
+        if (StringUtils.isBlank(domain.getName())) {
+            throw new StatusException("学校名称不能为空");
+        }
+        if (domain.getEnable() == null) {
+            throw new StatusException("启用禁用不能为空");
+        }
+        SchoolEntity ue = null;
+        if (domain.getId() != null) {
+            ue = this.getById(domain.getId());
+            if (ue == null) {
+                throw new StatusException("未找到学校");
+            }
+        } else {
+            if (findSchoolByCode(domain.getCode()) != null) {
+                throw new StatusException("学校编码已存在");
+            }
+            ue = new SchoolEntity();
+            ue.setCode(domain.getCode());
+        }
+        ue.setEnable(domain.getEnable());
+        ue.setName(domain.getName());
+        ue.setContacts(domain.getContacts());
+        ue.setTelephone(domain.getTelephone());
+        ue.setRegion(domain.getRegion());
+        this.saveOrUpdate(ue);
+    }
+
+    @Override
+    public PageResult<SchoolVo> page(SchoolQuery query, User user) {
+        Long schoolId = null;
+        if (!user.getRole().equals(Role.SUPER_ADMIN)) {
+            schoolId = user.getSchoolId();
+        }
+        IPage<SchoolVo> iPage = this.baseMapper.page(new Page<SchoolVo>(query.getPageNumber(), query.getPageSize()),
+                query, schoolId);
+        if (CollectionUtils.isNotEmpty(iPage.getRecords())) {
+            for (SchoolVo vo : iPage.getRecords()) {
+                vo.setQrCode(wxappUrl);
+            }
+        }
+        return PageUtil.of(iPage);
+    }
+
+    @Override
+    public SchoolVo info(Long id, User user) {
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(id)) {
+            return null;
+        }
+        SchoolEntity ue = this.getById(id);
+        if (ue == null) {
+            throw new StatusException("未找到学校");
+        }
+        SchoolVo vo = new SchoolVo();
+        BeanUtils.copyProperties(ue, vo);
+        vo.setQrCode(wxappUrl);
+        return vo;
+    }
+
+    @Transactional
+    @Override
+    public void toggle(List<Long> ids, Boolean enable, User user) {
+        if (!user.getRole().equals(Role.SUPER_ADMIN)) {
+            throw new StatusException("没有权限");
+        }
+        if (ids.contains(1L)) {
+            throw new StatusException("默认学校不能禁用(ID:1)");
+        }
+        UpdateWrapper<SchoolEntity> wrapper = new UpdateWrapper<>();
+        LambdaUpdateWrapper<SchoolEntity> lw = wrapper.lambda();
+        lw.set(SchoolEntity::getEnable, enable);
+        lw.in(SchoolEntity::getId, ids);
+        this.update(wrapper);
+    }
 }

+ 42 - 41
src/main/java/cn/com/qmth/mps/service/impl/SessionServiceImpl.java

@@ -13,54 +13,55 @@ import cn.com.qmth.mps.service.SessionService;
 
 @Service
 public class SessionServiceImpl implements SessionService {
-	private final static Map<String, User> userSessionData = new ConcurrentHashMap<>();
 
-	@Autowired
-	private SysProperty sysProperty;
+    private final static Map<String, User> userSessionData = new ConcurrentHashMap<>();
 
-	@Override
-	public Long updateUserSession(User user) {
-		if (user.getSessionId() == null) {
-			return null;
-		}
-		user.setActiveTime(new Date().getTime());
-		userSessionData.put(user.getSessionId(), user);
-		return user.getActiveTime();
-	}
+    @Autowired
+    private SysProperty sysProperty;
 
-	@Override
-	public void clearTimeOutUser() {
-		Date d = new Date();
-		Long now = d.getTime();
-		for (String k : userSessionData.keySet()) {
-			if (now - userSessionData.get(k).getActiveTime() > getTimeout()) {
-				userSessionData.remove(k);
-			}
-		}
-	}
+    @Override
+    public Long updateUserSession(User user) {
+        if (user.getSessionId() == null) {
+            return null;
+        }
+        user.setActiveTime(new Date().getTime());
+        userSessionData.put(user.getSessionId(), user);
+        return user.getActiveTime();
+    }
 
-	@Override
-	public void userLogout(User user) {
-		userSessionData.remove(user.getSessionId());
-	}
+    @Override
+    public void clearTimeOutUser() {
+        Date d = new Date();
+        Long now = d.getTime();
+        for (String k : userSessionData.keySet()) {
+            if (now - userSessionData.get(k).getActiveTime() > getTimeout()) {
+                userSessionData.remove(k);
+            }
+        }
+    }
 
-	@Override
-	public void userLogin(User user) {
-		updateUserSession(user);
-	}
+    @Override
+    public void userLogout(User user) {
+        userSessionData.remove(user.getSessionId());
+    }
 
-	@Override
-	public User getSessionUser(String sessionId) {
-		return userSessionData.get(sessionId);
-	}
+    @Override
+    public void userLogin(User user) {
+        updateUserSession(user);
+    }
 
-	@Override
-	public int getOnlineCount() {
-		return userSessionData.size();
-	}
+    @Override
+    public User getSessionUser(String sessionId) {
+        return userSessionData.get(sessionId);
+    }
 
-	private long getTimeout() {
-		return (sysProperty.getSessionTimeout() == null ? 7200 : sysProperty.getSessionTimeout()) * 1000L;
-	}
+    @Override
+    public int getOnlineCount() {
+        return userSessionData.size();
+    }
+
+    private long getTimeout() {
+        return (sysProperty.getSessionTimeout() == null ? 7200 : sysProperty.getSessionTimeout()) * 1000L;
+    }
 
 }

+ 38 - 38
src/main/java/cn/com/qmth/mps/service/impl/UserCourseRelationServiceImpl.java

@@ -20,48 +20,48 @@ import cn.com.qmth.mps.service.CourseService;
 import cn.com.qmth.mps.service.UserCourseRelationService;
 
 @Service
-public class UserCourseRelationServiceImpl extends
-		MppServiceImpl<UserCourseRelationDao, UserCourseRelationEntity> implements UserCourseRelationService {
-	@Autowired
-	private CourseService courseService;
-	
-	@Transactional
-	@Override
-	public void saveCourse(Long schoolId,Long userId, List<String> course) {
-		List<UserCourseRelationEntity> ret=new ArrayList<>();
-		for(String s:course) {
-			CourseEntity c= courseService.getByCode(schoolId,s);
-			if(c==null) {
-				throw new StatusException("科目代码不存在:"+s);
-			}
-			UserCourseRelationEntity uc=new UserCourseRelationEntity();
-			uc.setCourseId(c.getId());
-			uc.setUserId(userId);
-			ret.add(uc);
-		}
-		this.removeCourse(userId);
-		this.saveOrUpdateBatchByMultiId(ret);
-	}
-	
-	@Transactional
-	@Override
-	public void removeCourse(Long userId) {
-		QueryWrapper<UserCourseRelationEntity> wrapper = new QueryWrapper<>();
+public class UserCourseRelationServiceImpl extends MppServiceImpl<UserCourseRelationDao, UserCourseRelationEntity>
+        implements UserCourseRelationService {
+
+    @Autowired
+    private CourseService courseService;
+
+    @Transactional
+    @Override
+    public void saveCourse(Long schoolId, Long userId, List<String> course) {
+        List<UserCourseRelationEntity> ret = new ArrayList<>();
+        for (String s : course) {
+            CourseEntity c = courseService.getByCode(schoolId, s);
+            if (c == null) {
+                throw new StatusException("科目代码不存在:" + s);
+            }
+            UserCourseRelationEntity uc = new UserCourseRelationEntity();
+            uc.setCourseId(c.getId());
+            uc.setUserId(userId);
+            ret.add(uc);
+        }
+        this.removeCourse(userId);
+        this.saveOrUpdateBatchByMultiId(ret);
+    }
+
+    @Transactional
+    @Override
+    public void removeCourse(Long userId) {
+        QueryWrapper<UserCourseRelationEntity> wrapper = new QueryWrapper<>();
         LambdaQueryWrapper<UserCourseRelationEntity> lw = wrapper.lambda();
         lw.eq(UserCourseRelationEntity::getUserId, userId);
         this.remove(wrapper);
-	}
-
-	@Override
-	public List<CourseInfo> getCourses(Long userId) {
-		return this.baseMapper.getCourses(userId);
-	}
+    }
 
-	@Transactional
-	@Override
-	public void clearBySchool(Long schoolId) {
-		baseMapper.clearBySchool(schoolId);
-	}
+    @Override
+    public List<CourseInfo> getCourses(Long userId) {
+        return this.baseMapper.getCourses(userId);
+    }
 
+    @Transactional
+    @Override
+    public void clearBySchool(Long schoolId) {
+        baseMapper.clearBySchool(schoolId);
+    }
 
 }

+ 333 - 330
src/main/java/cn/com/qmth/mps/service/impl/UserServiceImpl.java

@@ -49,339 +49,342 @@ import cn.com.qmth.mps.vo.user.UserVo;
 
 @Service
 public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {
-	private static final String[] EXCEL_HEADER = new String[] { "姓名", "登录名", "角色", "科目" };
-
-	private static final String DEFAULT_PASSWD = "123456";
-	private static Pattern numberRex = Pattern.compile("^1[0-9]{10}$");
-
-	@Autowired
-	private UserCourseRelationService userCourseRelationService;
-	@Autowired
-	private SchoolService schoolService;
-
-	@Override
-	public UserEntity getByLoginName(String phone) {
-		QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<UserEntity> lw = wrapper.lambda();
-		lw.eq(UserEntity::getLoginName, phone);
-		return this.getOne(wrapper);
-	}
-
-	@Transactional
-	@Override
-	public void saveUser(UserDomain domain, User user) {
-		if (domain.getSchoolId() == null) {
-			throw new StatusException("学校不能为空");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(domain.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		if (StringUtils.isBlank(domain.getName())) {
-			throw new StatusException("姓名不能为空");
-		}
-		if (StringUtils.isBlank(domain.getLoginName())) {
-			throw new StatusException("登录名不能为空");
-		}
-
-		if (domain.getRole() == null) {
-			throw new StatusException("角色不能为空");
-		}
-
-		if (domain.getRole().equals(Role.SUPER_ADMIN)) {
-			throw new StatusException("不能新增超管");
-		}
-		if (!domain.getRole().equals(Role.SECTION_LEADER) && domain.getId() == null
-				&& StringUtils.isBlank(domain.getPasswd())) {
-			throw new StatusException("密码不能为空");
-		}
-		if (!domain.getRole().equals(Role.SECTION_LEADER) && CollectionUtils.isNotEmpty(domain.getCourse())) {
-			throw new StatusException("只有科组长可关联科目");
-		}
-		UserEntity ue = null;
-		if (domain.getId() != null) {
-			ue = this.getById(domain.getId());
-			if (ue == null) {
-				throw new StatusException("未找到用户");
-			}
-			if (ue.getRoleId().equals(Role.SUPER_ADMIN.getId())) {
-				throw new StatusException("不能编辑超管");
-			}
-		} else {
-			ue = new UserEntity();
-			ue.setPassword(ByteUtil.toHexAscii(SHA256.encode(domain.getPasswd())));
-			ue.setSchoolId(domain.getSchoolId());
-			ue.setEnable(true);
-		}
-		UserEntity lg = getByLoginName(domain.getLoginName());
-		if (lg != null && (domain.getId() == null || !lg.getId().equals(domain.getId()))) {
-			throw new StatusException("登录名已存在");
-		}
-		ue.setLoginName(domain.getLoginName());
-		ue.setName(domain.getName());
-		ue.setRoleId(domain.getRole().getId());
-		this.saveOrUpdate(ue);
-		if (CollectionUtils.isNotEmpty(domain.getCourse())) {
-			Set<String> set = new HashSet<>();
-			for (String s : domain.getCourse()) {
-				set.add(s);
-			}
-			if (set.size() != domain.getCourse().size()) {
-				throw new StatusException("科目代码不能重复");
-			}
-			userCourseRelationService.saveCourse(ue.getSchoolId(), ue.getId(), domain.getCourse());
-		} else {
-			userCourseRelationService.removeCourse(ue.getId());
-		}
-	}
-
-	@Transactional
-	@Override
-	public List<String> importUser(Long schoolId, User user, MultipartFile file) {
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(schoolId)) {
-			throw new StatusException("没有权限");
-		}
-		InputStream inputStream = null;
-		try {
-			inputStream = file.getInputStream();
-			ExcelReader reader = ExcelReader.create(ExcelType.XLSX, inputStream, 0);
-			List<DataMap> lineList = reader.getDataMapList();
-			if (!Arrays.equals(EXCEL_HEADER, reader.getColumnNames())) {
-				throw new StatusException("Excel表头错误");
-			}
-			if (CollectionUtils.isEmpty(lineList)) {
-				throw new StatusException("Excel无内容");
-			}
-			if (1001 < lineList.size()) {
-				throw new StatusException("数据行数不能超过1000");
-			}
-			List<String> failRecords = new ArrayList<>();
-			List<UserDomain> userList = new ArrayList<>();
-			for (int i = 0; i < lineList.size(); i++) {
-				DataMap line = lineList.get(i);
-
-				StringBuilder msg = new StringBuilder();
-
-				UserDomain impuser = new UserDomain();
-				impuser.setSchoolId(schoolId);
-				String name = trimAndNullIfBlank(line.get(EXCEL_HEADER[0]));
-				if (StringUtils.isBlank(name)) {
-					msg.append("  姓名不能为空");
-				} else if (name.length() > 50) {
-					msg.append("  姓名不能超过50个字符");
-				}
-				impuser.setName(name);
-
-				String loginname = trimAndNullIfBlank(line.get(EXCEL_HEADER[1]));
-				if (StringUtils.isBlank(loginname)) {
-					msg.append("  登录名不能为空");
-				} else if (loginname.length() > 50) {
-					msg.append("  登录名不能超过50个字符");
-				}
-				impuser.setLoginName(loginname);
-
-				String role = trimAndNullIfBlank(line.get(EXCEL_HEADER[2]));
-				if (StringUtils.isBlank(role)) {
-					msg.append("  角色名称不能为空");
-				} else if (Role.getByName(role) == null) {
-					msg.append("  角色名称错误");
-				} else if (Role.SUPER_ADMIN.equals(Role.getByName(role))) {
-					msg.append("  不能新建超级管理员");
-				}
-
-				impuser.setRole(Role.getByName(role));
-
-				if (Role.SECTION_LEADER.equals(impuser.getRole()) && StringUtils.isNotBlank(impuser.getLoginName())) {
-					if (!numberRex.matcher(impuser.getLoginName()).find()) {
-						msg.append("  科组长登录名必须为手机号");
-					}
-
-				}
-
-				String coursecodes = trimAndNullIfBlank(line.get(EXCEL_HEADER[3]));
-				if (StringUtils.isNotBlank(coursecodes)) {
-					impuser.setCourse(Arrays.asList(coursecodes.split(",")));
-				}
-
-				if (msg.length() > 0) {
-					failRecords.add(newError(i + 1, msg.toString()));
-				} else {
-					userList.add(impuser);
-				}
-
-			}
-			if (CollectionUtils.isNotEmpty(failRecords)) {
-				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-				return failRecords;
-			}
-			clearUser(schoolId);
-			for (int i = 0; i < userList.size(); i++) {
-				UserDomain cur = userList.get(i);
-				cur.setPasswd(DEFAULT_PASSWD);
-				try {
-					saveUser(cur, user);
-				} catch (StatusException e) {
-					failRecords.add(newError(i + 1, e.getMessage()));
-				} catch (Exception e) {
-					failRecords.add(newError(i + 1, "系统异常"));
-					log.error("用户导入系统异常", e);
-				}
-			}
-			if (CollectionUtils.isNotEmpty(failRecords)) {
-				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-			}
-			return failRecords;
-		} catch (StatusException e) {
-			throw e;
-		} catch (Exception e) {
-			throw new StatusException("系统错误", e);
-		} finally {
-			if (inputStream != null) {
-				try {
-					inputStream.close();
-				} catch (IOException e) {
-				}
-			}
-		}
-	}
-
-	private void clearUser(Long schoolId) {
-		userCourseRelationService.clearBySchool(schoolId);
-		QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
+
+    private static final String[] EXCEL_HEADER = new String[] { "姓名", "登录名", "角色", "科目" };
+
+    private static final String DEFAULT_PASSWD = "123456";
+
+    private static Pattern numberRex = Pattern.compile("^1[0-9]{10}$");
+
+    @Autowired
+    private UserCourseRelationService userCourseRelationService;
+
+    @Autowired
+    private SchoolService schoolService;
+
+    @Override
+    public UserEntity getByLoginName(String phone) {
+        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<UserEntity> lw = wrapper.lambda();
+        lw.eq(UserEntity::getLoginName, phone);
+        return this.getOne(wrapper);
+    }
+
+    @Transactional
+    @Override
+    public void saveUser(UserDomain domain, User user) {
+        if (domain.getSchoolId() == null) {
+            throw new StatusException("学校不能为空");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(domain.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        if (StringUtils.isBlank(domain.getName())) {
+            throw new StatusException("姓名不能为空");
+        }
+        if (StringUtils.isBlank(domain.getLoginName())) {
+            throw new StatusException("登录名不能为空");
+        }
+
+        if (domain.getRole() == null) {
+            throw new StatusException("角色不能为空");
+        }
+
+        if (domain.getRole().equals(Role.SUPER_ADMIN)) {
+            throw new StatusException("不能新增超管");
+        }
+        if (!domain.getRole().equals(Role.SECTION_LEADER) && domain.getId() == null
+                && StringUtils.isBlank(domain.getPasswd())) {
+            throw new StatusException("密码不能为空");
+        }
+        if (!domain.getRole().equals(Role.SECTION_LEADER) && CollectionUtils.isNotEmpty(domain.getCourse())) {
+            throw new StatusException("只有科组长可关联科目");
+        }
+        UserEntity ue = null;
+        if (domain.getId() != null) {
+            ue = this.getById(domain.getId());
+            if (ue == null) {
+                throw new StatusException("未找到用户");
+            }
+            if (ue.getRoleId().equals(Role.SUPER_ADMIN.getId())) {
+                throw new StatusException("不能编辑超管");
+            }
+        } else {
+            ue = new UserEntity();
+            ue.setPassword(ByteUtil.toHexAscii(SHA256.encode(domain.getPasswd())));
+            ue.setSchoolId(domain.getSchoolId());
+            ue.setEnable(true);
+        }
+        UserEntity lg = getByLoginName(domain.getLoginName());
+        if (lg != null && (domain.getId() == null || !lg.getId().equals(domain.getId()))) {
+            throw new StatusException("登录名已存在");
+        }
+        ue.setLoginName(domain.getLoginName());
+        ue.setName(domain.getName());
+        ue.setRoleId(domain.getRole().getId());
+        this.saveOrUpdate(ue);
+        if (CollectionUtils.isNotEmpty(domain.getCourse())) {
+            Set<String> set = new HashSet<>();
+            for (String s : domain.getCourse()) {
+                set.add(s);
+            }
+            if (set.size() != domain.getCourse().size()) {
+                throw new StatusException("科目代码不能重复");
+            }
+            userCourseRelationService.saveCourse(ue.getSchoolId(), ue.getId(), domain.getCourse());
+        } else {
+            userCourseRelationService.removeCourse(ue.getId());
+        }
+    }
+
+    @Transactional
+    @Override
+    public List<String> importUser(Long schoolId, User user, MultipartFile file) {
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(schoolId)) {
+            throw new StatusException("没有权限");
+        }
+        InputStream inputStream = null;
+        try {
+            inputStream = file.getInputStream();
+            ExcelReader reader = ExcelReader.create(ExcelType.XLSX, inputStream, 0);
+            List<DataMap> lineList = reader.getDataMapList();
+            if (!Arrays.equals(EXCEL_HEADER, reader.getColumnNames())) {
+                throw new StatusException("Excel表头错误");
+            }
+            if (CollectionUtils.isEmpty(lineList)) {
+                throw new StatusException("Excel无内容");
+            }
+            if (1001 < lineList.size()) {
+                throw new StatusException("数据行数不能超过1000");
+            }
+            List<String> failRecords = new ArrayList<>();
+            List<UserDomain> userList = new ArrayList<>();
+            for (int i = 0; i < lineList.size(); i++) {
+                DataMap line = lineList.get(i);
+
+                StringBuilder msg = new StringBuilder();
+
+                UserDomain impuser = new UserDomain();
+                impuser.setSchoolId(schoolId);
+                String name = trimAndNullIfBlank(line.get(EXCEL_HEADER[0]));
+                if (StringUtils.isBlank(name)) {
+                    msg.append("  姓名不能为空");
+                } else if (name.length() > 50) {
+                    msg.append("  姓名不能超过50个字符");
+                }
+                impuser.setName(name);
+
+                String loginname = trimAndNullIfBlank(line.get(EXCEL_HEADER[1]));
+                if (StringUtils.isBlank(loginname)) {
+                    msg.append("  登录名不能为空");
+                } else if (loginname.length() > 50) {
+                    msg.append("  登录名不能超过50个字符");
+                }
+                impuser.setLoginName(loginname);
+
+                String role = trimAndNullIfBlank(line.get(EXCEL_HEADER[2]));
+                if (StringUtils.isBlank(role)) {
+                    msg.append("  角色名称不能为空");
+                } else if (Role.getByName(role) == null) {
+                    msg.append("  角色名称错误");
+                } else if (Role.SUPER_ADMIN.equals(Role.getByName(role))) {
+                    msg.append("  不能新建超级管理员");
+                }
+
+                impuser.setRole(Role.getByName(role));
+
+                if (Role.SECTION_LEADER.equals(impuser.getRole()) && StringUtils.isNotBlank(impuser.getLoginName())) {
+                    if (!numberRex.matcher(impuser.getLoginName()).find()) {
+                        msg.append("  科组长登录名必须为手机号");
+                    }
+
+                }
+
+                String coursecodes = trimAndNullIfBlank(line.get(EXCEL_HEADER[3]));
+                if (StringUtils.isNotBlank(coursecodes)) {
+                    impuser.setCourse(Arrays.asList(coursecodes.split(",")));
+                }
+
+                if (msg.length() > 0) {
+                    failRecords.add(newError(i + 1, msg.toString()));
+                } else {
+                    userList.add(impuser);
+                }
+
+            }
+            if (CollectionUtils.isNotEmpty(failRecords)) {
+                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                return failRecords;
+            }
+            clearUser(schoolId);
+            for (int i = 0; i < userList.size(); i++) {
+                UserDomain cur = userList.get(i);
+                cur.setPasswd(DEFAULT_PASSWD);
+                try {
+                    saveUser(cur, user);
+                } catch (StatusException e) {
+                    failRecords.add(newError(i + 1, e.getMessage()));
+                } catch (Exception e) {
+                    failRecords.add(newError(i + 1, "系统异常"));
+                    log.error("用户导入系统异常", e);
+                }
+            }
+            if (CollectionUtils.isNotEmpty(failRecords)) {
+                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            }
+            return failRecords;
+        } catch (StatusException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new StatusException("系统错误", e);
+        } finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    private void clearUser(Long schoolId) {
+        userCourseRelationService.clearBySchool(schoolId);
+        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
         LambdaQueryWrapper<UserEntity> lw = wrapper.lambda();
         lw.eq(UserEntity::getSchoolId, schoolId);
         lw.ne(UserEntity::getRoleId, Role.SUPER_ADMIN.getId());
         this.remove(wrapper);
-	}
-
-	private String trimAndNullIfBlank(String s) {
-		if (StringUtils.isBlank(s)) {
-			return null;
-		}
-		return s.trim();
-	}
-
-	private String newError(int lineNum, String msg) {
-		return "第" + lineNum + "行" + msg;
-	}
-
-	@Override
-	public PageResult<UserVo> page(UserQuery query, User user) {
-		if (query.getSchoolId() == null) {
-			throw new StatusException("学校不能为空");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(query.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		IPage<UserVo> iPage = this.baseMapper.page(new Page<UserVo>(query.getPageNumber(), query.getPageSize()), query);
-		if (CollectionUtils.isNotEmpty(iPage.getRecords())) {
-			for (UserVo vo : iPage.getRecords()) {
-				vo.setRole(Role.getById(vo.getRoleId()));
-				if (vo.getRoleId().equals(Role.SECTION_LEADER.getId())) {
-					List<CourseInfo> cs = userCourseRelationService.getCourses(vo.getId());
-					vo.setCourseCodes(cs.stream().map(m -> m.getCode()).collect(Collectors.toList()));
-				}
-			}
-		}
-		return PageUtil.of(iPage);
-	}
-
-	@Override
-	public UserVo info(Long id) {
-		UserEntity ue = this.getById(id);
-		if (ue == null) {
-			throw new StatusException("未找到用户信息");
-		}
-		UserVo vo = new UserVo();
-		vo.setEnable(ue.getEnable());
-		vo.setId(ue.getId());
-		vo.setRoleId(ue.getRoleId());
-		vo.setRole(Role.getById(ue.getRoleId()));
-		vo.setLoginName(ue.getLoginName());
-		vo.setName(ue.getName());
-		vo.setSchoolId(ue.getSchoolId());
-		vo.setSchoolName(schoolService.getById(ue.getSchoolId()).getName());
-		if (vo.getRoleId().equals(Role.SECTION_LEADER.getId())) {
-			List<CourseInfo> cs = userCourseRelationService.getCourses(vo.getId());
-			vo.setCourseCodes(cs.stream().map(m -> m.getCode()).collect(Collectors.toList()));
-		}
-		return vo;
-	}
-
-	@Transactional
-	@Override
-	public void toggle(List<Long> ids, Boolean enable, User user) {
-		UpdateWrapper<UserEntity> wrapper = new UpdateWrapper<>();
-		LambdaUpdateWrapper<UserEntity> lw = wrapper.lambda();
-		lw.set(UserEntity::getEnable, enable);
-		lw.in(UserEntity::getId, ids);
-		if (!user.getRole().equals(Role.SUPER_ADMIN)) {
-			lw.eq(UserEntity::getSchoolId, user.getSchoolId());
-		}
-		this.update(wrapper);
-	}
-
-	@Transactional
-	@Override
-	public void updatePass(String password, User accessUser) {
-		if (!accessUser.getRole().equals(Role.SUPER_ADMIN)) {
-			throw new StatusException("不能修改超级管理员");
-		}
-		Long userId = accessUser.getId();
-		String realPassword = StringEscapeUtils.unescapeJava(password);
-		byte[] bytes = SHA256.encode(realPassword);
-		String encodePassword = ByteUtil.toHexAscii(bytes);
-		UserEntity ue = this.getById(userId);
-		if (ue == null) {
-			throw new StatusException("未找到用户信息");
-		}
-		ue.setPassword(encodePassword);
-		this.updateById(ue);
-	}
-
-	@Transactional
-	@Override
-	public void resetPass(Long userId, String passwd, User user) {
-		UserEntity ue = this.getById(userId);
-		if (ue == null) {
-			throw new StatusException("未找到用户信息");
-		}
-		if (ue.getRoleId().equals(Role.SUPER_ADMIN.getId())) {
-			throw new StatusException("不能修改超级管理员");
-		}
-		if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(ue.getSchoolId())) {
-			throw new StatusException("没有权限");
-		}
-		String pw = ByteUtil.toHexAscii(SHA256.encode(passwd));
-		UpdateWrapper<UserEntity> wrapper = new UpdateWrapper<>();
-		LambdaUpdateWrapper<UserEntity> lw = wrapper.lambda();
-		lw.set(UserEntity::getPassword, pw);
-		lw.eq(UserEntity::getId, userId);
-		this.update(wrapper);
-	}
-
-	@Override
-	public UserVo myInfo(User user) {
-		UserEntity ue = this.getById(user.getId());
-		if (ue == null) {
-			throw new StatusException("未找到用户信息");
-		}
-		UserVo vo = new UserVo();
-		vo.setEnable(ue.getEnable());
-		vo.setId(ue.getId());
-		vo.setRoleId(ue.getRoleId());
-		vo.setRole(Role.getById(ue.getRoleId()));
-		vo.setLoginName(ue.getLoginName());
-		vo.setName(ue.getName());
-		vo.setSchoolId(ue.getSchoolId());
-		vo.setSchoolName(schoolService.getById(ue.getSchoolId()).getName());
-		if (vo.getRoleId().equals(Role.SECTION_LEADER.getId())) {
-			List<CourseInfo> cs = userCourseRelationService.getCourses(vo.getId());
-			if (CollectionUtils.isNotEmpty(cs)) {
-				vo.setCourseCodes(cs.stream().map(m -> m.getCode()).collect(Collectors.toList()));
-				vo.setCourseNames(cs.stream().map(m -> m.getCode() + "-" + m.getName()).collect(Collectors.toList()));
-			}
-		}
-		return vo;
-	}
+    }
+
+    private String trimAndNullIfBlank(String s) {
+        if (StringUtils.isBlank(s)) {
+            return null;
+        }
+        return s.trim();
+    }
+
+    private String newError(int lineNum, String msg) {
+        return "第" + lineNum + "行" + msg;
+    }
+
+    @Override
+    public PageResult<UserVo> page(UserQuery query, User user) {
+        if (query.getSchoolId() == null) {
+            throw new StatusException("学校不能为空");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(query.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        IPage<UserVo> iPage = this.baseMapper.page(new Page<UserVo>(query.getPageNumber(), query.getPageSize()), query);
+        if (CollectionUtils.isNotEmpty(iPage.getRecords())) {
+            for (UserVo vo : iPage.getRecords()) {
+                vo.setRole(Role.getById(vo.getRoleId()));
+                if (vo.getRoleId().equals(Role.SECTION_LEADER.getId())) {
+                    List<CourseInfo> cs = userCourseRelationService.getCourses(vo.getId());
+                    vo.setCourseCodes(cs.stream().map(m -> m.getCode()).collect(Collectors.toList()));
+                }
+            }
+        }
+        return PageUtil.of(iPage);
+    }
+
+    @Override
+    public UserVo info(Long id) {
+        UserEntity ue = this.getById(id);
+        if (ue == null) {
+            throw new StatusException("未找到用户信息");
+        }
+        UserVo vo = new UserVo();
+        vo.setEnable(ue.getEnable());
+        vo.setId(ue.getId());
+        vo.setRoleId(ue.getRoleId());
+        vo.setRole(Role.getById(ue.getRoleId()));
+        vo.setLoginName(ue.getLoginName());
+        vo.setName(ue.getName());
+        vo.setSchoolId(ue.getSchoolId());
+        vo.setSchoolName(schoolService.getById(ue.getSchoolId()).getName());
+        if (vo.getRoleId().equals(Role.SECTION_LEADER.getId())) {
+            List<CourseInfo> cs = userCourseRelationService.getCourses(vo.getId());
+            vo.setCourseCodes(cs.stream().map(m -> m.getCode()).collect(Collectors.toList()));
+        }
+        return vo;
+    }
+
+    @Transactional
+    @Override
+    public void toggle(List<Long> ids, Boolean enable, User user) {
+        UpdateWrapper<UserEntity> wrapper = new UpdateWrapper<>();
+        LambdaUpdateWrapper<UserEntity> lw = wrapper.lambda();
+        lw.set(UserEntity::getEnable, enable);
+        lw.in(UserEntity::getId, ids);
+        if (!user.getRole().equals(Role.SUPER_ADMIN)) {
+            lw.eq(UserEntity::getSchoolId, user.getSchoolId());
+        }
+        this.update(wrapper);
+    }
+
+    @Transactional
+    @Override
+    public void updatePass(String password, User accessUser) {
+        if (!accessUser.getRole().equals(Role.SUPER_ADMIN)) {
+            throw new StatusException("不能修改超级管理员");
+        }
+        Long userId = accessUser.getId();
+        String realPassword = StringEscapeUtils.unescapeJava(password);
+        byte[] bytes = SHA256.encode(realPassword);
+        String encodePassword = ByteUtil.toHexAscii(bytes);
+        UserEntity ue = this.getById(userId);
+        if (ue == null) {
+            throw new StatusException("未找到用户信息");
+        }
+        ue.setPassword(encodePassword);
+        this.updateById(ue);
+    }
+
+    @Transactional
+    @Override
+    public void resetPass(Long userId, String passwd, User user) {
+        UserEntity ue = this.getById(userId);
+        if (ue == null) {
+            throw new StatusException("未找到用户信息");
+        }
+        if (ue.getRoleId().equals(Role.SUPER_ADMIN.getId())) {
+            throw new StatusException("不能修改超级管理员");
+        }
+        if (!user.getRole().equals(Role.SUPER_ADMIN) && !user.getSchoolId().equals(ue.getSchoolId())) {
+            throw new StatusException("没有权限");
+        }
+        String pw = ByteUtil.toHexAscii(SHA256.encode(passwd));
+        UpdateWrapper<UserEntity> wrapper = new UpdateWrapper<>();
+        LambdaUpdateWrapper<UserEntity> lw = wrapper.lambda();
+        lw.set(UserEntity::getPassword, pw);
+        lw.eq(UserEntity::getId, userId);
+        this.update(wrapper);
+    }
+
+    @Override
+    public UserVo myInfo(User user) {
+        UserEntity ue = this.getById(user.getId());
+        if (ue == null) {
+            throw new StatusException("未找到用户信息");
+        }
+        UserVo vo = new UserVo();
+        vo.setEnable(ue.getEnable());
+        vo.setId(ue.getId());
+        vo.setRoleId(ue.getRoleId());
+        vo.setRole(Role.getById(ue.getRoleId()));
+        vo.setLoginName(ue.getLoginName());
+        vo.setName(ue.getName());
+        vo.setSchoolId(ue.getSchoolId());
+        vo.setSchoolName(schoolService.getById(ue.getSchoolId()).getName());
+        if (vo.getRoleId().equals(Role.SECTION_LEADER.getId())) {
+            List<CourseInfo> cs = userCourseRelationService.getCourses(vo.getId());
+            if (CollectionUtils.isNotEmpty(cs)) {
+                vo.setCourseCodes(cs.stream().map(m -> m.getCode()).collect(Collectors.toList()));
+                vo.setCourseNames(cs.stream().map(m -> m.getCode() + "-" + m.getName()).collect(Collectors.toList()));
+            }
+        }
+        return vo;
+    }
 
 }

+ 27 - 26
src/main/java/cn/com/qmth/mps/service/impl/WxappAccessTokenServiceImpl.java

@@ -11,31 +11,32 @@ import cn.com.qmth.mps.entity.WxappAccessTokenEntity;
 import cn.com.qmth.mps.service.WxappAccessTokenService;
 
 @Service
-public class WxappAccessTokenServiceImpl extends ServiceImpl<WxappAccessTokenDao, WxappAccessTokenEntity> implements WxappAccessTokenService {
-	private static WxappAccessToken wt;
-	
-	
-	@Override
-	public WxappAccessToken getWxappAccessToken() {
-		if(wt!=null) {
-			return wt;
-		}
-		WxappAccessTokenEntity e=this.getById(1L);
-		wt=new WxappAccessToken();
-		wt.setAccessToken(e.getAccessToken());
-		wt.setExpireTime(e.getExpiresTime());
-		return wt;
-	}
-	
-	@Transactional
-	@Override
-	public void saveWxappAccessToken(String accessToken,Long expiresTime) {
-		wt.setAccessToken(accessToken);
-		wt.setExpireTime(expiresTime);
-		WxappAccessTokenEntity e=this.getById(1L);
-		e.setAccessToken(accessToken);
-		e.setExpiresTime(expiresTime);
-		this.updateById(e);
-	}
+public class WxappAccessTokenServiceImpl extends ServiceImpl<WxappAccessTokenDao, WxappAccessTokenEntity>
+        implements WxappAccessTokenService {
+
+    private static WxappAccessToken wt;
+
+    @Override
+    public WxappAccessToken getWxappAccessToken() {
+        if (wt != null) {
+            return wt;
+        }
+        WxappAccessTokenEntity e = this.getById(1L);
+        wt = new WxappAccessToken();
+        wt.setAccessToken(e.getAccessToken());
+        wt.setExpireTime(e.getExpiresTime());
+        return wt;
+    }
+
+    @Transactional
+    @Override
+    public void saveWxappAccessToken(String accessToken, Long expiresTime) {
+        wt.setAccessToken(accessToken);
+        wt.setExpireTime(expiresTime);
+        WxappAccessTokenEntity e = this.getById(1L);
+        e.setAccessToken(accessToken);
+        e.setExpiresTime(expiresTime);
+        this.updateById(e);
+    }
 
 }

+ 4 - 5
src/main/java/cn/com/qmth/mps/service/impl/WxappInfoServiceImpl.java

@@ -13,13 +13,12 @@ import cn.com.qmth.mps.service.WxappInfoService;
 @Service
 public class WxappInfoServiceImpl extends ServiceImpl<WxappInfoDao, WxappInfoEntity> implements WxappInfoService {
 
-	@Override
-	public WxappInfoEntity getByOpenId(String openid) {
-		QueryWrapper<WxappInfoEntity> wrapper = new QueryWrapper<>();
+    @Override
+    public WxappInfoEntity getByOpenId(String openid) {
+        QueryWrapper<WxappInfoEntity> wrapper = new QueryWrapper<>();
         LambdaQueryWrapper<WxappInfoEntity> lw = wrapper.lambda();
         lw.eq(WxappInfoEntity::getOpenid, openid);
         return this.getOne(wrapper);
-	}
-
+    }
 
 }

+ 105 - 105
src/main/java/cn/com/qmth/mps/support/ApiInfo.java

@@ -9,110 +9,110 @@ import java.io.Serializable;
 
 public class ApiInfo implements Serializable {
 
-	private static final long serialVersionUID = 1553810211239843543L;
-
-	/**
-	 * ID
-	 */
-	private Integer id;
-
-	/**
-	 * 映射
-	 */
-	private String mapping;
-
-	/**
-	 * mapping路径
-	 */
-	private String requestPath;
-
-	/**
-	 * http方法
-	 */
-	private String httpMethod;
-
-	/**
-	 * 接口描述
-	 */
-	private String description;
-
-	/**
-	 * 请求处理类
-	 */
-	private transient Class<?> beanType;
-
-	/**
-	 * 接口日志忽略堆栈
-	 */
-	private boolean withoutStackTrace;
-
-	/**
-	 * 接口裸奔
-	 */
-	private boolean naked;
-
-	public Integer getId() {
-		return id;
-	}
-
-	public void setId(Integer id) {
-		this.id = id;
-	}
-
-	public String getMapping() {
-		return mapping;
-	}
-
-	public void setMapping(String mapping) {
-		this.mapping = mapping;
-	}
-
-	public String getRequestPath() {
-		return requestPath;
-	}
-
-	public void setRequestPath(String requestPath) {
-		this.requestPath = requestPath;
-	}
-
-	public String getHttpMethod() {
-		return httpMethod;
-	}
-
-	public void setHttpMethod(String httpMethod) {
-		this.httpMethod = httpMethod;
-	}
-
-	public String getDescription() {
-		return description;
-	}
-
-	public void setDescription(String description) {
-		this.description = description;
-	}
-
-	public Class<?> getBeanType() {
-		return beanType;
-	}
-
-	public void setBeanType(Class<?> beanType) {
-		this.beanType = beanType;
-	}
-
-	public boolean isWithoutStackTrace() {
-		return withoutStackTrace;
-	}
-
-	public void setWithoutStackTrace(boolean withoutStackTrace) {
-		this.withoutStackTrace = withoutStackTrace;
-	}
-
-	public boolean isNaked() {
-		return naked;
-	}
-
-	public void setNaked(boolean naked) {
-		this.naked = naked;
-	}
+    private static final long serialVersionUID = 1553810211239843543L;
+
+    /**
+     * ID
+     */
+    private Integer id;
+
+    /**
+     * 映射
+     */
+    private String mapping;
+
+    /**
+     * mapping路径
+     */
+    private String requestPath;
+
+    /**
+     * http方法
+     */
+    private String httpMethod;
+
+    /**
+     * 接口描述
+     */
+    private String description;
+
+    /**
+     * 请求处理类
+     */
+    private transient Class<?> beanType;
+
+    /**
+     * 接口日志忽略堆栈
+     */
+    private boolean withoutStackTrace;
+
+    /**
+     * 接口裸奔
+     */
+    private boolean naked;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getMapping() {
+        return mapping;
+    }
+
+    public void setMapping(String mapping) {
+        this.mapping = mapping;
+    }
+
+    public String getRequestPath() {
+        return requestPath;
+    }
+
+    public void setRequestPath(String requestPath) {
+        this.requestPath = requestPath;
+    }
+
+    public String getHttpMethod() {
+        return httpMethod;
+    }
+
+    public void setHttpMethod(String httpMethod) {
+        this.httpMethod = httpMethod;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Class<?> getBeanType() {
+        return beanType;
+    }
+
+    public void setBeanType(Class<?> beanType) {
+        this.beanType = beanType;
+    }
+
+    public boolean isWithoutStackTrace() {
+        return withoutStackTrace;
+    }
+
+    public void setWithoutStackTrace(boolean withoutStackTrace) {
+        this.withoutStackTrace = withoutStackTrace;
+    }
+
+    public boolean isNaked() {
+        return naked;
+    }
+
+    public void setNaked(boolean naked) {
+        this.naked = naked;
+    }
 
 }

+ 110 - 116
src/main/java/cn/com/qmth/mps/support/ApiInfoHolder.java

@@ -28,121 +28,115 @@ import io.swagger.annotations.ApiOperation;
 @Order(100)
 public class ApiInfoHolder implements ApplicationRunner {
 
-	private static final Map<String, ApiInfo> INDEX_BY_MAPPING = Maps.newConcurrentMap();
-
-	private static final Map<Method, ApiInfo> INDEX_BY_METHOD = Maps.newConcurrentMap();
-
-	private static Set<ApiInfo> apiInfoSet = Sets.newHashSet();
-
-	@Autowired
-	private RequestMappingHandlerMapping requestMappingHandlerMapping;
-
-
-	/**
-	 * 通过方法获取ApiInfo
-	 *
-	 * @author 
-	 * @param method
-	 * @return
-	 */
-	public static ApiInfo getApiInfo(Method method) {
-		return INDEX_BY_METHOD.get(method);
-	}
-
-	/**
-	 * 通过mapping获取ApiInfo
-	 *
-	 * @author 
-	 * @param mapping
-	 * @return
-	 */
-	public static ApiInfo getApiInfo(String mapping) {
-		return INDEX_BY_MAPPING.get(mapping);
-	}
-
-	/**
-	 * 获取@ApiId注解的ApiInfo集合
-	 *
-	 * @author 
-	 * @return
-	 */
-	public static Set<ApiInfo> getApiInfoSet() {
-		return apiInfoSet;
-	}
-
-	@Override
-	public void run(ApplicationArguments args) throws Exception {
-
-		Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping
-				.getHandlerMethods();
-
-		for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : map.entrySet()) {
-			RequestMappingInfo requestMappingInfo = entry.getKey();
-			HandlerMethod handlerMethod = entry.getValue();
-
-			Class<?> beanType = handlerMethod.getBeanType();
-
-			RequestMapping requestMappingAnnotationOfClass = AnnotationUtils
-					.findAnnotation(beanType, RequestMapping.class);
-
-			RequestMapping requestMappingAnnotationOfMethod = handlerMethod
-					.getMethodAnnotation(RequestMapping.class);
-
-			WithoutStackTrace withoutStackTrace = handlerMethod
-					.getMethodAnnotation(WithoutStackTrace.class);
-
-			ApiOperation apiOperation = handlerMethod.getMethodAnnotation(ApiOperation.class);
-
-			RequestMethodsRequestCondition requestMethodsRequestCondition = requestMappingInfo
-					.getMethodsCondition();
-			Set<RequestMethod> requestMethodSet = requestMethodsRequestCondition.getMethods();
-
-			String[] mappingURIsOfClass = null;
-			String[] mappingURIsOfMethod = null;
-
-			if (null != requestMappingAnnotationOfClass) {
-				mappingURIsOfClass = requestMappingAnnotationOfClass.path();
-			}
-			if (null != requestMappingAnnotationOfMethod) {
-				mappingURIsOfMethod = requestMappingAnnotationOfMethod.path();
-			}
-
-			String mappingIdentifyOfClass = null;
-			String mappingIdentifyOfMethod = null;
-
-			if (null != mappingURIsOfClass) {
-				mappingIdentifyOfClass = StringUtils.join(mappingURIsOfClass, ",");
-			}
-			if (null != mappingURIsOfMethod) {
-				mappingIdentifyOfMethod = StringUtils.join(mappingURIsOfMethod, ",");
-			}
-
-			String methods = StringUtils.join(requestMethodSet, ",");
-
-			String mapping = StringUtils.join("[", mappingIdentifyOfClass, "][",
-					mappingIdentifyOfMethod, "][", methods, "]");
-
-			PatternsRequestCondition patternsRequestCondition = requestMappingInfo
-					.getPatternsCondition();
-
-			String requestPath = StringUtils.join(patternsRequestCondition.getPatterns(), ",");
-
-			ApiInfo apiInfo = new ApiInfo();
-			if (null != apiOperation) {
-				apiInfo.setDescription(apiOperation.value());
-			}
-			apiInfo.setHttpMethod(methods);
-			apiInfo.setMapping(mapping);
-			apiInfo.setRequestPath(requestPath);
-			apiInfo.setBeanType(beanType);
-			if (null != withoutStackTrace) {
-				apiInfo.setWithoutStackTrace(withoutStackTrace.value());
-			}
-
-			INDEX_BY_METHOD.put(handlerMethod.getMethod(), apiInfo);
-
-			INDEX_BY_MAPPING.put(mapping, apiInfo);
-		}
-	}
+    private static final Map<String, ApiInfo> INDEX_BY_MAPPING = Maps.newConcurrentMap();
+
+    private static final Map<Method, ApiInfo> INDEX_BY_METHOD = Maps.newConcurrentMap();
+
+    private static Set<ApiInfo> apiInfoSet = Sets.newHashSet();
+
+    @Autowired
+    private RequestMappingHandlerMapping requestMappingHandlerMapping;
+
+    /**
+     * 通过方法获取ApiInfo
+     *
+     * @author
+     * @param method
+     * @return
+     */
+    public static ApiInfo getApiInfo(Method method) {
+        return INDEX_BY_METHOD.get(method);
+    }
+
+    /**
+     * 通过mapping获取ApiInfo
+     *
+     * @author
+     * @param mapping
+     * @return
+     */
+    public static ApiInfo getApiInfo(String mapping) {
+        return INDEX_BY_MAPPING.get(mapping);
+    }
+
+    /**
+     * 获取@ApiId注解的ApiInfo集合
+     *
+     * @author
+     * @return
+     */
+    public static Set<ApiInfo> getApiInfoSet() {
+        return apiInfoSet;
+    }
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+
+        Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
+
+        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : map.entrySet()) {
+            RequestMappingInfo requestMappingInfo = entry.getKey();
+            HandlerMethod handlerMethod = entry.getValue();
+
+            Class<?> beanType = handlerMethod.getBeanType();
+
+            RequestMapping requestMappingAnnotationOfClass = AnnotationUtils.findAnnotation(beanType,
+                    RequestMapping.class);
+
+            RequestMapping requestMappingAnnotationOfMethod = handlerMethod.getMethodAnnotation(RequestMapping.class);
+
+            WithoutStackTrace withoutStackTrace = handlerMethod.getMethodAnnotation(WithoutStackTrace.class);
+
+            ApiOperation apiOperation = handlerMethod.getMethodAnnotation(ApiOperation.class);
+
+            RequestMethodsRequestCondition requestMethodsRequestCondition = requestMappingInfo.getMethodsCondition();
+            Set<RequestMethod> requestMethodSet = requestMethodsRequestCondition.getMethods();
+
+            String[] mappingURIsOfClass = null;
+            String[] mappingURIsOfMethod = null;
+
+            if (null != requestMappingAnnotationOfClass) {
+                mappingURIsOfClass = requestMappingAnnotationOfClass.path();
+            }
+            if (null != requestMappingAnnotationOfMethod) {
+                mappingURIsOfMethod = requestMappingAnnotationOfMethod.path();
+            }
+
+            String mappingIdentifyOfClass = null;
+            String mappingIdentifyOfMethod = null;
+
+            if (null != mappingURIsOfClass) {
+                mappingIdentifyOfClass = StringUtils.join(mappingURIsOfClass, ",");
+            }
+            if (null != mappingURIsOfMethod) {
+                mappingIdentifyOfMethod = StringUtils.join(mappingURIsOfMethod, ",");
+            }
+
+            String methods = StringUtils.join(requestMethodSet, ",");
+
+            String mapping = StringUtils.join("[", mappingIdentifyOfClass, "][", mappingIdentifyOfMethod, "][", methods,
+                    "]");
+
+            PatternsRequestCondition patternsRequestCondition = requestMappingInfo.getPatternsCondition();
+
+            String requestPath = StringUtils.join(patternsRequestCondition.getPatterns(), ",");
+
+            ApiInfo apiInfo = new ApiInfo();
+            if (null != apiOperation) {
+                apiInfo.setDescription(apiOperation.value());
+            }
+            apiInfo.setHttpMethod(methods);
+            apiInfo.setMapping(mapping);
+            apiInfo.setRequestPath(requestPath);
+            apiInfo.setBeanType(beanType);
+            if (null != withoutStackTrace) {
+                apiInfo.setWithoutStackTrace(withoutStackTrace.value());
+            }
+
+            INDEX_BY_METHOD.put(handlerMethod.getMethod(), apiInfo);
+
+            INDEX_BY_MAPPING.put(mapping, apiInfo);
+        }
+    }
 
 }

+ 13 - 13
src/main/java/cn/com/qmth/mps/support/BaseResponse.java

@@ -5,25 +5,25 @@ import io.swagger.annotations.ApiModelProperty;
 /**
  * 响应体基类
  * 
- * @author 
+ * @author
  *
  */
 public abstract class BaseResponse extends ExchangeBean {
 
-	private static final long serialVersionUID = 1755304211766414171L;
+    private static final long serialVersionUID = 1755304211766414171L;
 
-	/**
-	 * 耗时(毫秒)
-	 */
-	@ApiModelProperty(value = "耗时(毫秒)", example = "500", required = true)
-	private Long cost;
+    /**
+     * 耗时(毫秒)
+     */
+    @ApiModelProperty(value = "耗时(毫秒)", example = "500", required = true)
+    private Long cost;
 
-	public Long getCost() {
-		return cost;
-	}
+    public Long getCost() {
+        return cost;
+    }
 
-	public void setCost(Long cost) {
-		this.cost = cost;
-	}
+    public void setCost(Long cost) {
+        this.cost = cost;
+    }
 
 }

+ 2 - 2
src/main/java/cn/com/qmth/mps/support/ExchangeBean.java

@@ -3,11 +3,11 @@ package cn.com.qmth.mps.support;
 /**
  * bean 基类
  * 
- * @author 
+ * @author
  *
  */
 public abstract class ExchangeBean implements JsonSerializable {
 
-	private static final long serialVersionUID = 3913250969569367810L;
+    private static final long serialVersionUID = 3913250969569367810L;
 
 }

+ 26 - 26
src/main/java/cn/com/qmth/mps/support/HttpMethodProcessor.java

@@ -8,33 +8,33 @@ import javax.servlet.http.HttpServletRequest;
  */
 public interface HttpMethodProcessor {
 
-	/**
-	 * 方法前处理
-	 *
-	 * @author 
-	 * @param request
-	 * @param args
-	 */
-	void beforeMethod(HttpServletRequest request, Object[] args);
+    /**
+     * 方法前处理
+     *
+     * @author
+     * @param request
+     * @param args
+     */
+    void beforeMethod(HttpServletRequest request, Object[] args);
 
-	/**
-	 * 方法执行未抛出异常时执行
-	 *
-	 * @author 
-	 * @param request
-	 * @param args
-	 * @param ret
-	 */
-	void onSuccess(HttpServletRequest request, Object[] args, Object ret);
+    /**
+     * 方法执行未抛出异常时执行
+     *
+     * @author
+     * @param request
+     * @param args
+     * @param ret
+     */
+    void onSuccess(HttpServletRequest request, Object[] args, Object ret);
 
-	/**
-	 * 方法执行抛出异常时执行
-	 *
-	 * @author 
-	 * @param request
-	 * @param args
-	 * @param e
-	 */
-	void onException(HttpServletRequest request, Object[] args, Throwable e);
+    /**
+     * 方法执行抛出异常时执行
+     *
+     * @author
+     * @param request
+     * @param args
+     * @param e
+     */
+    void onException(HttpServletRequest request, Object[] args, Throwable e);
 
 }

+ 9 - 9
src/main/java/cn/com/qmth/mps/support/HttpMethodProcessorImpl.java

@@ -7,17 +7,17 @@ import org.springframework.stereotype.Component;
 @Component
 public class HttpMethodProcessorImpl implements HttpMethodProcessor {
 
-	@Override
-	public void beforeMethod(HttpServletRequest request, Object[] args) {
+    @Override
+    public void beforeMethod(HttpServletRequest request, Object[] args) {
 
-	}
+    }
 
-	@Override
-	public void onSuccess(HttpServletRequest request, Object[] args, Object ret) {
-	}
+    @Override
+    public void onSuccess(HttpServletRequest request, Object[] args, Object ret) {
+    }
 
-	@Override
-	public void onException(HttpServletRequest request, Object[] args, Throwable e) {
-	}
+    @Override
+    public void onException(HttpServletRequest request, Object[] args, Throwable e) {
+    }
 
 }

+ 25 - 25
src/main/java/cn/com/qmth/mps/support/LogProperties.java

@@ -11,30 +11,30 @@ import org.springframework.stereotype.Component;
 @ConfigurationProperties("scan.web.log")
 public class LogProperties {
 
-	/**
-	 * 是否记录正常相应信息
-	 */
-	private boolean normalResponseLogEnable = true;
-
-	/**
-	 * 正常响应信息json长度限制
-	 */
-	private int responseLogJsonMaxSize = 200;
-
-	public boolean isNormalResponseLogEnable() {
-		return normalResponseLogEnable;
-	}
-
-	public void setNormalResponseLogEnable(boolean normalResponseLogEnable) {
-		this.normalResponseLogEnable = normalResponseLogEnable;
-	}
-
-	public int getResponseLogJsonMaxSize() {
-		return responseLogJsonMaxSize;
-	}
-
-	public void setResponseLogJsonMaxSize(int responseLogJsonMaxSize) {
-		this.responseLogJsonMaxSize = responseLogJsonMaxSize;
-	}
+    /**
+     * 是否记录正常相应信息
+     */
+    private boolean normalResponseLogEnable = true;
+
+    /**
+     * 正常响应信息json长度限制
+     */
+    private int responseLogJsonMaxSize = 200;
+
+    public boolean isNormalResponseLogEnable() {
+        return normalResponseLogEnable;
+    }
+
+    public void setNormalResponseLogEnable(boolean normalResponseLogEnable) {
+        this.normalResponseLogEnable = normalResponseLogEnable;
+    }
+
+    public int getResponseLogJsonMaxSize() {
+        return responseLogJsonMaxSize;
+    }
+
+    public void setResponseLogJsonMaxSize(int responseLogJsonMaxSize) {
+        this.responseLogJsonMaxSize = responseLogJsonMaxSize;
+    }
 
 }

+ 44 - 44
src/main/java/cn/com/qmth/mps/support/SpringContextHolder.java

@@ -12,63 +12,63 @@ import org.springframework.stereotype.Component;
 @Component
 public class SpringContextHolder implements ApplicationContextAware {
 
-	private static ApplicationContext ctx = null;
+    private static ApplicationContext ctx = null;
 
-	@Override
-	public void setApplicationContext(ApplicationContext ctx) {
-		SpringContextHolder.ctx = ctx;
-	}
+    @Override
+    public void setApplicationContext(ApplicationContext ctx) {
+        SpringContextHolder.ctx = ctx;
+    }
 
-	public static ApplicationContext getApplicationContext() {
-		return ctx;
-	}
+    public static ApplicationContext getApplicationContext() {
+        return ctx;
+    }
 
-	public static Object getBean(String name) {
-		return ctx.getBean(name);
-	}
+    public static Object getBean(String name) {
+        return ctx.getBean(name);
+    }
 
-	public static <T> T getBean(String name, Class<T> requiredType) {
-		return ctx.getBean(name, requiredType);
-	}
+    public static <T> T getBean(String name, Class<T> requiredType) {
+        return ctx.getBean(name, requiredType);
+    }
 
-	public static <T> T getBean(Class<T> requiredType) {
-		return ctx.getBean(requiredType);
-	}
+    public static <T> T getBean(Class<T> requiredType) {
+        return ctx.getBean(requiredType);
+    }
 
-	public static Object getBean(String name, Object... args) {
-		return ctx.getBean(name, args);
-	}
+    public static Object getBean(String name, Object... args) {
+        return ctx.getBean(name, args);
+    }
 
-	public static <T> T getBean(Class<T> requiredType, Object... args) {
-		return ctx.getBean(requiredType, args);
-	}
+    public static <T> T getBean(Class<T> requiredType, Object... args) {
+        return ctx.getBean(requiredType, args);
+    }
 
-	public static boolean containsBean(String name) {
-		return ctx.containsBean(name);
-	}
+    public static boolean containsBean(String name) {
+        return ctx.containsBean(name);
+    }
 
-	public static boolean isSingleton(String name) {
-		return ctx.isSingleton(name);
-	}
+    public static boolean isSingleton(String name) {
+        return ctx.isSingleton(name);
+    }
 
-	public static boolean isPrototype(String name) {
-		return ctx.isPrototype(name);
-	}
+    public static boolean isPrototype(String name) {
+        return ctx.isPrototype(name);
+    }
 
-	public static boolean isTypeMatch(String name, ResolvableType typeToMatch) {
-		return ctx.isTypeMatch(name, typeToMatch);
-	}
+    public static boolean isTypeMatch(String name, ResolvableType typeToMatch) {
+        return ctx.isTypeMatch(name, typeToMatch);
+    }
 
-	public static boolean isTypeMatch(String name, Class<?> typeToMatch) {
-		return ctx.isTypeMatch(name, typeToMatch);
-	}
+    public static boolean isTypeMatch(String name, Class<?> typeToMatch) {
+        return ctx.isTypeMatch(name, typeToMatch);
+    }
 
-	public static Class<?> getType(String name) {
-		return ctx.getType(name);
-	}
+    public static Class<?> getType(String name) {
+        return ctx.getType(name);
+    }
 
-	public static String[] getAliases(String name) {
-		return ctx.getAliases(name);
-	}
+    public static String[] getAliases(String name) {
+        return ctx.getAliases(name);
+    }
 
 }

+ 43 - 43
src/main/java/cn/com/qmth/mps/support/StatusResponse.java

@@ -8,48 +8,48 @@ import io.swagger.annotations.ApiModelProperty;
  */
 public class StatusResponse implements JsonSerializable {
 
-	private static final long serialVersionUID = 8393074113722405560L;
-
-	@ApiModelProperty(value = "响应编码", example = "001001", required = true)
-	private Integer code;
-
-	@ApiModelProperty(value = "响应描述", example = "密码错误", required = true)
-	private String desc;
-
-	/**
-	 * 构造函数
-	 *
-	 */
-	public StatusResponse() {
-		super();
-	}
-
-	/**
-	 * 构造函数
-	 *
-	 * @param code
-	 * @param desc
-	 */
-	public StatusResponse(Integer code, String desc) {
-		super();
-		this.code = code;
-		this.desc = desc;
-	}
-
-	public Integer getCode() {
-		return code;
-	}
-
-	public void setCode(Integer code) {
-		this.code = code;
-	}
-
-	public String getDesc() {
-		return desc;
-	}
-
-	public void setDesc(String desc) {
-		this.desc = desc;
-	}
+    private static final long serialVersionUID = 8393074113722405560L;
+
+    @ApiModelProperty(value = "响应编码", example = "001001", required = true)
+    private Integer code;
+
+    @ApiModelProperty(value = "响应描述", example = "密码错误", required = true)
+    private String desc;
+
+    /**
+     * 构造函数
+     *
+     */
+    public StatusResponse() {
+        super();
+    }
+
+    /**
+     * 构造函数
+     *
+     * @param code
+     * @param desc
+     */
+    public StatusResponse(Integer code, String desc) {
+        super();
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
 
 }

+ 1 - 1
src/main/java/cn/com/qmth/mps/support/WithoutStackTrace.java

@@ -16,6 +16,6 @@ import java.lang.annotation.Target;
 @Documented
 public @interface WithoutStackTrace {
 
-	boolean value() default true;
+    boolean value() default true;
 
 }

+ 8 - 9
src/main/java/cn/com/qmth/mps/util/AuthorizationCreateUtil.java

@@ -8,15 +8,14 @@ import com.qmth.boot.tools.signature.SignatureType;
  */
 public class AuthorizationCreateUtil {
 
-    
     public static void main(String[] args) {
-    	long time = System.currentTimeMillis();
-    	String identity="SUPER_ADMIN_1";//登录后user属性
-    	String token="ffffffffe81423190000000035ea37c4";//登录后user属性
-    	String url="/api/paper/import-struct-subject";//请求路径
-    	String s = SignatureEntity.build(SignatureType.TOKEN, "post", url, time, identity, token);
-    	System.out.println("time:"+time);
-    	System.out.println("Authorization:"+s);
-	}
+        long time = System.currentTimeMillis();
+        String identity = "SUPER_ADMIN_1";// 登录后user属性
+        String token = "ffffffffe81423190000000035ea37c4";// 登录后user属性
+        String url = "/api/paper/import-struct-subject";// 请求路径
+        String s = SignatureEntity.build(SignatureType.TOKEN, "post", url, time, identity, token);
+        System.out.println("time:" + time);
+        System.out.println("Authorization:" + s);
+    }
 
 }

+ 51 - 41
src/main/java/cn/com/qmth/mps/util/BatchGetDataUtil.java

@@ -6,48 +6,58 @@ import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
 
 /**
- *	多次批量获取数据
+ * 多次批量获取数据
+ * 
  * @author xiatian
- * @param <R> 结果类
- * @param <P> 参数类
+ * @param <R>
+ *            结果类
+ * @param <P>
+ *            参数类
  */
-public abstract  class BatchGetDataUtil<R,P> {
-	/**
-	 * @param resultList 全部结果集合
-	 * @param paramList 全部参数集合
-	 * @param batchSize 每批参数数量
-	 */
-	public final List<R> getDataForBatch(List<P> paramList,int batchSize) {
-		if(CollectionUtils.isEmpty(paramList)) {
-			return null;
-		}
-		List<R> resultList=new ArrayList<>();
-		if(paramList.size()<=batchSize) {
-			List<R> temlist = getData(paramList);
-			if(temlist!=null&&temlist.size()>0) {
-				resultList.addAll(temlist);
-			}
-		}else {
-			int size = paramList.size();
-			int len=batchSize;
-			int count = (size + len - 1) / len;
+public abstract class BatchGetDataUtil<R, P> {
 
-			for (int i = 0; i < count; i++) {
-				List<P> subList = paramList.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
-				List<R> temlist = getData(subList);
-				if(temlist!=null&&temlist.size()>0) {
-					resultList.addAll(temlist);
-				}
-			}
-		}
-		return resultList;
-	}
-	/**
-	 * 	每批获取数据方法
-	 * @param <R>
-	 * @param <P>
-	 * @param paramList 获取每批数据时参数
-	 * @return
-	 */
-	protected abstract  List<R> getData(List<P> paramList);
+    /**
+     * @param resultList
+     *            全部结果集合
+     * @param paramList
+     *            全部参数集合
+     * @param batchSize
+     *            每批参数数量
+     */
+    public final List<R> getDataForBatch(List<P> paramList, int batchSize) {
+        if (CollectionUtils.isEmpty(paramList)) {
+            return null;
+        }
+        List<R> resultList = new ArrayList<>();
+        if (paramList.size() <= batchSize) {
+            List<R> temlist = getData(paramList);
+            if (temlist != null && temlist.size() > 0) {
+                resultList.addAll(temlist);
+            }
+        } else {
+            int size = paramList.size();
+            int len = batchSize;
+            int count = (size + len - 1) / len;
+
+            for (int i = 0; i < count; i++) {
+                List<P> subList = paramList.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
+                List<R> temlist = getData(subList);
+                if (temlist != null && temlist.size() > 0) {
+                    resultList.addAll(temlist);
+                }
+            }
+        }
+        return resultList;
+    }
+
+    /**
+     * 每批获取数据方法
+     * 
+     * @param <R>
+     * @param <P>
+     * @param paramList
+     *            获取每批数据时参数
+     * @return
+     */
+    protected abstract List<R> getData(List<P> paramList);
 }

+ 24 - 21
src/main/java/cn/com/qmth/mps/util/BatchSetDataUtil.java

@@ -3,27 +3,30 @@ package cn.com.qmth.mps.util;
 import java.util.List;
 
 public abstract class BatchSetDataUtil<P> {
-	/**
-	 * @param dataList 待填充的对象集合
-	 * @param batchSize 每批数量
-	 */
-	public final void setDataForBatch(List<P> dataList, int batchSize) {
-		if (dataList == null || dataList.size() == 0) {
-			return;
-		}
-		if (dataList.size() <= batchSize) {
-			setData(dataList);
-		} else {
-			int size = dataList.size();
-			int len = batchSize;
-			int count = (size + len - 1) / len;
 
-			for (int i = 0; i < count; i++) {
-				List<P> subList = dataList.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
-				setData(subList);
-			}
-		}
-	}
+    /**
+     * @param dataList
+     *            待填充的对象集合
+     * @param batchSize
+     *            每批数量
+     */
+    public final void setDataForBatch(List<P> dataList, int batchSize) {
+        if (dataList == null || dataList.size() == 0) {
+            return;
+        }
+        if (dataList.size() <= batchSize) {
+            setData(dataList);
+        } else {
+            int size = dataList.size();
+            int len = batchSize;
+            int count = (size + len - 1) / len;
 
-	protected abstract void setData(List<P> dataList);
+            for (int i = 0; i < count; i++) {
+                List<P> subList = dataList.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
+                setData(subList);
+            }
+        }
+    }
+
+    protected abstract void setData(List<P> dataList);
 }

+ 103 - 102
src/main/java/cn/com/qmth/mps/util/ByteUtil.java

@@ -7,110 +7,111 @@ import java.io.StringWriter;
 /**
  * 字节转换工具
  *
- * @author 
+ * @author
  * @date 2018427
  */
 public class ByteUtil {
-	public final static short UNSIGNED_MAX_VALUE = (Byte.MAX_VALUE * 2) + 1;
-
-	private ByteUtil() {
-	}
-
-	public static int unsignedPromote(byte b) {
-		return b & 0xff;
-	}
-
-	public static String toHexAscii(byte b) {
-		StringWriter sw = new StringWriter(2);
-		addHexAscii(b, sw);
-		return sw.toString();
-	}
-
-	public static String toLowercaseHexAscii(byte b) {
-		StringWriter sw = new StringWriter(2);
-		addLowercaseHexAscii(b, sw);
-		return sw.toString();
-	}
-
-	public static String toHexAscii(byte[] bytes) {
-		int len = bytes.length;
-		StringWriter sw = new StringWriter(len * 2);
-		for (int i = 0; i < len; ++i)
-			addHexAscii(bytes[i], sw);
-		return sw.toString();
-	}
-
-	public static String toLowercaseHexAscii(byte[] bytes) {
-		int len = bytes.length;
-		StringWriter sw = new StringWriter(len * 2);
-		for (int i = 0; i < len; ++i)
-			addLowercaseHexAscii(bytes[i], sw);
-		return sw.toString();
-	}
-
-	public static byte[] fromHexAscii(String s) throws NumberFormatException {
-		try {
-			int len = s.length();
-			if ((len % 2) != 0)
-				throw new NumberFormatException("Hex ascii must be exactly two digits per byte.");
-
-			int out_len = len / 2;
-			byte[] out = new byte[out_len];
-			int i = 0;
-			StringReader sr = new StringReader(s);
-			while (i < out_len) {
-				int val = (16 * fromHexDigit(sr.read())) + fromHexDigit(sr.read());
-				out[i++] = (byte) val;
-			}
-			return out;
-		} catch (IOException e) {
-			throw new InternalError("IOException reading from StringReader?!?!");
-		}
-	}
-
-	static void addHexAscii(byte b, StringWriter sw) {
-		int ub = unsignedPromote(b);
-		int h1 = ub / 16;
-		int h2 = ub % 16;
-		sw.write(toHexDigit(h1));
-		sw.write(toHexDigit(h2));
-	}
-
-	static void addLowercaseHexAscii(byte b, StringWriter sw) {
-		int ub = unsignedPromote(b);
-		int h1 = ub / 16;
-		int h2 = ub % 16;
-		sw.write(toLowercaseHexDigit(h1));
-		sw.write(toLowercaseHexDigit(h2));
-	}
-
-	private static int fromHexDigit(int c) throws NumberFormatException {
-		if (c >= 0x30 && c < 0x3A)
-			return c - 0x30;
-		else if (c >= 0x41 && c < 0x47)
-			return c - 0x37;
-		else if (c >= 0x61 && c < 0x67)
-			return c - 0x57;
-		else
-			throw new NumberFormatException('\'' + c + "' is not a valid hexadecimal digit.");
-	}
-
-	private static char toHexDigit(int h) {
-		char out;
-		if (h <= 9)
-			out = (char) (h + 0x30);
-		else
-			out = (char) (h + 0x37);
-		return out;
-	}
-
-	private static char toLowercaseHexDigit(int h) {
-		char out;
-		if (h <= 9)
-			out = (char) (h + 0x30);
-		else
-			out = (char) (h + 0x57);
-		return out;
-	}
+
+    public final static short UNSIGNED_MAX_VALUE = (Byte.MAX_VALUE * 2) + 1;
+
+    private ByteUtil() {
+    }
+
+    public static int unsignedPromote(byte b) {
+        return b & 0xff;
+    }
+
+    public static String toHexAscii(byte b) {
+        StringWriter sw = new StringWriter(2);
+        addHexAscii(b, sw);
+        return sw.toString();
+    }
+
+    public static String toLowercaseHexAscii(byte b) {
+        StringWriter sw = new StringWriter(2);
+        addLowercaseHexAscii(b, sw);
+        return sw.toString();
+    }
+
+    public static String toHexAscii(byte[] bytes) {
+        int len = bytes.length;
+        StringWriter sw = new StringWriter(len * 2);
+        for (int i = 0; i < len; ++i)
+            addHexAscii(bytes[i], sw);
+        return sw.toString();
+    }
+
+    public static String toLowercaseHexAscii(byte[] bytes) {
+        int len = bytes.length;
+        StringWriter sw = new StringWriter(len * 2);
+        for (int i = 0; i < len; ++i)
+            addLowercaseHexAscii(bytes[i], sw);
+        return sw.toString();
+    }
+
+    public static byte[] fromHexAscii(String s) throws NumberFormatException {
+        try {
+            int len = s.length();
+            if ((len % 2) != 0)
+                throw new NumberFormatException("Hex ascii must be exactly two digits per byte.");
+
+            int out_len = len / 2;
+            byte[] out = new byte[out_len];
+            int i = 0;
+            StringReader sr = new StringReader(s);
+            while (i < out_len) {
+                int val = (16 * fromHexDigit(sr.read())) + fromHexDigit(sr.read());
+                out[i++] = (byte) val;
+            }
+            return out;
+        } catch (IOException e) {
+            throw new InternalError("IOException reading from StringReader?!?!");
+        }
+    }
+
+    static void addHexAscii(byte b, StringWriter sw) {
+        int ub = unsignedPromote(b);
+        int h1 = ub / 16;
+        int h2 = ub % 16;
+        sw.write(toHexDigit(h1));
+        sw.write(toHexDigit(h2));
+    }
+
+    static void addLowercaseHexAscii(byte b, StringWriter sw) {
+        int ub = unsignedPromote(b);
+        int h1 = ub / 16;
+        int h2 = ub % 16;
+        sw.write(toLowercaseHexDigit(h1));
+        sw.write(toLowercaseHexDigit(h2));
+    }
+
+    private static int fromHexDigit(int c) throws NumberFormatException {
+        if (c >= 0x30 && c < 0x3A)
+            return c - 0x30;
+        else if (c >= 0x41 && c < 0x47)
+            return c - 0x37;
+        else if (c >= 0x61 && c < 0x67)
+            return c - 0x57;
+        else
+            throw new NumberFormatException('\'' + c + "' is not a valid hexadecimal digit.");
+    }
+
+    private static char toHexDigit(int h) {
+        char out;
+        if (h <= 9)
+            out = (char) (h + 0x30);
+        else
+            out = (char) (h + 0x37);
+        return out;
+    }
+
+    private static char toLowercaseHexDigit(int h) {
+        char out;
+        if (h <= 9)
+            out = (char) (h + 0x30);
+        else
+            out = (char) (h + 0x57);
+        return out;
+    }
 
 }

+ 56 - 49
src/main/java/cn/com/qmth/mps/util/Calculator.java

@@ -5,59 +5,66 @@ import java.math.BigDecimal;
 /**
  * 计算器
  *
- * @author 
+ * @author
  * @date 2019730
  * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
  */
 public class Calculator {
 
-	public static double add(double v1, double v2) {
-		BigDecimal b1 = new BigDecimal(Double.toString(v1));
-		BigDecimal b2 = new BigDecimal(Double.toString(v2));
-		return b1.add(b2).doubleValue();
-
-	}
-	public static double add(double v1, double v2,int len) {
-		BigDecimal b1 = new BigDecimal(Double.toString(v1));
-		BigDecimal b2 = new BigDecimal(Double.toString(v2));
-		return b1.add(b2).setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();
-
-	}
-
-	/**减法
-	 * @param v1
-	 * @param v2
-	 * @return
-	 */
-	public static double subtract(double v1, double v2) {
-		BigDecimal b1 = new BigDecimal(Double.toString(v1));
-		BigDecimal b2 = new BigDecimal(Double.toString(v2));
-		return b1.subtract(b2).doubleValue();
-
-	}
-
-	/**乘法
-	 * @param v1
-	 * @param v2
-	 * @return
-	 */
-	public static double multiply(double v1, double v2) {
-		BigDecimal b1 = new BigDecimal(v1);
-		BigDecimal b2 = new BigDecimal(v2);
-		return b1.multiply(b2).doubleValue();
-
-	}
-
-	/**除法
-	 * @param v1
-	 * @param v2
-	 * @param len
-	 * @return
-	 */
-	public static double divide(double v1, double v2, int len) {
-		BigDecimal b1 = new BigDecimal(v1);
-		BigDecimal b2 = new BigDecimal(v2);
-		return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue();
-	}
+    public static double add(double v1, double v2) {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.add(b2).doubleValue();
+
+    }
+
+    public static double add(double v1, double v2, int len) {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.add(b2).setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();
+
+    }
+
+    /**
+     * 减法
+     * 
+     * @param v1
+     * @param v2
+     * @return
+     */
+    public static double subtract(double v1, double v2) {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.subtract(b2).doubleValue();
+
+    }
+
+    /**
+     * 乘法
+     * 
+     * @param v1
+     * @param v2
+     * @return
+     */
+    public static double multiply(double v1, double v2) {
+        BigDecimal b1 = new BigDecimal(v1);
+        BigDecimal b2 = new BigDecimal(v2);
+        return b1.multiply(b2).doubleValue();
+
+    }
+
+    /**
+     * 除法
+     * 
+     * @param v1
+     * @param v2
+     * @param len
+     * @return
+     */
+    public static double divide(double v1, double v2, int len) {
+        BigDecimal b1 = new BigDecimal(v1);
+        BigDecimal b2 = new BigDecimal(v2);
+        return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue();
+    }
 
 }

+ 195 - 196
src/main/java/cn/com/qmth/mps/util/DateUtil.java

@@ -8,207 +8,206 @@ import java.util.Date;
 
 import com.qmth.boot.core.exception.StatusException;
 
-
 /**
  * 日期工具
  * 
- * @author 
+ * @author
  */
 public class DateUtil {
 
-	/**
-	 * patterns describing the date and time format
-	 *
-	 * @author 
-	 */
-	public interface DatePatterns {
-
-		public static final String DEFAULT = "yyyyMMddHHmmss";
-
-		public static final String YYYY = "yyyy";
-
-		public static final String YYYYMM = "yyyyMM";
-
-		public static final String YYYYMMDD = "yyyyMMdd";
-
-		public static final String YYYYMMDDHH = "yyyyMMddHH";
-
-		public static final String YYYYMMDDHHMM = "yyyyMMddHHmm";
-
-		public static final String CHINA_DEFAULT = "yyyy-MM-dd HH:mm:ss";
-
-		public static final String YYYY_MM = "yyyy-MM";
-
-		public static final String YYYY_MM_DD = "yyyy-MM-dd";
-
-		public static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
-
-		public static final String YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd HH:mm:ss.SSS";
-	}
-
-	/**
-	 * get now date.
-	 * 
-	 * @param pattern
-	 * @return
-	 */
-	public static String now(String pattern) {
-		return format(new Date(), pattern);
-	}
-
-	/**
-	 * get now china date.
-	 * 
-	 * @return
-	 */
-	public static String chinaNow() {
-		return format(new Date(), DatePatterns.CHINA_DEFAULT);
-	}
-
-	/**
-	 * format date.
-	 * 
-	 * @param date
-	 * @param pattern
-	 * @return
-	 */
-	public static String format(Date date, String pattern) {
-		if(date==null) {
-			return null;
-		}
-		try {
-			SimpleDateFormat df = new SimpleDateFormat(pattern);
-			return df.format(date);
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		}
-	}
-
-	/**
-	 * format now date.
-	 *
-	 * @author 
-	 * @param pattern
-	 * @return
-	 */
-	public static String formatNow(String pattern) {
-		try {
-			SimpleDateFormat df = new SimpleDateFormat(pattern);
-			return df.format(new Date());
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		}
-	}
-
-	/**
-	 * parse date.
-	 * 
-	 * @param source
-	 * @param pattern
-	 * @return
-	 */
-	public static Date parse(String source, String pattern) {
-		SimpleDateFormat df = new SimpleDateFormat(pattern);
-		try {
-			return df.parse(source);
-		} catch (ParseException e) {
-			throw new RuntimeException(e);
-		}
-	}
-
-	/**
-	 * parse date randomly.
-	 *
-	 * @author 
-	 * @param s
-	 * @return
-	 */
-	public static Date parseRandomly(String s) {
-		if (s.matches("\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{1,2}:\\d{1,2}")) {
-			return parse(s, "yyyy/MM/dd HH:mm:ss");
-		} else if (s.matches("\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{1,2}")) {
-			return parse(s, "yyyy/MM/dd HH:mm");
-		} else if (s.matches("\\d{4}/\\d{1,2}/\\d{1,2}")) {
-			return parse(s, "yyyy/MM/dd");
-		} else if (s.matches("\\d{4}-\\d{1,2}-\\d{1,2}\\s+\\d{1,2}:\\d{1,2}:\\d{1,2}")) {
-			return parse(s, "yyyy-MM-dd HH:mm:ss");
-		} else if (s.matches("\\d{4}-\\d{1,2}-\\d{1,2}\\s+\\d{1,2}:\\d{1,2}")) {
-			return parse(s, "yyyy-MM-dd HH:mm");
-		} else if (s.matches("\\d{4}-\\d{1,2}-\\d{1,2}")) {
-			return parse(s, "yyyy-MM-dd");
-		} else {
-			throw new StatusException("unsupported date string.");
-		}
-	}
-
-	/**
-	 * 解析excel日期
-	 *
-	 * @author 
-	 * @param number
-	 * @return
-	 */
-	public static Date parseExcel(String number) {
-
-		BigDecimal bd = new BigDecimal(number);
-		int days = bd.intValue();
-		int mills = (int) Math.round(bd.subtract(new BigDecimal(days)).doubleValue() * 24 * 3600);
-
-		Calendar c = Calendar.getInstance();
-		c.set(1900, 0, 1);
-		c.add(Calendar.DATE, days - 2);
-		int hour = mills / 3600;
-		int minute = (mills - hour * 3600) / 60;
-		int second = mills - hour * 3600 - minute * 60;
-		c.set(Calendar.HOUR_OF_DAY, hour);
-		c.set(Calendar.MINUTE, minute);
-		c.set(Calendar.SECOND, second);
-
-		Date date = c.getTime();
-
-		return date;
-	}
-
-	/**
-	 * 是否同一天
-	 *
-	 * @author 
-	 * @param date1
-	 * @param date2
-	 * @return
-	 */
-	public static boolean isSameDay(Date date1, Date date2) {
-		if (null == date1) {
-			throw new StatusException("first argument must not be null");
-		}
-		if (null == date2) {
-			throw new StatusException("second argument must not be null");
-		}
-
-		Calendar cal1 = Calendar.getInstance();
-		cal1.setTime(date1);
-		Calendar cal2 = Calendar.getInstance();
-		cal2.setTime(date2);
-		return isSameDay(cal1, cal2);
-	}
-
-	/**
-	 * 是否同一天
-	 *
-	 * @author 
-	 * @param calendar1
-	 * @param calendar2
-	 * @return
-	 */
-	public static boolean isSameDay(Calendar calendar1, Calendar calendar2) {
-		if (null == calendar1) {
-			throw new StatusException("first argument must not be null");
-		}
-		if (null == calendar2) {
-			throw new StatusException("second argument must not be null");
-		}
-		return calendar1.get(0) == calendar2.get(0) && calendar1.get(1) == calendar2.get(1)
-				&& calendar1.get(6) == calendar2.get(6);
-	}
+    /**
+     * patterns describing the date and time format
+     *
+     * @author
+     */
+    public interface DatePatterns {
+
+        public static final String DEFAULT = "yyyyMMddHHmmss";
+
+        public static final String YYYY = "yyyy";
+
+        public static final String YYYYMM = "yyyyMM";
+
+        public static final String YYYYMMDD = "yyyyMMdd";
+
+        public static final String YYYYMMDDHH = "yyyyMMddHH";
+
+        public static final String YYYYMMDDHHMM = "yyyyMMddHHmm";
+
+        public static final String CHINA_DEFAULT = "yyyy-MM-dd HH:mm:ss";
+
+        public static final String YYYY_MM = "yyyy-MM";
+
+        public static final String YYYY_MM_DD = "yyyy-MM-dd";
+
+        public static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
+
+        public static final String YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd HH:mm:ss.SSS";
+    }
+
+    /**
+     * get now date.
+     * 
+     * @param pattern
+     * @return
+     */
+    public static String now(String pattern) {
+        return format(new Date(), pattern);
+    }
+
+    /**
+     * get now china date.
+     * 
+     * @return
+     */
+    public static String chinaNow() {
+        return format(new Date(), DatePatterns.CHINA_DEFAULT);
+    }
+
+    /**
+     * format date.
+     * 
+     * @param date
+     * @param pattern
+     * @return
+     */
+    public static String format(Date date, String pattern) {
+        if (date == null) {
+            return null;
+        }
+        try {
+            SimpleDateFormat df = new SimpleDateFormat(pattern);
+            return df.format(date);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * format now date.
+     *
+     * @author
+     * @param pattern
+     * @return
+     */
+    public static String formatNow(String pattern) {
+        try {
+            SimpleDateFormat df = new SimpleDateFormat(pattern);
+            return df.format(new Date());
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * parse date.
+     * 
+     * @param source
+     * @param pattern
+     * @return
+     */
+    public static Date parse(String source, String pattern) {
+        SimpleDateFormat df = new SimpleDateFormat(pattern);
+        try {
+            return df.parse(source);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * parse date randomly.
+     *
+     * @author
+     * @param s
+     * @return
+     */
+    public static Date parseRandomly(String s) {
+        if (s.matches("\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{1,2}:\\d{1,2}")) {
+            return parse(s, "yyyy/MM/dd HH:mm:ss");
+        } else if (s.matches("\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{1,2}")) {
+            return parse(s, "yyyy/MM/dd HH:mm");
+        } else if (s.matches("\\d{4}/\\d{1,2}/\\d{1,2}")) {
+            return parse(s, "yyyy/MM/dd");
+        } else if (s.matches("\\d{4}-\\d{1,2}-\\d{1,2}\\s+\\d{1,2}:\\d{1,2}:\\d{1,2}")) {
+            return parse(s, "yyyy-MM-dd HH:mm:ss");
+        } else if (s.matches("\\d{4}-\\d{1,2}-\\d{1,2}\\s+\\d{1,2}:\\d{1,2}")) {
+            return parse(s, "yyyy-MM-dd HH:mm");
+        } else if (s.matches("\\d{4}-\\d{1,2}-\\d{1,2}")) {
+            return parse(s, "yyyy-MM-dd");
+        } else {
+            throw new StatusException("unsupported date string.");
+        }
+    }
+
+    /**
+     * 解析excel日期
+     *
+     * @author
+     * @param number
+     * @return
+     */
+    public static Date parseExcel(String number) {
+
+        BigDecimal bd = new BigDecimal(number);
+        int days = bd.intValue();
+        int mills = (int) Math.round(bd.subtract(new BigDecimal(days)).doubleValue() * 24 * 3600);
+
+        Calendar c = Calendar.getInstance();
+        c.set(1900, 0, 1);
+        c.add(Calendar.DATE, days - 2);
+        int hour = mills / 3600;
+        int minute = (mills - hour * 3600) / 60;
+        int second = mills - hour * 3600 - minute * 60;
+        c.set(Calendar.HOUR_OF_DAY, hour);
+        c.set(Calendar.MINUTE, minute);
+        c.set(Calendar.SECOND, second);
+
+        Date date = c.getTime();
+
+        return date;
+    }
+
+    /**
+     * 是否同一天
+     *
+     * @author
+     * @param date1
+     * @param date2
+     * @return
+     */
+    public static boolean isSameDay(Date date1, Date date2) {
+        if (null == date1) {
+            throw new StatusException("first argument must not be null");
+        }
+        if (null == date2) {
+            throw new StatusException("second argument must not be null");
+        }
+
+        Calendar cal1 = Calendar.getInstance();
+        cal1.setTime(date1);
+        Calendar cal2 = Calendar.getInstance();
+        cal2.setTime(date2);
+        return isSameDay(cal1, cal2);
+    }
+
+    /**
+     * 是否同一天
+     *
+     * @author
+     * @param calendar1
+     * @param calendar2
+     * @return
+     */
+    public static boolean isSameDay(Calendar calendar1, Calendar calendar2) {
+        if (null == calendar1) {
+            throw new StatusException("first argument must not be null");
+        }
+        if (null == calendar2) {
+            throw new StatusException("second argument must not be null");
+        }
+        return calendar1.get(0) == calendar2.get(0) && calendar1.get(1) == calendar2.get(1)
+                && calendar1.get(6) == calendar2.get(6);
+    }
 
 }

+ 70 - 70
src/main/java/cn/com/qmth/mps/util/FileUtil.java

@@ -14,77 +14,77 @@ import com.qmth.boot.core.exception.StatusException;
 
 public class FileUtil {
 
-	public static String readFileContent(InputStream in) {
-		StringBuilder content = new StringBuilder();
-		InputStreamReader streamReader = null;
-		BufferedReader bufferedReader = null;
-		try {
-			String encoding = "UTF-8";
-			streamReader = new InputStreamReader(in, encoding);
-			bufferedReader = new BufferedReader(streamReader);
-			String line;
-			while ((line = bufferedReader.readLine()) != null) {
-				content.append(line);
-			}
-			return content.toString();
-		} catch (IOException e) {
-			throw new StatusException("出错", e);
-		} finally {
-			if(streamReader!=null) {
-				try {
-					streamReader.close();
-				} catch (IOException e) {
-				}
-			}
-			if(bufferedReader!=null) {
-				try {
-					bufferedReader.close();
-				} catch (IOException e) {
-				}
-			}
-			if(in!=null) {
-				try {
-					in.close();
-				} catch (IOException e) {
-				}
-			}
-		}
-	}
+    public static String readFileContent(InputStream in) {
+        StringBuilder content = new StringBuilder();
+        InputStreamReader streamReader = null;
+        BufferedReader bufferedReader = null;
+        try {
+            String encoding = "UTF-8";
+            streamReader = new InputStreamReader(in, encoding);
+            bufferedReader = new BufferedReader(streamReader);
+            String line;
+            while ((line = bufferedReader.readLine()) != null) {
+                content.append(line);
+            }
+            return content.toString();
+        } catch (IOException e) {
+            throw new StatusException("出错", e);
+        } finally {
+            if (streamReader != null) {
+                try {
+                    streamReader.close();
+                } catch (IOException e) {
+                }
+            }
+            if (bufferedReader != null) {
+                try {
+                    bufferedReader.close();
+                } catch (IOException e) {
+                }
+            }
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
 
-	/**
-	 * 获得文件的byte数组
-	 * 
-	 * @param filePath
-	 * @return
-	 * @throws IOException
-	 */
-	public static byte[] getBytes(String filePath) throws IOException {
-		File file = new File(filePath);
-		if (!file.exists()) {
-			throw new FileNotFoundException(filePath);
-		}
+    /**
+     * 获得文件的byte数组
+     * 
+     * @param filePath
+     * @return
+     * @throws IOException
+     */
+    public static byte[] getBytes(String filePath) throws IOException {
+        File file = new File(filePath);
+        if (!file.exists()) {
+            throw new FileNotFoundException(filePath);
+        }
 
-		ByteArrayOutputStream bos = new ByteArrayOutputStream(((int) file.length()));
-		BufferedInputStream in = null;
-		try {
-			in = new BufferedInputStream(new FileInputStream(file));
-			int bufSize = 1024;
-			byte[] buffer = new byte[bufSize];
-			int len = 0;
-			while (-1 != (len = in.read(buffer, 0, bufSize))) {
-				bos.write(buffer, 0, len);
-			}
-			return bos.toByteArray();
-		} finally {
-			try {
-				if (in != null) {
-					in.close();
-				}
-			} catch (IOException e) {
-				e.printStackTrace();
-			}
-			bos.close();
-		}
-	}
+        ByteArrayOutputStream bos = new ByteArrayOutputStream(((int) file.length()));
+        BufferedInputStream in = null;
+        try {
+            in = new BufferedInputStream(new FileInputStream(file));
+            int bufSize = 1024;
+            byte[] buffer = new byte[bufSize];
+            int len = 0;
+            while (-1 != (len = in.read(buffer, 0, bufSize))) {
+                bos.write(buffer, 0, len);
+            }
+            return bos.toByteArray();
+        } finally {
+            try {
+                if (in != null) {
+                    in.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            bos.close();
+        }
+    }
 
 }

+ 378 - 372
src/main/java/cn/com/qmth/mps/util/HttpUtil.java

@@ -23,377 +23,383 @@ import net.sf.json.JSONObject;
 
 public class HttpUtil {
 
-	/** 默认的编码格式 */
-	private static final String DEFAULT_CHARSET = "UTF-8";
-
-	private static final String CONTENT_TYPE = "Content-Type";
-
-	private static final String APPLICATION_FORM= "application/x-www-form-urlencoded;charset=utf-8";
-	
-	private static final String APPLICATION_JSON = "application/json;charset=utf-8";
-	
-	public static String actionPostForm(String uri, Map<String, String> heads, Map<String, Object> params) {
-		if(uri.toLowerCase().startsWith("https")) {
-			return httpsActionPostForm(uri, heads, params);
-		}else {
-			return httpActionPostForm(uri, heads, params);
-		}
-	}
-	public static String httpActionPostForm(String uri, Map<String, String> heads, Map<String, Object> params) {
-		String result = null;
-		HttpURLConnection conn = null;
-		OutputStream os = null;
-		InputStream is = null;
-
-		try {
-			// 获取链接
-			URL url = new URL(uri);
-			conn = (HttpURLConnection) url.openConnection();
-
-			conn.setRequestMethod("POST");
-			conn.setRequestProperty(CONTENT_TYPE, APPLICATION_JSON);
-			// 初始化
-			// 获取SSLSocketFactory对象
-
-			conn.setUseCaches(false);
-			conn.setDoOutput(true);
-
-			// 设置额外的参数
-			if (heads != null && !heads.isEmpty()) {
-
-				for (Map.Entry<String, String> head : heads.entrySet()) {
-					conn.setRequestProperty(head.getKey(), head.getValue());
-				}
-			}
-			// 创建链接
-			conn.connect();
-			if (params != null) {
-				StringBuilder sb = new StringBuilder();
-				for (Map.Entry<String, Object> data : params.entrySet()) {
-					sb.append(data.getKey()).append("=").append(data.getValue()).append("&");
-				}
-				os = conn.getOutputStream();
-				os.write(sb.toString().getBytes());
-				os.flush();
-			}
-			result = getResult(conn);
-		} catch (Exception e) {
-			throw new StatusException("服务器访问失败", e);
-		} finally {
-			try {
-				if (os != null) {
-					os.close();
-					os = null;
-				}
-				if (is != null) {
-					is.close();
-					is = null;
-				}
-			} catch (IOException e) {
-			}
-
-			if (conn != null) {
-				conn.disconnect();
-				conn = null;
-			}
-		}
-
-		return result;
-	}
-	public static String httpsActionPostForm(String uri, Map<String, String> heads, Map<String, Object> params) {
-		String result = null;
-		HttpsURLConnection conn = null;
-		OutputStream os = null;
-		InputStream is = null;
-
-		try {
-			// 获取链接
-			URL url = new URL(uri);
-			conn = (HttpsURLConnection) url.openConnection();
-
-			conn.setRequestMethod("POST");
-			conn.setRequestProperty(CONTENT_TYPE, APPLICATION_JSON);
-			// ssl
-			SSLContext context = SSLContext.getInstance("SSL", "SunJSSE");
-			TrustManager[] tm = new TrustManager[] { new X509TrustManager() {
-
-				@Override
-				public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
-				}
-
-				@Override
-				public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
-				}
-
-				@Override
-				public X509Certificate[] getAcceptedIssuers() {
-					return null;
-				}
-			} };
-			// 初始化
-			context.init(null, tm, new java.security.SecureRandom());
-			// 获取SSLSocketFactory对象
-			SSLSocketFactory ssf = context.getSocketFactory();
-			conn.setSSLSocketFactory(ssf);
-			conn.setUseCaches(false);
-			conn.setDoOutput(true);
-
-			// 设置额外的参数
-			if (heads != null && !heads.isEmpty()) {
-
-				for (Map.Entry<String, String> head : heads.entrySet()) {
-					conn.setRequestProperty(head.getKey(), head.getValue());
-				}
-			}
-			// 创建链接
-			conn.connect();
-			if (params != null) {
-				StringBuilder sb = new StringBuilder();
-				for (Map.Entry<String, Object> data : params.entrySet()) {
-					sb.append(data.getKey()).append("=").append(data.getValue()).append("&");
-				}
-				os = conn.getOutputStream();
-				os.write(sb.toString().getBytes());
-				os.flush();
-			}
-			result = getResult(conn);
-		} catch (Exception e) {
-			throw new StatusException("服务器访问失败", e);
-		} finally {
-			try {
-				if (os != null) {
-					os.close();
-					os = null;
-				}
-				if (is != null) {
-					is.close();
-					is = null;
-				}
-			} catch (IOException e) {
-			}
-
-			if (conn != null) {
-				conn.disconnect();
-				conn = null;
-			}
-		}
-
-		return result;
-	}
-	public static String httpsActionPost(String uri, Map<String, String> heads, Map<String, String> params) {
-		String result = null;
-		HttpsURLConnection conn = null;
-		OutputStream os = null;
-		InputStream is = null;
-
-		try {
-			// 获取链接
-			URL url = new URL(uri);
-			conn = (HttpsURLConnection) url.openConnection();
-
-			conn.setRequestMethod("POST");
-			conn.setRequestProperty(CONTENT_TYPE, APPLICATION_JSON);
-			// ssl
-			SSLContext context = SSLContext.getInstance("SSL", "SunJSSE");
-			TrustManager[] tm = new TrustManager[] { new X509TrustManager() {
-
-				@Override
-				public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
-				}
-
-				@Override
-				public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
-				}
-
-				@Override
-				public X509Certificate[] getAcceptedIssuers() {
-					return null;
-				}
-			} };
-			// 初始化
-			context.init(null, tm, new java.security.SecureRandom());
-			// 获取SSLSocketFactory对象
-			SSLSocketFactory ssf = context.getSocketFactory();
-			conn.setSSLSocketFactory(ssf);
-
-			conn.setUseCaches(false);
-			conn.setDoOutput(true);
-
-			// 设置额外的参数
-			if (heads != null && !heads.isEmpty()) {
-
-				for (Map.Entry<String, String> head : heads.entrySet()) {
-					conn.setRequestProperty(head.getKey(), head.getValue());
-				}
-			}
-			// 创建链接
-			conn.connect();
-			if (params != null) {
-				String s=JSONObject.fromObject(params).toString();
-				os = conn.getOutputStream();
-				os.write(s.toString().getBytes());
-				os.flush();
-			}
-			result = getResult(conn);
-		} catch (Exception e) {
-			throw new StatusException("服务器访问失败", e);
-		} finally {
-			try {
-				if (os != null) {
-					os.close();
-					os = null;
-				}
-				if (is != null) {
-					is.close();
-					is = null;
-				}
-			} catch (IOException e) {
-			}
-
-			if (conn != null) {
-				conn.disconnect();
-				conn = null;
-			}
-		}
-
-		return result;
-	}
-	/**
-	 * 
-	 * @param params headers参数
-	 * @param datas  requestParams参数
-	 * @return
-	 * @throws Exception
-	 */
-	public static String httpsActionGet(String uri, Map<String, String> heads, Map<String, String> params) {
-		String result = null;
-		HttpsURLConnection conn = null;
-		OutputStream os = null;
-		InputStream is = null;
-
-		try {
-			// 设置请求参数
-			if (params != null) {
-				StringBuilder sb = new StringBuilder();
-				for (Map.Entry<String, String> data : params.entrySet()) {
-					sb.append(data.getKey()).append("=").append(data.getValue()).append("&");
-				}
-				uri = uri+"?" + sb.toString();
-			}
-			// 获取链接
-			URL url = new URL(uri);
-			conn = (HttpsURLConnection) url.openConnection();
-
-			conn.setRequestMethod("GET");
-			conn.setRequestProperty(CONTENT_TYPE, APPLICATION_FORM);
-			// ssl
-			SSLContext context = SSLContext.getInstance("SSL", "SunJSSE");
-			TrustManager[] tm = new TrustManager[] { new X509TrustManager() {
-
-				@Override
-				public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
-				}
-
-				@Override
-				public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
-				}
-
-				@Override
-				public X509Certificate[] getAcceptedIssuers() {
-					return null;
-				}
-			} };
-			// 初始化
-			context.init(null, tm, new java.security.SecureRandom());
-			// 获取SSLSocketFactory对象
-			SSLSocketFactory ssf = context.getSocketFactory();
-			conn.setSSLSocketFactory(ssf);
-
-			conn.setUseCaches(false);
-			conn.setDoOutput(true);
-
-			// 设置额外的参数
-			if (heads != null && !heads.isEmpty()) {
-
-				for (Map.Entry<String, String> head : heads.entrySet()) {
-					conn.setRequestProperty(head.getKey(), head.getValue());
-				}
-			}
-			// 创建链接
-			conn.connect();
-
-			result = getResult(conn);
-		} catch (Exception e) {
-			throw new StatusException("服务器访问失败", e);
-		} finally {
-			try {
-				if (os != null) {
-					os.close();
-					os = null;
-				}
-				if (is != null) {
-					is.close();
-					is = null;
-				}
-			} catch (IOException e) {
-			}
-
-			if (conn != null) {
-				conn.disconnect();
-				conn = null;
-			}
-		}
-
-		return result;
-	}
-
-	/**
-	 * 获得连接请求的返回数据
-	 * 
-	 * @param conn
-	 * 
-	 * @return 字符串
-	 */
-	private static String getResult(HttpURLConnection conn) throws IOException {
-
-		StringBuilder text = new StringBuilder();
-
-		InputStream is = null;
-		InputStreamReader sr = null;
-		BufferedReader br = null;
-
-		int code = conn.getResponseCode();
-
-		try {
-			is = code != 200 ? conn.getErrorStream() : conn.getInputStream();
-
-			sr = new InputStreamReader(is, DEFAULT_CHARSET);
-			br = new BufferedReader(sr);
-
-			char[] chars = new char[4096];
-			int length = 0;
-
-			while ((length = br.read(chars)) != -1) {
-				text.append(chars, 0, length);
-			}
-		} finally {
-			if (br != null) {
-				br.close();
-				br = null;
-			}
-			if (sr != null) {
-				sr.close();
-				sr = null;
-			}
-			if (is != null) {
-				is.close();
-				is = null;
-			}
-		}
-		if (code != 200) {
-			throw new IOException(text.toString());
-		}
-		return text.toString();
-	}
+    /** 默认的编码格式 */
+    private static final String DEFAULT_CHARSET = "UTF-8";
+
+    private static final String CONTENT_TYPE = "Content-Type";
+
+    private static final String APPLICATION_FORM = "application/x-www-form-urlencoded;charset=utf-8";
+
+    private static final String APPLICATION_JSON = "application/json;charset=utf-8";
+
+    public static String actionPostForm(String uri, Map<String, String> heads, Map<String, Object> params) {
+        if (uri.toLowerCase().startsWith("https")) {
+            return httpsActionPostForm(uri, heads, params);
+        } else {
+            return httpActionPostForm(uri, heads, params);
+        }
+    }
+
+    public static String httpActionPostForm(String uri, Map<String, String> heads, Map<String, Object> params) {
+        String result = null;
+        HttpURLConnection conn = null;
+        OutputStream os = null;
+        InputStream is = null;
+
+        try {
+            // 获取链接
+            URL url = new URL(uri);
+            conn = (HttpURLConnection) url.openConnection();
+
+            conn.setRequestMethod("POST");
+            conn.setRequestProperty(CONTENT_TYPE, APPLICATION_JSON);
+            // 初始化
+            // 获取SSLSocketFactory对象
+
+            conn.setUseCaches(false);
+            conn.setDoOutput(true);
+
+            // 设置额外的参数
+            if (heads != null && !heads.isEmpty()) {
+
+                for (Map.Entry<String, String> head : heads.entrySet()) {
+                    conn.setRequestProperty(head.getKey(), head.getValue());
+                }
+            }
+            // 创建链接
+            conn.connect();
+            if (params != null) {
+                StringBuilder sb = new StringBuilder();
+                for (Map.Entry<String, Object> data : params.entrySet()) {
+                    sb.append(data.getKey()).append("=").append(data.getValue()).append("&");
+                }
+                os = conn.getOutputStream();
+                os.write(sb.toString().getBytes());
+                os.flush();
+            }
+            result = getResult(conn);
+        } catch (Exception e) {
+            throw new StatusException("服务器访问失败", e);
+        } finally {
+            try {
+                if (os != null) {
+                    os.close();
+                    os = null;
+                }
+                if (is != null) {
+                    is.close();
+                    is = null;
+                }
+            } catch (IOException e) {
+            }
+
+            if (conn != null) {
+                conn.disconnect();
+                conn = null;
+            }
+        }
+
+        return result;
+    }
+
+    public static String httpsActionPostForm(String uri, Map<String, String> heads, Map<String, Object> params) {
+        String result = null;
+        HttpsURLConnection conn = null;
+        OutputStream os = null;
+        InputStream is = null;
+
+        try {
+            // 获取链接
+            URL url = new URL(uri);
+            conn = (HttpsURLConnection) url.openConnection();
+
+            conn.setRequestMethod("POST");
+            conn.setRequestProperty(CONTENT_TYPE, APPLICATION_JSON);
+            // ssl
+            SSLContext context = SSLContext.getInstance("SSL", "SunJSSE");
+            TrustManager[] tm = new TrustManager[] { new X509TrustManager() {
+
+                @Override
+                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                }
+
+                @Override
+                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                }
+
+                @Override
+                public X509Certificate[] getAcceptedIssuers() {
+                    return null;
+                }
+            } };
+            // 初始化
+            context.init(null, tm, new java.security.SecureRandom());
+            // 获取SSLSocketFactory对象
+            SSLSocketFactory ssf = context.getSocketFactory();
+            conn.setSSLSocketFactory(ssf);
+            conn.setUseCaches(false);
+            conn.setDoOutput(true);
+
+            // 设置额外的参数
+            if (heads != null && !heads.isEmpty()) {
+
+                for (Map.Entry<String, String> head : heads.entrySet()) {
+                    conn.setRequestProperty(head.getKey(), head.getValue());
+                }
+            }
+            // 创建链接
+            conn.connect();
+            if (params != null) {
+                StringBuilder sb = new StringBuilder();
+                for (Map.Entry<String, Object> data : params.entrySet()) {
+                    sb.append(data.getKey()).append("=").append(data.getValue()).append("&");
+                }
+                os = conn.getOutputStream();
+                os.write(sb.toString().getBytes());
+                os.flush();
+            }
+            result = getResult(conn);
+        } catch (Exception e) {
+            throw new StatusException("服务器访问失败", e);
+        } finally {
+            try {
+                if (os != null) {
+                    os.close();
+                    os = null;
+                }
+                if (is != null) {
+                    is.close();
+                    is = null;
+                }
+            } catch (IOException e) {
+            }
+
+            if (conn != null) {
+                conn.disconnect();
+                conn = null;
+            }
+        }
+
+        return result;
+    }
+
+    public static String httpsActionPost(String uri, Map<String, String> heads, Map<String, String> params) {
+        String result = null;
+        HttpsURLConnection conn = null;
+        OutputStream os = null;
+        InputStream is = null;
+
+        try {
+            // 获取链接
+            URL url = new URL(uri);
+            conn = (HttpsURLConnection) url.openConnection();
+
+            conn.setRequestMethod("POST");
+            conn.setRequestProperty(CONTENT_TYPE, APPLICATION_JSON);
+            // ssl
+            SSLContext context = SSLContext.getInstance("SSL", "SunJSSE");
+            TrustManager[] tm = new TrustManager[] { new X509TrustManager() {
+
+                @Override
+                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                }
+
+                @Override
+                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                }
+
+                @Override
+                public X509Certificate[] getAcceptedIssuers() {
+                    return null;
+                }
+            } };
+            // 初始化
+            context.init(null, tm, new java.security.SecureRandom());
+            // 获取SSLSocketFactory对象
+            SSLSocketFactory ssf = context.getSocketFactory();
+            conn.setSSLSocketFactory(ssf);
+
+            conn.setUseCaches(false);
+            conn.setDoOutput(true);
+
+            // 设置额外的参数
+            if (heads != null && !heads.isEmpty()) {
+
+                for (Map.Entry<String, String> head : heads.entrySet()) {
+                    conn.setRequestProperty(head.getKey(), head.getValue());
+                }
+            }
+            // 创建链接
+            conn.connect();
+            if (params != null) {
+                String s = JSONObject.fromObject(params).toString();
+                os = conn.getOutputStream();
+                os.write(s.toString().getBytes());
+                os.flush();
+            }
+            result = getResult(conn);
+        } catch (Exception e) {
+            throw new StatusException("服务器访问失败", e);
+        } finally {
+            try {
+                if (os != null) {
+                    os.close();
+                    os = null;
+                }
+                if (is != null) {
+                    is.close();
+                    is = null;
+                }
+            } catch (IOException e) {
+            }
+
+            if (conn != null) {
+                conn.disconnect();
+                conn = null;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 
+     * @param params
+     *            headers参数
+     * @param datas
+     *            requestParams参数
+     * @return
+     * @throws Exception
+     */
+    public static String httpsActionGet(String uri, Map<String, String> heads, Map<String, String> params) {
+        String result = null;
+        HttpsURLConnection conn = null;
+        OutputStream os = null;
+        InputStream is = null;
+
+        try {
+            // 设置请求参数
+            if (params != null) {
+                StringBuilder sb = new StringBuilder();
+                for (Map.Entry<String, String> data : params.entrySet()) {
+                    sb.append(data.getKey()).append("=").append(data.getValue()).append("&");
+                }
+                uri = uri + "?" + sb.toString();
+            }
+            // 获取链接
+            URL url = new URL(uri);
+            conn = (HttpsURLConnection) url.openConnection();
+
+            conn.setRequestMethod("GET");
+            conn.setRequestProperty(CONTENT_TYPE, APPLICATION_FORM);
+            // ssl
+            SSLContext context = SSLContext.getInstance("SSL", "SunJSSE");
+            TrustManager[] tm = new TrustManager[] { new X509TrustManager() {
+
+                @Override
+                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                }
+
+                @Override
+                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                }
+
+                @Override
+                public X509Certificate[] getAcceptedIssuers() {
+                    return null;
+                }
+            } };
+            // 初始化
+            context.init(null, tm, new java.security.SecureRandom());
+            // 获取SSLSocketFactory对象
+            SSLSocketFactory ssf = context.getSocketFactory();
+            conn.setSSLSocketFactory(ssf);
+
+            conn.setUseCaches(false);
+            conn.setDoOutput(true);
+
+            // 设置额外的参数
+            if (heads != null && !heads.isEmpty()) {
+
+                for (Map.Entry<String, String> head : heads.entrySet()) {
+                    conn.setRequestProperty(head.getKey(), head.getValue());
+                }
+            }
+            // 创建链接
+            conn.connect();
+
+            result = getResult(conn);
+        } catch (Exception e) {
+            throw new StatusException("服务器访问失败", e);
+        } finally {
+            try {
+                if (os != null) {
+                    os.close();
+                    os = null;
+                }
+                if (is != null) {
+                    is.close();
+                    is = null;
+                }
+            } catch (IOException e) {
+            }
+
+            if (conn != null) {
+                conn.disconnect();
+                conn = null;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 获得连接请求的返回数据
+     * 
+     * @param conn
+     * 
+     * @return 字符串
+     */
+    private static String getResult(HttpURLConnection conn) throws IOException {
+
+        StringBuilder text = new StringBuilder();
+
+        InputStream is = null;
+        InputStreamReader sr = null;
+        BufferedReader br = null;
+
+        int code = conn.getResponseCode();
+
+        try {
+            is = code != 200 ? conn.getErrorStream() : conn.getInputStream();
+
+            sr = new InputStreamReader(is, DEFAULT_CHARSET);
+            br = new BufferedReader(sr);
+
+            char[] chars = new char[4096];
+            int length = 0;
+
+            while ((length = br.read(chars)) != -1) {
+                text.append(chars, 0, length);
+            }
+        } finally {
+            if (br != null) {
+                br.close();
+                br = null;
+            }
+            if (sr != null) {
+                sr.close();
+                sr = null;
+            }
+            if (is != null) {
+                is.close();
+                is = null;
+            }
+        }
+        if (code != 200) {
+            throw new IOException(text.toString());
+        }
+        return text.toString();
+    }
 
 }

+ 7 - 5
src/main/java/cn/com/qmth/mps/util/IpUtil.java

@@ -23,7 +23,8 @@ public class IpUtil {
      * excludeProxyIp
      *
      * @param request
-     * @param excludeProxyIp 是否排除代理ip
+     * @param excludeProxyIp
+     *            是否排除代理ip
      * @return
      */
     public static String getRemoteIp(HttpServletRequest request, boolean excludeProxyIp) {
@@ -48,15 +49,16 @@ public class IpUtil {
         }
 
         if (excludeProxyIp) {
-            //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
-            if (ip != null && ip.length() > 15) { //"***.***.***.***".length() = 15
+            // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
+            if (ip != null && ip.length() > 15) { // "***.***.***.***".length()
+                                                  // = 15
                 if (ip.indexOf(",") > 0) {
                     ip = ip.substring(0, ip.indexOf(","));
                 }
             }
         }
-        if("0:0:0:0:0:0:0:1".equals(ip)) {
-        	ip="127.0.0.1";
+        if ("0:0:0:0:0:0:0:1".equals(ip)) {
+            ip = "127.0.0.1";
         }
         return ip;
     }

+ 17 - 20
src/main/java/cn/com/qmth/mps/util/JsonMapper.java

@@ -17,10 +17,9 @@ import java.util.List;
 import java.util.Map;
 
 /**
- * 简单封装Jackson,实现JSON 与 Java Object互相转换的Mapper
- * 封装不同的输出风格, 使用不同的builder函数创建实例
+ * 简单封装Jackson,实现JSON 与 Java Object互相转换的Mapper 封装不同的输出风格, 使用不同的builder函数创建实例
  */
-@SuppressWarnings({"rawtypes","unchecked"})
+@SuppressWarnings({ "rawtypes", "unchecked" })
 public class JsonMapper {
 
     private static Logger log = LoggerFactory.getLogger(JsonMapper.class);
@@ -61,24 +60,22 @@ public class JsonMapper {
     public JsonMapper(Include include) {
         mapper = new ObjectMapper();
 
-        //设置输出时包含属性的风格
+        // 设置输出时包含属性的风格
         if (include != null) {
             mapper.setSerializationInclusion(include);
         }
 
-        //设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
+        // 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
         mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
-        //忽略无法转换的对象
+        // 忽略无法转换的对象
         mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
 
-        //设置默认日期格式
+        // 设置默认日期格式
         mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
     }
 
     /**
-     * Object可以是POJO,也可以是Collection或数组
-     * 如果对象为Null, 返回"null"
-     * 如果集合为空集合, 返回"[]"
+     * Object可以是POJO,也可以是Collection或数组 如果对象为Null, 返回"null" 如果集合为空集合, 返回"[]"
      */
     public String toJson(Object object) {
         if (object == null) {
@@ -94,10 +91,9 @@ public class JsonMapper {
     }
 
     /**
-     * 反序列化POJO或简单Collection如List<String>
-     * 如果JSON字符串为Null或"null"字符串, 返回Null
-     * 如果JSON字符串为"[]", 返回空集合
-     * 如需反序列化复杂Collection如List<MyBean>, 请使用parseJson(String, JavaType)
+     * 反序列化POJO或简单Collection如List<String> 如果JSON字符串为Null或"null"字符串, 返回Null
+     * 如果JSON字符串为"[]", 返回空集合 如需反序列化复杂Collection如List<MyBean>,
+     * 请使用parseJson(String, JavaType)
      */
     public <T> T parseJson(String jsonStr, Class<T> clazz) {
         if (StringUtils.isEmpty(jsonStr)) {
@@ -113,9 +109,10 @@ public class JsonMapper {
     }
 
     /**
-     * 反序列化复杂Collection如List<Bean>, 先使用createCollectionType()或constructMapType()构造类型, 然后调用本函数
+     * 反序列化复杂Collection如List<Bean>,
+     * 先使用createCollectionType()或constructMapType()构造类型, 然后调用本函数
      */
-	public <T> T parseJson(String jsonStr, JavaType javaType) {
+    public <T> T parseJson(String jsonStr, JavaType javaType) {
         if (StringUtils.isEmpty(jsonStr)) {
             return null;
         }
@@ -131,7 +128,7 @@ public class JsonMapper {
     /**
      * 反序列化复杂的对象,如Page<Bean>
      */
-	public <T> T parseJson(String jsonStr, TypeReference javaType) {
+    public <T> T parseJson(String jsonStr, TypeReference javaType) {
         if (StringUtils.isEmpty(jsonStr)) {
             return null;
         }
@@ -219,8 +216,7 @@ public class JsonMapper {
     }
 
     /**
-     * 設定是否使用Enum的toString函数來读写Enum
-     * 为False時使用Enum的name()函数來读写Enum, 默认为False
+     * 設定是否使用Enum的toString函数來读写Enum 为False時使用Enum的name()函数來读写Enum, 默认为False
      * 注意本函数一定要在Mapper創建後, 所有的读写動作之前調用
      */
     public void enableEnumUseToString() {
@@ -244,7 +240,8 @@ public class JsonMapper {
         }
 
         try {
-            //mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
+            // mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS,
+            // true);
             return mapper.readTree(jsonStr);
         } catch (IOException e) {
             log.error(e.getMessage(), e);

Some files were not shown because too many files changed in this diff