diff --git a/pom.xml b/pom.xml
index 0abf06a55de05733354f7e017d8e2cee3665ff3d..065550a94d2d2d28e584da571e1b9c218bfb232a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,6 +41,8 @@
1.37.0
1.9.3
4.3.0
+ 3.15.1
+ 5.6.155
@@ -135,6 +137,18 @@
knife4j-openapi3-spring-boot-starter
${knife4j-openapi3.version}
+
+
+ com.aliyun.oss
+ aliyun-sdk-oss
+ ${aliyun.oss.version}
+
+
+
+ com.qcloud
+ cos_api
+ ${tencent.cos.version}
+
diff --git a/springbok-common/src/main/java/cn/code4java/springbok/storage/AliyunStorage.java b/springbok-common/src/main/java/cn/code4java/springbok/storage/AliyunStorage.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c1816f39b71cfc4482e5302c7a520efd7864bcf
--- /dev/null
+++ b/springbok-common/src/main/java/cn/code4java/springbok/storage/AliyunStorage.java
@@ -0,0 +1,76 @@
+package cn.code4java.springbok.storage;
+
+import cn.code4java.springbok.enums.OSSDistrictEnum;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.model.*;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.InputStream;
+
+/**
+ * @ClassName AliyunStorage
+ * @Description: 阿里云OSS
+ * @Author fengwensheng
+ * @Date 2024/03/11
+ * @Version V1.0
+ **/
+@Slf4j
+@Data
+public class AliyunStorage implements Storage {
+
+ private String bucketName = "springbok";
+ private String endpoint = "oss-cn-guangzhou.aliyuncs.com";
+ private String accessKeyId;
+ private String accessKeySecret;
+
+ @Override
+ public void store(InputStream inputStream, String contentType, String keyName, int type) {
+ OSSDistrictEnum ossDistrictEnum = OSSDistrictEnum.getOSSDistrictEnum(type);
+ // 创建bucket
+ createBucket(bucketName);
+ ObjectMetadata objectMetadata = new ObjectMetadata();
+ objectMetadata.setContentType(contentType);
+ PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, ossDistrictEnum.getValue() + "/" + keyName, inputStream, objectMetadata);
+ getOSSClient().putObject(putObjectRequest);
+ }
+
+ @Override
+ public String generateUrl(String keyName, int type) {
+ OSSDistrictEnum ossDistrictEnum = OSSDistrictEnum.getOSSDistrictEnum(type);
+ return "https://" + bucketName + "." + endpoint + "/" + ossDistrictEnum.getValue() + "/" + keyName;
+ }
+
+ /**
+ * 创建bucket
+ */
+ private void createBucket(String bucketName) {
+ OSS ossClient = getOSSClient();
+ try {
+ // 创建存储空间
+ boolean exists = ossClient.doesBucketExist(bucketName);
+ if (!exists) {
+ CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
+ // 设置存储空间读写权限为公共读,默认为私有
+ createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
+ ossClient.createBucket(createBucketRequest);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (ossClient != null) {
+ ossClient.shutdown();
+ }
+ }
+ }
+
+ /**
+ * 创建OSS实例
+ *
+ * @return
+ */
+ private OSS getOSSClient() {
+ return new OSSClientBuilder().build("https://" + endpoint, accessKeyId, accessKeySecret);
+ }
+}
diff --git a/springbok-common/src/main/java/cn/code4java/springbok/storage/LocalStorage.java b/springbok-common/src/main/java/cn/code4java/springbok/storage/LocalStorage.java
index f5efe520f71bc42823ddbaa21ef897929b8c8288..60b443240a6ee57d97d72337f4934e135a4f353d 100644
--- a/springbok-common/src/main/java/cn/code4java/springbok/storage/LocalStorage.java
+++ b/springbok-common/src/main/java/cn/code4java/springbok/storage/LocalStorage.java
@@ -1,6 +1,7 @@
package cn.code4java.springbok.storage;
import cn.code4java.springbok.enums.OSSDistrictEnum;
+import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@@ -18,24 +19,13 @@ import java.nio.file.StandardCopyOption;
* @Version V1.0
**/
@Slf4j
+@Data
public class LocalStorage implements Storage {
private Path rootLocation;
private String address;
private String storagePath;
- public void setStoragePath(String storagePath) {
- this.storagePath = storagePath;
- }
-
- public String getAddress() {
- return address;
- }
-
- public void setAddress(String address) {
- this.address = address;
- }
-
@Override
public void store(InputStream inputStream, String contentType, String keyName, int type) {
try {
diff --git a/springbok-common/src/main/java/cn/code4java/springbok/storage/TencentStorage.java b/springbok-common/src/main/java/cn/code4java/springbok/storage/TencentStorage.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1c6e55cd88611b09daec91287b33e68dd336df7
--- /dev/null
+++ b/springbok-common/src/main/java/cn/code4java/springbok/storage/TencentStorage.java
@@ -0,0 +1,93 @@
+package cn.code4java.springbok.storage;
+
+import cn.code4java.springbok.enums.OSSDistrictEnum;
+import com.qcloud.cos.COSClient;
+import com.qcloud.cos.ClientConfig;
+import com.qcloud.cos.auth.BasicCOSCredentials;
+import com.qcloud.cos.auth.BasicSessionCredentials;
+import com.qcloud.cos.auth.COSCredentials;
+import com.qcloud.cos.http.HttpProtocol;
+import com.qcloud.cos.model.*;
+import com.qcloud.cos.region.Region;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.InputStream;
+
+/**
+ * @ClassName TencentStorage
+ * @Description: 腾讯云COS
+ * @Author fengwensheng
+ * @Date 2024/03/12
+ * @Version V1.0
+ **/
+@Slf4j
+@Data
+public class TencentStorage implements Storage {
+
+ private String bucketName = "springbok";
+ private String endpoint = "ap-guangzhou";
+ private String appId;
+ private String secretId;
+ private String secretKey;
+
+ @Override
+ public void store(InputStream inputStream, String contentType, String keyName, int type) {
+ OSSDistrictEnum ossDistrictEnum = OSSDistrictEnum.getOSSDistrictEnum(type);
+ // 创建bucket
+ createBucket(bucketName);
+ ObjectMetadata objectMetadata = new ObjectMetadata();
+ objectMetadata.setContentType(contentType);
+ PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, ossDistrictEnum.getValue() + "/" + keyName, inputStream, objectMetadata);
+ getCOSClient().putObject(putObjectRequest);
+ }
+
+ @Override
+ public String generateUrl(String keyName, int type) {
+ OSSDistrictEnum ossDistrictEnum = OSSDistrictEnum.getOSSDistrictEnum(type);
+ return "https://" + bucketName + ".cos." + endpoint + ".myqcloud.com/" + ossDistrictEnum.getValue() + "/" + keyName;
+ }
+
+ /**
+ * 创建bucket
+ */
+ private void createBucket(String bucketName) {
+ COSClient cosClient = getCOSClient();
+ try {
+ // 创建存储空间
+ boolean exists = cosClient.doesBucketExist(bucketName);
+ if (!exists) {
+ CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
+ // 设置 bucket 的权限为 Private(私有读写), 其他可选有公有读私有写, 公有读写
+ createBucketRequest.setCannedAcl(CannedAccessControlList.PublicRead);
+ cosClient.createBucket(createBucketRequest);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (cosClient != null) {
+ cosClient.shutdown();
+ }
+ }
+ }
+
+ /**
+ * 创建COS实例
+ *
+ * @return
+ */
+ private COSClient getCOSClient() {
+ // 1 初始化用户身份信息(secretId, secretKey)。
+ COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
+ // 2 设置 bucket 的地域, COS 地域的简称请参见 https://cloud.tencent.com/document/product/436/6224
+ // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
+ Region region = new Region(endpoint);
+ ClientConfig clientConfig = new ClientConfig(region);
+ // 这里建议设置使用 https 协议
+ // 从 5.6.54 版本开始,默认使用了 https
+ clientConfig.setHttpProtocol(HttpProtocol.https);
+ // 3 生成 cos 客户端。
+ COSClient cosClient = new COSClient(cred, clientConfig);
+ return cosClient;
+ }
+}
diff --git a/springbok-core/src/main/resources/application-dev.yml b/springbok-core/src/main/resources/application-dev.yml
index 7a85ffe7171b9ef33aaafc7f1cdc679e7b3816b8..5ce4ce916612f58b7ad1001f15a0c8f5b742ba5f 100644
--- a/springbok-core/src/main/resources/application-dev.yml
+++ b/springbok-core/src/main/resources/application-dev.yml
@@ -101,6 +101,20 @@ springbok:
storagePath: storages
# 返回前端的图片地址
address: http://localhost:9988/image/
+ # 阿里云OSS配置
+ aliyun:
+ # id
+ accessKeyId: xxx
+ # secret
+ accessKeySecret: xxx
+ # 腾讯云COS配置
+ tencent:
+ # appId
+ appId: xxx
+ # secretId
+ secretId: xxx
+ # secretKey
+ secretKey: xxx
api:
security:
# 请求有效时间,单位:s
diff --git a/springbok-system/src/main/java/cn/code4java/springbok/config/StorageAutoConfig.java b/springbok-system/src/main/java/cn/code4java/springbok/config/StorageAutoConfig.java
index 455c28b8c6df60812d1b11444504e6a7a0532fb2..3b7332768f9a189786abb4711da0e5bfb0557c9e 100644
--- a/springbok-system/src/main/java/cn/code4java/springbok/config/StorageAutoConfig.java
+++ b/springbok-system/src/main/java/cn/code4java/springbok/config/StorageAutoConfig.java
@@ -1,8 +1,11 @@
package cn.code4java.springbok.config;
import cn.code4java.springbok.properties.StorageProperties;
+import cn.code4java.springbok.storage.AliyunStorage;
import cn.code4java.springbok.storage.LocalStorage;
import cn.code4java.springbok.storage.StorageService;
+import cn.code4java.springbok.storage.TencentStorage;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -14,6 +17,7 @@ import org.springframework.context.annotation.Configuration;
* @Date 2024/1/8
* @Version V1.0
**/
+@Slf4j
@Configuration
@EnableConfigurationProperties(StorageProperties.class)
public class StorageAutoConfig {
@@ -29,8 +33,13 @@ public class StorageAutoConfig {
StorageService storageService = new StorageService();
String active = this.properties.getActive();
storageService.setActive(active);
+ log.info("当前存储模式为{}", active);
if (active.equals("local")) {
storageService.setStorage(localStorage());
+ } else if (active.equals("aliyun")) {
+ storageService.setStorage(aliyunStorage());
+ } else if (active.equals("tencent")) {
+ storageService.setStorage(tencentStorage());
} else {
throw new RuntimeException("当前存储模式 " + active + " 不支持");
}
@@ -46,4 +55,24 @@ public class StorageAutoConfig {
localStorage.setStoragePath(local.getStoragePath());
return localStorage;
}
+
+ @Bean
+ public AliyunStorage aliyunStorage() {
+ AliyunStorage aliyunStorage = new AliyunStorage();
+ StorageProperties.Aliyun aliyun = this.properties.getAliyun();
+ aliyunStorage.setAccessKeyId(aliyun.getAccessKeyId());
+ aliyunStorage.setAccessKeySecret(aliyun.getAccessKeySecret());
+ return aliyunStorage;
+ }
+
+ @Bean
+ public TencentStorage tencentStorage() {
+ TencentStorage tencentStorage = new TencentStorage();
+ StorageProperties.Tencent tencent = this.properties.getTencent();
+ tencentStorage.setAppId(tencent.getAppId());
+ tencentStorage.setSecretId(tencent.getSecretId());
+ tencentStorage.setSecretKey(tencent.getSecretKey());
+ tencentStorage.setBucketName(tencentStorage.getBucketName() + "-" + tencentStorage.getAppId());
+ return tencentStorage;
+ }
}
diff --git a/springbok-system/src/main/java/cn/code4java/springbok/properties/StorageProperties.java b/springbok-system/src/main/java/cn/code4java/springbok/properties/StorageProperties.java
index eacfd23b7fb177d9953fec82f0440380f56174e4..0a9ed2ee102d70d52d10e465214c1ad6e5890dcf 100644
--- a/springbok-system/src/main/java/cn/code4java/springbok/properties/StorageProperties.java
+++ b/springbok-system/src/main/java/cn/code4java/springbok/properties/StorageProperties.java
@@ -1,5 +1,6 @@
package cn.code4java.springbok.properties;
+import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
@@ -9,45 +10,30 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @Date 2024/1/8
* @Version V1.0
**/
+@Data
@ConfigurationProperties(prefix = "springbok.storage")
public class StorageProperties {
private String active;
private Local local;
+ private Aliyun aliyun;
+ private Tencent tencent;
- public String getActive() {
- return active;
- }
-
- public void setActive(String active) {
- this.active = active;
- }
-
- public Local getLocal() {
- return local;
- }
-
- public void setLocal(Local local) {
- this.local = local;
- }
-
+ @Data
public static class Local {
private String address;
private String storagePath;
+ }
- public String getAddress() {
- return address;
- }
-
- public void setAddress(String address) {
- this.address = address;
- }
-
- public String getStoragePath() {
- return storagePath;
- }
+ @Data
+ public static class Aliyun {
+ private String accessKeyId;
+ private String accessKeySecret;
+ }
- public void setStoragePath(String storagePath) {
- this.storagePath = storagePath;
- }
+ @Data
+ public static class Tencent {
+ private String appId;
+ private String secretId;
+ private String secretKey;
}
}