Pārlūkot izejas kodu

获得专利附图的guid

lwhhszx 1 gadu atpakaļ
vecāks
revīzija
80e58d4e93

+ 1 - 0
src/main/java/com/example/fms/common/core/base/RedisConf.java

@@ -19,4 +19,5 @@ public class RedisConf {
     public final static String USER_FIELD = "user-field";
     public final static String FIELD_ORDER = "field-order";
     public final static String USER_IMPORT = "user-import";
+    public final static String OSS_PART_TAG="oss-part-tag";
 }

+ 20 - 4
src/main/java/com/example/fms/controller/FileMangerController.java

@@ -1,7 +1,10 @@
 package com.example.fms.controller;
 
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.IdUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.example.fms.common.model.dto.FMSDeleteFileDTO;
+import com.example.fms.common.utils.FileUtils;
 import com.example.fms.common.utils.Response;
 import com.example.fms.domain.SystemFile;
 import com.example.fms.exception.XiaoShiException;
@@ -18,9 +21,7 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
+import java.io.*;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.util.List;
@@ -38,7 +39,7 @@ import java.util.List;
 public class FileMangerController {
     private final FileMangerService fileManagerService;
     private final SystemFileService systemFileService;
-
+    private final FileUtils fileUtils;
 
     @PostMapping("/uploadNormalFile")
     @Operation(summary = "上传普通文件")
@@ -193,4 +194,19 @@ public class FileMangerController {
         List<String> mes = fileManagerService.getPatentPictureGuids(appNo);
         return Response.success(mes);
     }
+
+    @PostMapping("/chunks")
+    @Operation(summary = "上传分片")
+    public String uploadChunks(MultipartFile file, String md5, Integer index) throws Exception {
+       fileManagerService.uploadChunks(file,md5,index);
+        return Response.success(true);
+    }
+
+    @PostMapping("/merge")
+    @Operation(summary = "合并分片")
+    public String uploadChunksMerge(String md5, String fileName)  throws Exception{
+      fileManagerService.uploadChunksMerge(md5);
+        return Response.success("saveUrl");
+    }
+
 }

+ 3 - 0
src/main/java/com/example/fms/service/File2OssService.java

@@ -106,5 +106,8 @@ public class File2OssService implements IFileFactory {
         } catch (Exception e) {
             throw new XiaoShiException("删除错误");
         }
+
+
+
     }
 }

+ 37 - 2
src/main/java/com/example/fms/service/FileMangerService.java

@@ -1,11 +1,18 @@
 package com.example.fms.service;
 
+import cn.hutool.core.util.IdUtil;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.model.CompleteMultipartUploadRequest;
+import com.aliyun.oss.model.CompleteMultipartUploadResult;
+import com.aliyun.oss.model.PartETag;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.example.fms.common.model.dto.DownloadSysFileDTO;
 import com.example.fms.common.model.dto.SystemFileDTO;
 import com.example.fms.common.model.vo.ConfigSettingVO;
 import com.example.fms.common.model.vo.SystemFileVO;
 import com.example.fms.common.utils.ExcuteConfigUtils;
+import com.example.fms.common.utils.FileUtils;
+import com.example.fms.common.utils.Response;
 import com.example.fms.domain.SystemFile;
 import com.example.fms.exception.XiaoShiException;
 import com.example.fms.mapper.SystemFileMapper;
