瀏覽代碼

Merge remote-tracking branch 'origin/dev3' into prod-test

# Conflicts:
#	src/main/resources/application.yml
lwhhszx 1 年之前
父節點
當前提交
1baf0bfd93

+ 6 - 1
pom.xml

@@ -65,10 +65,15 @@
             <artifactId>pdfbox</artifactId>
             <version>2.0.4</version>
         </dependency>
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>3.10.2</version>
+        </dependency>
     </dependencies>
 
     <build>
-        <finalName>FMS</finalName>
+        <finalName>FMS-weiXin</finalName>
         <plugins>
             <plugin>
                 <groupId>org.springframework.boot</groupId>

+ 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";
 }

+ 4 - 0
src/main/java/com/example/fms/common/model/vo/ConfigSettingVO.java

@@ -17,4 +17,8 @@ public class ConfigSettingVO {
     private String userName;
     private String password;
     private String filePath;
+    private String endPoint;
+    private String accessKeyId;
+    private String accessKeySecret;
+    private String bucketName;
 }

+ 79 - 5
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 = "上传普通文件")
@@ -77,10 +78,68 @@ public class FileMangerController {
                 try {
                     //文件原始名中的中文字符可能会乱码,对文件名进行URL编码
                     String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
+                    String s = systemFile.getOriginalName().substring(systemFile.getOriginalName().indexOf("."));
+                    String contentType = "application/octet-stream"; // 默认二进制流
+                    switch (s) {
+                        case ".xlsx":
+                            contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
+                            break;
+                        case ".xls":
+                        case ".xlt":
+                        case ".xla":
+                            contentType = "application/vnd.ms-excel";
+                            break;
+                        case ".pdf":
+                            contentType = "application/pdf";
+                            break;
+                        case ".doc":
+                        case ".dot":
+                            contentType = "application/msword";
+                            break;
+                        case ".docx":
+                            contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
+                            break;
+                        case ".dotx":
+                            contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.template";
+                            break;
+                        case ".docm":
+                            contentType = "application/vnd.ms-word.document.macroEnabled.12";
+                            break;
+                        case ".dotm":
+                            contentType = "application/vnd.ms-word.template.macroEnabled.12";
+                            break;
+                        case ".ppt":
+                        case ".pot":
+                        case ".pps":
+                        case ".ppa":
+                            contentType = "application/vnd.ms-powerpoint";
+                            break;
+                        case ".gif":
+                            contentType = "image/gif";
+                            break;
+                        case ".jpg":
+                        case ".jpeg":
+                        case ".jpe":
+                        case ".jfif":
+                            contentType = "image/jpeg";
+                            break;
+                        case ".tiff":
+                        case ".tif":
+                            contentType = "image/tiff";
+                            break;
+                        case ".png":
+                            contentType = "image/png";
+                            break;
+                        // 添加其他文件类型的case
+                        // ...
+                        default:
+                            // 如果不是已知的文件类型,则作为二进制流返回
+                            break;
+                    }
                     return ResponseEntity.ok()
                             .contentLength(fileData.length)
                             .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedFileName + "\"")
-                            .contentType(MediaType.parseMediaType("application/octet-stream"))
+                            .contentType(MediaType.parseMediaType(contentType))
                             .body(new InputStreamResource(new ByteArrayInputStream(fileData)));
                 } catch (UnsupportedEncodingException e){
                     throw new XiaoShiException("文件名取出时发生错误!");
@@ -135,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");
+    }
+
 }

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

