add 增加ruoyi-resource资源模块 移除ruoyi-file模块 调整项目结构

2.X
疯狂的狮子li 2022-02-09 18:59:04 +08:00
parent 5870045c35
commit 69e699946f
91 changed files with 3324 additions and 2007 deletions

View File

@ -279,7 +279,7 @@ knife4j:
# seata配置 # seata配置
seata: seata:
# 默认关闭如需启用spring.datasource.dynami.seata需要同时开启 # 默认关闭如需启用spring.datasource.dynami.seata需要同时开启
enabled: false enabled: true
# Seata 应用编号,默认为 ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name}
application-id: ${spring.application.name} application-id: ${spring.application.name}
# Seata 事务组编号,用于 TC 集群名 # Seata 事务组编号,用于 TC 集群名

View File

@ -22,7 +22,7 @@ spring:
# 性能分析插件(有性能损耗 不建议生产环境使用) # 性能分析插件(有性能损耗 不建议生产环境使用)
p6spy: true p6spy: true
# 开启seata代理开启后默认每个数据源都代理如果某个不需要代理可单独关闭 # 开启seata代理开启后默认每个数据源都代理如果某个不需要代理可单独关闭
seata: false seata: true
druid: druid:
initial-size: 5 initial-size: 5
min-idle: 5 min-idle: 5

View File

@ -1,25 +0,0 @@
# dubbo 订阅配置
dubbo:
cloud:
# 需要远程调用的服务 多个用逗号分割
subscribed-services: ruoyi-system
# 本地文件上传
file:
domain: http://127.0.0.1:9300
path: D:/ruoyi/uploadPath
prefix: /statics
# FastDFS配置
fdfs:
domain: http://8.129.231.12
soTimeout: 3000
connectTimeout: 2000
trackerList: 8.129.231.12:22122
# Minio配置
minio:
url: http://8.129.231.12:9000
accessKey: minioadmin
secretKey: minioadmin
bucketName: test

View File

@ -53,13 +53,6 @@ spring:
- Path=/code/** - Path=/code/**
filters: filters:
- StripPrefix=1 - StripPrefix=1
# 定时任务
- id: ruoyi-job
uri: lb://ruoyi-job
predicates:
- Path=/schedule/**
filters:
- StripPrefix=1
# 系统模块 # 系统模块
- id: ruoyi-system - id: ruoyi-system
uri: lb://ruoyi-system uri: lb://ruoyi-system
@ -67,11 +60,11 @@ spring:
- Path=/system/** - Path=/system/**
filters: filters:
- StripPrefix=1 - StripPrefix=1
# 文件服务 # 资源服务
- id: ruoyi-file - id: ruoyi-resource
uri: lb://ruoyi-file uri: lb://ruoyi-resource
predicates: predicates:
- Path=/file/** - Path=/resource/**
filters: filters:
- StripPrefix=1 - StripPrefix=1

View File

@ -0,0 +1,24 @@
# dubbo 订阅配置
dubbo:
cloud:
# 需要远程调用的服务 多个用逗号分割
subscribed-services: ruoyi-system
spring:
datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为 master
primary: master
datasource:
# 主库数据源
master:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${datasource.system-master.url}
username: ${datasource.system-master.username}
password: ${datasource.system-master.password}
# 从库数据源
# slave:
# driver-class-name:
# url:
# username:
# password:

View File

@ -2,7 +2,7 @@
dubbo: dubbo:
cloud: cloud:
# 需要远程调用的服务 多个用逗号分割 # 需要远程调用的服务 多个用逗号分割
subscribed-services: ruoyi-file subscribed-services: ruoyi-resource
spring: spring:
datasource: datasource:

View File

@ -1,6 +1,6 @@
service.vgroupMapping.ruoyi-auth-group=default service.vgroupMapping.ruoyi-auth-group=default
service.vgroupMapping.ruoyi-system-group=default service.vgroupMapping.ruoyi-system-group=default
service.vgroupMapping.ruoyi-file-group=default service.vgroupMapping.ruoyi-resource-group=default
service.vgroupMapping.ruoyi-gen-group=default service.vgroupMapping.ruoyi-gen-group=default
service.enableDegrade=false service.enableDegrade=false
service.disableGlobalTransaction=false service.disableGlobalTransaction=false

40
pom.xml
View File

@ -23,16 +23,12 @@
<alibaba.nacos.version>2.0.4</alibaba.nacos.version> <alibaba.nacos.version>2.0.4</alibaba.nacos.version>
<spring-boot-admin.version>2.6.2</spring-boot-admin.version> <spring-boot-admin.version>2.6.2</spring-boot-admin.version>
<spring-boot.mybatis>2.2.0</spring-boot.mybatis> <spring-boot.mybatis>2.2.0</spring-boot.mybatis>
<swagger.core.version>1.6.2</swagger.core.version> <swagger.core.version>1.5.22</swagger.core.version>
<tobato.version>1.27.2</tobato.version>
<mybatis-plus.version>3.5.1</mybatis-plus.version> <mybatis-plus.version>3.5.1</mybatis-plus.version>
<p6spy.version>3.9.1</p6spy.version> <p6spy.version>3.9.1</p6spy.version>
<druid.version>1.2.8</druid.version> <druid.version>1.2.8</druid.version>
<dynamic-ds.version>3.5.0</dynamic-ds.version> <dynamic-ds.version>3.5.0</dynamic-ds.version>
<commons.io.version>2.11.0</commons.io.version>
<commons.fileupload.version>1.4</commons.fileupload.version>
<velocity.version>2.3</velocity.version> <velocity.version>2.3</velocity.version>
<minio.version>8.2.2</minio.version>
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>
<easyexcel.version>3.0.5</easyexcel.version> <easyexcel.version>3.0.5</easyexcel.version>
<cglib.version>3.3.0</cglib.version> <cglib.version>3.3.0</cglib.version>
@ -54,6 +50,7 @@
<aliyun.oss.version>3.14.0</aliyun.oss.version> <aliyun.oss.version>3.14.0</aliyun.oss.version>
<qcloud.cos.version>5.6.68</qcloud.cos.version> <qcloud.cos.version>5.6.68</qcloud.cos.version>
<minio.version>8.3.5</minio.version> <minio.version>8.3.5</minio.version>
<okhttp.version>4.9.2</okhttp.version>
<!-- docker 配置 --> <!-- docker 配置 -->
<docker.registry.url>localhost</docker.registry.url> <docker.registry.url>localhost</docker.registry.url>
@ -178,11 +175,10 @@
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
<!-- FastDFS 分布式文件系统 -->
<dependency> <dependency>
<groupId>com.github.tobato</groupId> <groupId>cn.dev33</groupId>
<artifactId>fastdfs-client</artifactId> <artifactId>sa-token-core</artifactId>
<version>${tobato.version}</version> <version>${satoken.version}</version>
</dependency> </dependency>
<!-- Mybatis 依赖配置 --> <!-- Mybatis 依赖配置 -->
@ -193,9 +189,9 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.swagger</groupId> <groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-models</artifactId> <artifactId>knife4j-micro-spring-boot-starter</artifactId>
<version>${swagger.core.version}</version> <version>${knife4j.version}</version>
</dependency> </dependency>
<!-- Swagger 依赖配置 --> <!-- Swagger 依赖配置 -->
@ -223,13 +219,6 @@
<version>${p6spy.version}</version> <version>${p6spy.version}</version>
</dependency> </dependency>
<!-- io常用工具类 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<!-- excel工具 --> <!-- excel工具 -->
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
@ -259,13 +248,6 @@
<version>${cglib.version}</version> <version>${cglib.version}</version>
</dependency> </dependency>
<!-- 文件上传工具类 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons.fileupload.version}</version>
</dependency>
<!-- 代码生成使用模板 --> <!-- 代码生成使用模板 -->
<dependency> <dependency>
<groupId>org.apache.velocity</groupId> <groupId>org.apache.velocity</groupId>
@ -301,9 +283,9 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.xiaoymin</groupId> <groupId>com.squareup.okhttp3</groupId>
<artifactId>knife4j-micro-spring-boot-starter</artifactId> <artifactId>okhttp</artifactId>
<version>${knife4j.version}</version> <version>${okhttp.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -11,7 +11,7 @@
<modules> <modules>
<module>ruoyi-api-bom</module> <module>ruoyi-api-bom</module>
<module>ruoyi-api-system</module> <module>ruoyi-api-system</module>
<module>ruoyi-api-file</module> <module>ruoyi-api-resource</module>
</modules> </modules>
<artifactId>ruoyi-api</artifactId> <artifactId>ruoyi-api</artifactId>

View File

@ -23,10 +23,10 @@
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<!-- 文件服务接口 --> <!-- 资源服务接口 -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api-file</artifactId> <artifactId>ruoyi-api-resource</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>

View File

@ -9,10 +9,10 @@
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-api-file</artifactId> <artifactId>ruoyi-api-resource</artifactId>
<description> <description>
ruoyi-api-file文件服务接口模块 ruoyi-api-resource 资源服务接口模块
</description> </description>
<dependencies> <dependencies>

View File

@ -1,6 +1,6 @@
package com.ruoyi.file.api; package com.ruoyi.resource.api;
import com.ruoyi.file.api.domain.SysFile; import com.ruoyi.resource.api.domain.SysFile;
/** /**
* *

View File

@ -1,4 +1,4 @@
package com.ruoyi.file.api.domain; package com.ruoyi.resource.api.domain;
import lombok.Data; import lombok.Data;

View File

@ -18,7 +18,6 @@
<module>ruoyi-common-swagger</module> <module>ruoyi-common-swagger</module>
<module>ruoyi-common-security</module> <module>ruoyi-common-security</module>
<module>ruoyi-common-satoken</module> <module>ruoyi-common-satoken</module>
<module>ruoyi-common-datasource</module>
<module>ruoyi-common-web</module> <module>ruoyi-common-web</module>
<module>ruoyi-common-mybatis</module> <module>ruoyi-common-mybatis</module>
<module>ruoyi-common-job</module> <module>ruoyi-common-job</module>

View File

@ -42,13 +42,6 @@
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<!-- 多数据源 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datasource</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 日志记录 --> <!-- 日志记录 -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>

View File

@ -66,18 +66,6 @@
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
</dependency> </dependency>
<!-- Commons Io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- Commons Fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<dependency> <dependency>
<groupId>cglib</groupId> <groupId>cglib</groupId>
<artifactId>cglib</artifactId> <artifactId>cglib</artifactId>

View File

@ -1,69 +0,0 @@
package com.ruoyi.common.core.exception.file;
import org.apache.commons.fileupload.FileUploadException;
import java.util.Arrays;
/**
*
*
* @author ruoyi
*/
public class InvalidExtensionException extends FileUploadException {
private static final long serialVersionUID = 1L;
private String[] allowedExtension;
private String extension;
private String filename;
public InvalidExtensionException(String[] allowedExtension, String extension, String filename) {
super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]");
this.allowedExtension = allowedExtension;
this.extension = extension;
this.filename = filename;
}
public String[] getAllowedExtension() {
return allowedExtension;
}
public String getExtension() {
return extension;
}
public String getFilename() {
return filename;
}
public static class InvalidImageExtensionException extends InvalidExtensionException {
private static final long serialVersionUID = 1L;
public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) {
super(allowedExtension, extension, filename);
}
}
public static class InvalidFlashExtensionException extends InvalidExtensionException {
private static final long serialVersionUID = 1L;
public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) {
super(allowedExtension, extension, filename);
}
}
public static class InvalidMediaExtensionException extends InvalidExtensionException {
private static final long serialVersionUID = 1L;
public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) {
super(allowedExtension, extension, filename);
}
}
public static class InvalidVideoExtensionException extends InvalidExtensionException {
private static final long serialVersionUID = 1L;
public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) {
super(allowedExtension, extension, filename);
}
}
}

