Jelajahi Sumber

update OSS模块 更新 阿里云 腾讯云 相关代码 重构部分代码结构

疯狂的狮子li 3 tahun lalu
induk
melakukan
7114fc2720

+ 39 - 0
ruoyi-admin/src/main/resources/application-dev.yml

@@ -137,3 +137,42 @@ management:
   endpoint:
     logfile:
       external-file: ./logs/sys-console.log
+
+--- # OSS 云存储(界面 <参数设置> 可切换)
+cloud-storage:
+  # minio配置
+  minio:
+    endpoint: http://localhost:9000
+    accessKey: ruoyi
+    secretKey: ruoyi123
+    bucketName: ruoyi
+  # 七牛云配置
+  qiniu:
+    domain: http://XXX.XXXX.com
+    prefix:
+    accessKey: XXXXXXXXXXXXXXX
+    secretKey: XXXXXXXXXXXXXXX
+    bucketName: ruoyi
+    isHttps: false
+    # z0 华东  z1 华北  z2 华南  na0 北美  as0 东南亚
+    # 不填为自动获取(性能低 易出问题)
+    region: z0
+  # 阿里云配置
+  aliyun:
+    endpoint: http://oss-cn-beijing.aliyuncs.com
+    prefix:
+    accessKeyId: XXXXXXXXXXXXXXX
+    accessKeySecret: XXXXXXXXXXXXXXX
+    bucketName: ruoyi
+  # 腾讯云配置
+  qcloud:
+    endpoint: http://cos.ap-beijing.myqcloud.com
+    prefix:
+    secretId: XXXXXXXXXXXXXXX
+    secretKey: XXXXXXXXXXXXXXX
+    # 腾讯云bucket名规则 格式为 BucketName-APPID 此处填写的存储桶名称必须为此格式
+    bucketName: ruoyi-1250000000
+    isHttps: false
+    # 地域名参考官方文档
+    # https://cloud.tencent.com/document/product/436/6224
+    region: ap-beijing

+ 39 - 0
ruoyi-admin/src/main/resources/application-prod.yml

@@ -137,3 +137,42 @@ management:
   endpoint:
     logfile:
       external-file: ./logs/sys-console.log
+
+--- # OSS 云存储(界面 <参数设置> 可切换)
+cloud-storage:
+  # minio配置
+  minio:
+    endpoint: http://172.30.0.54:9000
+    accessKey: ruoyi
+    secretKey: ruoyi123
+    bucketName: ruoyi
+  # 七牛云配置
+  qiniu:
+    domain: http://XXX.XXXX.com
+    prefix:
+    accessKey: XXXXXXXXXXXXXXX
+    secretKey: XXXXXXXXXXXXXXX
+    bucketName: ruoyi
+    isHttps: false
+    # z0 华东  z1 华北  z2 华南  na0 北美  as0 东南亚
+    # 不填为自动获取(性能低 易出问题)
+    region: z0
+  # 阿里云配置
+  aliyun:
+    endpoint: http://oss-cn-beijing.aliyuncs.com
+    prefix:
+    accessKeyId: XXXXXXXXXXXXXXX
+    accessKeySecret: XXXXXXXXXXXXXXX
+    bucketName: ruoyi
+  # 腾讯云配置
+  qcloud:
+    endpoint: http://cos.ap-beijing.myqcloud.com
+    prefix:
+    secretId: XXXXXXXXXXXXXXX
+    secretKey: XXXXXXXXXXXXXXX
+    # 腾讯云bucket名规则 格式为 BucketName-APPID 此处填写的存储桶名称必须为此格式
+    bucketName: ruoyi-1250000000
+    isHttps: false
+    # 地域名参考官方文档
+    # https://cloud.tencent.com/document/product/436/6224
+    region: ap-beijing

+ 2 - 1
ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/CloudServiceEnumd.java

@@ -2,6 +2,7 @@ package com.ruoyi.oss.enumd;
 
 import com.ruoyi.oss.service.impl.AliyunCloudStorageServiceImpl;
 import com.ruoyi.oss.service.impl.MinioCloudStorageServiceImpl;
+import com.ruoyi.oss.service.impl.QcloudCloudStorageServiceImpl;
 import com.ruoyi.oss.service.impl.QiniuCloudStorageServiceImpl;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
