ソースを参照

OSS文件的导入导出

lengfaqiang 3 年 前
コミット
2eda61966a

+ 1 - 0
sckw-modules/pom.xml

@@ -16,6 +16,7 @@
         <module>sckw-system</module>
         <module>sckw-message</module>
         <module>sckw-example</module>
+        <module>sckw-file</module>
     </modules>
 
     <properties>

+ 6 - 6
sckw-modules/sckw-example/pom.xml

@@ -22,6 +22,12 @@
 
     <dependencies>
 
+        <dependency>
+            <groupId>com.sckw</groupId>
+            <artifactId>sckw-file</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+
 
         <dependency>
             <groupId>com.sckw</groupId>
@@ -58,12 +64,6 @@
             <version>1.0.0</version>
         </dependency>
 
-        <dependency>
-            <groupId>com.sckw</groupId>
-            <artifactId>sckw-common-stream</artifactId>
-            <version>1.0.0</version>
-        </dependency>
-
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>

+ 55 - 0
sckw-modules/sckw-example/src/main/java/com/sckw/example/controller/FileApiController.java

@@ -0,0 +1,55 @@
+package com.sckw.example.controller;
+
+import com.sckw.core.web.response.HttpResult;
+import com.sckw.example.service.FileService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @author lfdc
+ * @version 1.0
+ * @className FileApiController
+ * @description alibaba-oss测试用例
+ * z
+ * @company sckw
+ * @date 2023-06-02 16:06:43
+ */
+@Slf4j
+@RestController
+@RequestMapping("/file")
+@AllArgsConstructor
+//@RequestMapping("/export")
+public class FileApiController {
+
+    @Autowired
+    private FileService fileService;
+
+    /**
+     * 上传文件至OSS
+     * @param file
+     * @return
+     */
+    @RequestMapping(value = "/fileUpload",method = RequestMethod.POST)
+    public HttpResult fileUpload(@RequestParam("file")MultipartFile file) {
+        //获取上传文件
+        String url = fileService.uploadFile(file);
+        return HttpResult.ok(url);
+
+    }
+
+    /**
+     * OSS下载文件/获取文件地址
+     * @return
+     */
+        @GetMapping("/fileDownload")
+    public HttpResult fileDownload() {
+        String fileName = "测试=JPEG.webp";
+        //获取上传文件
+        String url = fileService.fileDownload(fileName);
+        return HttpResult.ok(url);
+    }
+
+}

+ 48 - 0
sckw-modules/sckw-example/src/main/java/com/sckw/example/service/FileService.java

@@ -0,0 +1,48 @@
+package com.sckw.example.service;
+
+
+import com.sckw.excel.config.easyexcel.RequestHolder;
+import com.sckw.file.common.enums.FileEnum;
+import com.sckw.file.utils.FileUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+
+/**
+ * @author lfdc
+ * @version 1.0
+ * @className FileService
+ * @description 文件上传下载service
+ * @company sckw
+ * @date 2023-06-02 16:06:46
+ */
+@Slf4j
+@Service
+public class FileService {
+
+
+    /**
+     * 上传文件至OSS
+     *
+     * @param file
+     * @return
+     */
+    public String uploadFile(MultipartFile file) {
+        //
+        String url = FileUtils.uploadFile(file, FileEnum.DOCUMENT_ADDRESS);
+        //
+        return url;
+    }
+
+
+    /**
+     * OSS下载文件/获取文件地址
+     *
+     * @return
+     */
+    public String fileDownload(String fileName) {
+        FileUtils.downloadByObjectName(RequestHolder.getResponse(),fileName);
+        return null;
+    }
+}

+ 87 - 0
sckw-modules/sckw-file/pom.xml

@@ -0,0 +1,87 @@
+<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>sckw-modules</artifactId>
+        <groupId>com.sckw</groupId>
+        <version>1.0.0</version>
+    </parent>
+
+<!--    <groupId>com.sckw</groupId>-->
+    <artifactId>sckw-file</artifactId>
+    <version>1.0.0</version>
+    <description>文件服务</description>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+
+    <dependencies>
+
+        <dependency>
+            <groupId>com.sckw</groupId>
+            <artifactId>sckw-common-remote</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sckw</groupId>
+            <artifactId>sckw-common-datasource</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sckw</groupId>
+            <artifactId>sckw-common-redis</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.sckw</groupId>
+            <artifactId>sckw-system-api</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+
+        <!--alibaba oss-->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
+            <version>2.2.0.RELEASE</version>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.aliyun.oss</groupId>-->
+<!--            <artifactId>aliyun-sdk-oss</artifactId>-->
+<!--            <version>3.8.0</version>-->
+<!--            <scope>compile</scope>-->
+<!--        </dependency>-->
+        <!--jdk9+ 以上需要手动添加-->
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+            <version>2.3.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <!--注册中心客户端-->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+        <!--配置中心客户端-->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-bootstrap</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 33 - 0
sckw-modules/sckw-file/src/main/java/com/sckw/file/FileApplication.java