View File

@ -1,64 +0,0 @@
package com.ruoyi.common.core.utils.file;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
/**
*
*
* @author ruoyi
*/
public class FileTypeUtils {
/**
*
* <p>
* : ruoyi.txt, : txt
*
* @param file
* @return ".")
*/
public static String getFileType(File file) {
if (null == file) {
return StringUtils.EMPTY;
}
return getFileType(file.getName());
}
/**
*
* <p>
* : ruoyi.txt, : txt
*
* @param fileName
* @return ".")
*/
public static String getFileType(String fileName) {
int separatorIndex = fileName.lastIndexOf(".");
if (separatorIndex < 0) {
return "";
}
return fileName.substring(separatorIndex + 1).toLowerCase();
}
/**
*
*
* @param photoByte
* @return ".")
*/
public static String getFileExtendName(byte[] photoByte) {
String strFileExtendName = "JPG";
if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
&& ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) {
strFileExtendName = "GIF";
} else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) {
strFileExtendName = "JPG";
} else if ((photoByte[0] == 66) && (photoByte[1] == 77)) {
strFileExtendName = "BMP";
} else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) {
strFileExtendName = "PNG";
}
return strFileExtendName;
}
}

View File

@ -1,71 +0,0 @@
package com.ruoyi.common.core.utils.file;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
/**
*
*
* @author ruoyi
*/
public class ImageUtils {
private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);
public static byte[] getImage(String imagePath) {
InputStream is = getFile(imagePath);
try {
return IOUtils.toByteArray(is);
} catch (Exception e) {
log.error("图片加载异常 {}", e);
return null;
} finally {
IOUtils.closeQuietly(is);
}
}
public static InputStream getFile(String imagePath) {
try {
byte[] result = readFile(imagePath);
result = Arrays.copyOf(result, result.length);
return new ByteArrayInputStream(result);
} catch (Exception e) {
log.error("获取图片异常 {}", e);
}
return null;
}
/**
*
*
* @param key
* @return
*/
public static byte[] readFile(String url) {
InputStream in = null;
ByteArrayOutputStream baos = null;
try {
// 网络地址
URL urlObj = new URL(url);
URLConnection urlConnection = urlObj.openConnection();
urlConnection.setConnectTimeout(30 * 1000);
urlConnection.setReadTimeout(60 * 1000);
urlConnection.setDoInput(true);
in = urlConnection.getInputStream();
return IOUtils.toByteArray(in);
} catch (Exception e) {
log.error("访问文件异常 {}", e);
return null;
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(baos);
}
}
}

View File

@ -1,56 +0,0 @@
package com.ruoyi.common.core.utils.file;
/**
*
*
* @author ruoyi
*/
public class MimeTypeUtils {
public static final String IMAGE_PNG = "image/png";
public static final String IMAGE_JPG = "image/jpg";
public static final String IMAGE_JPEG = "image/jpeg";
public static final String IMAGE_BMP = "image/bmp";
public static final String IMAGE_GIF = "image/gif";
public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"};
public static final String[] FLASH_EXTENSION = {"swf", "flv"};
public static final String[] MEDIA_EXTENSION = {"swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
"asf", "rm", "rmvb"};
public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"};
public static final String[] DEFAULT_ALLOWED_EXTENSION = {
// 图片
"bmp", "gif", "jpg", "jpeg", "png",
// word excel powerpoint
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
// 压缩文件
"rar", "zip", "gz", "bz2",
// 视频格式
"mp4", "avi", "rmvb",
// pdf
"pdf"};
public static String getExtension(String prefix) {
switch (prefix) {
case IMAGE_PNG:
return "png";
case IMAGE_JPG:
return "jpg";
case IMAGE_JPEG:
return "jpeg";
case IMAGE_BMP:
return "bmp";
case IMAGE_GIF:
return "gif";
default:
return "";
}
}
}

View File

@ -0,0 +1,9 @@
package com.ruoyi.common.core.validate;
/**
* add
*
* @author Lion Li
*/
public interface AddGroup {
}

View File

@ -0,0 +1,9 @@
package com.ruoyi.common.core.validate;
/**
* edit
*
* @author Lion Li
*/
public interface EditGroup {
}

View File

@ -0,0 +1,9 @@
package com.ruoyi.common.core.validate;
/**
* query
*
* @author Lion Li
*/
public interface QueryGroup {
}

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>0.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-datasource</artifactId>
<description>
ruoyi-common-datasource多数据源
</description>
<dependencies>
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- Dynamic DataSource -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-ds.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -1,18 +0,0 @@
package com.ruoyi.common.datasource.annotation;
import com.baomidou.dynamic.datasource.annotation.DS;
import java.lang.annotation.*;
/**
*
*
* @author ruoyi
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@DS("master")
public @interface Master {
}

View File

@ -1,18 +0,0 @@
package com.ruoyi.common.datasource.annotation;
import com.baomidou.dynamic.datasource.annotation.DS;
import java.lang.annotation.*;
/**
*
*
* @author ruoyi
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@DS("slave")
public @interface Slave {
}

View File

@ -1 +0,0 @@
org.springframework.boot.env.EnvironmentPostProcessor=

View File

@ -38,5 +38,19 @@
<groupId>p6spy</groupId> <groupId>p6spy</groupId>
<artifactId>p6spy</artifactId> <artifactId>p6spy</artifactId>
</dependency> </dependency>
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- Dynamic DataSource -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-ds.version}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,11 +1,13 @@
package com.ruoyi.common.mybatis.config; package com.ruoyi.common.mybatis.config;
import cn.hutool.core.net.NetUtil; import cn.hutool.core.net.NetUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator; import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.ruoyi.common.mybatis.handler.CreateAndUpdateMetaObjectHandler;
import com.ruoyi.common.mybatis.interceptor.PlusDataPermissionInterceptor; import com.ruoyi.common.mybatis.interceptor.PlusDataPermissionInterceptor;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -64,10 +66,10 @@ public class MybatisPlusConfiguration {
/** /**
* *
*/ */
// @Bean @Bean
// public MetaObjectHandler metaObjectHandler() { public MetaObjectHandler metaObjectHandler() {
// return new CreateAndUpdateMetaObjectHandler(); return new CreateAndUpdateMetaObjectHandler();
// } }
/** /**
* 使 * 使

View File

@ -1 +1,5 @@
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

View File

@ -20,7 +20,6 @@
<dependency> <dependency>
<groupId>cn.dev33</groupId> <groupId>cn.dev33</groupId>
<artifactId>sa-token-core</artifactId> <artifactId>sa-token-core</artifactId>
<version>${satoken.version}</version>
</dependency> </dependency>
<!-- Sa-Token 整合 jwt --> <!-- Sa-Token 整合 jwt -->

View File

@ -36,8 +36,9 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>cn.dev33</groupId>
<artifactId>lombok</artifactId> <artifactId>sa-token-core</artifactId>
<scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,7 +1,10 @@
package com.ruoyi.common.swagger.config; package com.ruoyi.common.swagger.config;
import cn.dev33.satoken.config.SaTokenConfig;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.ruoyi.common.swagger.config.properties.SwaggerProperties; import com.ruoyi.common.swagger.config.properties.SwaggerProperties;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -31,6 +34,9 @@ import java.util.function.Predicate;
@ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true) @ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true)
public class SwaggerAutoConfiguration { public class SwaggerAutoConfiguration {
@Autowired
private SaTokenConfig saTokenConfig;
/** /**
* Spring Boot * Spring Boot
*/ */
@ -57,6 +63,7 @@ public class SwaggerAutoConfiguration {
swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path))); swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path)));
ApiSelectorBuilder builder = new Docket(DocumentationType.OAS_30) ApiSelectorBuilder builder = new Docket(DocumentationType.OAS_30)
.enable(swaggerProperties.getEnabled())
.host(swaggerProperties.getHost()) .host(swaggerProperties.getHost())
.apiInfo(apiInfo(swaggerProperties)) .apiInfo(apiInfo(swaggerProperties))
.select() .select()
@ -76,7 +83,8 @@ public class SwaggerAutoConfiguration {
*/ */
private List<SecurityScheme> securitySchemes() { private List<SecurityScheme> securitySchemes() {
List<SecurityScheme> apiKeyList = new ArrayList<>(); List<SecurityScheme> apiKeyList = new ArrayList<>();
apiKeyList.add(new ApiKey("Authorization", "Authorization", "header")); String header = saTokenConfig.getTokenName();
apiKeyList.add(new ApiKey(header, header, In.HEADER.toValue()));
return apiKeyList; return apiKeyList;
} }
@ -101,7 +109,7 @@ public class SwaggerAutoConfiguration {
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope; authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>(); List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); securityReferences.add(new SecurityReference(saTokenConfig.getTokenName(), authorizationScopes));
return securityReferences; return securityReferences;
} }

View File

@ -11,7 +11,7 @@
<modules> <modules>
<module>ruoyi-system</module> <module>ruoyi-system</module>
<module>ruoyi-gen</module> <module>ruoyi-gen</module>
<module>ruoyi-file</module> <module>ruoyi-resource</module>
</modules> </modules>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>

View File

@ -1,46 +0,0 @@
package com.ruoyi.file.config;
import io.minio.MinioClient;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Minio
*
* @author ruoyi
*/
@Data
@NoArgsConstructor
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
/**
*
*/
private String url;
/**
*
*/
private String accessKey;
/**
*
*/
private String secretKey;
/**
*
*/
private String bucketName;
@Bean
public MinioClient getMinioClient() {
return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();
}
}

View File

@ -1,50 +0,0 @@
package com.ruoyi.file.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.io.File;
/**
*
*
* @author ruoyi
*/
@Configuration
public class ResourcesConfig implements WebMvcConfigurer {
/**
*
*/
@Value("${file.path}")
private String localFilePath;
/**
*
*/
@Value("${file.prefix}")
public String localFilePrefix;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/** 本地文件上传路径 */
registry.addResourceHandler(localFilePrefix + "/**")
.addResourceLocations("file:" + localFilePath + File.separator);
}
/**
*
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
// 设置允许跨域的路由
registry.addMapping(localFilePrefix + "/**")
// 设置允许跨域请求的域名
.allowedOrigins("*")
// 设置允许的方法
.allowedMethods("GET");
}
}

View File

@ -1,44 +0,0 @@
package com.ruoyi.file.controller;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.file.FileUtils;
import com.ruoyi.file.api.domain.SysFile;
import com.ruoyi.file.service.ISysFileService;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
/**
*
*
* @author ruoyi
*/
@Api(tags = "文件处理")
@Slf4j
@RequiredArgsConstructor
@RestController
public class SysFileController {
private final ISysFileService sysFileService;
/**
*
*/
@PostMapping("upload")
public R<SysFile> upload(MultipartFile file) {
try {
// 上传并返回访问地址
String url = sysFileService.uploadFile(file);
SysFile sysFile = new SysFile();
sysFile.setName(FileUtils.getName(url));
sysFile.setUrl(url);
return R.ok(sysFile);
} catch (Exception e) {
log.error("上传文件失败", e);
return R.fail(e.getMessage());
}
}
}

View File

