pull/131/head
caohong 4 years ago
commit 5848337579

@ -0,0 +1,67 @@
#!/bin/sh
# 使用说明,用来提示输入参数
usage() {
echo "Usage: sh 执行脚本.sh [port|base|modules|stop|rm]"
exit 1
}
# 开启所需端口
port(){
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --add-port=8848/tcp --permanent
firewall-cmd --add-port=9848/tcp --permanent
firewall-cmd --add-port=9849/tcp --permanent
firewall-cmd --add-port=6379/tcp --permanent
firewall-cmd --add-port=3306/tcp --permanent
firewall-cmd --add-port=9100/tcp --permanent
firewall-cmd --add-port=9200/tcp --permanent
firewall-cmd --add-port=9201/tcp --permanent
firewall-cmd --add-port=9202/tcp --permanent
firewall-cmd --add-port=9203/tcp --permanent
firewall-cmd --add-port=9300/tcp --permanent
service firewalld restart
}
# 启动基础环境(必须)
base(){
docker-compose up -d ruoyi-mysql ruoyi-redis ruoyi-nacos ruoyi-nginx
}
# 启动程序模块(必须)
modules(){
docker-compose up -d ruoyi-gateway ruoyi-auth ruoyi-modules-system
}
# 关闭所有环境/模块
stop(){
docker-compose stop
}
# 删除所有环境/模块
rm(){
docker-compose rm
}
# 根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"port")
port
;;
"base")
base
;;
"modules")
modules
;;
"stop")
stop
;;
"rm")
rm
;;
*)
usage
;;
esac

@ -0,0 +1,140 @@
version : '3.8'
services:
ruoyi-nacos:
container_name: ruoyi-nacos
image: nacos/nacos-server
build:
context: ./nacos
environment:
- MODE=standalone
volumes:
- ./nacos/logs/:/home/nacos/logs
- ./nacos/conf/application.properties:/home/nacos/conf/application.properties
ports:
- "8848:8848"
- "9848:9848"
- "9849:9849"
depends_on:
- ruoyi-mysql
ruoyi-mysql:
container_name: ruoyi-mysql
image: mysql:5.7
build:
context: ./mysql
ports:
- "3306:3306"
volumes:
- ./mysql/conf:/etc/mysql/conf.d
- ./mysql/logs:/logs
- ./mysql/data:/var/lib/mysql
command: [
'mysqld',
'--innodb-buffer-pool-size=80M',
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_unicode_ci',
'--default-time-zone=+8:00',
'--lower-case-table-names=1'
]
environment:
MYSQL_DATABASE: 'ry-cloud'
MYSQL_ROOT_PASSWORD: password
ruoyi-redis:
container_name: ruoyi-redis
image: redis
build:
context: ./redis
ports:
- "6379:6379"
volumes:
- ./redis/conf/redis.conf:/home/ruoyi/redis/redis.conf
- ./redis/data:/data
command: redis-server /home/ruoyi/redis/redis.conf
ruoyi-nginx:
container_name: ruoyi-nginx
image: nginx
build:
context: ./nginx
ports:
- "80:80"
volumes:
- ./nginx/html/dist:/home/ruoyi/projects/ruoyi-ui
- ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/logs:/var/log/nginx
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- ruoyi-gateway
links:
- ruoyi-gateway
ruoyi-gateway:
container_name: ruoyi-gateway
build:
context: ./ruoyi/gateway
dockerfile: dockerfile
ports:
- "8080:8080"
depends_on:
- ruoyi-redis
links:
- ruoyi-redis
ruoyi-auth:
container_name: ruoyi-auth
build:
context: ./ruoyi/auth
dockerfile: dockerfile
ports:
- "9200:9200"
depends_on:
- ruoyi-redis
links:
- ruoyi-redis
ruoyi-modules-system:
container_name: ruoyi-modules-system
build:
context: ./ruoyi/modules/system
dockerfile: dockerfile
ports:
- "9201:9201"
depends_on:
- ruoyi-redis
- ruoyi-mysql
links:
- ruoyi-redis
- ruoyi-mysql
ruoyi-modules-gen:
container_name: ruoyi-modules-gen
build:
context: ./ruoyi/modules/gen
dockerfile: dockerfile
ports:
- "9202:9202"
depends_on:
- ruoyi-mysql
links:
- ruoyi-mysql
ruoyi-modules-job:
container_name: ruoyi-modules-job
build:
context: ./ruoyi/modules/job
dockerfile: dockerfile
ports:
- "9203:9203"
depends_on:
- ruoyi-mysql
links:
- ruoyi-mysql
ruoyi-modules-file:
container_name: ruoyi-modules-file
build:
context: ./ruoyi/modules/file
dockerfile: dockerfile
ports:
- "9300:9300"
volumes:
- ./ruoyi/uploadPath:/home/ruoyi/uploadPath
ruoyi-visual-monitor:
container_name: ruoyi-visual-monitor
build:
context: ./ruoyi/visual/monitor
dockerfile: dockerfile
ports:
- "9100:9100"

@ -0,0 +1 @@
存放sql目录下的所有脚本用于docker自动执行。

