疯狂的狮子li
2021-08-13 cb13642e85a9d572d6f88f6ce7e3d7b0893dd713
update 重写 OSS 模块相关实现 支持动态配置(页面配置)
已修改10个文件
已重命名6个文件
533 ■■■■■ 文件已修改
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-oss/src/main/java/com/ruoyi/oss/constant/CloudConstant.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/CloudServiceEnumd.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-oss/src/main/java/com/ruoyi/oss/factory/OssFactory.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-oss/src/main/java/com/ruoyi/oss/properties/CloudStorageProperties.java 179 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-oss/src/main/java/com/ruoyi/oss/service/ICloudStorageStrategy.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractCloudStorageStrategy.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunCloudStorageStrategy.java 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioCloudStorageStrategy.java 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudCloudStorageStrategy.java 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuCloudStorageStrategy.java 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/oss/config.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/oss.sql 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java
@@ -92,7 +92,7 @@
    @Log(title = "云存储配置", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ossConfigIds}")
    public AjaxResult<Void> remove(@NotEmpty(message = "主键不能为空")
                                   @PathVariable Integer[] ossConfigIds) {
                                   @PathVariable Long[] ossConfigIds) {
        return toAjax(iSysOssConfigService.deleteWithValidByIds(Arrays.asList(ossConfigIds), true) ? 1 : 0);
    }
ruoyi-oss/src/main/java/com/ruoyi/oss/constant/CloudConstant.java
@@ -1,5 +1,10 @@
package com.ruoyi.oss.constant;
import com.ruoyi.oss.properties.CloudStorageProperties;
import java.util.Arrays;
import java.util.List;
/**
 * äº‘存储常量
 *
@@ -8,13 +13,32 @@
public class CloudConstant {
    /**
     * OSS模块KEY
     */
    public static final String SYS_OSS_KEY = "sys_oss:";
    /**
     * äº‘存储配置KEY
     */
    public final static String CLOUD_STORAGE_CONFIG_KEY = "sys.oss.cloudStorageService";
    public static final String CLOUD_STORAGE_CONFIG_KEY = "CloudStorageConfig";
    /**
     * ç¼“存配置KEY
     */
    public static final String CACHE_CONFIG_KEY = SYS_OSS_KEY + CLOUD_STORAGE_CONFIG_KEY;
    /**
     * é¢„览列表资源开关Key
     */
    public final static String PEREVIEW_LIST_RESOURCE_KEY = "sys.oss.previewListResource";
    public static final String PEREVIEW_LIST_RESOURCE_KEY = "sys.oss.previewListResource";
    /**
     * ç³»ç»Ÿæ•°æ®ids
     */
    public static final List<Integer> SYSTEM_DATA_IDS = Arrays.asList(1, 2, 3, 4);
    public static String getPropertiesName(String key) {
        return key + CloudStorageProperties.class.getSimpleName();
    }
}
ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/CloudServiceEnumd.java
@@ -1,9 +1,10 @@
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 com.ruoyi.common.utils.StringUtils;
import com.ruoyi.oss.service.impl.AliyunCloudStorageStrategy;
import com.ruoyi.oss.service.impl.MinioCloudStorageStrategy;
import com.ruoyi.oss.service.impl.QcloudCloudStorageStrategy;
import com.ruoyi.oss.service.impl.QiniuCloudStorageStrategy;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -19,22 +20,22 @@
    /**
     * ä¸ƒç‰›äº‘
     */
    QINIU("qiniu", QiniuCloudStorageServiceImpl.class),
    QINIU("qiniu", QiniuCloudStorageStrategy.class),
    /**
     * é˜¿é‡Œäº‘
     */
    ALIYUN("aliyun", AliyunCloudStorageServiceImpl.class),
    ALIYUN("aliyun", AliyunCloudStorageStrategy.class),
    /**
     * è…¾è®¯äº‘
     */
    QCLOUD("qcloud", QcloudCloudStorageServiceImpl.class),
    QCLOUD("qcloud", QcloudCloudStorageStrategy.class),
    /**
     * minio
     */
    MINIO("minio", MinioCloudStorageServiceImpl.class);
    MINIO("minio", MinioCloudStorageStrategy.class);
    private final String value;
