Merge remote-tracking branch 'ruoyi/master'
# Conflicts: # README.md # ruoyi-ui/package.json # ruoyi-ui/src/assets/styles/index.scss # ruoyi-ui/src/utils/generator/js.js # ruoyi-ui/src/views/index.vue # ruoyi-ui/vue.config.js
This commit is contained in:
15
pom.xml
15
pom.xml
@@ -6,14 +6,14 @@
|
||||
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>3.8.5</version>
|
||||
<version>3.8.6</version>
|
||||
|
||||
<name>ruoyi</name>
|
||||
<url>http://www.ruoyi.vip</url>
|
||||
<description>若依管理系统</description>
|
||||
|
||||
<properties>
|
||||
<ruoyi.version>3.8.5</ruoyi.version>
|
||||
<ruoyi.version>3.8.6</ruoyi.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
@@ -23,8 +23,8 @@
|
||||
<swagger.version>3.0.0</swagger.version>
|
||||
<kaptcha.version>2.3.3</kaptcha.version>
|
||||
<pagehelper.boot.version>1.4.6</pagehelper.boot.version>
|
||||
<fastjson.version>2.0.25</fastjson.version>
|
||||
<oshi.version>6.4.0</oshi.version>
|
||||
<fastjson.version>2.0.34</fastjson.version>
|
||||
<oshi.version>6.4.3</oshi.version>
|
||||
<commons.io.version>2.11.0</commons.io.version>
|
||||
<commons.collections.version>3.2.2</commons.collections.version>
|
||||
<poi.version>4.1.2</poi.version>
|
||||
@@ -41,7 +41,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>2.5.14</version>
|
||||
<version>2.5.15</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -207,11 +207,6 @@
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
||||
<dependencies>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.5</version>
|
||||
<version>3.8.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -3,7 +3,7 @@ ruoyi:
|
||||
# 名称
|
||||
name: RuoYi
|
||||
# 版本
|
||||
version: 3.8.5
|
||||
version: 3.8.6
|
||||
# 版权年份
|
||||
copyrightYear: 2023
|
||||
# 实例演示开关
|
||||
@@ -12,7 +12,7 @@ ruoyi:
|
||||
profile: D:/ruoyi/uploadPath
|
||||
# 获取ip地址开关
|
||||
addressEnabled: false
|
||||
# 验证码类型 math 数组计算 char 字符验证
|
||||
# 验证码类型 math 数字计算 char 字符验证
|
||||
captchaType: math
|
||||
|
||||
# 开发环境配置
|
||||
@@ -53,15 +53,15 @@ spring:
|
||||
messages:
|
||||
# 国际化资源文件路径
|
||||
basename: i18n/messages
|
||||
profiles:
|
||||
profiles:
|
||||
active: druid
|
||||
# 文件上传
|
||||
servlet:
|
||||
multipart:
|
||||
# 单个文件大小
|
||||
max-file-size: 10MB
|
||||
# 设置总上传的文件大小
|
||||
max-request-size: 20MB
|
||||
multipart:
|
||||
# 单个文件大小
|
||||
max-file-size: 10MB
|
||||
# 设置总上传的文件大小
|
||||
max-request-size: 20MB
|
||||
# 服务模块
|
||||
devtools:
|
||||
restart:
|
||||
@@ -76,7 +76,7 @@ spring:
|
||||
# 数据库索引
|
||||
database: 0
|
||||
# 密码
|
||||
password:
|
||||
password:
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
@@ -92,27 +92,27 @@ spring:
|
||||
|
||||
# token配置
|
||||
token:
|
||||
# 令牌自定义标识
|
||||
header: Authorization
|
||||
# 令牌密钥
|
||||
secret: abcdefghijklmnopqrstuvwxyz
|
||||
# 令牌有效期(默认30分钟)
|
||||
expireTime: 30
|
||||
|
||||
# 令牌自定义标识
|
||||
header: Authorization
|
||||
# 令牌密钥
|
||||
secret: abcdefghijklmnopqrstuvwxyz
|
||||
# 令牌有效期(默认30分钟)
|
||||
expireTime: 30
|
||||
|
||||
# MyBatis配置
|
||||
mybatis:
|
||||
# 搜索指定包别名
|
||||
typeAliasesPackage: com.ruoyi.**.domain
|
||||
# 配置mapper的扫描,找到所有的mapper.xml映射文件
|
||||
mapperLocations: classpath*:mapper/**/*Mapper.xml
|
||||
# 加载全局的配置文件
|
||||
configLocation: classpath:mybatis/mybatis-config.xml
|
||||
# 搜索指定包别名
|
||||
typeAliasesPackage: com.ruoyi.**.domain
|
||||
# 配置mapper的扫描,找到所有的mapper.xml映射文件
|
||||
mapperLocations: classpath*:mapper/**/*Mapper.xml
|
||||
# 加载全局的配置文件
|
||||
configLocation: classpath:mybatis/mybatis-config.xml
|
||||
|
||||
# PageHelper分页插件
|
||||
pagehelper:
|
||||
pagehelper:
|
||||
helperDialect: mysql
|
||||
supportMethodsArguments: true
|
||||
params: count=countSql
|
||||
params: count=countSql
|
||||
|
||||
# Swagger配置
|
||||
swagger:
|
||||
@@ -122,7 +122,7 @@ swagger:
|
||||
pathMapping: /dev-api
|
||||
|
||||
# 防止XSS攻击
|
||||
xss:
|
||||
xss:
|
||||
# 过滤开关
|
||||
enabled: true
|
||||
# 排除链接(多个用逗号分隔)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.5</version>
|
||||
<version>3.8.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -59,12 +59,12 @@ public @interface Excel
|
||||
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
|
||||
|
||||
/**
|
||||
* 导出时在excel中每个列的高度 单位为字符
|
||||
* 导出时在excel中每个列的高度
|
||||
*/
|
||||
public double height() default 14;
|
||||
|
||||
/**
|
||||
* 导出时在excel中每个列的宽 单位为字符
|
||||
* 导出时在excel中每个列的宽度
|
||||
*/
|
||||
public double width() default 16;
|
||||
|
||||
@@ -114,7 +114,7 @@ public @interface Excel
|
||||
public ColumnType cellType() default ColumnType.STRING;
|
||||
|
||||
/**
|
||||
* 导出列头背景色
|
||||
* 导出列头背景颜色
|
||||
*/
|
||||
public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
|
||||
|
||||
@@ -124,7 +124,7 @@ public @interface Excel
|
||||
public IndexedColors headerColor() default IndexedColors.WHITE;
|
||||
|
||||
/**
|
||||
* 导出单元格背景色
|
||||
* 导出单元格背景颜色
|
||||
*/
|
||||
public IndexedColors backgroundColor() default IndexedColors.WHITE;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ruoyi.common.core.domain;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
@@ -169,6 +170,36 @@ public class AjaxResult extends HashMap<String, Object>
|
||||
return new AjaxResult(code, msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为成功消息
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean isSuccess()
|
||||
{
|
||||
return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为警告消息
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean isWarn()
|
||||
{
|
||||
return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为错误消息
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean isError()
|
||||
{
|
||||
return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
|
||||
}
|
||||
|
||||
/**
|
||||
* 方便链式调用
|
||||
*
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.ruoyi.common.core.domain.model;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 登录用户身份权限
|
||||
@@ -71,6 +71,24 @@ public class LoginUser implements UserDetails
|
||||
*/
|
||||
private SysUser user;
|
||||
|
||||
public LoginUser()
|
||||
{
|
||||
}
|
||||
|
||||
public LoginUser(SysUser user, Set<String> permissions)
|
||||
{
|
||||
this.user = user;
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions)
|
||||
{
|
||||
this.userId = userId;
|
||||
this.deptId = deptId;
|
||||
this.user = user;
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public Long getUserId()
|
||||
{
|
||||
return userId;
|
||||
@@ -101,24 +119,6 @@ public class LoginUser implements UserDetails
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public LoginUser()
|
||||
{
|
||||
}
|
||||
|
||||
public LoginUser(SysUser user, Set<String> permissions)
|
||||
{
|
||||
this.user = user;
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions)
|
||||
{
|
||||
this.userId = userId;
|
||||
this.deptId = deptId;
|
||||
this.user = user;
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
@Override
|
||||
public String getPassword()
|
||||
|
||||
@@ -147,7 +147,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
|
||||
/**
|
||||
* 计算时间差
|
||||
*
|
||||
* @param endTime 最后时间
|
||||
* @param endDate 最后时间
|
||||
* @param startTime 开始时间
|
||||
* @return 时间差(天/小时/分钟)
|
||||
*/
|
||||
|
||||
@@ -325,9 +325,9 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断给定的set列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
|
||||
* 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
|
||||
*
|
||||
* @param set 给定的集合
|
||||
* @param collection 给定的集合
|
||||
* @param array 给定的数组
|
||||
* @return boolean 结果
|
||||
*/
|
||||
|
||||
@@ -98,6 +98,11 @@ public class ExcelUtil<T>
|
||||
|
||||
public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
|
||||
|
||||
/**
|
||||
* 用于dictType属性数据存储,避免重复查缓存
|
||||
*/
|
||||
public Map<String, String> sysDictMap = new HashMap<String, String>();
|
||||
|
||||
/**
|
||||
* Excel sheet最大行数,默认65536
|
||||
*/
|
||||
@@ -1034,7 +1039,12 @@ public class ExcelUtil<T>
|
||||
}
|
||||
else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value))
|
||||
{
|
||||
cell.setCellValue(convertDictByExp(Convert.toStr(value), dictType, separator));
|
||||
if (!sysDictMap.containsKey(dictType + value))
|
||||
{
|
||||
String lable = convertDictByExp(Convert.toStr(value), dictType, separator);
|
||||
sysDictMap.put(dictType + value, lable);
|
||||
}
|
||||
cell.setCellValue(sysDictMap.get(dictType + value));
|
||||
}
|
||||
else if (value instanceof BigDecimal && -1 != attr.scale())
|
||||
{
|
||||
|
||||
@@ -20,6 +20,11 @@ public class SqlUtil
|
||||
*/
|
||||
public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
|
||||
|
||||
/**
|
||||
* 限制orderBy最大长度
|
||||
*/
|
||||
private static final int ORDER_BY_MAX_LENGTH = 500;
|
||||
|
||||
/**
|
||||
* 检查字符,防止注入绕过
|
||||
*/
|
||||
@@ -29,6 +34,10 @@ public class SqlUtil
|
||||
{
|
||||
throw new UtilException("参数不符合规范,不能进行查询");
|
||||
}
|
||||
if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH)
|
||||
{
|
||||
throw new UtilException("参数已超过最大限制,不能进行查询");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的本地线程伪随机数生成器生成该 UUID。
|
||||
* 获取类型 4(伪随机生成的)UUID 的静态工厂。
|
||||
*
|
||||
* @return 随机生成的 {@code UUID}
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.5</version>
|
||||
<version>3.8.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<artifactId>kaptcha</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
|
||||
@@ -14,7 +14,7 @@ public class DynamicDataSourceContextHolder
|
||||
|
||||
/**
|
||||
* 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
|
||||
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
|
||||
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
|
||||
*/
|
||||
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
|
||||
|
||||
|
||||
@@ -7,8 +7,10 @@ import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingPathVariableException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.exception.DemoModeException;
|
||||
@@ -59,6 +61,28 @@ public class GlobalExceptionHandler
|
||||
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求路径中缺少必需的路径变量
|
||||
*/
|
||||
@ExceptionHandler(MissingPathVariableException.class)
|
||||
public AjaxResult handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e);
|
||||
return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求参数类型不匹配
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
||||
public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e);
|
||||
return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), e.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截未知的运行时异常
|
||||
*/
|
||||
|
||||
@@ -62,7 +62,7 @@ public class PermissionService
|
||||
/**
|
||||
* 验证用户是否具有以下任意一个权限
|
||||
*
|
||||
* @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
|
||||
* @param permissions 以 PERMISSION_DELIMETER 为分隔符的权限列表
|
||||
* @return 用户是否具有以下任意一个权限
|
||||
*/
|
||||
public boolean hasAnyPermi(String permissions)
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.system.service.ISysMenuService;
|
||||
@@ -62,7 +63,7 @@ public class SysPermissionService
|
||||
else
|
||||
{
|
||||
List<SysRole> roles = user.getRoles();
|
||||
if (!roles.isEmpty() && roles.size() > 1)
|
||||
if (!CollectionUtils.isEmpty(roles))
|
||||
{
|
||||
// 多角色设置permissions属性,以便数据权限匹配权限
|
||||
for (SysRole role : roles)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.5</version>
|
||||
<version>3.8.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# 代码生成
|
||||
gen:
|
||||
gen:
|
||||
# 作者
|
||||
author: ruoyi
|
||||
# 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.generator.mapper.GenTableColumnMapper">
|
||||
|
||||
|
||||
<resultMap type="GenTableColumn" id="GenTableColumnResult">
|
||||
<id property="columnId" column="column_id" />
|
||||
<result property="tableId" column="table_id" />
|
||||
@@ -28,23 +28,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
</resultMap>
|
||||
|
||||
|
||||
<sql id="selectGenTableColumnVo">
|
||||
select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column
|
||||
</sql>
|
||||
|
||||
|
||||
<select id="selectGenTableColumnListByTableId" parameterType="Long" resultMap="GenTableColumnResult">
|
||||
<include refid="selectGenTableColumnVo"/>
|
||||
where table_id = #{tableId}
|
||||
order by sort
|
||||
</select>
|
||||
|
||||
|
||||
<select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult">
|
||||
select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type
|
||||
from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})
|
||||
order by ordinal_position
|
||||
</select>
|
||||
|
||||
|
||||
<insert id="insertGenTableColumn" parameterType="GenTableColumn" useGeneratedKeys="true" keyProperty="columnId">
|
||||
insert into gen_table_column (
|
||||
<if test="tableId != null and tableId != ''">table_id,</if>
|
||||
@@ -88,7 +88,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
sysdate()
|
||||
)
|
||||
</insert>
|
||||
|
||||
|
||||
<update id="updateGenTableColumn" parameterType="GenTableColumn">
|
||||
update gen_table_column
|
||||
<set>
|
||||
@@ -111,14 +111,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</update>
|
||||
|
||||
<delete id="deleteGenTableColumnByIds" parameterType="Long">
|
||||
delete from gen_table_column where table_id in
|
||||
delete from gen_table_column where table_id in
|
||||
<foreach collection="array" item="tableId" open="(" separator="," close=")">
|
||||
#{tableId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
|
||||
<delete id="deleteGenTableColumns">
|
||||
delete from gen_table_column where column_id in
|
||||
delete from gen_table_column where column_id in
|
||||
<foreach collection="list" item="item" open="(" separator="," close=")">
|
||||
#{item.columnId}
|
||||
</foreach>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.5</version>
|
||||
<version>3.8.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public class JobInvokeUtil
|
||||
}
|
||||
else
|
||||
{
|
||||
Object bean = Class.forName(beanName).newInstance();
|
||||
Object bean = Class.forName(beanName).getDeclaredConstructor().newInstance();
|
||||
invokeMethod(bean, methodName, methodParams);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.5</version>
|
||||
<version>3.8.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -501,17 +501,18 @@ public class SysUserServiceImpl implements ISysUserService
|
||||
BeanValidators.validateWithException(validator, user);
|
||||
user.setPassword(SecurityUtils.encryptPassword(password));
|
||||
user.setCreateBy(operName);
|
||||
this.insertUser(user);
|
||||
userMapper.insertUser(user);
|
||||
successNum++;
|
||||
successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 导入成功");
|
||||
}
|
||||
else if (isUpdateSupport)
|
||||
{
|
||||
BeanValidators.validateWithException(validator, user);
|
||||
checkUserAllowed(user);
|
||||
checkUserDataScope(user.getUserId());
|
||||
checkUserAllowed(u);
|
||||
checkUserDataScope(u.getUserId());
|
||||
user.setUserId(u.getUserId());
|
||||
user.setUpdateBy(operName);
|
||||
this.updateUser(user);
|
||||
userMapper.updateUser(user);
|
||||
successNum++;
|
||||
successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 更新成功");
|
||||
}
|
||||
|
||||
BIN
ruoyi-ui/src/assets/images/pay.png
Normal file
BIN
ruoyi-ui/src/assets/images/pay.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 137 KiB |
@@ -1,7 +1,7 @@
|
||||
#app {
|
||||
|
||||
.main-container {
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
transition: margin-left .28s;
|
||||
margin-left: $base-sidebar-width;
|
||||
position: relative;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
:key="item.value"
|
||||
:index="index"
|
||||
:class="item.raw.cssClass"
|
||||
>{{ item.label }}</span
|
||||
>{{ item.label + " " }}</span
|
||||
>
|
||||
<el-tag
|
||||
v-else
|
||||
@@ -17,10 +17,13 @@
|
||||
:type="item.raw.listClass == 'primary' ? '' : item.raw.listClass"
|
||||
:class="item.raw.cssClass"
|
||||
>
|
||||
{{ item.label }}
|
||||
{{ item.label + " " }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="unmatch && showValue">
|
||||
{{ unmatchArray | handleArray }}
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -33,20 +36,57 @@ export default {
|
||||
default: null,
|
||||
},
|
||||
value: [Number, String, Array],
|
||||
// 当未找到匹配的数据时,显示value
|
||||
showValue: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
unmatchArray: [], // 记录未匹配的项
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
values() {
|
||||
if (this.value !== null && typeof this.value !== 'undefined') {
|
||||
if (this.value !== null && typeof this.value !== "undefined") {
|
||||
return Array.isArray(this.value) ? this.value : [String(this.value)];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
unmatch() {
|
||||
this.unmatchArray = [];
|
||||
if (this.value !== null && typeof this.value !== "undefined") {
|
||||
// 传入值为非数组
|
||||
if (!Array.isArray(this.value)) {
|
||||
if (this.options.some((v) => v.value == this.value)) return false;
|
||||
this.unmatchArray.push(this.value);
|
||||
return true;
|
||||
}
|
||||
// 传入值为Array
|
||||
this.value.forEach((item) => {
|
||||
if (!this.options.some((v) => v.value == item))
|
||||
this.unmatchArray.push(item);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
// 没有value不显示
|
||||
return false;
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
handleArray(array) {
|
||||
if (array.length === 0) return "";
|
||||
return array.reduce((pre, cur) => {
|
||||
return pre + " " + cur;
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-tag + .el-tag {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,68 +1,104 @@
|
||||
<!-- @author zhengjie -->
|
||||
<template>
|
||||
<div class="icon-body">
|
||||
<el-input v-model="name" style="position: relative;" clearable placeholder="请输入图标名称" @clear="filterIcons" @input.native="filterIcons">
|
||||
<i slot="suffix" class="el-icon-search el-input__icon" />
|
||||
</el-input>
|
||||
<div class="icon-list">
|
||||
<div v-for="(item, index) in iconList" :key="index" @click="selectedIcon(item)">
|
||||
<svg-icon :icon-class="item" style="height: 30px;width: 16px;" />
|
||||
<span>{{ item }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import icons from './requireIcons'
|
||||
export default {
|
||||
name: 'IconSelect',
|
||||
data() {
|
||||
return {
|
||||
name: '',
|
||||
iconList: icons
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
filterIcons() {
|
||||
this.iconList = icons
|
||||
if (this.name) {
|
||||
this.iconList = this.iconList.filter(item => item.includes(this.name))
|
||||
}
|
||||
},
|
||||
selectedIcon(name) {
|
||||
this.$emit('selected', name)
|
||||
document.body.click()
|
||||
},
|
||||
reset() {
|
||||
this.name = ''
|
||||
this.iconList = icons
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.icon-body {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
.icon-list {
|
||||
height: 200px;
|
||||
overflow-y: scroll;
|
||||
div {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
margin-bottom: -5px;
|
||||
cursor: pointer;
|
||||
width: 33%;
|
||||
float: left;
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- @author zhengjie -->
|
||||
<template>
|
||||
<div class="icon-body">
|
||||
<el-input v-model="name" class="icon-search" clearable placeholder="请输入图标名称" @clear="filterIcons" @input="filterIcons">
|
||||
<i slot="suffix" class="el-icon-search el-input__icon" />
|
||||
</el-input>
|
||||
<div class="icon-list">
|
||||
<div class="list-container">
|
||||
<div v-for="(item, index) in iconList" class="icon-item-wrapper" :key="index" @click="selectedIcon(item)">
|
||||
<div :class="['icon-item', { active: activeIcon === item }]">
|
||||
<svg-icon :icon-class="item" class-name="icon" style="height: 25px;width: 16px;"/>
|
||||
<span>{{ item }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import icons from './requireIcons'
|
||||
export default {
|
||||
name: 'IconSelect',
|
||||
props: {
|
||||
activeIcon: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
name: '',
|
||||
iconList: icons
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
filterIcons() {
|
||||
this.iconList = icons
|
||||
if (this.name) {
|
||||
this.iconList = this.iconList.filter(item => item.includes(this.name))
|
||||
}
|
||||
},
|
||||
selectedIcon(name) {
|
||||
this.$emit('selected', name)
|
||||
document.body.click()
|
||||
},
|
||||
reset() {
|
||||
this.name = ''
|
||||
this.iconList = icons
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.icon-body {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
.icon-search {
|
||||
position: relative;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.icon-list {
|
||||
height: 200px;
|
||||
overflow: auto;
|
||||
.list-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.icon-item-wrapper {
|
||||
width: calc(100% / 3);
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
.icon-item {
|
||||
display: flex;
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 5px;
|
||||
&:hover {
|
||||
background: #ececec;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.icon {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
padding-left: 2px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.icon-item.active {
|
||||
background: #ececec;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -127,7 +127,13 @@ export default {
|
||||
window.open(key, "_blank");
|
||||
} else if (!route || !route.children) {
|
||||
// 没有子路由路径内部打开
|
||||
this.$router.push({ path: key });
|
||||
const routeMenu = this.childrenMenus.find(item => item.path === key);
|
||||
if (routeMenu && routeMenu.query) {
|
||||
let query = JSON.parse(routeMenu.query);
|
||||
this.$router.push({ path: key, query: query });
|
||||
} else {
|
||||
this.$router.push({ path: key });
|
||||
}
|
||||
this.$store.dispatch('app/toggleSideBarHide', true);
|
||||
} else {
|
||||
// 显示左侧联动菜单
|
||||
|
||||
@@ -50,3 +50,26 @@ export default {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
// fix css style bug in open el-dialog
|
||||
.el-popup-parent--hidden {
|
||||
.fixed-header {
|
||||
padding-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #c0c0c0;
|
||||
border-radius: 3px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -35,7 +35,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: '若依管理系统',
|
||||
title: process.env.VUE_APP_TITLE,
|
||||
logo: logoImg
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,94 +1,94 @@
|
||||
<template>
|
||||
<el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">
|
||||
<slot />
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const tagAndTagSpacing = 4 // tagAndTagSpacing
|
||||
|
||||
export default {
|
||||
name: 'ScrollPane',
|
||||
data() {
|
||||
return {
|
||||
left: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
scrollWrapper() {
|
||||
return this.$refs.scrollContainer.$refs.wrap
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.scrollWrapper.addEventListener('scroll', this.emitScroll, true)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.scrollWrapper.removeEventListener('scroll', this.emitScroll)
|
||||
},
|
||||
methods: {
|
||||
handleScroll(e) {
|
||||
const eventDelta = e.wheelDelta || -e.deltaY * 40
|
||||
const $scrollWrapper = this.scrollWrapper
|
||||
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
|
||||
},
|
||||
emitScroll() {
|
||||
this.$emit('scroll')
|
||||
},
|
||||
moveToTarget(currentTag) {
|
||||
const $container = this.$refs.scrollContainer.$el
|
||||
const $containerWidth = $container.offsetWidth
|
||||
const $scrollWrapper = this.scrollWrapper
|
||||
const tagList = this.$parent.$refs.tag
|
||||
|
||||
let firstTag = null
|
||||
let lastTag = null
|
||||
|
||||
// find first tag and last tag
|
||||
if (tagList.length > 0) {
|
||||
firstTag = tagList[0]
|
||||
lastTag = tagList[tagList.length - 1]
|
||||
}
|
||||
|
||||
if (firstTag === currentTag) {
|
||||
$scrollWrapper.scrollLeft = 0
|
||||
} else if (lastTag === currentTag) {
|
||||
$scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth
|
||||
} else {
|
||||
// find preTag and nextTag
|
||||
const currentIndex = tagList.findIndex(item => item === currentTag)
|
||||
const prevTag = tagList[currentIndex - 1]
|
||||
const nextTag = tagList[currentIndex + 1]
|
||||
|
||||
// the tag's offsetLeft after of nextTag
|
||||
const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing
|
||||
|
||||
// the tag's offsetLeft before of prevTag
|
||||
const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing
|
||||
|
||||
if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
|
||||
$scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth
|
||||
} else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
|
||||
$scrollWrapper.scrollLeft = beforePrevTagOffsetLeft
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.scroll-container {
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
::v-deep {
|
||||
.el-scrollbar__bar {
|
||||
bottom: 0px;
|
||||
}
|
||||
.el-scrollbar__wrap {
|
||||
height: 49px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">
|
||||
<slot />
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const tagAndTagSpacing = 4 // tagAndTagSpacing
|
||||
|
||||
export default {
|
||||
name: 'ScrollPane',
|
||||
data() {
|
||||
return {
|
||||
left: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
scrollWrapper() {
|
||||
return this.$refs.scrollContainer.$refs.wrap
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.scrollWrapper.addEventListener('scroll', this.emitScroll, true)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.scrollWrapper.removeEventListener('scroll', this.emitScroll)
|
||||
},
|
||||
methods: {
|
||||
handleScroll(e) {
|
||||
const eventDelta = e.wheelDelta || -e.deltaY * 40
|
||||
const $scrollWrapper = this.scrollWrapper
|
||||
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
|
||||
},
|
||||
emitScroll() {
|
||||
this.$emit('scroll')
|
||||
},
|
||||
moveToTarget(currentTag) {
|
||||
const $container = this.$refs.scrollContainer.$el
|
||||
const $containerWidth = $container.offsetWidth
|
||||
const $scrollWrapper = this.scrollWrapper
|
||||
const tagList = this.$parent.$refs.tag
|
||||
|
||||
let firstTag = null
|
||||
let lastTag = null
|
||||
|
||||
// find first tag and last tag
|
||||
if (tagList.length > 0) {
|
||||
firstTag = tagList[0]
|
||||
lastTag = tagList[tagList.length - 1]
|
||||
}
|
||||
|
||||
if (firstTag === currentTag) {
|
||||
$scrollWrapper.scrollLeft = 0
|
||||
} else if (lastTag === currentTag) {
|
||||
$scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth
|
||||
} else {
|
||||
// find preTag and nextTag
|
||||
const currentIndex = tagList.findIndex(item => item === currentTag)
|
||||
const prevTag = tagList[currentIndex - 1]
|
||||
const nextTag = tagList[currentIndex + 1]
|
||||
|
||||
// the tag's offsetLeft after of nextTag
|
||||
const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing
|
||||
|
||||
// the tag's offsetLeft before of prevTag
|
||||
const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing
|
||||
|
||||
if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
|
||||
$scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth
|
||||
} else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
|
||||
$scrollWrapper.scrollLeft = beforePrevTagOffsetLeft
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.scroll-container {
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
::v-deep {
|
||||
.el-scrollbar__bar {
|
||||
bottom: 0px;
|
||||
}
|
||||
.el-scrollbar__wrap {
|
||||
height: 49px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -182,7 +182,7 @@ export default {
|
||||
})
|
||||
},
|
||||
closeOthersTags() {
|
||||
this.$router.push(this.selectedTag).catch(()=>{});
|
||||
this.$router.push(this.selectedTag.fullPath).catch(()=>{});
|
||||
this.$tab.closeOtherPage(this.selectedTag).then(() => {
|
||||
this.moveToCurrentTag()
|
||||
})
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
<template>
|
||||
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
|
||||
<el-scrollbar>
|
||||
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
|
||||
<sidebar v-if="!sidebar.hide" class="sidebar-container"/>
|
||||
<div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
|
||||
<div :class="{'fixed-header':fixedHeader}">
|
||||
<navbar/>
|
||||
<tags-view v-if="needTagsView"/>
|
||||
</div>
|
||||
<app-main/>
|
||||
<right-panel>
|
||||
<settings/>
|
||||
</right-panel>
|
||||
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
|
||||
<sidebar v-if="!sidebar.hide" class="sidebar-container"/>
|
||||
<div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
|
||||
<div :class="{'fixed-header':fixedHeader}">
|
||||
<navbar/>
|
||||
<tags-view v-if="needTagsView"/>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<app-main/>
|
||||
<right-panel>
|
||||
<settings/>
|
||||
</right-panel>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -74,14 +72,6 @@ export default {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.el-scrollbar{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
::v-deep .el-scrollbar__wrap {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
&.mobile.openSidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
|
||||
@@ -244,9 +244,15 @@ export const dynamicRoutes = [
|
||||
|
||||
// 防止连续点击多次路由报错
|
||||
let routerPush = Router.prototype.push;
|
||||
let routerReplace = Router.prototype.replace;
|
||||
// push
|
||||
Router.prototype.push = function push(location) {
|
||||
return routerPush.call(this, location).catch(err => err)
|
||||
}
|
||||
// replace
|
||||
Router.prototype.replace = function push(location) {
|
||||
return routerReplace.call(this, location).catch(err => err)
|
||||
}
|
||||
|
||||
export default new Router({
|
||||
mode: 'history', // 去掉url中的#
|
||||
|
||||
2
ruoyi-ui/src/views/monitor/cache/list.vue
vendored
2
ruoyi-ui/src/views/monitor/cache/list.vue
vendored
@@ -187,7 +187,7 @@ export default {
|
||||
/** 清理指定名称缓存 */
|
||||
handleClearCacheName(row) {
|
||||
clearCacheName(row.cacheName).then(response => {
|
||||
this.$modal.msgSuccess("清理缓存名称[" + this.nowCacheName + "]成功");
|
||||
this.$modal.msgSuccess("清理缓存名称[" + row.cacheName + "]成功");
|
||||
this.getCacheKeys();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@@ -134,14 +134,13 @@
|
||||
trigger="click"
|
||||
@show="$refs['iconSelect'].reset()"
|
||||
>
|
||||
<IconSelect ref="iconSelect" @selected="selected" />
|
||||
<IconSelect ref="iconSelect" @selected="selected" :active-icon="form.icon" />
|
||||
<el-input slot="reference" v-model="form.icon" placeholder="点击选择图标" readonly>
|
||||
<svg-icon
|
||||
v-if="form.icon"
|
||||
slot="prefix"
|
||||
:icon-class="form.icon"
|
||||
class="el-input__icon"
|
||||
style="height: 32px;width: 16px;"
|
||||
style="width: 25px;"
|
||||
/>
|
||||
<i v-else slot="prefix" class="el-icon-search el-input__icon" />
|
||||
</el-input>
|
||||
|
||||
@@ -674,7 +674,7 @@ create table gen_table (
|
||||
drop table if exists gen_table_column;
|
||||
create table gen_table_column (
|
||||
column_id bigint(20) not null auto_increment comment '编号',
|
||||
table_id varchar(64) comment '归属表编号',
|
||||
table_id bigint(20) comment '归属表编号',
|
||||
column_name varchar(200) comment '列名称',
|
||||
column_comment varchar(500) comment '列描述',
|
||||
column_type varchar(100) comment '列类型',
|
||||
Reference in New Issue
Block a user