@ -0,0 +1,7 @@
# 基础镜像
FROM mysql:5.7
# author
MAINTAINER ruoyi
# 执行sql脚本
ADD ./db/*.sql /docker-entrypoint-initdb.d/

@ -0,0 +1,32 @@
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://ruoyi-mysql:3306/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=password
nacos.naming.empty-service.auto-clean=true
nacos.naming.empty-service.clean.initial-delay-ms=50000
nacos.naming.empty-service.clean.period-time-ms=30000
management.endpoints.web.exposure.include=*
management.metrics.export.elastic.enabled=false
management.metrics.export.influx.enabled=false
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i
server.tomcat.basedir=
nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-ui/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
nacos.core.auth.system.type=nacos
nacos.core.auth.enabled=false
nacos.core.auth.default.token.expire.seconds=18000
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
nacos.core.auth.caching.enabled=true
nacos.core.auth.enable.userAgentAuthWhite=false
nacos.core.auth.server.identity.key=serverIdentity
nacos.core.auth.server.identity.value=security
nacos.istio.mcp.server.enabled=false

@ -0,0 +1,7 @@
# 基础镜像
FROM nacos/nacos-server
# author
MAINTAINER ruoyi
# 复制conf文件到路径
COPY ./conf/application.properties /home/nacos/conf/application.properties

@ -0,0 +1,36 @@
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /home/ruoyi/projects/ruoyi-ui;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
location /prod-api/{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://ruoyi-gateway:8080/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}# requirepass 123456

@ -0,0 +1,15 @@
# 基础镜像
FROM nginx
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi/projects/ruoyi-ui
# 创建目录
RUN mkdir -p /home/ruoyi/projects/ruoyi-ui
# 指定路径
WORKDIR /home/ruoyi/projects/ruoyi-ui
# 复制conf文件到路径
COPY ./conf/nginx.conf /etc/nginx/nginx.conf
# 复制html文件到路径
COPY ./html/dist /home/ruoyi/projects/ruoyi-ui

@ -0,0 +1 @@
存放前端ruoyi-ui构建好的静态文件用于nginx请求访问。

@ -0,0 +1 @@
# requirepass 123456

@ -0,0 +1,13 @@
# 基础镜像
FROM redis
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi/redis
# 创建目录
RUN mkdir -p /home/ruoyi/redis
# 指定路径
WORKDIR /home/ruoyi/redis
# 复制conf文件到路径
COPY ./conf/redis.conf /home/ruoyi/redis/redis.conf

@ -0,0 +1,15 @@
# 基础镜像
FROM openjdk:8-jre
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi
# 创建目录
RUN mkdir -p /home/ruoyi
# 指定路径
WORKDIR /home/ruoyi
# 复制jar文件到路径
COPY ./jar/ruoyi-auth.jar /home/ruoyi/ruoyi-auth.jar
# 启动认证服务
ENTRYPOINT ["java","-jar","ruoyi-auth.jar"]

@ -0,0 +1 @@
存放认证中心打包好的jar文件用于docker启动应用。

@ -0,0 +1,15 @@
# 基础镜像
FROM openjdk:8-jre
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi
# 创建目录
RUN mkdir -p /home/ruoyi
# 指定路径
WORKDIR /home/ruoyi
# 复制jar文件到路径
COPY ./jar/ruoyi-gateway.jar /home/ruoyi/ruoyi-gateway.jar
# 启动网关服务
ENTRYPOINT ["java","-jar","ruoyi-gateway.jar"]

@ -0,0 +1 @@
存放网关模块打包好的jar文件用于docker启动应用。

@ -0,0 +1,15 @@
# 基础镜像
FROM openjdk:8-jre
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi
# 创建目录
RUN mkdir -p /home/ruoyi
# 指定路径
WORKDIR /home/ruoyi
# 复制jar文件到路径
COPY ./jar/ruoyi-modules-file.jar /home/ruoyi/ruoyi-modules-file.jar
# 启动文件服务
ENTRYPOINT ["java","-jar","ruoyi-modules-file.jar"]

@ -0,0 +1 @@
存放文件服务打包好的jar文件用于docker启动应用。

@ -0,0 +1,15 @@
# 基础镜像
FROM openjdk:8-jre
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi
# 创建目录
RUN mkdir -p /home/ruoyi
# 指定路径
WORKDIR /home/ruoyi
# 复制jar文件到路径
COPY ./jar/ruoyi-modules-gen.jar /home/ruoyi/ruoyi-modules-gen.jar
# 启动代码生成服务
ENTRYPOINT ["java","-jar","ruoyi-modules-gen.jar"]

@ -0,0 +1 @@
存放代码生成打包好的jar文件用于docker启动应用。

@ -0,0 +1,15 @@
# 基础镜像
FROM openjdk:8-jre
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi
# 创建目录
RUN mkdir -p /home/ruoyi
# 指定路径
WORKDIR /home/ruoyi
# 复制jar文件到路径
COPY ./jar/ruoyi-modules-job.jar /home/ruoyi/ruoyi-modules-job.jar
# 启动定时任务服务
ENTRYPOINT ["java","-jar","ruoyi-modules-job.jar"]

@ -0,0 +1 @@
存放定时任务打包好的jar文件用于docker启动应用。

@ -0,0 +1,15 @@
# 基础镜像
FROM openjdk:8-jre
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi
# 创建目录
RUN mkdir -p /home/ruoyi
# 指定路径
WORKDIR /home/ruoyi
# 复制jar文件到路径
COPY ./jar/ruoyi-modules-system.jar /home/ruoyi/ruoyi-modules-system.jar
# 启动系统服务
ENTRYPOINT ["java","-jar","ruoyi-modules-system.jar"]

@ -0,0 +1 @@
存放系统模块打包好的jar文件用于docker启动应用。

@ -0,0 +1,15 @@
# 基础镜像
FROM openjdk:8-jre
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi
# 创建目录
RUN mkdir -p /home/ruoyi
# 指定路径
WORKDIR /home/ruoyi
# 复制jar文件到路径
COPY ./jar/ruoyi-visual-monitor.jar /home/ruoyi/ruoyi-visual-monitor.jar
# 启动系统服务
ENTRYPOINT ["java","-jar","ruoyi-visual-monitor.jar"]

@ -0,0 +1 @@
存放监控中心打包好的jar文件用于docker启动应用。

@ -6,30 +6,30 @@
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
<name>ruoyi</name> <name>ruoyi</name>
<url>http://www.ruoyi.vip</url> <url>http://www.ruoyi.vip</url>
<description>若依微服务系统</description> <description>若依微服务系统</description>
<properties> <properties>
<ruoyi.version>2.5.0</ruoyi.version> <ruoyi.version>3.0.0</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<spring-boot.version>2.5.0</spring-boot.version> <spring-boot.version>2.5.1</spring-boot.version>
<spring-cloud.version>2020.0.2</spring-cloud.version> <spring-cloud.version>2020.0.3</spring-cloud.version>
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version> <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
<alibaba.nacos.version>2.0.1</alibaba.nacos.version> <alibaba.nacos.version>2.0.2</alibaba.nacos.version>
<spring-boot-admin.version>2.4.1</spring-boot-admin.version> <spring-boot-admin.version>2.4.1</spring-boot-admin.version>
<spring-boot.mybatis>2.1.4</spring-boot.mybatis> <spring-boot.mybatis>2.1.4</spring-boot.mybatis>
<swagger.fox.version>2.9.2</swagger.fox.version> <swagger.fox.version>3.0.0</swagger.fox.version>
<swagger.core.version>1.5.24</swagger.core.version> <swagger.core.version>1.6.2</swagger.core.version>
<tobato.version>1.26.5</tobato.version> <tobato.version>1.26.5</tobato.version>
<kaptcha.version>2.3.2</kaptcha.version> <kaptcha.version>2.3.2</kaptcha.version>
<pagehelper.boot.version>1.3.0</pagehelper.boot.version> <pagehelper.boot.version>1.3.0</pagehelper.boot.version>
<druid.version>1.2.6</druid.version> <druid.version>1.2.6</druid.version>
<dynamic-ds.version>3.3.2</dynamic-ds.version> <dynamic-ds.version>3.4.0</dynamic-ds.version>
<commons.io.version>2.5</commons.io.version> <commons.io.version>2.5</commons.io.version>
<commons.fileupload.version>1.3.3</commons.fileupload.version> <commons.fileupload.version>1.3.3</commons.fileupload.version>
<velocity.version>1.7</velocity.version> <velocity.version>1.7</velocity.version>

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api</artifactId> <artifactId>ruoyi-api</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -33,8 +33,8 @@ public class SysRole extends BaseEntity
@Excel(name = "角色排序") @Excel(name = "角色排序")
private String roleSort; private String roleSort;
/** 数据范围1所有数据权限2自定义数据权限3本部门数据权限4本部门及以下数据权限 */ /** 数据范围1所有数据权限2自定义数据权限3本部门数据权限4本部门及以下数据权限5仅本人数据权限 */
@Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限") @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
private String dataScope; private String dataScope;
/** 菜单树选择项是否关联显示( 0父子不互相关联显示 1父子互相关联显示 */ /** 菜单树选择项是否关联显示( 0父子不互相关联显示 1父子互相关联显示 */

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -80,6 +80,7 @@ public class ImageUtils
} }
finally finally
{ {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(baos); IOUtils.closeQuietly(baos);
} }
} }

