From fd8c0dfd2cf590b5bded1b23ce222ba53c9cbeb4 Mon Sep 17 00:00:00 2001
From: huliguo <2023611923@qq.com>
Date: 星期四, 17 七月 2025 11:46:00 +0800
Subject: [PATCH] 增加oss

---
 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/OSSUtil.java |  484 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 ruoyi-common/pom.xml                                                |    5 
 2 files changed, 489 insertions(+), 0 deletions(-)

diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index 12920cc..0e7407f 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -168,6 +168,11 @@
             <artifactId>easypoi-annotation</artifactId>
             <version>4.4.0</version>
         </dependency>
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>3.15.1</version>
+        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/OSSUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/OSSUtil.java
new file mode 100644
index 0000000..2937312
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/OSSUtil.java
@@ -0,0 +1,484 @@
+package com.ruoyi.common.utils.file;
+
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.model.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpMethod;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.multipart.MultipartFile;
+ 
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.security.SecureRandom;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+ 
+@Slf4j
+@Component
+public class OSSUtil {
+ 
+    private static final String endpoint = "oss-cn-chengdu.aliyuncs.com";
+    private static final String accessKeyId = "LTAI5tHYSpwifc3rqLYJoETo";
+    private static final String accessKeySecret = "xrDyQ89h8P0alWW7rrLIW2D2rt7Eig";
+    private static final String bucketName = "yizhengcheng";
+    private static final String FOLDER = "https://yizhengcheng.oss-cn-chengdu.aliyuncs.com/";
+
+    /**
+     * 获取oss
+     *
+     * @return
+     */
+    public static OSS getOSSClient() {
+        return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+    }
+ 
+    /**
+     * 上传图片
+     *
+     * @param url
+     * @throws
+     */
+    public void uploadImg2Oss(String url) throws IOException {
+        File fileOnServer = new File(url);
+        FileInputStream fin;
+        try {
+            fin = new FileInputStream(fileOnServer);
+            String[] split = url.split("/");
+            this.uploadFile2OSS(fin, split[split.length - 1]);
+        } catch (FileNotFoundException e) {
+            throw new IOException("图片上传失败");
+        }
+    }
+ 
+    public String uploadImg2Oss(MultipartFile file) throws IOException {
+        if (file.getSize() > 5 * 1024 * 1024) {
+            throw new IOException("上传图片大小不能超过5M!");
+        }
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        // 获取文件名
+        String originalFilename = file.getOriginalFilename();
+        // 获取文件后缀名
+        String suffixName  = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
+        // 最后上传生成的文件名
+        String finalFileName = System.currentTimeMillis() + "" + new SecureRandom().nextInt(0x0400) + suffixName;
+        // oss中的文件夹名
+        String objectName = sdf.format(new Date()) + "/" + finalFileName;
+ 
+//        name = DateUtils.dateStr(new Date(), "yyyy/MM/dd") + "/" + System.currentTimeMillis() + substring;
+        try {
+            InputStream inputStream = file.getInputStream();
+            this.uploadFile2OSS(inputStream, objectName);
+            return objectName;
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new IOException("图片上传失败");
+        }
+    }
+ 
+    /**
+     * 获得图片路径
+     *
+     * @param fileUrl
+     * @return
+     */
+    public String getImgUrl(String fileUrl) {
+        System.out.println(fileUrl);
+        if (!StringUtils.isEmpty(fileUrl)) {
+//            String[] split = fileUrl.split("/");
+            return this.getUrl(this.FOLDER + fileUrl);
+        }
+        return "";
+    }
+ 
+    /**
+     * 上传到OSS服务器 如果同名文件会覆盖服务器上的
+     *
+     * @param instream 文件流
+     * @param fileName 文件名称 包括后缀名
+     * @return 出错返回"" ,唯一MD5数字签名
+     */
+    public String uploadFile2OSS(InputStream instream, String fileName) {
+ 
+        String ret = "";
+        try {
+            OSS ossClient = getOSSClient();
+            // 创建上传Object的Metadata
+            ObjectMetadata objectMetadata = new ObjectMetadata();
+            objectMetadata.setContentLength(instream.available());
+            objectMetadata.setCacheControl("no-cache");
+            objectMetadata.setContentType(getContentType(fileName.substring(fileName.lastIndexOf("."))));
+            objectMetadata.setHeader("Pragma", "no-cache");
+//            objectMetadata.setContentDisposition("inline;filename=" + fileName);
+            // 上传文件
+            PutObjectResult putResult = ossClient.putObject(bucketName, FOLDER + fileName, instream, objectMetadata);
+            ret = putResult.getETag();
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            try {
+                if (instream != null) {
+                    instream.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return ret;
+    }
+ 
+    /**
+     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
+     *
+     * @param filenameExtension 文件名
+     * @return 文件的contentType
+     */
+    public static final String getContentType(String filenameExtension) {
+ 
+        if (filenameExtension.equalsIgnoreCase(".bmp")) {
+            return "application/x-bmp";
+        }
+        if (filenameExtension.equalsIgnoreCase(".gif")) {
+            return "image/gif";
+        }
+        if (filenameExtension.equalsIgnoreCase(".jpeg") ||
+                filenameExtension.equalsIgnoreCase(".jpg") ||
+                filenameExtension.equalsIgnoreCase(".png")) {
+            return "image/jpg";
+        }
+        if (filenameExtension.equalsIgnoreCase(".html")) {
+            return "text/html";
+        }
+        if (filenameExtension.equalsIgnoreCase(".txt")) {
+            return "text/plain";
+        }
+        if (filenameExtension.equalsIgnoreCase(".vsd")) {
+            return "application/vnd.visio";
+        }
+        if (filenameExtension.equalsIgnoreCase(".pptx") ||
+                filenameExtension.equalsIgnoreCase(".ppt")) {
+            return "application/vnd.ms-powerpoint";
+        }
+        if (filenameExtension.equalsIgnoreCase(".docx") ||
+                filenameExtension.equalsIgnoreCase(".doc")) {
+            return "application/msword";
+        }
+        if (filenameExtension.equalsIgnoreCase(".xla") ||
+                filenameExtension.equalsIgnoreCase(".xlc") ||
+                filenameExtension.equalsIgnoreCase(".xlm") ||
+                filenameExtension.equalsIgnoreCase(".xls") ||
+                filenameExtension.equalsIgnoreCase(".xlt") ||
+                filenameExtension.equalsIgnoreCase(".xlw")) {
+            return "application/vnd.ms-excel";
+        }
+        if (filenameExtension.equalsIgnoreCase(".xlsx")) {
+            return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
+        }
+        if (filenameExtension.equalsIgnoreCase(".xml")) {
+            return "text/xml";
+        }
+        if (filenameExtension.equalsIgnoreCase(".pdf")) {
+            return "application/pdf";
+        }
+        if (filenameExtension.equalsIgnoreCase(".zip")) {
+            return "application/zip";
+        }
+        if (filenameExtension.equalsIgnoreCase(".tar")) {
+            return "application/x-tar";
+        }
+        if (filenameExtension.equalsIgnoreCase(".avi")) {
+            return "video/avi";
+        }
+        if (filenameExtension.equalsIgnoreCase(".mp4")) {
+            return "video/mpeg4";
+        }
+        if (filenameExtension.equalsIgnoreCase(".mp3")) {
+            return "audio/mp3";
+        }
+        if (filenameExtension.equalsIgnoreCase(".mp2")) {
+            return "audio/mp2";
+        }
+        // 默认下载
+//        return "application/octet-stream";
+        return "image/jpg";
+    }
+ 
+ 
+    /**
+     * 获得url链接
+     *
+     * @param key
+     * @return
+     */
+    public String getUrl(String key) {
+        // 设置URL过期时间为10年 3600l* 1000*24*365*10
+        OSS ossClient = getOSSClient();
+        Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);
+        // 生成URL
+        URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
+        System.out.println("url: "+url);
+        if (url != null) {
+            String host = "https://" + url.getHost() + url.getPath();
+            System.out.println("host: "+host);
+            // http://wxcall-xiaobanben.oss-cn-shenzhen.aliyuncs.com/image/20220129/1643469496754508.jpg
+            return host;
+        }
+        return "";
+    }
+ 
+    /**
+     * 获取文件夹
+     *
+     * @param fileName
+     * @return
+     */
+    public List<String> fileFolder(String fileName) {
+        // 创建OSSClient实例。
+        OSS ossClient = getOSSClient();
+        // 构造ListObjectsRequest请求。
+        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
+ 
+        // 设置正斜线(/)为文件夹的分隔符。
+        listObjectsRequest.setDelimiter("/");
+        // 设置prefix参数来获取fun目录下的所有文件。
+        if (!StringUtils.isEmpty(fileName)) {
+            listObjectsRequest.setPrefix(fileName + "/");
+        }
+        // 列出文件
+        ObjectListing listing = ossClient.listObjects(listObjectsRequest);
+        // 遍历所有commonPrefix
+        List<String> list = new ArrayList<>();
+        for (String commonPrefix : listing.getCommonPrefixes()) {
+            String newCommonPrefix = commonPrefix.substring(0, commonPrefix.length() - 1);
+            String[] s = newCommonPrefix.split("/");
+            if (!StringUtils.isEmpty(fileName)) {
+                list.add(s[s.length - 1]);
+            } else {
+                list.add(s[0]);
+            }
+        }
+        // 关闭OSSClient
+        ossClient.shutdown();
+        return list;
+    }
+ 
+    /**
+     * 列举文件下所有的文件url信息
+     */
+    public ObjectListing listFile2(String fileHost, String nextMarker) {
+        // 创建OSSClient实例。
+        OSS ossClient = getOSSClient();
+ 
+        // 构造ListObjectsRequest请求。
+        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
+ 
+        // 设置正斜线(/)为文件夹的分隔符。
+        listObjectsRequest.setDelimiter("/");
+        // 列出fun目录下的所有文件和文件夹。
+        listObjectsRequest.setPrefix(fileHost + "/");
+ 
+        ObjectListing listing = ossClient.listObjects(listObjectsRequest);
+ 
+        // 遍历所有文件。
+        System.out.println("Objects:");
+        // objectSummaries的列表中给出的是fun目录下的文件。
+        for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
+            System.out.println(objectSummary.getKey());
+        }
+ 
+        // 遍历所有commonPrefix。
+        System.out.println("\nCommonPrefixes:");
+        // commonPrefixs列表中显示的是fun目录下的所有子文件夹。由于fun/movie/001.avi和fun/movie/007.avi属于fun文件夹下的movie目录,因此这两个文件未在列表中。
+        for (String commonPrefix : listing.getCommonPrefixes()) {
+            System.out.println(commonPrefix);
+        }
+ 
+        // 关闭OSSClient。
+        ossClient.shutdown();
+        return listing;
+    }
+ 
+    /**
+     * 列举文件下所有的文件url信息
+     */
+    public List<String> listFile(String fileHost, String nextMarker) {
+        // 创建OSSClient实例。
+        OSS ossClient = getOSSClient();
+        // 构造ListObjectsRequest请求
+        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
+ 
+        // 设置prefix参数来获取fun目录下的所有文件。
+        listObjectsRequest.setPrefix(fileHost + "/");
+        listObjectsRequest.setMarker(nextMarker);
+ 
+        // 列出文件。
+        ObjectListing listing = ossClient.listObjects(listObjectsRequest);
+        // 遍历所有文件。
+        List<String> list = new ArrayList<>();
+        for (int i = 0; i < listing.getObjectSummaries().size(); i++) {
+            String FILE_URL = "http://" + bucketName + "." + endpoint + "/" + listing.getObjectSummaries().get(i).getKey();
+            list.add(FILE_URL);
+        }
+        // 关闭OSSClient。
+        ossClient.shutdown();
+ 
+ 
+//        ObjectListing objectListing = null;
+//        int total = 0;
+//        HashMap<Integer, String> markerMap = new HashMap<>();
+//        try {
+//            ObjectListing objectListing2 = null;
+//            do {
+//                String nextMarker2 = objectListing2 != null ? objectListing2.getNextMarker() : null;
+//                ListObjectsRequest listObjectsRequest2 = new ListObjectsRequest(bucketName).withMarker(nextMarker2).withMaxKeys(100);
+//                listObjectsRequest2.setPrefix(fileHost + "/");
+//                objectListing2 = ossClient.listObjects(listObjectsRequest2);
+//                total += (objectListing2 != null && objectListing2.getObjectSummaries() != null ? objectListing2.getObjectSummaries().size() : 0);
+//                markerMap.put(markerMap.size() + 1, nextMarker2);
+//            } while (objectListing2 != null && !StringUtils.isEmpty(objectListing2.getNextMarker()));
+//
+//            ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName).withMarker(nextMarker).withMaxKeys(100);
+//
+//            listObjectsRequest.setPrefix(fileHost + "/");
+//
+//            objectListing = ossClient.listObjects(listObjectsRequest);
+//            for (int i = 0; i < objectListing.getObjectSummaries().size(); i++) {
+//                String FILE_URL = "https://" + bucketName + "." + endpoint + "/" + objectListing.getObjectSummaries().get(i).getKey();
+//                list.add(FILE_URL);
+//            }
+//
+//        } catch (Exception e) {
+//
+//        } finally {
+//            // 关闭client
+//            ossClient.shutdown();
+//        }
+ 
+        return list;
+    }
+ 
+    /**
+     * 删除文件
+     * objectName key 地址
+     *
+     * @param filePath
+     */
+    public Boolean delFile(String filePath) {
+        // 创建OSSClient实例。
+        OSS ossClient = getOSSClient();
+        // 删除Object.
+        boolean exist = ossClient.doesObjectExist(bucketName, filePath);
+        if (!exist) {
+            return false;
+        }
+        ossClient.deleteObject(bucketName, filePath);
+        ossClient.shutdown();
+        return true;
+    }
+ 
+    /**
+     * 批量删除
+     *
+     * @param keys
+     */
+    public Boolean delFileList(List<String> keys) {
+        // 创建OSSClient实例。
+        OSS ossClient = getOSSClient();
+        try {
+            // 删除文件。
+            DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(keys));
+            List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        } finally {
+            ossClient.shutdown();
+        }
+        return true;
+ 
+    }
+ 
+    /**
+     * 创建文件夹
+     *
+     * @param folder
+     * @return
+     */
+    public String createFolder(String folder) {
+        // 创建OSSClient实例。
+        OSS ossClient = getOSSClient();
+        // 文件夹名
+        final String keySuffixWithSlash = folder;
+        // 判断文件夹是否存在,不存在则创建
+        if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) {
+            // 创建文件夹
+            ossClient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));
+            // 得到文件夹名
+            OSSObject object = ossClient.getObject(bucketName, keySuffixWithSlash);
+            String fileDir = object.getKey();
+            ossClient.shutdown();
+            return fileDir;
+        }
+        return keySuffixWithSlash;
+    }
+ 
+    /**
+     * 通过文件名下载文件
+     *
+     * @param objectName    要下载的文件名
+     * @param localFileName 本地要创建的文件名
+     */
+    public void downloadFile(HttpServletResponse response, String objectName, String localFileName) throws Exception {
+        // 创建OSSClient实例。
+        OSS ossClient = getOSSClient();
+        try {
+            // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
+            OSSObject ossObject = ossClient.getObject(bucketName, objectName);
+            // 读去Object内容  返回
+            BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
+ 
+            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
+            //通知浏览器以附件形式下载
+            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(objectName, "utf-8"));
+            //BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(new File("f:\\a.txt")));
+            byte[] car = new byte[1024];
+            int L = 0;
+            while ((L = in.read(car)) != -1) {
+                out.write(car, 0, L);
+ 
+            }
+            if (out != null) {
+                out.flush();
+                out.close();
+            }
+            if (in != null) {
+                in.close();
+            }
+ 
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            // 关闭OSSClient。
+            ossClient.shutdown();
+        }
+    }
+ 
+    public String onlineSee(String key) {
+        // 创建OSSClient实例。
+        OSS ossClient = getOSSClient();
+        // 设置URL过期时间为1小时
+        Date expiration = new Date(new Date().getTime() + 3600 * 1000);
+        // 临时地址
+        URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
+        // 关闭OSSClient。
+        ossClient.shutdown();
+        return url.toString();
+    }
+ 
+
+}
\ No newline at end of file

--
Gitblit v1.7.1