Преглед на файлове

Merge branch 'dev' into release
1

wangliang преди 4 години
родител
ревизия
b85616e2d1
променени са 16 файла, в които са добавени 323 реда и са изтрити 280 реда
  1. 12 6
      pom.xml
  2. 31 32
      themis-backend/src/main/java/com/qmth/themis/backend/api/SysController.java
  3. 69 72
      themis-backend/src/main/java/com/qmth/themis/backend/api/TEOpenController.java
  4. 14 0
      themis-business/src/main/java/com/qmth/themis/business/entity/TBAttachment.java
  5. 8 6
      themis-business/src/main/java/com/qmth/themis/business/service/TEOpenService.java
  6. 6 16
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TBAttachmentServiceImpl.java
  7. 5 8
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java
  8. 14 8
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TEOpenServiceImpl.java
  9. 4 7
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TEStudentServiceImpl.java
  10. 1 3
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java
  11. 6 3
      themis-business/src/main/java/com/qmth/themis/business/templete/TaskExportCommon.java
  12. 1 5
      themis-business/src/main/java/com/qmth/themis/business/templete/TaskImportCommon.java
  13. 36 40
      themis-business/src/main/java/com/qmth/themis/business/templete/impl/TaskExamPaperImportTemplete.java
  14. 18 5
      themis-business/src/main/java/com/qmth/themis/business/util/OssUtil.java
  15. 73 69
      themis-common/pom.xml
  16. 25 0
      themis-common/src/main/java/com/qmth/themis/common/util/HexUtils.java

+ 12 - 6
pom.xml

@@ -42,8 +42,9 @@
         <spring-boot.version>2.3.0.RELEASE</spring-boot.version>
         <gson.version>2.8.6</gson.version>
         <commons.version>3.10</commons.version>
+        <commons.codec.version>1.15</commons.codec.version>
         <jackson.version>2.11.0</jackson.version>
-<!--        <ehcache.version>2.10.6</ehcache.version>-->
+        <!--        <ehcache.version>2.10.6</ehcache.version>-->
         <swagger2-bootstrap.version>1.9.6</swagger2-bootstrap.version>
         <jetbrains.version>13.0</jetbrains.version>
         <tencentyun.version>1.1</tencentyun.version>
@@ -113,6 +114,11 @@
                 <artifactId>commons-lang3</artifactId>
                 <version>${commons.version}</version>
             </dependency>
+            <dependency>
+                <groupId>commons-codec</groupId>
+                <artifactId>commons-codec</artifactId>
+                <version>${commons.codec.version}</version>
+            </dependency>
             <dependency>
                 <groupId>com.google.code.gson</groupId>
                 <artifactId>gson</artifactId>
@@ -191,11 +197,11 @@
                 <version>${redis.version}</version>
             </dependency>
             <!-- ehcache 缓存 -->
-<!--            <dependency>-->
-<!--                <groupId>net.sf.ehcache</groupId>-->
-<!--                <artifactId>ehcache</artifactId>-->
-<!--                <version>${ehcache.version}</version>-->
-<!--            </dependency>-->
+            <!--            <dependency>-->
+            <!--                <groupId>net.sf.ehcache</groupId>-->
+            <!--                <artifactId>ehcache</artifactId>-->
+            <!--                <version>${ehcache.version}</version>-->
+            <!--            </dependency>-->
             <!-- rocketmq -->
             <dependency>
                 <groupId>org.apache.rocketmq</groupId>

+ 31 - 32
themis-backend/src/main/java/com/qmth/themis/backend/api/SysController.java