@ -1,102 +0,0 @@
package com.ruoyi.file.dubbo;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.file.FileUtils;
import com.ruoyi.file.api.RemoteFileService;
import com.ruoyi.file.api.domain.SysFile;
import com.ruoyi.file.service.ISysFileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
/**
*
*
* @author ruoyi
*/
@Slf4j
@Service
@DubboService
public class RemoteFileServiceImpl implements RemoteFileService {
@Autowired
private ISysFileService sysFileService;
/**
*
*/
@Override
public SysFile upload(String name, String originalFilename, String contentType, byte[] file) {
// todo 临时用于测试 seata
// throw new ServiceException("上传文件失败");
MultipartFile multipartFile = getMultipartFile(name, originalFilename, contentType, file);
try {
// 上传并返回访问地址
String url = sysFileService.uploadFile(multipartFile);
SysFile sysFile = new SysFile();
sysFile.setName(FileUtils.getName(url));
sysFile.setUrl(url);
return sysFile;
} catch (Exception e) {
log.error("上传文件失败", e);
throw new ServiceException("上传文件失败");
}
}
private MultipartFile getMultipartFile(String name, String originalFilename, String contentType, byte[] file) {
return new MultipartFile() {
@Override
public String getName() {
return name;
}
@Override
public String getOriginalFilename() {
return originalFilename;
}
@Override
public String getContentType() {
return contentType;
}
@Override
public boolean isEmpty() {
return getSize() == 0;
}
@Override
public long getSize() {
return file.length;
}
@Override
public byte[] getBytes() throws IOException {
return file;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(file);
}
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(dest);
outputStream.write(file);
} finally {
if (outputStream != null) {
outputStream.close();
}
}
}
};
}
}

View File

@ -1,40 +0,0 @@
package com.ruoyi.file.service;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
/**
* FastDFS
*
* @author ruoyi
*/
@Service
public class FastDfsSysFileServiceImpl implements ISysFileService {
/**
* 访
*/
@Value("${fdfs.domain}")
public String domain;
@Autowired
private FastFileStorageClient storageClient;
/**
* FastDfs
*
* @param file
* @return 访
* @throws Exception
*/
@Override
public String uploadFile(MultipartFile file) throws Exception {
StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(),
FilenameUtils.getExtension(file.getOriginalFilename()), null);
return domain + "/" + storePath.getFullPath();
}
}

View File

@ -1,19 +0,0 @@
package com.ruoyi.file.service;
import org.springframework.web.multipart.MultipartFile;
/**
*
*
* @author ruoyi
*/
public interface ISysFileService {
/**
*
*
* @param file
* @return 访
* @throws Exception
*/
String uploadFile(MultipartFile file) throws Exception;
}

View File

@ -1,48 +0,0 @@
package com.ruoyi.file.service;
import com.ruoyi.file.utils.FileUploadUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
/**
*
*
* @author ruoyi
*/
@Primary
@Service
public class LocalSysFileServiceImpl implements ISysFileService {
/**
*
*/
@Value("${file.prefix}")
public String localFilePrefix;
/**
* 访
*/
@Value("${file.domain}")
public String domain;
/**
*
*/
@Value("${file.path}")
private String localFilePath;
/**
*
*
* @param file
* @return 访
* @throws Exception
*/
@Override
public String uploadFile(MultipartFile file) throws Exception {
String name = FileUploadUtils.upload(localFilePath, file);
String url = domain + localFilePrefix + name;
return url;
}
}

View File

@ -1,43 +0,0 @@
package com.ruoyi.file.service;
import com.ruoyi.file.config.MinioConfig;
import com.ruoyi.file.utils.FileUploadUtils;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
/**
* Minio
*
* @author ruoyi
*/
@Service
public class MinioSysFileServiceImpl implements ISysFileService {
@Autowired
private MinioConfig minioConfig;
@Autowired
private MinioClient client;
/**
*
*
* @param file
* @return 访
* @throws Exception
*/
@Override
public String uploadFile(MultipartFile file) throws Exception {
String fileName = FileUploadUtils.extractFilename(file);
PutObjectArgs args = PutObjectArgs.builder()
.bucket(minioConfig.getBucketName())
.object(fileName)
.stream(file.getInputStream(), file.getSize(), -1)
.contentType(file.getContentType())
.build();
client.putObject(args);
return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
}
}

View File

@ -1,168 +0,0 @@
package com.ruoyi.file.utils;
import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.core.exception.file.FileNameLengthLimitExceededException;
import com.ruoyi.common.core.exception.file.FileSizeLimitExceededException;
import com.ruoyi.common.core.exception.file.InvalidExtensionException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.file.MimeTypeUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
/**
*
*
* @author ruoyi
*/
public class FileUploadUtils {
/**
* 50M
*/
public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
/**
* 100
*/
public static final int DEFAULT_FILE_NAME_LENGTH = 100;
/**
*
*
* @param baseDir
* @param file
* @return
* @throws IOException
*/
public static final String upload(String baseDir, MultipartFile file) throws IOException {
try {
return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
} catch (Exception e) {
throw new IOException(e.getMessage(), e);
}
}
/**
*
*
* @param baseDir
* @param file
* @param allowedExtension
* @return
* @throws FileSizeLimitExceededException
* @throws FileNameLengthLimitExceededException
* @throws IOException
* @throws InvalidExtensionException
*/
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
InvalidExtensionException {
int fileNamelength = file.getOriginalFilename().length();
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) {
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
}
assertAllowed(file, allowedExtension);
String fileName = extractFilename(file);
File desc = getAbsoluteFile(baseDir, fileName);
file.transferTo(desc);
String pathFileName = getPathFileName(fileName);
return pathFileName;
}
/**
*
*/
public static final String extractFilename(MultipartFile file) {
String fileName = file.getOriginalFilename();
String extension = getExtension(file);
fileName = DateUtils.datePath() + "/" + IdUtil.fastUUID() + "." + extension;
return fileName;
}
private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException {
File desc = new File(uploadDir + File.separator + fileName);
if (!desc.exists()) {
if (!desc.getParentFile().exists()) {
desc.getParentFile().mkdirs();
}
}
return desc.isAbsolute() ? desc : desc.getAbsoluteFile();
}
private static final String getPathFileName(String fileName) throws IOException {
String pathFileName = "/" + fileName;
return pathFileName;
}
/**
*
*
* @param file
* @throws FileSizeLimitExceededException
* @throws InvalidExtensionException
*/
public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
throws FileSizeLimitExceededException, InvalidExtensionException {
long size = file.getSize();
if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE) {
throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
}
String fileName = file.getOriginalFilename();
String extension = getExtension(file);
if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) {
if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) {
throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
fileName);
} else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) {
throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
fileName);
} else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) {
throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
fileName);
} else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) {
throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
fileName);
} else {
throw new InvalidExtensionException(allowedExtension, extension, fileName);
}
}
}
/**
* MIMEMIME
*
* @param extension
* @param allowedExtension
* @return true/false
*/
public static final boolean isAllowedExtension(String extension, String[] allowedExtension) {
for (String str : allowedExtension) {
if (str.equalsIgnoreCase(extension)) {
return true;
}
}
return false;
}
/**
*
*
* @param file
* @return
*/
public static final String getExtension(MultipartFile file) {
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
if (StringUtils.isEmpty(extension)) {
extension = MimeTypeUtils.getExtension(file.getContentType());
}
return extension;
}
}

View File

@ -1,10 +0,0 @@
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}
_ __ _ _
(_) / _|(_)| |
_ __ _ _ ___ _ _ _ ______ | |_ _ | | ___
| '__|| | | | / _ \ | | | || ||______|| _|| || | / _ \
| | | |_| || (_) || |_| || | | | | || || __/
|_| \__,_| \___/ \__, ||_| |_| |_||_| \___|
__/ |
|___/

View File

@ -81,12 +81,6 @@
<artifactId>ruoyi-common-mybatis</artifactId> <artifactId>ruoyi-common-mybatis</artifactId>
</dependency> </dependency>
<!-- RuoYi Common DataSource -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datasource</artifactId>
</dependency>
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-dubbo</artifactId> <artifactId>ruoyi-common-dubbo</artifactId>

View File

@ -10,6 +10,7 @@ import com.ruoyi.common.core.constant.GenConstants;
import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.JsonUtils; import com.ruoyi.common.core.utils.JsonUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.file.FileUtils;
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.satoken.utils.LoginHelper; import com.ruoyi.common.satoken.utils.LoginHelper;
@ -22,8 +23,6 @@ import com.ruoyi.gen.util.VelocityInitializer;
import com.ruoyi.gen.util.VelocityUtils; import com.ruoyi.gen.util.VelocityUtils;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.Template; import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext; import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity; import org.apache.velocity.app.Velocity;
@ -261,8 +260,8 @@ public class GenTableServiceImpl implements IGenTableService {
tpl.merge(context, sw); tpl.merge(context, sw);
try { try {
String path = getGenPath(table, template); String path = getGenPath(table, template);
FileUtils.writeStringToFile(new File(path), sw.toString(), StandardCharsets.UTF_8); FileUtils.writeUtf8String(sw.toString(), path);
} catch (IOException e) { } catch (Exception e) {
throw new ServiceException("渲染模板失败,表名:" + table.getTableName()); throw new ServiceException("渲染模板失败,表名:" + table.getTableName());
} }
} }
@ -355,8 +354,8 @@ public class GenTableServiceImpl implements IGenTableService {
try { try {
// 添加到zip // 添加到zip
zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table))); zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table)));
IOUtils.write(sw.toString(), zip, Constants.UTF8); IoUtil.write(zip, StandardCharsets.UTF_8, false, sw.toString());
IOUtils.closeQuietly(sw); IoUtil.close(sw);
zip.flush(); zip.flush();
zip.closeEntry(); zip.closeEntry();
} catch (IOException e) { } catch (IOException e) {

View File

@ -9,10 +9,10 @@
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-file</artifactId> <artifactId>ruoyi-resource</artifactId>
<description> <description>
ruoyi-file文件服务 ruoyi-resource资源服务
</description> </description>
<dependencies> <dependencies>
@ -35,30 +35,18 @@
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency> </dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- SpringBoot Actuator --> <!-- SpringBoot Actuator -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependency>
<!-- FastDFS -->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
</dependency>
<!-- Minio -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio.version}</version>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api-file</artifactId>
</dependency>
<!-- RuoYi Common Swagger --> <!-- RuoYi Common Swagger -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
@ -80,6 +68,32 @@
<artifactId>ruoyi-common-web</artifactId> <artifactId>ruoyi-common-web</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-log</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-oss</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-mybatis</artifactId>
</dependency>
<!-- RuoYi Api System -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api-system</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api-resource</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -1,4 +1,4 @@
package com.ruoyi.file; package com.ruoyi.resource;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
@ -6,15 +6,15 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
/** /**
* *
* *
* @author ruoyi * @author Lion Li
*/ */
@EnableDubbo @EnableDubbo
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class RuoYiFileApplication { public class RuoYiResourceApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(RuoYiFileApplication.class, args); SpringApplication.run(RuoYiResourceApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 文件服务模块启动成功 ლ(´ڡ`ლ)゙ "); System.out.println("(♥◠‿◠)ノ゙ 资源服务模块启动成功 ლ(´ڡ`ლ)゙ ");
} }
} }

View File