@ -36,6 +36,7 @@ import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddressList; import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor; import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDataValidation; import org.apache.poi.xssf.usermodel.XSSFDataValidation;
@ -179,7 +180,8 @@ public class ExcelUtil<T>
throw new IOException("文件sheet不存在"); throw new IOException("文件sheet不存在");
} }
int rows = sheet.getPhysicalNumberOfRows(); // 获取最后一个非空行的行下标比如总行数为n则返回的为n-1
int rows = sheet.getLastRowNum();
if (rows > 0) if (rows > 0)
{ {
@ -219,10 +221,15 @@ public class ExcelUtil<T>
} }
} }
} }
for (int i = 1; i < rows; i++) for (int i = 1; i <= rows; i++)
{ {
// 从第2行开始取数据,默认第一行是表头. // 从第2行开始取数据,默认第一行是表头.
Row row = sheet.getRow(i); Row row = sheet.getRow(i);
// 判断当前行是否是空行
if (isRowEmpty(row))
{
continue;
}
T entity = null; T entity = null;
for (Map.Entry<Integer, Field> entry : fieldsMap.entrySet()) for (Map.Entry<Integer, Field> entry : fieldsMap.entrySet())
{ {
@ -321,7 +328,7 @@ public class ExcelUtil<T>
*/ */
public void exportExcel(HttpServletResponse response, List<T> list, String sheetName) throws IOException public void exportExcel(HttpServletResponse response, List<T> list, String sheetName) throws IOException
{ {
response.setContentType("application/vnd.ms-excel"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");
this.init(list, sheetName, Type.EXPORT); this.init(list, sheetName, Type.EXPORT);
exportExcel(response.getOutputStream()); exportExcel(response.getOutputStream());
@ -335,7 +342,7 @@ public class ExcelUtil<T>
*/ */
public void importTemplateExcel(HttpServletResponse response, String sheetName) throws IOException public void importTemplateExcel(HttpServletResponse response, String sheetName) throws IOException
{ {
response.setContentType("application/vnd.ms-excel"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");
this.init(null, sheetName, Type.IMPORT); this.init(null, sheetName, Type.IMPORT);
exportExcel(response.getOutputStream()); exportExcel(response.getOutputStream());
@ -346,9 +353,28 @@ public class ExcelUtil<T>
* *
* @return * @return
*/ */
public void exportExcel(OutputStream outputStream) public void exportExcel(OutputStream out)
{ {
try try
{
writeSheet();
wb.write(out);
}
catch (Exception e)
{
log.error("导出Excel异常{}", e.getMessage());
}
finally
{
IOUtils.closeQuietly(wb);
IOUtils.closeQuietly(out);
}
}
/**
* Sheet
*/
public void writeSheet()
{ {
// 取出一共有多少个sheet. // 取出一共有多少个sheet.
double sheetNo = Math.ceil(list.size() / sheetSize); double sheetNo = Math.ceil(list.size() / sheetSize);
@ -371,37 +397,6 @@ public class ExcelUtil<T>
addStatisticsRow(); addStatisticsRow();
} }
} }
wb.write(outputStream);
}
catch (Exception e)
{
log.error("导出Excel异常{}", e.getMessage());
}
finally
{
if (wb != null)
{
try
{
wb.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
if (outputStream != null)
{
try
{
outputStream.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
}
} }
/** /**
@ -535,8 +530,7 @@ public class ExcelUtil<T>
} }
else if (ColumnType.IMAGE == attr.cellType()) else if (ColumnType.IMAGE == attr.cellType())
{ {
ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);
cell.getRow().getRowNum() + 1);
String imagePath = Convert.toStr(value); String imagePath = Convert.toStr(value);
if (StringUtils.isNotEmpty(imagePath)) if (StringUtils.isNotEmpty(imagePath))
{ {
@ -1028,4 +1022,27 @@ public class ExcelUtil<T>
} }
return val; return val;
} }
/**
*
*
* @param row
* @return
*/
private boolean isRowEmpty(Row row)
{
if (row == null)
{
return true;
}
for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++)
{
Cell cell = row.getCell(i);
if (cell != null && cell.getCellType() != CellType.BLANK)
{
return false;
}
}
return true;
}
} }

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -3,13 +3,12 @@ package com.ruoyi.common.swagger.config;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.function.Predicate;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.builders.RequestHandlerSelectors;
@ -18,8 +17,10 @@ import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope; import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact; import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityReference; import springfox.documentation.service.SecurityReference;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.ApiSelectorBuilder;
import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2; import springfox.documentation.swagger2.annotations.EnableSwagger2;
@ -60,27 +61,26 @@ public class SwaggerAutoConfiguration
{ {
swaggerProperties.getExcludePath().addAll(DEFAULT_EXCLUDE_PATH); swaggerProperties.getExcludePath().addAll(DEFAULT_EXCLUDE_PATH);
} }
List<Predicate<String>> excludePath = new ArrayList<>(); List<Predicate<String>> excludePath = new ArrayList<>();
swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path))); swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path)));
//noinspection Guava ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2).host(swaggerProperties.getHost())
return new Docket(DocumentationType.SWAGGER_2)
.host(swaggerProperties.getHost())
.apiInfo(apiInfo(swaggerProperties)).select() .apiInfo(apiInfo(swaggerProperties)).select()
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage())) .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()));
.paths(Predicates.and(Predicates.not(Predicates.or(excludePath)), Predicates.or(basePath)))
.build() swaggerProperties.getBasePath().forEach(p -> builder.paths(PathSelectors.ant(p)));
.securitySchemes(securitySchemes()) swaggerProperties.getExcludePath().forEach(p -> builder.paths(PathSelectors.ant(p).negate()));
.securityContexts(securityContexts())
.pathMapping("/"); return builder.build().securitySchemes(securitySchemes()).securityContexts(securityContexts()).pathMapping("/");
} }
/** /**
* tokenAuthorization * tokenAuthorization
*/ */
private List<ApiKey> securitySchemes() private List<SecurityScheme> securitySchemes()
{ {
List<ApiKey> apiKeyList = new ArrayList<ApiKey>(); List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
apiKeyList.add(new ApiKey("Authorization", "Authorization", "header")); apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
return apiKeyList; return apiKeyList;
} }
@ -94,7 +94,7 @@ public class SwaggerAutoConfiguration
securityContexts.add( securityContexts.add(
SecurityContext.builder() SecurityContext.builder()
.securityReferences(defaultAuth()) .securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("^(?!auth).*$")) .operationSelector(o -> o.requestMappingPattern().matches("/.*"))
.build()); .build());
return securityContexts; return securityContexts;
} }