@@ -0,0 +1,113 @@
+package com.example.fms.service;
+
+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.exception.XiaoShiException;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * OSS文件管理接口
+ *
+ * @Author xiexiang
+ * @Date 2024/4/1
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class File2OssService implements IFileFactory {
+    private final FileUtils fileUtils;
+    private final OssService ossService;
+
+    /**
+     * 上传文件
+     *
+     * @param files
+     * @param configSettingVO 根据传入的id,选择的配置类,选择的上传路径以及上传方法
+     * @return
+     * @throws IOException
+     */
+    public List<SystemFileDTO> uploadFile(List<MultipartFile> files, ConfigSettingVO configSettingVO) throws IOException {
+        List<SystemFileDTO> systemFileDTOS = new ArrayList<>();
+        for (MultipartFile file : files) {
+            try {
+                String directoryName = fileUtils.getDirectoryName();
+                SystemFileDTO systemFileDTO = OssService.upload(configSettingVO.getFilePath() + directoryName, file, configSettingVO);
+                //服务器存储目录位置(1.本地project/pas/prod/file 2.本地project/rms/prod/file 3.生产project/pas/prod/file 4.生产project/rms/prod/file)
+                systemFileDTO.setPType(configSettingVO.getId());
+                //FSS
+                systemFileDTO.setSourceId(configSettingVO.getSourceId());
+                systemFileDTO.setOriginalName(file.getOriginalFilename());
+                systemFileDTO.setFilePath(configSettingVO.getFilePath() + directoryName + "/" + systemFileDTO.getFileName());
+                systemFileDTOS.add(systemFileDTO);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return systemFileDTOS;
+    }
+
+    @Override
+    public SystemFileDTO replaceFile(String fileGuid, MultipartFile file, ConfigSettingVO configSettingVO) {
+        try {
+            String directoryName = fileUtils.getDirectoryName();
+            SystemFileDTO systemFileDTO = ossService.upload(configSettingVO.getFilePath() + directoryName, file, configSettingVO);
+            //服务器存储目录位置(1.本地project/pas/prod/file 2.本地project/rms/prod/file 3.生产project/pas/prod/file 4.生产project/rms/prod/file)
+            systemFileDTO.setPType(configSettingVO.getId());
+            //FSS
+            systemFileDTO.setSourceId(configSettingVO.getSourceId());
+            systemFileDTO.setOriginalName(file.getOriginalFilename());
+            systemFileDTO.setGUID(fileGuid);
+            systemFileDTO.setFilePath(configSettingVO.getFilePath() + directoryName + "/" + systemFileDTO.getFileName());
+            return systemFileDTO;
+        } catch (Exception e) {
+
+        }
+        return null;
+    }
+
+    /**
+     * 下载文件
+     *
+     * @param downloadSysFileDTO
+     * @param configSettingVO
+     * @return
+     */
+    public byte[] downloadFile(DownloadSysFileDTO downloadSysFileDTO, ConfigSettingVO configSettingVO) {
+        String filePath = downloadSysFileDTO.getFilePath();
+        try {
+            Long startTime =System.currentTimeMillis();
+            byte[] fileData = OssService.download(filePath, configSettingVO);
+            Long endTime =System.currentTimeMillis();
+            System.out.println("下载文件执行时间"+(endTime-startTime));
+            return fileData;
+        } catch (Exception e) {
+            throw new XiaoShiException("下载错误");
+        }
+    }
+
+    /**
+     * 删除文件
+     *
+     * @param filePath
+     * @param configSettingVO
+     */
+    public void deleteFile(String filePath, ConfigSettingVO configSettingVO) {
+        try {
+            OssService.delete(filePath, configSettingVO);
+        } catch (Exception e) {
+            throw new XiaoShiException("删除错误");
+        }
+
+
+
+    }
+}

+ 1 - 0
src/main/java/com/example/fms/service/File2SftpService.java

@@ -69,6 +69,7 @@ public class File2SftpService implements IFileFactory {
         }
         return systemFileDTO;
     }
+
     /**
      * 下载文件
      * @param downloadSysFileDTO

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

@@ -14,6 +14,7 @@ import org.springframework.stereotype.Service;
 @RequiredArgsConstructor
 public class FileFactory {
     private final File2SftpService file2SftpService;
+    private final File2OssService file2OssService;
 
     /**
      * 判断
@@ -24,6 +25,8 @@ public class FileFactory {
         switch(sourceName){
             case "FSS":
                 return file2SftpService;
+            case "OSS":
+                return file2OssService;
             default:
                 return null;
         }

+ 41 - 3
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;
     /**
      * 上传文件的最外部接口
      *
@@ -48,7 +56,7 @@ public class FileMangerService {
         if (files != null && files.size() != 0) {
             //1.调用解析配置方法,获取配置信息
             List<ConfigSettingVO> configSettingVOS = ExcuteConfigUtils.excuteConfigVO();
-            //2.根据传入id,获得配置类,根据配置类选择使用的上传方法
+            //2.根据传入id,获得配置类,根据配置类中的id去匹配sourceId来选择使用的上传方法
             ConfigSettingVO configSettingVO = configSettingVOS.stream().filter(item -> item.getId().equals(sourceId)).findFirst().orElse(null);
             //3.获取文件上传到服务器,调用工厂类
             String sourceName = configSettingVO.getSourceName();
@@ -153,6 +161,9 @@ public class FileMangerService {
                 LambdaQueryWrapper<SystemFile> queryWrapper = new LambdaQueryWrapper<>();
                 queryWrapper.eq(SystemFile::getGuid, guIds.get(i));
                 SystemFile systemFileVO = systemFileService.getOne(queryWrapper);
+                if(systemFileVO==null){
+                    continue;
+                }
                 //3.1.3 将对象的是否删除字段置为1
                 systemFileVO.setIsDelete(1);
                 //3.1.4 将查询出来的vo赋值给实体类
@@ -224,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);
+
+
+    }
 }

+ 420 - 0
src/main/java/com/example/fms/service/OssService.java

@@ -0,0 +1,420 @@
+package com.example.fms.service;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.IdUtil;
+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.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author xiexiang
+ * @Date 2024/3/29
+ */
+@RequiredArgsConstructor
+@Slf4j
+@Service
+public class OssService {
+    private final FileUtils fileUtils;
+    private final RedisUtil redisUtil;
+
+    //创建桶
+    public void createBucket() throws Exception {
+        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
+        String endpoint = "https://oss-cn-shanghai.aliyuncs.com";
+        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
+        String accessKeyId = "LTAI5tGyG1Q7fKprgg1nWhXj";
+        String accessKeySecret = "Y6Erboh5lEFiRPR4XK8oCPMvUzYGLN";
+        // 填写Bucket名称。
+        String bucketName = "xiaoshi-pas";
+        // 填写资源组ID。如果不填写资源组ID,则创建的Bucket属于默认资源组。
+        //String rsId = "rg-aek27tc****";
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+
+        try {
+            // 创建CreateBucketRequest对象。
+            CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
+
+            // 如果创建存储空间的同时需要指定存储类型、存储空间的读写权限、数据容灾类型, 请参考如下代码。
+            // 此处以设置存储空间的存储类型为标准存储为例介绍。
+            //createBucketRequest.setStorageClass(StorageClass.Standard);
+            // 数据容灾类型默认为本地冗余存储,即DataRedundancyType.LRS。如果需要设置数据容灾类型为同城冗余存储,请设置为DataRedundancyType.ZRS。
+            //createBucketRequest.setDataRedundancyType(DataRedundancyType.ZRS);
+            // 设置存储空间读写权限为公共读,默认为私有。
+            //createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
+
+            // 在支持资源组的地域创建Bucket时,您可以为Bucket配置资源组。
+            //createBucketRequest.setResourceGroupId(rsId);
+
+            // 创建存储空间。
+            ossClient.createBucket(createBucketRequest);
+        } 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 void deleteBucket() throws Exception {
+        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
+        String endpoint = "https://oss-cn-shanghai.aliyuncs.com";
+        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
+        String accessKeyId = "LTAI5tGyG1Q7fKprgg1nWhXj";
+        String accessKeySecret = "Y6Erboh5lEFiRPR4XK8oCPMvUzYGLN";
+        // 填写Bucket名称。
+        String bucketName = "xiaoshi-pas";
+
+
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+
+        try {
+            // 删除存储空间。
+            ossClient.deleteBucket(bucketName);
+        } 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();
+            }
+        }
+    }
+
+
+    /**
+     * OSS下载文件
+     *
+     * @param filePath
+     * @param configSettingVO
+     * @return
+     * @throws Exception
+     */
+    public static byte[] download(String filePath, ConfigSettingVO configSettingVO) throws Exception {
+        String endpoint = configSettingVO.getEndPoint();
+        String accessKeyId = configSettingVO.getAccessKeyId();
+        String accessKeySecret = configSettingVO.getAccessKeySecret();
+        String bucketName = configSettingVO.getBucketName();
+        String objectName = filePath;
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        try {
+            // 下载Object到本地文件,并保存到指定的本地路径中。如果指定的本地文件存在会覆盖,不存在则新建。
+            OSSObject ossObject = ossClient.getObject(new GetObjectRequest(bucketName, objectName));
+            //读取文件内容
+
+            byte[] buffer = new byte[1024];
+            int len;
+            while ((len = ossObject.getObjectContent().read(buffer)) != -1) {
+                outputStream.write(buffer, 0, len);
+            }
+        } 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();
+            }
+        }
+        return outputStream.toByteArray();
+    }
+
+    /**
+     * 删除文件
+     *
+     * @param filePath
+     * @param configSettingVO
+     * @throws Exception
+     */
+    public static void delete(String filePath, ConfigSettingVO configSettingVO) throws Exception {
+        String endpoint = configSettingVO.getEndPoint();
+        String accessKeyId = configSettingVO.getAccessKeyId();
+        String accessKeySecret = configSettingVO.getAccessKeySecret();
+        String bucketName = configSettingVO.getBucketName();
+        String objectName = filePath;
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        try {
+            // 删除文件或目录。如果要删除目录,目录必须为空。
+            ossClient.deleteObject(bucketName, objectName);
+        } 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();
+            }
+        }
+    }
+
+    /**
+     * OSS上传文件
+     *
+     * @param directory
+     * @param multipartFile
+     * @param configSettingVO
+     * @return
+     * @throws IOException
+     */
+    public static SystemFileDTO upload(String directory, MultipartFile multipartFile, ConfigSettingVO configSettingVO) throws IOException {
+        SystemFileDTO systemFileDTO = new SystemFileDTO();
+        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
+        String endpoint = configSettingVO.getEndPoint();
+        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
+        String accessKeyId = configSettingVO.getAccessKeyId();
+        String accessKeySecret = configSettingVO.getAccessKeySecret();
+        // 填写Bucket名称,例如examplebucket。
+        String bucketName = configSettingVO.getBucketName();
+        // 随机生成文件名
+        String fileName = IdUtil.simpleUUID();
+        // 获取文件的后缀,不带“.”,必须是multipartFile类型
+        String extName = FileUtil.extName(multipartFile.getOriginalFilename());
+        //拼接文件完整名存入数据库表
+        String name = fileName + "." + extName;
+        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
+        String objectName = directory + "/" + name;
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        try {
+            // 创建PutObjectRequest对象。
+            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(multipartFile.getBytes()));
+            // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
+            // ObjectMetadata metadata = new ObjectMetadata();
+            // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
+            // metadata.setObjectAcl(CannedAccessControlList.Private);
+            // putObjectRequest.setMetadata(metadata);
+            // 上传。
+            PutObjectResult result = ossClient.putObject(putObjectRequest);
+            systemFileDTO.setFileName(name);
+            systemFileDTO.setFileLength(Long.toString(multipartFile.getSize()));
+            systemFileDTO.setIsDelete(0);
+        } 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();
+            }
+        }
+        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