@ -0,0 +1,110 @@
package com.ruoyi.resource.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.core.validate.QueryGroup;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.resource.domain.bo.SysOssConfigBo;
import com.ruoyi.resource.domain.vo.SysOssConfigVo;
import com.ruoyi.resource.service.ISysOssConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
/**
* Controller
*
* @author Lion Li
* @author
* @date 2021-08-13
*/
@Validated
@Api(value = "对象存储配置控制器", tags = {"对象存储配置管理"})
@RequiredArgsConstructor
@RestController
@RequestMapping("/oss/config")
public class SysOssConfigController extends BaseController {
private final ISysOssConfigService iSysOssConfigService;
/**
*
*/
@ApiOperation("查询对象存储配置列表")
@SaCheckPermission("system:oss:list")
@GetMapping("/list")
public TableDataInfo<SysOssConfigVo> list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) {
return iSysOssConfigService.queryPageList(bo, pageQuery);
}
/**
*
*/
@ApiOperation("获取对象存储配置详细信息")
@SaCheckPermission("system:oss:query")
@GetMapping("/{ossConfigId}")
public R<SysOssConfigVo> getInfo(@ApiParam("OSS配置ID")
@NotNull(message = "主键不能为空")
@PathVariable("ossConfigId") Integer ossConfigId) {
return R.ok(iSysOssConfigService.queryById(ossConfigId));
}
/**
*
*/
@ApiOperation("新增对象存储配置")
@SaCheckPermission("system:oss:add")
@Log(title = "对象存储配置", businessType = BusinessType.INSERT)
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody SysOssConfigBo bo) {
return toAjax(iSysOssConfigService.insertByBo(bo) ? 1 : 0);
}
/**
*
*/
@ApiOperation("修改对象存储配置")
@SaCheckPermission("system:oss:edit")
@Log(title = "对象存储配置", businessType = BusinessType.UPDATE)
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysOssConfigBo bo) {
return toAjax(iSysOssConfigService.updateByBo(bo) ? 1 : 0);
}
/**
*
*/
@ApiOperation("删除对象存储配置")
@SaCheckPermission("system:oss:remove")
@Log(title = "对象存储配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ossConfigIds}")
public R<Void> remove(@ApiParam("OSS配置ID串")
@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ossConfigIds) {
return toAjax(iSysOssConfigService.deleteWithValidByIds(Arrays.asList(ossConfigIds), true) ? 1 : 0);
}
/**
*
*/
@ApiOperation("状态修改")
@SaCheckPermission("system:oss:edit")
@Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) {
return toAjax(iSysOssConfigService.updateOssConfigStatus(bo));
}
}

View File

@ -0,0 +1,119 @@
package com.ruoyi.resource.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpUtil;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.file.FileUtils;
import com.ruoyi.common.core.validate.QueryGroup;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.resource.domain.SysOss;
import com.ruoyi.resource.domain.bo.SysOssBo;
import com.ruoyi.resource.domain.vo.SysOssVo;
import com.ruoyi.resource.service.ISysOssService;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
*
*
* @author Lion Li
*/
@Validated
@Api(value = "对象存储控制器", tags = {"对象存储管理"})
@RequiredArgsConstructor
@RestController
@RequestMapping("/oss")
public class SysOssController extends BaseController {
private final ISysOssService iSysOssService;
/**
* OSS
*/
@ApiOperation("查询OSS对象存储列表")
@SaCheckPermission("system:oss:list")
@GetMapping("/list")
public TableDataInfo<SysOssVo> list(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) {
return iSysOssService.queryPageList(bo, pageQuery);
}
/**
* OSS
*/
@ApiOperation("上传OSS对象存储")
@ApiImplicitParams({
@ApiImplicitParam(name = "file", value = "文件", dataTypeClass = File.class, required = true),
})
@SaCheckPermission("system:oss:upload")
@Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
@PostMapping("/upload")
public R<Map<String, String>> upload(@RequestPart("file") MultipartFile file) {
if (ObjectUtil.isNull(file)) {
throw new ServiceException("上传文件不能为空");
}
SysOss oss = iSysOssService.upload(file);
Map<String, String> map = new HashMap<>(2);
map.put("url", oss.getUrl());
map.put("fileName", oss.getFileName());
return R.ok(map);
}
@ApiOperation("下载OSS对象存储")
@SaCheckPermission("system:oss:download")
@GetMapping("/download/{ossId}")
public void download(@ApiParam("OSS对象ID") @PathVariable Long ossId, HttpServletResponse response) throws IOException {
SysOss sysOss = iSysOssService.getById(ossId);
if (ObjectUtil.isNull(sysOss)) {
throw new ServiceException("文件数据不存在!");
}
response.reset();
FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName());
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
long data;
try {
data = HttpUtil.download(sysOss.getUrl(), response.getOutputStream(), false);
} catch (HttpException e) {
if (e.getMessage().contains("403")) {
throw new ServiceException("无读取权限, 请在对应的OSS开启'公有读'权限!");
} else {
throw new ServiceException(e.getMessage());
}
}
response.setContentLength(Convert.toInt(data));
}
/**
* OSS
*/
@ApiOperation("删除OSS对象存储")
@SaCheckPermission("system:oss:remove")
@Log(title = "OSS对象存储", businessType = BusinessType.DELETE)
@DeleteMapping("/{ossIds}")
public R<Void> remove(@ApiParam("OSS对象ID串")
@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ossIds) {
return toAjax(iSysOssService.deleteWithValidByIds(Arrays.asList(ossIds), true) ? 1 : 0);
}
}

View File

@ -0,0 +1,51 @@
package com.ruoyi.resource.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.core.web.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* OSS
*
* @author Lion Li
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_oss")
public class SysOss extends BaseEntity {
/**
*
*/
@TableId(value = "oss_id", type = IdType.AUTO)
private Long ossId;
/**
*
*/
private String fileName;
/**
*
*/
private String originalName;
/**
*
*/
private String fileSuffix;
/**
* URL
*/
private String url;
/**
*
*/
private String service;
}

View File

@ -0,0 +1,80 @@
package com.ruoyi.resource.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.core.web.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* sys_oss_config
*
* @author Lion Li
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_oss_config")
public class SysOssConfig extends BaseEntity {
/**
*
*/
@TableId(value = "oss_config_id")
private Long ossConfigId;
/**
* key
*/
private String configKey;
/**
* accessKey
*/
private String accessKey;
/**
*
*/
private String secretKey;
/**
*
*/
private String bucketName;
/**
*
*/
private String prefix;
/**
* 访
*/
private String endpoint;
/**
* https0 1
*/
private String isHttps;
/**
*
*/
private String region;
/**
* (0 1)
*/
private String status;
/**
*
*/
private String ext1;
/**
*
*/
private String remark;
}

View File

@ -0,0 +1,45 @@
package com.ruoyi.resource.domain.bo;
import com.ruoyi.common.core.web.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* OSS sys_oss
*
* @author Lion Li
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("OSS对象存储分页查询对象")
public class SysOssBo extends BaseEntity {
/**
*
*/
@ApiModelProperty("文件名")
private String fileName;
/**
*
*/
@ApiModelProperty("原名")
private String originalName;
/**
*
*/
@ApiModelProperty("文件后缀名")
private String fileSuffix;
/**
* URL
*/
@ApiModelProperty("URL地址")
private String url;
/**
*
*/
@ApiModelProperty("服务商")
private String service;
}

View File

@ -0,0 +1,105 @@
package com.ruoyi.resource.domain.bo;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.core.web.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* sys_oss_config
*
* @author Lion Li
* @author
* @date 2021-08-13
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("对象存储配置业务对象")
public class SysOssConfigBo extends BaseEntity {
/**
*
*/
@ApiModelProperty(value = "主建", required = true)
@NotNull(message = "主建不能为空", groups = {EditGroup.class})
private Long ossConfigId;
/**
* key
*/
@ApiModelProperty(value = "configKey", required = true)
@NotBlank(message = "configKey不能为空", groups = {AddGroup.class, EditGroup.class})
@Size(min = 2, max = 100, message = "configKey长度必须介于2和20 之间")
private String configKey;
/**
* accessKey
*/
@ApiModelProperty(value = "accessKey", required = true)
@NotBlank(message = "accessKey不能为空", groups = {AddGroup.class, EditGroup.class})
@Size(min = 2, max = 100, message = "accessKey长度必须介于2和100 之间")
private String accessKey;
/**
*
*/
@ApiModelProperty(value = "secretKey", required = true)
@NotBlank(message = "secretKey不能为空", groups = {AddGroup.class, EditGroup.class})
@Size(min = 2, max = 100, message = "secretKey长度必须介于2和100 之间")
private String secretKey;
/**
*
*/
@ApiModelProperty(value = "bucketName", required = true)
@NotBlank(message = "bucketName不能为空", groups = {AddGroup.class, EditGroup.class})
@Size(min = 2, max = 100, message = "bucketName长度必须介于2和100之间")
private String bucketName;
/**
*
*/
@ApiModelProperty(value = "前缀")
private String prefix;
/**
* 访
*/
@ApiModelProperty(value = "endpoint", required = true)
@NotBlank(message = "endpoint不能为空", groups = {AddGroup.class, EditGroup.class})
@Size(min = 2, max = 100, message = "endpoint长度必须介于2和100之间")
private String endpoint;
/**
* httpsY=,N=
*/
@ApiModelProperty("是否httpsY=是,N=否)")
private String isHttps;
/**
* 0=,1=
*/
@ApiModelProperty("状态0=正常,1=停用)")
private String status;
/**
*
*/
@ApiModelProperty(value = "region")
private String region;
/**
*
*/
@ApiModelProperty(value = "扩展字段")
private String ext1;
}

View File