@ -0,0 +1,22 @@
package com.ruoyi.common.swagger.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* swagger
*
* @author ruoyi
*/
@Configuration
public class SwaggerWebConfiguration implements WebMvcConfigurer
{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
/** swagger-ui 地址 */
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
}
}

@ -1,2 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ruoyi.common.swagger.config.SwaggerAutoConfiguration com.ruoyi.common.swagger.config.SwaggerAutoConfiguration,\
com.ruoyi.common.swagger.config.SwaggerWebConfiguration

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -7,6 +7,8 @@ import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils; import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.reactive.config.ResourceHandlerRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;
import springfox.documentation.swagger.web.SwaggerResource; import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider; import springfox.documentation.swagger.web.SwaggerResourcesProvider;
@ -16,7 +18,7 @@ import springfox.documentation.swagger.web.SwaggerResourcesProvider;
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class SwaggerProvider implements SwaggerResourcesProvider public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigurer
{ {
/** /**
* Swagger2url * Swagger2url
@ -63,4 +65,12 @@ public class SwaggerProvider implements SwaggerResourcesProvider
swaggerResource.setSwaggerVersion("2.0"); swaggerResource.setSwaggerVersion("2.0");
return swaggerResource; return swaggerResource;
} }
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
/** swagger-ui 地址 */
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
}
} }

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -532,7 +532,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
} }
} }
}; };

