17 Commits
v4.3 ... v4.3.1

Author SHA1 Message Date
7c48bc3184 若依 4.3.1 2020-07-04 22:40:47 +08:00
91986f13f8 国家信息安全漏洞(请务必保持cipherKey密钥唯一性) 2020-07-04 20:52:27 +08:00
7728ad9eb4 检查字符支持小数点&降级改成异常提醒 2020-07-04 11:36:59 +08:00
868aed4079 openOptions函数中加入自定义maxmin属性 2020-06-29 14:55:27 +08:00
9627ba9e1d 支持openOptions方法最大化 2020-06-28 17:25:14 +08:00
e0e305c423 验证码清除,防止多次使用。 2020-06-28 16:34:23 +08:00
ed4280379d !169 修改验证码使用后仍可用的问题
Merge pull request !169 from goodhal/master
2020-06-28 16:05:20 +08:00
233089b3e6 支持openOptions方法多个按钮回调 2020-06-28 11:44:12 +08:00
bb0e7bd563 右键页签操作实现与菜单联动 2020-06-28 09:49:41 +08:00
tys
7bca4fcbc4 关闭顶部tab页时,左侧菜单定位到当前显示页 2020-06-27 22:19:14 +08:00
1b7a735f9c 升级shiro到最新版1.5.3 阻止权限绕过漏洞 2020-06-26 09:53:10 +08:00
829dfafdaa 新增isLinkage支持页签与菜单联动 2020-06-24 22:23:42 +08:00
5a59670124 修改代码生成导入表结构出现异常页面不提醒问题 2020-06-24 18:12:26 +08:00
2499685a31 如果加载头像时发生了错误,则显示一个默认头像 2020-06-24 10:39:02 +08:00
a3bb603382 Excel支持dictType读取字符串组内容 2020-06-23 21:05:38 +08:00
9ad3cc0b9a Excel导出支持字典类型 2020-06-23 20:59:23 +08:00
690a9a6281 修改验证码在使用后仍可用的问题 2020-06-10 17:27:43 +08:00
26 changed files with 335 additions and 117 deletions

View File

@ -6,18 +6,18 @@
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>4.3.0</version> <version>4.3.1</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>4.3.0</ruoyi.version> <ruoyi.version>4.3.1</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>
<shiro.version>1.4.2</shiro.version> <shiro.version>1.5.3</shiro.version>
<thymeleaf.extras.shiro.version>2.0.0</thymeleaf.extras.shiro.version> <thymeleaf.extras.shiro.version>2.0.0</thymeleaf.extras.shiro.version>
<mybatis.boot.version>1.3.2</mybatis.boot.version> <mybatis.boot.version>1.3.2</mybatis.boot.version>
<druid.version>1.1.14</druid.version> <druid.version>1.1.14</druid.version>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0</version> <version>4.3.1</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>

View File

@ -3,7 +3,7 @@ ruoyi:
# 名称 # 名称
name: RuoYi name: RuoYi
# 版本 # 版本
version: 4.3.0 version: 4.3.1
# 版权年份 # 版权年份
copyrightYear: 2019 copyrightYear: 2019
# 实例演示开关 # 实例演示开关
@ -108,6 +108,8 @@ shiro:
httpOnly: true httpOnly: true
# 设置Cookie的过期时间天为单位 # 设置Cookie的过期时间天为单位
maxAge: 30 maxAge: 30
# 设置密钥务必保持唯一性生成方式直接拷贝到main运行即可KeyGenerator keygen = KeyGenerator.getInstance("AES"); SecretKey deskey = keygen.generateKey(); System.out.println(Base64.encodeToString(deskey.getEncoded()));
cipherKey: zSyK5Kp6PZAAjlT+eeNMlg==
session: session:
# Session超时时间-1代表永不过期默认30分钟 # Session超时时间-1代表永不过期默认30分钟
expireTime: 30 expireTime: 30

View File