@@ -28,7 +29,7 @@ public enum CloudServiceEnumd {
 	/**
 	 * 腾讯云
 	 */
-	QCLOUD("qcloud", QiniuCloudStorageServiceImpl.class),
+	QCLOUD("qcloud", QcloudCloudStorageServiceImpl.class),
 
 	/**
 	 * minio

+ 7 - 7
ruoyi-oss/src/main/java/com/ruoyi/oss/properties/CloudStorageProperties.java

@@ -102,18 +102,13 @@ public class CloudStorageProperties {
 		/**
 		 * 腾讯云绑定的域名
 		 */
-		private String domain;
+		private String endpoint;
 
 		/**
 		 * 腾讯云路径前缀
 		 */
 		private String prefix;
 
-		/**
-		 * 腾讯云appId
-		 */
-		private String appId;
-
 		/**
 		 * 腾讯云SecretId
 		 */
@@ -129,6 +124,11 @@ public class CloudStorageProperties {
 		 */
 		private String bucketName;
 
+		/**
+		 * 七牛是否使用https
+		 */
+		private Boolean isHttps;
+
 		/**
 		 * 腾讯云COS所属地区
 		 */
@@ -176,7 +176,7 @@ public class CloudStorageProperties {
 		private String region;
 
 		/**
-		 * 七牛存储区域
+		 * 七牛是否使用https
 		 */
 		private Boolean isHttps;
 

+ 4 - 0
ruoyi-oss/src/main/java/com/ruoyi/oss/service/ICloudStorageService.java

@@ -11,6 +11,8 @@ import java.io.InputStream;
  */
 public interface ICloudStorageService {
 
+	void createBucket();
+
 	/**
 	 * 获取服务商类型
 	 */
@@ -67,4 +69,6 @@ public interface ICloudStorageService {
 	 * @return 返回http地址
 	 */
 	UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType);
+
+    String getEndpointLink();
 }

+ 6 - 0
ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractCloudStorageService.java

@@ -18,6 +18,9 @@ import java.util.Date;
  */
 public abstract class AbstractCloudStorageService implements ICloudStorageService, InitializingBean {
 
+	@Override
+	public abstract void createBucket();
+
 	@Override
 	public abstract String getServiceType();
 
@@ -53,4 +56,7 @@ public abstract class AbstractCloudStorageService implements ICloudStorageServic
 
 	@Override
 	public abstract void afterPropertiesSet() throws Exception;
+
+	@Override
+	public abstract String getEndpointLink();
 }

+ 46 - 9
ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunCloudStorageServiceImpl.java

@@ -1,8 +1,13 @@
 package com.ruoyi.oss.service.impl;
 
+import cn.hutool.core.util.StrUtil;
 import com.aliyun.oss.ClientConfiguration;
 import com.aliyun.oss.OSSClient;
 import com.aliyun.oss.common.auth.DefaultCredentialProvider;
+import com.aliyun.oss.model.CannedAccessControlList;
+import com.aliyun.oss.model.CreateBucketRequest;
+import com.aliyun.oss.model.ObjectMetadata;
+import com.aliyun.oss.model.PutObjectRequest;
 import com.ruoyi.oss.entity.UploadResult;
 import com.ruoyi.oss.enumd.CloudServiceEnumd;
 import com.ruoyi.oss.exception.OssException;
@@ -39,11 +44,27 @@ public class AliyunCloudStorageServiceImpl extends AbstractCloudStorageService i
 				this.properties.getAccessKeyId(),
 				this.properties.getAccessKeySecret());
 			client = new OSSClient(this.properties.getEndpoint(), credentialProvider, configuration);
+			createBucket();
 		} catch (Exception e) {
 			throw new IllegalArgumentException("阿里云存储配置错误! 请检查系统配置!");
 		}
 	}
 
+	@Override
+	public void createBucket() {
+		try {
+			String bucketName = properties.getBucketName();
+			if (client.doesBucketExist(bucketName)) {
+				return;
+			}
+			CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
+			createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
+			client.createBucket(createBucketRequest);
+		} catch (Exception e) {
+			throw new OssException("创建Bucket失败, 请核对阿里云配置信息");
+		}
+	}
+
 	@Override
 	public String getServiceType() {
 		return CloudServiceEnumd.ALIYUN.getValue();
@@ -57,35 +78,51 @@ public class AliyunCloudStorageServiceImpl extends AbstractCloudStorageService i
 	@Override
 	public UploadResult upload(InputStream inputStream, String path, String contentType) {
 		try {
-			client.putObject(this.properties.getBucketName(), path, inputStream);
+			ObjectMetadata metadata = new ObjectMetadata();
+			metadata.setContentType(contentType);
+			client.putObject(new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata));
 		} catch (Exception e) {
-			throw new OssException("上传文件失败,请检查配置信息");
+			throw new OssException("上传文件失败,请检查阿里云配置信息");
 		}
-		return new UploadResult().setUrl(properties.getEndpoint() + "/" + path).setFilename(path);
+		return new UploadResult().setUrl(getEndpointLink() + "/" + path).setFilename(path);
 	}
 
 	@Override
 	public void delete(String path) {
-		path = path.replace(this.properties.getEndpoint() + "/", "");
+		path = path.replace(getEndpointLink() + "/", "");
 		try {
-			client.deleteObject(this.properties.getBucketName(), path);
+			client.deleteObject(properties.getBucketName(), path);
 		} catch (Exception e) {
-			throw new OssException("上传文件失败,请检查配置信息");
+			throw new OssException("上传文件失败,请检查阿里云配置信息");
 		}
 	}
 
 	@Override
 	public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
