mirror of
https://gitee.com/dromara/RuoYi-Cloud-Plus.git
synced 2025-09-04 19:38:02 +00:00
update 基于S3协议重新实现 OSS模块 支持自定义域名
This commit is contained in:
@@ -23,34 +23,8 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.qiniu</groupId>
|
<groupId>com.amazonaws</groupId>
|
||||||
<artifactId>qiniu-java-sdk</artifactId>
|
<artifactId>aws-java-sdk-s3</artifactId>
|
||||||
<version>${qiniu.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.aliyun.oss</groupId>
|
|
||||||
<artifactId>aliyun-sdk-oss</artifactId>
|
|
||||||
<version>${aliyun.oss.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.qcloud</groupId>
|
|
||||||
<artifactId>cos_api</artifactId>
|
|
||||||
<version>${qcloud.cos.version}</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-log4j12</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcprov-jdk15on</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.minio</groupId>
|
|
||||||
<artifactId>minio</artifactId>
|
|
||||||
<version>${minio.version}</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@@ -8,31 +8,41 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
public class OssConstant {
|
public interface OssConstant {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OSS模块KEY
|
* OSS模块KEY
|
||||||
*/
|
*/
|
||||||
public static final String SYS_OSS_KEY = "sys_oss:";
|
String SYS_OSS_KEY = "sys_oss:";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对象存储配置KEY
|
* 对象存储配置KEY
|
||||||
*/
|
*/
|
||||||
public static final String OSS_CONFIG_KEY = "OssConfig";
|
String OSS_CONFIG_KEY = "OssConfig";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存配置KEY
|
* 缓存配置KEY
|
||||||
*/
|
*/
|
||||||
public static final String CACHE_CONFIG_KEY = SYS_OSS_KEY + OSS_CONFIG_KEY;
|
String CACHE_CONFIG_KEY = SYS_OSS_KEY + OSS_CONFIG_KEY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预览列表资源开关Key
|
* 预览列表资源开关Key
|
||||||
*/
|
*/
|
||||||
public static final String PEREVIEW_LIST_RESOURCE_KEY = "sys.oss.previewListResource";
|
String PEREVIEW_LIST_RESOURCE_KEY = "sys.oss.previewListResource";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统数据ids
|
* 系统数据ids
|
||||||
*/
|
*/
|
||||||
public static final List<Integer> SYSTEM_DATA_IDS = Arrays.asList(1, 2, 3, 4);
|
List<Integer> SYSTEM_DATA_IDS = Arrays.asList(1, 2, 3, 4);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云服务商
|
||||||
|
*/
|
||||||
|
String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu"};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https 状态
|
||||||
|
*/
|
||||||
|
String IS_HTTPS = "Y";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,52 +0,0 @@
|
|||||||
package com.ruoyi.common.oss.enumd;
|
|
||||||
|
|
||||||
import com.ruoyi.common.oss.service.impl.AliyunOssStrategy;
|
|
||||||
import com.ruoyi.common.oss.service.impl.MinioOssStrategy;
|
|
||||||
import com.ruoyi.common.oss.service.impl.QcloudOssStrategy;
|
|
||||||
import com.ruoyi.common.oss.service.impl.QiniuOssStrategy;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对象存储服务商枚举
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum OssEnumd {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 七牛云
|
|
||||||
*/
|
|
||||||
QINIU("qiniu", QiniuOssStrategy.class),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 阿里云
|
|
||||||
*/
|
|
||||||
ALIYUN("aliyun", AliyunOssStrategy.class),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 腾讯云
|
|
||||||
*/
|
|
||||||
QCLOUD("qcloud", QcloudOssStrategy.class),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* minio
|
|
||||||
*/
|
|
||||||
MINIO("minio", MinioOssStrategy.class);
|
|
||||||
|
|
||||||
private final String value;
|
|
||||||
|
|
||||||
private final Class<?> beanClass;
|
|
||||||
|
|
||||||
public static OssEnumd find(String value) {
|
|
||||||
for (OssEnumd enumd : values()) {
|
|
||||||
if (enumd.getValue().equals(value)) {
|
|
||||||
return enumd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,19 +1,3 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the dreamlu.net developer nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
* Author: Chill 庄骞 (smallchill@163.com)
|
|
||||||
*/
|
|
||||||
package com.ruoyi.common.oss.enumd;
|
package com.ruoyi.common.oss.enumd;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
@@ -1,17 +1,17 @@
|
|||||||
package com.ruoyi.common.oss.factory;
|
package com.ruoyi.common.oss.factory;
|
||||||
|
|
||||||
import com.ruoyi.common.core.utils.JsonUtils;
|
import com.ruoyi.common.core.utils.JsonUtils;
|
||||||
import com.ruoyi.common.core.utils.SpringUtils;
|
|
||||||
import com.ruoyi.common.core.utils.StringUtils;
|
import com.ruoyi.common.core.utils.StringUtils;
|
||||||
import com.ruoyi.common.oss.constant.OssConstant;
|
import com.ruoyi.common.oss.constant.OssConstant;
|
||||||
import com.ruoyi.common.oss.enumd.OssEnumd;
|
import com.ruoyi.common.oss.core.OssClient;
|
||||||
import com.ruoyi.common.oss.exception.OssException;
|
import com.ruoyi.common.oss.exception.OssException;
|
||||||
import com.ruoyi.common.oss.properties.OssProperties;
|
import com.ruoyi.common.oss.properties.OssProperties;
|
||||||
import com.ruoyi.common.oss.service.IOssStrategy;
|
|
||||||
import com.ruoyi.common.oss.service.abstractd.AbstractOssStrategy;
|
|
||||||
import com.ruoyi.common.redis.utils.RedisUtils;
|
import com.ruoyi.common.redis.utils.RedisUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件上传Factory
|
* 文件上传Factory
|
||||||
*
|
*
|
||||||
@@ -20,17 +20,19 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class OssFactory {
|
public class OssFactory {
|
||||||
|
|
||||||
|
private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化工厂
|
* 初始化工厂
|
||||||
*/
|
*/
|
||||||
public static void init() {
|
public static void init() {
|
||||||
log.info("初始化OSS工厂");
|
log.info("初始化OSS工厂");
|
||||||
RedisUtils.subscribe(OssConstant.CACHE_CONFIG_KEY, String.class, type -> {
|
RedisUtils.subscribe(OssConstant.CACHE_CONFIG_KEY, String.class, configKey -> {
|
||||||
AbstractOssStrategy strategy = getStrategy(type);
|
OssClient client = getClient(configKey);
|
||||||
// 未初始化不处理
|
// 未初始化不处理
|
||||||
if (strategy.isInit) {
|
if (client != null) {
|
||||||
refresh(type);
|
refresh(configKey);
|
||||||
log.info("订阅刷新OSS配置 => " + type);
|
log.info("订阅刷新OSS配置 => " + configKey);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -38,42 +40,38 @@ public class OssFactory {
|
|||||||
/**
|
/**
|
||||||
* 获取默认实例
|
* 获取默认实例
|
||||||
*/
|
*/
|
||||||
public static IOssStrategy instance() {
|
public static OssClient instance() {
|
||||||
// 获取redis 默认类型
|
// 获取redis 默认类型
|
||||||
String type = RedisUtils.getCacheObject(OssConstant.CACHE_CONFIG_KEY);
|
String configKey = RedisUtils.getCacheObject(OssConstant.CACHE_CONFIG_KEY);
|
||||||
if (StringUtils.isEmpty(type)) {
|
if (StringUtils.isEmpty(configKey)) {
|
||||||
throw new OssException("文件存储服务类型无法找到!");
|
throw new OssException("文件存储服务类型无法找到!");
|
||||||
}
|
}
|
||||||
return instance(type);
|
return instance(configKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据类型获取实例
|
* 根据类型获取实例
|
||||||
*/
|
*/
|
||||||
public static IOssStrategy instance(String type) {
|
public static OssClient instance(String configKey) {
|
||||||
OssEnumd enumd = OssEnumd.find(type);
|
OssClient client = getClient(configKey);
|
||||||
if (enumd == null) {
|
if (client == null) {
|
||||||
throw new OssException("文件存储服务类型无法找到!");
|
refresh(configKey);
|
||||||
|
return getClient(configKey);
|
||||||
}
|
}
|
||||||
AbstractOssStrategy strategy = getStrategy(type);
|
return client;
|
||||||
if (!strategy.isInit) {
|
|
||||||
refresh(type);
|
|
||||||
}
|
|
||||||
return strategy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void refresh(String type) {
|
private static void refresh(String configKey) {
|
||||||
Object json = RedisUtils.getCacheObject(OssConstant.SYS_OSS_KEY + type);
|
Object json = RedisUtils.getCacheObject(OssConstant.SYS_OSS_KEY + configKey);
|
||||||
OssProperties properties = JsonUtils.parseObject(json.toString(), OssProperties.class);
|
OssProperties properties = JsonUtils.parseObject(json.toString(), OssProperties.class);
|
||||||
if (properties == null) {
|
if (properties == null) {
|
||||||
throw new OssException("系统异常, '" + type + "'配置信息不存在!");
|
throw new OssException("系统异常, '" + configKey + "'配置信息不存在!");
|
||||||
}
|
}
|
||||||
getStrategy(type).init(properties);
|
CLIENT_CACHE.put(configKey, new OssClient(configKey, properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AbstractOssStrategy getStrategy(String type) {
|
private static OssClient getClient(String configKey) {
|
||||||
OssEnumd enumd = OssEnumd.find(type);
|
return CLIENT_CACHE.get(configKey);
|
||||||
return (AbstractOssStrategy) SpringUtils.getBean(enumd.getBeanClass());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,11 @@ public class OssProperties {
|
|||||||
*/
|
*/
|
||||||
private String endpoint;
|
private String endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义域名
|
||||||
|
*/
|
||||||
|
private String domain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 前缀
|
* 前缀
|
||||||
*/
|
*/
|
||||||
|
@@ -1,74 +0,0 @@
|
|||||||
package com.ruoyi.common.oss.service;
|
|
||||||
|
|
||||||
|
|
||||||
import com.ruoyi.common.oss.entity.UploadResult;
|
|
||||||
import com.ruoyi.common.oss.enumd.OssEnumd;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对象存储策略
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
*/
|
|
||||||
public interface IOssStrategy {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建存储桶
|
|
||||||
*/
|
|
||||||
void createBucket();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取服务商类型
|
|
||||||
* @return 对象存储服务商枚举
|
|
||||||
*/
|
|
||||||
OssEnumd getServiceType();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件上传
|
|
||||||
*
|
|
||||||
* @param data 文件字节数组
|
|
||||||
* @param path 文件路径,包含文件名
|
|
||||||
* @param contentType 文件类型
|
|
||||||
* @return 返回http地址
|
|
||||||
*/
|
|
||||||
UploadResult upload(byte[] data, String path, String contentType);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件删除
|
|
||||||
*
|
|
||||||
* @param path 文件路径,包含文件名
|
|
||||||
*/
|
|
||||||
void delete(String path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件上传
|
|
||||||
*
|
|
||||||
* @param data 文件字节数组
|
|
||||||
* @param suffix 后缀
|
|
||||||
* @param contentType 文件类型
|
|
||||||
* @return 返回http地址
|
|
||||||
*/
|
|
||||||
UploadResult uploadSuffix(byte[] data, String suffix, String contentType);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件上传
|
|
||||||
*
|
|
||||||
* @param inputStream 字节流
|
|
||||||
* @param path 文件路径,包含文件名
|
|
||||||
* @param contentType 文件类型
|
|
||||||
* @return 返回http地址
|
|
||||||
*/
|
|
||||||
UploadResult upload(InputStream inputStream, String path, String contentType);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件上传
|
|
||||||
*
|
|
||||||
* @param inputStream 字节流
|
|
||||||
* @param suffix 后缀
|
|
||||||
* @param contentType 文件类型
|
|
||||||
* @return 返回http地址
|
|
||||||
*/
|
|
||||||
UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType);
|
|
||||||
|
|
||||||
}
|
|
@@ -1,69 +0,0 @@
|
|||||||
package com.ruoyi.common.oss.service.abstractd;
|
|
||||||
|
|
||||||
import cn.hutool.core.io.IoUtil;
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
|
||||||
import com.ruoyi.common.core.utils.DateUtils;
|
|
||||||
import com.ruoyi.common.core.utils.StringUtils;
|
|
||||||
import com.ruoyi.common.oss.entity.UploadResult;
|
|
||||||
import com.ruoyi.common.oss.enumd.OssEnumd;
|
|
||||||
import com.ruoyi.common.oss.properties.OssProperties;
|
|
||||||
import com.ruoyi.common.oss.service.IOssStrategy;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对象存储策略(支持七牛、阿里云、腾讯云、minio)
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
*/
|
|
||||||
public abstract class AbstractOssStrategy implements IOssStrategy {
|
|
||||||
|
|
||||||
protected OssProperties properties;
|
|
||||||
public boolean isInit = false;
|
|
||||||
|
|
||||||
public void init(OssProperties properties) {
|
|
||||||
this.properties = properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract void createBucket();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract OssEnumd getServiceType();
|
|
||||||
|
|
||||||
public String getPath(String prefix, String suffix) {
|
|
||||||
// 生成uuid
|
|
||||||
String uuid = IdUtil.fastSimpleUUID();
|
|
||||||
// 文件路径
|
|
||||||
String path = DateUtils.datePath() + "/" + uuid;
|
|
||||||
if (StringUtils.isNotBlank(prefix)) {
|
|
||||||
path = prefix + "/" + path;
|
|
||||||
}
|
|
||||||
return path + suffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract UploadResult upload(byte[] data, String path, String contentType);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract void delete(String path);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult upload(InputStream inputStream, String path, String contentType) {
|
|
||||||
byte[] data = IoUtil.readBytes(inputStream);
|
|
||||||
return this.upload(data, path, contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract UploadResult uploadSuffix(byte[] data, String suffix, String contentType);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取域名访问链接
|
|
||||||
*
|
|
||||||
* @return 域名访问链接
|
|
||||||
*/
|
|
||||||
public abstract String getEndpointLink();
|
|
||||||
}
|
|
@@ -1,115 +0,0 @@
|
|||||||
package com.ruoyi.common.oss.service.impl;
|
|
||||||
|
|
||||||
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.common.core.utils.StringUtils;
|
|
||||||
import com.ruoyi.common.oss.entity.UploadResult;
|
|
||||||
import com.ruoyi.common.oss.enumd.OssEnumd;
|
|
||||||
import com.ruoyi.common.oss.exception.OssException;
|
|
||||||
import com.ruoyi.common.oss.properties.OssProperties;
|
|
||||||
import com.ruoyi.common.oss.service.abstractd.AbstractOssStrategy;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 阿里云存储策略
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class AliyunOssStrategy extends AbstractOssStrategy {
|
|
||||||
|
|
||||||
private OSSClient client;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(OssProperties ossProperties) {
|
|
||||||
super.init(ossProperties);
|
|
||||||
try {
|
|
||||||
ClientConfiguration configuration = new ClientConfiguration();
|
|
||||||
DefaultCredentialProvider credentialProvider = new DefaultCredentialProvider(
|
|
||||||
properties.getAccessKey(), properties.getSecretKey());
|
|
||||||
client = new OSSClient(properties.getEndpoint(), credentialProvider, configuration);
|
|
||||||
createBucket();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new OssException("阿里云存储配置错误! 请检查系统配置:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
isInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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失败, 请核对阿里云配置信息:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OssEnumd getServiceType() {
|
|
||||||
return OssEnumd.ALIYUN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult upload(byte[] data, String path, String contentType) {
|
|
||||||
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("上传文件失败,请检查阿里云配置信息:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
return UploadResult.builder().url(getEndpointLink() + "/" + path).filename(path).build(); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(String path) {
|
|
||||||
path = path.replace(getEndpointLink() + "/", "");
|
|
||||||
try {
|
|
||||||
client.deleteObject(properties.getBucketName(), path);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new OssException("上传文件失败,请检查阿里云配置信息:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
|
|
||||||
return upload(data, getPath(properties.getPrefix(), suffix), contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
|
|
||||||
return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getEndpointLink() {
|
|
||||||
String endpoint = properties.getEndpoint();
|
|
||||||
StringBuilder sb = new StringBuilder(endpoint);
|
|
||||||
if (StringUtils.containsAnyIgnoreCase(endpoint, "http://")) {
|
|
||||||
sb.insert(7, properties.getBucketName() + ".");
|
|
||||||
} else if (StringUtils.containsAnyIgnoreCase(endpoint, "https://")) {
|
|
||||||
sb.insert(8, properties.getBucketName() + ".");
|
|
||||||
} else {
|
|
||||||
throw new OssException("Endpoint配置错误");
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,186 +0,0 @@
|
|||||||
package com.ruoyi.common.oss.service.impl;
|
|
||||||
|
|
||||||
import com.ruoyi.common.core.utils.StringUtils;
|
|
||||||
import com.ruoyi.common.oss.entity.UploadResult;
|
|
||||||
import com.ruoyi.common.oss.enumd.OssEnumd;
|
|
||||||
import com.ruoyi.common.oss.enumd.PolicyType;
|
|
||||||
import com.ruoyi.common.oss.exception.OssException;
|
|
||||||
import com.ruoyi.common.oss.properties.OssProperties;
|
|
||||||
import com.ruoyi.common.oss.service.abstractd.AbstractOssStrategy;
|
|
||||||
import io.minio.*;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* minio存储策略
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class MinioOssStrategy extends AbstractOssStrategy {
|
|
||||||
|
|
||||||
private MinioClient minioClient;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(OssProperties ossProperties) {
|
|
||||||
super.init(ossProperties);
|
|
||||||
try {
|
|
||||||
minioClient = MinioClient.builder()
|
|
||||||
.endpoint(properties.getEndpoint())
|
|
||||||
.credentials(properties.getAccessKey(), properties.getSecretKey())
|
|
||||||
.build();
|
|
||||||
createBucket();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new OssException("Minio存储配置错误! 请检查系统配置:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
isInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createBucket() {
|
|
||||||
try {
|
|
||||||
String bucketName = properties.getBucketName();
|
|
||||||
boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).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 OssException("创建Bucket失败, 请核对Minio配置信息:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OssEnumd getServiceType() {
|
|
||||||
return OssEnumd.MINIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult upload(byte[] data, String path, String contentType) {
|
|
||||||
return upload(new ByteArrayInputStream(data), path, contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult upload(InputStream inputStream, String path, String contentType) {
|
|
||||||
try {
|
|
||||||
// 解决 inputStream.available() 在 socket 下传输延迟问题 导致获取数值不精确
|
|
||||||
Thread.sleep(1000);
|
|
||||||
minioClient.putObject(PutObjectArgs.builder()
|
|
||||||
.bucket(properties.getBucketName())
|
|
||||||
.object(path)
|
|
||||||
.contentType(StringUtils.blankToDefault(contentType, MediaType.APPLICATION_OCTET_STREAM_VALUE))
|
|
||||||
.stream(inputStream, inputStream.available(), -1)
|
|
||||||
.build());
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new OssException("上传文件失败,请核对Minio配置信息:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
return UploadResult.builder().url(getEndpointLink() + "/" + path).filename(path).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(String path) {
|
|
||||||
path = path.replace(getEndpointLink() + "/", "");
|
|
||||||
try {
|
|
||||||
minioClient.removeObject(RemoveObjectArgs.builder()
|
|
||||||
.bucket(properties.getBucketName())
|
|
||||||
.object(path)
|
|
||||||
.build());
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new OssException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
|
|
||||||
return upload(data, getPath(properties.getPrefix(), suffix), contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
|
|
||||||
return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getEndpointLink() {
|
|
||||||
return properties.getEndpoint() + "/" + properties.getBucketName();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getPolicy(String bucketName, PolicyType policyType) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("{\n");
|
|
||||||
builder.append(" \"Statement\": [\n");
|
|
||||||
builder.append(" {\n");
|
|
||||||
builder.append(" \"Action\": [\n");
|
|
||||||
if (policyType == PolicyType.WRITE) {
|
|
||||||
builder.append(" \"s3:GetBucketLocation\",\n");
|
|
||||||
builder.append(" \"s3:ListBucketMultipartUploads\"\n");
|
|
||||||
} else if (policyType == PolicyType.READ_WRITE) {
|
|
||||||
builder.append(" \"s3:GetBucketLocation\",\n");
|
|
||||||
builder.append(" \"s3:ListBucket\",\n");
|
|
||||||
builder.append(" \"s3:ListBucketMultipartUploads\"\n");
|
|
||||||
} else {
|
|
||||||
builder.append(" \"s3:GetBucketLocation\"\n");
|
|
||||||
}
|
|
||||||
builder.append(" ],\n");
|
|
||||||
builder.append(" \"Effect\": \"Allow\",\n");
|
|
||||||
builder.append(" \"Principal\": \"*\",\n");
|
|
||||||
builder.append(" \"Resource\": \"arn:aws:s3:::");
|
|
||||||
builder.append(bucketName);
|
|
||||||
builder.append("\"\n");
|
|
||||||
builder.append(" },\n");
|
|
||||||
if (PolicyType.READ.equals(policyType)) {
|
|
||||||
builder.append(" {\n");
|
|
||||||
builder.append(" \"Action\": [\n");
|
|
||||||
builder.append(" \"s3:ListBucket\"\n");
|
|
||||||
builder.append(" ],\n");
|
|
||||||
builder.append(" \"Effect\": \"Deny\",\n");
|
|
||||||
builder.append(" \"Principal\": \"*\",\n");
|
|
||||||
builder.append(" \"Resource\": \"arn:aws:s3:::");
|
|
||||||
builder.append(bucketName);
|
|
||||||
builder.append("\"\n");
|
|
||||||
builder.append(" },\n");
|
|
||||||
}
|
|
||||||
builder.append(" {\n");
|
|
||||||
builder.append(" \"Action\": ");
|
|
||||||
switch (policyType) {
|
|
||||||
case WRITE:
|
|
||||||
builder.append("[\n");
|
|
||||||
builder.append(" \"s3:AbortMultipartUpload\",\n");
|
|
||||||
builder.append(" \"s3:DeleteObject\",\n");
|
|
||||||
builder.append(" \"s3:ListMultipartUploadParts\",\n");
|
|
||||||
builder.append(" \"s3:PutObject\"\n");
|
|
||||||
builder.append(" ],\n");
|
|
||||||
break;
|
|
||||||
case READ_WRITE:
|
|
||||||
builder.append("[\n");
|
|
||||||
builder.append(" \"s3:AbortMultipartUpload\",\n");
|
|
||||||
builder.append(" \"s3:DeleteObject\",\n");
|
|
||||||
builder.append(" \"s3:GetObject\",\n");
|
|
||||||
builder.append(" \"s3:ListMultipartUploadParts\",\n");
|
|
||||||
builder.append(" \"s3:PutObject\"\n");
|
|
||||||
builder.append(" ],\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
builder.append("\"s3:GetObject\",\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
builder.append(" \"Effect\": \"Allow\",\n");
|
|
||||||
builder.append(" \"Principal\": \"*\",\n");
|
|
||||||
builder.append(" \"Resource\": \"arn:aws:s3:::");
|
|
||||||
builder.append(bucketName);
|
|
||||||
builder.append("/*\"\n");
|
|
||||||
builder.append(" }\n");
|
|
||||||
builder.append(" ],\n");
|
|
||||||
builder.append(" \"Version\": \"2012-10-17\"\n");
|
|
||||||
builder.append("}\n");
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,124 +0,0 @@
|
|||||||
package com.ruoyi.common.oss.service.impl;
|
|
||||||
|
|
||||||
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.common.core.utils.StringUtils;
|
|
||||||
import com.ruoyi.common.oss.entity.UploadResult;
|
|
||||||
import com.ruoyi.common.oss.enumd.OssEnumd;
|
|
||||||
import com.ruoyi.common.oss.exception.OssException;
|
|
||||||
import com.ruoyi.common.oss.properties.OssProperties;
|
|
||||||
import com.ruoyi.common.oss.service.abstractd.AbstractOssStrategy;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 腾讯云存储策略
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class QcloudOssStrategy extends AbstractOssStrategy {
|
|
||||||
|
|
||||||
private COSClient client;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(OssProperties ossProperties) {
|
|
||||||
super.init(ossProperties);
|
|
||||||
try {
|
|
||||||
COSCredentials credentials = new BasicCOSCredentials(
|
|
||||||
properties.getAccessKey(), properties.getSecretKey());
|
|
||||||
// 初始化客户端配置
|
|
||||||
ClientConfig clientConfig = new ClientConfig();
|
|
||||||
// 设置bucket所在的区域,华南:gz 华北:tj 华东:sh
|
|
||||||
clientConfig.setRegion(new Region(properties.getRegion()));
|
|
||||||
if ("Y".equals(properties.getIsHttps())) {
|
|
||||||
clientConfig.setHttpProtocol(HttpProtocol.https);
|
|
||||||
} else {
|
|
||||||
clientConfig.setHttpProtocol(HttpProtocol.http);
|
|
||||||
}
|
|
||||||
client = new COSClient(credentials, clientConfig);
|
|
||||||
createBucket();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new OssException("腾讯云存储配置错误! 请检查系统配置:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
isInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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失败, 请核对腾讯云配置信息:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OssEnumd getServiceType() {
|
|
||||||
return OssEnumd.QCLOUD;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult upload(byte[] data, String path, String contentType) {
|
|
||||||
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("上传文件失败,请检查腾讯云配置信息:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
return UploadResult.builder().url(getEndpointLink() + "/" + path).filename(path).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(String path) {
|
|
||||||
path = path.replace(getEndpointLink() + "/", "");
|
|
||||||
try {
|
|
||||||
client.deleteObject(new DeleteObjectRequest(properties.getBucketName(), path));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new OssException("上传文件失败,请检腾讯云查配置信息:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
|
|
||||||
return upload(data, getPath(properties.getPrefix(), suffix), contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
|
|
||||||
return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getEndpointLink() {
|
|
||||||
String endpoint = properties.getEndpoint();
|
|
||||||
StringBuilder sb = new StringBuilder(endpoint);
|
|
||||||
if (StringUtils.containsAnyIgnoreCase(endpoint, "http://")) {
|
|
||||||
sb.insert(7, properties.getBucketName() + ".");
|
|
||||||
} else if (StringUtils.containsAnyIgnoreCase(endpoint, "https://")) {
|
|
||||||
sb.insert(8, properties.getBucketName() + ".");
|
|
||||||
} else {
|
|
||||||
throw new OssException("Endpoint配置错误");
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,127 +0,0 @@
|
|||||||
package com.ruoyi.common.oss.service.impl;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
|
||||||
import com.qiniu.http.Response;
|
|
||||||
import com.qiniu.storage.BucketManager;
|
|
||||||
import com.qiniu.storage.Configuration;
|
|
||||||
import com.qiniu.storage.Region;
|
|
||||||
import com.qiniu.storage.UploadManager;
|
|
||||||
import com.qiniu.util.Auth;
|
|
||||||
import com.ruoyi.common.oss.entity.UploadResult;
|
|
||||||
import com.ruoyi.common.oss.enumd.OssEnumd;
|
|
||||||
import com.ruoyi.common.oss.exception.OssException;
|
|
||||||
import com.ruoyi.common.oss.properties.OssProperties;
|
|
||||||
import com.ruoyi.common.oss.service.abstractd.AbstractOssStrategy;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 七牛云存储策略
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class QiniuOssStrategy extends AbstractOssStrategy {
|
|
||||||
|
|
||||||
private UploadManager uploadManager;
|
|
||||||
private BucketManager bucketManager;
|
|
||||||
private Auth auth;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(OssProperties ossProperties) {
|
|
||||||
super.init(ossProperties);
|
|
||||||
try {
|
|
||||||
Configuration config = new Configuration(getRegion(properties.getRegion()));
|
|
||||||
// https设置
|
|
||||||
config.useHttpsDomains = false;
|
|
||||||
config.useHttpsDomains = "Y".equals(properties.getIsHttps());
|
|
||||||
uploadManager = new UploadManager(config);
|
|
||||||
auth = Auth.create(properties.getAccessKey(), properties.getSecretKey());
|
|
||||||
bucketManager = new BucketManager(auth, config);
|
|
||||||
createBucket();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new OssException("七牛云存储配置错误! 请检查系统配置:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
isInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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失败, 请核对七牛云配置信息:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OssEnumd getServiceType() {
|
|
||||||
return OssEnumd.QINIU;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult upload(byte[] data, String path, String contentType) {
|
|
||||||
try {
|
|
||||||
String token = auth.uploadToken(properties.getBucketName());
|
|
||||||
Response res = uploadManager.put(data, path, token, null, contentType, false);
|
|
||||||
if (!res.isOK()) {
|
|
||||||
throw new RuntimeException("上传七牛出错:" + res.error);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new OssException("上传文件失败,请核对七牛配置信息:[" + e.getMessage() + "]");
|
|
||||||
}
|
|
||||||
return UploadResult.builder().url(getEndpointLink() + "/" + path).filename(path).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(String path) {
|
|
||||||
try {
|
|
||||||
path = path.replace(getEndpointLink() + "/", "");
|
|
||||||
Response res = bucketManager.delete(properties.getBucketName(), path);
|
|
||||||
if (!res.isOK()) {
|
|
||||||
throw new RuntimeException("删除七牛文件出错:" + res.error);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new OssException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
|
|
||||||
return upload(data, getPath(properties.getPrefix(), suffix), contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
|
|
||||||
return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getEndpointLink() {
|
|
||||||
return properties.getEndpoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Region getRegion(String region) {
|
|
||||||
switch (region) {
|
|
||||||
case "z0":
|
|
||||||
return Region.region0();
|
|
||||||
case "z1":
|
|
||||||
return Region.region1();
|
|
||||||
case "z2":
|
|
||||||
return Region.region2();
|
|
||||||
case "na0":
|
|
||||||
return Region.regionNa0();
|
|
||||||
case "as0":
|
|
||||||
return Region.regionAs0();
|
|
||||||
default:
|
|
||||||
return Region.autoRegion();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,5 +1 @@
|
|||||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
|
||||||
com.ruoyi.common.oss.service.impl.AliyunOssStrategy,\
|
|
||||||
com.ruoyi.common.oss.service.impl.MinioOssStrategy,\
|
|
||||||
com.ruoyi.common.oss.service.impl.QcloudOssStrategy,\
|
|
||||||
com.ruoyi.common.oss.service.impl.QiniuOssStrategy
|
|
||||||
|
@@ -52,6 +52,12 @@ public class SysOssConfig extends BaseEntity {
|
|||||||
*/
|
*/
|
||||||
private String endpoint;
|
private String endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义域名
|
||||||
|
*/
|
||||||
|
private String domain;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否https(0否 1是)
|
* 是否https(0否 1是)
|
||||||
*/
|
*/
|
||||||
|
@@ -35,8 +35,8 @@ public class SysOssConfigBo extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 配置key
|
* 配置key
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "configKey", required = true)
|
@ApiModelProperty(value = "配置key", required = true)
|
||||||
@NotBlank(message = "configKey不能为空", groups = {AddGroup.class, EditGroup.class})
|
@NotBlank(message = "配置key不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||||
@Size(min = 2, max = 100, message = "configKey长度必须介于2和20 之间")
|
@Size(min = 2, max = 100, message = "configKey长度必须介于2和20 之间")
|
||||||
private String configKey;
|
private String configKey;
|
||||||
|
|
||||||
@@ -59,8 +59,8 @@ public class SysOssConfigBo extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 桶名称
|
* 桶名称
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "bucketName", required = true)
|
@ApiModelProperty(value = "桶名称", required = true)
|
||||||
@NotBlank(message = "bucketName不能为空", groups = {AddGroup.class, EditGroup.class})
|
@NotBlank(message = "桶名称不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||||
@Size(min = 2, max = 100, message = "bucketName长度必须介于2和100之间")
|
@Size(min = 2, max = 100, message = "bucketName长度必须介于2和100之间")
|
||||||
private String bucketName;
|
private String bucketName;
|
||||||
|
|
||||||
@@ -73,11 +73,17 @@ public class SysOssConfigBo extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 访问站点
|
* 访问站点
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "endpoint", required = true)
|
@ApiModelProperty(value = "访问站点", required = true)
|
||||||
@NotBlank(message = "endpoint不能为空", groups = {AddGroup.class, EditGroup.class})
|
@NotBlank(message = "访问站点不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||||
@Size(min = 2, max = 100, message = "endpoint长度必须介于2和100之间")
|
@Size(min = 2, max = 100, message = "endpoint长度必须介于2和100之间")
|
||||||
private String endpoint;
|
private String endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义域名
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("自定义域名")
|
||||||
|
private String domain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否https(Y=是,N=否)
|
* 是否https(Y=是,N=否)
|
||||||
*/
|
*/
|
||||||
@@ -93,7 +99,7 @@ public class SysOssConfigBo extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 域
|
* 域
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "region")
|
@ApiModelProperty(value = "域")
|
||||||
private String region;
|
private String region;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -60,6 +60,12 @@ public class SysOssConfigVo {
|
|||||||
@ApiModelProperty("访问站点")
|
@ApiModelProperty("访问站点")
|
||||||
private String endpoint;
|
private String endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义域名
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("自定义域名")
|
||||||
|
private String domain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否https(Y=是,N=否)
|
* 是否https(Y=是,N=否)
|
||||||
*/
|
*/
|
||||||
|
@@ -2,9 +2,9 @@ package com.ruoyi.resource.dubbo;
|
|||||||
|
|
||||||
import com.ruoyi.common.core.exception.ServiceException;
|
import com.ruoyi.common.core.exception.ServiceException;
|
||||||
import com.ruoyi.common.core.utils.StringUtils;
|
import com.ruoyi.common.core.utils.StringUtils;
|
||||||
|
import com.ruoyi.common.oss.core.OssClient;
|
||||||
import com.ruoyi.common.oss.entity.UploadResult;
|
import com.ruoyi.common.oss.entity.UploadResult;
|
||||||
import com.ruoyi.common.oss.factory.OssFactory;
|
import com.ruoyi.common.oss.factory.OssFactory;
|
||||||
import com.ruoyi.common.oss.service.IOssStrategy;
|
|
||||||
import com.ruoyi.resource.api.RemoteFileService;
|
import com.ruoyi.resource.api.RemoteFileService;
|
||||||
import com.ruoyi.resource.api.domain.SysFile;
|
import com.ruoyi.resource.api.domain.SysFile;
|
||||||
import com.ruoyi.resource.domain.SysOss;
|
import com.ruoyi.resource.domain.SysOss;
|
||||||
@@ -36,7 +36,7 @@ public class RemoteFileServiceImpl implements RemoteFileService {
|
|||||||
public SysFile upload(String name, String originalFilename, String contentType, byte[] file) throws ServiceException {
|
public SysFile upload(String name, String originalFilename, String contentType, byte[] file) throws ServiceException {
|
||||||
try {
|
try {
|
||||||
String suffix = StringUtils.substring(originalFilename, originalFilename.lastIndexOf("."), originalFilename.length());
|
String suffix = StringUtils.substring(originalFilename, originalFilename.lastIndexOf("."), originalFilename.length());
|
||||||
IOssStrategy storage = OssFactory.instance();
|
OssClient storage = OssFactory.instance();
|
||||||
UploadResult uploadResult = storage.uploadSuffix(file, suffix, contentType);
|
UploadResult uploadResult = storage.uploadSuffix(file, suffix, contentType);
|
||||||
// 保存文件信息
|
// 保存文件信息
|
||||||
SysOss oss = new SysOss();
|
SysOss oss = new SysOss();
|
||||||
@@ -44,7 +44,7 @@ public class RemoteFileServiceImpl implements RemoteFileService {
|
|||||||
oss.setFileSuffix(suffix);
|
oss.setFileSuffix(suffix);
|
||||||
oss.setFileName(uploadResult.getFilename());
|
oss.setFileName(uploadResult.getFilename());
|
||||||
oss.setOriginalName(originalFilename);
|
oss.setOriginalName(originalFilename);
|
||||||
oss.setService(storage.getServiceType().getValue());
|
oss.setService(storage.getConfigKey());
|
||||||
sysOssMapper.insert(oss);
|
sysOssMapper.insert(oss);
|
||||||
SysFile sysFile = new SysFile();
|
SysFile sysFile = new SysFile();
|
||||||
sysFile.setName(uploadResult.getFilename());
|
sysFile.setName(uploadResult.getFilename());
|
||||||
|
@@ -7,9 +7,9 @@ import com.ruoyi.common.core.exception.ServiceException;
|
|||||||
import com.ruoyi.common.core.utils.StringUtils;
|
import com.ruoyi.common.core.utils.StringUtils;
|
||||||
import com.ruoyi.common.mybatis.core.page.PageQuery;
|
import com.ruoyi.common.mybatis.core.page.PageQuery;
|
||||||
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
|
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.oss.core.OssClient;
|
||||||
import com.ruoyi.common.oss.entity.UploadResult;
|
import com.ruoyi.common.oss.entity.UploadResult;
|
||||||
import com.ruoyi.common.oss.factory.OssFactory;
|
import com.ruoyi.common.oss.factory.OssFactory;
|
||||||
import com.ruoyi.common.oss.service.IOssStrategy;
|
|
||||||
import com.ruoyi.resource.domain.SysOss;
|
import com.ruoyi.resource.domain.SysOss;
|
||||||
import com.ruoyi.resource.domain.bo.SysOssBo;
|
import com.ruoyi.resource.domain.bo.SysOssBo;
|
||||||
import com.ruoyi.resource.domain.vo.SysOssVo;
|
import com.ruoyi.resource.domain.vo.SysOssVo;
|
||||||
@@ -65,7 +65,7 @@ public class SysOssServiceImpl implements ISysOssService {
|
|||||||
public SysOss upload(MultipartFile file) {
|
public SysOss upload(MultipartFile file) {
|
||||||
String originalfileName = file.getOriginalFilename();
|
String originalfileName = file.getOriginalFilename();
|
||||||
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
|
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
|
||||||
IOssStrategy storage = OssFactory.instance();
|
OssClient storage = OssFactory.instance();
|
||||||
UploadResult uploadResult;
|
UploadResult uploadResult;
|
||||||
try {
|
try {
|
||||||
uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
|
uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
|
||||||
@@ -78,7 +78,7 @@ public class SysOssServiceImpl implements ISysOssService {
|
|||||||
oss.setFileSuffix(suffix);
|
oss.setFileSuffix(suffix);
|
||||||
oss.setFileName(uploadResult.getFilename());
|
oss.setFileName(uploadResult.getFilename());
|
||||||
oss.setOriginalName(originalfileName);
|
oss.setOriginalName(originalfileName);
|
||||||
oss.setService(storage.getServiceType().getValue());
|
oss.setService(storage.getConfigKey());
|
||||||
baseMapper.insert(oss);
|
baseMapper.insert(oss);
|
||||||
return oss;
|
return oss;
|
||||||
}
|
}
|
||||||
@@ -90,7 +90,7 @@ public class SysOssServiceImpl implements ISysOssService {
|
|||||||
}
|
}
|
||||||
List<SysOss> list = baseMapper.selectBatchIds(ids);
|
List<SysOss> list = baseMapper.selectBatchIds(ids);
|
||||||
for (SysOss sysOss : list) {
|
for (SysOss sysOss : list) {
|
||||||
IOssStrategy storage = OssFactory.instance(sysOss.getService());
|
OssClient storage = OssFactory.instance(sysOss.getService());
|
||||||
storage.delete(sysOss.getUrl());
|
storage.delete(sysOss.getUrl());
|
||||||
}
|
}
|
||||||
return baseMapper.deleteBatchIds(ids) > 0;
|
return baseMapper.deleteBatchIds(ids) > 0;
|
||||||
|
@@ -2,14 +2,13 @@
|
|||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
|
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
<el-form-item label="配置key" prop="configKey">
|
<el-form-item label="配置key" prop="configKey">
|
||||||
<el-select v-model="queryParams.configKey" placeholder="请选择配置key" clearable size="small">
|
<el-input
|
||||||
<el-option
|
v-model="queryParams.configKey"
|
||||||
v-for="configKey in configKeyOptions"
|
placeholder="配置key"
|
||||||
:key="configKey.configKey"
|
clearable
|
||||||
:label="configKey.label"
|
size="small"
|
||||||
:value="configKey.configKey"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="桶名称" prop="bucketName">
|
<el-form-item label="桶名称" prop="bucketName">
|
||||||
<el-input
|
<el-input
|
||||||
@@ -77,6 +76,7 @@
|
|||||||
<el-table-column label="主建" align="center" prop="ossConfigId" v-if="false"/>
|
<el-table-column label="主建" align="center" prop="ossConfigId" v-if="false"/>
|
||||||
<el-table-column label="配置key" align="center" prop="configKey" />
|
<el-table-column label="配置key" align="center" prop="configKey" />
|
||||||
<el-table-column label="访问站点" align="center" prop="endpoint" width="200" />
|
<el-table-column label="访问站点" align="center" prop="endpoint" width="200" />
|
||||||
|
<el-table-column label="自定义域名" align="center" prop="domain" width="200" />
|
||||||
<el-table-column label="桶名称" align="center" prop="bucketName" />
|
<el-table-column label="桶名称" align="center" prop="bucketName" />
|
||||||
<el-table-column label="前缀" align="center" prop="prefix" />
|
<el-table-column label="前缀" align="center" prop="prefix" />
|
||||||
<el-table-column label="域" align="center" prop="region" />
|
<el-table-column label="域" align="center" prop="region" />
|
||||||
@@ -122,18 +122,14 @@
|
|||||||
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
|
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
|
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
|
||||||
<el-form-item label="配置key" prop="configKey">
|
<el-form-item label="配置key" prop="configKey">
|
||||||
<el-select v-model="form.configKey" placeholder="请选择配置key">
|
<el-input v-model="form.configKey" placeholder="请输入配置key" />
|
||||||
<el-option
|
|
||||||
v-for="configKey in configKeyOptions"
|
|
||||||
:key="configKey.configKey"
|
|
||||||
:label="configKey.label"
|
|
||||||
:value="configKey.configKey"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="访问站点" prop="endpoint">
|
<el-form-item label="访问站点" prop="endpoint">
|
||||||
<el-input v-model="form.endpoint" placeholder="请输入访问站点" />
|
<el-input v-model="form.endpoint" placeholder="请输入访问站点" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="自定义域名" prop="domain">
|
||||||
|
<el-input v-model="form.domain" placeholder="请输入自定义域名" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="accessKey" prop="accessKey">
|
<el-form-item label="accessKey" prop="accessKey">
|
||||||
<el-input v-model="form.accessKey" placeholder="请输入accessKey" />
|
<el-input v-model="form.accessKey" placeholder="请输入accessKey" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -204,14 +200,6 @@ export default {
|
|||||||
total: 0,
|
total: 0,
|
||||||
// 对象存储配置表格数据
|
// 对象存储配置表格数据
|
||||||
ossConfigList: [],
|
ossConfigList: [],
|
||||||
// configKeyOptions
|
|
||||||
configKeyOptions: [],
|
|
||||||
configKeyDatas: [
|
|
||||||
{ configKey: "minio", label: "Minio" },
|
|
||||||
{ configKey: "qiniu", label: "七牛云" },
|
|
||||||
{ configKey: "aliyun", label: "阿里云" },
|
|
||||||
{ configKey: "qcloud", label: "腾讯云" },
|
|
||||||
],
|
|
||||||
// 弹出层标题
|
// 弹出层标题
|
||||||
title: "",
|
title: "",
|
||||||
// 是否显示弹出层
|
// 是否显示弹出层
|
||||||
@@ -276,7 +264,6 @@ export default {
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getList();
|
||||||
this.configKeyOptions = this.configKeyDatas;
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/** 查询对象存储配置列表 */
|
/** 查询对象存储配置列表 */
|
||||||
@@ -303,6 +290,7 @@ export default {
|
|||||||
bucketName: undefined,
|
bucketName: undefined,
|
||||||
prefix: undefined,
|
prefix: undefined,
|
||||||
endpoint: undefined,
|
endpoint: undefined,
|
||||||
|
domain: undefined,
|
||||||
isHttps: "N",
|
isHttps: "N",
|
||||||
region: undefined,
|
region: undefined,
|
||||||
status: "1",
|
status: "1",
|
||||||
|
@@ -612,6 +612,7 @@ create table sys_oss_config (
|
|||||||
bucket_name varchar(255) default '' comment '桶名称',
|
bucket_name varchar(255) default '' comment '桶名称',
|
||||||
prefix varchar(255) default '' comment '前缀',
|
prefix varchar(255) default '' comment '前缀',
|
||||||
endpoint varchar(255) default '' comment '访问站点',
|
endpoint varchar(255) default '' comment '访问站点',
|
||||||
|
domain varchar(255) default '' comment '自定义域名',
|
||||||
is_https char(1) default 'N' comment '是否https(Y=是,N=否)',
|
is_https char(1) default 'N' comment '是否https(Y=是,N=否)',
|
||||||
region varchar(255) default '' comment '域',
|
region varchar(255) default '' comment '域',
|
||||||
status char(1) default '1' comment '状态(0=正常,1=停用)',
|
status char(1) default '1' comment '状态(0=正常,1=停用)',
|
||||||
@@ -624,10 +625,11 @@ create table sys_oss_config (
|
|||||||
primary key (oss_config_id)
|
primary key (oss_config_id)
|
||||||
) engine=innodb comment='对象存储配置表';
|
) engine=innodb comment='对象存储配置表';
|
||||||
|
|
||||||
insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', 'http://localhost:9000', 'N', '', '0', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
|
insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', 'localhost:9000', '','N', '', '0', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
|
||||||
insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://XXX.XXXX.com', 'N', 'z0', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
|
insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 's3-cn-north-1.qiniucs.com', '','N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
|
||||||
insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://oss-cn-beijing.aliyuncs.com', 'N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
|
insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'oss-cn-beijing.aliyuncs.com', '','N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
|
||||||
insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'http://cos.ap-beijing.myqcloud.com', 'N', 'ap-beijing', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
|
insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'cos.ap-beijing.myqcloud.com', '','N', 'ap-beijing', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
|
||||||
|
insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', 'localhost:9000', '','N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- 18、代码生成业务表
|
-- 18、代码生成业务表
|
||||||
|
Reference in New Issue
Block a user