+ 1 - 1
src/main/resources/application-prodNetIn.yml

@@ -29,7 +29,7 @@ spring:
         max-wait: -1ms
     timeout: 2000ms
   datasource:
-    url: jdbc:mysql://172.27.247.174:3306/PCS_PROD?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8
+    url: jdbc:mysql://172.27.247.174:3306/ecs?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8
     username: root
     password: TU5x6IeBi7rl
     driver-class-name: com.mysql.cj.jdbc.Driver

+ 1 - 1
src/main/resources/application-prodNetOut.yml

@@ -29,7 +29,7 @@ spring:
         max-wait: -1ms
     timeout: 2000ms
   datasource:
-    url: jdbc:mysql://47.101.137.223:3306/PCS_PROD?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8
+    url: jdbc:mysql://47.101.137.223:3306/ecs?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8
     username: root
     password: TU5x6IeBi7rl
     driver-class-name: com.mysql.cj.jdbc.Driver

+ 1 - 1
src/main/resources/application-testNetOut.yml

@@ -29,7 +29,7 @@ spring:
         max-wait: -1ms
     timeout: 2000ms
   datasource:
-    url: jdbc:mysql://47.101.137.223:3306/PCS_TEST?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8
+    url: jdbc:mysql://47.101.137.223:3306/ecs?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8
     username: root
     password: TU5x6IeBi7rl
     driver-class-name: com.mysql.cj.jdbc.Driver