@ -0,0 +1,93 @@
package com.ruoyi.resource.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* sys_oss_config
*
* @author Lion Li
* @author
* @date 2021-08-13
*/
@Data
@ApiModel("对象存储配置视图对象")
public class SysOssConfigVo {
private static final long serialVersionUID = 1L;
/**
*
*/
@ApiModelProperty("主建")
private Long ossConfigId;
/**
* key
*/
@ApiModelProperty("配置key")
private String configKey;
/**
* accessKey
*/
@ApiModelProperty("accessKey")
private String accessKey;
/**
*
*/
@ApiModelProperty("secretKey")
private String secretKey;
/**
*
*/
@ApiModelProperty("桶名称")
private String bucketName;
/**
*
*/
@ApiModelProperty("前缀")
private String prefix;
/**
* 访
*/
@ApiModelProperty("访问站点")
private String endpoint;
/**
* httpsY=,N=
*/
@ApiModelProperty("是否httpsY=是,N=否)")
private String isHttps;
/**
*
*/
@ApiModelProperty("域")
private String region;
/**
* 0=,1=
*/
@ApiModelProperty("状态0=正常,1=停用)")
private String status;
/**
*
*/
@ApiModelProperty("扩展字段")
private String ext1;
/**
*
*/
@ApiModelProperty("备注")
private String remark;
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.resource.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* OSS sys_oss
*
* @author Lion Li
*/
@Data
@ApiModel("OSS对象存储视图对象")
public class SysOssVo {
private static final long serialVersionUID = 1L;
/**
*
*/
@ApiModelProperty("对象存储主键")
private Long ossId;
/**
*
*/
@ApiModelProperty("文件名")
private String fileName;
/**
*
*/
@ApiModelProperty("原名")
private String originalName;
/**
*
*/
@ApiModelProperty("文件后缀名")
private String fileSuffix;
/**
* URL
*/
@ApiModelProperty("URL地址")
private String url;
/**
*
*/
@ApiModelProperty("创建时间")
private Date createTime;
/**
*
*/
@ApiModelProperty("上传人")
private String createBy;
/**
*
*/
@ApiModelProperty("服务商")
private String service;
}

View File

@ -0,0 +1,59 @@
package com.ruoyi.resource.dubbo;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.oss.entity.UploadResult;
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.domain.SysFile;
import com.ruoyi.resource.domain.SysOss;
import com.ruoyi.resource.mapper.SysOssMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
*
*
* @author Lion Li
*/
@Slf4j
@Service
@DubboService
public class RemoteFileServiceImpl implements RemoteFileService {
@Autowired
private SysOssMapper sysOssMapper;
/**
*
*/
@Transactional(rollbackFor = Exception.class)
@Override
public SysFile upload(String name, String originalFilename, String contentType, byte[] file) {
try {
String suffix = StringUtils.substring(originalFilename, originalFilename.lastIndexOf("."), originalFilename.length());
IOssStrategy storage = OssFactory.instance();
UploadResult uploadResult = storage.uploadSuffix(file, suffix, contentType);
// 保存文件信息
SysOss oss = new SysOss();
oss.setUrl(uploadResult.getUrl());
oss.setFileSuffix(suffix);
oss.setFileName(uploadResult.getFilename());
oss.setOriginalName(originalFilename);
oss.setService(storage.getServiceType().getValue());
sysOssMapper.insert(oss);
SysFile sysFile = new SysFile();
sysFile.setName(uploadResult.getFilename());
sysFile.setUrl(uploadResult.getUrl());
return sysFile;
} catch (Exception e) {
log.error("上传文件失败", e);
throw new ServiceException("上传文件失败");
}
}
}

View File

@ -0,0 +1,17 @@
package com.ruoyi.resource.mapper;
import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import com.ruoyi.resource.domain.SysOssConfig;
import com.ruoyi.resource.domain.vo.SysOssConfigVo;
/**
* Mapper
*
* @author Lion Li
* @author
* @date 2021-08-13
*/
public interface SysOssConfigMapper extends BaseMapperPlus<SysOssConfigMapper, SysOssConfig, SysOssConfigVo> {
}

View File

@ -0,0 +1,13 @@
package com.ruoyi.resource.mapper;
import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import com.ruoyi.resource.domain.SysOss;
import com.ruoyi.resource.domain.vo.SysOssVo;
/**
*
*
* @author Lion Li
*/
public interface SysOssMapper extends BaseMapperPlus<SysOssMapper, SysOss, SysOssVo> {
}

View File

@ -0,0 +1,28 @@
package com.ruoyi.resource.runner;
import com.ruoyi.resource.service.ISysOssConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
/**
* system
*
* @author Lion Li
*/
@Slf4j
@RequiredArgsConstructor
@Component
public class ResourceApplicationRunner implements ApplicationRunner {
private final ISysOssConfigService ossConfigService;
@Override
public void run(ApplicationArguments args) throws Exception {
ossConfigService.init();
log.info("初始化OSS配置成功");
}
}

View File

@ -0,0 +1,66 @@
package com.ruoyi.resource.service;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.resource.domain.bo.SysOssConfigBo;
import com.ruoyi.resource.domain.vo.SysOssConfigVo;
import java.util.Collection;
/**
* Service
*
* @author Lion Li
* @author
* @date 2021-08-13
*/
public interface ISysOssConfigService {
/**
* OSS
*/
void init();
/**
*
*/
SysOssConfigVo queryById(Integer ossConfigId);
/**
*
*/
TableDataInfo<SysOssConfigVo> queryPageList(SysOssConfigBo bo, PageQuery pageQuery);
/**
*
*
* @param bo
* @return
*/
Boolean insertByBo(SysOssConfigBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean updateByBo(SysOssConfigBo bo);
/**
*
*
* @param ids
* @param isValid ,true-,false-
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
*
*/
int updateOssConfigStatus(SysOssConfigBo bo);
}

View File

@ -0,0 +1,27 @@
package com.ruoyi.resource.service;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.resource.domain.SysOss;
import com.ruoyi.resource.domain.bo.SysOssBo;
import com.ruoyi.resource.domain.vo.SysOssVo;
import org.springframework.web.multipart.MultipartFile;
import java.util.Collection;
/**
*
*
* @author Lion Li
*/
public interface ISysOssService {
TableDataInfo<SysOssVo> queryPageList(SysOssBo sysOss, PageQuery pageQuery);
SysOss getById(Long ossId);
SysOss upload(MultipartFile file);
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@ -0,0 +1,194 @@
package com.ruoyi.resource.service.impl;
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;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.JsonUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.oss.constant.OssConstant;
import com.ruoyi.common.oss.factory.OssFactory;
import com.ruoyi.common.redis.utils.RedisUtils;
import com.ruoyi.resource.domain.SysOssConfig;
import com.ruoyi.resource.domain.bo.SysOssConfigBo;
import com.ruoyi.resource.domain.vo.SysOssConfigVo;
import com.ruoyi.resource.mapper.SysOssConfigMapper;
import com.ruoyi.resource.service.ISysOssConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
/**
* Service
*
* @author Lion Li
* @author
* @date 2021-08-13
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class SysOssConfigServiceImpl implements ISysOssConfigService {
private final SysOssConfigMapper baseMapper;
/**
*
*/
@Override
public void init() {
List<SysOssConfig> list = baseMapper.selectList();
// 加载OSS初始化配置
for (SysOssConfig config : list) {
String configKey = config.getConfigKey();
if ("0".equals(config.getStatus())) {
RedisUtils.setCacheObject(OssConstant.CACHE_CONFIG_KEY, configKey);
}
setConfigCache(true, config);
}
// 初始化OSS工厂
OssFactory.init();
}
@Override
public SysOssConfigVo queryById(Integer ossConfigId) {
return baseMapper.selectVoById(ossConfigId);
}
@Override
public TableDataInfo<SysOssConfigVo> queryPageList(SysOssConfigBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SysOssConfig> lqw = buildQueryWrapper(bo);
Page<SysOssConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
private LambdaQueryWrapper<SysOssConfig> buildQueryWrapper(SysOssConfigBo bo) {
LambdaQueryWrapper<SysOssConfig> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getConfigKey()), SysOssConfig::getConfigKey, bo.getConfigKey());
lqw.like(StringUtils.isNotBlank(bo.getBucketName()), SysOssConfig::getBucketName, bo.getBucketName());
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysOssConfig::getStatus, bo.getStatus());
return lqw;
}
@Override
public Boolean insertByBo(SysOssConfigBo bo) {
SysOssConfig config = BeanUtil.toBean(bo, SysOssConfig.class);
validEntityBeforeSave(config);
return setConfigCache(baseMapper.insert(config) > 0, config);
}
@Override
public Boolean updateByBo(SysOssConfigBo bo) {
SysOssConfig config = BeanUtil.toBean(bo, SysOssConfig.class);
validEntityBeforeSave(config);
LambdaUpdateWrapper<SysOssConfig> luw = new LambdaUpdateWrapper<>();
luw.set(StringUtils.isBlank(config.getPrefix()), SysOssConfig::getPrefix, "");
luw.set(StringUtils.isBlank(config.getRegion()), SysOssConfig::getRegion, "");
luw.set(StringUtils.isBlank(config.getExt1()), SysOssConfig::getExt1, "");
luw.eq(SysOssConfig::getOssConfigId, config.getOssConfigId());
return setConfigCache(baseMapper.update(config, luw) > 0, config);
}
/**
*
*/
private void validEntityBeforeSave(SysOssConfig entity) {
if (StringUtils.isNotEmpty(entity.getConfigKey())
&& UserConstants.NOT_UNIQUE.equals(checkConfigKeyUnique(entity))) {
throw new ServiceException("操作配置'" + entity.getConfigKey() + "'失败, 配置key已存在!");
}
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
if (CollUtil.containsAny(ids, OssConstant.SYSTEM_DATA_IDS)) {
throw new ServiceException("系统内置, 不可删除!");
}
}
List<SysOssConfig> list = Lists.newArrayList();
for (Long configId : ids) {
SysOssConfig config = baseMapper.selectById(configId);
list.add(config);
}
boolean flag = baseMapper.deleteBatchIds(ids) > 0;
if (flag) {
list.stream().forEach(sysOssConfig -> {
RedisUtils.deleteObject(getCacheKey(sysOssConfig.getConfigKey()));
});
}
return flag;
}
/**
* configKey
*/
private String checkConfigKeyUnique(SysOssConfig sysOssConfig) {
long ossConfigId = ObjectUtil.isNull(sysOssConfig.getOssConfigId()) ? -1L : sysOssConfig.getOssConfigId();
SysOssConfig info = baseMapper.selectOne(new LambdaQueryWrapper<SysOssConfig>()
.select(SysOssConfig::getOssConfigId, SysOssConfig::getConfigKey)
.eq(SysOssConfig::getConfigKey, sysOssConfig.getConfigKey()));
if (ObjectUtil.isNotNull(info) && info.getOssConfigId() != ossConfigId) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
*
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int updateOssConfigStatus(SysOssConfigBo bo) {
SysOssConfig sysOssConfig = BeanUtil.toBean(bo, SysOssConfig.class);
int row = baseMapper.update(null, new LambdaUpdateWrapper<SysOssConfig>()
.set(SysOssConfig::getStatus, "1"));
row += baseMapper.updateById(sysOssConfig);
if (row > 0) {
RedisUtils.setCacheObject(OssConstant.CACHE_CONFIG_KEY, sysOssConfig.getConfigKey());
}
return row;
}
/**
* cache key
*
* @param configKey
* @return key
*/
private String getCacheKey(String configKey) {
return OssConstant.SYS_OSS_KEY + configKey;
}
/**
*
*
* @param flag
* @param config
* @return
*/
private boolean setConfigCache(boolean flag, SysOssConfig config) {
if (flag) {
RedisUtils.setCacheObject(
getCacheKey(config.getConfigKey()),
JsonUtils.toJsonString(config));
RedisUtils.publish(OssConstant.CACHE_CONFIG_KEY, config.getConfigKey(), msg -> {
log.info("发布刷新OSS配置 => " + msg);
});
}
return flag;
}
}

View File

@ -0,0 +1,99 @@
package com.ruoyi.resource.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.common.oss.entity.UploadResult;
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.bo.SysOssBo;
import com.ruoyi.resource.domain.vo.SysOssVo;
import com.ruoyi.resource.mapper.SysOssMapper;
import com.ruoyi.resource.service.ISysOssService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
*
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Service
public class SysOssServiceImpl implements ISysOssService {
private final SysOssMapper baseMapper;
@Override
public TableDataInfo<SysOssVo> queryPageList(SysOssBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SysOss> lqw = buildQueryWrapper(bo);
Page<SysOssVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
private LambdaQueryWrapper<SysOss> buildQueryWrapper(SysOssBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SysOss> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getFileName()), SysOss::getFileName, bo.getFileName());
lqw.like(StringUtils.isNotBlank(bo.getOriginalName()), SysOss::getOriginalName, bo.getOriginalName());
lqw.eq(StringUtils.isNotBlank(bo.getFileSuffix()), SysOss::getFileSuffix, bo.getFileSuffix());
lqw.eq(StringUtils.isNotBlank(bo.getUrl()), SysOss::getUrl, bo.getUrl());
lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
SysOss::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), SysOss::getCreateBy, bo.getCreateBy());
lqw.eq(StringUtils.isNotBlank(bo.getService()), SysOss::getService, bo.getService());
return lqw;
}
@Override
public SysOss getById(Long ossId) {
return baseMapper.selectById(ossId);
}
@Override
public SysOss upload(MultipartFile file) {
String originalfileName = file.getOriginalFilename();
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
IOssStrategy storage = OssFactory.instance();
UploadResult uploadResult;
try {
uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
} catch (IOException e) {
throw new ServiceException(e.getMessage());
}
// 保存文件信息
SysOss oss = new SysOss();
oss.setUrl(uploadResult.getUrl());
oss.setFileSuffix(suffix);
oss.setFileName(uploadResult.getFilename());
oss.setOriginalName(originalfileName);
oss.setService(storage.getServiceType().getValue());
baseMapper.insert(oss);
return oss;
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// 做一些业务上的校验,判断是否需要校验
}
List<SysOss> list = baseMapper.selectBatchIds(ids);
for (SysOss sysOss : list) {
IOssStrategy storage = OssFactory.instance(sysOss.getService());
storage.delete(sysOss.getUrl());
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@ -0,0 +1,10 @@
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}
_
(_)
_ __ _ _ ___ _ _ _ ______ _ __ ___ ___ ___ _ _ _ __ ___ ___
| '__| | | |/ _ \| | | | |______| '__/ _ \/ __|/ _ \| | | | '__/ __/ _ \
| | | |_| | (_) | |_| | | | | | __/\__ \ (_) | |_| | | | (_| __/
|_| \__,_|\___/ \__, |_| |_| \___||___/\___/ \__,_|_| \___\___|
__/ |
|___/

