Эх сурвалжийг харах

新加入云阅卷推送数据

wangliang 2 жил өмнө
parent
commit
68601d0af3

+ 6 - 0
pom.xml

@@ -54,6 +54,7 @@
         <ip2region.version>2.6.5</ip2region.version>
         <qmth.boot.version>1.0.3</qmth.boot.version>
         <jave-all-deps.version>3.3.1</jave-all-deps.version>
+        <httpmime.version>4.5.13</httpmime.version>
     </properties>
 
     <dependencyManagement>
@@ -269,6 +270,11 @@
                 <artifactId>core-solar</artifactId>
                 <version>${qmth.boot.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpmime</artifactId>
+                <version>${httpmime.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 

+ 1 - 0
themis-admin/src/main/resources/application-dev.properties

@@ -162,6 +162,7 @@ cloud.mark.studentScoreApi=/api/exam/student/score
 cloud.mark.examSaveApi=/api/exam/save
 cloud.mark.subjectSaveApi=/api/exam/subject/save
 cloud.mark.studentSaveApi=/api/exam/student/save
+cloud.mark.fileUploadApi=/api/file/{type}/upload
 
 #============================================================================
 # \u914D\u7F6Erocketmq

+ 1 - 0
themis-admin/src/main/resources/application-test.properties

@@ -164,6 +164,7 @@ cloud.mark.studentScoreApi=/api/exam/student/score
 cloud.mark.examSaveApi=/api/exam/save
 cloud.mark.subjectSaveApi=/api/exam/subject/save
 cloud.mark.studentSaveApi=/api/exam/student/save
+cloud.mark.fileUploadApi=/api/file/{type}/upload
 
 #============================================================================
 # \u914D\u7F6Erocketmq

+ 143 - 0
themis-business/src/main/java/com/qmth/themis/business/bean/cloudmark/FileUploadParams.java

@@ -0,0 +1,143 @@
+package com.qmth.themis.business.bean.cloudmark;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.themis.business.enums.CloudMarkFileUploadTypeEnum;
+import com.qmth.themis.common.exception.BusinessException;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.codec.digest.DigestUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * @Description: 推送云阅卷文件接口参数
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/9/28
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class FileUploadParams extends BaseParams implements Serializable {
+
+    @ApiModelProperty(value = "云阅卷考试id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examId;
+
+    @ApiModelProperty(value = "准考证号")
+    private String examNumber;
+
+    @ApiModelProperty(value = "文件")
+    private File file;
+
+    @ApiModelProperty(value = "文件md5")
+    private String md5;
+
+    @ApiModelProperty(value = "文件类型")
+    private CloudMarkFileUploadTypeEnum format;
+
+    @ApiModelProperty(value = "科目代码")
+    private String subjectCode;
+
+    public FileUploadParams() {
+
+    }
+
+    public FileUploadParams(Long orgId, Long examId, String examNumber, File file) throws IOException {
+        super(orgId, null, null);
+        this.examId = examId;
+        this.examNumber = examNumber;
+        this.file = file;
+        this.md5 = DigestUtils.md5Hex(new FileInputStream(file));
+    }
+
+    public FileUploadParams(Long orgId, Long examId, String subjectCode, CloudMarkFileUploadTypeEnum format, File file) throws IOException {
+        super(orgId, null, null);
+        this.examId = examId;
+        this.subjectCode = subjectCode;
+        this.format = format;
+        this.file = file;
+        this.md5 = DigestUtils.md5Hex(new FileInputStream(file));
+    }
+
+    public void vaildParams(CloudMarkFileUploadTypeEnum format) {
+        switch (format) {
+            case JSON:
+                if (Objects.isNull(examNumber)) {
+                    throw new BusinessException("准考证号不能为空");
+                }
+                break;
+            case PAPER:
+                if (Objects.isNull(subjectCode)) {
+                    throw new BusinessException("科目编码不能为空");
+                }
+                if (Objects.isNull(this.format)) {
+                    throw new BusinessException("文件类型不能为空");
+                }
+                break;
+            default:
+                break;
+        }
+        if (Objects.isNull(examId)) {
+            throw new BusinessException("云阅卷考试id不能为空");
+        }
+        if (Objects.isNull(file)) {
+            throw new BusinessException("文件不能为空");
+        }
+        if (Objects.isNull(md5)) {
+            throw new BusinessException("文件md5不能为空");
+        }
+    }
+
+    public File getFile() {
+        return file;
+    }
+
+    public void setFile(File file) {
+        this.file = file;
+    }
+
+    public String getMd5() {
+        return md5;
+    }
+
+    public void setMd5(String md5) {
+        this.md5 = md5;
+    }
+
+    public CloudMarkFileUploadTypeEnum getFormat() {
+        return format;
+    }
+
+    public void setFormat(CloudMarkFileUploadTypeEnum format) {
+        this.format = format;
+    }
+
+    public String getSubjectCode() {
+        return subjectCode;
+    }
+
+    public void setSubjectCode(String subjectCode) {
+        this.subjectCode = subjectCode;
+    }
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+}

+ 7 - 0
themis-business/src/main/java/com/qmth/themis/business/constant/SystemConstant.java

@@ -95,6 +95,7 @@ public class SystemConstant {
     /**
      * 系统相关
      */
+    public static final String FILE_UPLOAD_VARIABLE_URL = "\\{type\\}";
     public static final String CLOUD_MARK_EXAM_ID = "cloudMarkExamId";
     public static final String CONTENT = "content";
     public static final String FORM_USER_ID = "formUserId";
@@ -454,6 +455,12 @@ public class SystemConstant {
     //    public static final String orgCodeCache = "org_code_cache";
     //    public static final String roleCache = "role_cache";
 
+    /**
+     * http设置
+     */
+    public static final int CONNECT_TIME_OUT = 1000 * 60 * 2;//请求超时
+    public static final int SOCKET_CONNECT_TIME_OUT = 1000 * 60 * 30;//读取数据超时
+
     static {
         String[] strs = delayLevel.split(",");
         mqDelayLevel = new LinkedHashMap();

+ 14 - 2
themis-business/src/main/java/com/qmth/themis/business/domain/CloudMarkDomain.java

@@ -21,16 +21,28 @@ public class CloudMarkDomain implements Serializable {
 
     private String studentSaveApi;
 
+    private String fileUploadApi;
+
     public CloudMarkDomain() {
 
     }
 
-    public CloudMarkDomain(String url, String studentScoreApi, String examSaveApi, String subjectSaveApi, String studentSaveApi) {
+    public CloudMarkDomain(String url, String studentScoreApi, String examSaveApi, String subjectSaveApi,
+                           String studentSaveApi, String fileUploadApi) {
         this.url = url;
         this.studentScoreApi = studentScoreApi;
         this.examSaveApi = examSaveApi;
         this.subjectSaveApi = subjectSaveApi;
-        this.studentScoreApi = studentScoreApi;
+        this.studentSaveApi = studentSaveApi;
+        this.fileUploadApi = fileUploadApi;
+    }
+
+    public String getFileUploadApi() {
+        return fileUploadApi;
+    }
+
+    public void setFileUploadApi(String fileUploadApi) {
+        this.fileUploadApi = fileUploadApi;
     }
 
     public String getExamSaveApi() {

+ 27 - 0
themis-business/src/main/java/com/qmth/themis/business/enums/CloudMarkFileUploadTypeEnum.java

@@ -0,0 +1,27 @@
+package com.qmth.themis.business.enums;
+
+/**
+ * @Description: 云阅卷文件上传类型
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/9/29
+ */
+public enum CloudMarkFileUploadTypeEnum {
+
+    JSON("json"),
+
+    PAPER("paper"),
+
+    PDF("pdf");
+
+    private String code;
+
+    private CloudMarkFileUploadTypeEnum(String code) {
+        this.code = code;
+    }
+
+    public String getCode() {
+        return code;
+    }
+}

+ 41 - 1
themis-business/src/main/java/com/qmth/themis/business/util/CloudMarkUtil.java

@@ -41,7 +41,8 @@ public class CloudMarkUtil {
                 cloudMarkDomain.getStudentScoreApi(),
                 cloudMarkDomain.getExamSaveApi(),
                 cloudMarkDomain.getSubjectSaveApi(),
-                cloudMarkDomain.getStudentSaveApi());
+                cloudMarkDomain.getStudentSaveApi(),
+                cloudMarkDomain.getFileUploadApi());
         return this.cloudMarkDomain;
     }
 
@@ -184,4 +185,43 @@ public class CloudMarkUtil {
         Map<String, Object> resultMap = (Map<String, Object>) JSON.parse(result);
         return String.valueOf(resultMap.get("updateTime"));
     }
+
+    /**
+     * 推送云阅卷文件
+     *
+     * @param fileUploadParams
+     * @return
+     * @throws IOException
+     */
+    public Boolean callFileUploadApi(FileUploadParams fileUploadParams) throws IOException {
+//        // 参数
+//        Map paramMap = JSON.parseObject(JSON.toJSONString(obj), Map.class);
+//        File file = new File(String.valueOf(paramMap.get("file")));
+//        Map<String, String> files = new HashMap<>();
+//        if (file.exists()) {
+//            files.put(file.getName(), file.getPath());
+//        }
+//
+//        paramMap.put(SystemConstant.MD5, DigestUtils.md5Hex(new FileInputStream(file)));
+//        paramMap.remove("file");
+        fileUploadParams.vaildParams(fileUploadParams.getFormat());
+        this.getAccessKeyAndAccessSecret(fileUploadParams);
+        Map<String, Object> params = JSON.parseObject(JSON.toJSONString(fileUploadParams), Map.class);
+
+        // api
+        String host = cloudMarkDomain.getUrl();
+        String api = cloudMarkDomain.getFileUploadApi();
+//        api = api.replaceAll(SystemConstant.FILE_UPLOAD_VARIABLE_URL, type);
+        String url = host + api;
+        long timestamp = System.currentTimeMillis();
+        String accessToken = SignatureInfo.build(SignatureType.SECRET, SystemConstant.METHOD, cloudMarkDomain.getStudentSaveApi(), timestamp, fileUploadParams.getAccessKey(), fileUploadParams.getAccessSecret());
+        String result = HttpUtil.postFile(url, params, accessToken, timestamp);
+        result = StringEscapeUtils.unescapeHtml4(result);
+        if (result.contains("HTTP")) {
+            log.error("callFileUploadApi result:{}", result);
+            throw new BusinessException("云阅卷推送文件信息失败");
+        }
+        Map<String, Object> resultMap = (Map<String, Object>) JSON.parse(result);
+        return (Boolean) resultMap.get("success");
+    }
 }

+ 78 - 27
themis-business/src/main/java/com/qmth/themis/business/util/HttpUtil.java

@@ -7,11 +7,15 @@ import org.apache.http.Consts;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.ContentType;
 import org.apache.http.entity.StringEntity;
+import org.apache.http.entity.mime.HttpMultipartMode;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.message.BasicHeader;
 import org.apache.http.message.BasicNameValuePair;
@@ -71,33 +75,6 @@ public class HttpUtil {
         return result;
     }
 
-    /**
-     * post json
-     *
-     * @param url
-     * @param json
-     * @param secret
-     * @param timestamp
-     * @return
-     * @throws IOException
-     */
-    public static String postJson(String url, String json, String secret, Long timestamp) throws IOException {
-        // 构建post请求
-        HttpPost post = new HttpPost(url);
-        post.setHeader("authorization-token", secret);
-        post.setHeader(SystemConstant.HEADER_TIME, String.valueOf(timestamp));
-        post.setHeader(HTTP.CONTENT_TYPE, "application/json; charset=utf-8");
-        post.setHeader("Accept", "application/json");
-
-        String encoderJson = URLEncoder.encode(json, SystemConstant.CHARSET_NAME);
-        StringEntity se = new StringEntity(encoderJson);
-        se.setContentType("text/json");
-        se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
-        post.setEntity(se);
-        // 执行请求,获取响应
-        return getRespString(post);
-    }
-
     /**
      * post 请求
      *
@@ -252,4 +229,78 @@ public class HttpUtil {
         }
         return file;
     }
+
+    /**
+     * post file
+     *
+     * @param url
+     * @param params
+     * @param secret
+     * @param timestamp
+     * @return
+     * @throws IOException
+     */
+    public static String postFile(String url, Map<String, Object> params, String secret, Long timestamp) throws IOException {
+        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(SystemConstant.CONNECT_TIME_OUT)// 连接主机服务超时时间
+                .setConnectionRequestTimeout(SystemConstant.CONNECT_TIME_OUT)// 请求超时时间
+                .setSocketTimeout(SystemConstant.SOCKET_CONNECT_TIME_OUT)// 数据读取超时时间
+                .build();
+        HttpPost post = new HttpPost(url);
+        post.setHeader(SystemConstant.HEADER_AUTHORIZATION, secret);
+        post.setHeader(SystemConstant.HEADER_TIME, String.valueOf(timestamp));
+
+        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
+        // 解决中文文件名乱码问题
+        entityBuilder.setMode(HttpMultipartMode.RFC6532);
+        entityBuilder.setCharset(Consts.UTF_8);
+        ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), Consts.UTF_8);
+
+        // 构建请求参数
+        if (params != null) {
+            for (String key : params.keySet()) {
+                if (key.contains("file")) {
+                    File file = new File((String) params.get(key));
+                    entityBuilder.addBinaryBody(key, file, ContentType.DEFAULT_BINARY, file.getName());
+                } else {
+                    entityBuilder.addTextBody(key, String.valueOf(params.get(key)), contentType);
+                }
+            }
+        }
+        post.setEntity(entityBuilder.build());
+        post.setConfig(requestConfig);
+        return getRespString(post);
+    }
+
+    /**
+     * post json
+     *
+     * @param url
+     * @param json
+     * @param secret
+     * @param timestamp
+     * @return
+     * @throws IOException
+     */
+    public static String postJson(String url, String json, String secret, Long timestamp) throws IOException {
+        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(SystemConstant.CONNECT_TIME_OUT)// 连接主机服务超时时间
+                .setConnectionRequestTimeout(SystemConstant.CONNECT_TIME_OUT)// 请求超时时间
+                .setSocketTimeout(SystemConstant.SOCKET_CONNECT_TIME_OUT)// 数据读取超时时间
+                .build();
+
+        // 构建post请求
+        HttpPost post = new HttpPost(url);
+        post.setConfig(requestConfig);
+        post.setHeader(SystemConstant.HEADER_AUTHORIZATION, secret);
+        post.setHeader(SystemConstant.HEADER_TIME, String.valueOf(timestamp));
+        post.setHeader(HTTP.CONTENT_TYPE, "application/json; charset=utf-8");
+        post.setHeader("Accept", "application/json");
+
+        String encoderJson = URLEncoder.encode(json, SystemConstant.CHARSET_NAME);
+        StringEntity se = new StringEntity(encoderJson);
+        se.setContentType("text/json");
+        se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
+        post.setEntity(se);
+        // 执行请求,获取响应
+        return getRespString(post);
+    }
 }

+ 4 - 8
themis-common/pom.xml

@@ -82,14 +82,6 @@
             <groupId>com.tencentcloudapi</groupId>
             <artifactId>tencentcloud-sdk-java</artifactId>
         </dependency>
-<!--        <dependency>-->
-<!--            <groupId>com.google.zxing</groupId>-->
-<!--            <artifactId>core</artifactId>-->
-<!--        </dependency>-->
-<!--        <dependency>-->
-<!--            <groupId>com.google.zxing</groupId>-->
-<!--            <artifactId>javase</artifactId>-->
-<!--        </dependency>-->
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
@@ -102,5 +94,9 @@
             <groupId>com.qmth.boot</groupId>
             <artifactId>core-solar</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+        </dependency>
     </dependencies>
 </project>

+ 2 - 1
themis-task/src/main/resources/application-dev.properties

@@ -222,4 +222,5 @@ cloud.mark.url=http://192.168.10.224:80
 cloud.mark.studentScoreApi=/api/exam/student/score
 cloud.mark.examSaveApi=/api/exam/save
 cloud.mark.subjectSaveApi=/api/exam/subject/save
-cloud.mark.studentSaveApi=/api/exam/student/save
+cloud.mark.studentSaveApi=/api/exam/student/save
+cloud.mark.fileUploadApi=/api/file/{type}/upload

+ 2 - 1
themis-task/src/main/resources/application-test.properties

@@ -237,4 +237,5 @@ cloud.mark.url=http://192.168.10.224:80
 cloud.mark.studentScoreApi=/api/exam/student/score
 cloud.mark.examSaveApi=/api/exam/save
 cloud.mark.subjectSaveApi=/api/exam/subject/save
-cloud.mark.studentSaveApi=/api/exam/student/save
+cloud.mark.studentSaveApi=/api/exam/student/save
+cloud.mark.fileUploadApi=/api/file/{type}/upload