+ 9 - 0
src/main/resources/configSetting.json

@@ -34,5 +34,14 @@
     "userName": "root",
     "passWord": "cslg-pas-820f1e412aaf",
     "filePath": "/project/rms/prod/file/"
+  },{
+    "sourceId": "2",
+    "sourceName": "OSS",
+    "id": 5,
+    "endPoint": "https://oss-cn-shanghai.aliyuncs.com",
+    "accessKeyId": "LTAI5tGyG1Q7fKprgg1nWhXj",
+    "accessKeySecret": "Y6Erboh5lEFiRPR4XK8oCPMvUzYGLN",
+    "bucketName": "xiaoshi-pas",
+    "filePath": "project/ecs/prod/file"
   }
 ]

+ 3 - 3
src/main/resources/mapper/SystemFileMapper.xml

@@ -6,7 +6,7 @@
     <!--int add(SystemFile systemFile);-->
     <insert id="add" useGeneratedKeys="true" keyProperty="id">
         INSERT INTO SYSTEM_FILE(GUID, P_TYPE, SOURCE_ID, FILE_PATH, FILE_NAME, ORIGINAL_NAME, FILE_LENGTH, CREATE_ID, UPDATE_TIME, IS_DELETE)
-        VALUES (#{GUID}, #{pType}, #{sourceId}, #{filePath}, #{fileName}, #{originalName}, #{fileLength},#{createId}, #{updateTime}, #{isDelete})
+        VALUES (#{guid}, #{pType}, #{sourceId}, #{filePath}, #{fileName}, #{originalName}, #{fileLength},#{createId}, #{updateTime}, #{isDelete})
     </insert>
 
 
@@ -15,8 +15,8 @@
     <update id="update">
         UPDATE SYSTEM_FILE
         <set>
-            <if test="GUID != null">
-                GUID = #{GUID},
+            <if test="guid != null">
+                GUID = #{guid},
             </if>
             <if test="pType != null">
                 P_TYPE = #{pType},