View File

@ -9,7 +9,7 @@ spring:
allow-circular-references: true allow-circular-references: true
application: application:
# 应用名称 # 应用名称
name: ruoyi-file name: ruoyi-resource
profiles: profiles:
# 环境配置 # 环境配置
active: @profiles.active@ active: @profiles.active@
@ -34,3 +34,5 @@ spring:
shared-configs: shared-configs:
- data-id: application.${spring.cloud.nacos.config.file-extension} - data-id: application.${spring.cloud.nacos.config.file-extension}
refresh: true refresh: true
- data-id: datasource.${spring.cloud.nacos.config.file-extension}
refresh: true

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false"> <configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 --> <!-- 日志存放路径 -->
<property name="log.path" value="logs/ruoyi-file" /> <property name="log.path" value="logs/ruoyi-resource" />
<!-- 日志输出格式 --> <!-- 日志输出格式 -->
<property name="console.log.pattern" <property name="console.log.pattern"
value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/> value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>

View File

@ -0,0 +1,3 @@
java包使用 `.` 分割 resource 目录使用 `/` 分割
<br>
此文件目的 防止文件夹粘连找不到 `xml` 文件

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.resource.mapper.SysOssConfigMapper">
<resultMap type="com.ruoyi.resource.domain.SysOssConfig" id="SysOssConfigResult">
<result property="ossConfigId" column="oss_config_id"/>
<result property="configKey" column="config_key"/>
<result property="accessKey" column="access_key"/>
<result property="secretKey" column="secret_key"/>
<result property="bucketName" column="bucket_name"/>
<result property="prefix" column="prefix"/>
<result property="endpoint" column="endpoint"/>
<result property="isHttps" column="is_https"/>
<result property="region" column="region"/>
<result property="status" column="status"/>
<result property="ext1" column="ext1"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
</mapper>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.resource.mapper.SysOssMapper">
<resultMap type="com.ruoyi.resource.domain.SysOss" id="SysOssResult">
<result property="ossId" column="oss_id"/>
<result property="fileName" column="file_name"/>
<result property="fileSuffix" column="file_suffix"/>
<result property="url" column="url"/>
<result property="createTime" column="create_time"/>
<result property="createBy" column="create_by"/>
<result property="updateTime" column="update_time"/>
<result property="updateBy" column="update_by"/>
<result property="service" column="service"/>
</resultMap>
</mapper>

View File

@ -0,0 +1,24 @@
# p6spy 性能分析插件配置文件
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
#deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2
# 是否过滤 Log
filter=true

View File

@ -47,12 +47,6 @@
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
</dependency> </dependency>
<!-- RuoYi Common DataSource -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datasource</artifactId>
</dependency>
<!-- RuoYi Common Log --> <!-- RuoYi Common Log -->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
@ -103,7 +97,7 @@
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api-file</artifactId> <artifactId>ruoyi-api-resource</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -99,6 +99,17 @@ public class SysConfigController extends BaseController {
return toAjax(configService.updateConfig(config)); return toAjax(configService.updateConfig(config));
} }
/**
*
*/
@ApiOperation("根据参数键名修改参数配置")
@SaCheckPermission("system:config:edit")
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PutMapping("/updateByKey")
public R<Void> updateByKey(@RequestBody SysConfig config) {
return toAjax(configService.updateConfig(config));
}
/** /**
* *
*/ */

View File

