16 Commits
24 changed files with 124 additions and 60 deletions
+3 -3
View File
@@ -17,7 +17,7 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<shiro.version>1.10.1</shiro.version>
<shiro.version>1.12.0</shiro.version>
<thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
<druid.version>1.2.16</druid.version>
<bitwalker.version>1.21</bitwalker.version>
@@ -25,7 +25,7 @@
<swagger.version>3.0.0</swagger.version>
<pagehelper.boot.version>1.4.6</pagehelper.boot.version>
<fastjson.version>1.2.83</fastjson.version>
<oshi.version>6.4.1</oshi.version>
<oshi.version>6.4.3</oshi.version>
<commons.io.version>2.11.0</commons.io.version>
<poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version>
@@ -39,7 +39,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>
+1 -1
View File
@@ -74,7 +74,7 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
<version>2.5.15</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
</configuration>
+18 -18
View File
@@ -58,15 +58,15 @@ spring:
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
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:
@@ -75,18 +75,18 @@ spring:
# 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
# Shiro
shiro:
@@ -99,11 +99,11 @@ shiro:
indexUrl: /index
# 验证码开关
captchaEnabled: true
# 验证码类型 math 数计算 char 字符
# 验证码类型 math 数计算 char 字符验证
captchaType: math
cookie:
# 设置Cookie的域名 默认空,即当前访问的域名
domain:
domain:
# 设置cookie的有效访问路径
path: /
# 设置HttpOnly属性
@@ -111,7 +111,7 @@ shiro:
# 设置Cookie的过期时间,天为单位
maxAge: 30
# 设置密钥,务必保持唯一性(生成方式,直接拷贝到main运行即可)Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) (默认启动生成随机秘钥,随机秘钥会导致之前客户端RememberMe Cookie无效,如设置固定秘钥RememberMe Cookie则有效)
cipherKey:
cipherKey:
session:
# Session超时时间,-1代表永不过期(默认30分钟)
expireTime: 30
@@ -128,7 +128,7 @@ shiro:
enabled: true
# 防止XSS攻击
xss:
xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
@@ -1,7 +1,7 @@
/*! X-editable - v1.5.1
/*! X-editable - v1.5.3
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
* Copyright (c) 2019 Vitaliy Potapov; Licensed MIT */
.editableform {
margin-bottom: 0; /* overwrites bootstrap margin */
}
@@ -12,6 +12,16 @@
line-height: 20px; /* overwriting bootstrap line-height. See #133 */
}
/*
BS3 fix: stop css from breaking when the form is inside a popup and inside a form with the class .form-horizontal
See: https://github.com/vitalets/x-editable/issues/682
*/
.form-horizontal .editable-popup .editableform .form-group {
margin-left:0;
margin-right:0;
}
/*
BS3 width:1005 for inputs breaks editable form in popup
See: https://github.com/vitalets/x-editable/issues/393
@@ -145,6 +155,7 @@
.editable-pre-wrapped {
white-space: pre-wrap;
}
.editable-container.editable-popup {
max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
}
File diff suppressed because one or more lines are too long
@@ -26,7 +26,7 @@ $.extend($.fn.bootstrapTable.columnDefaults, {
alwaysUseFormatter: false
})
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
$.extend($.fn.bootstrapTable.events, {
'editable-init.bs.table': 'onEditableInit',
'editable-save.bs.table': 'onEditableSave',
'editable-shown.bs.table': 'onEditableShown',
@@ -63,7 +63,7 @@ $.BootstrapTable = class extends $.BootstrapTable {
column.formatter = column.formatter || (value => value)
column._formatter = column._formatter ? column._formatter : column.formatter
column.formatter = (value, row, index) => {
column.formatter = (value, row, index, field) => {
let result = Utils.calculateObjectValue(column, column._formatter, [value, row, index], value)
result = typeof result === 'undefined' || result === null ? this.options.undefinedText : result
@@ -86,7 +86,7 @@ $.BootstrapTable = class extends $.BootstrapTable {
column.editable, [index, row], {})
if (editableOpts.hasOwnProperty('noEditFormatter')) {
noEditFormatter = editableOpts.noEditFormatter(value, row, index)
noEditFormatter = editableOpts.noEditFormatter(value, row, index, field)
}
if (noEditFormatter === false) {
@@ -177,11 +177,13 @@ $.BootstrapTable = class extends $.BootstrapTable {
if (params && params.escape) {
for (const row of data) {
for (const [key, value] of Object.entries(row)) {
row[key] = Utils.unescapeHTML(value)
if (typeof(value) !== "number") {
row[key] = Utils.unescapeHTML(value)
}
}
}
}
return data
}
}
}
@@ -217,6 +217,8 @@
if (!data || data.length <= 0) {
var _empty = '<tr><td colspan="' + options.columns.length + '"><div style="display: block;text-align: center;">没有找到匹配的记录</div></td></tr>'
$tbody.html(_empty);
options.pageNumber = 1;
initPagination(0, 0);
return;
}
// 缓存并格式化数据
@@ -272,6 +274,9 @@
if (pageTo > target.totalRows) {
pageTo = target.totalRows;
}
if (pageFrom > pageTo) {
pageFrom = pageTo;
}
html.push('<div class="pull-left pagination-detail">');
html.push('<span class="pagination-info">' + formatShowingRows(pageFrom, pageTo, target.totalRows) + '</span>');
var pageList = false;
File diff suppressed because one or more lines are too long
@@ -694,9 +694,7 @@ var table = {
var tableId = $.common.isEmpty(tableId) ? table.options.id : tableId;
if (table.options.type == table_type.bootstrapTable) {
var params = $("#" + tableId).bootstrapTable('getOptions');
if ($.common.isNotEmpty(pageNumber)) {
params.pageNumber = pageNumber;
}
params.pageNumber = 1;
if ($.common.isNotEmpty(pageSize)) {
params.pageSize = pageSize;
}
@@ -21,7 +21,7 @@
<div class="form-group">
<label class="col-sm-3 control-label is-required">参数键值:</label>
<div class="col-sm-8">
<input id="configValue" name="configValue" class="form-control" type="text" required>
<textarea id="configValue" name="configValue" class="form-control" rows="4" required></textarea>
</div>
</div>
<div class="form-group">
@@ -87,26 +87,30 @@
field: 'configName',
title: '参数名称',
formatter: function(value, row, index) {
return $.table.tooltip(value);
return $.table.tooltip(value);
}
},
{
field: 'configKey',
title: '参数键名',
formatter: function(value, row, index) {
return $.table.tooltip(value);
return $.table.tooltip(value);
}
},
{
field: 'configValue',
title: '参数键值'
title: '参数键值',
align: 'center',
formatter: function(value, row, index) {
return $.table.tooltip(value, 10, "open");
}
},
{
field: 'configType',
title: '系统内置',
align: 'center',
formatter: function(value, row, index) {
return $.table.selectDictLabel(datas, value);
return $.table.selectDictLabel(datas, value);
}
},
{
@@ -114,7 +118,7 @@
title: '备注',
align: 'center',
formatter: function(value, row, index) {
return $.table.tooltip(value, 10, "open");
return $.table.tooltip(value, 10, "open");
}
},
{
@@ -22,7 +22,7 @@
<div class="form-group">
<label class="col-sm-3 control-label is-required">参数键值:</label>
<div class="col-sm-8">
<input id="configValue" name="configValue" th:field="*{configValue}" class="form-control" type="text" required>
<textarea id="configValue" name="configValue" class="form-control" rows="4" required>[[*{configValue}]]</textarea>
</div>
</div>
<div class="form-group">
@@ -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;
@@ -14,7 +14,7 @@ public class DynamicDataSourceContextHolder
/**
* 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
*/
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
@@ -188,7 +188,17 @@ public class AjaxResult extends HashMap<String, Object>
*/
public boolean isSuccess()
{
return !isError();
return Objects.equals(Type.SUCCESS.value, this.get(CODE_TAG));
}
/**
* 是否为警告消息
*
* @return 结果
*/
public boolean isWarn()
{
return Objects.equals(Type.WARN.value, this.get(CODE_TAG));
}
/**
@@ -147,7 +147,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
/**
* 计算时间差
*
* @param endTime 最后时间
* @param endDate 最后时间
* @param startTime 开始时间
* @return 时间差(天/小时/分钟)
*/
@@ -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}
*/
@@ -118,7 +118,7 @@ public class SysLoginService
if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark())));
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked")));
throw new UserBlockedException();
}
@@ -6,8 +6,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
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 org.springframework.web.servlet.ModelAndView;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.DemoModeException;
@@ -94,6 +96,29 @@ public class GlobalExceptionHandler
}
}
/**
* 请求路径中缺少必需的路径变量
*/
@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()));
}
/**
* 自定义验证异常
*/
@@ -52,7 +52,7 @@ public class PermissionService
/**
* 验证用户是否具有以下任意一个权限,无权限返回hidden用于隐藏(如需返回Boolean使用hasAnyPermissions
*
* @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
* @param permissions 以 PERMISSION_DELIMETER 为分隔符的权限列表
* @return 用户是否具有以下任意一个权限
*/
public String hasAnyPermi(String permissions)
@@ -129,7 +129,7 @@ public class PermissionService
/**
* 验证用户是否具有以下任意一个权限。
*
* @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
* @param permissions 以 PERMISSION_DELIMETER 为分隔符的权限列表
* @return 用户是否具有以下任意一个权限
*/
public boolean hasAnyPermissions(String permissions)
@@ -1,6 +1,6 @@
# 代码生成
gen:
gen:
# 作者
author: ruoyi
# 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool
@@ -716,7 +716,7 @@
<div class="tab-pane" id="tabDay">
<div class="radio">
<label>
<input type="radio" name="rdoDay" id="day_all">小时 允许的通配符[, - * /]
<input type="radio" name="rdoDay" id="day_all"> 允许的通配符[, - * /]
</label>
</div>
<div class="radio">
@@ -1169,4 +1169,4 @@ $('#checkCron').click(function() {
});
</script>
</body>
</html>
</html>
+1 -1
View File
@@ -695,7 +695,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 '列类型',