-		return upload(data, getPath(this.properties.getPrefix(), suffix), contentType);
+		return upload(data, getPath(properties.getPrefix(), suffix), contentType);
 	}
 
 	@Override
 	public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
-		return upload(inputStream, getPath(this.properties.getPrefix(), suffix), contentType);
+		return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
 	}
 
 	@Override
 	public void afterPropertiesSet() throws Exception {
-		OssFactory.register(getServiceType(),this);
+		OssFactory.register(getServiceType(), this);
+	}
+
+	@Override
+	public String getEndpointLink() {
+		String endpoint = properties.getEndpoint();
+		StringBuilder sb = new StringBuilder(endpoint);
+		if (StrUtil.containsAnyIgnoreCase(endpoint, "http://")) {
+			sb.insert(7, properties.getBucketName() + ".");
+		} else if (StrUtil.containsAnyIgnoreCase(endpoint, "https://")) {
+			sb.insert(8, properties.getBucketName() + ".");
+		} else {
+			throw new OssException("Endpoint配置错误");
+		}
+		return sb.toString();
 	}
 }

+ 24 - 13
ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioCloudStorageServiceImpl.java

@@ -39,18 +39,28 @@ public class MinioCloudStorageServiceImpl extends AbstractCloudStorageService im
 				.endpoint(this.properties.getEndpoint())
 				.credentials(this.properties.getAccessKey(), this.properties.getSecretKey())
 				.build();
-			String bucketName = this.properties.getBucketName();
+			createBucket();
+		} catch (Exception e) {
+			throw new IllegalArgumentException("Minio存储配置错误! 请检查系统配置!");
+		}
+	}
+
+	@Override
+	public void createBucket() {
+		try {
+			String bucketName = properties.getBucketName();
 			boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
-			// 不存在就创建桶
-			if (!exists) {
-				minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
-				minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()
-					.bucket(bucketName)
-					.config(getPolicy(bucketName, PolicyType.READ))
-					.build());
+			if (exists) {
+				return;
 			}
+			// 不存在就创建桶
+			minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
+			minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()
+				.bucket(bucketName)
+				.config(getPolicy(bucketName, PolicyType.READ))
+				.build());
 		} catch (Exception e) {
-			throw new IllegalArgumentException("Minio存储配置错误! 请检查系统配置!");
+			throw new OssException("创建Bucket失败, 请核对Minio配置信息");
 		}
 	}
 
@@ -76,12 +86,12 @@ public class MinioCloudStorageServiceImpl extends AbstractCloudStorageService im
 		} catch (Exception e) {
 			throw new OssException("上传文件失败,请核对Minio配置信息");
 		}