@ -72,6 +72,19 @@ $(window).bind("load resize", function() {
} }
}); });
function syncMenuTab(dataId) {
if(isLinkage) {
var $dataObj = $('a[href$="' + decodeURI(dataId) + '"]');
if (!$dataObj.hasClass("noactive")) {
$('.nav ul').removeClass("in");
$dataObj.parents("ul").addClass("in")
$dataObj.parents("li").addClass("active").siblings().removeClass("active").find('li').removeClass("active");
$dataObj.parents("ul").css('height', 'auto').height();
$dataObj.click();
}
}
}
function NavToggle() { function NavToggle() {
$('.navbar-minimalize').trigger('click'); $('.navbar-minimalize').trigger('click');
} }
@ -119,6 +132,7 @@ $(function() {
function setActiveTab(element) { function setActiveTab(element) {
if (!$(element).hasClass('active')) { if (!$(element).hasClass('active')) {
var currentId = $(element).data('id'); var currentId = $(element).data('id');
syncMenuTab(currentId);
// 显示tab对应的内容区 // 显示tab对应的内容区
$('.RuoYi_iframe').each(function() { $('.RuoYi_iframe').each(function() {
if ($(this).data('id') == currentId) { if ($(this).data('id') == currentId) {
@ -239,9 +253,12 @@ $(function() {
dataIndex = $(this).data('index'), dataIndex = $(this).data('index'),
menuName = $.trim($(this).text()), menuName = $.trim($(this).text()),
flag = true; flag = true;
if (!$('a[href$="' + dataUrl + '"]').hasClass("noactive")) {
$(".nav ul li, .nav li").removeClass("selected"); $(".nav ul li, .nav li").removeClass("selected");
$(this).parent("li").addClass("selected"); $(this).parent("li").addClass("selected");
setIframeUrl($(this).attr("href")); }
setIframeUrl(dataUrl);
if (dataUrl == undefined || $.trim(dataUrl).length == 0) return false; if (dataUrl == undefined || $.trim(dataUrl).length == 0) return false;
// 选项卡菜单已存在 // 选项卡菜单已存在
@ -383,7 +400,7 @@ $(function() {
}); });
} }
scrollToTab($('.menuTab.active')); scrollToTab($('.menuTab.active'));
setIframeUrl($('.page-tabs-content').find('.active').attr('data-id')); syncMenuTab($('.page-tabs-content').find('.active').attr('data-id'));
return false; return false;
} }
@ -399,6 +416,7 @@ $(function() {
function activeTab() { function activeTab() {
if (!$(this).hasClass('active')) { if (!$(this).hasClass('active')) {
var currentId = $(this).data('id'); var currentId = $(this).data('id');
syncMenuTab(currentId);
// 显示tab对应的内容区 // 显示tab对应的内容区
$('.mainContent .RuoYi_iframe').each(function() { $('.mainContent .RuoYi_iframe').each(function() {
if ($(this).data('id') == currentId) { if ($(this).data('id') == currentId) {
@ -441,7 +459,6 @@ $(function() {
$(this).remove(); $(this).remove();
}); });
$('.page-tabs-content').css("margin-left", "0"); $('.page-tabs-content').css("margin-left", "0");
setIframeUrl($('.page-tabs-content').find('.active').attr('data-id'));
} }
// 关闭全部选项卡 // 关闭全部选项卡
@ -455,7 +472,7 @@ $(function() {
$(this).addClass("active"); $(this).addClass("active");
}); });
$('.page-tabs-content').css("margin-left", "0"); $('.page-tabs-content').css("margin-left", "0");
setIframeUrl($('.page-tabs-content').find('.active').attr('data-id')); syncMenuTab($('.page-tabs-content').find('.active').attr('data-id'));
} }

View File

@ -801,9 +801,18 @@ var table = {
options.callBack(index, layero); options.callBack(index, layero);
} }
} }
layer.open({ var btnCallback = {};
if(options.btn instanceof Array){
for (var i = 1, len = options.btn.length; i < len; i++) {
var btn = options["btn" + (i + 1)];
if (btn) {
btnCallback["btn" + (i + 1)] = btn;
}
}
}
var index = layer.open($.extend({
type: 2, type: 2,
maxmin: true, maxmin: $.common.isEmpty(options.maxmin) ? true : options.maxmin,
shade: 0.3, shade: 0.3,
title: _title, title: _title,
fix: false, fix: false,
@ -816,7 +825,10 @@ var table = {
cancel: function () { cancel: function () {
return true; return true;
} }
}); }, btnCallback));
if ($.common.isNotEmpty(options.full) && options.full === true) {
layer.full(index);
}
}, },
// 弹出层全屏 // 弹出层全屏
openFull: function (title, url, width, height) { openFull: function (title, url, width, height) {

View File

@ -17,7 +17,7 @@
<h2>若依后台管理系统</h2> <h2>若依后台管理系统</h2>
<p>ruoyi是一个完全响应式基于Bootstrap3.3.6最新版本开发的扁平化主题她采用了主流的左右两栏式布局使用了Html5+CSS3等现代技术她提供了诸多的强大的可以重新组合的UI组件并集成了最新的jQuery版本(v2.1.1)当然也集成了很多功能强大用途广泛的就jQuery插件她可以用于所有的Web应用程序<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p> <p>ruoyi是一个完全响应式基于Bootstrap3.3.6最新版本开发的扁平化主题她采用了主流的左右两栏式布局使用了Html5+CSS3等现代技术她提供了诸多的强大的可以重新组合的UI组件并集成了最新的jQuery版本(v2.1.1)当然也集成了很多功能强大用途广泛的就jQuery插件她可以用于所有的Web应用程序<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p>
<p> <p>
<b>当前版本:</b>v4.3.0 <b>当前版本:</b>v4.3.1
</p> </p>
<p> <p>
<span class="label label-warning">免费开源</span> <span class="label label-warning">免费开源</span>
@ -56,7 +56,7 @@
<h3>你好,若依 </h3> <h3>你好,若依 </h3>
<p>H+是一个完全响应式基于Bootstrap3.3.6最新版本开发的扁平化主题她采用了主流的左右两栏式布局使用了Html5+CSS3等现代技术她提供了诸多的强大的可以重新组合的UI组件并集成了最新的jQuery版本(v2.1.1)当然也集成了很多功能强大用途广泛的就jQuery插件她可以用于所有的Web应用程序<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p> <p>H+是一个完全响应式基于Bootstrap3.3.6最新版本开发的扁平化主题她采用了主流的左右两栏式布局使用了Html5+CSS3等现代技术她提供了诸多的强大的可以重新组合的UI组件并集成了最新的jQuery版本(v2.1.1)当然也集成了很多功能强大用途广泛的就jQuery插件她可以用于所有的Web应用程序<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p>
<p> <p>
<b>当前版本:</b>v4.3.0 <b>当前版本:</b>v4.3.1
</p> </p>
<p> <p>
<span class="label label-warning">开源免费</span> <span class="label label-warning">开源免费</span>

View File

@ -41,8 +41,8 @@
<script th:src="@{/ajax/libs/iCheck/icheck.min.js}"></script> <script th:src="@{/ajax/libs/iCheck/icheck.min.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script> <script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ajax/libs/layui/layui.js}"></script> <script th:src="@{/ajax/libs/layui/layui.js}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.3.0}"></script> <script th:src="@{/ruoyi/js/common.js?v=4.3.1}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.3.0}"></script> <script th:src="@{/ruoyi/js/ry-ui.js?v=4.3.1}"></script>
<script th:inline="javascript"> var ctx = [[@{/}]]; </script> <script th:inline="javascript"> var ctx = [[@{/}]]; </script>
</div> </div>

View File

@ -14,7 +14,7 @@
<link th:href="@{/css/animate.css}" rel="stylesheet"/> <link th:href="@{/css/animate.css}" rel="stylesheet"/>
<link th:href="@{/css/style.css}" rel="stylesheet"/> <link th:href="@{/css/style.css}" rel="stylesheet"/>
<link th:href="@{/css/skins.css}" rel="stylesheet"/> <link th:href="@{/css/skins.css}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.3.0}" rel="stylesheet"/> <link th:href="@{/ruoyi/css/ry-ui.css?v=4.3.1}" rel="stylesheet"/>
</head> </head>
<body class="fixed-sidebar full-height-layout gray-bg" style="overflow: hidden"> <body class="fixed-sidebar full-height-layout gray-bg" style="overflow: hidden">
<div id="wrapper"> <div id="wrapper">
@ -36,7 +36,7 @@
<a class="menuItem noactive" title="个人中心" th:href="@{/system/user/profile}"> <a class="menuItem noactive" title="个人中心" th:href="@{/system/user/profile}">
<div class="hide" th:text="个人中心"></div> <div class="hide" th:text="个人中心"></div>
<div class="pull-left image"> <div class="pull-left image">
<img th:src="(${user.avatar} == '') ? @{/img/profile.jpg} : @{${user.avatar}}" class="img-circle" alt="User Image"> <img th:src="(${user.avatar} == '') ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="this.src='img/profile.jpg'" class="img-circle" alt="User Image">
</div> </div>
</a> </a>
<div class="pull-left info"> <div class="pull-left info">
@ -185,7 +185,7 @@
<li><a title="全屏显示" href="javascript:void(0)" id="fullScreen"><i class="fa fa-arrows-alt"></i> 全屏显示</a></li> <li><a title="全屏显示" href="javascript:void(0)" id="fullScreen"><i class="fa fa-arrows-alt"></i> 全屏显示</a></li>
<li class="dropdown user-menu"> <li class="dropdown user-menu">
<a href="javascript:void(0)" class="dropdown-toggle" data-hover="dropdown"> <a href="javascript:void(0)" class="dropdown-toggle" data-hover="dropdown">
<img th:src="(${user.avatar} == '') ? @{/img/profile.jpg} : @{${user.avatar}}" class="user-image"> <img th:src="(${user.avatar} == '') ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="this.src='img/profile.jpg'" class="user-image">
<span class="hidden-xs">[[${#strings.defaultString(user.userName, '-')}]]</span> <span class="hidden-xs">[[${#strings.defaultString(user.userName, '-')}]]</span>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
@ -246,8 +246,8 @@
<script th:src="@{/js/jquery.contextMenu.min.js}"></script> <script th:src="@{/js/jquery.contextMenu.min.js}"></script>
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script> <script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script> <script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.3.0}"></script> <script th:src="@{/ruoyi/js/ry-ui.js?v=4.3.1}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.3.0}"></script> <script th:src="@{/ruoyi/js/common.js?v=4.3.1}"></script>
<script th:src="@{/ruoyi/index.js}"></script> <script th:src="@{/ruoyi/index.js}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script> <script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
<script th:inline="javascript"> <script th:inline="javascript">
@ -258,6 +258,8 @@ var skin = storage.get("skin");
var mode = "history"; var mode = "history";
// 历史访问路径缓存 // 历史访问路径缓存
var historyPath = storage.get("historyPath"); var historyPath = storage.get("historyPath");
// 是否页签与菜单联动
var isLinkage = true;
// 本地主题优先,未设置取系统配置 // 本地主题优先,未设置取系统配置
if($.common.isNotEmpty(skin)){ if($.common.isNotEmpty(skin)){

View File

@ -9,7 +9,7 @@
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/> <link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link href="../static/css/style.css" th:href="@{/css/style.css}" rel="stylesheet"/> <link href="../static/css/style.css" th:href="@{/css/style.css}" rel="stylesheet"/>
<link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/> <link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.3.0}" rel="stylesheet"/> <link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.3.1}" rel="stylesheet"/>
<!-- 360浏览器急速模式 --> <!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 --> <!-- 避免IE使用兼容模式 -->
@ -78,7 +78,7 @@
<script src="../static/ajax/libs/validate/messages_zh.min.js" th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script> <script src="../static/ajax/libs/validate/messages_zh.min.js" th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script>
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script> <script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script> <script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.3.0}"></script> <script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.3.1}"></script>
<script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script> <script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script>
</body> </body>
</html> </html>

View File

@ -96,13 +96,37 @@
<div class="ibox-content no-padding"> <div class="ibox-content no-padding">
<div class="panel-body"> <div class="panel-body">
<div class="panel-group" id="version"> <div class="panel-group" id="version">
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v431">v4.3.1</a><code class="pull-right">2020.07.05</code>
</h5>
</div>
<div id="v431" class="panel-collapse collapse in">
<div class="panel-body">
<ol>
<li>国家信息安全漏洞请务必保持cipherKey密钥唯一性</li>
<li>升级shiro到最新版1.5.3 阻止权限绕过漏洞</li>
<li>修改验证码在使用后清除,防止多次使用</li>
<li>检查字符支持小数点&降级改成异常提醒</li>
<li>openOptions函数中加入自定义maxmin属性</li>
<li>支持openOptions方法最大化</li>
<li>支持openOptions方法多个按钮回调</li>
<li>新增isLinkage支持页签与菜单联动</li>
<li>修改代码生成导入表结构出现异常页面不提醒问题</li>
<li>优化用户头像发生错误,则显示一个默认头像</li>
<li>Excel导出支持字典类型</li>
</ol>
</div>
</div>
</div>
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h5 class="panel-title"> <h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v43">v4.3.0</a><code class="pull-right">2020.06.22</code> <a data-toggle="collapse" data-parent="#version" href="#v43">v4.3.0</a><code class="pull-right">2020.06.22</code>
</h5> </h5>
</div> </div>
<div id="v43" class="panel-collapse collapse in"> <div id="v43" class="panel-collapse collapse">
<div class="panel-body"> <div class="panel-body">
<ol> <ol>
<li>代码生成模板支持主子表</li> <li>代码生成模板支持主子表</li>

View File

@ -9,7 +9,7 @@
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/> <link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link href="../static/css/style.css" th:href="@{/css/style.css}" rel="stylesheet"/> <link href="../static/css/style.css" th:href="@{/css/style.css}" rel="stylesheet"/>
<link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/> <link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.3.0}" rel="stylesheet"/> <link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.3.1}" rel="stylesheet"/>
<!-- 360浏览器急速模式 --> <!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 --> <!-- 避免IE使用兼容模式 -->
@ -77,7 +77,7 @@
<script src="../static/ajax/libs/validate/messages_zh.min.js" th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script> <script src="../static/ajax/libs/validate/messages_zh.min.js" th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script>
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script> <script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script> <script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.3.0}"></script> <script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.3.1}"></script>
<script src="../static/ruoyi/register.js" th:src="@{/ruoyi/register.js}"></script> <script src="../static/ruoyi/register.js" th:src="@{/ruoyi/register.js}"></script>
</body> </body>
</html> </html>

View File

@ -140,7 +140,7 @@
</ul> </ul>
</body> </body>
<script th:src="@{/js/jquery.min.js}"></script> <script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.3.0}"></script> <script th:src="@{/ruoyi/js/common.js?v=4.3.1}"></script>
<script type="text/javascript"> <script type="text/javascript">
//皮肤样式列表 //皮肤样式列表
var skins = ["skin-blue", "skin-green", "skin-purple", "skin-red", "skin-yellow"]; var skins = ["skin-blue", "skin-green", "skin-purple", "skin-red", "skin-yellow"];

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0</version> <version>4.3.1</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -24,6 +24,11 @@ public @interface Excel
*/ */
public String dateFormat() default ""; public String dateFormat() default "";
/**
* 如果是字典类型请设置字典的type值 (如: sys_user_sex)
*/
public String dictType() default "";
/** /**
* 读取内容转表达式 (如: 0=男,1=女,2=未知) * 读取内容转表达式 (如: 0=男,1=女,2=未知)
*/ */

View File

@ -11,10 +11,13 @@ public class PageDomain
{ {
/** 当前记录起始索引 */ /** 当前记录起始索引 */
private Integer pageNum; private Integer pageNum;
/** 每页显示记录数 */ /** 每页显示记录数 */
private Integer pageSize; private Integer pageSize;
/** 排序列 */ /** 排序列 */
private String orderByColumn; private String orderByColumn;
/** 排序的方向 "desc" 或者 "asc". */ /** 排序的方向 "desc" 或者 "asc". */
private String isAsc; private String isAsc;

View File

@ -50,6 +50,7 @@ import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils; import com.ruoyi.common.utils.reflect.ReflectUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
/** /**
* Excel相关处理 * Excel相关处理
@ -276,7 +277,11 @@ public class ExcelUtil<T>
} }
else if (StringUtils.isNotEmpty(attr.readConverterExp())) else if (StringUtils.isNotEmpty(attr.readConverterExp()))
{ {
val = reverseByExp(String.valueOf(val), attr.readConverterExp(), attr.separator()); val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
}
else if (StringUtils.isNotEmpty(attr.dictType()))
{
val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());
} }
ReflectUtils.invokeSetter(entity, propertyName, val); ReflectUtils.invokeSetter(entity, propertyName, val);
} }
@ -536,13 +541,18 @@ public class ExcelUtil<T>
String dateFormat = attr.dateFormat(); String dateFormat = attr.dateFormat();
String readConverterExp = attr.readConverterExp(); String readConverterExp = attr.readConverterExp();
String separator = attr.separator(); String separator = attr.separator();
String dictType = attr.dictType();
if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
{ {
cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value)); cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value));
} }
else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
{ {
cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp, separator)); cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator));
}
else if (StringUtils.isNotEmpty(dictType))
{
cell.setCellValue(convertDictByExp(Convert.toStr(value), dictType, separator));
} }
else else
{ {
@ -672,8 +682,6 @@ public class ExcelUtil<T>
public static String reverseByExp(String propertyValue, String converterExp, String separator) throws Exception public static String reverseByExp(String propertyValue, String converterExp, String separator) throws Exception
{ {
StringBuilder propertyString = new StringBuilder(); StringBuilder propertyString = new StringBuilder();
try
{
String[] convertSource = converterExp.split(","); String[] convertSource = converterExp.split(",");
for (String item : convertSource) for (String item : convertSource)
{ {
@ -697,14 +705,41 @@ public class ExcelUtil<T>
} }
} }
} }
}
catch (Exception e)
{
throw e;
}
return StringUtils.stripEnd(propertyString.toString(), separator); return StringUtils.stripEnd(propertyString.toString(), separator);
} }
/**
* 解析字典值
*
* @param dictValue 字典值
* @param dictType 字典类型
* @param separator 分隔符
* @return 字典标签
*/
public static String convertDictByExp(String dictValue, String dictType, String separator) throws Exception
{
Object bean = SpringUtils.getBean("dictUtils");
String methodName = "getDictLabel";
Method method = bean.getClass().getDeclaredMethod(methodName, String.class, String.class, String.class);
return Convert.toStr(method.invoke(bean, dictType, dictValue, separator));
}
/**
* 反向解析值字典值
*
* @param dictLabel 字典标签
* @param dictType 字典类型
* @param separator 分隔符
* @return 字典值
*/
public static String reverseDictByExp(String dictLabel, String dictType, String separator) throws Exception
{
Object bean = SpringUtils.getBean("dictUtils");
String methodName = "getDictValue";
Method method = bean.getClass().getDeclaredMethod(methodName, String.class, String.class, String.class);
return Convert.toStr(method.invoke(bean, dictType, dictLabel, separator));
}
/** /**
* 编码文件名 * 编码文件名
*/ */

View File

@ -1,5 +1,6 @@
package com.ruoyi.common.utils.sql; package com.ruoyi.common.utils.sql;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
@ -10,9 +11,9 @@ import com.ruoyi.common.utils.StringUtils;
public class SqlUtil public class SqlUtil
{ {
/** /**
* 仅支持字母、数字、下划线、空格、逗号(支持多个字段排序) * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
*/ */
public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,]+"; public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
/** /**
* 检查字符,防止注入绕过 * 检查字符,防止注入绕过
@ -21,7 +22,7 @@ public class SqlUtil
{ {
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
{ {
return StringUtils.EMPTY; throw new BaseException("参数不符合规范,不能进行查询");
} }
return value; return value;
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0</version> <version>4.3.1</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -85,6 +85,10 @@ public class ShiroConfig
@Value("${shiro.cookie.maxAge}") @Value("${shiro.cookie.maxAge}")
private int maxAge; private int maxAge;
// 设置cipherKey密钥
@Value("${shiro.cookie.cipherKey}")
private String cipherKey;
// 登录地址 // 登录地址
@Value("${shiro.user.loginUrl}") @Value("${shiro.user.loginUrl}")
private String loginUrl; private String loginUrl;
@ -328,7 +332,7 @@ public class ShiroConfig
{ {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie()); cookieRememberMeManager.setCookie(rememberMeCookie());
cookieRememberMeManager.setCipherKey(Base64.decode("fCq+/xW488hMTCD+cmJ3aQ==")); cookieRememberMeManager.setCipherKey(Base64.decode(cipherKey));
return cookieRememberMeManager; return cookieRememberMeManager;
} }

View File

@ -83,8 +83,8 @@ public class SysPasswordService
return new Md5Hash(username + password + salt).toHex(); return new Md5Hash(username + password + salt).toHex();
} }
public void unlock(String loginName){ public void unlock(String loginName)
{
loginRecordCache.remove(loginName); loginRecordCache.remove(loginName);
} }
} }

View File

@ -61,6 +61,8 @@ public class CaptchaValidateFilter extends AccessControlFilter
{ {
Object obj = ShiroUtils.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY); Object obj = ShiroUtils.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
String code = String.valueOf(obj != null ? obj : ""); String code = String.valueOf(obj != null ? obj : "");
// 验证码清除,防止多次使用。
request.getSession().removeAttribute(Constants.KAPTCHA_SESSION_KEY);
if (StringUtils.isEmpty(validateCode) || !validateCode.equalsIgnoreCase(code)) if (StringUtils.isEmpty(validateCode) || !validateCode.equalsIgnoreCase(code))
{ {
return false; return false;

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0</version> <version>4.3.1</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -155,10 +155,10 @@ public class GenTableServiceImpl implements IGenTableService
@Override @Override
@Transactional @Transactional
public void importGenTable(List<GenTable> tableList, String operName) public void importGenTable(List<GenTable> tableList, String operName)
{
for (GenTable table : tableList)
{ {
try try
{
for (GenTable table : tableList)
{ {
String tableName = table.getTableName(); String tableName = table.getTableName();
GenUtils.initTable(table, operName); GenUtils.initTable(table, operName);
@ -174,10 +174,10 @@ public class GenTableServiceImpl implements IGenTableService
} }
} }
} }
}
catch (Exception e) catch (Exception e)
{ {
log.error("表名 " + table.getTableName() + " 导入失败:", e); throw new BusinessException("导入失败:" + e.getMessage());
}
} }
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0</version> <version>4.3.1</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0</version> <version>4.3.1</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -1,6 +1,7 @@
package com.ruoyi.system.utils; package com.ruoyi.system.utils;
import java.util.List; import java.util.List;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.CacheUtils; import com.ruoyi.common.utils.CacheUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
@ -11,8 +12,14 @@ import com.ruoyi.system.domain.SysDictData;
* *
* @author ruoyi * @author ruoyi
*/ */
@Component
public class DictUtils public class DictUtils
{ {
/**
* 分隔符
*/
public static final String SEPARATOR = ",";
/** /**
* 设置字典缓存 * 设置字典缓存
* *
@ -41,6 +48,110 @@ public class DictUtils
return null; return null;
} }
/**
* 根据字典类型和字典值获取字典标签
*
* @param dictType 字典类型
* @param dictValue 字典值
* @return 字典标签
*/
public static String getDictLabel(String dictType, String dictValue)
{
return getDictLabel(dictType, dictValue, SEPARATOR);
}
/**
* 根据字典类型和字典标签获取字典值
*
* @param dictType 字典类型
* @param dictLabel 字典标签
* @return 字典值
*/
public static String getDictValue(String dictType, String dictLabel)
{
return getDictValue(dictType, dictLabel, SEPARATOR);
}
/**
* 根据字典类型和字典值获取字典标签
*
* @param dictType 字典类型
* @param dictValue 字典值
* @param separator 分隔符
* @return 字典标签
*/
public static String getDictLabel(String dictType, String dictValue, String separator)
{
StringBuilder propertyString = new StringBuilder();
List<SysDictData> datas = getDictCache(dictType);
if (StringUtils.containsAny(separator, dictValue) && StringUtils.isNotEmpty(datas))
{
for (SysDictData dict : datas)
{
for (String value : dictValue.split(separator))
{
if (value.equals(dict.getDictValue()))
{
propertyString.append(dict.getDictLabel() + separator);
break;
}
}
}
}
else
{
for (SysDictData dict : datas)
{
if (dictValue.equals(dict.getDictValue()))
{
return dict.getDictLabel();
}
}
}
return StringUtils.stripEnd(propertyString.toString(), separator);
}
/**
* 根据字典类型和字典标签获取字典值
*
* @param dictType 字典类型
* @param dictLabel 字典标签
* @param separator 分隔符
* @return 字典值
*/
public static String getDictValue(String dictType, String dictLabel, String separator)
{
StringBuilder propertyString = new StringBuilder();
List<SysDictData> datas = getDictCache(dictType);
if (StringUtils.containsAny(separator, dictLabel) && StringUtils.isNotEmpty(datas))
{
for (SysDictData dict : datas)
{
for (String label : dictLabel.split(separator))
{
if (label.equals(dict.getDictLabel()))
{
propertyString.append(dict.getDictValue() + separator);
break;
}
}
}
}
else
{
for (SysDictData dict : datas)
{
if (dictLabel.equals(dict.getDictLabel()))
{
return dict.getDictValue();
}
}
}
return StringUtils.stripEnd(propertyString.toString(), separator);
}
/** /**
* 清空字典缓存 * 清空字典缓存
*/ */