Merge branch 'master' into only-master

pull/162/head
thinkcodee 3 years ago
commit e16ece69c1

@ -1,11 +1,11 @@
<p align="center"> <p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-b99b286755aef70355a7084753f89cdb7c9.png"> <img alt="logo" src="https://oscimg.oschina.net/oscnet/up-b99b286755aef70355a7084753f89cdb7c9.png">
</p> </p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.4.0</h1> <h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.5.0</h1>
<h4 align="center">基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构</h4> <h4 align="center">基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构</h4>
<p align="center"> <p align="center">
<a href="https://gitee.com/y_project/RuoYi-Cloud/stargazers"><img src="https://gitee.com/y_project/RuoYi-Cloud/badge/star.svg?theme=dark"></a> <a href="https://gitee.com/y_project/RuoYi-Cloud/stargazers"><img src="https://gitee.com/y_project/RuoYi-Cloud/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Cloud"><img src="https://img.shields.io/badge/RuoYi-v3.4.0-brightgreen.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Cloud"><img src="https://img.shields.io/badge/RuoYi-v3.5.0-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Cloud/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Cloud/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p> </p>
@ -127,4 +127,4 @@ com.ruoyi
## 若依微服务交流群 ## 若依微服务交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-42799195-blue.svg)](https://jq.qq.com/?_wv=1027&k=yqInfq0S) [![加入QQ群](https://img.shields.io/badge/已满-170157040-blue.svg)](https://jq.qq.com/?_wv=1027&k=Oy1mb3p8) [![加入QQ群](https://img.shields.io/badge/已满-130643120-blue.svg)](https://jq.qq.com/?_wv=1027&k=rvxkJtXK) [![加入QQ群](https://img.shields.io/badge/已满-225920371-blue.svg)](https://jq.qq.com/?_wv=1027&k=0Ck3PvTe) [![加入QQ群](https://img.shields.io/badge/已满-201705537-blue.svg)](https://jq.qq.com/?_wv=1027&k=FnHHP4TT) [![加入QQ群](https://img.shields.io/badge/236543183-blue.svg)](https://jq.qq.com/?_wv=1027&k=qdT1Ojpz) 点击按钮入群。 QQ群 [![加入QQ群](https://img.shields.io/badge/已满-42799195-blue.svg)](https://jq.qq.com/?_wv=1027&k=yqInfq0S) [![加入QQ群](https://img.shields.io/badge/已满-170157040-blue.svg)](https://jq.qq.com/?_wv=1027&k=Oy1mb3p8) [![加入QQ群](https://img.shields.io/badge/已满-130643120-blue.svg)](https://jq.qq.com/?_wv=1027&k=rvxkJtXK) [![加入QQ群](https://img.shields.io/badge/已满-225920371-blue.svg)](https://jq.qq.com/?_wv=1027&k=0Ck3PvTe) [![加入QQ群](https://img.shields.io/badge/已满-201705537-blue.svg)](https://jq.qq.com/?_wv=1027&k=FnHHP4TT) [![加入QQ群](https://img.shields.io/badge/已满-236543183-blue.svg)](https://jq.qq.com/?_wv=1027&k=qdT1Ojpz) [![加入QQ群](https://img.shields.io/badge/213618602-blue.svg)](https://jq.qq.com/?_wv=1027&k=nw3OiyXs) 点击按钮入群。

@ -6,22 +6,22 @@
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.4.0</version> <version>3.5.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>3.4.0</ruoyi.version> <ruoyi.version>3.5.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.6.4</spring-boot.version> <spring-boot.version>2.6.7</spring-boot.version>
<spring-cloud.version>2021.0.1</spring-cloud.version> <spring-cloud.version>2021.0.1</spring-cloud.version>
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version> <spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version>
<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.7</spring-boot-admin.version>
<spring-boot.mybatis>2.2.2</spring-boot.mybatis> <spring-boot.mybatis>2.2.2</spring-boot.mybatis>
<swagger.fox.version>3.0.0</swagger.fox.version> <swagger.fox.version>3.0.0</swagger.fox.version>
<swagger.core.version>1.6.2</swagger.core.version> <swagger.core.version>1.6.2</swagger.core.version>
@ -33,7 +33,7 @@
<commons.io.version>2.11.0</commons.io.version> <commons.io.version>2.11.0</commons.io.version>
<commons.fileupload.version>1.4</commons.fileupload.version> <commons.fileupload.version>1.4</commons.fileupload.version>
<velocity.version>2.3</velocity.version> <velocity.version>2.3</velocity.version>
<fastjson.version>1.2.79</fastjson.version> <fastjson.version>1.2.80</fastjson.version>
<jjwt.version>0.9.1</jjwt.version> <jjwt.version>0.9.1</jjwt.version>
<minio.version>8.2.2</minio.version> <minio.version>8.2.2</minio.version>
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.4.0</version> <version>3.5.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>3.4.0</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.validation.constraints.Email; import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@ -31,7 +32,7 @@ public class SysDept extends BaseEntity
private String deptName; private String deptName;
/** 显示顺序 */ /** 显示顺序 */
private String orderNum; private Integer orderNum;
/** 负责人 */ /** 负责人 */
private String leader; private String leader;
@ -96,13 +97,13 @@ public class SysDept extends BaseEntity
this.deptName = deptName; this.deptName = deptName;
} }
@NotBlank(message = "显示顺序不能为空") @NotNull(message = "显示顺序不能为空")
public String getOrderNum() public Integer getOrderNum()
{ {
return orderNum; return orderNum;
} }
public void setOrderNum(String orderNum) public void setOrderNum(Integer orderNum)
{ {
this.orderNum = orderNum; this.orderNum = orderNum;
} }

@ -1,6 +1,7 @@
package com.ruoyi.system.api.domain; package com.ruoyi.system.api.domain;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@ -57,6 +58,7 @@ public class SysDictType extends BaseEntity
@NotBlank(message = "字典类型不能为空") @NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符") @Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
@Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)")
public String getDictType() public String getDictType()
{ {
return dictType; return dictType;

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

@ -148,11 +148,11 @@ public class SysLoginService
// 日志状态 // 日志状态
if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER))
{ {
logininfor.setStatus("0"); logininfor.setStatus(Constants.LOGIN_SUCCESS_STATUS);
} }
else if (Constants.LOGIN_FAIL.equals(status)) else if (Constants.LOGIN_FAIL.equals(status))
{ {
logininfor.setStatus("1"); logininfor.setStatus(Constants.LOGIN_FAIL_STATUS);
} }
remoteLogService.saveLogininfor(logininfor, SecurityConstants.INNER); remoteLogService.saveLogininfor(logininfor, SecurityConstants.INNER);
} }

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.4.0</version> <version>3.5.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>3.4.0</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,6 +5,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.math.BigDecimal; import java.math.BigDecimal;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import com.ruoyi.common.core.utils.poi.ExcelHandlerAdapter; import com.ruoyi.common.core.utils.poi.ExcelHandlerAdapter;
/** /**
@ -51,11 +53,6 @@ public @interface Excel
*/ */
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
/**
* 0 1
*/
public ColumnType cellType() default ColumnType.STRING;
/** /**
* excel * excel
*/ */
@ -102,9 +99,19 @@ public @interface Excel
public boolean isStatistics() default false; public boolean isStatistics() default false;
/** /**
* 0123 * 0 1
*/
public ColumnType cellType() default ColumnType.STRING;
/**
*
*/
public IndexedColors color() default IndexedColors.BLACK;
/**
*
*/ */
public Align align() default Align.AUTO; public HorizontalAlignment align() default HorizontalAlignment.CENTER;
/** /**
* *
@ -116,22 +123,6 @@ public @interface Excel
*/ */
public String[] args() default {}; public String[] args() default {};
public enum Align
{
AUTO(0), LEFT(1), CENTER(2), RIGHT(3);
private final int value;
Align(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
/** /**
* 012 * 012
*/ */

@ -52,6 +52,16 @@ public class Constants
*/ */
public static final Integer FAIL = 500; public static final Integer FAIL = 500;
/**
*
*/
public static final String LOGIN_SUCCESS_STATUS = "0";
/**
*
*/
public static final String LOGIN_FAIL_STATUS = "1";
/** /**
* *
*/ */

@ -561,17 +561,12 @@ public class Convert
switch (valueStr) switch (valueStr)
{ {
case "true": case "true":
return true;
case "false":
return false;
case "yes": case "yes":
return true;
case "ok": case "ok":
return true;
case "no":
return false;
case "1": case "1":
return true; return true;
case "false":
case "no":
case "0": case "0":
return false; return false;
default: default:

@ -20,11 +20,16 @@ public class PageUtils extends PageHelper
PageDomain pageDomain = TableSupport.buildPageRequest(); PageDomain pageDomain = TableSupport.buildPageRequest();
Integer pageNum = pageDomain.getPageNum(); Integer pageNum = pageDomain.getPageNum();
Integer pageSize = pageDomain.getPageSize(); Integer pageSize = pageDomain.getPageSize();
if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
{ Boolean reasonable = pageDomain.getReasonable();
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
Boolean reasonable = pageDomain.getReasonable(); }
PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
} /**
* 线
*/
public static void clearPage()
{
PageHelper.clearPage();
} }
} }

@ -1,7 +1,10 @@
package com.ruoyi.common.core.utils.file; package com.ruoyi.common.core.utils.file;
import java.io.File; import java.io.File;
import java.util.Objects;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;
/** /**
* *
@ -45,6 +48,22 @@ public class FileTypeUtils
return fileName.substring(separatorIndex + 1).toLowerCase(); return fileName.substring(separatorIndex + 1).toLowerCase();
} }
/**
*
*
* @param file
* @return
*/
public static final String getExtension(MultipartFile file)
{
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
if (StringUtils.isEmpty(extension))
{
extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType()));
}
return extension;
}
/** /**
* *
* *

@ -12,58 +12,62 @@ import com.ruoyi.common.core.utils.StringUtils;
*/ */
public class IpUtils public class IpUtils
{ {
/**
* IP
*
* @param request
* @return IP
*/
public static String getIpAddr(HttpServletRequest request) public static String getIpAddr(HttpServletRequest request)
{ {
if (request == null) if (request == null)
{ {
return null; return "unknown";
}
String ip = null;
// X-Forwarded-ForSquid 服务代理
String ipAddresses = request.getHeader("X-Forwarded-For");
if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
{
// Proxy-Client-IPapache 服务代理
ipAddresses = request.getHeader("Proxy-Client-IP");
} }
if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{ {
// WL-Proxy-Client-IPweblogic 服务代理 ip = request.getHeader("Proxy-Client-IP");
ipAddresses = request.getHeader("WL-Proxy-Client-IP");
} }
if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{ {
// HTTP_CLIENT_IP有些代理服务器 ip = request.getHeader("X-Forwarded-For");
ipAddresses = request.getHeader("HTTP_CLIENT_IP");
} }
if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{ {
// X-Real-IPnginx服务代理 ip = request.getHeader("WL-Proxy-Client-IP");
ipAddresses = request.getHeader("X-Real-IP");
} }
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
// 有些网络通过多层代理那么获取到的ip就会有多个一般都是通过逗号,分割开来并且第一个ip为客户端的真实IP
if (ipAddresses != null && ipAddresses.length() != 0)
{ {
ip = ipAddresses.split(",")[0]; ip = request.getHeader("X-Real-IP");
} }
// 还是不能获取到最后再通过request.getRemoteAddr();获取 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
{ {
ip = request.getRemoteAddr(); ip = request.getRemoteAddr();
} }
return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
} }
/**
* IP
*
* @param ip IP
* @return
*/
public static boolean internalIp(String ip) public static boolean internalIp(String ip)
{ {
byte[] addr = textToNumericFormatV4(ip); byte[] addr = textToNumericFormatV4(ip);
return internalIp(addr) || "127.0.0.1".equals(ip); return internalIp(addr) || "127.0.0.1".equals(ip);
} }
/**
* IP
*
* @param addr byte
* @return
*/
private static boolean internalIp(byte[] addr) private static boolean internalIp(byte[] addr)
{ {
if (StringUtils.isNull(addr) || addr.length < 2) if (StringUtils.isNull(addr) || addr.length < 2)
@ -124,7 +128,8 @@ public class IpUtils
{ {
case 1: case 1:
l = Long.parseLong(elements[0]); l = Long.parseLong(elements[0]);
if ((l < 0L) || (l > 4294967295L)){ if ((l < 0L) || (l > 4294967295L))
{
return null; return null;
} }
bytes[0] = (byte) (int) (l >> 24 & 0xFF); bytes[0] = (byte) (int) (l >> 24 & 0xFF);
@ -134,12 +139,14 @@ public class IpUtils
break; break;
case 2: case 2:
l = Integer.parseInt(elements[0]); l = Integer.parseInt(elements[0]);
if ((l < 0L) || (l > 255L)) { if ((l < 0L) || (l > 255L))
{
return null; return null;
} }
bytes[0] = (byte) (int) (l & 0xFF); bytes[0] = (byte) (int) (l & 0xFF);
l = Integer.parseInt(elements[1]); l = Integer.parseInt(elements[1]);
if ((l < 0L) || (l > 16777215L)) { if ((l < 0L) || (l > 16777215L))
{
return null; return null;
} }
bytes[1] = (byte) (int) (l >> 16 & 0xFF); bytes[1] = (byte) (int) (l >> 16 & 0xFF);
@ -150,13 +157,15 @@ public class IpUtils
for (i = 0; i < 2; ++i) for (i = 0; i < 2; ++i)
{ {
l = Integer.parseInt(elements[i]); l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L)) { if ((l < 0L) || (l > 255L))
{
return null; return null;
} }
bytes[i] = (byte) (int) (l & 0xFF); bytes[i] = (byte) (int) (l & 0xFF);
} }
l = Integer.parseInt(elements[2]); l = Integer.parseInt(elements[2]);
if ((l < 0L) || (l > 65535L)) { if ((l < 0L) || (l > 65535L))
{
return null; return null;
} }
bytes[2] = (byte) (int) (l >> 8 & 0xFF); bytes[2] = (byte) (int) (l >> 8 & 0xFF);
@ -166,7 +175,8 @@ public class IpUtils
for (i = 0; i < 4; ++i) for (i = 0; i < 4; ++i)
{ {
l = Integer.parseInt(elements[i]); l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L)) { if ((l < 0L) || (l > 255L))
{
return null; return null;
} }
bytes[i] = (byte) (int) (l & 0xFF); bytes[i] = (byte) (int) (l & 0xFF);
@ -183,6 +193,11 @@ public class IpUtils
return bytes; return bytes;
} }
/**
* IP
*
* @return IP
*/
public static String getHostIp() public static String getHostIp()
{ {
try try
@ -195,6 +210,11 @@ public class IpUtils
return "127.0.0.1"; return "127.0.0.1";
} }
/**
*
*
* @return
*/
public static String getHostName() public static String getHostName()
{ {
try try
@ -206,4 +226,39 @@ public class IpUtils
} }
return "未知"; return "未知";
} }
/**
* unknown IP
*
* @param ip IP
* @return unknown IP
*/
public static String getMultistageReverseProxyIp(String ip)
{
// 多级反向代理检测
if (ip != null && ip.indexOf(",") > 0)
{
final String[] ips = ip.trim().split(",");
for (String subIp : ips)
{
if (false == isUnknown(subIp))
{
ip = subIp;
break;
}
}
}
return ip;
}
/**
* HTTP
*
* @param checkString
* @return
*/
public static boolean isUnknown(String checkString)
{
return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
}
} }