-		return new UploadResult().setUrl(getBaseUrl() + path).setFilename(path);
+		return new UploadResult().setUrl(getEndpointLink() + "/" + path).setFilename(path);
 	}
 
 	@Override
 	public void delete(String path) {
-		path = path.replace(getBaseUrl(), "");
+		path = path.replace(getEndpointLink() + "/", "");
 		try {
 			minioClient.removeObject(RemoveObjectArgs.builder()
 				.bucket(properties.getBucketName())
@@ -107,8 +117,9 @@ public class MinioCloudStorageServiceImpl extends AbstractCloudStorageService im
 		OssFactory.register(getServiceType(), this);
 	}
 
-	private String getBaseUrl() {
-		return properties.getEndpoint() + "/" + properties.getBucketName() + "/";
+	@Override
+	public String getEndpointLink() {
+		return properties.getEndpoint() + "/" + properties.getBucketName();
 	}
 
 	private String getPolicy(String bucketName, PolicyType policyType) {

+ 60 - 20
ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudCloudStorageServiceImpl.java

@@ -1,12 +1,16 @@
 package com.ruoyi.oss.service.impl;
 
+import cn.hutool.core.util.StrUtil;
 import com.qcloud.cos.COSClient;
 import com.qcloud.cos.ClientConfig;
 import com.qcloud.cos.auth.BasicCOSCredentials;
 import com.qcloud.cos.auth.COSCredentials;
+import com.qcloud.cos.http.HttpProtocol;
+import com.qcloud.cos.model.*;
 import com.qcloud.cos.region.Region;
 import com.ruoyi.oss.entity.UploadResult;
 import com.ruoyi.oss.enumd.CloudServiceEnumd;
+import com.ruoyi.oss.exception.OssException;
 import com.ruoyi.oss.factory.OssFactory;
 import com.ruoyi.oss.properties.CloudStorageProperties;
 import com.ruoyi.oss.properties.CloudStorageProperties.QcloudProperties;
@@ -16,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
+import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 
 /**
@@ -41,12 +46,33 @@ public class QcloudCloudStorageServiceImpl extends AbstractCloudStorageService i
 			ClientConfig clientConfig = new ClientConfig();
 			// 设置bucket所在的区域,华南:gz 华北:tj 华东:sh
 			clientConfig.setRegion(new Region(this.properties.getRegion()));
+			if (this.properties.getIsHttps()) {
+				clientConfig.setHttpProtocol(HttpProtocol.https);
+			} else {
+				clientConfig.setHttpProtocol(HttpProtocol.http);
+			}
 			client = new COSClient(credentials, clientConfig);
+			createBucket();
 		} catch (Exception e) {
 			throw new IllegalArgumentException("腾讯云存储配置错误! 请检查系统配置!");
 		}
 	}
 
+	@Override
+	public void createBucket() {
+		try {
+			String bucketName = properties.getBucketName();
+			if (client.doesBucketExist(bucketName)) {
+				return;
+			}
+			CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
+			createBucketRequest.setCannedAcl(CannedAccessControlList.PublicRead);
+			client.createBucket(createBucketRequest);
+		} catch (Exception e) {
+			throw new OssException("创建Bucket失败, 请核对腾讯云配置信息");
+		}
+	}
+
 	@Override
 	public String getServiceType() {
 		return CloudServiceEnumd.QCLOUD.getValue();
@@ -54,43 +80,57 @@ public class QcloudCloudStorageServiceImpl extends AbstractCloudStorageService i
 
 	@Override
 	public UploadResult upload(byte[] data, String path, String contentType) {
-		// 腾讯云必需要以"/"开头
-		if (!path.startsWith("/")) {
-			path = "/" + path;
+		return upload(new ByteArrayInputStream(data), path, contentType);
+	}
+
+	@Override
+	public UploadResult upload(InputStream inputStream, String path, String contentType) {
+		try {
+			ObjectMetadata metadata = new ObjectMetadata();
+			metadata.setContentType(contentType);
+			client.putObject(new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata));
+		} catch (Exception e) {
+			throw new OssException("上传文件失败,请检查腾讯云配置信息");
 		}
-		// 上传到腾讯云
-//        UploadFileRequest request = new UploadFileRequest(config.getQcloudBucketName(), path, data);
-//        String response = client.uploadFile(request);
-//        Map<String, Object> jsonObject = JsonUtils.parseMap(response);
-//        if (Convert.toInt(jsonObject.get("code")) != 0) {
-//            throw new OssException("文件上传失败," + Convert.toStr(jsonObject.get("message")));
-//        }
-		return new UploadResult().setUrl(properties.getDomain() + "/" + path).setFilename(path);
+		return new UploadResult().setUrl(getEndpointLink() + "/" + path).setFilename(path);
 	}
 
 	@Override
 	public void delete(String path) {
-//        path = path.replace(config.getDomain(),"");
-//        DelFileRequest request = new DelFileRequest(config.getBucketName(), path);
-//        String response = client.delFile(request);
-//		Map<String, Object> jsonObject = JsonUtils.parseMap(response);
-//        if (Convert.toInt(jsonObject.get("code")) != 0) {
-//            throw new OssException("文件删除失败," + Convert.toStr(jsonObject.get("message")));
-//        }
+		path = path.replace(getEndpointLink() + "/", "");
+		try {
+			client.deleteObject(new DeleteObjectRequest(properties.getBucketName(), path));
+		} catch (Exception e) {
+			throw new OssException("上传文件失败,请检腾讯云查配置信息");
+		}
 	}
 
 	@Override
 	public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
-		return upload(data, getPath(this.properties.getPrefix(), suffix), contentType);
+		return upload(data, getPath(properties.getPrefix(), suffix), contentType);
 	}
 
 	@Override
 	public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
-		return upload(inputStream, getPath(this.properties.getPrefix(), suffix), contentType);
+		return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
 	}
 
 	@Override
 	public void afterPropertiesSet() throws Exception {
 		OssFactory.register(getServiceType(),this);
 	}
+
+	@Override
+	public String getEndpointLink() {
+		String endpoint = properties.getEndpoint();
+		StringBuilder sb = new StringBuilder(endpoint);
+		if (StrUtil.containsAnyIgnoreCase(endpoint, "http://")) {
+			sb.insert(7, properties.getBucketName() + ".");
+		} else if (StrUtil.containsAnyIgnoreCase(endpoint, "https://")) {
+			sb.insert(8, properties.getBucketName() + ".");
+		} else {
+			throw new OssException("Endpoint配置错误");
+		}
+		return sb.toString();
+	}
 }

+ 28 - 9
ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuCloudStorageServiceImpl.java

@@ -49,17 +49,31 @@ public class QiniuCloudStorageServiceImpl extends AbstractCloudStorageService im
 			Auth auth = Auth.create(
 				this.properties.getAccessKey(),
 				this.properties.getSecretKey());
-			token = auth.uploadToken(this.properties.getBucketName());
+			String bucketName = this.properties.getBucketName();
+			token = auth.uploadToken(bucketName);
 			bucketManager = new BucketManager(auth, config);
 
-			if (!ArrayUtil.contains(bucketManager.buckets(), this.properties.getBucketName())) {
-				bucketManager.createBucket(this.properties.getBucketName(), this.properties.getRegion());
+			if (!ArrayUtil.contains(bucketManager.buckets(), bucketName)) {
+				bucketManager.createBucket(bucketName, this.properties.getRegion());
 			}
 		} catch (Exception e) {
 			throw new IllegalArgumentException("七牛云存储配置错误! 请检查系统配置!");
 		}
 	}
 
+	@Override
+	public void createBucket() {
+		try {
+			String bucketName = properties.getBucketName();
+			if (ArrayUtil.contains(bucketManager.buckets(), bucketName)) {
+				return;
+			}
+			bucketManager.createBucket(bucketName, properties.getRegion());
+		} catch (Exception e) {
+			throw new OssException("创建Bucket失败, 请核对七牛云配置信息");
+		}
+	}
+
 	@Override
 	public String getServiceType() {
 		return CloudServiceEnumd.QINIU.getValue();
@@ -68,21 +82,21 @@ public class QiniuCloudStorageServiceImpl extends AbstractCloudStorageService im
 	@Override
 	public UploadResult upload(byte[] data, String path, String contentType) {
 		try {
-			Response res = uploadManager.put(data, path, token);
+			Response res = uploadManager.put(data, path, token, null, contentType, false);
 			if (!res.isOK()) {
 				throw new RuntimeException("上传七牛出错:" + res.toString());
 			}
 		} catch (Exception e) {
 			throw new OssException("上传文件失败,请核对七牛配置信息");
 		}
-		return new UploadResult().setUrl(properties.getDomain() + "/" + path).setFilename(path);
+		return new UploadResult().setUrl(getEndpointLink() + "/" + path).setFilename(path);
 	}
 
 	@Override
 	public void delete(String path) {
 		try {
-			path = path.replace(this.properties.getDomain() + "/", "");
-			Response res = bucketManager.delete(this.properties.getBucketName(), path);
+			path = path.replace(getEndpointLink() + "/", "");
+			Response res = bucketManager.delete(properties.getBucketName(), path);
 			if (!res.isOK()) {
 				throw new RuntimeException("删除七牛文件出错:" + res.toString());
 			}
@@ -93,12 +107,12 @@ public class QiniuCloudStorageServiceImpl extends AbstractCloudStorageService im
 
 	@Override
 	public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
-		return upload(data, getPath(this.properties.getPrefix(), suffix), contentType);
+		return upload(data, getPath(properties.getPrefix(), suffix), contentType);
 	}
 
 	@Override
 	public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
-		return upload(inputStream, getPath(this.properties.getPrefix(), suffix), contentType);
+		return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
 	}
 
 	@Override
@@ -106,6 +120,11 @@ public class QiniuCloudStorageServiceImpl extends AbstractCloudStorageService im
 		OssFactory.register(getServiceType(),this);
 	}
 
+	@Override
+	public String getEndpointLink() {
+		return properties.getDomain();
+	}
+
 	private Region getRegion(String region) {
 		switch (region) {
 			case "z0":