@ -587,7 +587,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
}, },
#if($table.sub) #if($table.sub)
/** ${subTable.functionName}序号 */ /** ${subTable.functionName}序号 */

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -96,11 +96,11 @@ public interface SysDeptMapper
public int updateDept(SysDept dept); public int updateDept(SysDept dept);
/** /**
* *
* *
* @param dept * @param deptIds ID
*/ */
public void updateDeptStatus(SysDept dept); public void updateDeptStatusNormal(Long[] deptIds);
/** /**
* *

@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.common.core.constant.UserConstants; import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.exception.CustomException; import com.ruoyi.common.core.exception.CustomException;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.datascope.annotation.DataScope; import com.ruoyi.common.datascope.annotation.DataScope;
import com.ruoyi.system.api.domain.SysDept; import com.ruoyi.system.api.domain.SysDept;
@ -211,7 +212,7 @@ public class SysDeptServiceImpl implements ISysDeptService
if (UserConstants.DEPT_NORMAL.equals(dept.getStatus())) if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()))
{ {
// 如果该部门是启用状态,则启用该部门的所有上级部门 // 如果该部门是启用状态,则启用该部门的所有上级部门
updateParentDeptStatus(dept); updateParentDeptStatusNormal(dept);
} }
return result; return result;
} }
@ -221,12 +222,11 @@ public class SysDeptServiceImpl implements ISysDeptService
* *
* @param dept * @param dept
*/ */
private void updateParentDeptStatus(SysDept dept) private void updateParentDeptStatusNormal(SysDept dept)
{ {
String updateBy = dept.getUpdateBy(); String ancestors = dept.getAncestors();
dept = deptMapper.selectDeptById(dept.getDeptId()); Long[] deptIds = Convert.toLongArray(ancestors);
dept.setUpdateBy(updateBy); deptMapper.updateDeptStatusNormal(deptIds);
deptMapper.updateDeptStatus(dept);
} }
/** /**

@ -140,14 +140,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach> </foreach>
</update> </update>
<update id="updateDeptStatus" parameterType="SysDept"> <update id="updateDeptStatusNormal" parameterType="Long">
update sys_dept update sys_dept set status = '0' where dept_id in
<set> <foreach collection="array" item="deptId" open="(" separator="," close=")">
<if test="status != null and status != ''">status = #{status},</if> #{deptId}
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> </foreach>
update_time = sysdate()
</set>
where find_in_set(#{deptId}, ancestors)
</update> </update>
<delete id="deleteDeptById" parameterType="Long"> <delete id="deleteDeptById" parameterType="Long">

@ -1,3 +1,6 @@
# 页面标题
VUE_APP_TITLE = 若依管理系统
# 开发环境配置 # 开发环境配置
ENV = 'development' ENV = 'development'

@ -1,3 +1,6 @@
# 页面标题
VUE_APP_TITLE = 若依管理系统
# 生产环境配置 # 生产环境配置
ENV = 'production' ENV = 'production'

@ -1,3 +1,6 @@
# 页面标题
VUE_APP_TITLE = 若依管理系统
NODE_ENV = production NODE_ENV = production
# 测试环境配置 # 测试环境配置

@ -1,6 +1,6 @@
{ {
"name": "ruoyi", "name": "ruoyi",
"version": "2.5.0", "version": "3.0.0",
"description": "若依管理系统", "description": "若依管理系统",
"author": "若依", "author": "若依",
"license": "MIT", "license": "MIT",
@ -33,7 +33,7 @@
], ],
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://gitee.com/y_project/RuoYi-Vue.git" "url": "https://gitee.com/y_project/RuoYi-Cloud.git"
}, },
"dependencies": { "dependencies": {
"@riophae/vue-treeselect": "0.4.0", "@riophae/vue-treeselect": "0.4.0",
@ -41,7 +41,7 @@
"clipboard": "2.0.6", "clipboard": "2.0.6",
"core-js": "3.8.1", "core-js": "3.8.1",
"echarts": "4.9.0", "echarts": "4.9.0",
"element-ui": "2.15.0", "element-ui": "2.15.2",
"file-saver": "2.0.4", "file-saver": "2.0.4",
"fuse.js": "6.4.3", "fuse.js": "6.4.3",
"highlight.js": "9.18.5", "highlight.js": "9.18.5",
@ -56,6 +56,7 @@
"vue-count-to": "1.0.13", "vue-count-to": "1.0.13",
"vue-cropper": "0.5.5", "vue-cropper": "0.5.5",
"vue-router": "3.4.9", "vue-router": "3.4.9",
"vue-meta": "^2.4.0",
"vuedraggable": "2.24.3", "vuedraggable": "2.24.3",
"vuex": "3.6.0" "vuex": "3.6.0"
}, },

@ -6,6 +6,14 @@
<script> <script>
export default { export default {
name: 'App' name: 'App',
metaInfo() {
return {
title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title,
titleTemplate: title => {
return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
}
}
}
} }
</script> </script>

@ -105,6 +105,15 @@
position: absolute; position: absolute;
} }
@media ( max-width : 768px) {
.pagination-container .el-pagination > .el-pagination__jump {
display: none !important;
}
.pagination-container .el-pagination > .el-pagination__sizes {
display: none !important;
}
}
.el-table .fixed-width .el-button--mini { .el-table .fixed-width .el-button--mini {
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;

@ -75,7 +75,7 @@ export default {
[{ color: [] }, { background: [] }], // [{ color: [] }, { background: [] }], //
[{ align: [] }], // [{ align: [] }], //
["clean"], // ["clean"], //
["link", "image"] // ["link", "image", "video"] //
], ],
}, },
placeholder: "请输入内容", placeholder: "请输入内容",
@ -165,7 +165,7 @@ export default {
// //
let length = quill.getSelection().index; let length = quill.getSelection().index;
// res.url // res.url
quill.insertEmbed(length, "image", res.data.url); quill.insertEmbed(length, "image", res.url);
// //
quill.setSelection(length + 1); quill.setSelection(length + 1);
} else { } else {

@ -6,6 +6,7 @@
:page-size.sync="pageSize" :page-size.sync="pageSize"
:layout="layout" :layout="layout"
:page-sizes="pageSizes" :page-sizes="pageSizes"
:pager-count="pagerCount"
:total="total" :total="total"
v-bind="$attrs" v-bind="$attrs"
@size-change="handleSizeChange" @size-change="handleSizeChange"
@ -38,6 +39,11 @@ export default {
return [10, 20, 30, 50] return [10, 20, 30, 50]
} }
}, },
// 5
pagerCount: {
type: Number,
default: document.body.clientWidth < 992 ? 5 : 7
},
layout: { layout: {
type: String, type: String,
default: 'total, sizes, prev, pager, next, jumper' default: 'total, sizes, prev, pager, next, jumper'

@ -104,7 +104,7 @@ export default {
this.$store.dispatch('LogOut').then(() => { this.$store.dispatch('LogOut').then(() => {
location.href = '/index'; location.href = '/index';
}) })
}) }).catch(() => {});
} }
} }
} }

@ -62,6 +62,11 @@
<el-switch v-model="sidebarLogo" class="drawer-switch" /> <el-switch v-model="sidebarLogo" class="drawer-switch" />
</div> </div>
<div class="drawer-item">
<span>动态标题</span>
<el-switch v-model="dynamicTitle" class="drawer-switch" />
</div>
<el-divider/> <el-divider/>
<el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting"></el-button> <el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting"></el-button>
@ -129,6 +134,17 @@ export default {
}) })
} }
}, },
dynamicTitle: {
get() {
return this.$store.state.settings.dynamicTitle
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'dynamicTitle',
value: val
})
}
},
}, },
methods: { methods: {
themeChange(val) { themeChange(val) {
@ -160,6 +176,7 @@ export default {
"tagsView":${this.tagsView}, "tagsView":${this.tagsView},
"fixedHeader":${this.fixedHeader}, "fixedHeader":${this.fixedHeader},
"sidebarLogo":${this.sidebarLogo}, "sidebarLogo":${this.sidebarLogo},
"dynamicTitle":${this.dynamicTitle},
"sideTheme":"${this.sideTheme}", "sideTheme":"${this.sideTheme}",
"theme":"${this.theme}" "theme":"${this.theme}"
}` }`

@ -21,6 +21,8 @@ import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels,
import Pagination from "@/components/Pagination"; import Pagination from "@/components/Pagination";
// 自定义表格工具扩展 // 自定义表格工具扩展
import RightToolbar from "@/components/RightToolbar" import RightToolbar from "@/components/RightToolbar"
// 头部标签插件
import VueMeta from 'vue-meta'
// 全局方法挂载 // 全局方法挂载
Vue.prototype.getDicts = getDicts Vue.prototype.getDicts = getDicts
@ -50,6 +52,7 @@ Vue.component('Pagination', Pagination)
Vue.component('RightToolbar', RightToolbar) Vue.component('RightToolbar', RightToolbar)
Vue.use(permission) Vue.use(permission)
Vue.use(VueMeta)
/** /**
* If you don't want to use mock-server * If you don't want to use mock-server

@ -12,6 +12,7 @@ const whiteList = ['/login', '/auth-redirect', '/bind', '/register']
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
NProgress.start() NProgress.start()
if (getToken()) { if (getToken()) {
to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
/* has token*/ /* has token*/
if (to.path === '/login') { if (to.path === '/login') {
next({ path: '/' }) next({ path: '/' })

@ -1,6 +1,4 @@
module.exports = { module.exports = {
title: '若依管理系统',
/** /**
* 侧边栏主题 深色主题theme-dark浅色主题theme-light * 侧边栏主题 深色主题theme-dark浅色主题theme-light
*/ */
@ -31,6 +29,11 @@ module.exports = {
*/ */
sidebarLogo: true, sidebarLogo: true,
/**
* 是否显示动态标题
*/
dynamicTitle: false,
/** /**
* @type {string | array} 'production' | ['production', 'development'] * @type {string | array} 'production' | ['production', 'development']
* @description Need show err logs component. * @description Need show err logs component.

@ -1,17 +1,19 @@
import variables from '@/assets/styles/element-variables.scss' import variables from '@/assets/styles/element-variables.scss'
import defaultSettings from '@/settings' import defaultSettings from '@/settings'
const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo } = defaultSettings const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '' const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
const state = { const state = {
title: '',
theme: storageSetting.theme || variables.theme, theme: storageSetting.theme || variables.theme,
sideTheme: storageSetting.sideTheme || sideTheme, sideTheme: storageSetting.sideTheme || sideTheme,
showSettings: showSettings, showSettings: showSettings,
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav, topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView, tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
} }
const mutations = { const mutations = {
CHANGE_SETTING: (state, { key, value }) => { CHANGE_SETTING: (state, { key, value }) => {
@ -22,8 +24,13 @@ const mutations = {
} }
const actions = { const actions = {
// 修改布局设置
changeSetting({ commit }, data) { changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data) commit('CHANGE_SETTING', data)
},
// 设置网页标题
setTitle({ commit }, title) {
state.title = title
} }
} }

@ -65,7 +65,7 @@ service.interceptors.response.use(res => {
store.dispatch('LogOut').then(() => { store.dispatch('LogOut').then(() => {
location.href = '/index'; location.href = '/index';
}) })
}) }).catch(() => {});
} else if (code === 500) { } else if (code === 500) {
Message({ Message({
message: msg, message: msg,

@ -146,6 +146,62 @@
<span>更新日志</span> <span>更新日志</span>
</div> </div>
<el-collapse accordion> <el-collapse accordion>
<el-collapse-item title="v3.0.0 - 2021-06-10">
<ol>
<li>新增菜单导航显示风格TopNavfalse为左侧导航菜单true为顶部导航菜单</li>
<li>布局设置支持保存&重置配置</li>
<li>富文本编辑器支持自定义上传地址</li>
<li>富文本编辑组件新增readOnly属性</li>
<li>优化参数&字典缓存操作</li>
<li>新增IE浏览器版本过低提示页面</li>
<li>页签TagsView新增关闭右侧功能</li>
<li>显隐列组件加载初始默认隐藏列</li>
<li>关闭头像上传窗口还原默认图片</li>
<li>个人信息添加手机&邮箱重复验证</li>
<li>代码生成模板树表操作列添加新增按钮</li>
<li>代码生成模板修复主子表字段重名问题</li>
<li>支持docker部署项目</li>
<li>升级springcloud到最新版2020.0.3</li>
<li>升级spring-boot-alibaba到最新版2021.1</li>
<li>升级nacos到最新版2.0.1 性能提升</li>
<li>升级spring-boot到最新版本2.5.0</li>
<li>升级spring-boot-admin到最新版2.4.1</li>
<li>升级swagger到最新版本3.0.0</li>
<li>升级mybatis到最新版3.5.6</li>
<li>升级dynamic-ds到最新版本3.3.2</li>
<li>升级minio到最新版本8.2.1</li>
<li>升级fastjson到最新版1.2.76</li>
<li>升级druid到最新版本v1.2.6</li>
<li>修复四级菜单无法显示问题</li>
<li>修复树表数据显示不全&加载慢问题</li>
<li>修复关闭confirm提示框控制台报错问题</li>
<li>上传媒体类型添加视频格式</li>
<li>增加feign客户端IP头部信息</li>
<li>修复两处存在SQL注入漏洞问题</li>
<li>优化图片工具类读取文件防止异常</li>
<li>修复导出角色数据范围翻译缺少仅本人</li>
<li>修复表单构建选择下拉选择控制台报错问题</li>
<li>修复请求形参未传值记录日志异常问题</li>
<li>调整sql默认为当前时间</li>
<li>修改ip字段长度防止ipv6地址长度不够</li>
<li>删除操作日志记录信息</li>
<li>修复firefox下表单构建拖拽会新打卡一个选项卡</li>
<li>用户&角色单条删除时使其逻辑删除</li>
<li>优化树表代码生成模板</li>
<li>修正通知公告日志记录类型</li>
<li>修正后端导入表权限标识</li>
<li>过滤BindingResult对象防止异常</li>
<li>Redis设置HashKey序列化</li>
<li>优化Excel导入增加空行判断</li>
<li>树级结构更新子节点使用replaceFirst</li>
<li>富文本工具栏配置视频</li>
<li>修正模板字符编码</li>
<li>优化通用下载完成后删除节点</li>
<li>角色非自定义权限范围清空选择值</li>
<li>修改主题后mini类型按钮无效问题</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v2.5.0 - 2021-02-02"> <el-collapse-item title="v2.5.0 - 2021-02-02">
<ol> <ol>
<li>增加分布式事务seata支持</li> <li>增加分布式事务seata支持</li>
@ -449,7 +505,7 @@ export default {
data() { data() {
return { return {
// //
version: "2.5.0", version: "3.0.0",
}; };
}, },
methods: { methods: {

@ -407,7 +407,7 @@ export default {
return runJob(row.jobId, row.jobGroup); return runJob(row.jobId, row.jobGroup);
}).then(() => { }).then(() => {
this.msgSuccess("执行成功"); this.msgSuccess("执行成功");
}) }).catch(() => {});
}, },
/** 任务详细信息 */ /** 任务详细信息 */
handleView(row) { handleView(row) {

@ -116,7 +116,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("强退成功"); this.msgSuccess("强退成功");
}) }).catch(() => {});
} }
} }
}; };