@@ -87,7 +87,7 @@ public class SysController {
 
     @ApiOperation(value = "菜单查询接口")
     @RequestMapping(value = "/getMenu", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "菜单信息", response = TBPrivilege.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "菜单信息", response = TBPrivilege.class)})
     public Result getMenu() {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         if (Objects.isNull(tbUser)) {
@@ -98,7 +98,7 @@ public class SysController {
 
     @ApiOperation(value = "获取环境接口")
     @RequestMapping(value = "/env", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "环境信息", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "环境信息", response = Result.class)})
     public Result env(@ApiParam(value = "机构id", required = true) @RequestParam Long orgId) {
         if (Objects.isNull(orgId) || Objects.equals(orgId, "")) {
             throw new BusinessException(ExceptionResultEnum.ORG_ID_IS_NULL);
@@ -113,9 +113,9 @@ public class SysController {
     @ApiOperation(value = "上传文件接口")
     @RequestMapping(value = "/file/upload", method = RequestMethod.POST)
     @Transactional
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"id\":0}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"id\":0}", response = Result.class)})
     public Result fileUpload(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
-            @ApiParam(value = "上传文件类型", required = true) @RequestParam UploadFileEnum type) throws IOException {
+                             @ApiParam(value = "上传文件类型", required = true) @RequestParam UploadFileEnum type) throws IOException {
         if (Objects.isNull(file) || Objects.equals(file, "")) {
             throw new BusinessException(ExceptionResultEnum.ATTACHMENT_IS_NULL);
         }
@@ -124,11 +124,10 @@ public class SysController {
         }
         Map<String, Object> mapParameter = null;
         if (type.getId() == UploadFileEnum.file.getId()) {
-            mapParameter = ossUtil.getAliYunOssPrivateDomain().getMap();
-        } else {
-            mapParameter = ossUtil.getAliYunOssPublicDomain().getMap();
+            throw new BusinessException("只能上传upload附件");
         }
-        mapParameter.put(SystemConstant.UPLOAD_TYPE, type.name());
+        mapParameter = ossUtil.getAliYunOssPublicDomain().getMap();
+        mapParameter.put(SystemConstant.UPLOAD_TYPE, UploadFileEnum.upload.name());
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         TBAttachment tbAttachment = tbAttachmentService
                 .saveAttachment(file, ServletUtil.getRequestMd5(), ServletUtil.getRequestPath(), mapParameter, type,
@@ -162,9 +161,9 @@ public class SysController {
 
     @ApiOperation(value = "文件下载接口")
     @RequestMapping(value = "/file/download", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"url\":string}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"url\":string}", response = Result.class)})
     public Result fileDownload(@ApiParam(value = "任务id", required = true) @RequestParam Long id,
-            @ApiParam(value = "下载文件类型", required = true) @RequestParam DownloadFileEnum type) {
+                               @ApiParam(value = "下载文件类型", required = true) @RequestParam DownloadFileEnum type) {
         if (Objects.isNull(id) || Objects.equals(id, "")) {
             throw new BusinessException(ExceptionResultEnum.TASK_ID_IS_NULL);
         }
@@ -181,15 +180,15 @@ public class SysController {
         boolean oss = dictionaryConfig.sysDomain().isOss();
         JSONObject jsonObject = null;
         switch (type.getId()) {
-        case 0:
-            jsonObject = JSONObject.parseObject(tbTaskHistory.getImportFilePath());
-            break;
-        case 1:
-            jsonObject = JSONObject.parseObject(tbTaskHistory.getReportFilePath());
-            break;
-        default:
-            jsonObject = JSONObject.parseObject(tbTaskHistory.getResultFilePath());
-            break;
+            case 0:
+                jsonObject = JSONObject.parseObject(tbTaskHistory.getImportFilePath());
+                break;
+            case 1:
+                jsonObject = JSONObject.parseObject(tbTaskHistory.getReportFilePath());
+                break;
+            default:
+                jsonObject = JSONObject.parseObject(tbTaskHistory.getResultFilePath());
+                break;
         }
         if (Objects.isNull(jsonObject) || Objects.isNull(jsonObject.get("path"))) {
             throw new BusinessException("下载文件地址不存在");
@@ -214,7 +213,7 @@ public class SysController {
 
     @ApiOperation(value = "根据机构代码查询机构信息接口")
     @RequestMapping(value = "/org/queryByOrgCode", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "机构信息", response = TBOrg.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "机构信息", response = TBOrg.class)})
     public Result queryByOrgCode(@ApiParam(value = "机构code", required = true) @RequestParam String code) {
         if (Objects.isNull(code) || Objects.equals(code, "")) {
             throw new BusinessException(ExceptionResultEnum.ORG_CODE_IS_NULL);
@@ -240,11 +239,11 @@ public class SysController {
 
     @ApiOperation(value = "机构查询接口")
     @RequestMapping(value = "/org/query", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "机构信息", response = TBOrg.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "机构信息", response = TBOrg.class)})
     public Result query(@ApiParam(value = "机构id", required = false) @RequestParam(required = false) Long id,
-            @ApiParam(value = "机构代码", required = false) @RequestParam(required = false) String code,
-            @ApiParam(value = "机构名称", required = false) @RequestParam(required = false) String name,
-            @ApiParam(value = "是否启用", required = false) @RequestParam(required = false) Integer enable) {
+                        @ApiParam(value = "机构代码", required = false) @RequestParam(required = false) String code,
+                        @ApiParam(value = "机构名称", required = false) @RequestParam(required = false) String name,
+                        @ApiParam(value = "是否启用", required = false) @RequestParam(required = false) Integer enable) {
         QueryWrapper<TBOrg> tbOrgQueryWrapper = new QueryWrapper<>();
         if (Objects.nonNull(id)) {
             tbOrgQueryWrapper.lambda().eq(TBOrg::getId, id);
@@ -263,7 +262,7 @@ public class SysController {
 
     @ApiOperation(value = "角色查询接口")
     @RequestMapping(value = "/role/query", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "角色信息", response = TBRole.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "角色信息", response = TBRole.class)})
     public Result roleList() {
         List<TBRole> tbRoleList = (List<TBRole>) redisUtil.getRole();
         if (Objects.nonNull(tbRoleList) && tbRoleList.size() > 0) {
@@ -282,17 +281,17 @@ public class SysController {
 
     @ApiOperation(value = "考试场次查询接口")
     @RequestMapping(value = "/examActivity/query", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "角色信息", response = TEExamActivity.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "角色信息", response = TEExamActivity.class)})
     public Result examActivityQuery() {
         return ResultUtil.ok(teExamActivityService.list());
     }
 
     @ApiOperation(value = "考试批次查询接口")
     @RequestMapping(value = "/exam/query", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "角色信息", response = TEExamQueryDto.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "角色信息", response = TEExamQueryDto.class)})
     public Result examQuery(@ApiParam(value = "用户id", required = false) @RequestParam(required = false) Long userId,
-            @ApiParam(value = "批次名称", required = false) @RequestParam(required = false) String name,
-            @ApiParam(value = "类型(区分实时监考台和考务)", required = false) @RequestParam(required = false) String type) {
+                            @ApiParam(value = "批次名称", required = false) @RequestParam(required = false) String name,
+                            @ApiParam(value = "类型(区分实时监考台和考务)", required = false) @RequestParam(required = false) String type) {
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
         List<TEExam> teExamList = null;
@@ -334,7 +333,7 @@ public class SysController {
 
     @ApiOperation(value = "考场查询接口")
     @RequestMapping(value = "/examRoom/query", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "角色信息", response = RoomCodeQueryDto.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "角色信息", response = RoomCodeQueryDto.class)})
     public Result examRoomQuery(
             @ApiParam(value = "考场名称", required = false) @RequestParam(required = false) String roomName) {
         return ResultUtil.ok(teExamStudentService.examRoomQuery(roomName));
@@ -342,7 +341,7 @@ public class SysController {
 
     @ApiOperation(value = "根据权限获取场次和考场接口")
     @RequestMapping(value = "/exam/privilegeQuery", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "场次和考场信息", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "场次和考场信息", response = Result.class)})
     public Result examPrivilegeQuery(@ApiParam(value = "考试id", required = true) @RequestParam Long examId) {
         if (Objects.isNull(examId) || Objects.equals(examId, "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
@@ -410,7 +409,7 @@ public class SysController {
 
     @ApiOperation(value = "获取播放域接口")
     @RequestMapping(value = "/getPlayUrls", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "播放域接口", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "播放域接口", response = Result.class)})
     public Result getPlayUrls() {
         return ResultUtil.ok(dictionaryConfig.tencentYunDomain().getUrls());
     }

+ 69 - 72
themis-backend/src/main/java/com/qmth/themis/backend/api/TEOpenController.java

@@ -1,26 +1,23 @@
 package com.qmth.themis.backend.api;
 
-import javax.annotation.Resource;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
 import com.qmth.themis.business.service.TEOpenService;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
+import io.swagger.annotations.*;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
+import javax.annotation.Resource;
+import java.io.IOException;
 
-/**开放接口
- * @Description: 
+/**
+ * 开放接口
+ *
+ * @Description:
  * @Author: xiatian
  * @Date: 2020-10-19
  */
@@ -35,81 +32,81 @@ public class TEOpenController {
     @Resource
     RedisUtil redisUtil;
 
-
     @ApiOperation(value = "获取考试详情")
     @RequestMapping(value = "/exam/query", method = RequestMethod.POST)
-    @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
+    @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
     public Result examQueryPage(@ApiParam(value = "考试id", required = false) @RequestParam(required = false) Long examId,
-                                     @ApiParam(value = "考试code", required = false) @RequestParam(required = false) String code,
-                                     @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
-                                     @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
-    	
-    	if(pageSize!=null&&pageSize>20) {
-    		throw new BusinessException("每页最大条数为20");
-    	}
-    	if(pageNumber==null) {
-    		pageNumber=1;
-    	}
-    	if(pageSize==null) {
-    		pageSize=20;
-    	}
+            @ApiParam(value = "考试code", required = false) @RequestParam(required = false) String code,
+            @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
+            @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
+
+        if (pageSize != null && pageSize > 20) {
+            throw new BusinessException("每页最大条数为20");
+        }
+        if (pageNumber == null) {
+            pageNumber = 1;
+        }
+        if (pageSize == null) {
+            pageSize = 20;
+        }
         return ResultUtil.ok(openService.examQueryPage(examId, code, pageNumber, pageSize));
     }
-    
+
     @ApiOperation(value = "获取考试课程详情")
     @RequestMapping(value = "/exam/course/query", method = RequestMethod.POST)
-    @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
+    @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
     public Result examCourseQueryPage(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
-                                     @ApiParam(value = "课程code", required = false) @RequestParam(required = false) String courseCode,
-                                     @ApiParam(value = "是否有试卷", required = false) @RequestParam(required = false) Boolean hasPaper,
-                                     @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
-                                     @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
-    	if(pageSize!=null&&pageSize>100) {
-    		throw new BusinessException("每页最大条数为100");
-    	}
-    	if(pageNumber==null) {
-    		pageNumber=1;
-    	}
-    	if(pageSize==null) {
-    		pageSize=100;
-    	}
-    	if(examId==null) {
-    		throw new BusinessException("考试id不能为空");
-    	}
-        return ResultUtil.ok(openService.examCourseQueryPage(examId, courseCode,hasPaper, pageNumber, pageSize));
+            @ApiParam(value = "课程code", required = false) @RequestParam(required = false) String courseCode,
+            @ApiParam(value = "是否有试卷", required = false) @RequestParam(required = false) Boolean hasPaper,
+            @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
+            @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
+        if (pageSize != null && pageSize > 100) {
+            throw new BusinessException("每页最大条数为100");
+        }
+        if (pageNumber == null) {
+            pageNumber = 1;
+        }
+        if (pageSize == null) {
+            pageSize = 100;
+        }
+        if (examId == null) {
+            throw new BusinessException("考试id不能为空");
+        }
+        return ResultUtil.ok(openService.examCourseQueryPage(examId, courseCode, hasPaper, pageNumber, pageSize));
     }
-    
+
     @ApiOperation(value = "获取考试试卷详情")
     @RequestMapping(value = "/exam/paper/detail", method = RequestMethod.POST)
-    @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
+    @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
     public Result examPaperDetail(@ApiParam(value = "试卷id", required = true) @RequestParam Long paperId,
-                                     @ApiParam(value = "内容过滤卷", required = false) @RequestParam(required = false) String filter) {
-    	if(paperId==null) {
-    		throw new BusinessException("试卷id不能为空");
-    	}
+            @ApiParam(value = "内容过滤卷", required = false) @RequestParam(required = false) String filter)
+            throws IOException {
+        if (paperId == null) {
+            throw new BusinessException("试卷id不能为空");
+        }
         return ResultUtil.ok(openService.examPaperDetail(paperId, filter));
     }
-    
+
     @ApiOperation(value = "待评卷考试记录查询")
     @RequestMapping(value = "/exam/record/need_mark", method = RequestMethod.POST)
-    @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
+    @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
     public Result examRecordNeedMark(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
-                                     @ApiParam(value = "内容过滤卷", required = false) @RequestParam(required = false) String courseCode,
-                                     @ApiParam(value = "考生ID大于此参数", required = false) @RequestParam(required = false) Long examStudentIdGt,
-                                     @ApiParam(value = "数量(最大20)", required = false) @RequestParam(required = false) Integer count) {
-    	if(examId==null) {
-    		throw new BusinessException("考试id不能为空");
-    	}
-    	if(examStudentIdGt==null) {
-    		examStudentIdGt=0L;
-    	}
-    	if(count!=null&&count>20) {
-    		throw new BusinessException("count最大为20");
-    	}
-    	if(count==null) {
-    		count=20;
-    	}
-        return ResultUtil.ok(openService.examRecordNeedMark(examId, courseCode,examStudentIdGt,count));
+            @ApiParam(value = "内容过滤卷", required = false) @RequestParam(required = false) String courseCode,
+            @ApiParam(value = "考生ID大于此参数", required = false) @RequestParam(required = false) Long examStudentIdGt,
+            @ApiParam(value = "数量(最大20)", required = false) @RequestParam(required = false) Integer count) {
+        if (examId == null) {
+            throw new BusinessException("考试id不能为空");
+        }
+        if (examStudentIdGt == null) {
+            examStudentIdGt = 0L;
+        }
+        if (count != null && count > 20) {
+            throw new BusinessException("count最大为20");
+        }
+        if (count == null) {
+            count = 20;
+        }
+        return ResultUtil.ok(openService.examRecordNeedMark(examId, courseCode, examStudentIdGt, count));
     }
 
 }

+ 14 - 0
themis-business/src/main/java/com/qmth/themis/business/entity/TBAttachment.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.themis.common.contanst.Constants;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -61,6 +62,19 @@ public class TBAttachment implements Serializable {
     @ApiModelProperty(value = "创建时间")
     private Long createTime; //创建时间
 
+    public TBAttachment(){
+
+    }
+
+    public TBAttachment(String path,String name,String type,BigDecimal size,String md5){
+        this.id = Constants.idGen.next();
+        this.path = path;
+        this.name = name;
+        this.type = type;
+        this.size = size;
+        this.md5 = md5;
+    }
+
     public static long getSerialVersionUID() {
         return serialVersionUID;
     }

+ 8 - 6
themis-business/src/main/java/com/qmth/themis/business/service/TEOpenService.java

@@ -1,20 +1,22 @@
 package com.qmth.themis.business.service;
 
-import java.util.List;
-
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.qmth.themis.business.bean.backend.OpenExamBean;
 import com.qmth.themis.business.bean.backend.OpenExamCourseBean;
 
+import java.io.IOException;
+import java.util.List;
+
 public interface TEOpenService {
 
-	public List<OpenExamBean> examQueryPage(Long examId, String examCode, int pageNumber, int pageSize);
+    public List<OpenExamBean> examQueryPage(Long examId, String examCode, int pageNumber, int pageSize);
 
-	public List<OpenExamCourseBean> examCourseQueryPage(Long examId, String courseCode, Boolean hasPaper, int pageNumber, int pageSize);
+    public List<OpenExamCourseBean> examCourseQueryPage(Long examId, String courseCode, Boolean hasPaper,
+            int pageNumber, int pageSize);
 
-	public JSONObject examPaperDetail(Long paperId, String filter);
+    public JSONObject examPaperDetail(Long paperId, String filter) throws IOException;
 
-	public JSONArray examRecordNeedMark(Long examId, String courseCode, Long idGt, Integer count);
+    public JSONArray examRecordNeedMark(Long examId, String courseCode, Long idGt, Integer count);
 
 }

+ 6 - 16
themis-business/src/main/java/com/qmth/themis/business/service/impl/TBAttachmentServiceImpl.java

@@ -1,6 +1,7 @@
 package com.qmth.themis.business.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
+import com.aliyun.oss.common.utils.BinaryUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dao.TBAttachmentMapper;
@@ -9,9 +10,9 @@ import com.qmth.themis.business.enums.UploadFileEnum;
 import com.qmth.themis.business.service.TBAttachmentService;
 import com.qmth.themis.business.util.JacksonUtil;
 import com.qmth.themis.business.util.OssUtil;
-import com.qmth.themis.common.contanst.Constants;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
+import com.qmth.themis.common.util.HexUtils;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
@@ -96,13 +97,7 @@ public class TBAttachmentServiceImpl extends ServiceImpl<TBAttachmentMapper, TBA
             if (!Objects.equals(fileMd5, md5)) {
                 throw new BusinessException("md5不一致");
             }
-            tbAttachment = new TBAttachment();
-            tbAttachment.setId(Constants.idGen.next());
-            tbAttachment.setPath(path);
-            tbAttachment.setName(fileName);
-            tbAttachment.setType(format);
-            tbAttachment.setSize(b);
-            tbAttachment.setMd5(fileMd5);
+            tbAttachment = new TBAttachment(path, fileName, format, b, fileMd5);
 
             boolean oss = (boolean) map.get(SystemConstant.OSS);
             LocalDateTime nowTime = LocalDateTime.now();
@@ -125,7 +120,8 @@ public class TBAttachmentServiceImpl extends ServiceImpl<TBAttachmentMapper, TBA
             if (oss) {//上传至oss
                 stringJoiner.add(File.separator).add(String.valueOf(UUID.randomUUID()).replaceAll("-", ""))
                         .add(tbAttachment.getType());
-                ossUtil.upload(ossUtil.isPublic(type), stringJoiner.toString(), file.getInputStream());
+                ossUtil.upload(ossUtil.isPublic(type), stringJoiner.toString(), file.getInputStream(),
+                        BinaryUtil.toBase64String(HexUtils.decodeHex(md5)));
             } else {//上传至服务器
                 File finalFile = new File(
                         stringJoiner.add(File.separator).add(String.valueOf(UUID.randomUUID()).replaceAll("-", ""))
@@ -187,13 +183,7 @@ public class TBAttachmentServiceImpl extends ServiceImpl<TBAttachmentMapper, TBA
             log.info("format:{}", format);
             log.info("size:{}", b);
             log.info("md5:{}", md5);
-            tbAttachment = new TBAttachment();
-            tbAttachment.setId(Constants.idGen.next());
-            tbAttachment.setPath(path);
-            tbAttachment.setName(fileName);
-            tbAttachment.setType(format);
-            tbAttachment.setSize(b);
-            tbAttachment.setMd5(md5);
+            tbAttachment = new TBAttachment(path, fileName, format, b, md5);
 
             boolean oss = (boolean) map.get(SystemConstant.OSS);
             LocalDateTime nowTime = LocalDateTime.now();

+ 5 - 8
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -1,6 +1,7 @@
 package com.qmth.themis.business.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
+import com.aliyun.oss.common.utils.BinaryUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -28,8 +29,8 @@ import com.qmth.themis.business.service.*;
 import com.qmth.themis.business.util.*;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
+import com.qmth.themis.common.util.HexUtils;
 import com.qmth.themis.common.util.IpUtil;
-import org.apache.commons.codec.digest.DigestUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.CachePut;
@@ -756,13 +757,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         String filePath = "upload" + File.separator + sdf.format(new Date()) + File.separator + uuid() + "." + suffix;
         InputStream in = null;
         try {
-            String fileMd5 = DigestUtils.md5Hex(file.getBytes());
-            if (!md5.equals(fileMd5)) {
-                throw new BusinessException("文件md5不一致");
-            }
             in = file.getInputStream();
-            ossUtil.upload(false, filePath, in);
-            String url = ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + File.separator + filePath;
+            ossUtil.upload(true, filePath, in, BinaryUtil.toBase64String(HexUtils.decodeHex(md5)));
+            String url = ossUtil.getAliYunOssPublicDomain().getPublicUrl() + File.separator + filePath;
             ExamFileUploadBean ret = new ExamFileUploadBean();
             ret.setUrl(url);
             ret.setUploadTime(System.currentTimeMillis());
@@ -1306,7 +1303,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
             task.setStatus(TaskStatusEnum.FINISH);
             task.setFinishTime(System.currentTimeMillis());
             JSONObject json = new JSONObject();
-            String reportFilePath = "file/" + sdf.format(new Date()) + "/" + uuid() + SystemConstant.TXT_PREFIX;
+            String reportFilePath = "/" + sdf.format(new Date()) + "/" + uuid() + SystemConstant.TXT_PREFIX;
             json.put("path", reportFilePath);
             json.put("type", SystemConstant.OSS);
             ossUtil.upload(false, reportFilePath, e.getMessage());

+ 14 - 8
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEOpenServiceImpl.java

@@ -21,16 +21,22 @@ import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.FileUtil;
 import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.stream.Collectors;
 
 @Service
 public class TEOpenServiceImpl implements TEOpenService {
 
+    private final static Logger log = LoggerFactory.getLogger(TEOpenServiceImpl.class);
+
     @Resource
     TEExamService examService;
 
@@ -60,17 +66,15 @@ public class TEOpenServiceImpl implements TEOpenService {
         return ret.getRecords();
     }
 
-
     @Override
     public List<OpenExamCourseBean> examCourseQueryPage(Long examId, String courseCode, Boolean hasPaper,
-                                                        int pageNumber, int pageSize) {
+            int pageNumber, int pageSize) {
         Page<OpenExamCourseBean> ipage = new Page<>(pageNumber, pageSize);
         ipage.addOrder(OrderItem.desc("t.id"));
         IPage<OpenExamCourseBean> ret = examCourseService.examCourseQueryForOpen(ipage, examId, courseCode, hasPaper);
         return ret.getRecords();
     }
 
-
     @Override
     public JSONObject examPaperDetail(Long paperId, String filter) {
         String tempDir = SystemConstant.TEMP_FILES_DIR;
@@ -219,10 +223,8 @@ public class TEOpenServiceImpl implements TEOpenService {
         }
     }
 
-
     @Override
-    public JSONArray examRecordNeedMark(Long examId, String courseCode, Long idGt,
-                                        Integer count) {
+    public JSONArray examRecordNeedMark(Long examId, String courseCode, Long idGt, Integer count) {
         checkExam(examId);
         List<OpenRecordNeedMarkBean> list;
         for (; ; ) {
@@ -243,7 +245,8 @@ public class TEOpenServiceImpl implements TEOpenService {
             for (int i = 0; i < answers.size(); i++) {//剔除客观题答案
                 OpenRecordAnswerBean answer = answers.get(i);
                 Map<String, Integer> struct = examPaperService.getPaperStructCacheBean(answer.getPaperId());
-                Integer type = struct.get(RedisKeyHelper.examAnswerHashKey(answer.getMainNumber(), answer.getSubNumber(), answer.getSubIndex()));
+                Integer type = struct.get(RedisKeyHelper
+                        .examAnswerHashKey(answer.getMainNumber(), answer.getSubNumber(), answer.getSubIndex()));
                 if (type == 1 || type == 2 || type == 3) {
                     answers.remove(i);
                     i--;
@@ -306,7 +309,8 @@ public class TEOpenServiceImpl implements TEOpenService {
         TEExam exam = examService.getById(examId);
         if (RecordSelectStrategyEnum.HIGHEST_TOTAL_SCORE.equals(exam.getRecordSelectStrategy())) {//全阅
             return list;
-        } else if (RecordSelectStrategyEnum.HIGHEST_OBJECTIVE_SCORE.equals(exam.getRecordSelectStrategy())) {//客观分最高,相同则都阅
+        } else if (RecordSelectStrategyEnum.HIGHEST_OBJECTIVE_SCORE
+                .equals(exam.getRecordSelectStrategy())) {//客观分最高,相同则都阅
             Map<Long, List<OpenRecordNeedMarkBean>> map = new HashMap<>();
             for (OpenRecordNeedMarkBean bean : list) {
                 List<OpenRecordNeedMarkBean> temList = map.get(bean.getExamStudentId());
@@ -331,6 +335,7 @@ public class TEOpenServiceImpl implements TEOpenService {
                 }
             }
             Collections.sort(ret, new Comparator<OpenRecordNeedMarkBean>() {
+
                 @Override
                 public int compare(OpenRecordNeedMarkBean o1, OpenRecordNeedMarkBean o2) {
                     Long c1 = o1.getExamStudentId();
@@ -356,6 +361,7 @@ public class TEOpenServiceImpl implements TEOpenService {
             }
             List<OpenRecordNeedMarkBean> ret = map.values().stream().collect(Collectors.toList());
             Collections.sort(ret, new Comparator<OpenRecordNeedMarkBean>() {
+
                 @Override
                 public int compare(OpenRecordNeedMarkBean o1, OpenRecordNeedMarkBean o2) {
                     Long c1 = o1.getExamStudentId();

+ 4 - 7
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEStudentServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qmth.themis.business.service.impl;
 
+import com.aliyun.oss.common.utils.BinaryUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -14,7 +15,7 @@ import com.qmth.themis.business.service.TEStudentService;
 import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.exception.BusinessException;
-import org.apache.commons.codec.digest.DigestUtils;
+import com.qmth.themis.common.util.HexUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
@@ -88,18 +89,14 @@ public class TEStudentServiceImpl extends ServiceImpl<TEStudentMapper, TEStudent
         String filePath = "base_photo/" + orgId + "/" + student.getId() + "." + suffix;
         InputStream in = null;
         try {
-            String fileMd5 = DigestUtils.md5Hex(file.getBytes());
-            if (!md5.equals(fileMd5)) {
-                throw new BusinessException("文件md5不一致");
-            }
             student.setBasePhotoPath(filePath);
             this.saveOrUpdate(student);
             Gson gson = new Gson();
             TEStudentCacheDto teStudentCacheDto = gson.fromJson(gson.toJson(student), TEStudentCacheDto.class);
             redisUtil.setStudent(student.getId(), teStudentCacheDto);
             in = file.getInputStream();
-            ossUtil.upload(false, filePath, in);
-            String url = ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + File.separator + filePath;
+            ossUtil.upload(true, filePath, in, BinaryUtil.toBase64String(HexUtils.decodeHex(md5)));
+            String url = ossUtil.getAliYunOssPublicDomain().getPublicUrl() + File.separator + filePath;
             StudentPhotoUploadResponseBean ret = new StudentPhotoUploadResponseBean();
             ret.setPhotoUrl(url);
             return ret;

+ 1 - 3
themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java

@@ -416,9 +416,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
             //            examStudentService.saveOrUpdate(examStudent);
             //上传个人试卷结构
             if (struct != null) {
-                File structFile = new File(dir + "struct.json");
-                FileUtil.saveAsFile(structFile.getAbsolutePath(), struct.getContent());
-                ossUtil.upload(false, structFilePath, structFile);
+                ossUtil.upload(false, structFilePath, struct.getContent());
             }
         } finally {
             FileUtil.deleteFolder(dir);

+ 6 - 3
themis-business/src/main/java/com/qmth/themis/business/templete/TaskExportCommon.java

@@ -16,7 +16,10 @@ import org.apache.poi.ss.usermodel.Row;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.*;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
 import java.util.*;
 
 /**
@@ -109,10 +112,10 @@ public class TaskExportCommon {
      * @param file
      * @throws FileNotFoundException
      */
-    public void ossUpload(File file) throws FileNotFoundException {
+    public void ossUpload(File file) throws IOException {
         boolean oss = (boolean) this.getOssEnv().get(SystemConstant.OSS);
         if (oss) {//上传至oss
-            this.ossUtil.upload(false, file.getPath().replaceAll("\\\\", "/"), new FileInputStream(file));
+            this.ossUtil.upload(false, file.getPath().replaceAll("\\\\", "/"), file);
             file.delete();
         }
     }

+ 1 - 5
themis-business/src/main/java/com/qmth/themis/business/templete/TaskImportCommon.java

@@ -108,11 +108,7 @@ public class TaskImportCommon {
                     .add(this.path);
             file = new File(localPath.toString());
         } else {
-            try {
-                file = this.ossUtil.download(false, this.path, this.path);
-            } catch (IOException e) {
-                log.error("请求出错", e);
-            }
+            file = this.ossUtil.download(false, this.path, this.path);
         }
         return file;
     }

+ 36 - 40
themis-business/src/main/java/com/qmth/themis/business/templete/impl/TaskExamPaperImportTemplete.java

@@ -3,6 +3,7 @@ package com.qmth.themis.business.templete.impl;
 import cn.hutool.core.date.DateUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.aliyun.oss.common.utils.BinaryUtil;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.entity.TEExam;
 import com.qmth.themis.business.entity.TEExamCourse;
@@ -25,16 +26,16 @@ import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.FileUtil;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
-import org.apache.commons.io.FileUtils;
+import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import sun.misc.BASE64Decoder;
 
 import javax.annotation.Resource;
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FilenameFilter;
 import java.io.IOException;
@@ -159,7 +160,8 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         }
     }
 
-    private void disposeCourseDir(String rootDir, TEExam teExam, File courseDir, Map<String, Object> map) {
+    private void disposeCourseDir(String rootDir, TEExam teExam, File courseDir, Map<String, Object> map)
+            throws IOException {
         String courseCode = courseDir.getName();
         TEExamCourse course = teExamCourseService.findByExamIdAndCourseCode(teExam.getId(), courseCode);
         if (course == null) {
@@ -227,7 +229,7 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
     }
 
     private void disposePaperDir(String rootDir, TEExam teExam, TEExamCourse course, File paperDir,
-            Map<String, Object> map) {
+                                 Map<String, Object> map) throws IOException {
         String paperCode = paperDir.getName();
         File[] childs = paperDir.listFiles();
 
@@ -278,9 +280,8 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
                 structFile = paperFile;
             } else {
                 String structPath = paper.getStructPath();
-                String url = ossUtil.getPrivateUrl(structPath);
                 structFile = new File(rootDir + uuid() + ".json");
-                FileUtil.saveUrlAsFile(url, structFile);
+                ossUtil.download(false, structPath, structFile.getAbsolutePath());
             }
             disposeAnswer(rootDir, paper, answerFile, structFile, attachmentDir);
         }
@@ -289,8 +290,8 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         teExamPaperService.saveOrUpdate(paper);
     }
 
-    private void disposeViewPaper(String rootDir, TEExamPaper paper, File paperFile, File attachmentDir) {
-        File urlPaperFile = new File(rootDir + uuid() + ".json");
+    private void disposeViewPaper(String rootDir, TEExamPaper paper, File paperFile, File attachmentDir)
+            throws IOException {
         JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(paperFile));
         JSONArray structdetails = structJson.getJSONArray("details");
         if (structdetails == null || structdetails.size() == 0) {
@@ -318,13 +319,13 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
                 }
             }
         }
-        FileUtil.saveAsFile(urlPaperFile.getAbsolutePath(), structJson.toJSONString());
         String filePath = sdf.format(new Date()) + "/" + uuid() + ".json";
         paper.setPaperViewPath(filePath);
-        ossUtil.upload(false, filePath, urlPaperFile);
+        ossUtil.upload(false, filePath, structJson.toJSONString());
     }
 
-    private void disposeQuestionBodyUrl(String rootDir, JSONObject body, Long paperId, File attachmentDir) {
+    private void disposeQuestionBodyUrl(String rootDir, JSONObject body, Long paperId, File attachmentDir)
+            throws IOException {
         if (body == null) {
             return;
         }
@@ -346,7 +347,8 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         }
     }
 
-    private void disposeQuestionOptionsUrl(String rootDir, JSONArray options, Long paperId, File attachmentDir) {
+    private void disposeQuestionOptionsUrl(String rootDir, JSONArray options, Long paperId, File attachmentDir)
+            throws IOException {
         if (options == null || options.size() == 0) {
             return;
         }
@@ -375,7 +377,8 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         }
     }
 
-    private void disposePaper(String rootDir, TEExamPaper paper, File paperFile, File attachmentDir) {
+    private void disposePaper(String rootDir, TEExamPaper paper, File paperFile, File attachmentDir)
+            throws IOException {
         if (paperFile == null) {
             return;
         }
@@ -440,21 +443,18 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
             }
         }
 
-        File file = new File(rootDir + uuid() + ".json");
-        FileUtil.saveAsFile(file.getAbsolutePath(), paperJson.toJSONString());
         String filePath = sdf.format(new Date()) + "/" + uuid() + ".json";
         paper.setStructPath(filePath);
         paper.setTotalObjectiveScore(obTotal.doubleValue());
         paper.setTotalSubjectiveScore(subTotal.doubleValue());
-        ossUtil.upload(false, filePath, file);
+        ossUtil.upload(false, filePath, paperJson.toJSONString());
     }
 
-    private void disposeAnswer(String rootDir, TEExamPaper paper, File answerFile, File structFile,
-            File attachmentDir) {
+    private void disposeAnswer(String rootDir, TEExamPaper paper, File answerFile, File structFile, File attachmentDir)
+            throws IOException {
         if (answerFile == null) {
             return;
         }
-        File urlAnswerFile = new File(rootDir + uuid() + ".json");
         JSONObject answerJson = JSONObject.parseObject(FileUtil.readFileContent(answerFile));
         JSONArray answerdetails = answerJson.getJSONArray("details");
         JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(structFile));
@@ -488,13 +488,13 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
                 }
             }
         }
-        FileUtil.saveAsFile(urlAnswerFile.getAbsolutePath(), answerJson.toJSONString());
         String filePath = sdf.format(new Date()) + "/" + uuid() + ".json";
         paper.setAnswerPath(filePath);
-        ossUtil.upload(false, filePath, urlAnswerFile);
+        ossUtil.upload(false, filePath, answerJson.toJSONString());
     }
 
-    private void disposeAnswerUrl(String rootDir, JSONArray answer, Long paperId, File attachmentDir) {
+    private void disposeAnswerUrl(String rootDir, JSONArray answer, Long paperId, File attachmentDir)
+            throws IOException {
         if (answer != null && answer.size() > 0) {
             for (int i = 0; i < answer.size(); i++) {
                 JSONObject section = answer.getJSONObject(i);
@@ -519,30 +519,27 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         }
     }
 
-    private void uploadImageAndAudio(String rootDir, JSONObject blockInfo, Long paperId, File attachmentDir) {
+    private void uploadImageAndAudio(String rootDir, JSONObject blockInfo, Long paperId, File attachmentDir)
+            throws IOException {
         String type = blockInfo.getString("type");
         String value = blockInfo.getString("value");
         if (("image".equals(type) || "audio".equals(type)) && StringUtils.isNotBlank(value) && !value.toLowerCase()
                 .startsWith("https://") && !value.toLowerCase().startsWith("http://")) {
             if ("image".equals(type) && value.contains("data:image")) {
                 String suff = value.substring(11, value.indexOf(";"));
-                File iamgeFile = new File(rootDir + uuid() + "." + suff);
-                BASE64Decoder decoder = new BASE64Decoder();
-                try {
-                    byte[] bytes = decoder.decodeBuffer(value.substring(value.indexOf(",") + 1));
-                    FileUtils.writeByteArrayToFile(iamgeFile, bytes);
-                } catch (IOException e) {
-                    throw new BusinessException("媒体文件上传处理出错:" + blockInfo.toJSONString() + " errmsg:" + e.getMessage());
-                }
-                String filePath = "upload/paper_file/" + paperId + "/" + uuid() + "." + suff;
-                ossUtil.upload(false, filePath, iamgeFile);
-                blockInfo.put("value", ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + "/" + filePath);
+                byte[] bytes = Base64.decodeBase64(value.substring(value.indexOf(",") + 1));
+                String filePath =
+                        "upload" + File.separator + sdf.format(new Date()) + File.separator + uuid() + "." + suff;
+                String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(bytes));
+                ossUtil.upload(true, filePath, new ByteArrayInputStream(bytes), md5);
+                blockInfo.put("value", ossUtil.getAliYunOssPublicDomain().getPublicUrl() + "/" + filePath);
             } else {
                 String suff = value.substring(value.indexOf("."));
-                String filePath = "upload/paper_file/" + paperId + "/" + uuid() + suff;
+                String filePath =
+                        "upload" + File.separator + sdf.format(new Date()) + File.separator + uuid() + "." + suff;
                 File audioFile = new File(attachmentDir.getAbsolutePath() + "/" + value);
-                ossUtil.upload(false, filePath, audioFile);
-                blockInfo.put("value", ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + "/" + filePath);
+                ossUtil.upload(true, filePath, audioFile);
+                blockInfo.put("value", ossUtil.getAliYunOssPublicDomain().getPublicUrl() + "/" + filePath);
             }
         }
     }
@@ -640,7 +637,7 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
     }
 
     private void checkAnswerFile(String rootDir, File[] paperDirChilds, Long examId, String courseCode,
-            String paperCode) {
+                                 String paperCode) {
         File paperFile = null;
         File answerFile = null;
         for (File cfile : paperDirChilds) {// 校验试卷下的答案
@@ -659,11 +656,10 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
                     throw new BusinessException("科目 " + courseCode + " 试卷 " + paperCode + " 没有试卷信息,不能先导入答案");
                 }
                 String structPath = paper.getStructPath();
-                String url = ossUtil.getPrivateUrl(structPath);
                 String name = structPath.substring(structPath.lastIndexOf("/") + 1);
                 File structFile = new File(rootDir + name);
                 try {
-                    FileUtil.saveUrlAsFile(url, structFile);
+                    ossUtil.download(false, structPath, structFile.getAbsolutePath());
                     compareAnswerAndPaper(courseCode, paperCode, answerFile, structFile);
                 } finally {
                     if (structFile.exists()) {

+ 18 - 5
themis-business/src/main/java/com/qmth/themis/business/util/OssUtil.java

@@ -3,12 +3,14 @@ package com.qmth.themis.business.util;
 import com.aliyun.oss.ClientBuilderConfiguration;
 import com.aliyun.oss.OSS;
 import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.common.utils.BinaryUtil;
 import com.aliyun.oss.model.*;
 import com.qmth.themis.business.domain.AliYunOssDomain;
 import com.qmth.themis.business.domain.AliYunOssPrivateDomain;
 import com.qmth.themis.business.domain.AliYunOssPublicDomain;
 import com.qmth.themis.business.domain.SysDomain;
 import com.qmth.themis.business.enums.UploadFileEnum;
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -95,10 +97,13 @@ public class OssUtil {
      * @param objectName
      * @param inputStream
      */
-    public void upload(boolean isPublic, String objectName, InputStream inputStream) {
+    public void upload(boolean isPublic, String objectName, InputStream inputStream, String md5) {
         log.info("oss  upload stream is come in");
         String bucket = isPublic ? aliYunOssPublicDomain.getPublicBucket() : aliYunOssPrivateDomain.getPrivateBucket();
         OSS client = isPublic ? publicClient : privateClient;
+        ObjectMetadata meta = new ObjectMetadata();
+        // 设置MD5校验。
+        meta.setContentMD5(md5);
         // 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。
         PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, objectName, inputStream);
         PutObjectResult por = client.putObject(putObjectRequest);
@@ -112,12 +117,16 @@ public class OssUtil {
      * @param objectName
      * @param file
      */
-    public void upload(boolean isPublic, String objectName, File file) {
+    public void upload(boolean isPublic, String objectName, File file) throws IOException {
         log.info("oss  upload file is come in");
         String bucket = isPublic ? aliYunOssPublicDomain.getPublicBucket() : aliYunOssPrivateDomain.getPrivateBucket();
         OSS client = isPublic ? publicClient : privateClient;
+        ObjectMetadata meta = new ObjectMetadata();
+        // 设置MD5校验。
+        String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(FileUtils.readFileToByteArray(file)));
+        meta.setContentMD5(md5);
         // 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。
-        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, objectName, file);
+        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, objectName, file, meta);
         PutObjectResult por = client.putObject(putObjectRequest);
         log.info("objectName:{},requestid:{}", objectName, por.getRequestId());
     }
@@ -133,9 +142,13 @@ public class OssUtil {
         log.info("oss public upload string is come in");
         String bucket = isPublic ? aliYunOssPublicDomain.getPublicBucket() : aliYunOssPrivateDomain.getPrivateBucket();
         OSS client = isPublic ? publicClient : privateClient;
+        ObjectMetadata meta = new ObjectMetadata();
+        // 设置MD5校验。
+        String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(content.getBytes()));
+        meta.setContentMD5(md5);
         // 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。
         PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, objectName,
-                new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)));
+                new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), meta);
         PutObjectResult por = client.putObject(putObjectRequest);
         log.info("objectName:{},requestid:{}", objectName, por.getRequestId());
     }
@@ -147,7 +160,7 @@ public class OssUtil {
      * @param localPath
      * @throws IOException
      */
-    public File download(boolean isPublic, String objectName, String localPath) throws IOException {
+    public File download(boolean isPublic, String objectName, String localPath){
         log.info("oss Download is come in");
         String bucket = isPublic ? aliYunOssPublicDomain.getPublicBucket() : aliYunOssPrivateDomain.getPrivateBucket();
         OSS client = isPublic ? publicClient : privateClient;

+ 73 - 69
themis-common/pom.xml

@@ -1,78 +1,82 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	<groupId>com.qmth.themis.common</groupId>
-	<artifactId>themis-common</artifactId>
-	<version>1.0.0</version>
-	<packaging>jar</packaging>
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.qmth.themis.common</groupId>
+    <artifactId>themis-common</artifactId>
+    <version>1.0.0</version>
+    <packaging>jar</packaging>
 
-	<parent>
-		<groupId>com.qmth.themis</groupId>
-		<artifactId>themis-service</artifactId>
-		<version>1.0.0</version>
-	</parent>
+    <parent>
+        <groupId>com.qmth.themis</groupId>
+        <artifactId>themis-service</artifactId>
+        <version>1.0.0</version>
+    </parent>
 
-	<dependencies>
-		<dependency>
-			<groupId>com.alibaba</groupId>
-			<artifactId>fastjson</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.fasterxml.jackson.core</groupId>
-			<artifactId>jackson-core</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.fasterxml.jackson.core</groupId>
-			<artifactId>jackson-annotations</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.fasterxml.jackson.core</groupId>
-			<artifactId>jackson-databind</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.commons</groupId>
-			<artifactId>commons-lang3</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.google.guava</groupId>
-			<artifactId>guava</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.google.code.gson</groupId>
-			<artifactId>gson</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>cn.hutool</groupId>
-			<artifactId>hutool-all</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.bouncycastle</groupId>
-			<artifactId>bcprov-jdk15on</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework</groupId>
-			<artifactId>spring-web</artifactId>
-			<version>5.2.7.RELEASE</version>
-		</dependency>
-		<dependency>
-			<groupId>commons-io</groupId>
-			<artifactId>commons-io</artifactId>
-			<version>2.6</version>
-		</dependency>
+    <dependencies>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+            <version>5.2.7.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.6</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.tomcat.embed</groupId>
             <artifactId>tomcat-embed-core</artifactId>
         </dependency>
-		<dependency>
-			<groupId>org.slf4j</groupId>
-			<artifactId>slf4j-api</artifactId>
-			<version>2.0.0-alpha1</version>
-		</dependency>
-		<dependency>
-			<groupId>com.github.tencentyun</groupId>
-			<artifactId>tls-sig-api-v2</artifactId>
-		</dependency>
-	</dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>2.0.0-alpha1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.tencentyun</groupId>
+            <artifactId>tls-sig-api-v2</artifactId>
+        </dependency>
+    </dependencies>
 </project>

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

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