@@ -48,4 +49,15 @@
        }
        return null;
    }
    public static String getServiceName(String value) {
        for (CloudServiceEnumd clazz : values()) {
            if (clazz.getValue().equals(value)) {
                return StringUtils.uncapitalize(clazz.getServiceClass().getSimpleName());
            }
        }
        return null;
    }
}
ruoyi-oss/src/main/java/com/ruoyi/oss/factory/OssFactory.java
@@ -1,15 +1,16 @@
package com.ruoyi.oss.factory;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.JsonUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.oss.constant.CloudConstant;
import com.ruoyi.oss.enumd.CloudServiceEnumd;
import com.ruoyi.oss.exception.OssException;
import com.ruoyi.oss.service.ICloudStorageService;
import com.ruoyi.oss.properties.CloudStorageProperties;
import com.ruoyi.oss.service.ICloudStorageStrategy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -27,26 +28,37 @@
        OssFactory.redisCache = SpringUtils.getBean(RedisCache.class);
    }
    private static final Map<String, ICloudStorageService> SERVICES = new ConcurrentHashMap<>();
    private static final Map<String, ICloudStorageStrategy> SERVICES = new ConcurrentHashMap<>();
    public static ICloudStorageService instance() {
        String type = Convert.toStr(redisCache.getCacheObject(Constants.SYS_CONFIG_KEY + CloudConstant.CLOUD_STORAGE_CONFIG_KEY));
    public static ICloudStorageStrategy instance() {
        String type = Convert.toStr(redisCache.getCacheObject(CloudConstant.CACHE_CONFIG_KEY));
        if (StringUtils.isEmpty(type)) {
            throw new OssException("文件存储服务类型无法找到!");
        }
        return instance(type);
    }
    public static ICloudStorageService instance(String type) {
        ICloudStorageService service = SERVICES.get(type);
    public static ICloudStorageStrategy instance(String type) {
        ICloudStorageStrategy service = SERVICES.get(type);
        if (service == null) {
            service = (ICloudStorageService) SpringUtils.getBean(CloudServiceEnumd.getServiceClass(type));
            Object json = redisCache.getCacheObject(CloudConstant.SYS_OSS_KEY + type);
            CloudStorageProperties properties = JsonUtils.parseObject(json.toString(), CloudStorageProperties.class);
            String beanName = CloudServiceEnumd.getServiceName(type);
            ICloudStorageStrategy bean = (ICloudStorageStrategy) ReflectUtils.newInstance(CloudServiceEnumd.getServiceClass(type), properties);
            SpringUtils.registerBean(beanName, bean);
            service = SpringUtils.getBean(beanName);
            SERVICES.put(type, bean);
        }
        return service;
    }
    public static void register(String type, ICloudStorageService iCloudStorageService) {
        Assert.notNull(type, "type can't be null");
        SERVICES.put(type, iCloudStorageService);
    public static void destroy(String type) {
        ICloudStorageStrategy service = SERVICES.get(type);
        if (service == null) {
            return;
        }
        SpringUtils.unregisterBean(CloudServiceEnumd.getServiceName(type));
        SERVICES.remove(type);
    }
}
ruoyi-oss/src/main/java/com/ruoyi/oss/properties/CloudStorageProperties.java
@@ -1,9 +1,6 @@
package com.ruoyi.oss.properties;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
 * OSS云存储 é…ç½®å±žæ€§
@@ -11,177 +8,41 @@
 * @author Lion Li
 */
@Data
@Component
@ConfigurationProperties(prefix = "cloud-storage")
public class CloudStorageProperties {
    private Boolean previewListImage;
    private QiniuProperties qiniu;
    private AliyunProperties aliyun;
    private QcloudProperties qcloud;
    private MinioProperties minio;
    /**
     * åŸŸå
     */
    private String endpoint;
    /**
     * é˜¿é‡Œäº‘ é…ç½®å±žæ€§
     *
     * @author Lion Li
     * å‰ç¼€
     */
    @Data
    @NoArgsConstructor
    public static class AliyunProperties {
        /**
         * é˜¿é‡Œäº‘绑定的域名
         */
        private String endpoint;
        /**
         * é˜¿é‡Œäº‘路径前缀
         */
        private String prefix;
        /**
         * é˜¿é‡Œäº‘AccessKeyId
         */
        private String accessKeyId;
        /**
         * é˜¿é‡Œäº‘AccessKeySecret
         */
        private String accessKeySecret;
        /**
         * é˜¿é‡Œäº‘BucketName
         */
        private String bucketName;
    }
    private String prefix;
    /**
     * Minio é…ç½®å±žæ€§
     *
     * @author Lion Li
     * ACCESS_KEY
     */
    @Data
    @NoArgsConstructor
    public static class MinioProperties {
        /**
         * minio域名
         */
        private String endpoint;
        /**
         * minio ACCESS_KEY
         */
        private String accessKey;
        /**
         * minio SECRET_KEY
         */
        private String secretKey;
        /**
         * minio å­˜å‚¨ç©ºé—´å
         */
        private String bucketName;
    }
    private String accessKey;
    /**
     * è…¾è®¯äº‘COS é…ç½®å±žæ€§
     *
     * @author Lion Li
     * SECRET_KEY
     */
    @Data
    @NoArgsConstructor
    public static class QcloudProperties {
        /**
         * è…¾è®¯äº‘绑定的域名
         */
        private String endpoint;
        /**
         * è…¾è®¯äº‘路径前缀
         */
        private String prefix;
        /**
         * è…¾è®¯äº‘SecretId
         */
        private String secretId;
        /**
         * è…¾è®¯äº‘SecretKey
         */
        private String secretKey;
        /**
         * è…¾è®¯äº‘BucketName
         */
        private String bucketName;
        /**
         * ä¸ƒç‰›æ˜¯å¦ä½¿ç”¨https
         */
        private Boolean isHttps;
        /**
         * è…¾è®¯äº‘COS所属地区
         */
        private String region;
    }
    private String secretKey;
    /**
     * ä¸ƒç‰›äº‘ é…ç½®å±žæ€§
     *
     * @author Lion Li
     * å­˜å‚¨ç©ºé—´å
     */
    @Data
    @NoArgsConstructor
    public static class QiniuProperties {
    private String bucketName;
        /**
         * ä¸ƒç‰›ç»‘定的域名
         */
        private String domain;
    /**
     * å­˜å‚¨åŒºåŸŸ
     */
    private String region;
        /**
         * ä¸ƒç‰›è·¯å¾„前缀
         */
        private String prefix;
        /**
         * ä¸ƒç‰›ACCESS_KEY
         */
        private String accessKey;
        /**
         * ä¸ƒç‰›SECRET_KEY
         */
        private String secretKey;
        /**
         * ä¸ƒç‰›å­˜å‚¨ç©ºé—´å
         */
        private String bucketName;
        /**
         * ä¸ƒç‰›å­˜å‚¨åŒºåŸŸ
         */
        private String region;
        /**
         * ä¸ƒç‰›æ˜¯å¦ä½¿ç”¨https
         */
        private Boolean isHttps;
    }
    /**
     * æ˜¯å¦https(Y=是,N=否)
     */
    private String isHttps;
}
ruoyi-oss/src/main/java/com/ruoyi/oss/service/ICloudStorageStrategy.java
ÎļþÃû´Ó ruoyi-oss/src/main/java/com/ruoyi/oss/service/ICloudStorageService.java ÐÞ¸Ä
@@ -5,11 +5,11 @@
import java.io.InputStream;
/**
 * äº‘存储服务接口
 * äº‘存储策略
 *
 * @author Lion Li
 */
public interface ICloudStorageService {
public interface ICloudStorageStrategy {
    void createBucket();
ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractCloudStorageStrategy.java
ÎļþÃû´Ó ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractCloudStorageService.java ÐÞ¸Ä
@@ -5,18 +5,20 @@
import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.oss.entity.UploadResult;
import com.ruoyi.oss.service.ICloudStorageService;
import org.springframework.beans.factory.InitializingBean;
import com.ruoyi.oss.properties.CloudStorageProperties;
import com.ruoyi.oss.service.ICloudStorageStrategy;
import java.io.InputStream;
import java.util.Date;
/**
 * äº‘存储(支持七牛、阿里云、腾讯云、minio)
 * äº‘存储策略(支持七牛、阿里云、腾讯云、minio)
 *
 * @author Lion Li
 */
public abstract class AbstractCloudStorageService implements ICloudStorageService, InitializingBean {
public abstract class AbstractCloudStorageStrategy implements ICloudStorageStrategy {
    protected CloudStorageProperties properties;
    @Override
    public abstract void createBucket();
@@ -53,9 +55,6 @@
    @Override
    public abstract UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType);
    @Override
    public abstract void afterPropertiesSet() throws Exception;
    @Override
    public abstract String getEndpointLink();
ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunCloudStorageStrategy.java
ÎļþÃû´Ó ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunCloudStorageServiceImpl.java ÐÞ¸Ä
@@ -1,6 +1,5 @@
package com.ruoyi.oss.service.impl;
import com.ruoyi.common.utils.StringUtils;
import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
@@ -8,42 +7,32 @@
import com.aliyun.oss.model.CreateBucketRequest;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.ruoyi.common.utils.StringUtils;
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.AliyunProperties;
import com.ruoyi.oss.service.abstractd.AbstractCloudStorageService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/**
 * é˜¿é‡Œäº‘存储
 * é˜¿é‡Œäº‘存储策略
 *
 * @author Lion Li
 */
@Lazy
@Service
public class AliyunCloudStorageServiceImpl extends AbstractCloudStorageService implements InitializingBean {
public class AliyunCloudStorageStrategy extends AbstractCloudStorageStrategy {
    private final OSSClient client;
    private final AliyunProperties properties;
    @Autowired
    public AliyunCloudStorageServiceImpl(CloudStorageProperties properties) {
        this.properties = properties.getAliyun();
    public AliyunCloudStorageStrategy(CloudStorageProperties cloudStorageProperties) {
        properties = cloudStorageProperties;
        try {
            ClientConfiguration configuration = new ClientConfiguration();
            DefaultCredentialProvider credentialProvider = new DefaultCredentialProvider(
                this.properties.getAccessKeyId(),
                this.properties.getAccessKeySecret());
            client = new OSSClient(this.properties.getEndpoint(), credentialProvider, configuration);
                properties.getAccessKey(), properties.getSecretKey());
            client = new OSSClient(properties.getEndpoint(), credentialProvider, configuration);
            createBucket();
        } catch (Exception e) {
            throw new IllegalArgumentException("阿里云存储配置错误! è¯·æ£€æŸ¥ç³»ç»Ÿé…ç½®!");
@@ -105,11 +94,6 @@
    @Override
    public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
        return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        OssFactory.register(getServiceType(), this);
    }
    @Override
ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioCloudStorageStrategy.java
ÎļþÃû´Ó ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioCloudStorageServiceImpl.java ÐÞ¸Ä
@@ -5,39 +5,29 @@
import com.ruoyi.oss.enumd.CloudServiceEnumd;
import com.ruoyi.oss.enumd.PolicyType;
import com.ruoyi.oss.exception.OssException;
import com.ruoyi.oss.factory.OssFactory;
import com.ruoyi.oss.properties.CloudStorageProperties;
import com.ruoyi.oss.properties.CloudStorageProperties.MinioProperties;
import com.ruoyi.oss.service.abstractd.AbstractCloudStorageService;
import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy;
import io.minio.*;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/**
 * minio存储
 * minio存储策略
 *
 * @author Lion Li
 */
@Lazy
@Service
public class MinioCloudStorageServiceImpl extends AbstractCloudStorageService implements InitializingBean {
public class MinioCloudStorageStrategy extends AbstractCloudStorageStrategy {
    private final MinioClient minioClient;
    private final MinioProperties properties;
    @Autowired
    public MinioCloudStorageServiceImpl(CloudStorageProperties properties) {
        this.properties = properties.getMinio();
    public MinioCloudStorageStrategy(CloudStorageProperties cloudStorageProperties) {
        properties = cloudStorageProperties;
        try {
            minioClient = MinioClient.builder()
                .endpoint(this.properties.getEndpoint())
                .credentials(this.properties.getAccessKey(), this.properties.getSecretKey())
                .endpoint(properties.getEndpoint())
                .credentials(properties.getAccessKey(), properties.getSecretKey())
                .build();
            createBucket();
        } catch (Exception e) {
@@ -110,11 +100,6 @@
    @Override
    public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
        return upload(inputStream, getPath("", suffix), contentType);
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        OssFactory.register(getServiceType(), this);
    }
    @Override
ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudCloudStorageStrategy.java
ÎļþÃû´Ó ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudCloudStorageServiceImpl.java ÐÞ¸Ä
@@ -1,6 +1,5 @@
package com.ruoyi.oss.service.impl;
import com.ruoyi.common.utils.StringUtils;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
@@ -8,45 +7,35 @@
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import com.ruoyi.common.utils.StringUtils;
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;
import com.ruoyi.oss.service.abstractd.AbstractCloudStorageService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/**
 * è…¾è®¯äº‘存储
 * è…¾è®¯äº‘存储策略
 *
 * @author Lion Li
 */
@Lazy
@Service
public class QcloudCloudStorageServiceImpl extends AbstractCloudStorageService implements InitializingBean {
public class QcloudCloudStorageStrategy extends AbstractCloudStorageStrategy {
    private final COSClient client;
    private final QcloudProperties properties;
    @Autowired
    public QcloudCloudStorageServiceImpl(CloudStorageProperties properties) {
        this.properties = properties.getQcloud();
    public QcloudCloudStorageStrategy(CloudStorageProperties cloudStorageProperties) {
        properties = cloudStorageProperties;
        try {
            COSCredentials credentials = new BasicCOSCredentials(
                this.properties.getSecretId(),
                this.properties.getSecretKey());
                properties.getAccessKey(), properties.getSecretKey());
            // åˆå§‹åŒ–客户端配置
            ClientConfig clientConfig = new ClientConfig();
            // è®¾ç½®bucket所在的区域,华南:gz åŽåŒ—:tj åŽä¸œï¼šsh
            clientConfig.setRegion(new Region(this.properties.getRegion()));
            if (this.properties.getIsHttps()) {
            clientConfig.setRegion(new Region(properties.getRegion()));
            if ("Y".equals(properties.getIsHttps())) {
                clientConfig.setHttpProtocol(HttpProtocol.https);
            } else {
                clientConfig.setHttpProtocol(HttpProtocol.http);
@@ -113,11 +102,6 @@
    @Override
    public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
        return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        OssFactory.register(getServiceType(),this);
    }
    @Override
ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuCloudStorageStrategy.java
ÎļþÃû´Ó ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuCloudStorageServiceImpl.java ÐÞ¸Ä
@@ -10,51 +10,37 @@
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.QiniuProperties;
import com.ruoyi.oss.service.abstractd.AbstractCloudStorageService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy;
import java.io.InputStream;
/**
 * ä¸ƒç‰›äº‘存储
 * ä¸ƒç‰›äº‘存储策略
 *
 * @author Lion Li
 */
@Lazy
@Service
public class QiniuCloudStorageServiceImpl extends AbstractCloudStorageService implements InitializingBean {
public class QiniuCloudStorageStrategy extends AbstractCloudStorageStrategy {
    private final UploadManager uploadManager;
    private final BucketManager bucketManager;
    private final String token;
    private final QiniuProperties properties;
    @Autowired
    public QiniuCloudStorageServiceImpl(CloudStorageProperties properties) {
        this.properties = properties.getQiniu();
    public QiniuCloudStorageStrategy(CloudStorageProperties cloudStorageProperties) {
        properties = cloudStorageProperties;
        try {
            Configuration config = new Configuration(getRegion(this.properties.getRegion()));
            Configuration config = new Configuration(getRegion(properties.getRegion()));
            // https设置
            config.useHttpsDomains = false;
            if (this.properties.getIsHttps() != null) {
                config.useHttpsDomains = this.properties.getIsHttps();
            }
            config.useHttpsDomains = "Y".equals(properties.getIsHttps());
            uploadManager = new UploadManager(config);
            Auth auth = Auth.create(
                this.properties.getAccessKey(),
                this.properties.getSecretKey());
            String bucketName = this.properties.getBucketName();
            Auth auth = Auth.create(properties.getAccessKey(), properties.getSecretKey());
            String bucketName = properties.getBucketName();
            token = auth.uploadToken(bucketName);
            bucketManager = new BucketManager(auth, config);
            if (!ArrayUtil.contains(bucketManager.buckets(), bucketName)) {
                bucketManager.createBucket(bucketName, this.properties.getRegion());
                bucketManager.createBucket(bucketName, properties.getRegion());
            }
        } catch (Exception e) {
            throw new IllegalArgumentException("七牛云存储配置错误! è¯·æ£€æŸ¥ç³»ç»Ÿé…ç½®!");
@@ -116,13 +102,8 @@
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        OssFactory.register(getServiceType(),this);
    }
    @Override
    public String getEndpointLink() {
        return properties.getDomain();
        return properties.getEndpoint();
    }
    private Region getRegion(String region) {
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java
@@ -48,7 +48,7 @@
     * @param isValid æ˜¯å¦æ ¡éªŒ,true-删除前校验,false-不校验
     * @return
     */
    Boolean deleteWithValidByIds(Collection<Integer> ids, Boolean isValid);
    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
    /**
     * å¯ç”¨åœç”¨çŠ¶æ€
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
@@ -2,7 +2,6 @@
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -10,23 +9,26 @@
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
import com.ruoyi.common.core.page.PagePlus;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.JsonUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.oss.constant.CloudConstant;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.oss.factory.OssFactory;
import com.ruoyi.system.domain.SysOssConfig;
import com.ruoyi.system.domain.bo.SysOssConfigBo;
import com.ruoyi.system.domain.vo.SysOssConfigVo;
import com.ruoyi.system.mapper.SysOssConfigMapper;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysOssConfigService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.Collection;
import java.util.List;
/**
 * äº‘存储配置Service业务层处理
@@ -39,7 +41,22 @@
@Service
public class SysOssConfigServiceImpl extends ServicePlusImpl<SysOssConfigMapper, SysOssConfig, SysOssConfigVo> implements ISysOssConfigService {
    private final ISysConfigService iSysConfigService;
    private final RedisCache redisCache;
    /**
     * é¡¹ç›®å¯åŠ¨æ—¶ï¼Œåˆå§‹åŒ–å‚æ•°åˆ°ç¼“å­˜ï¼ŒåŠ è½½é…ç½®ç±»
     */
    @PostConstruct
    public void init() {
        List<SysOssConfig> list = list();
        for (SysOssConfig config : list) {
            String configKey = config.getConfigKey();
            if ("0".equals(config.getStatus())) {
                redisCache.setCacheObject(CloudConstant.CACHE_CONFIG_KEY, configKey);
            }
            redisCache.setCacheObject(getCacheKey(configKey), JsonUtils.toJsonString(config));
        }
    }
    @Override
    public SysOssConfigVo queryById(Integer ossConfigId){
@@ -63,16 +80,29 @@
    @Override
    public Boolean insertByBo(SysOssConfigBo bo) {
        SysOssConfig add = BeanUtil.toBean(bo, SysOssConfig.class);
        validEntityBeforeSave(add);
        return save(add);
        SysOssConfig config = BeanUtil.toBean(bo, SysOssConfig.class);
        validEntityBeforeSave(config);
        boolean flag = save(config);
        if (flag) {
            redisCache.setCacheObject(
                getCacheKey(config.getConfigKey()),
                JsonUtils.toJsonString(config));
        }
        return flag;
    }
    @Override
    public Boolean updateByBo(SysOssConfigBo bo) {
        SysOssConfig update = BeanUtil.toBean(bo, SysOssConfig.class);
        validEntityBeforeSave(update);
        return updateById(update);
        SysOssConfig config = BeanUtil.toBean(bo, SysOssConfig.class);
        validEntityBeforeSave(config);
        boolean flag = updateById(config);
        if (flag) {
            OssFactory.destroy(config.getConfigKey());
            redisCache.setCacheObject(
                getCacheKey(config.getConfigKey()),
                JsonUtils.toJsonString(config));
        }
        return flag;
    }
    /**
@@ -86,13 +116,21 @@
    }
    @Override
    public Boolean deleteWithValidByIds(Collection<Integer> ids, Boolean isValid) {
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid) {
            if (CollUtil.containsAny(ids, CollUtil.newArrayList(1, 2, 3, 4))) {
            if (CollUtil.containsAny(ids, CloudConstant.SYSTEM_DATA_IDS)) {
                throw new CustomException("系统内置, ä¸å¯åˆ é™¤!");
            }
        }
        return removeByIds(ids);
        boolean flag = removeByIds(ids);
        if (flag) {
            for (Long configId : ids) {
                SysOssConfig config = getById(configId);
                OssFactory.destroy(config.getConfigKey());
                redisCache.deleteObject(getCacheKey(config.getConfigKey()));
            }
        }
        return flag;
    }
    /**
@@ -115,18 +153,23 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateOssConfigStatus(SysOssConfigBo bo) {
        SysConfig sysConfig = iSysConfigService.getOne(new LambdaQueryWrapper<SysConfig>()
                .eq(SysConfig::getConfigKey, CloudConstant.CLOUD_STORAGE_CONFIG_KEY));
        if(ObjectUtil.isNotNull(sysConfig)){
            sysConfig.setConfigValue(bo.getConfigKey());
            iSysConfigService.updateConfig(sysConfig);
        } else {
            throw new CustomException("缺少'云存储配置KEY'参数!");
        }
        SysOssConfig sysOssConfig = BeanUtil.toBean(bo, SysOssConfig.class);
        baseMapper.update(null, new LambdaUpdateWrapper<SysOssConfig>()
        int row = baseMapper.update(null, new LambdaUpdateWrapper<SysOssConfig>()
            .set(SysOssConfig::getStatus, "1"));
        return baseMapper.updateById(sysOssConfig);
        row += baseMapper.updateById(sysOssConfig);
        if (row > 0) {
            redisCache.setCacheObject(CloudConstant.CACHE_CONFIG_KEY, sysOssConfig.getConfigKey());
        }
        return row;
    }
    /**
     * è®¾ç½®cache key
     *
     * @param configKey å‚æ•°é”®
     * @return ç¼“存键key
     */
    private String getCacheKey(String configKey) {
        return CloudConstant.SYS_OSS_KEY + configKey;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java
@@ -10,7 +10,7 @@
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.oss.entity.UploadResult;
import com.ruoyi.oss.factory.OssFactory;
import com.ruoyi.oss.service.ICloudStorageService;
import com.ruoyi.oss.service.ICloudStorageStrategy;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.domain.bo.SysOssBo;
import com.ruoyi.system.domain.vo.SysOssVo;
@@ -56,7 +56,7 @@
    public SysOss upload(MultipartFile file) {
        String originalfileName = file.getOriginalFilename();
        String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
        ICloudStorageService storage = OssFactory.instance();
        ICloudStorageStrategy storage = OssFactory.instance();
        UploadResult uploadResult;
        try {
            uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
@@ -81,7 +81,7 @@
        }
        List<SysOss> list = listByIds(ids);
        for (SysOss sysOss : list) {
            ICloudStorageService storage = OssFactory.instance(sysOss.getService());
            ICloudStorageStrategy storage = OssFactory.instance(sysOss.getService());
            storage.delete(sysOss.getUrl());
        }
        return removeByIds(ids);
ruoyi-ui/src/views/system/oss/config.vue
@@ -158,15 +158,6 @@
        <el-form-item label="域" prop="region">
          <el-input v-model="form.region" placeholder="请输入域" />
        </el-form-item>
        <el-form-item label="状态">
          <el-radio-group v-model="form.status">
            <el-radio
              v-for="dict in statusOptions"
              :key="dict.dictValue"
              :label="dict.dictValue"
            >{{dict.dictLabel}}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
        </el-form-item>
sql/oss.sql
@@ -40,7 +40,6 @@
    primary key (oss_config_id)
) engine=innodb comment='云存储配置表';
insert into sys_config values(10, 'OSS云存储服务商',       'sys.oss.cloudStorageService',      'minio',          'Y', 'admin', sysdate(), '', null, 'OSS云存储服务商(qiniu:七牛云, aliyun:阿里云, qcloud:腾讯云, minio: Minio)');
insert into sys_config values(11, 'OSS预览列表资源开关',   'sys.oss.previewListResource',      'true',           'Y', 'admin', sysdate(), '', null, 'true:开启, false:关闭');
insert into sys_menu values('118',  '文件管理', '1',   '10', 'oss',     'system/oss/index',      1, 0, 'C', '0', '0', 'system:oss:list',      'upload',       'admin', sysdate(), '', null, '文件管理菜单');