@ -335,7 +335,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {

@ -178,7 +178,7 @@ export default {
{ required: true, message: "部门名称不能为空", trigger: "blur" } { required: true, message: "部门名称不能为空", trigger: "blur" }
], ],
orderNum: [ orderNum: [
{ required: true, message: "菜单顺序不能为空", trigger: "blur" } { required: true, message: "显示排序不能为空", trigger: "blur" }
], ],
email: [ email: [
{ {
@ -310,7 +310,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
} }
} }
}; };

@ -1,6 +1,6 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" v-show="showSearch" :inline="true"> <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="字典名称" prop="dictType"> <el-form-item label="字典名称" prop="dictType">
<el-select v-model="queryParams.dictType" size="small"> <el-select v-model="queryParams.dictType" size="small">
<el-option <el-option
@ -334,7 +334,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {

@ -339,7 +339,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {

@ -196,7 +196,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
}, },
/** 清空按钮操作 */ /** 清空按钮操作 */
handleClean() { handleClean() {
@ -209,7 +209,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("清空成功"); this.msgSuccess("清空成功");
}) }).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {

@ -163,7 +163,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item v-if="form.menuType != 'M'" label="权限标识"> <el-form-item v-if="form.menuType != 'M'" label="权限标识">
<el-input v-model="form.perms" placeholder="请权限标识" maxlength="50" /> <el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="100" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -393,7 +393,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
} }
} }
}; };