@ -18,6 +18,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.RegExUtils;
import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
@ -65,6 +66,8 @@ public class ExcelUtil<T>
{ {
private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
public static final String FORMULA_REGEX_STR = "=|-|\\+|@";
public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
/** /**
@ -284,7 +287,7 @@ public class ExcelUtil<T>
String dateFormat = field.getAnnotation(Excel.class).dateFormat(); String dateFormat = field.getAnnotation(Excel.class).dateFormat();
if (StringUtils.isNotEmpty(dateFormat)) if (StringUtils.isNotEmpty(dateFormat))
{ {
val = parseDateToStr(dateFormat, (Date) val); val = parseDateToStr(dateFormat, val);
} }
else else
{ {
@ -296,7 +299,7 @@ public class ExcelUtil<T>
{ {
val = Convert.toInt(val); val = Convert.toInt(val);
} }
else if (Long.TYPE == fieldType || Long.class == fieldType) else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val)))
{ {
val = Convert.toLong(val); val = Convert.toLong(val);
} }
@ -550,21 +553,46 @@ public class ExcelUtil<T>
style.setFont(totalFont); style.setFont(totalFont);
styles.put("total", style); styles.put("total", style);
style = wb.createCellStyle(); styles.putAll(annotationStyles(wb));
style.cloneStyleFrom(styles.get("data"));
style.setAlignment(HorizontalAlignment.LEFT);
styles.put("data1", style);
style = wb.createCellStyle(); return styles;
style.cloneStyleFrom(styles.get("data")); }
style.setAlignment(HorizontalAlignment.CENTER);
styles.put("data2", style);
style = wb.createCellStyle();
style.cloneStyleFrom(styles.get("data"));
style.setAlignment(HorizontalAlignment.RIGHT);
styles.put("data3", style);
/**
* Excel
*
* @param wb
* @return
*/
private Map<String, CellStyle> annotationStyles(Workbook wb)
{
Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
for (Object[] os : fields)
{
Excel excel = (Excel) os[1];
String key = "data_" + excel.align() + "_" + excel.color();
if (!styles.containsKey(key))
{
CellStyle style = wb.createCellStyle();
style = wb.createCellStyle();
style.setAlignment(excel.align());
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderRight(BorderStyle.THIN);
style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderLeft(BorderStyle.THIN);
style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderTop(BorderStyle.THIN);
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderBottom(BorderStyle.THIN);
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
Font dataFont = wb.createFont();
dataFont.setFontName("Arial");
dataFont.setFontHeightInPoints((short) 10);
dataFont.setColor(excel.color().index);
style.setFont(dataFont);
styles.put(key, style);
}
}
return styles; return styles;
} }
@ -595,9 +623,9 @@ public class ExcelUtil<T>
{ {
String cellValue = Convert.toStr(value); String cellValue = Convert.toStr(value);
// 对于任何以表达式触发字符 =-+@开头的单元格直接使用tab字符作为前缀防止CSV注入。 // 对于任何以表达式触发字符 =-+@开头的单元格直接使用tab字符作为前缀防止CSV注入。
if (StringUtils.containsAny(cellValue, FORMULA_STR)) if (StringUtils.startsWithAny(cellValue, FORMULA_STR))
{ {
cellValue = StringUtils.replaceEach(cellValue, FORMULA_STR, new String[] { "\t=", "\t-", "\t+", "\t@" }); cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0");
} }
cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix()); cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix());
} }
@ -664,17 +692,10 @@ public class ExcelUtil<T>
// 设置列宽 // 设置列宽
sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
} }
// 如果设置了提示信息则鼠标放上去提示. if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0)
if (StringUtils.isNotEmpty(attr.prompt()))
{ {
// 这里默认设了2-101列提示. // 提示信息或只能选择不能输入的列内容.
setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column); setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);
}
// 如果设置了combo属性则本列只能选择不能输入
if (attr.combo().length > 0)
{
// 这里默认设了2-101列只能选择不能输入.
setXSSFValidation(sheet, attr.combo(), 1, 100, column, column);
} }
} }
@ -693,8 +714,7 @@ public class ExcelUtil<T>
{ {
// 创建cell // 创建cell
cell = row.createCell(column); cell = row.createCell(column);
int align = attr.align().value(); cell.setCellStyle(styles.get("data_" + attr.align() + "_" + attr.color()));
cell.setCellStyle(styles.get("data" + (align >= 1 && align <= 3 ? align : "")));
// 用于读取对象中的属性 // 用于读取对象中的属性
Object value = getTargetValue(vo, field, attr); Object value = getTargetValue(vo, field, attr);
@ -703,7 +723,7 @@ public class ExcelUtil<T>
String separator = attr.separator(); String separator = attr.separator();
if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
{ {
cell.setCellValue(parseDateToStr(dateFormat, (Date) value)); cell.setCellValue(parseDateToStr(dateFormat, value));
} }
else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
{ {
@ -733,48 +753,29 @@ public class ExcelUtil<T>
} }
/** /**
* POI XSSFSheet * POI XSSFSheet
* *
* @param sheet * @param sheet
* @param promptTitle * @param textlist
* @param promptContent * @param promptContent
* @param firstRow * @param firstRow
* @param endRow * @param endRow
* @param firstCol * @param firstCol
* @param endCol * @param endCol
*/ */
public void setXSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow, public void setPromptOrValidation(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow,
int firstCol, int endCol) int firstCol, int endCol)
{ {
DataValidationHelper helper = sheet.getDataValidationHelper(); DataValidationHelper helper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = helper.createCustomConstraint("DD1"); DataValidationConstraint constraint = textlist.length > 0 ? helper.createExplicitListConstraint(textlist) : helper.createCustomConstraint("DD1");
CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
DataValidation dataValidation = helper.createValidation(constraint, regions); DataValidation dataValidation = helper.createValidation(constraint, regions);
dataValidation.createPromptBox(promptTitle, promptContent); if (StringUtils.isNotEmpty(promptContent))
dataValidation.setShowPromptBox(true); {
sheet.addValidationData(dataValidation); // 如果设置了提示信息则鼠标放上去提示
} dataValidation.createPromptBox("", promptContent);
dataValidation.setShowPromptBox(true);
/** }
* ,.
*
* @param sheet sheet.
* @param textlist
* @param firstRow
* @param endRow
* @param firstCol
* @param endCol
* @return sheet.
*/
public void setXSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol)
{
DataValidationHelper helper = sheet.getDataValidationHelper();
// 加载下拉列表内容
DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist);
// 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
// 数据有效性对象
DataValidation dataValidation = helper.createValidation(constraint, regions);
// 处理Excel兼容性问题 // 处理Excel兼容性问题
if (dataValidation instanceof XSSFDataValidation) if (dataValidation instanceof XSSFDataValidation)
{ {
@ -785,7 +786,6 @@ public class ExcelUtil<T>
{ {
dataValidation.setSuppressDropDownArrow(false); dataValidation.setSuppressDropDownArrow(false);
} }
sheet.addValidationData(dataValidation); sheet.addValidationData(dataValidation);
} }

@ -48,6 +48,14 @@ public class BaseController
PageUtils.startPage(); PageUtils.startPage();
} }
/**
* 线
*/
protected void clearPage()
{
PageUtils.clearPage();
}
/** /**
* *
*/ */

@ -1,5 +1,6 @@
package com.ruoyi.common.core.web.page; package com.ruoyi.common.core.web.page;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.ServletUtils; import com.ruoyi.common.core.utils.ServletUtils;
/** /**
@ -40,8 +41,8 @@ public class TableSupport
public static PageDomain getPageDomain() public static PageDomain getPageDomain()
{ {
PageDomain pageDomain = new PageDomain(); PageDomain pageDomain = new PageDomain();
pageDomain.setPageNum(ServletUtils.getParameterToInt(PAGE_NUM)); pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1));
pageDomain.setPageSize(ServletUtils.getParameterToInt(PAGE_SIZE)); pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10));
pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN));
pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC));
pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE)); pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE));

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.4.0</version> <version>3.5.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>3.4.0</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -1,26 +0,0 @@
package com.ruoyi.common.datasource.env;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* seata springboot 2.6.x
*
* @author ruoyi
*/
public class ApplicationSeataInitializer implements EnvironmentPostProcessor, Ordered
{
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application)
{
System.setProperty("spring.main.allow-circular-references", "true");
}
@Override
public int getOrder()
{
return Ordered.LOWEST_PRECEDENCE;
}
}

@ -1,2 +0,0 @@
org.springframework.boot.env.EnvironmentPostProcessor=\
com.ruoyi.common.datasource.env.ApplicationSeataInitializer

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.4.0</version> <version>3.5.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>3.4.0</version> <version>3.5.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>3.4.0</version> <version>3.5.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>3.4.0</version> <version>3.5.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>3.4.0</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -58,6 +58,12 @@
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependency>
<!-- SpringCloud Loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!--验证码 --> <!--验证码 -->
<dependency> <dependency>
<groupId>com.github.penggle</groupId> <groupId>com.github.penggle</groupId>

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.4.0</version> <version>3.5.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>3.4.0</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -2,6 +2,7 @@ package com.ruoyi.file.utils;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Paths;
import java.util.Objects; import java.util.Objects;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -10,6 +11,7 @@ import com.ruoyi.common.core.exception.file.FileSizeLimitExceededException;
import com.ruoyi.common.core.exception.file.InvalidExtensionException; import com.ruoyi.common.core.exception.file.InvalidExtensionException;
import com.ruoyi.common.core.utils.DateUtils; import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.file.FileTypeUtils;
import com.ruoyi.common.core.utils.file.MimeTypeUtils; import com.ruoyi.common.core.utils.file.MimeTypeUtils;
import com.ruoyi.common.core.utils.uuid.Seq; import com.ruoyi.common.core.utils.uuid.Seq;
@ -76,8 +78,8 @@ public class FileUploadUtils
String fileName = extractFilename(file); String fileName = extractFilename(file);
File desc = getAbsoluteFile(baseDir, fileName); String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
file.transferTo(desc); file.transferTo(Paths.get(absPath));
return getPathFileName(fileName); return getPathFileName(fileName);
} }
@ -87,7 +89,7 @@ public class FileUploadUtils
public static final String extractFilename(MultipartFile file) public static final String extractFilename(MultipartFile file)
{ {
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(), return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file)); FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), FileTypeUtils.getExtension(file));
} }
private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
@ -127,7 +129,7 @@ public class FileUploadUtils
} }
String fileName = file.getOriginalFilename(); String fileName = file.getOriginalFilename();
String extension = getExtension(file); String extension = FileTypeUtils.getExtension(file);
if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
{ {
if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
@ -175,20 +177,4 @@ public class FileUploadUtils
} }
return false; 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(Objects.requireNonNull(file.getContentType()));
}
return extension;
}
} }

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