@@ -16,6 +23,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
@@ -34,8 +42,8 @@ public class FileMangerService {
     private final SystemFileService systemFileService;
     private final SystemFileMapper systemFileMapper;
     private final FileFactory fileFactory;
-
-
+    private final FileUtils fileUtils;
+    private final OssService ossService;
     /**
      * 上传文件的最外部接口
      *
@@ -227,4 +235,31 @@ public class FileMangerService {
         return guids;
     }
 
+
+    public void uploadChunks(MultipartFile file, String md5, Integer index) throws Exception{
+        //1.调用解析配置方法,获取配置信息
+        List<ConfigSettingVO> configSettingVOS = ExcuteConfigUtils.excuteConfigVO();
+        //2.根据传入id,获得配置类,根据配置类中的id去匹配sourceId来选择使用的上传方法
+        ConfigSettingVO configSettingVO = configSettingVOS.stream().filter(item -> item.getId().equals(5)).findFirst().orElse(null);
+        String tempPath = fileUtils.getTempPath(md5);
+        File tempDirectory = new File(tempPath);
+        if (!tempDirectory.exists()) {
+            tempDirectory.mkdir();
+        }
+        String savePath = tempPath + FileUtils.FILE_SEPARATOR + md5 + "-" + index;
+        File temFile =new File(savePath);
+        file.transferTo(temFile);
+        ossService.uploadChucks(temFile,configSettingVO,index,md5);
+
+
+    }
+    public void uploadChunksMerge(String md5) throws Exception {
+        //1.调用解析配置方法,获取配置信息
+        List<ConfigSettingVO> configSettingVOS = ExcuteConfigUtils.excuteConfigVO();
+        //2.根据传入id,获得配置类,根据配置类中的id去匹配sourceId来选择使用的上传方法
+        ConfigSettingVO configSettingVO = configSettingVOS.stream().filter(item -> item.getId().equals(5)).findFirst().orElse(null);
+    ossService.uploadChunksMerge(configSettingVO,md5);
+
+
+    }
 }

+ 166 - 10
src/main/java/com/example/fms/service/OssService.java

@@ -2,24 +2,26 @@ package com.example.fms.service;
 
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.IdUtil;
-import com.aliyun.oss.ClientException;
-import com.aliyun.oss.OSS;
-import com.aliyun.oss.OSSClientBuilder;
-import com.aliyun.oss.OSSException;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.aliyun.oss.*;
+import com.aliyun.oss.internal.Mimetypes;
 import com.aliyun.oss.model.*;
+import com.example.fms.common.core.base.RedisConf;
 import com.example.fms.common.model.dto.DownloadSysFileDTO;
 import com.example.fms.common.model.dto.SystemFileDTO;
 import com.example.fms.common.model.vo.ConfigSettingVO;
 import com.example.fms.common.utils.FileUtils;
+import com.example.fms.common.utils.JsonUtils;
+import com.example.fms.common.utils.RedisUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.tomcat.jni.OS;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
+import java.io.*;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -30,6 +32,8 @@ import java.util.List;
 @Slf4j
 @Service
 public class OssService {
+    private final FileUtils fileUtils;
+    private final RedisUtil redisUtil;
 
     //创建桶
     public void createBucket() throws Exception {
@@ -82,7 +86,6 @@ public class OssService {
     }
 
 
-
     public void deleteBucket() throws Exception {
         // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
         String endpoint = "https://oss-cn-shanghai.aliyuncs.com";
@@ -121,6 +124,7 @@ public class OssService {
 
     /**
      * OSS下载文件
+     *
      * @param filePath
      * @param configSettingVO
      * @return
@@ -143,7 +147,7 @@ public class OssService {
             byte[] buffer = new byte[1024];
             int len;
             while ((len = ossObject.getObjectContent().read(buffer)) != -1) {
-                outputStream.write(buffer, 0 , len);
+                outputStream.write(buffer, 0, len);
             }
         } catch (OSSException oe) {
             System.out.println("Caught an OSSException, which means your request made it to OSS, "
@@ -167,6 +171,7 @@ public class OssService {
 
     /**
      * 删除文件
+     *
      * @param filePath
      * @param configSettingVO
      * @throws Exception
@@ -203,6 +208,7 @@ public class OssService {
 
     /**
      * OSS上传文件
+     *
      * @param directory
      * @param multipartFile
      * @param configSettingVO
@@ -261,4 +267,154 @@ public class OssService {
         return systemFileDTO;
     }
 
+    public OSS getOssClient(ConfigSettingVO configSettingVO) {
+        String endpoint = configSettingVO.getEndPoint();
+        String accessKeyId = configSettingVO.getAccessKeyId();
+        String accessKeySecret = configSettingVO.getAccessKeySecret();
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        return ossClient;
+    }
+
+
+    public String setUploadId(String md5, OSS ossClient, InitiateMultipartUploadRequest initiateMultipartUploadRequest) {
+        InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(initiateMultipartUploadRequest);
+        String uploadId = upresult.getUploadId();
+        redisUtil.set(md5, uploadId);
+        return uploadId;
+    }
+
+    public String getUploadId(String md5) {
+        String uploadId = redisUtil.get(md5);
+        return uploadId;
+
+    }
+
+
+    public void uploadChucks(File file, ConfigSettingVO configSettingVO, Integer index, String md5) throws Exception {
+        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
+        String endpoint = configSettingVO.getEndPoint();
+        // 填写Bucket名称,例如examplebucket。
+        String bucketName = configSettingVO.getBucketName();
+
+        String accessKeyId = configSettingVO.getAccessKeyId();
+        String accessKeySecret = configSettingVO.getAccessKeySecret();
+
+        String directory = fileUtils.getDirectoryName();
+
+        String tempFileName = file.getName();
+        // 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
+        String objectName = "zhang.XLSX";
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+
+
+        try {
+            // 创建InitiateMultipartUploadRequest对象。
+            InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
+            //上传批次号
+            String uploadId = "";
+            if (index == 0) {
+                uploadId = this.setUploadId(md5, ossClient, request);
+
+            } else {
+                uploadId = this.getUploadId(md5);
+            }
+            // 如果需要在初始化分片时设置请求头,请参考以下示例代码。
+            ObjectMetadata metadata = new ObjectMetadata();
+
+
+            // 根据文件自动设置ContentType。如果不设置,ContentType默认值为application/oct-srream。
+            if (metadata.getContentType() == null) {
+                metadata.setContentType(Mimetypes.getInstance().getMimetype(file, objectName));
+            }
+
+
+            UploadPartRequest uploadPartRequest = new UploadPartRequest();
+            uploadPartRequest.setBucketName(bucketName);
+            uploadPartRequest.setKey(objectName);
+            uploadPartRequest.setUploadId(uploadId);
+            // 设置上传的分片流。
+            // 以本地文件为例说明如何创建FIleInputstream,并通过InputStream.skip()方法跳过指定数据。
+
+            InputStream instream = new FileInputStream(file);
+            uploadPartRequest.setInputStream(instream);
+            // 设置分片号。每一个上传的分片都有一个分片号,取值范围是1~10000,如果超出此范围,OSS将返回InvalidArgument错误码。
+            uploadPartRequest.setPartNumber(index+1);
+            // 每个分片不需要按顺序上传,甚至可以在不同客户端上传,OSS会按照分片号排序组成完整的文件。
+            UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
+            // 每次上传分片之后,OSS的返回结果包含PartETag。PartETag将被保存在partETags中。
+            // partETags是PartETag的集合。PartETag由分片的ETag和分片号组成。
+            List<PartETag> partETags = new ArrayList<PartETag>();
+            partETags.add(uploadPartResult.getPartETag());
+            this.addPartETags(md5,uploadPartResult.getPartETag());
+
+        } catch (OSSException oe) {
+            System.out.println("Caught an OSSException, which means your request made it to OSS, "
+                    + "but was rejected with an error response for some reason.");
+            System.out.println("Error Message:" + oe.getErrorMessage());
+            System.out.println("Error Code:" + oe.getErrorCode());
+            System.out.println("Request ID:" + oe.getRequestId());
+            System.out.println("Host ID:" + oe.getHostId());
+        } catch (ClientException ce) {
+            System.out.println("Caught an ClientException, which means the client encountered "
+                    + "a serious internal problem while trying to communicate with OSS, "
+                    + "such as not being able to access the network.");
+            System.out.println("Error Message:" + ce.getMessage());
+        } finally {
+//            if (ossClient != null) {
+//                ossClient.shutdown();
+//            }
+        }
+    }
+
+    public String getPartETagRedisKey(String md5) {
+        String key = RedisConf.OSS_PART_TAG + RedisConf.SYMBOL_COLON + md5;
+        return key;
+    }
+
+    public List<PartETag> getPartETags(String md5) {
+
+        List<PartETag> partETags = new ArrayList<>();
+        String key = this.getPartETagRedisKey(md5);
+        String json = redisUtil.get(key);
+        if (json != null) {
+            partETags =  JSONArray.parseArray(json,PartETag.class);
+
+        }
+        return partETags;
+    }
+
+    public List<PartETag> addPartETags(String md5, PartETag partETag) {
+        List<PartETag> partETags = new ArrayList<>();
+        String key = this.getPartETagRedisKey(md5);
+        String json = redisUtil.get(key);
+        if (json != null) {
+            partETags = JsonUtils.jsonToList(json, PartETag.class);
+        }
+        partETags.add(partETag);
+       String jsons = JSONObject.toJSONString(partETags);
+       redisUtil.set(key,jsons);
+       return partETags;
+    }
+
+    public void uploadChunksMerge(ConfigSettingVO configSettingVO, String md5) throws Exception {
+        String directory = fileUtils.getDirectoryName();
+        OSS ossClient = this.getOssClient(configSettingVO);
+        String bucketName = configSettingVO.getBucketName();
+        String uploadId = redisUtil.get(md5);
+        String tempFileName = IdUtil.simpleUUID() + "." + "xls";
+        String objectName = "zhang.XLSX";
+        List<PartETag> partETags = this.getPartETags(md5);
+        // 创建CompleteMultipartUploadRequest对象。
+        // 在执行完成分片上传操作时,需要提供所有有效的partETags。OSS收到提交的partETags后,会逐一验证每个分片的有效性。当所有的数据分片验证通过后,OSS将把这些分片组合成一个完整的文件。
+        CompleteMultipartUploadRequest completeMultipartUploadRequest =
+                new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
+
+        // 完成分片上传。
+        CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
+        System.out.println(completeMultipartUploadResult.getETag());
+
+
+    }
 }

+ 3 - 3
src/main/resources/application-dev.yml

@@ -1,10 +1,10 @@
 spring:
-  rabbitmq.host: 192.168.1.24
+  rabbitmq.host: 192.168.2.24
   rabbitmq.port: 5672
   rabbitmq.username: admin
   rabbitmq.password: 123456
   redis:
-    host: 192.168.1.24
+    host: 192.168.2.24
     port: 6379
     database: 3
     password: Xx0GWxdWQJxx6Swe
@@ -16,7 +16,7 @@ spring:
         max-wait: -1ms
     timeout: 2000ms
   datasource:
-    url: jdbc:mysql://192.168.1.24:3306/PCS_TEST?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8
+    url: jdbc:mysql://192.168.2.24:3306/PCS_TEST?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8
     username: root
     password: rrzTwWAYX8Gxh5JH
     driver-class-name: com.mysql.cj.jdbc.Driver

+ 2 - 2
src/main/resources/application.yml

@@ -1,7 +1,7 @@
 server:
   servlet:
     context-path: /
-  port: 8802
+  port: 8803
 sa-token:
   activity-timeout: 18000
   token-name: token
@@ -23,7 +23,7 @@ spring:
       max-file-size: 1000MB
       max-request-size: 1000MB
   profiles:
-    active:
+    active: dev
   jackson:
     default-property-inclusion: non_null
     serialization:

+ 2 - 2
src/main/resources/configSetting.json

@@ -38,10 +38,10 @@
     "sourceId": "2",
     "sourceName": "OSS",
     "id": 5,
-    "endPoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
+    "endPoint": "https://oss-cn-shanghai.aliyuncs.com",
     "accessKeyId": "LTAI5tGyG1Q7fKprgg1nWhXj",
     "accessKeySecret": "Y6Erboh5lEFiRPR4XK8oCPMvUzYGLN",
-    "bucketName": "xiaoshi-ecs-sys",
+    "bucketName": "xiaoshi-pas",
     "filePath": "project/ecs/prod/file"
   }
 ]