@ -224,7 +224,7 @@ export default {
{ required: true, message: "公告标题不能为空", trigger: "blur" } { required: true, message: "公告标题不能为空", trigger: "blur" }
], ],
noticeType: [ noticeType: [
{ required: true, message: "公告类型不能为空", trigger: "blur" } { required: true, message: "公告类型不能为空", trigger: "change" }
] ]
} }
}; };
@ -336,7 +336,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
} }
} }
}; };

@ -100,7 +100,7 @@
icon="el-icon-download" icon="el-icon-download"
size="mini" size="mini"
@click="handleExport" @click="handleExport"
v-hasPermi="['system:config:export']" v-hasPermi="['system:operlog:export']"
>导出</el-button> >导出</el-button>
</el-col> </el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@ -286,7 +286,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
}, },
/** 清空按钮操作 */ /** 清空按钮操作 */
handleClean() { handleClean() {
@ -299,7 +299,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("清空成功"); this.msgSuccess("清空成功");
}) }).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {

@ -306,7 +306,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {

@ -590,7 +590,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {

@ -542,7 +542,7 @@ export default {
}, },
/** 搜索按钮操作 */ /** 搜索按钮操作 */
handleQuery() { handleQuery() {
this.queryParams.page = 1; this.queryParams.pageNum = 1;
this.getList(); this.getList();
}, },
/** 重置按钮操作 */ /** 重置按钮操作 */
@ -628,7 +628,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {

@ -573,6 +573,7 @@
<script> <script>
import { isArray } from 'util' import { isArray } from 'util'
import draggable from 'vuedraggable'
import TreeNodeDialog from './TreeNodeDialog' import TreeNodeDialog from './TreeNodeDialog'
import { isNumberStr } from '@/utils/index' import { isNumberStr } from '@/utils/index'
import IconsDialog from './IconsDialog' import IconsDialog from './IconsDialog'
@ -595,6 +596,7 @@ const dateTimeFormat = {
export default { export default {
components: { components: {
draggable,
TreeNodeDialog, TreeNodeDialog,
IconsDialog IconsDialog
}, },

@ -283,7 +283,7 @@ export default {
return synchDb(tableName); return synchDb(tableName);
}).then(() => { }).then(() => {
this.msgSuccess("同步成功"); this.msgSuccess("同步成功");
}) }).catch(() => {});
}, },
/** 打开导入表弹窗 */ /** 打开导入表弹窗 */
openImportTable() { openImportTable() {
@ -333,7 +333,7 @@ export default {
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) }).catch(() => {});
} }
} }
}; };