@ -59,12 +59,12 @@ public class GenController extends BaseController
* *
*/ */
@RequiresPermissions("tool:gen:query") @RequiresPermissions("tool:gen:query")
@GetMapping(value = "/{talbleId}") @GetMapping(value = "/{tableId}")
public AjaxResult getInfo(@PathVariable Long talbleId) public AjaxResult getInfo(@PathVariable Long tableId)
{ {
GenTable table = genTableService.selectGenTableById(talbleId); GenTable table = genTableService.selectGenTableById(tableId);
List<GenTable> tables = genTableService.selectGenTableAll(); List<GenTable> tables = genTableService.selectGenTableAll();
List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(talbleId); List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(tableId);
Map<String, Object> map = new HashMap<String, Object>(); Map<String, Object> map = new HashMap<String, Object>();
map.put("info", table); map.put("info", table);
map.put("rows", list); map.put("rows", list);
@ -87,7 +87,7 @@ public class GenController extends BaseController
/** /**
* *
*/ */
@GetMapping(value = "/column/{talbleId}") @GetMapping(value = "/column/{tableId}")
public TableDataInfo columnList(Long tableId) public TableDataInfo columnList(Long tableId)
{ {
TableDataInfo dataInfo = new TableDataInfo(); TableDataInfo dataInfo = new TableDataInfo();

@ -1,6 +1,6 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
#foreach($column in $columns) #foreach($column in $columns)
#if($column.query) #if($column.query)
#set($dictType=$column.dictType) #set($dictType=$column.dictType)
@ -17,13 +17,12 @@
v-model="queryParams.${column.javaField}" v-model="queryParams.${column.javaField}"
placeholder="请输入${comment}" placeholder="请输入${comment}"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${comment}" prop="${column.javaField}">
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable size="small"> <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable>
<el-option <el-option
v-for="dict in dict.type.${dictType}" v-for="dict in dict.type.${dictType}"
:key="dict.value" :key="dict.value"
@ -34,13 +33,13 @@
</el-form-item> </el-form-item>
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${comment}" prop="${column.javaField}">
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable size="small"> <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable>
<el-option label="请选择字典生成" value="" /> <el-option label="请选择字典生成" value="" />
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") #elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${comment}" prop="${column.javaField}">
<el-date-picker clearable size="small" <el-date-picker clearable
v-model="queryParams.${column.javaField}" v-model="queryParams.${column.javaField}"
type="date" type="date"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
@ -51,7 +50,6 @@
<el-form-item label="${comment}"> <el-form-item label="${comment}">
<el-date-picker <el-date-picker
v-model="daterange${AttrName}" v-model="daterange${AttrName}"
size="small"
style="width: 240px" style="width: 240px"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
type="daterange" type="daterange"
@ -80,14 +78,24 @@
v-hasPermi="['${moduleName}:${businessName}:add']" v-hasPermi="['${moduleName}:${businessName}:add']"
>新增</el-button> >新增</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-sort"
size="mini"
@click="toggleExpandAll"
>展开/折叠</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
<el-table <el-table
v-if="refreshTable"
v-loading="loading" v-loading="loading"
:data="${businessName}List" :data="${businessName}List"
row-key="${treeCode}" row-key="${treeCode}"
default-expand-all :default-expand-all="isExpandAll"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}" :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
> >
#foreach($column in $columns) #foreach($column in $columns)
@ -244,7 +252,7 @@
</el-form-item> </el-form-item>
#elseif($column.htmlType == "datetime") #elseif($column.htmlType == "datetime")
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${comment}" prop="${field}">
<el-date-picker clearable size="small" <el-date-picker clearable
v-model="form.${field}" v-model="form.${field}"
type="date" type="date"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
@ -295,6 +303,10 @@ export default {
title: "", title: "",
// 是否显示弹出层 // 是否显示弹出层
open: false, open: false,
// 是否展开,默认全部展开
isExpandAll: true,
// 重新渲染表格状态
refreshTable: true,
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
@ -425,6 +437,14 @@ export default {
this.open = true; this.open = true;
this.title = "添加${functionName}"; this.title = "添加${functionName}";
}, },
/** 展开/折叠操作 */
toggleExpandAll() {
this.refreshTable = false;
this.isExpandAll = !this.isExpandAll;
this.$nextTick(() => {
this.refreshTable = true;
});
},
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
this.reset(); this.reset();

@ -1,6 +1,6 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
#foreach($column in $columns) #foreach($column in $columns)
#if($column.query) #if($column.query)
#set($dictType=$column.dictType) #set($dictType=$column.dictType)
@ -17,13 +17,12 @@
v-model="queryParams.${column.javaField}" v-model="queryParams.${column.javaField}"
placeholder="请输入${comment}" placeholder="请输入${comment}"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${comment}" prop="${column.javaField}">
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable size="small"> <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable>
<el-option <el-option
v-for="dict in dict.type.${dictType}" v-for="dict in dict.type.${dictType}"
:key="dict.value" :key="dict.value"
@ -34,13 +33,13 @@
</el-form-item> </el-form-item>
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${comment}" prop="${column.javaField}">
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable size="small"> <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable>
<el-option label="请选择字典生成" value="" /> <el-option label="请选择字典生成" value="" />
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") #elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${comment}" prop="${column.javaField}">
<el-date-picker clearable size="small" <el-date-picker clearable
v-model="queryParams.${column.javaField}" v-model="queryParams.${column.javaField}"
type="date" type="date"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
@ -51,7 +50,6 @@
<el-form-item label="${comment}"> <el-form-item label="${comment}">
<el-date-picker <el-date-picker
v-model="daterange${AttrName}" v-model="daterange${AttrName}"
size="small"
style="width: 240px" style="width: 240px"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
type="daterange" type="daterange"
@ -265,7 +263,7 @@
</el-form-item> </el-form-item>
#elseif($column.htmlType == "datetime") #elseif($column.htmlType == "datetime")
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${comment}" prop="${field}">
<el-date-picker clearable size="small" <el-date-picker clearable
v-model="form.${field}" v-model="form.${field}"
type="date" type="date"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"

@ -76,14 +76,23 @@
v-hasPermi="['${moduleName}:${businessName}:add']" v-hasPermi="['${moduleName}:${businessName}:add']"
>新增</el-button> >新增</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="Sort"
@click="toggleExpandAll"
>展开/折叠</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
<el-table <el-table
v-if="refreshTable"
v-loading="loading" v-loading="loading"
:data="${businessName}List" :data="${businessName}List"
row-key="${treeCode}" row-key="${treeCode}"
default-expand-all :default-expand-all="isExpandAll"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}" :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
> >
#foreach($column in $columns) #foreach($column in $columns)
@ -165,11 +174,13 @@
#set($dictType=$column.dictType) #set($dictType=$column.dictType)
#if("" != $treeParentCode && $column.javaField == $treeParentCode) #if("" != $treeParentCode && $column.javaField == $treeParentCode)
<el-form-item label="${comment}" prop="${treeParentCode}"> <el-form-item label="${comment}" prop="${treeParentCode}">
<tree-select <el-tree-select
v-model:value="form.${treeParentCode}" v-model="form.${treeParentCode}"
:options="${businessName}Options" :data="${businessName}Options"
:objMap="{ value: '${treeCode}', label: '${treeName}', children: 'children' }" :props="{ value: '${treeCode}', label: '${treeName}', children: 'children' }"
value-key="${treeCode}"
placeholder="请选择${comment}" placeholder="请选择${comment}"
check-strictly
/> />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "input") #elseif($column.htmlType == "input")
@ -283,6 +294,8 @@ const open = ref(false);
const loading = ref(true); const loading = ref(true);
const showSearch = ref(true); const showSearch = ref(true);
const title = ref(""); const title = ref("");
const isExpandAll = ref(true);
const refreshTable = ref(true);
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
@ -343,8 +356,8 @@ function getList() {
} }
/** 查询${functionName}下拉树结构 */ /** 查询${functionName}下拉树结构 */
async function getTreeselect() { function getTreeselect() {
await list${BusinessName}().then(response => { list${BusinessName}().then(response => {
${businessName}Options.value = []; ${businessName}Options.value = [];
const data = { ${treeCode}: 0, ${treeName}: '顶级节点', children: [] }; const data = { ${treeCode}: 0, ${treeName}: '顶级节点', children: [] };
data.children = proxy.handleTree(response.data, "${treeCode}", "${treeParentCode}"); data.children = proxy.handleTree(response.data, "${treeCode}", "${treeParentCode}");
@ -393,9 +406,9 @@ function resetQuery() {
} }
/** 新增按钮操作 */ /** 新增按钮操作 */
async function handleAdd(row) { function handleAdd(row) {
reset(); reset();
await getTreeselect(); getTreeselect();
if (row != null && row.${treeCode}) { if (row != null && row.${treeCode}) {
form.value.${treeParentCode} = row.${treeCode}; form.value.${treeParentCode} = row.${treeCode};
} else { } else {
@ -405,6 +418,15 @@ async function handleAdd(row) {
title.value = "添加${functionName}"; title.value = "添加${functionName}";
} }
/** 展开/折叠操作 */
function toggleExpandAll() {
refreshTable.value = false;
isExpandAll.value = !isExpandAll.value;
nextTick(() => {
refreshTable.value = true;
});
}
/** 修改按钮操作 */ /** 修改按钮操作 */
async function handleUpdate(row) { async function handleUpdate(row) {
reset(); reset();

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

@ -14,6 +14,7 @@ import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.ScheduleConstants; import com.ruoyi.common.core.constant.ScheduleConstants;
import com.ruoyi.common.core.exception.job.TaskException; import com.ruoyi.common.core.exception.job.TaskException;
import com.ruoyi.common.core.exception.job.TaskException.Code; import com.ruoyi.common.core.exception.job.TaskException.Code;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.job.domain.SysJob; import com.ruoyi.job.domain.SysJob;
@ -127,6 +128,7 @@ public class ScheduleUtils
{ {
return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR); return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR);
} }
return true; Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]);
return StringUtils.containsAnyIgnoreCase(obj.getClass().getPackage().getName(), Constants.JOB_WHITELIST_STR);
} }
} }

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

@ -1,6 +1,6 @@
package com.ruoyi.system.controller; package com.ruoyi.system.controller;
import java.io.IOException; import java.util.Arrays;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -13,6 +13,8 @@ import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.constant.UserConstants; import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.file.FileTypeUtils;
import com.ruoyi.common.core.utils.file.MimeTypeUtils;
import com.ruoyi.common.core.web.controller.BaseController; import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.log.annotation.Log; import com.ruoyi.common.log.annotation.Log;
@ -126,11 +128,16 @@ public class SysProfileController extends BaseController
*/ */
@Log(title = "用户头像", businessType = BusinessType.UPDATE) @Log(title = "用户头像", businessType = BusinessType.UPDATE)
@PostMapping("/avatar") @PostMapping("/avatar")
public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws IOException public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file)
{ {
if (!file.isEmpty()) if (!file.isEmpty())
{ {
LoginUser loginUser = SecurityUtils.getLoginUser(); LoginUser loginUser = SecurityUtils.getLoginUser();
String extension = FileTypeUtils.getExtension(file);
if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION))
{
return AjaxResult.error("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式");
}
R<SysFile> fileResult = remoteFileService.upload(file); R<SysFile> fileResult = remoteFileService.upload(file);
if (StringUtils.isNull(fileResult) || StringUtils.isNull(fileResult.getData())) if (StringUtils.isNull(fileResult) || StringUtils.isNull(fileResult.getData()))
{ {

@ -176,7 +176,7 @@ public class SysMenuServiceImpl implements ISysMenuService
else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) else if (menu.getParentId().intValue() == 0 && isInnerLink(menu))
{ {
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon())); router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
router.setPath("/inner"); router.setPath("/");
List<RouterVo> childrenList = new ArrayList<RouterVo>(); List<RouterVo> childrenList = new ArrayList<RouterVo>();
RouterVo children = new RouterVo(); RouterVo children = new RouterVo();
String routerPath = innerLinkReplaceEach(menu.getPath()); String routerPath = innerLinkReplaceEach(menu.getPath());

@ -91,7 +91,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="parentId != null and parentId != 0">parent_id,</if> <if test="parentId != null and parentId != 0">parent_id,</if>
<if test="deptName != null and deptName != ''">dept_name,</if> <if test="deptName != null and deptName != ''">dept_name,</if>
<if test="ancestors != null and ancestors != ''">ancestors,</if> <if test="ancestors != null and ancestors != ''">ancestors,</if>
<if test="orderNum != null and orderNum != ''">order_num,</if> <if test="orderNum != null">order_num,</if>
<if test="leader != null and leader != ''">leader,</if> <if test="leader != null and leader != ''">leader,</if>
<if test="phone != null and phone != ''">phone,</if> <if test="phone != null and phone != ''">phone,</if>
<if test="email != null and email != ''">email,</if> <if test="email != null and email != ''">email,</if>
@ -103,7 +103,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="parentId != null and parentId != 0">#{parentId},</if> <if test="parentId != null and parentId != 0">#{parentId},</if>
<if test="deptName != null and deptName != ''">#{deptName},</if> <if test="deptName != null and deptName != ''">#{deptName},</if>
<if test="ancestors != null and ancestors != ''">#{ancestors},</if> <if test="ancestors != null and ancestors != ''">#{ancestors},</if>
<if test="orderNum != null and orderNum != ''">#{orderNum},</if> <if test="orderNum != null">#{orderNum},</if>
<if test="leader != null and leader != ''">#{leader},</if> <if test="leader != null and leader != ''">#{leader},</if>
<if test="phone != null and phone != ''">#{phone},</if> <if test="phone != null and phone != ''">#{phone},</if>
<if test="email != null and email != ''">#{email},</if> <if test="email != null and email != ''">#{email},</if>
@ -119,7 +119,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="parentId != null and parentId != 0">parent_id = #{parentId},</if> <if test="parentId != null and parentId != 0">parent_id = #{parentId},</if>
<if test="deptName != null and deptName != ''">dept_name = #{deptName},</if> <if test="deptName != null and deptName != ''">dept_name = #{deptName},</if>
<if test="ancestors != null and ancestors != ''">ancestors = #{ancestors},</if> <if test="ancestors != null and ancestors != ''">ancestors = #{ancestors},</if>
<if test="orderNum != null and orderNum != ''">order_num = #{orderNum},</if> <if test="orderNum != null">order_num = #{orderNum},</if>
<if test="leader != null">leader = #{leader},</if> <if test="leader != null">leader = #{leader},</if>
<if test="phone != null">phone = #{phone},</if> <if test="phone != null">phone = #{phone},</if>
<if test="email != null">email = #{email},</if> <if test="email != null">email = #{email},</if>

@ -130,7 +130,7 @@
<set> <set>
<if test="menuName != null and menuName != ''">menu_name = #{menuName},</if> <if test="menuName != null and menuName != ''">menu_name = #{menuName},</if>
<if test="parentId != null">parent_id = #{parentId},</if> <if test="parentId != null">parent_id = #{parentId},</if>
<if test="orderNum != null and orderNum != ''">order_num = #{orderNum},</if> <if test="orderNum != null">order_num = #{orderNum},</if>
<if test="path != null and path != ''">path = #{path},</if> <if test="path != null and path != ''">path = #{path},</if>
<if test="component != null">component = #{component},</if> <if test="component != null">component = #{component},</if>
<if test="query != null">`query` = #{query},</if> <if test="query != null">`query` = #{query},</if>
@ -153,7 +153,7 @@
<if test="menuId != null and menuId != 0">menu_id,</if> <if test="menuId != null and menuId != 0">menu_id,</if>
<if test="parentId != null and parentId != 0">parent_id,</if> <if test="parentId != null and parentId != 0">parent_id,</if>
<if test="menuName != null and menuName != ''">menu_name,</if> <if test="menuName != null and menuName != ''">menu_name,</if>
<if test="orderNum != null and orderNum != ''">order_num,</if> <if test="orderNum != null">order_num,</if>
<if test="path != null and path != ''">path,</if> <if test="path != null and path != ''">path,</if>
<if test="component != null and component != ''">component,</if> <if test="component != null and component != ''">component,</if>
<if test="query != null and query != ''">`query`,</if> <if test="query != null and query != ''">`query`,</if>
@ -171,7 +171,7 @@
<if test="menuId != null and menuId != 0">#{menuId},</if> <if test="menuId != null and menuId != 0">#{menuId},</if>
<if test="parentId != null and parentId != 0">#{parentId},</if> <if test="parentId != null and parentId != 0">#{parentId},</if>
<if test="menuName != null and menuName != ''">#{menuName},</if> <if test="menuName != null and menuName != ''">#{menuName},</if>
<if test="orderNum != null and orderNum != ''">#{orderNum},</if> <if test="orderNum != null">#{orderNum},</if>
<if test="path != null and path != ''">#{path},</if> <if test="path != null and path != ''">#{path},</if>
<if test="component != null and component != ''">#{component},</if> <if test="component != null and component != ''">#{component},</if>
<if test="query != null and query != ''">#{query},</if> <if test="query != null and query != ''">#{query},</if>

@ -38,7 +38,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="title != null and title != ''"> <if test="title != null and title != ''">
AND title like concat('%', #{title}, '%') AND title like concat('%', #{title}, '%')
</if> </if>
<if test="businessType != null and businessType != ''"> <if test="businessType != null">
AND business_type = #{businessType} AND business_type = #{businessType}
</if> </if>
<if test="businessTypes != null and businessTypes.length > 0"> <if test="businessTypes != null and businessTypes.length > 0">

@ -46,7 +46,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where post_id = #{postId} where post_id = #{postId}
</select> </select>
<select id="selectPostListByUserId" parameterType="Long" resultType="Integer"> <select id="selectPostListByUserId" parameterType="Long" resultType="Long">
select p.post_id select p.post_id
from sys_post p from sys_post p
left join sys_user_post up on up.post_id = p.post_id left join sys_user_post up on up.post_id = p.post_id

@ -4,50 +4,51 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysUserMapper"> <mapper namespace="com.ruoyi.system.mapper.SysUserMapper">
<resultMap type="SysUser" id="SysUserResult"> <resultMap type="SysUser" id="SysUserResult">
<id property="userId" column="user_id" /> <id property="userId" column="user_id" />
<result property="deptId" column="dept_id" /> <result property="deptId" column="dept_id" />
<result property="userName" column="user_name" /> <result property="userName" column="user_name" />
<result property="nickName" column="nick_name" /> <result property="nickName" column="nick_name" />
<result property="email" column="email" /> <result property="email" column="email" />
<result property="phonenumber" column="phonenumber" /> <result property="phonenumber" column="phonenumber" />
<result property="sex" column="sex" /> <result property="sex" column="sex" />
<result property="avatar" column="avatar" /> <result property="avatar" column="avatar" />
<result property="password" column="password" /> <result property="password" column="password" />
<result property="status" column="status" /> <result property="status" column="status" />
<result property="delFlag" column="del_flag" /> <result property="delFlag" column="del_flag" />
<result property="loginIp" column="login_ip" /> <result property="loginIp" column="login_ip" />
<result property="loginDate" column="login_date" /> <result property="loginDate" column="login_date" />
<result property="createBy" column="create_by" /> <result property="createBy" column="create_by" />
<result property="createTime" column="create_time" /> <result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" /> <result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" /> <result property="updateTime" column="update_time" />
<result property="remark" column="remark" /> <result property="remark" column="remark" />
<association property="dept" column="dept_id" javaType="SysDept" resultMap="deptResult" /> <association property="dept" column="dept_id" javaType="SysDept" resultMap="deptResult" />
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" /> <collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
</resultMap> </resultMap>
<resultMap id="deptResult" type="SysDept"> <resultMap id="deptResult" type="SysDept">
<id property="deptId" column="dept_id" /> <id property="deptId" column="dept_id" />
<result property="parentId" column="parent_id" /> <result property="parentId" column="parent_id" />
<result property="deptName" column="dept_name" /> <result property="deptName" column="dept_name" />
<result property="orderNum" column="order_num" /> <result property="ancestors" column="ancestors" />
<result property="leader" column="leader" /> <result property="orderNum" column="order_num" />
<result property="status" column="dept_status" /> <result property="leader" column="leader" />
</resultMap> <result property="status" column="dept_status" />
</resultMap>
<resultMap id="RoleResult" type="SysRole">
<id property="roleId" column="role_id" /> <resultMap id="RoleResult" type="SysRole">
<result property="roleName" column="role_name" /> <id property="roleId" column="role_id" />
<result property="roleKey" column="role_key" /> <result property="roleName" column="role_name" />
<result property="roleSort" column="role_sort" /> <result property="roleKey" column="role_key" />
<result property="dataScope" column="data_scope" /> <result property="roleSort" column="role_sort" />
<result property="status" column="role_status" /> <result property="dataScope" column="data_scope" />
</resultMap> <result property="status" column="role_status" />
</resultMap>
<sql id="selectUserVo"> <sql id="selectUserVo">
select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
d.dept_id, d.parent_id, d.dept_name, d.order_num, d.leader, d.status as dept_status, d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,
r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
from sys_user u from sys_user u
left join sys_dept d on u.dept_id = d.dept_id left join sys_dept d on u.dept_id = d.dept_id

@ -11,7 +11,7 @@ cd ruoyi-ui
npm install npm install
# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题 # 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npm.taobao.org npm install --registry=https://registry.npmmirror.com
# 启动服务 # 启动服务
npm run dev npm run dev

@ -7,6 +7,6 @@ echo.
cd %~dp0 cd %~dp0
cd .. cd ..
npm install --registry=https://registry.npm.taobao.org npm install --registry=https://registry.npmmirror.com
pause pause

@ -1,6 +1,6 @@
{ {
"name": "ruoyi", "name": "ruoyi",
"version": "3.4.0", "version": "3.5.0",
"description": "若依管理系统", "description": "若依管理系统",
"author": "若依", "author": "若依",
"license": "MIT", "license": "MIT",
@ -41,13 +41,13 @@
"clipboard": "2.0.8", "clipboard": "2.0.8",
"core-js": "3.19.1", "core-js": "3.19.1",
"echarts": "4.9.0", "echarts": "4.9.0",
"element-ui": "2.15.6", "element-ui": "2.15.8",
"file-saver": "2.0.5", "file-saver": "2.0.5",
"fuse.js": "6.4.3", "fuse.js": "6.4.3",
"highlight.js": "9.18.5", "highlight.js": "9.18.5",
"js-beautify": "1.13.0", "js-beautify": "1.13.0",
"js-cookie": "3.0.1", "js-cookie": "3.0.1",
"jsencrypt": "3.2.1", "jsencrypt": "3.0.0-rc.1",
"nprogress": "0.2.0", "nprogress": "0.2.0",
"quill": "1.3.7", "quill": "1.3.7",
"screenfull": "5.0.2", "screenfull": "5.0.2",

@ -7,6 +7,10 @@
position: relative; position: relative;
} }
.sidebarHide {
margin-left: 0!important;
}
.sidebar-container { .sidebar-container {
-webkit-transition: width .28s; -webkit-transition: width .28s;
transition: width 0.28s; transition: width 0.28s;

@ -30,13 +30,14 @@
<script> <script>
import { constantRoutes } from "@/router"; import { constantRoutes } from "@/router";
//
const hideList = ['/index', '/user/profile'];
export default { export default {
data() { data() {
return { return {
// //
visibleNumber: 5, visibleNumber: 5,
//
isFrist: false,
// index // index
currentIndex: undefined currentIndex: undefined
}; };
@ -71,7 +72,7 @@ export default {
for (var item in router.children) { for (var item in router.children) {
if (router.children[item].parentPath === undefined) { if (router.children[item].parentPath === undefined) {
if(router.path === "/") { if(router.path === "/") {
router.children[item].path = "/redirect/" + router.children[item].path; router.children[item].path = "/" + router.children[item].path;
} else { } else {
if(!this.ishttp(router.children[item].path)) { if(!this.ishttp(router.children[item].path)) {
router.children[item].path = router.path + "/" + router.children[item].path; router.children[item].path = router.path + "/" + router.children[item].path;
@ -87,22 +88,16 @@ export default {
// //
activeMenu() { activeMenu() {
const path = this.$route.path; const path = this.$route.path;
let activePath = this.defaultRouter(); let activePath = path;
if (path.lastIndexOf("/") > 0) { if (path !== undefined && path.lastIndexOf("/") > 0 && hideList.indexOf(path) === -1) {
const tmpPath = path.substring(1, path.length); const tmpPath = path.substring(1, path.length);
activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/")); activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"));
} else if ("/index" == path || "" == path) { this.$store.dispatch('app/toggleSideBarHide', false);
if (!this.isFrist) { } else if(!this.$route.children) {
this.isFrist = true; activePath = path;
} else { this.$store.dispatch('app/toggleSideBarHide', true);
activePath = "index";
}
}
var routes = this.activeRoutes(activePath);
if (routes.length === 0) {
activePath = this.currentIndex || this.defaultRouter()
this.activeRoutes(activePath);
} }
this.activeRoutes(activePath);
return activePath; return activePath;
}, },
}, },
@ -121,29 +116,21 @@ export default {
const width = document.body.getBoundingClientRect().width / 3; const width = document.body.getBoundingClientRect().width / 3;
this.visibleNumber = parseInt(width / 85); this.visibleNumber = parseInt(width / 85);
}, },
//
defaultRouter() {
let router;
Object.keys(this.routers).some((key) => {
if (!this.routers[key].hidden) {
router = this.routers[key].path;
return true;
}
});
return router;
},
// //
handleSelect(key, keyPath) { handleSelect(key, keyPath) {
this.currentIndex = key; this.currentIndex = key;
const route = this.routers.find(item => item.path === key);
if (this.ishttp(key)) { if (this.ishttp(key)) {
// http(s):// // http(s)://
window.open(key, "_blank"); window.open(key, "_blank");
} else if (key.indexOf("/redirect") !== -1) { } else if (!route || !route.children) {
// /redirect //
this.$router.push({ path: key.replace("/redirect", "") }); this.$router.push({ path: key });
this.$store.dispatch('app/toggleSideBarHide', true);
} else { } else {
// //
this.activeRoutes(key); this.activeRoutes(key);
this.$store.dispatch('app/toggleSideBarHide', false);
} }
}, },
// //
@ -159,9 +146,8 @@ export default {
if(routes.length > 0) { if(routes.length > 0) {
this.$store.commit("SET_SIDEBAR_ROUTERS", routes); this.$store.commit("SET_SIDEBAR_ROUTERS", routes);
} }
return routes;
}, },
ishttp(url) { ishttp(url) {
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1 return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
} }
}, },

@ -108,6 +108,7 @@ export default {
value: val value: val
}) })
if (!val) { if (!val) {
this.$store.dispatch('app/toggleSideBarHide', false);
this.$store.commit("SET_SIDEBAR_ROUTERS", this.$store.state.permission.defaultRoutes); this.$store.commit("SET_SIDEBAR_ROUTERS", this.$store.state.permission.defaultRoutes);
} }
} }

@ -21,7 +21,11 @@ export default {
} }
if (title) { if (title) {
vnodes.push(<span slot='title'>{(title)}</span>) if (title.length > 5) {
vnodes.push(<span slot='title' title={(title)}>{(title)}</span>)
} else {
vnodes.push(<span slot='title'>{(title)}</span>)
}
} }
return vnodes return vnodes
} }

@ -1,8 +1,8 @@
<template> <template>
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}"> <div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/> <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
<sidebar class="sidebar-container"/> <sidebar v-if="!sidebar.hide" class="sidebar-container" />
<div :class="{hasTagsView:needTagsView}" class="main-container"> <div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
<div :class="{'fixed-header':fixedHeader}"> <div :class="{'fixed-header':fixedHeader}">
<navbar /> <navbar />
<tags-view v-if="needTagsView" /> <tags-view v-if="needTagsView" />
@ -101,6 +101,10 @@ export default {
width: calc(100% - 54px); width: calc(100% - 54px);
} }
.sidebarHide .fixed-header {
width: 100%;
}
.mobile .fixed-header { .mobile .fixed-header {
width: 100%; width: 100%;
} }

@ -55,10 +55,10 @@ export default {
return store.dispatch('tagsView/delOthersViews', obj || router.currentRoute); return store.dispatch('tagsView/delOthersViews', obj || router.currentRoute);
}, },
// 添加tab页签 // 添加tab页签
openPage(title, url) { openPage(title, url, params) {
var obj = { path: url, meta: { title: title } } var obj = { path: url, meta: { title: title } }
store.dispatch('tagsView/addView', obj); store.dispatch('tagsView/addView', obj);
return router.push(url); return router.push({ path: url, query: params });
}, },
// 修改tab页签 // 修改tab页签
updatePage(obj) { updatePage(obj) {

@ -164,6 +164,12 @@ export const dynamicRoutes = [
} }
] ]
// 防止连续点击多次路由报错
let routerPush = Router.prototype.push;
Router.prototype.push = function push(location) {
return routerPush.call(this, location).catch(err => err)
}
export default new Router({ export default new Router({
mode: 'history', // 去掉url中的# mode: 'history', // 去掉url中的#
scrollBehavior: () => ({ y: 0 }), scrollBehavior: () => ({ y: 0 }),

@ -3,7 +3,8 @@ import Cookies from 'js-cookie'
const state = { const state = {
sidebar: { sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false withoutAnimation: false,
hide: false
}, },
device: 'desktop', device: 'desktop',
size: Cookies.get('size') || 'medium' size: Cookies.get('size') || 'medium'
@ -11,6 +12,9 @@ const state = {
const mutations = { const mutations = {
TOGGLE_SIDEBAR: state => { TOGGLE_SIDEBAR: state => {
if (state.sidebar.hide) {
return false;
}
state.sidebar.opened = !state.sidebar.opened state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false state.sidebar.withoutAnimation = false
if (state.sidebar.opened) { if (state.sidebar.opened) {
@ -30,6 +34,9 @@ const mutations = {
SET_SIZE: (state, size) => { SET_SIZE: (state, size) => {
state.size = size state.size = size
Cookies.set('size', size) Cookies.set('size', size)
},
SET_SIDEBAR_HIDE: (state, status) => {
state.sidebar.hide = status
} }
} }
@ -45,6 +52,9 @@ const actions = {
}, },
setSize({ commit }, size) { setSize({ commit }, size) {
commit('SET_SIZE', size) commit('SET_SIZE', size)
},
toggleSideBarHide({ commit }, status) {
commit('SET_SIDEBAR_HIDE', status)
} }
} }

@ -22,12 +22,7 @@ const permission = {
state.defaultRoutes = constantRoutes.concat(routes) state.defaultRoutes = constantRoutes.concat(routes)
}, },
SET_TOPBAR_ROUTES: (state, routes) => { SET_TOPBAR_ROUTES: (state, routes) => {
// 顶部导航菜单默认添加统计报表栏指向首页 state.topbarRouters = routes
const index = [{
path: 'index',
meta: { title: '统计报表', icon: 'dashboard' }
}]
state.topbarRouters = routes.concat(index);
}, },
SET_SIDEBAR_ROUTERS: (state, routes) => { SET_SIDEBAR_ROUTERS: (state, routes) => {
state.sidebarRouters = routes state.sidebarRouters = routes

@ -57,7 +57,7 @@ const user = {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getInfo().then(res => { getInfo().then(res => {
const user = res.user const user = res.user
const avatar = user.avatar == "" ? require("@/assets/images/profile.jpg") : user.avatar; const avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/profile.jpg") : user.avatar;
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组 if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', res.roles) commit('SET_ROLES', res.roles)
commit('SET_PERMISSIONS', res.permissions) commit('SET_PERMISSIONS', res.permissions)

@ -11,7 +11,7 @@ import DictOptions from './DictOptions'
export default class DictMeta { export default class DictMeta {
constructor(options) { constructor(options) {
this.type = options.type this.type = options.type
this.request = options.request, this.request = options.request
this.responseConverter = options.responseConverter this.responseConverter = options.responseConverter
this.labelField = options.labelField this.labelField = options.labelField
this.valueField = options.valueField this.valueField = options.valueField

@ -41,7 +41,7 @@
<el-col :sm="24" :lg="12" style="padding-left: 20px"> <el-col :sm="24" :lg="12" style="padding-left: 20px">
<h2>若依后台管理框架</h2> <h2>若依后台管理框架</h2>
<p> <p>
一直想做一款后台管理系统看了很多优秀的开源项目但是发现没有合适自己的于是利用空闲休息时间开始自己写一套后台系统如此有了若依管理系统她可以用于所有的Web应用程序如网站管理后台网站会员中心CMSCRMOA等等当然您也可以对她进行深度定制以做出更强系统所有前端后台代码封装过后十分精简易上手出错概率低同时支持移动客户端访问系统会陆续更新一些实用功能 一直想做一款后台管理系统看了很多优秀的开源项目但是发现没有合适自己的于是利用空闲休息时间开始自己写一套后台系统如此有了若依管理系统她可以用于所有的Web应用程序如网站管理后台网站会员中心CMSCRMOA等等当然您也可以对她进行深度定制以做出更强系统所有前端后台代码封装过后十分精简易上手出错概率低同时支持移动客户端访问系统会陆续更新一些实用功能
</p> </p>
<p> <p>
<b>当前版本:</b> <span>v{{ version }}</span> <b>当前版本:</b> <span>v{{ version }}</span>
@ -118,10 +118,10 @@
> >
</p> </p>
<p> <p>
<i class="el-icon-user-solid"></i> QQ群<s>满42799195</s> <i class="el-icon-user-solid"></i> QQ群<s>满42799195</s> <s>满170157040</s>
<s>满170157040</s> <s>满130643120</s> <s>满225920371</s> <s>满201705537</s> <s>满130643120</s> <s>满225920371</s> <s>满201705537</s> <s>满236543183</s>
<a href="https://jq.qq.com/?_wv=1027&k=qdT1Ojpz" target="_blank"> <a href="https://jq.qq.com/?_wv=1027&k=73TMBe12" target="_blank">
236543183</a 213618602</a
> >
</p> </p>
<p> <p>
@ -146,6 +146,43 @@
<span>更新日志</span> <span>更新日志</span>
</div> </div>
<el-collapse accordion> <el-collapse accordion>
<el-collapse-item title="v3.5.0 - 2022-04-11">
<ol>
<li>开启TopNav没有子菜单情况隐藏侧边栏</li>
<li>侧边栏菜单名称过长悬停显示标题</li>
<li>用户访问控制时校验数据权限防止越权</li>
<li>导出Excel时屏蔽公式防止CSV注入风险</li>
<li>组件ImageUpload支持多图同时选择上传</li>
<li>组件FileUpload支持多文件同时选择上传</li>
<li>代码生成树表新增(展开/折叠)</li>
<li>代码生成子表支持日期/字典配置</li>
<li>代码生成编辑修改打开新页签</li>
<li>添加页签openPage支持传递参数</li>
<li>添加清理分页的线程变量方法</li>
<li>修改npm即将过期的注册源地址</li>
<li>用户缓存信息添加部门ancestors祖级列表</li>
<li>升级spring-cloud到最新版2021.0.1</li>
<li>升级spring-boot到最新版本2.6.6</li>
<li>升级spring-boot-admin到最新版2.6.6</li>
<li>升级spring-boot-mybatis到最新版2.2.2</li>
<li>降级jsencrypt版本兼容IE浏览器</li>
<li>修复分页组件请求两次问题</li>
<li>修复表单清除元素位置未垂直居中问题</li>
<li>修复Excel注解prompt/combo同时使用不生效问题</li>
<li>修复导入Excel时字典字段类型为Long转义为空问题</li>
<li>修复登录超时刷新页面跳转登录页面还提示重新登录问题</li>
<li>修复Xss注解字段值为空时的异常问题</li>
<li>优化IP地址获取到多个的问题</li>
<li>优化文件上传兼容Weblogic环境</li>
<li>代码生成同步保留必填/类型选项</li>
<li>优化Excel格式化不同类型的日期对象</li>
<li>优化菜单表关键字导致的插件报错问题</li>
<li>优化Oracle用户头像列为空时不显示问题</li>
<li>优化页面若未匹配到字典标签则返回原字典值</li>
<li>优化修复登录失效后多次请求提示多次弹窗问题</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.4.0 - 2022-01-24"> <el-collapse-item title="v3.4.0 - 2022-01-24">
<ol> <ol>
<li>新增Vue3前端代码生成模板</li> <li>新增Vue3前端代码生成模板</li>
@ -679,7 +716,7 @@ export default {
data() { data() {
return { return {
// //
version: "3.4.0", version: "3.5.0",
}; };
}, },
methods: { methods: {

@ -1,17 +1,16 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="任务名称" prop="jobName"> <el-form-item label="任务名称" prop="jobName">
<el-input <el-input
v-model="queryParams.jobName" v-model="queryParams.jobName"
placeholder="请输入任务名称" placeholder="请输入任务名称"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="任务组名" prop="jobGroup"> <el-form-item label="任务组名" prop="jobGroup">
<el-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" clearable size="small"> <el-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" clearable>
<el-option <el-option
v-for="dict in dict.type.sys_job_group" v-for="dict in dict.type.sys_job_group"
:key="dict.value" :key="dict.value"
@ -21,7 +20,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="任务状态" prop="status"> <el-form-item label="任务状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable size="small"> <el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable>
<el-option <el-option
v-for="dict in dict.type.sys_job_status" v-for="dict in dict.type.sys_job_status"
:key="dict.value" :key="dict.value"
@ -165,7 +164,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="任务分组" prop="jobGroup"> <el-form-item label="任务分组" prop="jobGroup">
<el-select v-model="form.jobGroup" placeholder="请选择"> <el-select v-model="form.jobGroup" placeholder="请选择任务分组">
<el-option <el-option
v-for="dict in dict.type.sys_job_group" v-for="dict in dict.type.sys_job_group"
:key="dict.value" :key="dict.value"

@ -1,12 +1,11 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="任务名称" prop="jobName"> <el-form-item label="任务名称" prop="jobName">
<el-input <el-input
v-model="queryParams.jobName" v-model="queryParams.jobName"
placeholder="请输入任务名称" placeholder="请输入任务名称"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -14,9 +13,8 @@
<el-form-item label="任务组名" prop="jobGroup"> <el-form-item label="任务组名" prop="jobGroup">
<el-select <el-select
v-model="queryParams.jobGroup" v-model="queryParams.jobGroup"
placeholder="请任务组名" placeholder="请选择任务组名"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
@ -32,7 +30,6 @@
v-model="queryParams.status" v-model="queryParams.status"
placeholder="请选择执行状态" placeholder="请选择执行状态"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
@ -46,7 +43,6 @@
<el-form-item label="执行时间"> <el-form-item label="执行时间">
<el-date-picker <el-date-picker
v-model="dateRange" v-model="dateRange"
size="small"
style="width: 240px" style="width: 240px"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
type="daterange" type="daterange"

@ -1,12 +1,11 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
<el-form-item label="登录地址" prop="ipaddr"> <el-form-item label="登录地址" prop="ipaddr">
<el-input <el-input
v-model="queryParams.ipaddr" v-model="queryParams.ipaddr"
placeholder="请输入登录地址" placeholder="请输入登录地址"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
@ -15,7 +14,6 @@
v-model="queryParams.userName" v-model="queryParams.userName"
placeholder="请输入用户名称" placeholder="请输入用户名称"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>

@ -1,12 +1,11 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="参数名称" prop="configName"> <el-form-item label="参数名称" prop="configName">
<el-input <el-input
v-model="queryParams.configName" v-model="queryParams.configName"
placeholder="请输入参数名称" placeholder="请输入参数名称"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -16,13 +15,12 @@
v-model="queryParams.configKey" v-model="queryParams.configKey"
placeholder="请输入参数键名" placeholder="请输入参数键名"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="系统内置" prop="configType"> <el-form-item label="系统内置" prop="configType">
<el-select v-model="queryParams.configType" placeholder="系统内置" clearable size="small"> <el-select v-model="queryParams.configType" placeholder="系统内置" clearable>
<el-option <el-option
v-for="dict in dict.type.sys_yes_no" v-for="dict in dict.type.sys_yes_no"
:key="dict.value" :key="dict.value"
@ -34,7 +32,6 @@
<el-form-item label="创建时间"> <el-form-item label="创建时间">
<el-date-picker <el-date-picker
v-model="dateRange" v-model="dateRange"
size="small"
style="width: 240px" style="width: 240px"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
type="daterange" type="daterange"

@ -1,17 +1,16 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<el-form-item label="部门名称" prop="deptName"> <el-form-item label="部门名称" prop="deptName">
<el-input <el-input
v-model="queryParams.deptName" v-model="queryParams.deptName"
placeholder="请输入部门名称" placeholder="请输入部门名称"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="部门状态" clearable size="small"> <el-select v-model="queryParams.status" placeholder="部门状态" clearable>
<el-option <el-option
v-for="dict in dict.type.sys_normal_disable" v-for="dict in dict.type.sys_normal_disable"
:key="dict.value" :key="dict.value"

@ -1,8 +1,8 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :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">
<el-option <el-option
v-for="item in typeOptions" v-for="item in typeOptions"
:key="item.dictId" :key="item.dictId"
@ -16,12 +16,11 @@
v-model="queryParams.dictLabel" v-model="queryParams.dictLabel"
placeholder="请输入字典标签" placeholder="请输入字典标签"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="数据状态" clearable size="small"> <el-select v-model="queryParams.status" placeholder="数据状态" clearable>
<el-option <el-option
v-for="dict in dict.type.sys_normal_disable" v-for="dict in dict.type.sys_normal_disable"
:key="dict.value" :key="dict.value"
@ -192,7 +191,7 @@
<script> <script>
import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data"; import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data";
import { listType, getType } from "@/api/system/dict/type"; import { optionselect as getDictOptionselect, getType } from "@/api/system/dict/type";
export default { export default {
name: "Data", name: "Data",
@ -288,8 +287,8 @@ export default {
}, },
/** 查询字典类型列表 */ /** 查询字典类型列表 */
getTypeList() { getTypeList() {
listType().then(response => { getDictOptionselect().then(response => {
this.typeOptions = response.rows; this.typeOptions = response.data;
}); });
}, },
/** 查询字典数据列表 */ /** 查询字典数据列表 */

@ -1,12 +1,11 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="字典名称" prop="dictName"> <el-form-item label="字典名称" prop="dictName">
<el-input <el-input
v-model="queryParams.dictName" v-model="queryParams.dictName"
placeholder="请输入字典名称" placeholder="请输入字典名称"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -16,7 +15,6 @@
v-model="queryParams.dictType" v-model="queryParams.dictType"
placeholder="请输入字典类型" placeholder="请输入字典类型"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -26,7 +24,6 @@
v-model="queryParams.status" v-model="queryParams.status"
placeholder="字典状态" placeholder="字典状态"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
@ -40,7 +37,6 @@
<el-form-item label="创建时间"> <el-form-item label="创建时间">
<el-date-picker <el-date-picker
v-model="dateRange" v-model="dateRange"
size="small"
style="width: 240px" style="width: 240px"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
type="daterange" type="daterange"

@ -1,12 +1,11 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="登录地址" prop="ipaddr"> <el-form-item label="登录地址" prop="ipaddr">
<el-input <el-input
v-model="queryParams.ipaddr" v-model="queryParams.ipaddr"
placeholder="请输入登录地址" placeholder="请输入登录地址"
clearable clearable
size="small"
style="width: 240px;" style="width: 240px;"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -16,7 +15,6 @@
v-model="queryParams.userName" v-model="queryParams.userName"
placeholder="请输入用户名称" placeholder="请输入用户名称"
clearable clearable
size="small"
style="width: 240px;" style="width: 240px;"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -26,7 +24,6 @@
v-model="queryParams.status" v-model="queryParams.status"
placeholder="登录状态" placeholder="登录状态"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
@ -40,7 +37,6 @@
<el-form-item label="登录时间"> <el-form-item label="登录时间">
<el-date-picker <el-date-picker
v-model="dateRange" v-model="dateRange"
size="small"
style="width: 240px" style="width: 240px"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
type="daterange" type="daterange"

@ -1,17 +1,16 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<el-form-item label="菜单名称" prop="menuName"> <el-form-item label="菜单名称" prop="menuName">
<el-input <el-input
v-model="queryParams.menuName" v-model="queryParams.menuName"
placeholder="请输入菜单名称" placeholder="请输入菜单名称"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="菜单状态" clearable size="small"> <el-select v-model="queryParams.status" placeholder="菜单状态" clearable>
<el-option <el-option
v-for="dict in dict.type.sys_normal_disable" v-for="dict in dict.type.sys_normal_disable"
:key="dict.value" :key="dict.value"

@ -1,12 +1,11 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="公告标题" prop="noticeTitle"> <el-form-item label="公告标题" prop="noticeTitle">
<el-input <el-input
v-model="queryParams.noticeTitle" v-model="queryParams.noticeTitle"
placeholder="请输入公告标题" placeholder="请输入公告标题"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
@ -15,12 +14,11 @@
v-model="queryParams.createBy" v-model="queryParams.createBy"
placeholder="请输入操作人员" placeholder="请输入操作人员"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="类型" prop="noticeType"> <el-form-item label="类型" prop="noticeType">
<el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable size="small"> <el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable>
<el-option <el-option
v-for="dict in dict.type.sys_notice_type" v-for="dict in dict.type.sys_notice_type"
:key="dict.value" :key="dict.value"
@ -135,7 +133,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="公告类型" prop="noticeType"> <el-form-item label="公告类型" prop="noticeType">
<el-select v-model="form.noticeType" placeholder="请选择"> <el-select v-model="form.noticeType" placeholder="请选择公告类型">
<el-option <el-option
v-for="dict in dict.type.sys_notice_type" v-for="dict in dict.type.sys_notice_type"
:key="dict.value" :key="dict.value"

@ -1,12 +1,11 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="系统模块" prop="title"> <el-form-item label="系统模块" prop="title">
<el-input <el-input
v-model="queryParams.title" v-model="queryParams.title"
placeholder="请输入系统模块" placeholder="请输入系统模块"
clearable clearable
size="small"
style="width: 240px;" style="width: 240px;"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -16,7 +15,6 @@
v-model="queryParams.operName" v-model="queryParams.operName"
placeholder="请输入操作人员" placeholder="请输入操作人员"
clearable clearable
size="small"
style="width: 240px;" style="width: 240px;"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -26,7 +24,6 @@
v-model="queryParams.businessType" v-model="queryParams.businessType"
placeholder="操作类型" placeholder="操作类型"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
@ -42,7 +39,6 @@
v-model="queryParams.status" v-model="queryParams.status"
placeholder="操作状态" placeholder="操作状态"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
@ -56,7 +52,6 @@
<el-form-item label="操作时间"> <el-form-item label="操作时间">
<el-date-picker <el-date-picker
v-model="dateRange" v-model="dateRange"
size="small"
style="width: 240px" style="width: 240px"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
type="daterange" type="daterange"

@ -1,12 +1,11 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="岗位编码" prop="postCode"> <el-form-item label="岗位编码" prop="postCode">
<el-input <el-input
v-model="queryParams.postCode" v-model="queryParams.postCode"
placeholder="请输入岗位编码" placeholder="请输入岗位编码"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
@ -15,12 +14,11 @@
v-model="queryParams.postName" v-model="queryParams.postName"
placeholder="请输入岗位名称" placeholder="请输入岗位名称"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="岗位状态" clearable size="small"> <el-select v-model="queryParams.status" placeholder="岗位状态" clearable>
<el-option <el-option
v-for="dict in dict.type.sys_normal_disable" v-for="dict in dict.type.sys_normal_disable"
:key="dict.value" :key="dict.value"

@ -1,12 +1,11 @@
<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" size="small" :inline="true" v-show="showSearch">
<el-form-item label="用户名称" prop="userName"> <el-form-item label="用户名称" prop="userName">
<el-input <el-input
v-model="queryParams.userName" v-model="queryParams.userName"
placeholder="请输入用户名称" placeholder="请输入用户名称"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -16,7 +15,6 @@
v-model="queryParams.phonenumber" v-model="queryParams.phonenumber"
placeholder="请输入手机号码" placeholder="请输入手机号码"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />

@ -1,12 +1,11 @@
<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" size="small" :inline="true" v-show="showSearch">
<el-form-item label="角色名称" prop="roleName"> <el-form-item label="角色名称" prop="roleName">
<el-input <el-input
v-model="queryParams.roleName" v-model="queryParams.roleName"
placeholder="请输入角色名称" placeholder="请输入角色名称"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -16,7 +15,6 @@
v-model="queryParams.roleKey" v-model="queryParams.roleKey"
placeholder="请输入权限字符" placeholder="请输入权限字符"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -26,7 +24,6 @@
v-model="queryParams.status" v-model="queryParams.status"
placeholder="角色状态" placeholder="角色状态"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
@ -40,7 +37,6 @@
<el-form-item label="创建时间"> <el-form-item label="创建时间">
<el-date-picker <el-date-picker
v-model="dateRange" v-model="dateRange"
size="small"
style="width: 240px" style="width: 240px"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
type="daterange" type="daterange"

@ -1,13 +1,12 @@
<template> <template>
<!-- 授权用户 --> <!-- 授权用户 -->
<el-dialog title="选择用户" :visible.sync="visible" width="800px" top="5vh" append-to-body> <el-dialog title="选择用户" :visible.sync="visible" width="800px" top="5vh" append-to-body>
<el-form :model="queryParams" ref="queryForm" :inline="true"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true">
<el-form-item label="用户名称" prop="userName"> <el-form-item label="用户名称" prop="userName">
<el-input <el-input
v-model="queryParams.userName" v-model="queryParams.userName"
placeholder="请输入用户名称" placeholder="请输入用户名称"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
@ -16,7 +15,6 @@
v-model="queryParams.phonenumber" v-model="queryParams.phonenumber"
placeholder="请输入手机号码" placeholder="请输入手机号码"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>

@ -21,19 +21,19 @@
:filter-node-method="filterNode" :filter-node-method="filterNode"
ref="tree" ref="tree"
default-expand-all default-expand-all
highlight-current
@node-click="handleNodeClick" @node-click="handleNodeClick"
/> />
</div> </div>
</el-col> </el-col>
<!--用户数据--> <!--用户数据-->
<el-col :span="20" :xs="24"> <el-col :span="20" :xs="24">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="用户名称" prop="userName"> <el-form-item label="用户名称" prop="userName">
<el-input <el-input
v-model="queryParams.userName" v-model="queryParams.userName"
placeholder="请输入用户名称" placeholder="请输入用户名称"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -43,7 +43,6 @@
v-model="queryParams.phonenumber" v-model="queryParams.phonenumber"
placeholder="请输入手机号码" placeholder="请输入手机号码"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -53,7 +52,6 @@
v-model="queryParams.status" v-model="queryParams.status"
placeholder="用户状态" placeholder="用户状态"
clearable clearable
size="small"
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
@ -67,7 +65,6 @@
<el-form-item label="创建时间"> <el-form-item label="创建时间">
<el-date-picker <el-date-picker
v-model="dateRange" v-model="dateRange"
size="small"
style="width: 240px" style="width: 240px"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
type="daterange" type="daterange"
@ -248,7 +245,7 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="用户性别"> <el-form-item label="用户性别">
<el-select v-model="form.sex" placeholder="请选择"> <el-select v-model="form.sex" placeholder="请选择性别">
<el-option <el-option
v-for="dict in dict.type.sys_user_sex" v-for="dict in dict.type.sys_user_sex"
:key="dict.value" :key="dict.value"
@ -273,7 +270,7 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="岗位"> <el-form-item label="岗位">
<el-select v-model="form.postIds" multiple placeholder="请选择"> <el-select v-model="form.postIds" multiple placeholder="请选择岗位">
<el-option <el-option
v-for="item in postOptions" v-for="item in postOptions"
:key="item.postId" :key="item.postId"
@ -286,7 +283,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="角色"> <el-form-item label="角色">
<el-select v-model="form.roleIds" multiple placeholder="请选择"> <el-select v-model="form.roleIds" multiple placeholder="请选择角色">
<el-option <el-option
v-for="item in roleOptions" v-for="item in roleOptions"
:key="item.roleId" :key="item.roleId"

@ -1,13 +1,12 @@
<template> <template>
<!-- 导入表 --> <!-- 导入表 -->
<el-dialog title="导入表" :visible.sync="visible" width="800px" top="5vh" append-to-body> <el-dialog title="导入表" :visible.sync="visible" width="800px" top="5vh" append-to-body>
<el-form :model="queryParams" ref="queryForm" :inline="true"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true">
<el-form-item label="表名称" prop="tableName"> <el-form-item label="表名称" prop="tableName">
<el-input <el-input
v-model="queryParams.tableName" v-model="queryParams.tableName"
placeholder="请输入表名称" placeholder="请输入表名称"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
@ -16,7 +15,6 @@
v-model="queryParams.tableComment" v-model="queryParams.tableComment"
placeholder="请输入表描述" placeholder="请输入表描述"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>

@ -1,12 +1,11 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="表名称" prop="tableName"> <el-form-item label="表名称" prop="tableName">
<el-input <el-input
v-model="queryParams.tableName" v-model="queryParams.tableName"
placeholder="请输入表名称" placeholder="请输入表名称"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
@ -15,14 +14,12 @@
v-model="queryParams.tableComment" v-model="queryParams.tableComment"
placeholder="请输入表描述" placeholder="请输入表描述"
clearable clearable
size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="创建时间"> <el-form-item label="创建时间">
<el-date-picker <el-date-picker
v-model="dateRange" v-model="dateRange"
size="small"
style="width: 240px" style="width: 240px"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
type="daterange" type="daterange"
@ -321,7 +318,9 @@ export default {
/** 修改按钮操作 */ /** 修改按钮操作 */
handleEditTable(row) { handleEditTable(row) {
const tableId = row.tableId || this.ids[0]; const tableId = row.tableId || this.ids[0];
this.$router.push({ path: '/tool/gen-edit/index/' + tableId, query: { pageNum: this.queryParams.pageNum } }); const tableName = row.tableName || this.tableNames[0];
const params = { pageNum: this.queryParams.pageNum };
this.$tab.openPage("修改[" + tableName + "]生成配置", '/tool/gen-edit/index/' + tableId, params);
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.4.0</version> <version>3.5.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>3.4.0</version> <version>3.5.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -27,20 +27,21 @@ CREATE TABLE `config_info` (
`effect` varchar(64) DEFAULT NULL, `effect` varchar(64) DEFAULT NULL,
`type` varchar(64) DEFAULT NULL, `type` varchar(64) DEFAULT NULL,
`c_schema` text, `c_schema` text,
`encrypted_data_key` text COMMENT '秘钥',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';
insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_modified, src_user, src_ip, app_name, tenant_id, c_desc, c_use, effect, type, c_schema) values insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_modified, src_user, src_ip, app_name, tenant_id, c_desc, c_use, effect, type, c_schema, encrypted_data_key) values
(1,'application-dev.yml','DEFAULT_GROUP','spring:\n main:\n allow-circular-references: true\n allow-bean-definition-overriding: true\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\n mvc:\n pathmatch:\n matching-strategy: ant_path_matcher\n cloud:\n sentinel:\n filter:\n # sentinel 在 springboot 2.6.x 不兼容问题的处理\n enabled: false\n\n# feign 配置\nfeign:\n sentinel:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n client:\n config:\n default:\n connectTimeout: 10000\n readTimeout: 10000\n compression:\n request:\n enabled: true\n response:\n enabled: true\n\n# 暴露监控端点\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n','e6a8dafc6fcec97f777836bea3ed5028','2020-05-20 12:00:00','2022-01-14 02:20:19','nacos','0:0:0:0:0:0:0:1','','','通用配置','null','null','yaml','null'), (1,'application-dev.yml','DEFAULT_GROUP','spring:\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\n mvc:\n pathmatch:\n matching-strategy: ant_path_matcher\n\n# feign 配置\nfeign:\n sentinel:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n client:\n config:\n default:\n connectTimeout: 10000\n readTimeout: 10000\n compression:\n request:\n enabled: true\n response:\n enabled: true\n\n# 暴露监控端点\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n','aaa73b809cfd4d0058893aa13da57806','2020-05-20 12:00:00','2022-04-24 10:26:34','nacos','0:0:0:0:0:0:0:1','','','通用配置','null','null','yaml',NULL,''),
(2,'ruoyi-gateway-dev.yml','DEFAULT_GROUP','spring:\n redis:\n host: localhost\n port: 6379\n password: \n cloud:\n gateway:\n discovery:\n locator:\n lowerCaseServiceId: true\n enabled: true\n routes:\n # 认证中心\n - id: ruoyi-auth\n uri: lb://ruoyi-auth\n predicates:\n - Path=/auth/**\n filters:\n # 验证码处理\n - CacheRequestFilter\n - ValidateCodeFilter\n - StripPrefix=1\n # 代码生成\n - id: ruoyi-gen\n uri: lb://ruoyi-gen\n predicates:\n - Path=/code/**\n filters:\n - StripPrefix=1\n # 定时任务\n - id: ruoyi-job\n uri: lb://ruoyi-job\n predicates:\n - Path=/schedule/**\n filters:\n - StripPrefix=1\n # 系统模块\n - id: ruoyi-system\n uri: lb://ruoyi-system\n predicates:\n - Path=/system/**\n filters:\n - StripPrefix=1\n # 文件服务\n - id: ruoyi-file\n uri: lb://ruoyi-file\n predicates:\n - Path=/file/**\n filters:\n - StripPrefix=1\n\n# 安全配置\nsecurity:\n # 验证码\n captcha:\n enabled: true\n type: math\n # 防止XSS攻击\n xss:\n enabled: true\n excludeUrls:\n - /system/notice\n # 不校验白名单\n ignore:\n whites:\n - /auth/logout\n - /auth/login\n - /auth/register\n - /*/v2/api-docs\n - /csrf\n','2f5a6b5a4ccf20b5801c5cf842456ec6','2020-05-14 14:17:55','2021-07-30 09:07:14',NULL,'0:0:0:0:0:0:0:1','','','网关模块','null','null','yaml','null'), (2,'ruoyi-gateway-dev.yml','DEFAULT_GROUP','spring:\n redis:\n host: localhost\n port: 6379\n password: \n cloud:\n gateway:\n discovery:\n locator:\n lowerCaseServiceId: true\n enabled: true\n routes:\n # 认证中心\n - id: ruoyi-auth\n uri: lb://ruoyi-auth\n predicates:\n - Path=/auth/**\n filters:\n # 验证码处理\n - CacheRequestFilter\n - ValidateCodeFilter\n - StripPrefix=1\n # 代码生成\n - id: ruoyi-gen\n uri: lb://ruoyi-gen\n predicates:\n - Path=/code/**\n filters:\n - StripPrefix=1\n # 定时任务\n - id: ruoyi-job\n uri: lb://ruoyi-job\n predicates:\n - Path=/schedule/**\n filters:\n - StripPrefix=1\n # 系统模块\n - id: ruoyi-system\n uri: lb://ruoyi-system\n predicates:\n - Path=/system/**\n filters:\n - StripPrefix=1\n # 文件服务\n - id: ruoyi-file\n uri: lb://ruoyi-file\n predicates:\n - Path=/file/**\n filters:\n - StripPrefix=1\n\n# 安全配置\nsecurity:\n # 验证码\n captcha:\n enabled: true\n type: math\n # 防止XSS攻击\n xss:\n enabled: true\n excludeUrls:\n - /system/notice\n # 不校验白名单\n ignore:\n whites:\n - /auth/logout\n - /auth/login\n - /auth/register\n - /*/v2/api-docs\n - /csrf\n','2f5a6b5a4ccf20b5801c5cf842456ec6','2020-05-14 14:17:55','2021-07-30 09:07:14',NULL,'0:0:0:0:0:0:0:1','','','网关模块','null','null','yaml',NULL,''),
(3,'ruoyi-auth-dev.yml','DEFAULT_GROUP','spring: \r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n','b7354e1eb62c2d846d44a796d9ec6930','2020-11-20 00:00:00','2021-02-28 21:06:58',NULL,'0:0:0:0:0:0:0:1','','','认证中心','null','null','yaml','null'), (3,'ruoyi-auth-dev.yml','DEFAULT_GROUP','spring: \r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n','b7354e1eb62c2d846d44a796d9ec6930','2020-11-20 00:00:00','2021-02-28 21:06:58',NULL,'0:0:0:0:0:0:0:1','','','认证中心','null','null','yaml',NULL,''),
(4,'ruoyi-monitor-dev.yml','DEFAULT_GROUP','# spring\r\nspring: \r\n security:\r\n user:\r\n name: ruoyi\r\n password: 123456\r\n boot:\r\n admin:\r\n ui:\r\n title: 若依服务状态监控\r\n','d8997d0707a2fd5d9fc4e8409da38129','2020-11-20 00:00:00','2020-12-21 16:28:07',NULL,'0:0:0:0:0:0:0:1','','','监控中心','null','null','yaml','null'), (4,'ruoyi-monitor-dev.yml','DEFAULT_GROUP','# spring\r\nspring: \r\n security:\r\n user:\r\n name: ruoyi\r\n password: 123456\r\n boot:\r\n admin:\r\n ui:\r\n title: 若依服务状态监控\r\n','d8997d0707a2fd5d9fc4e8409da38129','2020-11-20 00:00:00','2020-12-21 16:28:07',NULL,'0:0:0:0:0:0:0:1','','','监控中心','null','null','yaml',NULL,''),
(5,'ruoyi-system-dev.yml','DEFAULT_GROUP','# spring配置\r\nspring: \r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n datasource:\r\n druid:\r\n stat-view-servlet:\r\n enabled: true\r\n loginUsername: admin\r\n loginPassword: 123456\r\n dynamic:\r\n druid:\r\n initial-size: 5\r\n min-idle: 5\r\n maxActive: 20\r\n maxWait: 60000\r\n timeBetweenEvictionRunsMillis: 60000\r\n minEvictableIdleTimeMillis: 300000\r\n validationQuery: SELECT 1 FROM DUAL\r\n testWhileIdle: true\r\n testOnBorrow: false\r\n testOnReturn: false\r\n poolPreparedStatements: true\r\n maxPoolPreparedStatementPerConnectionSize: 20\r\n filters: stat,slf4j\r\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\r\n datasource:\r\n # 主库数据源\r\n master:\r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: root\r\n password: password\r\n # 从库数据源\r\n # slave:\r\n # username: \r\n # password: \r\n # url: \r\n # driver-class-name: \r\n # seata: true # 开启seata代理开启后默认每个数据源都代理如果某个不需要代理可单独关闭\r\n\r\n# seata配置\r\nseata:\r\n # 默认关闭如需启用spring.datasource.dynami.seata需要同时开启\r\n enabled: false\r\n # Seata 应用编号,默认为 ${spring.application.name}\r\n application-id: ${spring.application.name}\r\n # Seata 事务组编号,用于 TC 集群名\r\n tx-service-group: ${spring.application.name}-group\r\n # 关闭自动代理\r\n enable-auto-data-source-proxy: false\r\n # 服务配置项\r\n service:\r\n # 虚拟组和分组的映射\r\n vgroup-mapping:\r\n ruoyi-system-group: default\r\n config:\r\n type: nacos\r\n nacos:\r\n serverAddr: 127.0.0.1:8848\r\n group: SEATA_GROUP\r\n namespace:\r\n registry:\r\n type: nacos\r\n nacos:\r\n application: seata-server\r\n server-addr: 127.0.0.1:8848\r\n namespace:\r\n\r\n# mybatis配置\r\nmybatis:\r\n # 搜索指定包别名\r\n typeAliasesPackage: com.ruoyi.system\r\n # 配置mapper的扫描找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger配置\r\nswagger:\r\n title: 系统模块接口文档\r\n license: Powered By ruoyi\r\n licenseUrl: https://ruoyi.vip','ac8913dee679e65bb7d482df5f267d4e','2020-11-20 00:00:00','2021-01-27 10:42:25',NULL,'0:0:0:0:0:0:0:1','','','系统模块','null','null','yaml','null'), (5,'ruoyi-system-dev.yml','DEFAULT_GROUP','# spring配置\r\nspring: \r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n datasource:\r\n druid:\r\n stat-view-servlet:\r\n enabled: true\r\n loginUsername: admin\r\n loginPassword: 123456\r\n dynamic:\r\n druid:\r\n initial-size: 5\r\n min-idle: 5\r\n maxActive: 20\r\n maxWait: 60000\r\n timeBetweenEvictionRunsMillis: 60000\r\n minEvictableIdleTimeMillis: 300000\r\n validationQuery: SELECT 1 FROM DUAL\r\n testWhileIdle: true\r\n testOnBorrow: false\r\n testOnReturn: false\r\n poolPreparedStatements: true\r\n maxPoolPreparedStatementPerConnectionSize: 20\r\n filters: stat,slf4j\r\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\r\n datasource:\r\n # 主库数据源\r\n master:\r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: root\r\n password: password\r\n # 从库数据源\r\n # slave:\r\n # username: \r\n # password: \r\n # url: \r\n # driver-class-name: \r\n # seata: true # 开启seata代理开启后默认每个数据源都代理如果某个不需要代理可单独关闭\r\n\r\n# seata配置\r\nseata:\r\n # 默认关闭如需启用spring.datasource.dynami.seata需要同时开启\r\n enabled: false\r\n # Seata 应用编号,默认为 ${spring.application.name}\r\n application-id: ${spring.application.name}\r\n # Seata 事务组编号,用于 TC 集群名\r\n tx-service-group: ${spring.application.name}-group\r\n # 关闭自动代理\r\n enable-auto-data-source-proxy: false\r\n # 服务配置项\r\n service:\r\n # 虚拟组和分组的映射\r\n vgroup-mapping:\r\n ruoyi-system-group: default\r\n config:\r\n type: nacos\r\n nacos:\r\n serverAddr: 127.0.0.1:8848\r\n group: SEATA_GROUP\r\n namespace:\r\n registry:\r\n type: nacos\r\n nacos:\r\n application: seata-server\r\n server-addr: 127.0.0.1:8848\r\n namespace:\r\n\r\n# mybatis配置\r\nmybatis:\r\n # 搜索指定包别名\r\n typeAliasesPackage: com.ruoyi.system\r\n # 配置mapper的扫描找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger配置\r\nswagger:\r\n title: 系统模块接口文档\r\n license: Powered By ruoyi\r\n licenseUrl: https://ruoyi.vip','ac8913dee679e65bb7d482df5f267d4e','2020-11-20 00:00:00','2021-01-27 10:42:25',NULL,'0:0:0:0:0:0:0:1','','','系统模块','null','null','yaml',NULL,''),
(6,'ruoyi-gen-dev.yml','DEFAULT_GROUP','# spring配置\r\nspring: \r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n datasource: \r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: root\r\n password: password\r\n\r\n# mybatis配置\r\nmybatis:\r\n # 搜索指定包别名\r\n typeAliasesPackage: com.ruoyi.gen.domain\r\n # 配置mapper的扫描找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger配置\r\nswagger:\r\n title: 代码生成接口文档\r\n license: Powered By ruoyi\r\n licenseUrl: https://ruoyi.vip\r\n\r\n# 代码生成\r\ngen: \r\n # 作者\r\n author: ruoyi\r\n # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool\r\n packageName: com.ruoyi.system\r\n # 自动去除表前缀默认是false\r\n autoRemovePre: false\r\n # 表前缀(生成类名不会包含表前缀,多个用逗号分隔)\r\n tablePrefix: sys_\r\n','8c79f64a4cca9b821a03dc8b27a2d8eb','2020-11-20 00:00:00','2021-01-26 10:36:45',NULL,'0:0:0:0:0:0:0:1','','','代码生成','null','null','yaml','null'), (6,'ruoyi-gen-dev.yml','DEFAULT_GROUP','# spring配置\r\nspring: \r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n datasource: \r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: root\r\n password: password\r\n\r\n# mybatis配置\r\nmybatis:\r\n # 搜索指定包别名\r\n typeAliasesPackage: com.ruoyi.gen.domain\r\n # 配置mapper的扫描找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger配置\r\nswagger:\r\n title: 代码生成接口文档\r\n license: Powered By ruoyi\r\n licenseUrl: https://ruoyi.vip\r\n\r\n# 代码生成\r\ngen: \r\n # 作者\r\n author: ruoyi\r\n # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool\r\n packageName: com.ruoyi.system\r\n # 自动去除表前缀默认是false\r\n autoRemovePre: false\r\n # 表前缀(生成类名不会包含表前缀,多个用逗号分隔)\r\n tablePrefix: sys_\r\n','8c79f64a4cca9b821a03dc8b27a2d8eb','2020-11-20 00:00:00','2021-01-26 10:36:45',NULL,'0:0:0:0:0:0:0:1','','','代码生成','null','null','yaml',NULL,''),
(7,'ruoyi-job-dev.yml','DEFAULT_GROUP','# spring配置\r\nspring: \r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n datasource:\r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: root\r\n password: password\r\n\r\n# mybatis配置\r\nmybatis:\r\n # 搜索指定包别名\r\n typeAliasesPackage: com.ruoyi.job.domain\r\n # 配置mapper的扫描找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger配置\r\nswagger:\r\n title: 定时任务接口文档\r\n license: Powered By ruoyi\r\n licenseUrl: https://ruoyi.vip\r\n','d6dfade9a2c93c463ae857cd503cb172','2020-11-20 00:00:00','2021-01-26 10:36:04',NULL,'0:0:0:0:0:0:0:1','','','定时任务','null','null','yaml','null'), (7,'ruoyi-job-dev.yml','DEFAULT_GROUP','# spring配置\r\nspring: \r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n datasource:\r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: root\r\n password: password\r\n\r\n# mybatis配置\r\nmybatis:\r\n # 搜索指定包别名\r\n typeAliasesPackage: com.ruoyi.job.domain\r\n # 配置mapper的扫描找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger配置\r\nswagger:\r\n title: 定时任务接口文档\r\n license: Powered By ruoyi\r\n licenseUrl: https://ruoyi.vip\r\n','d6dfade9a2c93c463ae857cd503cb172','2020-11-20 00:00:00','2021-01-26 10:36:04',NULL,'0:0:0:0:0:0:0:1','','','定时任务','null','null','yaml',NULL,''),
(8,'ruoyi-file-dev.yml','DEFAULT_GROUP','# 本地文件上传 \r\nfile:\r\n domain: http://127.0.0.1:9300\r\n path: D:/ruoyi/uploadPath\r\n prefix: /statics\r\n\r\n# FastDFS配置\r\nfdfs:\r\n domain: http://8.129.231.12\r\n soTimeout: 3000\r\n connectTimeout: 2000\r\n trackerList: 8.129.231.12:22122\r\n\r\n# Minio配置\r\nminio:\r\n url: http://8.129.231.12:9000\r\n accessKey: minioadmin\r\n secretKey: minioadmin\r\n bucketName: test','5382b93f3d8059d6068c0501fdd41195','2020-11-20 00:00:00','2020-12-21 21:01:59',NULL,'0:0:0:0:0:0:0:1','','','文件服务','null','null','yaml','null'), (8,'ruoyi-file-dev.yml','DEFAULT_GROUP','# 本地文件上传 \r\nfile:\r\n domain: http://127.0.0.1:9300\r\n path: D:/ruoyi/uploadPath\r\n prefix: /statics\r\n\r\n# FastDFS配置\r\nfdfs:\r\n domain: http://8.129.231.12\r\n soTimeout: 3000\r\n connectTimeout: 2000\r\n trackerList: 8.129.231.12:22122\r\n\r\n# Minio配置\r\nminio:\r\n url: http://8.129.231.12:9000\r\n accessKey: minioadmin\r\n secretKey: minioadmin\r\n bucketName: test','5382b93f3d8059d6068c0501fdd41195','2020-11-20 00:00:00','2020-12-21 21:01:59',NULL,'0:0:0:0:0:0:0:1','','','文件服务','null','null','yaml',NULL,''),
(9,'sentinel-ruoyi-gateway','DEFAULT_GROUP','[\r\n {\r\n \"resource\": \"ruoyi-auth\",\r\n \"count\": 500,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-system\",\r\n \"count\": 1000,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-gen\",\r\n \"count\": 200,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-job\",\r\n \"count\": 300,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n }\r\n]','9f3a3069261598f74220bc47958ec252','2020-11-20 00:00:00','2020-11-20 00:00:00',NULL,'0:0:0:0:0:0:0:1','','','限流策略','null','null','json','null'); (9,'sentinel-ruoyi-gateway','DEFAULT_GROUP','[\r\n {\r\n \"resource\": \"ruoyi-auth\",\r\n \"count\": 500,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-system\",\r\n \"count\": 1000,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-gen\",\r\n \"count\": 200,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-job\",\r\n \"count\": 300,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n }\r\n]','9f3a3069261598f74220bc47958ec252','2020-11-20 00:00:00','2020-11-20 00:00:00',NULL,'0:0:0:0:0:0:0:1','','','限流策略','null','null','json',NULL,'');
/******************************************/ /******************************************/
@ -76,6 +77,7 @@ CREATE TABLE `config_info_beta` (
`src_user` text COMMENT 'source user', `src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip', `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
`encrypted_data_key` text COMMENT '秘钥',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';
@ -151,6 +153,7 @@ CREATE TABLE `his_config_info` (
`src_ip` varchar(50) DEFAULT NULL, `src_ip` varchar(50) DEFAULT NULL,
`op_type` char(10) DEFAULT NULL, `op_type` char(10) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
`encrypted_data_key` text COMMENT '秘钥',
PRIMARY KEY (`nid`), PRIMARY KEY (`nid`),
KEY `idx_gmt_create` (`gmt_create`), KEY `idx_gmt_create` (`gmt_create`),
KEY `idx_gmt_modified` (`gmt_modified`), KEY `idx_gmt_modified` (`gmt_modified`),
Loading…
Cancel
Save