@@ -0,0 +1,33 @@
+package com.sckw.file;
+
+
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+
+/**
+ * @author lfdc
+ * @version 1.0
+ * @className FileApplication
+ * @description 文件上传下载启动类
+ * @company sckw
+ * @date 2023-06-02 17:06:43
+ */
+@EnableDubbo
+@EnableFeignClients({"com.sckw.*.api.feign"})
+@EnableDiscoveryClient
+@SpringBootApplication
+public class FileApplication {
+
+    public static void main(String[] args) {
+        // 关闭nacos日志
+        System.setProperty("nacos.logging.default.config.enabled", "false");
+        try {
+            SpringApplication.run(FileApplication.class, args);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 67 - 0
sckw-modules/sckw-file/src/main/java/com/sckw/file/common/enums/AliyunOssFileTypeEnum.java

@@ -0,0 +1,67 @@
+package com.sckw.file.common.enums;
+
+/**
+ * @author lfdc
+ * @version 1.0
+ * @className AliyunOssFileTypeEnum
+ * @description 阿里云文件类型
+ * @company sckw
+ * @date 2023-06-05 13:06:54
+ */
+public enum AliyunOssFileTypeEnum {
+    BMP(".bmp","image/bmp"),
+    GIF(".gif","image/gif"),
+    JPEG(".jpeg","image/jpeg"),
+    JPG(".jpg","image/jpeg"),
+    PNG(".png","image/jpeg"),
+    HTML(".html","text/html"),
+    XML(".xml","text/xml"),
+    TXT(".txt","application/octet-stream"),
+    SQL(".sql","application/octet-stream"),
+    VSD(".vsd","application/vnd.visio"),
+    PDF(".pdf","application/pdf"),
+    PPT(".ppt","application/vnd.ms-powerpoint"),
+    PPTX(".pptx","application/vnd.ms-powerpoint"),
+    DOC(".doc","application/msword"),
+    DOCX(".docx","application/msword"),
+    XLS(".xls","application/vnd.ms-excel"),
+    XLSX(".xlsx","application/vnd.ms-excel"),
+    CSV(".csv","application/vnd.ms-excel");
+
+
+    String code;
+
+
+    String text;
+
+
+    AliyunOssFileTypeEnum() {
+    }
+
+
+    AliyunOssFileTypeEnum(String code, String text) {
+        this.code = code;
+        this.text = text;
+    }
+
+
+    public String getCode() {
+        return code;
+    }
+
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+
+    public String getText() {
+        return text;
+    }
+
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+}

+ 76 - 0
sckw-modules/sckw-file/src/main/java/com/sckw/file/common/enums/FileEnum.java

@@ -0,0 +1,76 @@
+package com.sckw.file.common.enums;
+/**
+ * @author lfdc
+ * @version 1.0
+ * @className FileEnum
+ * @description 文件上传保存地址
+ * @company sckw
+ * @date 2023-06-02 16:06:43
+ */
+public enum FileEnum {
+
+
+    /**
+     * 本地存储地址
+     */
+    Local_Address("1","/image", "本地上传保存地址"),
+    /**
+     * 用户存储地址
+     */
+    User_Address("2","/user", "用户存储地址"),
+    /**
+     * 企业存储地址
+     */
+    Enterprise_Address("3","/enterprise", "企业存储地址"),
+    /**
+     * 合同存储地址
+     */
+    CONTRACT_ADDRESS("4","/contract", "合同存储地址"),
+    /**
+     * 文件存储地址
+     */
+    DOCUMENT_ADDRESS("5","/excel", "文件存储地址"),;
+//    /**
+//     * 腾讯云的 OSS
+//     */
+//    TENCENT(4, RegionTencent.values()),
+//    /**
+//     * 百度云的OSS
+//     */
+//    BAIDU(5, RegionBaiDu.values()),
+
+    private final String fileType;
+    private final String fileAddress;
+    private final String fileDescription;
+
+    public String getFileType() {
+        return fileType;
+    }
+
+    public String getFileAddress() {
+        return fileAddress;
+    }
+
+    public String getFileDescription() {
+        return fileDescription;
+    }
+
+    FileEnum(String fileType, String fileAddress, String fileDescription) {
+        this.fileType = fileType;
+        this.fileAddress = fileAddress;
+        this.fileDescription = fileDescription;
+    }
+
+
+
+
+    public static String getValue(String fileType) {
+        for (FileEnum ele : FileEnum.values()) {
+            if (ele.getFileType().equals(fileType)) {
+                return ele.getFileAddress();
+            }
+        }
+        return null;
+    }
+
+}

+ 71 - 0
sckw-modules/sckw-file/src/main/java/com/sckw/file/controller/FileApiController.java

@@ -0,0 +1,71 @@
+package com.sckw.file.controller;
+
+import com.sckw.core.web.response.HttpResult;
+import com.sckw.file.service.FileService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @author lfdc
+ * @version 1.0
+ * @className FileApiController
+ * @description alibaba-oss测试用例
+ *
+ * @company sckw
+ * @date 2023-06-02 16:06:43
+ */
+@Slf4j
+@RestController
+@RequestMapping("/file")
+@AllArgsConstructor
+public class FileApiController {
+
+    @Autowired
+    private FileService fileService;
+
+    /**
+     * 上传文件至OSS
+     *
+     * @param file
+     * @return
+     */
+    @RequestMapping(value = "/fileUpload", method = RequestMethod.POST)
+    public HttpResult fileUpload(@RequestParam("file") MultipartFile file) {
+        //获取上传文件
+//        String url = fileService.uploadFile(file);
+        return fileService.uploadFile(file);
+
+    }
+
+    /**
+     * 上传文件至OSS
+     *
+     * @param file
+     * @return
+     */
+    @RequestMapping(value = "/fileUploadList", method = RequestMethod.POST)
+    public HttpResult uploadFileList(@RequestParam("file") MultipartFile[] file) {
+        //获取上传文件
+//        String url = fileService.uploadFile(file);
+        return fileService.uploadFileList(file);
+
+    }
+
+    /**
+     * OSS下载文件/获取文件地址
+     * @return
+     */
+    @GetMapping("/fileDownload")
+    public HttpResult fileDownload() {
+//        String fileName = "https://kaiwu-saas.oss-cn-chengdu.aliyuncs.com/kll/uploads/20230605/146288830649995264测试=JPEG.webp";
+//        String fileName = "https://kaiwu-saas.oss-cn-chengdu.aliyuncs.com/kll/uploads/20230605/146325493677821952598454132.jpg";
+        String fileName = "https://kaiwu-saas.oss-cn-chengdu.aliyuncs.com/kll/uploads/20230605/14633197602917990420230605demo.txt";
+        //获取上传文件
+        fileService.fileDownload(fileName);
+        return HttpResult.ok();
+    }
+
+}

+ 129 - 0
sckw-modules/sckw-file/src/main/java/com/sckw/file/service/FileService.java

@@ -0,0 +1,129 @@
+package com.sckw.file.service;
+
+
+import com.sckw.core.utils.StringUtils;
+import com.sckw.core.web.constant.HttpStatus;
+import com.sckw.core.web.response.HttpResult;
+import com.sckw.file.common.enums.FileEnum;
+import com.sckw.file.utils.FileUtils;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.*;
+
+
+/**
+ * @author lfdc
+ * @version 1.0
+ * @className FileService
+ * @description 文件上传下载service
+ * @company sckw
+ * @date 2023-06-02 16:06:46
+ */
+@Service
+public class FileService {
+    /**
+     * 上传文件至OSS
+     *
+     * @param file
+     * @return
+     */
+    public HttpResult uploadFile(@RequestParam("file") MultipartFile file) {
+        HttpResult result = new HttpResult();
+        List<Map<String,Object>> resultList=new ArrayList<>();
+        result.setCode(HttpStatus.SUCCESS_CODE);
+        boolean isEmpty = file.isEmpty();
+        if (isEmpty) {
+            result.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
+            result.setMsg("上传请选择文件");
+        }
+        //文件大小
+        String fileSize = FileUtils.getFileSize(file);
+        //文件名称
+        String originalFilename = file.getOriginalFilename();
+        String url = FileUtils.uploadFile(file, FileEnum.DOCUMENT_ADDRESS);
+        //上传至oss文件地址
+        if (StringUtils.isNotBlank(url)){
+            String oosUrl = url;
+            result.setCode(HttpStatus.SUCCESS_CODE);
+            result.setMsg("上传成功");
+
+            Map<String, Object> map = new HashMap<>();
+            map.put("fileKey",url);
+            map.put("fileName",originalFilename);
+            resultList.add(map);
+            result.setData(resultList);
+        }else {
+            result.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
+            result.setMsg("上传请选择文件");
+        }
+        return result;
+    }
+
+
+    /**
+     * 批量上传文件至OSS
+     *
+     * @param file
+     * @return
+     */
+    @Async
+    public HttpResult uploadFileList( MultipartFile[] file) {
+        HttpResult result = new HttpResult();
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        if (!ObjectUtils.isEmpty(file) && file.length > 0) {
+            List<MultipartFile> multipartFiles = Arrays.asList(file);
+            for (MultipartFile multipartFile : multipartFiles) {
+                Map<String, Object> map = new HashMap<>();
+                //文件大小
+                String fileSize = FileUtils.getFileSize(multipartFile);
+                //文件名称
+                String originalFilename = multipartFile.getOriginalFilename();
+                map.put("code", HttpStatus.SUCCESS_CODE);
+                map.put("fileName", originalFilename);
+                map.put("message", HttpStatus.SUCCESS_MESSAGE);
+                String url = null;
+                //上传文件是否成功
+                try {
+                    url = FileUtils.uploadFile(multipartFile, FileEnum.DOCUMENT_ADDRESS);
+                } catch (Exception e) {
+                    map.put("code", HttpStatus.GLOBAL_EXCEPTION_CODE);
+                    map.put("fileName", originalFilename);
+                    map.put("message", e);
+                }
+                if (StringUtils.isBlank(url)) {
+                    map.put("code", HttpStatus.GLOBAL_EXCEPTION_CODE);
+                    map.put("fileName", originalFilename);
+                    map.put("message", HttpStatus.SUCCESS_MESSAGE);
+                }
+                //上传至oss文件地址
+                String oosUrl = url;
+                resultList.add(map);
+            }
+        } else {
+            result.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
+            result.setMsg("上传选择文件为空");
+        }
+        result.setData(resultList);
+        return result;
+    }
+
+
+    /**
+     * OSS下载文件/获取文件地址
+     *
+     * @return
+     */
+    public void fileDownload(String fileName) {
+        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
+//        FileUtils.downloadByUrl(response,fileName);
+        FileUtils.downOSSFile(fileName,response);
+//        FileUtils.downloadByFileName(fileName);
+    }
+}

+ 660 - 0
sckw-modules/sckw-file/src/main/java/com/sckw/file/utils/FileUtils.java

@@ -0,0 +1,660 @@
+package com.sckw.file.utils;
+
+import cn.hutool.core.date.DateTime;
+import com.aliyun.oss.ClientException;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.OSSException;
+import com.aliyun.oss.model.*;
+import com.sckw.core.utils.IdWorker;
+import com.sckw.core.utils.StringUtils;
+import com.sckw.file.common.enums.AliyunOssFileTypeEnum;
+import com.sckw.file.common.enums.FileEnum;
+import jakarta.annotation.PostConstruct;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.text.DecimalFormat;
+import java.util.Date;
+
+/**
+ * @author lfdc
+ * @version 1.0
+ * @className FileUtils
+ * @description Oss文件工具类
+ * @company sckw
+ * @date 2023-06-05 09:06:57
+ */
+@Slf4j
+@Component
+@Configuration
+public class FileUtils {
+
+    private static String BASE_DIR = "kll/uploads/";
+
+    //oss客户端连接
+    private static OSS ossclient = null;
+
+
+    private static String DEFAULT_ENDPOINT = "oss-cn-chengdu.aliyuncs.com";
+    private static String DEFAULT_ACCESS_KEY_ID = "LTAI5tPEbubCGq5Rdwygbz4Q";
+    private static String DEFAULT_ACCESS_KEY_SECRET = "7mQLWMaBJeZPRV1SRGogctYGXwppjQ";
+    private static String DEFAULT_BUCKET_NAME = "kaiwu-saas";
+
+    private static String endpoint;
+    private static String accessKeyId;
+    private static String accessKeySecret;
+    private static String bucketName;
+
+
+    @Value("${aliyun.oss.endpoint}")
+    private String oss_endpoint;
+
+    @Value("${aliyun.oss.accessKeyId}")
+    private String oss_accessKeyId;
+
+    @Value("${aliyun.oss.secret}")
+    private String oss_accessKeySecret;
+
+    @Value("${aliyun.oss.bucket}")
+    public String oss_bucketName;
+
+    @PostConstruct
+    public void setEndpoint() {
+        endpoint = this.oss_endpoint;
+    }
+
+    @PostConstruct
+    public void setAccessKeyId() {
+        accessKeyId = this.oss_accessKeyId;
+    }
+
+    @PostConstruct
+    public void setAccessKeySecret() {
+        accessKeySecret = this.oss_accessKeySecret;
+    }
+
+    @PostConstruct
+    public void setBucketName() {
+        bucketName = this.oss_bucketName;
+    }
+
+
+    /**
+     * 上传文件
+     * <p>
+     * kll/uploads/年月日/md5(file).xxx
+     *
+     * @param file
+     * @param fileEnum
+     * @return
+     */
+    public static String uploadFile(MultipartFile file, FileEnum fileEnum) {
+        try {
+            //创建OSSClient实例
+            defalutOSS();
+            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+
+            //容器不存在,就创建
+            if (!ossClient.doesBucketExist(bucketName)) {
+                ossClient.createBucket(bucketName);
+                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
+                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
+                ossClient.createBucket(createBucketRequest);
+            }
+            //上传文件流
+            InputStream inputStream = file.getInputStream();
+            String fileName = file.getOriginalFilename();
+            //生成随机唯一值,使用uuid,添加到文件名称里面
+            long uuid = new IdWorker(1).nextId();
+            fileName = String.valueOf(uuid) + fileName;
+            //按照当前日期,创建文件夹,上传到创建文件夹里面
+            //2021/02/02/01.jpgossClient = {OSSClient@13049}
+            String timeUrl = new DateTime().toString("yyyyMMdd");
+            fileName = timeUrl + "/" + fileName;
+            String filePath = BASE_DIR + fileName;
+            //调用方法实现上传
+            ossClient.putObject(bucketName, filePath, inputStream);
+            //上传后的文件地址
+//            String url1 = getUrl(ossClient, bucketName, filePath);
+//            System.out.println(url1);
+            //关闭OSSClient。
+            ossClient.shutdown();
+            //上传之后文件路径
+            //https://yygh-atguigu.oss-cn-beijing.aliyuncs.com/01.jpg
+            String url = "https://" + bucketName + "." + endpoint + "/" + filePath;
+            //返回 上传文件地址
+            return url;
+        } catch (IOException e) {
+            e.printStackTrace();
+            log.error("oss-upload-file-error:{}", e.getMessage(), e);
+            return null;
+        }
+    }
+
+    private static void defalutOSS() {
+        if (StringUtils.isBlank(endpoint)) {
+            endpoint = DEFAULT_ENDPOINT;
+        }
+        if (StringUtils.isBlank(accessKeyId)) {
+            accessKeyId = DEFAULT_ACCESS_KEY_ID;
+        }
+        if (StringUtils.isBlank(accessKeySecret)) {
+            accessKeySecret = DEFAULT_ACCESS_KEY_SECRET;
+        }
+        if (StringUtils.isBlank(bucketName)) {
+            bucketName = DEFAULT_BUCKET_NAME;
+        }
+    }
+
+
+    /**
+     * 获取文件上传大小
+     *
+     * @param file
+     * @return
+     */
+    public static String getFileSize(MultipartFile file) {
+        long size = file.getSize();
+        DecimalFormat df = new DecimalFormat("#.00");
+        String fileSizeString;
+        if (size < 1024) {
+            fileSizeString = df.format((double) size) + "B";
+        } else if (size < 1048576) {
+            fileSizeString = df.format((double) size / 1024) + "KB";
+        } else if (size < 1073741824) {
+            fileSizeString = df.format((double) size / 1048576) + "MB";
+        } else {
+            fileSizeString = df.format((double) size / 1073741824) + "GB";
+        }
+        return fileSizeString;
+    }
+
+    /**
+     * 获得阿里云OSS客户端对象
+     *
+     * @param ossEndpoint
+     * @param accessId
+     * @param accessKey
+     * @return
+     */
+    public static OSS getOssClient(String ossEndpoint, String accessId, String accessKey) {
+        if (ossclient == null) {
+            ossclient = new OSSClientBuilder().build(ossEndpoint, accessId, accessKey);
+        }
+        return ossclient;
+    }
+
+    /**
+     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
+     *
+     * @param fileName 文件名
+     * @return 文件的contentType
+     */
+    public static String getContentType(String fileName) {
+        // 文件的后缀名
+        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
+        log.info("getContentType->fileName={},fileExtension={}", fileName, fileExtension);
+        for (AliyunOssFileTypeEnum e : AliyunOssFileTypeEnum.values()) {
+            if (e.getCode().equalsIgnoreCase(fileExtension)) {
+                return e.getText();
+            }
+        }
+        // 默认返回类型
+        return AliyunOssFileTypeEnum.TXT.getText();
+    }
+
+    public static void downOSSFile(String fileName, HttpServletResponse response) {
+        BufferedInputStream input = null;
+        OutputStream outputStream = null;
+        defalutOSS();
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+//        OSSObject ossObject = ossClient.getObject(bucketName, folder + fileName);
+        OSSObject ossObject = ossClient.getObject(bucketName, fileName);
+        try {
+            response.reset();
+            response.setCharacterEncoding("utf-8");
+            response.setContentType("application/x-msdownload");
+            response.addHeader("Content-Disposition",
+                    "attachment;filename=" + new String(fileName.getBytes("gb2312"), "ISO8859-1"));
+
+            input = new BufferedInputStream(ossObject.getObjectContent());
+            byte[] buffBytes = new byte[1024];
+            outputStream = response.getOutputStream();
+            int read = 0;
+            while ((read = input.read(buffBytes)) != -1) {
+                outputStream.write(buffBytes, 0, read);
+            }
+            outputStream.flush();
+            // 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
+            ossObject.close();
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        } finally {
+            try {
+                if (outputStream != null) {
+                    outputStream.close();
+                }
+                if (input != null) {
+                    input.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        ossClient.shutdown();
+    }
+
+
+    /**
+     * 通过文件名字下载
+     *
+     * @param response response
+     * @param fileName 文件名字,带后缀,例子:postman.txt 文件全路径 https://kaiwu-saas.oss-cn-chengdu.aliyuncs.com/kll/uploads/20230605/146325493677821952598454132.txt
+     */
+    public static void downloadByFileName(HttpServletResponse response, String fileName) {
+        defalutOSS();
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        OSSObject ossObject = ossClient.getObject(bucketName, fileName);
+        String contentType = ossObject.getObjectMetadata().getContentType();
+        String contentType1 = getContentType(fileName);
+        System.out.println("contentType:" + contentType);
+        System.out.println("contentType1:" + contentType1);
+        //设置响应内容类型,当设置了ContentType为“image/jpg”时,浏览器可以直接显示图片;
+        response.setContentType(contentType);
+        BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
+        try {
+            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
+            //通知浏览器以附件形式下载
+            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
+            byte[] car = new byte[1024];
+            int len = 0;
+            while ((len = in.read(car)) != -1) {
+                out.write(car, 0, len);
+            }
+            out.flush();
+            out.close();
+            in.close();
+            ossClient.shutdown();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 创建存储空间
+     *
+     * @param ossClient  OSS连接
+     * @param bucketName 存储空间
+     * @return
+     */
+    public static String createBucketName(OSS ossClient, String bucketName) {
+        // 存储空间
+        final String bucketNames = bucketName;
+        if (!ossClient.doesBucketExist(bucketName)) {
+            // 创建存储空间
+            Bucket bucket = ossClient.createBucket(bucketName);
+            log.info("创建存储空间成功");
+            return bucket.getName();
+        }
+        return bucketNames;
+    }
+
+
+    /**
+     * 删除存储空间bucketName
+     *
+     * @param ossClient  oss对象
+     * @param bucketName 存储空间
+     */
+    public static void deleteBucket(OSS ossClient, String bucketName) {
+        ossClient.deleteBucket(bucketName);
+        log.info("删除" + bucketName + "Bucket成功");
+    }
+
+
+    /**
+     * 创建模拟文件夹:多级目录
+     *
+     * @param ossClient  oss连接
+     * @param bucketName 存储空间
+     * @param folder     模拟文件夹名如"upload/2023/01/11/"
+     * @return 文件夹名
+     */
+    public static String createFolder(OSS ossClient, String bucketName, String folder) {
+        // 文件夹名
+        final String keySuffixWithSlash = folder;
+        // 判断文件夹是否存在,不存在则创建
+        if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) {
+            // 创建文件夹
+            ossClient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));
+            log.info("创建文件夹成功");
+            // 得到文件夹名
+            OSSObject object = ossClient.getObject(bucketName, keySuffixWithSlash);
+            String fileDir = object.getKey();
+            return fileDir;
+        }
+        return keySuffixWithSlash;
+    }
+
+
+    /**
+     * 根据key删除OSS服务器上的文件
+     *
+     * @param ossClient  oss连接
+     * @param bucketName 存储空间
+     * @param key        Bucket下的文件的路径名+文件名 如:"upload/2023/01/11/cake.jpg"
+     */
+    public static void deleteObject(OSS ossClient, String bucketName, String key) {
+        ossClient.deleteObject(bucketName, key);
+        log.info("删除" + bucketName + "下的文件" + key + "成功");
+    }
+
+
+    /**
+     * 上传文件
+     *
+     * @param ossClient  oss连接
+     * @param bucketName 存储空间
+     * @param ossPath    上传文件相对路径+文件名如"upload/2023/01/11/cake.jpg"
+     * @param is         以输入流的形式上传文件
+     * @param fileName   上传文件后新文件名
+     * @return String 返回的唯一MD5数字签名
+     */
+    public static String uploadFileOss(OSS ossClient, String bucketName, String ossPath, InputStream is, String fileName) {
+        try {
+            // 文件大小
+            long fileSize = is.available();
+            // 创建上传Object的Metadata
+            ObjectMetadata metadata = new ObjectMetadata();
+            // 上传的文件的长度
+            metadata.setContentLength(is.available());
+            // 指定该Object被下载时的网页的缓存行为
+            metadata.setCacheControl("no-cache");
+            // 指定该Object下设置Header
+            metadata.setHeader("Pragma", "no-cache");
+            // 指定该Object被下载时的内容编码格式
+            metadata.setContentEncoding("utf-8");
+            // 文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,
+            // 如果没有扩展名则填默认值application/octet-stream
+            metadata.setContentType(getContentType(fileName));
+            // 指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)
+            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte");
+            //上传文件到OSS时需要指定包含文件后缀在内的完整路径如ossPath="upload/2023/01/11/cake.jpg"
+            PutObjectResult putResult = ossClient.putObject(bucketName, ossPath, is, metadata);
+            // 解析结果
+            String resultStr = putResult.getETag();
+            log.info("唯一MD5数字签名:" + resultStr);
+            //上传文件后相对路径如"upload/2023/01/11/cake.jpg"
+            String path = ossPath;
+            return path;
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
+            return null;
+        }
+    }
+
+
+    /**
+     * 下载文件到本地
+     *
+     * @param ossClient     oss连接
+     * @param bucketName    存储空间
+     * @param key           Bucket下的文件的路径名+文件名 如:"upload/2023/01/11/cake.jpg"
+     * @param localFilePath 下载本地文件绝对路径如"C:\Users\Administrator\Desktop\oss-download\xxx.pdf"
+     */
+    public static void downloadFileOss(OSS ossClient, String bucketName, String key, String localFilePath) {
+        try {
+            //创建本地文件
+            File file = new File(localFilePath);
+            GetObjectRequest objectRequest = new GetObjectRequest(bucketName, key);
+            //下载OSS文件到本地文件,若指定的本地文件存在则覆盖,否则新建
+            ossClient.getObject(objectRequest, file);
+            log.info("下载文件到本地成功");
+        } catch (OSSException e) {
+            e.printStackTrace();
+        } catch (ClientException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    /**
+     * 获取上传文件对象
+     * 备注:最重要的是获取上传文件的输出流InputStream
+     *
+     * @param ossClient  oss连接
+     * @param bucketName 存储空间
+     * @param key        Bucket下的文件的路径名+文件名 如:"upload/2023/01/11/cake.jpg"
+     * @return
+     */
+    public static OSSObject getObject(OSS ossClient, String bucketName, String key) {
+        OSSObject object = null;
+        try {
+            object = ossClient.getObject(bucketName, key);
+            //文件大小
+            long fileSize = object.getObjectMetadata().getContentLength();
+            //文件相对路径
+            String ossPath = object.getKey();
+            //文件输入流
+            InputStream is = object.getObjectContent();
+            log.info("success to getObject,fileSize:" + fileSize + "\nossPath:" + ossPath + "\ninputStream:" + is);
+        } catch (OSSException e) {
+            e.printStackTrace();
+        } catch (ClientException e) {
+            e.printStackTrace();
+        }
+        return object;
+    }
+
+
+    /**
+     * 获取上传文件url
+     *
+     * @param ossClient  oss连接
+     * @param bucketName bucketName
+     * @param key        文件全路径
+     * @return
+     */
+    public static String getUrl(OSS ossClient, String bucketName, String key) {
+        //设置URl过期时间为99年:3600L*1000*24*365*99
+        Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24 * 365 * 99);
+        GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, key);
+        generatePresignedUrlRequest.setExpiration(expiration);
+        URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
+        String returnUrl = url.toString();
+        return returnUrl;
+    }
+
+
+    public static void downloadByFileName(String objectName) {
+        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。关于其他Region对应的Endpoint信息,请参见访问域名和数据中心。
+//        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
+        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
+//        String accessKeyId = "yourAccessKeyId";
+//        String accessKeySecret = "yourAccessKeySecret";
+        // 填写Bucket名称,例如examplebucket。
+//        String bucketName = "examplebucket";
+        // 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
+//        String objectName = "exampledir/exampleobject.txt";
+
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        try {
+            // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
+            OSSObject ossObject = ossClient.getObject(bucketName, objectName);
+            // 读取文件内容。
+            System.out.println("Object content:");
+            BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
+            while (true) {
+                String line = reader.readLine();
+                if (line == null) break;
+
+                System.out.println("\n" + line);
+            }
+            // 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
+            reader.close();
+            // ossObject对象使用完毕后必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
+            ossObject.close();
+
+        } 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 (Throwable 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的完整key下载
+     *
+     * @param response   response
+     * @param objectName oss完整的key,例子:fj_wechat_web/public/postman.txt
+     */
+    public static void downloadByObjectName(HttpServletResponse response, String objectName) {
+//        String endpointStr = "http://" + endpoint + ".aliyuncs.com";
+        String endpointStr = "http://" + endpoint;
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        OSSObject ossObject = ossClient.getObject(bucketName, objectName);
+
+        BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
+
+        try {
+            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
+            //通知浏览器以附件形式下载
+            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("postman.txt", "utf-8"));
+
+            byte[] car = new byte[1024];
+            int len;
+            while ((len = in.read(car)) != -1) {
+                out.write(car, 0, len);
+            }
+            out.flush();
+            out.close();
+            in.close();
+            ossClient.shutdown();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 通过oss的完整key下载
+     *
+     * @param response response
+     * @param url      全路径的url地址
+     */
+    public static void downloadByUrl(HttpServletResponse response, String url) {
+        downloadByFileName(response, url);
+    }
+
+    /**
+     * 判断文件是否存在
+     *
+     * @param fileName 文件名:postman.txt
+     * @return true文件存在,false文件不存在
+     */
+    public boolean isExitByFileName(String fileName) {
+//        String endpointStr = "http://" + endpoint + ".aliyuncs.com";
+        String endpointStr = "http://" + endpoint;
+        OSS ossClient = new OSSClientBuilder().build(endpointStr, accessKeyId, accessKeySecret);
+        return ossClient.doesObjectExist(bucketName, BASE_DIR + fileName);
+    }
+
+    /**
+     * 判断文件是否存在
+     *
+     * @param url 能直接访问的完整url
+     * @return true文件存在,false文件不存在
+     */
+    public boolean isExitByUrl(String url) {
+        return isExitByFileName(getFileNameByUrl(url));
+    }
+
+    /**
+     * 通过url获取文件名
+     *
+     * @param url 能够直接访问的url
+     * @return 文件名:postman.txt
+     */
+    public static String getFileNameByUrl(String url) {
+        String[] split = url.split("/");
+        return split[split.length - 1];
+    }
+
+
+    // 测试
+    public static void main(String[] args) throws FileNotFoundException {
+        //阿里云OSS账号自行到阿里云官网申请
+        String ossEndpoint = "XXX";
+        String accessId = "XXX";
+        String accessKey = "XXX";
+        String bucketName = "test";
+        // 初始化OSSClient
+//        OSS ossClient = AliyunOSSClientUtil.getOssClient(ossEndpoint, accessId, accessKey);
+        OSS ossClient = FileUtils.getOssClient(ossEndpoint, accessId, accessKey);
+
+
+        //测试创建多级目录
+        /*String tmpDir = "upload/2023/01/11/";
+        String folder = createFolder(ossClient, bucketName, tmpDir);
+        System.out.println("folder:"+folder);*/
+
+
+        //测试删除文件
+        /*String key="upload/2023/01/11/xxx.pdf";
+        deleteObject(ossClient,bucketName,key);*/
+
+
+        //测试上传文件
+        /*String pathAndname = "C:\\Users\\Administrator\\Desktop\\测试文件上传\\xxx.pdf";
+        File file = new File(pathAndname);
+        //原始文件名:带后缀
+        String oldfilename = file.getName();
+        //新文件名:带后缀
+        String newfilename = "9065df0f3ab72419b36d2dec088e11d6.pdf";//可以自行生成随机唯一文件名
+        String newpath = "C:\\Users\\Administrator\\Desktop\\upload\\2023\\01\\11\\";
+        String ossPath = newpath + newfilename;
+        InputStream is = new FileInputStream(file);
+        String absolutePath = uploadFileOss(ossClient, bucketName, ossPath, is, newfilename);
+        System.out.println("absolutePath:"+absolutePath);*/
+
+
+        //测试获取文件url
+        /*String key="upload/2023/01/11/9065df0f3ab72419b36d2dec088e11d6.pdf";
+        String url = getUrl(ossClient, bucketName, key);
+        System.out.println("url:"+url);*/
+
+
+        //测试获取上传对象
+        /*String key = "upload/2023/01/11/9065df0f3ab72419b36d2dec088e11d6.pdf";
+        getObject(ossClient, bucketName, key);*/
+
+
+        //测试下载文件到本地
+        /*String key = "upload/2023/01/11/9065df0f3ab72419b36d2dec088e11d6.pdf";
+        String localFilePath = "C:\\Users\\Administrator\\Desktop\\oss-download\\xxx.pdf";
+        downloadFileOss(ossClient, bucketName, key, localFilePath);*/
+    }
+
+}

+ 5 - 0
sckw-modules/sckw-file/src/main/resouces/banner.txt

@@ -0,0 +1,5 @@
+====================================================================================================================
+
+                    欢迎使用 [sckw-file] 开物供应链服务平台-文件服务 - Powered By https://www.xxxx.com
+
+====================================================================================================================

+ 82 - 0
sckw-modules/sckw-file/src/main/resouces/bootstrap-dev.yml

@@ -0,0 +1,82 @@
+spring:
+  cloud:
+    nacos:
+      discovery:
+        # 服务注册地址
+        server-addr: 127.0.0.1:8848
+        # 命名空间
+        namespace: sckw-service-platform-dev
+        # 共享配置
+        group: sckw-service-platform
+      config:
+        # 配置中心地址
+        server-addr: 127.0.0.1:8848
+        # 配置文件格式
+        file-extension: yaml
+        # 命名空间
+        namespace: sckw-service-platform-dev
+        # 共享配置
+        group: sckw-service-platform
+    function:
+      definition: sckwSms;sckwMessage
+    stream:
+      bindings:
+        sckwSms-in-0:
+          destination: sckw-sms
+          content-type: application/json
+          default-binder: defaultRabbit
+          group: sckw
+        sckwSms-out-0:
+          destination: sckw-sms
+          content-type: application/json
+          default-binder: defaultRabbit
+          group: sckw
+        sckwMessage-in-0:
+          destination: sckw-message
+          content-type: application/json
+          default-binder: defaultRabbit
+          group: sckw
+        sckwMessage-out-0:
+          destination: sckw-message
+          content-type: application/json
+          default-binder: defaultRabbit
+          group: sckw
+      binders:
+        defaultRabbit:
+          type: rabbit
+          environment:
+            spring:
+              rabbitmq:
+                virtual-host: /
+                host: 39.104.134.114
+                port: 5672
+                username: wph
+                password: Yy123...
+#限制上传文件大小
+  servlet:
+    multipart:
+      max-file-size: 100MB
+      max-request-size: 100MB
+
+
+# dubbo
+dubbo:
+  application:
+    # 此处没有延用spring.application.name是因为当前项目本身也会注册到nacos中,如果dubbo也延用相同的名称,在nacos服务里会看到注册的producer-server服务数为2
+    name: file-dubbo-server
+  protocol:
+    name: dubbo
+    port: -1
+  registry:
+    # 配置dubbo的注册中心为nacos
+    address: nacos://${spring.cloud.nacos.discovery.server-addr}
+    group: ${spring.cloud.nacos.config.group}
+    protocol: nacos
+    #use-as-config-center: false
+    #use-as-metadata-center: false
+aliyun:
+  oss:
+    endpoint: oss-cn-chengdu.aliyuncs.com
+    accessKeyId: LTAI5tPEbubCGq5Rdwygbz4Q
+    secret: 7mQLWMaBJeZPRV1SRGogctYGXwppjQ
+    bucket: kaiwu-saas

+ 27 - 0
sckw-modules/sckw-file/src/main/resouces/bootstrap.yml

@@ -0,0 +1,27 @@
+server:
+  port: 10050
+
+spring:
+  application:
+    name: sckw-file
+  profiles:
+    active: ${DEPLOY_MODE:dev}
+  main:
+    allow-bean-definition-overriding: true
+# Spring
+dubbo:
+  application:
+    name: file-dubbo-server
+    # 该配置在producer-server中是没有的,但是在consumer这里要配置一下
+    # 如果不配置这个QOS的端口,它会延用dubbo自动生成的端口,在启动的时候,QOS注册就会提示该端口已经被使用的错误
+    # 虽然启动时有打印端口已经被使用的错误,但是依旧可以正常启动服务,并且dubbo也可以正常调用,但是为了解决启动报错还是加上这个端口
+    # 这个也是apache官方给出的解决方案,这个端口不能给-1,它不会自动找到一个可用的端口,给-1会报错,端口1-65535自己选择一个
+    qos-port: 3334
+  protocol:
+    name: dubbo
+    # port为-1表示自动找一个可用的端口
+    port: -1
+  registry:
+    address: nacos://${spring.cloud.nacos.discovery.server-addr}
+    group: ${spring.cloud.nacos.config.group}
+    protocol: nacos