@ -1,12 +1,11 @@
'use strict' 'use strict'
const path = require('path') const path = require('path')
const defaultSettings = require('./src/settings.js')
function resolve(dir) { function resolve(dir) {
return path.join(__dirname, dir) return path.join(__dirname, dir)
} }
const name = defaultSettings.title || '若依管理系统' // 标题 const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
const port = process.env.port || process.env.npm_config_port || 80 // 端口 const port = process.env.port || process.env.npm_config_port || 80 // 端口

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-visual</artifactId> <artifactId>ruoyi-visual</artifactId>
<version>2.5.0</version> <version>3.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -177,7 +177,7 @@ insert into sys_menu values('112', 'Nacos控制台', '2', '4', 'http://lo
insert into sys_menu values('113', 'Admin控制台', '2', '5', 'http://localhost:9100/login', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', sysdate(), '', null, '服务监控菜单'); insert into sys_menu values('113', 'Admin控制台', '2', '5', 'http://localhost:9100/login', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', '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('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:8080/swagger-ui.html', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单'); insert into sys_menu values('116', '系统接口', '3', '3', 'http://localhost:8080/swagger-ui/index.html', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', '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, '登录日志菜单');

@ -1,3 +1,12 @@
DROP DATABASE IF EXISTS `ry-seata`;
CREATE DATABASE `ry-seata` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
USE `ry-seata`;
-- -------------------------------- The script used when storeMode is 'db' -------------------------------- -- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data -- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `global_table` CREATE TABLE IF NOT EXISTS `global_table`

Loading…
Cancel
Save