@ -9,10 +9,11 @@ import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType; import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.satoken.utils.LoginHelper; import com.ruoyi.common.satoken.utils.LoginHelper;
import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.file.api.RemoteFileService; import com.ruoyi.resource.api.RemoteFileService;
import com.ruoyi.file.api.domain.SysFile; import com.ruoyi.resource.api.domain.SysFile;
import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
import io.seata.spring.annotation.GlobalTransactional;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiImplicitParams;
@ -111,17 +112,14 @@ public class SysProfileController extends BaseController {
/** /**
* *
*/ */
// @GlobalTransactional(rollbackFor = Exception.class) @GlobalTransactional(rollbackFor = Exception.class)
@ApiOperation("头像上传") @ApiOperation("头像上传")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "avatarfile", value = "用户头像", dataTypeClass = File.class, required = true), @ApiImplicitParam(name = "avatarfile", value = "用户头像", dataTypeClass = File.class, required = true),
}) })
@Log(title = "用户头像", businessType = BusinessType.UPDATE) @Log(title = "用户头像", businessType = BusinessType.UPDATE)
@PostMapping("/avatar") @PostMapping("/avatar")
public R<Map<String, Object>> avatar(@RequestParam("avatarfile") MultipartFile file) throws IOException { public R<Map<String, Object>> avatar(@RequestPart("avatarfile") MultipartFile file) throws IOException {
// todo 临时用于测试 seata
// userService.insertUser(new SysUser().setUserName("test").setNickName("test"));
if (!file.isEmpty()) { if (!file.isEmpty()) {
SysFile sysFile = remoteFileService.upload(file.getName(), file.getOriginalFilename(), file.getContentType(), file.getBytes()); SysFile sysFile = remoteFileService.upload(file.getName(), file.getOriginalFilename(), file.getContentType(), file.getBytes());
if (ObjectUtil.isNull(sysFile)) { if (ObjectUtil.isNull(sysFile)) {

View File

@ -0,0 +1,32 @@
package com.ruoyi.system.runner;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDictTypeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
/**
* system
*
* @author Lion Li
*/
@Slf4j
@RequiredArgsConstructor
@Component
public class SystemApplicationRunner implements ApplicationRunner {
private final ISysConfigService configService;
private final ISysDictTypeService dictTypeService;
@Override
public void run(ApplicationArguments args) throws Exception {
configService.loadingConfigCache();
log.info("加载参数缓存数据成功");
dictTypeService.loadingDictCache();
log.info("加载字典缓存数据成功");
}
}

View File

@ -34,14 +34,6 @@ public class SysConfigServiceImpl implements ISysConfigService {
private final SysConfigMapper baseMapper; private final SysConfigMapper baseMapper;
/**
*
*/
@PostConstruct
public void init() {
loadingConfigCache();
}
@Override @Override
public TableDataInfo<SysConfig> selectPageConfigList(SysConfig config, PageQuery pageQuery) { public TableDataInfo<SysConfig> selectPageConfigList(SysConfig config, PageQuery pageQuery) {
Map<String, Object> params = config.getParams(); Map<String, Object> params = config.getParams();
@ -128,7 +120,13 @@ public class SysConfigServiceImpl implements ISysConfigService {
*/ */
@Override @Override
public int updateConfig(SysConfig config) { public int updateConfig(SysConfig config) {
int row = baseMapper.updateById(config); int row = 0;
if (config.getConfigId() != null) {
row = baseMapper.updateById(config);
} else {
row = baseMapper.update(config, new LambdaQueryWrapper<SysConfig>()
.eq(SysConfig::getConfigKey, config.getConfigKey()));
}
if (row > 0) { if (row > 0) {
RedisUtils.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); RedisUtils.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
} }

View File

@ -39,14 +39,6 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService {
private final SysDictTypeMapper baseMapper; private final SysDictTypeMapper baseMapper;
private final SysDictDataMapper dictDataMapper; private final SysDictDataMapper dictDataMapper;
/**
*
*/
@PostConstruct
public void init() {
loadingDictCache();
}
@Override @Override
public TableDataInfo<SysDictType> selectPageDictTypeList(SysDictType dictType, PageQuery pageQuery) { public TableDataInfo<SysDictType> selectPageDictTypeList(SysDictType dictType, PageQuery pageQuery) {
Map<String, Object> params = dictType.getParams(); Map<String, Object> params = dictType.getParams();

View File

@ -43,6 +43,18 @@ export function updateConfig(data) {
}) })
} }
// 修改参数配置
export function updateConfigByKey(key, value) {
return request({
url: '/system/config/updateByKey',
method: 'put',
data: {
configKey: key,
configValue: value
}
})
}
// 删除参数配置 // 删除参数配置
export function delConfig(configId) { export function delConfig(configId) {
return request({ return request({

View File

@ -0,0 +1,19 @@
import request from '@/utils/request'
// 查询OSS对象存储列表
export function listOss(query) {
return request({
url: '/resource/oss/list',
method: 'get',
params: query
})
}
// 删除OSS对象存储
export function delOss(ossId) {
return request({
url: '/resource/oss/' + ossId,
method: 'delete'
})
}

View File

@ -0,0 +1,58 @@
import request from '@/utils/request'
// 查询对象存储配置列表
export function listOssConfig(query) {
return request({
url: '/resource/oss/config/list',
method: 'get',
params: query
})
}
// 查询对象存储配置详细
export function getOssConfig(ossConfigId) {
return request({
url: '/resource/oss/config/' + ossConfigId,
method: 'get'
})
}
// 新增对象存储配置
export function addOssConfig(data) {
return request({
url: '/resource/oss/config',
method: 'post',
data: data
})
}
// 修改对象存储配置
export function updateOssConfig(data) {
return request({
url: '/resource/oss/config',
method: 'put',
data: data
})
}
// 删除对象存储配置
export function delOssConfig(ossConfigId) {
return request({
url: '/resource/oss/config/' + ossConfigId,
method: 'delete'
})
}
// 用户状态修改
export function changeOssConfigStatus(ossConfigId, status, configKey) {
const data = {
ossConfigId,
status,
configKey
}
return request({
url: '/resource/oss/config/changeStatus',
method: 'put',
data: data
})
}

View File

@ -60,7 +60,7 @@ export default {
}, },
data() { data() {
return { return {
uploadUrl: process.env.VUE_APP_BASE_API + "/file/upload", // uploadUrl: process.env.VUE_APP_BASE_API + "/resource/oss/upload", //
headers: { headers: {
Authorization: "Bearer " + getToken() Authorization: "Bearer " + getToken()
}, },
@ -180,7 +180,7 @@ export default {
// //
quill.setSelection(length + 1); quill.setSelection(length + 1);
} else { } else {
this.$message.error("图片插入失败"); this.$message.error(res.msg);
} }
}, },
handleUploadError() { handleUploadError() {

View File

@ -69,7 +69,7 @@ export default {
}, },
data() { data() {
return { return {
uploadFileUrl: process.env.VUE_APP_BASE_API + "/file/upload", // uploadFileUrl: process.env.VUE_APP_BASE_API + "/resource/oss/upload", //
headers: { headers: {
Authorization: "Bearer " + getToken(), Authorization: "Bearer " + getToken(),
}, },
@ -146,7 +146,7 @@ export default {
// //
handleUploadSuccess(res, file) { handleUploadSuccess(res, file) {
this.$message.success("上传成功"); this.$message.success("上传成功");
this.fileList.push({ name: res.data.url, url: res.data.url }); this.fileList.push({ name: res.data.fileName, url: res.data.url });
this.$emit("input", this.listToString(this.fileList)); this.$emit("input", this.listToString(this.fileList));
}, },
// //
@ -169,7 +169,7 @@ export default {
for (let i in list) { for (let i in list) {
strs += list[i].url + separator; strs += list[i].url + separator;
} }
return strs != '' ? strs.substr(0, strs.length - 1) : ''; return strs != "" ? strs.substr(0, strs.length - 1) : "";
} }
} }
}; };

View File

@ -73,7 +73,7 @@ export default {
dialogImageUrl: "", dialogImageUrl: "",
dialogVisible: false, dialogVisible: false,
hideUpload: false, hideUpload: false,
uploadImgUrl: process.env.VUE_APP_BASE_API + "/file/upload", // uploadImgUrl: process.env.VUE_APP_BASE_API + "/resource/oss/upload", //
headers: { headers: {
Authorization: "Bearer " + getToken(), Authorization: "Bearer " + getToken(),
}, },
@ -119,7 +119,7 @@ export default {
}, },
// //
handleUploadSuccess(res) { handleUploadSuccess(res) {
this.fileList.push({ name: res.data.url, url: res.data.url }); this.fileList.push({ name: res.data.fileName, url: res.data.url });
this.$emit("input", this.listToString(this.fileList)); this.$emit("input", this.listToString(this.fileList));
this.loading.close(); this.loading.close();
}, },

View File

@ -17,7 +17,7 @@ import { download } from '@/utils/request'
import './assets/icons' // icon import './assets/icons' // icon
import './permission' // permission control import './permission' // permission control
import { getDicts } from "@/api/system/dict/data"; import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config"; import { getConfigKey, updateConfigByKey } from "@/api/system/config";
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi"; import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
// 分页组件 // 分页组件
import Pagination from "@/components/Pagination"; import Pagination from "@/components/Pagination";
@ -41,6 +41,7 @@ import DictData from '@/components/DictData'
// 全局方法挂载 // 全局方法挂载
Vue.prototype.getDicts = getDicts Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey Vue.prototype.getConfigKey = getConfigKey
Vue.prototype.updateConfigByKey = updateConfigByKey
Vue.prototype.parseTime = parseTime Vue.prototype.parseTime = parseTime
Vue.prototype.resetForm = resetForm Vue.prototype.resetForm = resetForm
Vue.prototype.addDateRange = addDateRange Vue.prototype.addDateRange = addDateRange

View File

@ -134,6 +134,20 @@ export const dynamicRoutes = [
} }
] ]
}, },
{
path: '/system/oss-config',
component: Layout,
hidden: true,
permissions: ['system:oss:list'],
children: [
{
path: 'index',
component: () => import('@/views/system/oss/config'),
name: 'OssConfig',
meta: { title: '配置管理', activeMenu: '/system/oss' }
}
]
},
{ {
path: '/tool/gen-edit', path: '/tool/gen-edit',
component: Layout, component: Layout,

View File

@ -0,0 +1,400 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="配置key" prop="configKey">
<el-select v-model="queryParams.configKey" placeholder="请选择配置key" clearable size="small">
<el-option
v-for="configKey in configKeyOptions"
:key="configKey.configKey"
:label="configKey.label"
:value="configKey.configKey"
/>
</el-select>
</el-form-item>
<el-form-item label="桶名称" prop="bucketName">
<el-input
v-model="queryParams.bucketName"
placeholder="请输入桶名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:oss:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:oss:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:oss:remove']"
>删除</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="ossConfigList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主建" align="center" prop="ossConfigId" v-if="false"/>
<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="bucketName" />
<el-table-column label="前缀" align="center" prop="prefix" />
<el-table-column label="域" align="center" prop="region" />
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
active-value="0"
inactive-value="1"
@change="handleStatusChange(scope.row)"
></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:oss:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:oss:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对象存储配置对话框 -->
<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-item label="配置key" prop="configKey">
<el-select 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 label="访问站点" prop="endpoint">
<el-input v-model="form.endpoint" placeholder="请输入访问站点" />
</el-form-item>
<el-form-item label="accessKey" prop="accessKey">
<el-input v-model="form.accessKey" placeholder="请输入accessKey" />
</el-form-item>
<el-form-item label="secretKey" prop="secretKey">
<el-input v-model="form.secretKey" placeholder="请输入秘钥" show-password />
</el-form-item>
<el-form-item label="桶名称" prop="bucketName">
<el-input v-model="form.bucketName" placeholder="请输入桶名称" />
</el-form-item>
<el-form-item label="前缀" prop="prefix">
<el-input v-model="form.prefix" placeholder="请输入前缀" />
</el-form-item>
<el-form-item label="是否HTTPS">
<el-radio-group v-model="form.isHttps">
<el-radio
v-for="dict in dict.type.sys_yes_no"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="域" prop="region">
<el-input v-model="form.region" placeholder="请输入域" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listOssConfig,
getOssConfig,
delOssConfig,
addOssConfig,
updateOssConfig,
changeOssConfigStatus
} from "@/api/system/ossConfig";
export default {
name: "OssConfig",
dicts: ['sys_yes_no', 'sys_normal_disable'],
data() {
return {
// loading
buttonLoading: false,
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
ossConfigList: [],
// configKeyOptions
configKeyOptions: [],
configKeyDatas: [
{ configKey: "minio", label: "Minio" },
{ configKey: "qiniu", label: "七牛云" },
{ configKey: "aliyun", label: "阿里云" },
{ configKey: "qcloud", label: "腾讯云" },
],
//
title: "",
//
open: false,
// https
isHttpsOptions: [],
// (0 1)
statusOptions: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
configKey: undefined,
bucketName: undefined,
status: undefined,
},
//
form: {},
//
rules: {
configKey: [
{ required: true, message: "configKey不能为空", trigger: "blur" },
],
accessKey: [
{ required: true, message: "accessKey不能为空", trigger: "blur" },
{
min: 2,
max: 200,
message: "accessKey长度必须介于 2 和 100 之间",
trigger: "blur",
},
],
secretKey: [
{ required: true, message: "secretKey不能为空", trigger: "blur" },
{
min: 2,
max: 100,
message: "secretKey长度必须介于 2 和 100 之间",
trigger: "blur",
},
],
bucketName: [
{ required: true, message: "bucketName不能为空", trigger: "blur" },
{
min: 2,
max: 100,
message: "bucketName长度必须介于 2 和 100 之间",
trigger: "blur",
},
],
endpoint: [
{ required: true, message: "endpoint不能为空", trigger: "blur" },
{
min: 2,
max: 100,
message: "endpoint名称长度必须介于 2 和 100 之间",
trigger: "blur",
},
],
},
};
},
created() {
this.getList();
this.configKeyOptions = this.configKeyDatas;
},
methods: {
/** 查询对象存储配置列表 */
getList() {
this.loading = true;
listOssConfig(this.queryParams).then((response) => {
this.ossConfigList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
ossConfigId: undefined,
configKey: undefined,
accessKey: undefined,
secretKey: undefined,
bucketName: undefined,
prefix: undefined,
endpoint: undefined,
isHttps: "N",
region: undefined,
status: "1",
remark: undefined,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.ossConfigId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加对象存储配置";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const ossConfigId = row.ossConfigId || this.ids;
getOssConfig(ossConfigId).then((response) => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改对象存储配置";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.ossConfigId != null) {
updateOssConfig(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addOssConfig(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ossConfigIds = row.ossConfigId || this.ids;
this.$modal.confirm('是否确认删除对象存储配置编号为"' + ossConfigIds + '"的数据项?').then(() => {
this.loading = true;
return delOssConfig(ossConfigIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).finally(() => {
this.loading = false;
});
},
//
handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用";
this.$modal.confirm('确认要"' + text + '""' + row.configKey + '"配置吗?').then(() => {
return changeOssConfigStatus(row.ossConfigId, row.status, row.configKey);
}).then(() => {
this.getList()
this.$modal.msgSuccess(text + "成功");
}).catch(() => {
row.status = row.status === "0" ? "1" : "0";
})
}
}
};
</script>

View File

@ -0,0 +1,357 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="文件名" prop="fileName">
<el-input
v-model="queryParams.fileName"
placeholder="请输入文件名"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="原名" prop="originalName">
<el-input
v-model="queryParams.originalName"
placeholder="请输入原名"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="文件后缀" prop="fileSuffix">
<el-input
v-model="queryParams.fileSuffix"
placeholder="请输入文件后缀"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="daterangeCreateTime"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item label="上传人" prop="createBy">
<el-input
v-model="queryParams.createBy"
placeholder="请输入上传人"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="服务商" prop="service">
<el-input
v-model="queryParams.service"
placeholder="请输入服务商"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleFile"
v-hasPermi="['system:oss:upload']"
>上传文件</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleImage"
v-hasPermi="['system:oss:upload']"
>上传图片</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:oss:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
:type="previewListResource ? 'danger' : 'warning'"
plain
size="mini"
@click="handlePreviewListResource(!previewListResource)"
v-hasPermi="['system:oss:edit']"
>预览开关 : {{previewListResource ? "禁用" : "启用"}}</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-s-operation"
size="mini"
@click="handleOssConfig"
v-hasPermi="['system:oss:list']"
>配置管理</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="ossList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="对象存储主键" align="center" prop="ossId" v-if="false"/>
<el-table-column label="文件名" align="center" prop="fileName" />
<el-table-column label="原名" align="center" prop="originalName" />
<el-table-column label="文件后缀" align="center" prop="fileSuffix" />
<el-table-column label="文件展示" align="center" prop="url">
<template slot-scope="scope">
<el-image
v-if="previewListResource && checkFileSuffix(scope.row.fileSuffix)"
style="width: 100px; height: 100px;"
:src="scope.row.url"
:preview-src-list="[scope.row.url]"/>
<span v-text="scope.row.url"
v-if="!checkFileSuffix(scope.row.fileSuffix) || !previewListResource"/>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="上传人" align="center" prop="createBy" />
<el-table-column label="服务商" align="center" prop="service" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleDownload(scope.row)"
v-hasPermi="['system:oss:download']"
>下载</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:oss:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改OSS对象存储对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="文件名">
<fileUpload v-model="form.file" v-if="type === 0"/>
<imageUpload v-model="form.file" v-if="type === 1"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listOss, delOss } from "@/api/system/oss";
export default {
name: "Oss",
data() {
return {
// loading
buttonLoading: false,
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
// OSS
ossList: [],
//
title: "",
//
type: 0,
//
open: false,
//
previewListResource: true,
//
daterangeCreateTime: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
fileName: undefined,
originalName: undefined,
fileSuffix: undefined,
url: undefined,
createTime: undefined,
createBy: undefined,
service: undefined
},
//
form: {},
//
rules: {
file: [
{ required: true, message: "文件不能为空", trigger: "blur" }
]
}
};
},
created() {
this.getList();
},
methods: {
/** 查询OSS对象存储列表 */
getList() {
this.loading = true;
this.queryParams.params = {};
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
this.queryParams.params["beginCreateTime"] = this.daterangeCreateTime[0];
this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
}
this.getConfigKey("sys.oss.previewListResource").then(response => {
this.previewListResource = response.msg === undefined ? true : response.msg === 'true';
});
listOss(this.queryParams).then(response => {
this.ossList = response.rows;
this.total = response.total;
this.loading = false;
});
},
checkFileSuffix(fileSuffix) {
let arr = ["png", "jpg", "jpeg"];
return arr.some(type => {
return fileSuffix.indexOf(type) > -1;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
file: undefined,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.daterangeCreateTime = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.ossId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 任务日志列表查询 */
handleOssConfig() {
this.$router.push({ path: '/system/oss-config/index'})
},
/** 文件按钮操作 */
handleFile() {
this.reset();
this.open = true;
this.title = "上传文件";
this.type = 0;
},
/** 图片按钮操作 */
handleImage() {
this.reset();
this.open = true;
this.title = "上传图片";
this.type = 1;
},
/** 提交按钮 */
submitForm() {
this.open = false;
this.getList();
},
/** 下载按钮操作 */
handleDownload(row) {
this.$download.oss(row.ossId)
},
/** 删除按钮操作 */
handleDelete(row) {
const ossIds = row.ossId || this.ids;
this.$modal.confirm('是否确认删除OSS对象存储编号为"' + ossIds + '"的数据项?').then(() => {
this.loading = true;
return delOss(ossIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).finally(() => {
this.loading = false;
});
},
//
handlePreviewListResource(previewListResource) {
let text = previewListResource ? "启用" : "停用";
this.$modal.confirm('确认要"' + text + '""预览列表图片"配置吗?').then(() => {
return this.updateConfigByKey("sys.oss.previewListResource", previewListResource);
}).then(() => {
this.getList()
this.$modal.msgSuccess(text + "成功");
}).catch(() => {
this.previewListResource = previewListResource !== true;
})
}
}
};
</script>

View File

@ -77,7 +77,8 @@ export default {
autoCrop: true, // autoCrop: true, //
autoCropWidth: 200, // autoCropWidth: 200, //
autoCropHeight: 200, // autoCropHeight: 200, //
fixedBox: true // fixedBox: true, //
filename: ''
}, },
previews: {} previews: {}
}; };
@ -116,6 +117,7 @@ export default {
reader.readAsDataURL(file); reader.readAsDataURL(file);
reader.onload = () => { reader.onload = () => {
this.options.img = reader.result; this.options.img = reader.result;
this.options.filename = file.name;
}; };
} }
}, },
@ -123,7 +125,8 @@ export default {
uploadImg() { uploadImg() {
this.$refs.cropper.getCropBlob(data => { this.$refs.cropper.getCropBlob(data => {
let formData = new FormData(); let formData = new FormData();
formData.append("avatarfile", data); console.log(this.options.filename)
formData.append("avatarfile", data, this.options.filename);
uploadAvatar(formData).then(response => { uploadAvatar(formData).then(response => {
this.open = false; this.open = false;
this.options.img = response.data.imgUrl; this.options.img = response.data.imgUrl;

View File

@ -15,6 +15,6 @@ knife4j:
- name: 代码生成 - name: 代码生成
uri: ${knife4j.cloud.gatewayUri} uri: ${knife4j.cloud.gatewayUri}
location: /code/v2/api-docs location: /code/v2/api-docs
- name: 文件服务 - name: 资源服务
uri: ${knife4j.cloud.gatewayUri} uri: ${knife4j.cloud.gatewayUri}
location: /file/v2/api-docs location: /resource/v2/api-docs

View File

@ -162,7 +162,7 @@ create table sys_menu (
insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录'); insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录');
insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录'); insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录');
insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录'); insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录');
insert into sys_menu values('4', '若依官网', '0', '4', 'http://ruoyi.vip', null, '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, '若依官网地址'); insert into sys_menu values('4', 'PLUS官网', '0', '4', 'https://gitee.com/JavaLionLi/RuoYi-Cloud-Plus', null, '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, '若依官网地址');
-- 二级菜单 -- 二级菜单
insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单'); insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单');
insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单'); insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单');
@ -181,6 +181,8 @@ insert into sys_menu values('113', 'Admin控制台', '2', '5', 'http://loc
insert into sys_menu values('114', '表单构建', '3', '1', 'build', 'tool/build/index', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单'); insert into sys_menu values('114', '表单构建', '3', '1', 'build', 'tool/build/index', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单');
insert into sys_menu values('115', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单'); insert into sys_menu values('115', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单');
insert into sys_menu values('116', '系统接口', '3', '3', 'http://localhost:18000/doc.html', '', '', 0, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单'); insert into sys_menu values('116', '系统接口', '3', '3', 'http://localhost:18000/doc.html', '', '', 0, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单');
-- oss菜单
insert into sys_menu values('118', '文件管理', '1', '10', 'oss', 'system/oss/index', '', 1, 0, 'C', '0', '0', 'system:oss:list', 'upload', 'admin', sysdate(), '', null, '文件管理菜单');
-- 三级菜单 -- 三级菜单
insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'system/operlog/index', '', 1, 0, 'C', '0', '0', 'system:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单'); insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'system/operlog/index', '', 1, 0, 'C', '0', '0', 'system:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单');
insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'system/logininfor/index', '', 1, 0, 'C', '0', '0', 'system:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单'); insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'system/logininfor/index', '', 1, 0, 'C', '0', '0', 'system:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单');
@ -250,6 +252,13 @@ insert into sys_menu values('1057', '生成删除', '115', '3', '#', '', '', 1,
insert into sys_menu values('1058', '导入代码', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1058', '导入代码', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1059', '预览代码', '115', '4', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1059', '预览代码', '115', '4', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1060', '生成代码', '115', '5', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1060', '生成代码', '115', '5', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, '');
-- oss相关按钮
insert into sys_menu values('1600', '文件查询', '118', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1601', '文件上传', '118', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:upload', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1602', '文件下载', '118', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:download', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1603', '文件删除', '118', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1604', '配置添加', '118', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1605', '配置编辑', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:edit', '#', 'admin', sysdate(), '', null, '');
-- ---------------------------- -- ----------------------------
@ -533,7 +542,7 @@ insert into sys_config values(1, '主框架页-默认皮肤样式名称', 's
insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' ); insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' );
insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark浅色主题theme-light' ); insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark浅色主题theme-light' );
insert into sys_config values(4, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能true开启false关闭'); insert into sys_config values(4, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能true开启false关闭');
insert into sys_config values(11, 'OSS预览列表资源开关', 'sys.oss.previewListResource', 'true', 'Y', 'admin', sysdate(), '', null, 'true:开启, false:关闭');
-- ---------------------------- -- ----------------------------
-- 14、系统访问记录 -- 14、系统访问记录
@ -573,6 +582,52 @@ create table sys_notice (
insert into sys_notice values('1', '温馨提醒2018-07-01 若依新版本发布啦', '2', '新版本内容', '0', 'admin', sysdate(), '', null, '管理员'); insert into sys_notice values('1', '温馨提醒2018-07-01 若依新版本发布啦', '2', '新版本内容', '0', 'admin', sysdate(), '', null, '管理员');
insert into sys_notice values('2', '维护通知2018-07-01 若依系统凌晨维护', '1', '维护内容', '0', 'admin', sysdate(), '', null, '管理员'); insert into sys_notice values('2', '维护通知2018-07-01 若依系统凌晨维护', '1', '维护内容', '0', 'admin', sysdate(), '', null, '管理员');
-- ----------------------------
-- OSS对象存储表
-- ----------------------------
drop table if exists sys_oss;
create table sys_oss (
oss_id bigint(20) not null auto_increment comment '对象存储主键',
file_name varchar(255) not null default '' comment '文件名',
original_name varchar(255) not null default '' comment '原名',
file_suffix varchar(10) not null default '' comment '文件后缀名',
url varchar(500) not null comment 'URL地址',
create_time datetime default null comment '创建时间',
create_by varchar(64) default '' comment '上传人',
update_time datetime default null comment '更新时间',
update_by varchar(64) default '' comment '更新人',
service varchar(10) not null default 'minio' comment '服务商',
primary key (oss_id)
) engine=innodb comment ='OSS对象存储表';
-- ----------------------------
-- OSS对象存储动态配置表
-- ----------------------------
drop table if exists sys_oss_config;
create table sys_oss_config (
oss_config_id bigint(20) not null auto_increment comment '主建',
config_key varchar(255) not null default '' comment '配置key',
access_key varchar(255) default '' comment 'accessKey',
secret_key varchar(255) default '' comment '秘钥',
bucket_name varchar(255) default '' comment '桶名称',
prefix varchar(255) default '' comment '前缀',
endpoint varchar(255) default '' comment '访问站点',
is_https char(1) default 'N' comment '是否httpsY=是,N=否)',
region varchar(255) default '' comment '',
status char(1) default '1' comment '状态0=正常,1=停用)',
ext1 varchar(255) default '' comment '扩展字段',
create_by varchar(64) default '' comment '创建者',
create_time datetime default null comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime default null comment '更新时间',
remark varchar(500) default null comment '备注',
primary key (oss_config_id)
) 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 (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://XXX.XXXX.com', 'N', 'z0', '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 (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'http://cos.ap-beijing.myqcloud.com', 'N', 'ap-beijing', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
-- ---------------------------- -- ----------------------------
-- 18、代码生成业务表 -- 18、代码生成业务表

View File

@ -40,7 +40,7 @@ insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_mod
(6, 'ruoyi-system.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:20:18', '2022-01-09 15:22:03', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '系统模块', NULL, NULL, 'yaml', NULL), (6, 'ruoyi-system.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:20:18', '2022-01-09 15:22:03', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '系统模块', NULL, NULL, 'yaml', NULL),
(7, 'ruoyi-gen.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:20:18', '2022-01-09 15:21:51', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '代码生成', NULL, NULL, 'yaml', NULL), (7, 'ruoyi-gen.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:20:18', '2022-01-09 15:21:51', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '代码生成', NULL, NULL, 'yaml', NULL),
(8, 'ruoyi-job.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:20:18', '2022-01-09 15:21:36', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '定时任务', NULL, NULL, 'yaml', NULL), (8, 'ruoyi-job.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:20:18', '2022-01-09 15:21:36', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '定时任务', NULL, NULL, 'yaml', NULL),
(9, 'ruoyi-file.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:20:35', '2022-01-09 15:21:21', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '文件服务', NULL, NULL, 'yaml', NULL), (9, 'ruoyi-resource.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:20:35', '2022-01-09 15:21:21', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '文件服务', NULL, NULL, 'yaml', NULL),
(10, 'sentinel-ruoyi-gateway.json', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '限流策略', NULL, NULL, 'json', NULL), (10, 'sentinel-ruoyi-gateway.json', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '限流策略', NULL, NULL, 'json', NULL),
(11, 'ruoyi-xxl-job-admin.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '定时任务控制台', NULL, NULL, 'yaml', NULL), (11, 'ruoyi-xxl-job-admin.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '定时任务控制台', NULL, NULL, 'yaml', NULL),
(12, 'seata-server.properties', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'dev', 'seata配置文件', NULL, NULL, 'properties', NULL), (12, 'seata-server.properties', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'dev', 'seata配置文件', NULL, NULL, 'properties', NULL),
@ -53,7 +53,7 @@ insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_mod
(106, 'ruoyi-system.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '系统模块', NULL, NULL, 'yaml', NULL), (106, 'ruoyi-system.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '系统模块', NULL, NULL, 'yaml', NULL),
(107, 'ruoyi-gen.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '代码生成', NULL, NULL, 'yaml', NULL), (107, 'ruoyi-gen.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '代码生成', NULL, NULL, 'yaml', NULL),
(108, 'ruoyi-job.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '定时任务', NULL, NULL, 'yaml', NULL), (108, 'ruoyi-job.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '定时任务', NULL, NULL, 'yaml', NULL),
(109, 'ruoyi-file.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '文件服务', NULL, NULL, 'yaml', NULL), (109, 'ruoyi-resource.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '文件服务', NULL, NULL, 'yaml', NULL),
(110, 'sentinel-ruoyi-gateway.json', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '限流策略', NULL, NULL, 'json', NULL), (110, 'sentinel-ruoyi-gateway.json', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '限流策略', NULL, NULL, 'json', NULL),
(111, 'ruoyi-xxl-job-admin.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '定时任务控制台', NULL, NULL, 'yaml', NULL), (111, 'ruoyi-xxl-job-admin.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '定时任务控制台', NULL, NULL, 'yaml', NULL),
(112, 'seata-server.properties', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'prod', 'seata配置文件', NULL, NULL, 'properties', NULL); (112, 'seata-server.properties', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'prod', 'seata配置文件', NULL, NULL, 'properties', NULL);