116 Commits

Author SHA1 Message Date
03201c36e8 若依 v4.7.7 2023-04-14 08:32:07 +08:00
aa7ee1aae1 升级oshi到最新版本6.4.1 2023-04-12 15:06:04 +08:00
07f9316935 优化导入用户时更新丢失岗位角色的问题 2023-04-10 18:20:28 +08:00
5e34d68d51 优化代码 2023-04-10 18:20:22 +08:00
5a07a91b50 升级jasny-bootstrap到最新版4.0.0 2023-04-07 19:38:29 +08:00
17abf826e9 优化用户导入更新时需获取用户编号问题 2023-04-07 19:20:38 +08:00
eca27ed5a1 !448 优化用户导入
Merge pull request !448 from 周冰/master
2023-04-07 11:08:15 +00:00
466d8800fc 优化导出Excel时设置dictType属性重复查缓存问题 2023-04-06 15:23:06 +08:00
ada2cb426b 用户导入,更新时需获取用户id,用于更新数据 2023-04-03 13:35:32 +08:00
f67600df28 支持自定义隐藏属性列过滤子对象 2023-03-17 14:54:24 +08:00
10bbb27684 修复用户注册唯一校验问题(I6MVZS) 2023-03-17 11:24:27 +08:00
a32da911d1 !442 用户多角色,数据权限切面处理时可能出现权限抬升的情况。
Merge pull request !442 from 0慕容雪0/master
2023-03-17 03:21:13 +00:00
6a861498ca update ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java.
Signed-off-by: 0慕容雪0 <ytu.mxh@163.com>
2023-03-11 04:28:09 +00:00
292ac30aa5 update ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java.
DataScopeAspect,数据权限切面处理类中,用户多角色情况下,若所有角色都不包含传递过来的权限字符,这个时候sqlString也会为空,会导致用户拥有全部数据权限,所以要限制一下, 可以根据conditions集合是否为空,来判断循环时所有角色是否都是在判断权限字符时continue了。
复现方法: 在使用@DataScope注解时permission定义了值,这个值所有角色不包含。


Signed-off-by: 0慕容雪0 <ytu.mxh@163.com>
2023-03-10 07:53:03 +00:00
1e91312f08 日志管理使用索引提升查询性能 2023-02-23 09:29:26 +08:00
bee73e87a5 升级layui到最新版本2.7.6 2023-02-23 09:23:26 +08:00
a1e2c6e1e6 修复isMatchedIp的参数判断产生空指针的问题 2023-02-22 10:30:49 +08:00
0bbe126125 移除apache/commons-fileupload依赖 2023-02-21 17:18:34 +08:00
590f6a302c 遗漏的优化代码 2023-02-21 16:19:33 +08:00
22470677d4 升级druid到最新版本1.2.16 2023-02-21 13:44:19 +08:00
7040cd26c6 优化代码 2023-02-21 13:43:52 +08:00
ac1e66b4b6 日志注解支持排除指定的请求参数 2023-02-20 15:50:15 +08:00
658ed5791b update sql 2023-02-20 15:49:35 +08:00
ef0a29552e 支持登录IP黑名单限制 2023-02-20 12:54:02 +08:00
99554659f0 修复异步表格树子项排序问题(I6G2YL) 2023-02-19 22:26:39 +08:00
995eb76c0f 修复冻结列不支持IE浏览器的问题(I6FD4W) 2023-02-19 20:54:55 +08:00
dbb312b26e 修复主子表使用suggest插件无法新增问题(I6FA5Z) 2023-02-19 19:29:35 +08:00
9b476399f0 更新fontawesome图标示例 2023-02-19 14:54:08 +08:00
e4f70b190c 优化前端属性提醒说明 2023-02-18 16:06:44 +08:00
bb5f87658e 新增监控页面图标显示 2023-02-17 08:52:15 +08:00
00f2db99d8 操作日志新增消耗时间属性 2023-02-16 11:57:40 +08:00
e26b65ca31 添加新群号:175104288 2023-02-11 12:16:15 +08:00
cda00589a4 修复菜单栏快速点击导致展开折叠样式问题(I6CWMP) 2023-02-04 21:56:56 +08:00
3b75d93d6b 连接池Druid支持新的配置connectTimeout和socketTimeout(I6CLL8) 2023-02-04 20:11:34 +08:00
10fb654d23 修复异步加载表格树重置列表父节点展开异常问题(I6AGWH) 2023-02-04 17:32:31 +08:00
432d5ce1be 屏蔽定时任务bean违规的字符 2023-02-04 16:06:04 +08:00
f2d5545092 update copyright 2023 2023-02-03 17:41:14 +08:00
8939e21a29 !437 解决单体版本表格行拖拽操作后,列表底部的总共记录条数变成了undefined问题
Merge pull request !437 from chenxin04187/master
2023-02-03 08:43:46 +00:00
b872a84a4a !436 EhCacheManager改为从bean容器获取,不使用自动装配
Merge pull request !436 from oak/master
2023-02-03 08:31:19 +00:00
311cb892a7 解决单体版本表格行拖拽操作后,列表底部的总共记录条数变成了undefined问题。
link https://gitee.com/y_project/RuoYi/issues/I68198
2023-01-23 22:19:34 +08:00
oak
fab98274b1 EhCacheManager改为从bean容器获取,不使用自动装配。作用:自建SpringBoot模块如果引用了ruoyi-system并且没有使用shiro,启动会报错。 2023-01-23 16:38:33 +08:00
3e8b211789 升级jquery到最新版v3.6.3 2023-01-19 11:59:10 +08:00
c92ed66436 修复页签属性refresh为undefined时页面被刷新问题 2023-01-12 17:31:30 +08:00
f1233c85d7 主子表根据序号删除方法加入表格ID参数 2023-01-12 17:31:06 +08:00
9d02f8f7e7 若依 v4.7.6 2022-12-16 08:50:57 +08:00
70205922fc 优化代码 2022-12-13 15:45:13 +08:00
f3d1f0afe2 修改参数键名时移除前缓存配置 2022-12-13 15:09:38 +08:00
7ee6ad8aec 升级pagehelper到最新版1.4.6 2022-12-13 14:23:20 +08:00
4ff9afac23 升级oshi到最新版本6.4.0 2022-12-13 14:21:58 +08:00
167970e5c4 优化SQL关键字检查防止注入 2022-12-13 13:17:17 +08:00
29395be19a !432 优化deleteFile方法返回值,接受File.delete的false返回值
Merge pull request !432 from 岳林/master
2022-12-12 05:48:17 +00:00
da01f093f8 优化deleteFile方法返回值,接受File.delete的false返回值 2022-12-12 09:41:38 +08:00
f53515eb70 升级druid到最新版本1.2.15 2022-12-07 11:55:23 +08:00
84dde0dcf2 升级kaptcha到最新版2.3.3 2022-12-07 10:58:07 +08:00
df1c283335 定时任务违规的字符 2022-12-03 11:32:41 +08:00
faa4bfaef3 升级oshi到最新版本6.3.2 2022-12-01 11:49:25 +08:00
eef7ef6544 !426 升级shiro到最新版本1.10.1
Merge pull request !426 from Hacker/N/A
2022-11-25 11:05:20 +00:00
22d42048ab 升级shiro到最新版本1.10.1
Signed-off-by: Hacker <721806280@qq.com>
2022-11-24 07:31:40 +00:00
e5b905c455 优化用户管理重置时取消部门选择(I621OJ) 2022-11-21 13:39:09 +08:00
c64f027e66 兼容Excel下拉框内容过多无法显示的问题(I61HCG) 2022-11-21 11:13:02 +08:00
96934ca139 修复操作日志类型多选导出不生效问题(I617FW) 2022-11-15 13:30:43 +08:00
f4c763c84d 升级druid到最新版本1.2.14 2022-11-14 11:47:57 +08:00
8cd0d9f366 忽略不必要的属性数据返回 2022-11-12 11:57:08 +08:00
6a7f727f70 优化导出对象的子列表为空会出现[]问题(I60904) 2022-11-11 10:35:32 +08:00
62381f0472 修复sheet超出最大行数异常问题 2022-11-07 11:27:12 +08:00
2952337f15 !420 update ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/session/OnlineSessionFactory.java.
Merge pull request !420 from chenjh/N/A
2022-11-07 03:22:59 +00:00
c719be609a update ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/session/OnlineSessionFactory.java.
ServletUtils.getRequest()应改request,可能为空

Signed-off-by: chenjh <asgard2023@outlook.com>
2022-11-06 14:26:47 +00:00
6253e41658 升级oshi到最新版本6.3.0 2022-10-28 21:31:14 +08:00
bd0e574268 优化select2搜索下拉后校验必填样式问题(I5VZY0) 2022-10-21 09:48:13 +08:00
6e176c807c 升级bootstrap-fileinput到最新版本5.5.2 2022-10-20 19:12:26 +08:00
2bdf12b1e1 升级shiro到最新版本1.10.0 2022-10-13 10:09:10 +08:00
67f2ba2aa9 修复导出包含空子列表数据异常的问题 2022-10-10 09:00:10 +08:00
c105f44eb9 优化树形表格层级显示(I5TQ87) 2022-10-09 21:17:20 +08:00
e23a6919af 优化topnav页缺少的样式右括号 2022-10-09 21:17:04 +08:00
b362e58646 R isError and isSuccess static 2022-10-09 21:16:52 +08:00
db3e571af0 优化代码生成同步后字典值NULL问题 2022-09-28 20:58:11 +08:00
52fe19e933 导入更新用户数据前校验数据权限 2022-09-28 20:58:02 +08:00
7b3ab45ecc 添加新群号:185760789 2022-09-28 10:56:36 +08:00
e337f685bc 修改用户登录账号重复验证 2022-09-18 11:25:03 +08:00
13287e02eb 修复关闭父页签后提交无法跳转的问题(I5QBMO) 2022-09-12 10:34:00 +08:00
d4a33eab94 优化代码 2022-09-09 10:09:56 +08:00
0ca327f538 若依 v4.7.5 2022-09-05 09:42:15 +08:00
31bd27fcf0 升级jquery到最新版3.6.1 2022-09-03 09:22:34 +08:00
dcfc062c01 修复用户分配角色大于默认页数丢失问题(I5OJA8) 2022-09-02 10:19:32 +08:00
daa8286804 AjaxResult错误消息结果类型的判断 2022-09-02 10:19:22 +08:00
5a3714e9bc 优化横向菜单下激活菜单样式 2022-08-27 11:54:15 +08:00
abe1f0d63e 定时任务支持执行父类方法 2022-08-27 11:54:06 +08:00
c95cb70af3 优化多角色数据权限匹配规则 2022-08-22 19:43:27 +08:00
47bd3c4c10 页签创建标题优先data-title属性(I4MC5L) 2022-08-22 19:41:08 +08:00
1c8f55c2c1 新增示例(进度条) 2022-08-20 18:52:26 +08:00
0f9558a825 自动设置切换多个树表格实例配置 2022-08-14 18:34:10 +08:00
8a4d37e975 菜单配置刷新时Tab页签切换时刷新 2022-08-14 10:32:24 +08:00
7fbabe1a8e 升级oshi到最新版本6.2.2 2022-08-14 09:19:19 +08:00
53cd4867df 修复树表onLoadSuccess不生效的问题 2022-08-10 13:07:28 +08:00
7aa4872cb9 优化导出对象的子列表判断条件 2022-08-10 12:47:46 +08:00
8fcc548d34 优化excel/scale属性导出单元格数值类型 2022-08-09 08:01:47 +08:00
d318b719fc Excel支持导出对象的子列表方法 2022-08-07 18:19:27 +08:00
d6db5963d5 数据逻辑删除不进行唯一验证 2022-08-03 15:54:58 +08:00
d5f4bba084 新增主子表提交校验示例 2022-08-02 12:09:11 +08:00
960dee7756 增加对AjaxResult消息结果类型的判断 2022-08-02 12:08:18 +08:00
08f775da4b 优化任务过期不执行调度 2022-07-29 20:07:29 +08:00
2a0fcdea21 升级layui到最新版本v2.7.5 2022-07-28 19:54:55 +08:00
3f0a34e20f 自定义数据权限不排除重复 2022-07-26 14:43:09 +08:00
289161b8c6 升级pagehelper到最新版1.4.3 2022-07-22 14:53:25 +08:00
47b51fe965 支持自定义隐藏Excel属性列 2022-07-21 13:51:09 +08:00
0c0efc9455 Excel注解支持backgroundColor属性设置背景颜色 2022-07-20 09:32:11 +08:00
dd86447176 优化多个相同角色数据导致权限SQL重复问题 2022-07-19 15:36:01 +08:00
3427223da2 升级oshi到最新版本6.2.1 2022-07-14 16:16:28 +08:00
1959b02220 升级shiro到最新版本1.9.1 2022-06-29 19:52:38 +08:00
acf8ea428f 修改错误命名属性 2022-06-24 23:09:44 +08:00
6e476e40af 新增内容编码/解码方便插件集成使用 2022-06-22 17:46:07 +08:00
25d07b11cc !395 修复导入导出时,当某字段类型为字典类型或解析类型时,如果有分隔符时无法正确解析的问题
Merge pull request !395 from jinyangaction/master
2022-06-22 09:20:38 +00:00
36013e6139 修复导入导出时,当某字段类型为字典类型或解析类型时,如果有分隔符时无法正确解析的问题 2022-06-20 22:23:05 +08:00
87d3c9a93c 升级druid到最新版本1.2.11 2022-06-14 11:30:24 +08:00
d1b3f4f397 优化druid开启wall过滤器出现的异常问题 2022-06-13 21:21:28 +08:00
5c5961f1b4 释放焦点,防止打开后按回车反复弹出(I5AA4V) 2022-06-08 19:52:07 +08:00
155 changed files with 3612 additions and 4359 deletions

View File

@ -1,11 +1,11 @@
<p align="center"> <p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-dd77653d7c9f197dd9d93684f3c8dcfbab6.png"> <img alt="logo" src="https://oscimg.oschina.net/oscnet/up-dd77653d7c9f197dd9d93684f3c8dcfbab6.png">
</p> </p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v4.7.4</h1> <h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v4.7.7</h1>
<h4 align="center">基于SpringBoot开发的轻量级Java快速开发框架</h4> <h4 align="center">基于SpringBoot开发的轻量级Java快速开发框架</h4>
<p align="center"> <p align="center">
<a href="https://gitee.com/y_project/RuoYi/stargazers"><img src="https://gitee.com/y_project/RuoYi/badge/star.svg?theme=gvp"></a> <a href="https://gitee.com/y_project/RuoYi/stargazers"><img src="https://gitee.com/y_project/RuoYi/badge/star.svg?theme=gvp"></a>
<a href="https://gitee.com/y_project/RuoYi"><img src="https://img.shields.io/badge/RuoYi-v4.7.4-brightgreen.svg"></a> <a href="https://gitee.com/y_project/RuoYi"><img src="https://img.shields.io/badge/RuoYi-v4.7.7-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a> <a href="https://gitee.com/y_project/RuoYi/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p> </p>
@ -99,4 +99,4 @@
## 若依交流群 ## 若依交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-1389287-blue.svg)](https://jq.qq.com/?_wv=1027&k=5HBAaYN) [![加入QQ群](https://img.shields.io/badge/已满-1679294-blue.svg)](https://jq.qq.com/?_wv=1027&k=5cHeRVW) [![加入QQ群](https://img.shields.io/badge/已满-1529866-blue.svg)](https://jq.qq.com/?_wv=1027&k=53R0L5Z) [![加入QQ群](https://img.shields.io/badge/已满-1772718-blue.svg)](https://jq.qq.com/?_wv=1027&k=5g75dCU) [![加入QQ群](https://img.shields.io/badge/已满-1366522-blue.svg)](https://jq.qq.com/?_wv=1027&k=58cPoHA) [![加入QQ群](https://img.shields.io/badge/已满-1382251-blue.svg)](https://jq.qq.com/?_wv=1027&k=5Ofd4Pb) [![加入QQ群](https://img.shields.io/badge/已满-1145125-blue.svg)](https://jq.qq.com/?_wv=1027&k=5yugASz) [![加入QQ群](https://img.shields.io/badge/已满-86752435-blue.svg)](https://jq.qq.com/?_wv=1027&k=5Rf3d2P) [![加入QQ群](https://img.shields.io/badge/已满-134072510-blue.svg)](https://jq.qq.com/?_wv=1027&k=5ZIjaeP) [![加入QQ群](https://img.shields.io/badge/已满-210336300-blue.svg)](https://jq.qq.com/?_wv=1027&k=5CJw1jY) [![加入QQ群](https://img.shields.io/badge/已满-339522636-blue.svg)](https://jq.qq.com/?_wv=1027&k=5omzbKc) [![加入QQ群](https://img.shields.io/badge/已满-130035985-blue.svg)](https://jq.qq.com/?_wv=1027&k=qPIKBb7s) [![加入QQ群](https://img.shields.io/badge/已满-143151071-blue.svg)](https://jq.qq.com/?_wv=1027&k=4NsjKbtU) [![加入QQ群](https://img.shields.io/badge/已满-158781320-blue.svg)](https://jq.qq.com/?_wv=1027&k=VD2pkz2G) [![加入QQ群](https://img.shields.io/badge/已满-201531282-blue.svg)](https://jq.qq.com/?_wv=1027&k=HlshFwkJ) [![加入QQ群](https://img.shields.io/badge/已满-101526938-blue.svg)](https://jq.qq.com/?_wv=1027&k=0ARRrO9V) [![加入QQ群](https://img.shields.io/badge/已满-264355400-blue.svg)](https://jq.qq.com/?_wv=1027&k=up9k3ZXJ) [![加入QQ群](https://img.shields.io/badge/已满-298522656-blue.svg)](https://jq.qq.com/?_wv=1027&k=540WfdEr) [![加入QQ群](https://img.shields.io/badge/已满-139845794-blue.svg)](https://jq.qq.com/?_wv=1027&k=ss91fC4t) [![加入QQ群](https://img.shields.io/badge/213650505-blue.svg)](https://jq.qq.com/?_wv=1027&k=uUQpdY7J) QQ群 [![加入QQ群](https://img.shields.io/badge/已满-1389287-blue.svg)](https://jq.qq.com/?_wv=1027&k=5HBAaYN) [![加入QQ群](https://img.shields.io/badge/已满-1679294-blue.svg)](https://jq.qq.com/?_wv=1027&k=5cHeRVW) [![加入QQ群](https://img.shields.io/badge/已满-1529866-blue.svg)](https://jq.qq.com/?_wv=1027&k=53R0L5Z) [![加入QQ群](https://img.shields.io/badge/已满-1772718-blue.svg)](https://jq.qq.com/?_wv=1027&k=5g75dCU) [![加入QQ群](https://img.shields.io/badge/已满-1366522-blue.svg)](https://jq.qq.com/?_wv=1027&k=58cPoHA) [![加入QQ群](https://img.shields.io/badge/已满-1382251-blue.svg)](https://jq.qq.com/?_wv=1027&k=5Ofd4Pb) [![加入QQ群](https://img.shields.io/badge/已满-1145125-blue.svg)](https://jq.qq.com/?_wv=1027&k=5yugASz) [![加入QQ群](https://img.shields.io/badge/已满-86752435-blue.svg)](https://jq.qq.com/?_wv=1027&k=5Rf3d2P) [![加入QQ群](https://img.shields.io/badge/已满-134072510-blue.svg)](https://jq.qq.com/?_wv=1027&k=5ZIjaeP) [![加入QQ群](https://img.shields.io/badge/已满-210336300-blue.svg)](https://jq.qq.com/?_wv=1027&k=5CJw1jY) [![加入QQ群](https://img.shields.io/badge/已满-339522636-blue.svg)](https://jq.qq.com/?_wv=1027&k=5omzbKc) [![加入QQ群](https://img.shields.io/badge/已满-130035985-blue.svg)](https://jq.qq.com/?_wv=1027&k=qPIKBb7s) [![加入QQ群](https://img.shields.io/badge/已满-143151071-blue.svg)](https://jq.qq.com/?_wv=1027&k=4NsjKbtU) [![加入QQ群](https://img.shields.io/badge/已满-158781320-blue.svg)](https://jq.qq.com/?_wv=1027&k=VD2pkz2G) [![加入QQ群](https://img.shields.io/badge/已满-201531282-blue.svg)](https://jq.qq.com/?_wv=1027&k=HlshFwkJ) [![加入QQ群](https://img.shields.io/badge/已满-101526938-blue.svg)](https://jq.qq.com/?_wv=1027&k=0ARRrO9V) [![加入QQ群](https://img.shields.io/badge/已满-264355400-blue.svg)](https://jq.qq.com/?_wv=1027&k=up9k3ZXJ) [![加入QQ群](https://img.shields.io/badge/已满-298522656-blue.svg)](https://jq.qq.com/?_wv=1027&k=540WfdEr) [![加入QQ群](https://img.shields.io/badge/已满-139845794-blue.svg)](https://jq.qq.com/?_wv=1027&k=ss91fC4t) [![加入QQ群](https://img.shields.io/badge/已满-185760789-blue.svg)](https://jq.qq.com/?_wv=1027&k=Cqd66IKe) [![加入QQ群](https://img.shields.io/badge/175104288-blue.svg)](https://jq.qq.com/?_wv=1027&k=7FplYUnR)

32
pom.xml
View File

@ -5,30 +5,28 @@
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>4.7.4</version> <version>4.7.7</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.7.4</ruoyi.version> <ruoyi.version>4.7.7</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>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<shiro.version>1.9.0</shiro.version> <shiro.version>1.10.1</shiro.version>
<thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version> <thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
<druid.version>1.2.8</druid.version> <druid.version>1.2.16</druid.version>
<bitwalker.version>1.21</bitwalker.version> <bitwalker.version>1.21</bitwalker.version>
<kaptcha.version>2.3.2</kaptcha.version> <kaptcha.version>2.3.3</kaptcha.version>
<swagger.version>3.0.0</swagger.version> <swagger.version>3.0.0</swagger.version>
<mybatis-spring-boot.version>2.2.2</mybatis-spring-boot.version> <pagehelper.boot.version>1.4.6</pagehelper.boot.version>
<pagehelper.boot.version>1.4.1</pagehelper.boot.version>
<fastjson.version>1.2.83</fastjson.version> <fastjson.version>1.2.83</fastjson.version>
<oshi.version>6.1.6</oshi.version> <oshi.version>6.4.1</oshi.version>
<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>
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version> <velocity.version>2.3</velocity.version>
</properties> </properties>
@ -55,7 +53,7 @@
<!-- 验证码 --> <!-- 验证码 -->
<dependency> <dependency>
<groupId>com.github.penggle</groupId> <groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId> <artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version> <version>${kaptcha.version}</version>
</dependency> </dependency>
@ -95,13 +93,6 @@
<version>${bitwalker.version}</version> <version>${bitwalker.version}</version>
</dependency> </dependency>
<!-- SpringBoot集成mybatis框架 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot.version}</version>
</dependency>
<!-- pagehelper 分页插件 --> <!-- pagehelper 分页插件 -->
<dependency> <dependency>
<groupId>com.github.pagehelper</groupId> <groupId>com.github.pagehelper</groupId>
@ -136,13 +127,6 @@
<version>${commons.io.version}</version> <version>${commons.io.version}</version>
</dependency> </dependency>
<!-- 文件上传工具类 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons.fileupload.version}</version>
</dependency>
<!-- excel工具 --> <!-- excel工具 -->
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>

View File

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

View File

@ -62,6 +62,15 @@ public class DemoFormController
return prefix + "/timeline"; return prefix + "/timeline";
} }
/**
* 进度条
*/
@GetMapping("/progress_bars")
public String progress_bars()
{
return prefix + "/progress_bars";
}
/** /**
* 表单校验 * 表单校验
*/ */

View File

@ -506,8 +506,8 @@ public class DemoTableController extends BaseController
} }
} }
PageDomain pageDomain = TableSupport.buildPageRequest(); PageDomain pageDomain = TableSupport.buildPageRequest();
Integer pageNum = (pageDomain.getPageNum() - 1) * 10; Integer pageNum = (pageDomain.getPageNum() - 1) * pageDomain.getPageSize();
Integer pageSize = pageDomain.getPageNum() * 10; Integer pageSize = pageDomain.getPageNum() * pageDomain.getPageSize();
if (pageSize > areaList.size()) if (pageSize > areaList.size())
{ {
pageSize = areaList.size(); pageSize = areaList.size();

View File

@ -47,7 +47,7 @@ public class CacheController extends BaseController
public String getCacheKeys(String fragment, String cacheName, ModelMap mmap) public String getCacheKeys(String fragment, String cacheName, ModelMap mmap)
{ {
mmap.put("cacheName", cacheName); mmap.put("cacheName", cacheName);
mmap.put("cacheKyes", cacheService.getCacheKeys(cacheName)); mmap.put("cacheKeys", cacheService.getCacheKeys(cacheName));
return prefix + "/cache::" + fragment; return prefix + "/cache::" + fragment;
} }

View File

@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
@ -84,7 +83,7 @@ public class SysConfigController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult addSave(@Validated SysConfig config) public AjaxResult addSave(@Validated SysConfig config)
{ {
if (UserConstants.CONFIG_KEY_NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) if (!configService.checkConfigKeyUnique(config))
{ {
return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
} }
@ -112,7 +111,7 @@ public class SysConfigController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult editSave(@Validated SysConfig config) public AjaxResult editSave(@Validated SysConfig config)
{ {
if (UserConstants.CONFIG_KEY_NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) if (!configService.checkConfigKeyUnique(config))
{ {
return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
} }
@ -151,7 +150,7 @@ public class SysConfigController extends BaseController
*/ */
@PostMapping("/checkConfigKeyUnique") @PostMapping("/checkConfigKeyUnique")
@ResponseBody @ResponseBody
public String checkConfigKeyUnique(SysConfig config) public boolean checkConfigKeyUnique(SysConfig config)
{ {
return configService.checkConfigKeyUnique(config); return configService.checkConfigKeyUnique(config);
} }

View File

@ -17,7 +17,6 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree; import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysDeptService; import com.ruoyi.system.service.ISysDeptService;
@ -75,7 +74,7 @@ public class SysDeptController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult addSave(@Validated SysDept dept) public AjaxResult addSave(@Validated SysDept dept)
{ {
if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) if (!deptService.checkDeptNameUnique(dept))
{ {
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
} }
@ -111,7 +110,7 @@ public class SysDeptController extends BaseController
{ {
Long deptId = dept.getDeptId(); Long deptId = dept.getDeptId();
deptService.checkDeptDataScope(deptId); deptService.checkDeptDataScope(deptId);
if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) if (!deptService.checkDeptNameUnique(dept))
{ {
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
} }
@ -153,7 +152,7 @@ public class SysDeptController extends BaseController
*/ */
@PostMapping("/checkDeptNameUnique") @PostMapping("/checkDeptNameUnique")
@ResponseBody @ResponseBody
public String checkDeptNameUnique(SysDept dept) public boolean checkDeptNameUnique(SysDept dept)
{ {
return deptService.checkDeptNameUnique(dept); return deptService.checkDeptNameUnique(dept);
} }
@ -166,24 +165,13 @@ public class SysDeptController extends BaseController
*/ */
@GetMapping(value = { "/selectDeptTree/{deptId}", "/selectDeptTree/{deptId}/{excludeId}" }) @GetMapping(value = { "/selectDeptTree/{deptId}", "/selectDeptTree/{deptId}/{excludeId}" })
public String selectDeptTree(@PathVariable("deptId") Long deptId, public String selectDeptTree(@PathVariable("deptId") Long deptId,
@PathVariable(value = "excludeId", required = false) String excludeId, ModelMap mmap) @PathVariable(value = "excludeId", required = false) Long excludeId, ModelMap mmap)
{ {
mmap.put("dept", deptService.selectDeptById(deptId)); mmap.put("dept", deptService.selectDeptById(deptId));
mmap.put("excludeId", excludeId); mmap.put("excludeId", excludeId);
return prefix + "/tree"; return prefix + "/tree";
} }
/**
* 加载部门列表树
*/
@GetMapping("/treeData")
@ResponseBody
public List<Ztree> treeData()
{
List<Ztree> ztrees = deptService.selectDeptTree(new SysDept());
return ztrees;
}
/** /**
* 加载部门列表树(排除下级) * 加载部门列表树(排除下级)
*/ */
@ -196,15 +184,4 @@ public class SysDeptController extends BaseController
List<Ztree> ztrees = deptService.selectDeptTreeExcludeChild(dept); List<Ztree> ztrees = deptService.selectDeptTreeExcludeChild(dept);
return ztrees; return ztrees;
} }
/**
* 加载角色部门(数据权限)列表树
*/
@GetMapping("/roleDeptTreeData")
@ResponseBody
public List<Ztree> deptTreeData(SysRole role)
{
List<Ztree> ztrees = deptService.roleDeptTreeData(role);
return ztrees;
}
} }

View File

@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree; import com.ruoyi.common.core.domain.Ztree;
@ -83,7 +82,7 @@ public class SysDictTypeController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult addSave(@Validated SysDictType dict) public AjaxResult addSave(@Validated SysDictType dict)
{ {
if (UserConstants.DICT_TYPE_NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) if (!dictTypeService.checkDictTypeUnique(dict))
{ {
return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
} }
@ -111,7 +110,7 @@ public class SysDictTypeController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult editSave(@Validated SysDictType dict) public AjaxResult editSave(@Validated SysDictType dict)
{ {
if (UserConstants.DICT_TYPE_NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) if (!dictTypeService.checkDictTypeUnique(dict))
{ {
return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
} }
@ -159,7 +158,7 @@ public class SysDictTypeController extends BaseController
*/ */
@PostMapping("/checkDictTypeUnique") @PostMapping("/checkDictTypeUnique")
@ResponseBody @ResponseBody
public String checkDictTypeUnique(SysDictType dictType) public boolean checkDictTypeUnique(SysDictType dictType)
{ {
return dictTypeService.checkDictTypeUnique(dictType); return dictTypeService.checkDictTypeUnique(dictType);
} }

View File

@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree; import com.ruoyi.common.core.domain.Ztree;
@ -105,7 +104,7 @@ public class SysMenuController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult addSave(@Validated SysMenu menu) public AjaxResult addSave(@Validated SysMenu menu)
{ {
if (UserConstants.MENU_NAME_NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) if (!menuService.checkMenuNameUnique(menu))
{ {
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} }
@ -134,7 +133,7 @@ public class SysMenuController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult editSave(@Validated SysMenu menu) public AjaxResult editSave(@Validated SysMenu menu)
{ {
if (UserConstants.MENU_NAME_NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) if (!menuService.checkMenuNameUnique(menu))
{ {
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} }
@ -157,7 +156,7 @@ public class SysMenuController extends BaseController
*/ */
@PostMapping("/checkMenuNameUnique") @PostMapping("/checkMenuNameUnique")
@ResponseBody @ResponseBody
public String checkMenuNameUnique(SysMenu menu) public boolean checkMenuNameUnique(SysMenu menu)
{ {
return menuService.checkMenuNameUnique(menu); return menuService.checkMenuNameUnique(menu);
} }

View File

@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
@ -97,11 +96,11 @@ public class SysPostController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult addSave(@Validated SysPost post) public AjaxResult addSave(@Validated SysPost post)
{ {
if (UserConstants.POST_NAME_NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) if (!postService.checkPostNameUnique(post))
{ {
return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
} }
else if (UserConstants.POST_CODE_NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) else if (!postService.checkPostCodeUnique(post))
{ {
return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
} }
@ -129,11 +128,11 @@ public class SysPostController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult editSave(@Validated SysPost post) public AjaxResult editSave(@Validated SysPost post)
{ {
if (UserConstants.POST_NAME_NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) if (!postService.checkPostNameUnique(post))
{ {
return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
} }
else if (UserConstants.POST_CODE_NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) else if (!postService.checkPostCodeUnique(post))
{ {
return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
} }
@ -146,7 +145,7 @@ public class SysPostController extends BaseController
*/ */
@PostMapping("/checkPostNameUnique") @PostMapping("/checkPostNameUnique")
@ResponseBody @ResponseBody
public String checkPostNameUnique(SysPost post) public boolean checkPostNameUnique(SysPost post)
{ {
return postService.checkPostNameUnique(post); return postService.checkPostNameUnique(post);
} }
@ -156,7 +155,7 @@ public class SysPostController extends BaseController
*/ */
@PostMapping("/checkPostCodeUnique") @PostMapping("/checkPostCodeUnique")
@ResponseBody @ResponseBody
public String checkPostCodeUnique(SysPost post) public boolean checkPostCodeUnique(SysPost post)
{ {
return postService.checkPostCodeUnique(post); return postService.checkPostCodeUnique(post);
} }

View File

@ -13,7 +13,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
@ -63,11 +62,7 @@ public class SysProfileController extends BaseController
public boolean checkPassword(String password) public boolean checkPassword(String password)
{ {
SysUser user = getSysUser(); SysUser user = getSysUser();
if (passwordService.matches(user, password)) return passwordService.matches(user, password);
{
return true;
}
return false;
} }
@GetMapping("/resetPwd") @GetMapping("/resetPwd")
@ -138,13 +133,11 @@ public class SysProfileController extends BaseController
currentUser.setEmail(user.getEmail()); currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber()); currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setSex(user.getSex()); currentUser.setSex(user.getSex());
if (StringUtils.isNotEmpty(user.getPhonenumber()) if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
&& UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(currentUser)))
{ {
return error("修改用户'" + currentUser.getLoginName() + "'失败,手机号码已存在"); return error("修改用户'" + currentUser.getLoginName() + "'失败,手机号码已存在");
} }
else if (StringUtils.isNotEmpty(user.getEmail()) else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
&& UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(currentUser)))
{ {
return error("修改用户'" + currentUser.getLoginName() + "'失败,邮箱账号已存在"); return error("修改用户'" + currentUser.getLoginName() + "'失败,邮箱账号已存在");
} }

View File

@ -12,9 +12,9 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
@ -22,6 +22,7 @@ import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.util.AuthorizationUtils; import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.domain.SysUserRole; import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
@ -42,6 +43,9 @@ public class SysRoleController extends BaseController
@Autowired @Autowired
private ISysUserService userService; private ISysUserService userService;
@Autowired
private ISysDeptService deptService;
@RequiresPermissions("system:role:view") @RequiresPermissions("system:role:view")
@GetMapping() @GetMapping()
public String role() public String role()
@ -88,11 +92,11 @@ public class SysRoleController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult addSave(@Validated SysRole role) public AjaxResult addSave(@Validated SysRole role)
{ {
if (UserConstants.ROLE_NAME_NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) if (!roleService.checkRoleNameUnique(role))
{ {
return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
} }
else if (UserConstants.ROLE_KEY_NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) else if (!roleService.checkRoleKeyUnique(role))
{ {
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
} }
@ -125,11 +129,11 @@ public class SysRoleController extends BaseController
{ {
roleService.checkRoleAllowed(role); roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId()); roleService.checkRoleDataScope(role.getRoleId());
if (UserConstants.ROLE_NAME_NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) if (!roleService.checkRoleNameUnique(role))
{ {
return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
} }
else if (UserConstants.ROLE_KEY_NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) else if (!roleService.checkRoleKeyUnique(role))
{ {
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
} }
@ -182,7 +186,7 @@ public class SysRoleController extends BaseController
*/ */
@PostMapping("/checkRoleNameUnique") @PostMapping("/checkRoleNameUnique")
@ResponseBody @ResponseBody
public String checkRoleNameUnique(SysRole role) public boolean checkRoleNameUnique(SysRole role)
{ {
return roleService.checkRoleNameUnique(role); return roleService.checkRoleNameUnique(role);
} }
@ -192,7 +196,7 @@ public class SysRoleController extends BaseController
*/ */
@PostMapping("/checkRoleKeyUnique") @PostMapping("/checkRoleKeyUnique")
@ResponseBody @ResponseBody
public String checkRoleKeyUnique(SysRole role) public boolean checkRoleKeyUnique(SysRole role)
{ {
return roleService.checkRoleKeyUnique(role); return roleService.checkRoleKeyUnique(role);
} }
@ -303,4 +307,16 @@ public class SysRoleController extends BaseController
roleService.checkRoleDataScope(roleId); roleService.checkRoleDataScope(roleId);
return toAjax(roleService.insertAuthUsers(roleId, userIds)); return toAjax(roleService.insertAuthUsers(roleId, userIds));
} }
/**
* 加载角色部门(数据权限)列表树
*/
@RequiresPermissions("system:role:edit")
@GetMapping("/deptTreeData")
@ResponseBody
public List<Ztree> deptTreeData(SysRole role)
{
List<Ztree> ztrees = deptService.roleDeptTreeData(role);
return ztrees;
}
} }

View File

@ -15,9 +15,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
@ -28,6 +29,7 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.service.SysPasswordService; import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.shiro.util.AuthorizationUtils; import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService; import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
@ -49,6 +51,9 @@ public class SysUserController extends BaseController
@Autowired @Autowired
private ISysRoleService roleService; private ISysRoleService roleService;
@Autowired
private ISysDeptService deptService;
@Autowired @Autowired
private ISysPostService postService; private ISysPostService postService;
@ -124,17 +129,15 @@ public class SysUserController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult addSave(@Validated SysUser user) public AjaxResult addSave(@Validated SysUser user)
{ {
if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user.getLoginName()))) if (!userService.checkLoginNameUnique(user))
{ {
return error("新增用户'" + user.getLoginName() + "'失败,登录账号已存在"); return error("新增用户'" + user.getLoginName() + "'失败,登录账号已存在");
} }
else if (StringUtils.isNotEmpty(user.getPhonenumber()) else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
&& UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{ {
return error("新增用户'" + user.getLoginName() + "'失败,手机号码已存在"); return error("新增用户'" + user.getLoginName() + "'失败,手机号码已存在");
} }
else if (StringUtils.isNotEmpty(user.getEmail()) else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
&& UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
{ {
return error("新增用户'" + user.getLoginName() + "'失败,邮箱账号已存在"); return error("新增用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
} }
@ -170,13 +173,15 @@ public class SysUserController extends BaseController
{ {
userService.checkUserAllowed(user); userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId()); userService.checkUserDataScope(user.getUserId());
if (StringUtils.isNotEmpty(user.getPhonenumber()) if (!userService.checkLoginNameUnique(user))
&& UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
return error("修改用户'" + user.getLoginName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{ {
return error("修改用户'" + user.getLoginName() + "'失败,手机号码已存在"); return error("修改用户'" + user.getLoginName() + "'失败,手机号码已存在");
} }
else if (StringUtils.isNotEmpty(user.getEmail()) else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
&& UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
{ {
return error("修改用户'" + user.getLoginName() + "'失败,邮箱账号已存在"); return error("修改用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
} }
@ -261,9 +266,9 @@ public class SysUserController extends BaseController
*/ */
@PostMapping("/checkLoginNameUnique") @PostMapping("/checkLoginNameUnique")
@ResponseBody @ResponseBody
public String checkLoginNameUnique(SysUser user) public boolean checkLoginNameUnique(SysUser user)
{ {
return userService.checkLoginNameUnique(user.getLoginName()); return userService.checkLoginNameUnique(user);
} }
/** /**
@ -271,7 +276,7 @@ public class SysUserController extends BaseController
*/ */
@PostMapping("/checkPhoneUnique") @PostMapping("/checkPhoneUnique")
@ResponseBody @ResponseBody
public String checkPhoneUnique(SysUser user) public boolean checkPhoneUnique(SysUser user)
{ {
return userService.checkPhoneUnique(user); return userService.checkPhoneUnique(user);
} }
@ -281,7 +286,7 @@ public class SysUserController extends BaseController
*/ */
@PostMapping("/checkEmailUnique") @PostMapping("/checkEmailUnique")
@ResponseBody @ResponseBody
public String checkEmailUnique(SysUser user) public boolean checkEmailUnique(SysUser user)
{ {
return userService.checkEmailUnique(user); return userService.checkEmailUnique(user);
} }
@ -299,4 +304,29 @@ public class SysUserController extends BaseController
userService.checkUserDataScope(user.getUserId()); userService.checkUserDataScope(user.getUserId());
return toAjax(userService.changeStatus(user)); return toAjax(userService.changeStatus(user));
} }
/**
* 加载部门列表树
*/
@RequiresPermissions("system:user:list")
@GetMapping("/deptTreeData")
@ResponseBody
public List<Ztree> deptTreeData()
{
List<Ztree> ztrees = deptService.selectDeptTree(new SysDept());
return ztrees;
}
/**
* 选择部门树
*
* @param deptId 部门ID
*/
@RequiresPermissions("system:user:list")
@GetMapping("/selectDeptTree/{deptId}")
public String selectDeptTree(@PathVariable("deptId") Long deptId, ModelMap mmap)
{
mmap.put("dept", deptService.selectDeptById(deptId));
return prefix + "/deptTree";
}
} }

View File

@ -24,6 +24,10 @@ spring:
maxActive: 20 maxActive: 20
# 配置获取连接等待超时的时间 # 配置获取连接等待超时的时间
maxWait: 60000 maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000 timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒 # 配置一个连接在池中最小生存的时间,单位是毫秒

View File

@ -3,9 +3,9 @@ ruoyi:
# 名称 # 名称
name: RuoYi name: RuoYi
# 版本 # 版本
version: 4.7.4 version: 4.7.7
# 版权年份 # 版权年份
copyrightYear: 2022 copyrightYear: 2023
# 实例演示开关 # 实例演示开关
demoEnabled: true demoEnabled: true
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath # 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath

View File

@ -1,11 +1,11 @@
/*! /*!
* bootstrap-fileinput v5.2.4 * bootstrap-fileinput v5.5.2
* http://plugins.krajee.com/file-input * http://plugins.krajee.com/file-input
* *
* Krajee default styling for bootstrap-fileinput. * Krajee default styling for bootstrap-fileinput.
* *
* Author: Kartik Visweswaran * Author: Kartik Visweswaran
* Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com * Copyright: 2014 - 2022, Kartik Visweswaran, Krajee.com
* *
* Licensed under the BSD-3-Clause * Licensed under the BSD-3-Clause
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
@ -50,6 +50,10 @@ input[type=file].file-loading {
display: none; display: none;
} }
.file-caption .input-group {
align-items: center;
}
.btn-file input[type=file], .btn-file input[type=file],
.file-caption-icon, .file-caption-icon,
.file-preview .fileinput-remove, .file-preview .fileinput-remove,
@ -274,6 +278,7 @@ input[type=file].file-loading {
padding: 6px; padding: 6px;
float: left; float: left;
text-align: center; text-align: center;
} }
.krajee-default.file-preview-frame .kv-file-content { .krajee-default.file-preview-frame .kv-file-content {
@ -281,12 +286,6 @@ input[type=file].file-loading {
height: 160px; height: 160px;
} }
.krajee-default .file-preview-other-frame {
display: flex;
align-items: center;
justify-content: center;
}
.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered { .krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered {
width: 400px; width: 400px;
} }
@ -330,7 +329,7 @@ input[type=file].file-loading {
text-align: center; text-align: center;
padding-top: 4px; padding-top: 4px;
font-size: 11px; font-size: 11px;
color: #777; color: #999;
margin-bottom: 30px; margin-bottom: 30px;
} }
@ -406,7 +405,7 @@ input[type=file].file-loading {
height: 2.4rem; height: 2.4rem;
top: 50%; top: 50%;
border-radius: 50%; border-radius: 50%;
text-align:center; text-align: center;
} }
.btn-navigate * { .btn-navigate * {
@ -426,19 +425,12 @@ input[type=file].file-loading {
right: 0; right: 0;
} }
.file-zoom-dialog .kv-zoom-caption {
max-width: 50%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.file-zoom-dialog .kv-zoom-header { .file-zoom-dialog .kv-zoom-header {
padding: 0.5rem; padding: 0.5rem;
} }
.file-zoom-dialog .kv-zoom-body { .file-zoom-dialog .kv-zoom-body {
padding: 0.25rem 0.5rem 0.25rem 0; padding: 0.25rem;
} }
.file-zoom-dialog .kv-zoom-description { .file-zoom-dialog .kv-zoom-description {
@ -554,6 +546,10 @@ input[type=file].file-loading {
z-index: 3000; z-index: 3000;
} }
.kv-zoom-actions {
min-width: 140px;
}
.kv-zoom-actions .btn-kv { .kv-zoom-actions .btn-kv {
margin-left: 3px; margin-left: 3px;
} }
@ -568,15 +564,6 @@ input[type=file].file-loading {
background: transparent; background: transparent;
} }
.file-zoom-content > * {
display: inline-block;
vertical-align: middle;
}
.file-zoom-content .kv-spacer {
height: 100%;
}
.file-zoom-content .file-preview-image { .file-zoom-content .file-preview-image {
max-height: 100%; max-height: 100%;
} }
@ -669,3 +656,33 @@ input[type=file].file-loading {
.file-preview .kv-zoom-cache { .file-preview .kv-zoom-cache {
display: none; display: none;
} }
.file-preview-other-frame, .file-preview-object, .kv-file-content, .kv-zoom-body {
display: flex;
align-items: center;
justify-content: center;
}
.btn-kv-rotate,
.kv-file-rotate {
display: none;
}
.rotatable:not(.hide-rotate) .btn-kv-rotate,
.rotatable:not(.hide-rotate) .kv-file-rotate {
display: inline-block;
}
.rotatable .file-zoom-detail,
.rotatable .kv-file-content,
.rotatable .kv-file-content > :first-child {
transform-origin: center center;
}
.rotate-animate {
transition: transform 0.3s ease;
}
.kv-overflow-hidden {
overflow: hidden;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -187,6 +187,7 @@
success: function(data, textStatus, jqXHR) { success: function(data, textStatus, jqXHR) {
data = calculateObjectValue(options, options.responseHandler, [data], data); data = calculateObjectValue(options, options.responseHandler, [data], data);
renderTable(data); renderTable(data);
calculateObjectValue(options, options.onLoadSuccess, [data], data);
}, },
error: function(xhr, textStatus) { error: function(xhr, textStatus) {
var _errorMsg = '<tr><td colspan="' + options.columns.length + '"><div style="display: block;text-align: center;">' + xhr.responseText + '</div></td></tr>' var _errorMsg = '<tr><td colspan="' + options.columns.length + '"><div style="display: block;text-align: center;">' + xhr.responseText + '</div></td></tr>'
@ -697,7 +698,8 @@
if (_ls && _ls.length > 0) { if (_ls && _ls.length > 0) {
$.each(_ls, function(index, item) { $.each(_ls, function(index, item) {
var _p_icon = $("#" + $(item).attr("pid")).children().eq(options.expandColumn).find(".treetable-expander"); var _p_icon = $("#" + $(item).attr("pid")).children().eq(options.expandColumn).find(".treetable-expander");
if (_p_icon.hasClass(options.expanderExpandedClass)) { var _p_display = $("#" + $(item).attr("pid")).css('display');
if (_p_icon.hasClass(options.expanderExpandedClass) && _p_display == 'table') {
$(item).css("display", "table"); $(item).css("display", "table");
} }
}); });
@ -728,7 +730,7 @@
$.ajax({ $.ajax({
type: options.type, type: options.type,
url: options.dataUrl, url: options.dataUrl,
data: $.extend(parms, options.ajaxParams), data: parms,
dataType: "json", dataType: "json",
success: function(data, textStatus, jqXHR) { success: function(data, textStatus, jqXHR) {
$("#" + row_id + "_load").remove(); $("#" + row_id + "_load").remove();
@ -764,6 +766,7 @@
} }
// 添加数据刷新表格 // 添加数据刷新表格
target.appendData = function(data) { target.appendData = function(data) {
data.reverse()
// 下边的操作主要是为了查询时让一些没有根节点的节点显示 // 下边的操作主要是为了查询时让一些没有根节点的节点显示
$.each(data, function(i, item) { $.each(data, function(i, item) {
if (options.pagination) { if (options.pagination) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,6 +8,7 @@ user.password.retry.limit.exceed=密码输入错误{0}次帐户锁定10分钟
user.password.delete=对不起,您的账号已被删除 user.password.delete=对不起,您的账号已被删除
user.blocked=用户已封禁,请联系管理员 user.blocked=用户已封禁,请联系管理员
role.blocked=角色已封禁,请联系管理员 role.blocked=角色已封禁,请联系管理员
login.blocked=很遗憾访问IP已被列入系统黑名单
user.logout.success=退出成功 user.logout.success=退出成功
length.not.valid=长度必须在{min}到{max}个字符之间 length.not.valid=长度必须在{min}到{max}个字符之间

File diff suppressed because one or more lines are too long

View File

@ -1,120 +1,10 @@
/* /*
* metismenu - v1.1.3 * metismenu - v2.0.2
* Easy menu jQuery plugin for Twitter Bootstrap 3 * A jQuery menu plugin
* https://github.com/onokumus/metisMenu * https://github.com/onokumus/metisMenu
* *
* Made by Osman Nuri Okumus * Made by Osman Nuri Okumus
* Under MIT License * Under MIT License
*/ */
;(function($, window, document, undefined) {
var pluginName = "metisMenu", !function(a){"use strict";function b(){var a=document.createElement("mm"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}function c(b){return this.each(function(){var c=a(this),d=c.data("mm"),f=a.extend({},e.DEFAULTS,c.data(),"object"==typeof b&&b);d||c.data("mm",d=new e(this,f)),"string"==typeof b&&d[b]()})}a.fn.emulateTransitionEnd=function(b){var c=!1,e=this;a(this).one("mmTransitionEnd",function(){c=!0});var f=function(){c||a(e).trigger(d.end)};return setTimeout(f,b),this};var d=b();d&&(a.event.special.mmTransitionEnd={bindType:d.end,delegateType:d.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}});var e=function(b,c){this.$element=a(b),this.options=a.extend({},e.DEFAULTS,c),this.transitioning=null,this.init()};e.TRANSITION_DURATION=350,e.DEFAULTS={toggle:!0,doubleTapToGo:!1,activeClass:"active"},e.prototype.init=function(){var b=this,c=this.options.activeClass;this.$element.find("li."+c).has("ul").children("ul").addClass("collapse in"),this.$element.find("li").not("."+c).has("ul").children("ul").addClass("collapse"),this.options.doubleTapToGo&&this.$element.find("li."+c).has("ul").children("a").addClass("doubleTapToGo"),this.$element.find("li").has("ul").children("a").on("click.metisMenu",function(d){var e=a(this),f=e.parent("li"),g=f.children("ul");return d.preventDefault(),f.hasClass(c)?b.hide(g):b.show(g),b.options.doubleTapToGo&&b.doubleTapToGo(e)&&"#"!==e.attr("href")&&""!==e.attr("href")?(d.stopPropagation(),void(document.location=e.attr("href"))):void 0})},e.prototype.doubleTapToGo=function(a){var b=this.$element;return a.hasClass("doubleTapToGo")?(a.removeClass("doubleTapToGo"),!0):a.parent().children("ul").length?(b.find(".doubleTapToGo").removeClass("doubleTapToGo"),a.addClass("doubleTapToGo"),!1):void 0},e.prototype.show=function(b){var c=this.options.activeClass,f=a(b),g=f.parent("li");if(!this.transitioning&&!f.hasClass("in")){g.addClass(c),this.options.toggle&&this.hide(g.siblings().children("ul.in")),f.removeClass("collapse").addClass("collapsing").height(0),this.transitioning=1;var h=function(){f.removeClass("collapsing").addClass("collapse in").height(""),this.transitioning=0};return d?void f.one("mmTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(e.TRANSITION_DURATION).height(f[0].scrollHeight):h.call(this)}},e.prototype.hide=function(b){var c=this.options.activeClass,f=a(b);if(!this.transitioning&&f.hasClass("in")){f.parent("li").removeClass(c),f.height(f.height())[0].offsetHeight,f.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var g=function(){this.transitioning=0,f.removeClass("collapsing").addClass("collapse")};return d?void f.height(0).one("mmTransitionEnd",a.proxy(g,this)).emulateTransitionEnd(e.TRANSITION_DURATION):g.call(this)}};var f=a.fn.metisMenu;a.fn.metisMenu=c,a.fn.metisMenu.Constructor=e,a.fn.metisMenu.noConflict=function(){return a.fn.metisMenu=f,this}}(jQuery);
defaults = {
toggle: true,
doubleTapToGo: false
};
function Plugin(element, options) {
this.element = $(element);
this.settings = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init: function() {
var $this = this.element,
$toggle = this.settings.toggle,
obj = this;
if (this.isIE() <= 9) {
$this.find("li.active").has("ul").children("ul").collapse("show");
$this.find("li").not(".active").has("ul").children("ul").collapse("hide");
} else {
$this.find("li.active").has("ul").children("ul").addClass("collapse in");
$this.find("li").not(".active").has("ul").children("ul").addClass("collapse");
}
//add the "doubleTapToGo" class to active items if needed
if (obj.settings.doubleTapToGo) {
$this.find("li.active").has("ul").children("a").addClass("doubleTapToGo");
}
$this.find("li").has("ul").children("a").on("click" + "." + pluginName, function(e) {
e.preventDefault();
//Do we need to enable the double tap
if (obj.settings.doubleTapToGo) {
//if we hit a second time on the link and the href is valid, navigate to that url
if (obj.doubleTapToGo($(this)) && $(this).attr("href") !== "#" && $(this).attr("href") !== "") {
e.stopPropagation();
document.location = $(this).attr("href");
return;
}
}
$(this).parent("li").toggleClass("active").children("ul").collapse("toggle");
if ($toggle) {
$(this).parent("li").siblings().removeClass("active").children("ul.in").collapse("hide");
}
});
},
isIE: function() { //https://gist.github.com/padolsey/527683
var undef,
v = 3,
div = document.createElement("div"),
all = div.getElementsByTagName("i");
while (
div.innerHTML = "<!--[if gt IE " + (++v) + "]><i></i><![endif]-->",
all[0]
) {
return v > 4 ? v : undef;
}
},
//Enable the link on the second click.
doubleTapToGo: function(elem) {
var $this = this.element;
//if the class "doubleTapToGo" exists, remove it and return
if (elem.hasClass("doubleTapToGo")) {
elem.removeClass("doubleTapToGo");
return true;
}
//does not exists, add a new class and return false
if (elem.parent().children("ul").length) {
//first remove all other class
$this.find(".doubleTapToGo").removeClass("doubleTapToGo");
//add the class on the current element
elem.addClass("doubleTapToGo");
return false;
}
},
remove: function() {
this.element.off("." + pluginName);
this.element.removeData(pluginName);
}
};
$.fn[pluginName] = function(options) {
this.each(function () {
var el = $(this);
if (el.data(pluginName)) {
el.data(pluginName).remove();
}
el.data(pluginName, new Plugin(this, options));
});
return this;
};
})(jQuery, window, document);

View File

@ -338,7 +338,7 @@ label.error {
.input-group label.error { .input-group label.error {
z-index:99; z-index:99;
right: 42px right: 42px;
} }
.input-group input.error + label.error + .input-group-addon>i { .input-group input.error + label.error + .input-group-addon>i {
@ -347,10 +347,14 @@ label.error {
.input-group.date label.error { .input-group.date label.error {
z-index:99; z-index:99;
right: 42px right: 42px;
} }
.Validform_error,input.error,textarea.error,select.error { .select2-hidden-accessible + label.error {
right: 38px;
}
.Validform_error,input.error,textarea.error,select.error,label.error+.select2-container--bootstrap .select2-selection--single {
background-color: #fbe2e2; background-color: #fbe2e2;
border-color: #c66161; border-color: #c66161;
color: #c00 color: #c00

View File

@ -262,7 +262,7 @@ $(function() {
// 获取标识数据 // 获取标识数据
var dataUrl = $(this).attr('href'), var dataUrl = $(this).attr('href'),
dataIndex = $(this).data('index'), dataIndex = $(this).data('index'),
menuName = $.trim($(this).text()), menuName = $(this).data('title') || $.trim($(this).text()),
isRefresh = $(this).data("refresh"), isRefresh = $(this).data("refresh"),
flag = true; flag = true;
@ -306,7 +306,7 @@ $(function() {
$('.menuTab').removeClass('active'); $('.menuTab').removeClass('active');
// 添加选项卡对应的iframe // 添加选项卡对应的iframe
var str1 = '<iframe class="RuoYi_iframe" name="iframe' + dataIndex + '" width="100%" height="100%" src="' + dataUrl + '" frameborder="0" data-id="' + dataUrl + '" seamless></iframe>'; var str1 = '<iframe class="RuoYi_iframe" name="iframe' + dataIndex + '" width="100%" height="100%" src="' + dataUrl + '" frameborder="0" data-id="' + dataUrl + '" data-refresh="' + isRefresh + '" seamless></iframe>';
$('.mainContent').find('iframe.RuoYi_iframe').hide().parents('.mainContent').append(str1); $('.mainContent').find('iframe.RuoYi_iframe').hide().parents('.mainContent').append(str1);
$.modal.loading("数据加载中,请稍候..."); $.modal.loading("数据加载中,请稍候...");
@ -434,15 +434,20 @@ $(function() {
function activeTab() { function activeTab() {
if (!$(this).hasClass('active')) { if (!$(this).hasClass('active')) {
var currentId = $(this).data('id'); var currentId = $(this).data('id');
var isRefresh = false;
syncMenuTab(currentId); syncMenuTab(currentId);
// 显示tab对应的内容区 // 显示tab对应的内容区
$('.mainContent .RuoYi_iframe').each(function() { $('.mainContent .RuoYi_iframe').each(function() {
if ($(this).data('id') == currentId) { if ($(this).data('id') == currentId) {
$(this).show().siblings('.RuoYi_iframe').hide(); $(this).show().siblings('.RuoYi_iframe').hide();
isRefresh = $.common.nullToDefault($(this).data('refresh'), false);
return false; return false;
} }
}); });
$(this).addClass('active').siblings('.menuTab').removeClass('active'); $(this).addClass('active').siblings('.menuTab').removeClass('active');
if (isRefresh) {
refreshTab();
}
scrollToTab(this); scrollToTab(this);
} }
} }

View File

@ -68,6 +68,7 @@ $(function() {
endLayDate.config.min.month = ''; endLayDate.config.min.month = '';
endLayDate.config.min.date = ''; endLayDate.config.min.date = '';
} }
$('#endTime').trigger('click');
} }
}); });
endLayDate = laydate.render({ endLayDate = laydate.render({
@ -383,6 +384,32 @@ function checkpwd(chrtype, password) {
return true; return true;
} }
/** 开始时间/时分秒 */
function beginOfTime(date) {
if($.common.isNotEmpty(date)) {
return $.common.sprintf("%s 00:00:00", date);
}
}
/** 结束时间/时分秒 */
function endOfTime(date) {
if($.common.isNotEmpty(date)) {
return $.common.sprintf("%s 23:59:59", date);
}
}
/** 重置日期/年月日 */
function resetDate() {
if ($.common.isNotEmpty(startLayDate) && $.common.isNotEmpty(endLayDate)) {
endLayDate.config.min.year = '';
endLayDate.config.min.month = '';
endLayDate.config.min.date = '';
startLayDate.config.max.year = '2099';
startLayDate.config.max.month = '12';
startLayDate.config.max.date = '31';
}
}
// 日志打印封装处理 // 日志打印封装处理
var log = { var log = {
log: function(msg) { log: function(msg) {
@ -428,7 +455,7 @@ var sub = {
var data = $("#" + table.options.id).bootstrapTable('getData'); var data = $("#" + table.options.id).bootstrapTable('getData');
var count = data.length; var count = data.length;
for (var dataIndex = 0; dataIndex < count; dataIndex++) { for (var dataIndex = 0; dataIndex < count; dataIndex++) {
var columns = $('#' + table.options.id + ' tr[data-index="' + dataIndex + '"] td'); var columns = $('#' + table.options.id + ' tr[data-index="' + dataIndex + '"] td:visible');
var obj = new Object(); var obj = new Object();
for (var i = 0; i < columns.length; i++) { for (var i = 0; i < columns.length; i++) {
var inputValue = $(columns[i]).find('input'); var inputValue = $(columns[i]).find('input');
@ -465,9 +492,10 @@ var sub = {
} }
$("#" + table.options.id).bootstrapTable('remove', { field: subColumn, values: ids }); $("#" + table.options.id).bootstrapTable('remove', { field: subColumn, values: ids });
}, },
delRowByIndex: function(value) { delRowByIndex: function(value, tableId) {
var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId;
sub.editRow(); sub.editRow();
$("#" + table.options.id).bootstrapTable('remove', { field: "index", values: [value] }); $("#" + currentId).bootstrapTable('remove', { field: "index", values: [value] });
sub.editRow(); sub.editRow();
}, },
addRow: function(row, tableId) { addRow: function(row, tableId) {

View File

@ -10,8 +10,8 @@ var table = {
options: {}, options: {},
// 设置实例配置 // 设置实例配置
set: function(id) { set: function(id) {
if($.common.getLength(table.config) > 1 && $.common.isNotEmpty(event)) { if ($.common.getLength(table.config) > 1 && $.common.isNotEmpty(event)) {
var tableId = $.common.isEmpty(id) ? $(event.currentTarget).parents(".bootstrap-table").find("table.table").attr("id") : id; var tableId = $.common.isEmpty(id) ? $(event.currentTarget).parents(".bootstrap-table").find("table.table").attr("id") || $(event.currentTarget).parents(".bootstrap-tree-table").find("table.table").attr("id") : id;
if ($.common.isNotEmpty(tableId)) { if ($.common.isNotEmpty(tableId)) {
table.options = table.get(tableId); table.options = table.get(tableId);
} }
@ -221,13 +221,13 @@ var table = {
if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) { if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) {
func = $.inArray(e.type, ['check', 'check-all']) > -1 ? 'union' : 'difference'; func = $.inArray(e.type, ['check', 'check-all']) > -1 ? 'union' : 'difference';
var selectedIds = table.rememberSelectedIds[table.options.id]; var selectedIds = table.rememberSelectedIds[table.options.id];
if($.common.isNotEmpty(selectedIds)) { if ($.common.isNotEmpty(selectedIds)) {
table.rememberSelectedIds[table.options.id] = _[func](selectedIds, rowIds); table.rememberSelectedIds[table.options.id] = _[func](selectedIds, rowIds);
} else { } else {
table.rememberSelectedIds[table.options.id] = _[func]([], rowIds); table.rememberSelectedIds[table.options.id] = _[func]([], rowIds);
} }
var selectedRows = table.rememberSelecteds[table.options.id]; var selectedRows = table.rememberSelecteds[table.options.id];
if($.common.isNotEmpty(selectedRows)) { if ($.common.isNotEmpty(selectedRows)) {
table.rememberSelecteds[table.options.id] = _[func](selectedRows, rows); table.rememberSelecteds[table.options.id] = _[func](selectedRows, rows);
} else { } else {
table.rememberSelecteds[table.options.id] = _[func]([], rows); table.rememberSelecteds[table.options.id] = _[func]([], rows);
@ -249,7 +249,7 @@ var table = {
$(optionsIds).off("click").on("click", '.img-circle', function() { $(optionsIds).off("click").on("click", '.img-circle', function() {
var src = $(this).attr('src'); var src = $(this).attr('src');
var target = $(this).data('target'); var target = $(this).data('target');
if($.common.equals("self", target)) { if ($.common.equals("self", target)) {
var height = $(this).data('height'); var height = $(this).data('height');
var width = $(this).data('width'); var width = $(this).data('width');
top.layer.open({ top.layer.open({
@ -363,7 +363,7 @@ var table = {
if ($.common.isNotEmpty(pageSize)) { if ($.common.isNotEmpty(pageSize)) {
params.pageSize = pageSize; params.pageSize = pageSize;
} }
if($.common.isNotEmpty(tableId)){ if ($.common.isNotEmpty(tableId)){
$("#" + tableId).bootstrapTable('refresh', params); $("#" + tableId).bootstrapTable('refresh', params);
} else{ } else{
$("#" + table.options.id).bootstrapTable('refresh', params); $("#" + table.options.id).bootstrapTable('refresh', params);
@ -493,7 +493,7 @@ var table = {
}); });
if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) { if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) {
var selectedRows = table.rememberSelecteds[table.options.id]; var selectedRows = table.rememberSelecteds[table.options.id];
if($.common.isNotEmpty(selectedRows)) { if ($.common.isNotEmpty(selectedRows)) {
rows = $.map(table.rememberSelecteds[table.options.id], function (row) { rows = $.map(table.rememberSelecteds[table.options.id], function (row) {
return $.common.getItemField(row, column); return $.common.getItemField(row, column);
}); });
@ -522,7 +522,7 @@ var table = {
}); });
if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) { if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) {
var selectedRows = table.rememberSelecteds[table.options.id]; var selectedRows = table.rememberSelecteds[table.options.id];
if($.common.isNotEmpty(selectedRows)) { if ($.common.isNotEmpty(selectedRows)) {
rows = $.map(selectedRows, function (row) { rows = $.map(selectedRows, function (row) {
return $.common.getItemField(row, table.options.columns[1].field); return $.common.getItemField(row, table.options.columns[1].field);
}); });
@ -704,14 +704,7 @@ var table = {
} else if (table.options.type == table_type.bootstrapTreeTable) { } else if (table.options.type == table_type.bootstrapTreeTable) {
$("#" + tableId).bootstrapTreeTable('refresh', table.options.ajaxParams); $("#" + tableId).bootstrapTreeTable('refresh', table.options.ajaxParams);
} }
if ($.common.isNotEmpty(startLayDate) && $.common.isNotEmpty(endLayDate)) { resetDate();
endLayDate.config.min.year = '';
endLayDate.config.min.month = '';
endLayDate.config.min.date = '';
startLayDate.config.max.year = '2099';
startLayDate.config.max.month = '12';
startLayDate.config.max.date = '31';
}
}, },
// 获取选中复选框项 // 获取选中复选框项
selectCheckeds: function(name) { selectCheckeds: function(name) {
@ -812,7 +805,7 @@ var table = {
}, },
// 获取iframe页的DOM // 获取iframe页的DOM
getChildFrame: function (index) { getChildFrame: function (index) {
if($.common.isEmpty(index)){ if ($.common.isEmpty(index)){
var index = parent.layer.getFrameIndex(window.name); var index = parent.layer.getFrameIndex(window.name);
return parent.layer.getChildFrame('body', index); return parent.layer.getChildFrame('body', index);
} else { } else {
@ -821,7 +814,7 @@ var table = {
}, },
// 关闭窗体 // 关闭窗体
close: function (index) { close: function (index) {
if($.common.isEmpty(index)){ if ($.common.isEmpty(index)){
var index = parent.layer.getFrameIndex(window.name); var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index); parent.layer.close(index);
} else { } else {
@ -883,6 +876,9 @@ var table = {
yes: callback, yes: callback,
cancel: function(index) { cancel: function(index) {
return true; return true;
},
success: function () {
$(':focus').blur();
} }
}); });
}, },
@ -904,7 +900,7 @@ var table = {
} }
} }
var btnCallback = {}; var btnCallback = {};
if(options.btn instanceof Array){ if (options.btn instanceof Array){
for (var i = 1, len = options.btn.length; i < len; i++) { for (var i = 1, len = options.btn.length; i < len; i++) {
var btn = options["btn" + (i + 1)]; var btn = options["btn" + (i + 1)];
if (btn) { if (btn) {
@ -929,6 +925,9 @@ var table = {
yes: options.yes, yes: options.yes,
cancel: function () { cancel: function () {
return true; return true;
},
success: function () {
$(':focus').blur();
} }
}, btnCallback)); }, btnCallback));
if ($.common.isNotEmpty(options.full) && options.full === true) { if ($.common.isNotEmpty(options.full) && options.full === true) {
@ -972,6 +971,9 @@ var table = {
}, },
cancel: function(index) { cancel: function(index) {
return true; return true;
},
success: function () {
$(':focus').blur();
} }
}); });
top.layer.full(index); top.layer.full(index);
@ -1086,7 +1088,7 @@ var table = {
table.set(); table.set();
$.modal.confirm("确定删除该条" + table.options.modalName + "信息吗?", function() { $.modal.confirm("确定删除该条" + table.options.modalName + "信息吗?", function() {
var url = $.common.isEmpty(id) ? table.options.removeUrl : table.options.removeUrl.replace("{id}", id); var url = $.common.isEmpty(id) ? table.options.removeUrl : table.options.removeUrl.replace("{id}", id);
if(table.options.type == table_type.bootstrapTreeTable) { if (table.options.type == table_type.bootstrapTreeTable) {
$.operate.get(url); $.operate.get(url);
} else { } else {
var data = { "ids": id }; var data = { "ids": id };
@ -1139,7 +1141,7 @@ var table = {
// 修改信息 // 修改信息
edit: function(id) { edit: function(id) {
table.set(); table.set();
if($.common.isEmpty(id) && table.options.type == table_type.bootstrapTreeTable) { if ($.common.isEmpty(id) && table.options.type == table_type.bootstrapTreeTable) {
var row = $("#" + table.options.id).bootstrapTreeTable('getSelections')[0]; var row = $("#" + table.options.id).bootstrapTreeTable('getSelections')[0];
if ($.common.isEmpty(row)) { if ($.common.isEmpty(row)) {
$.modal.alertWarning("请至少选择一条记录"); $.modal.alertWarning("请至少选择一条记录");
@ -1163,7 +1165,7 @@ var table = {
if ($.common.isNotEmpty(id)) { if ($.common.isNotEmpty(id)) {
url = table.options.updateUrl.replace("{id}", id); url = table.options.updateUrl.replace("{id}", id);
} else { } else {
if(table.options.type == table_type.bootstrapTreeTable) { if (table.options.type == table_type.bootstrapTreeTable) {
var row = $("#" + table.options.id).bootstrapTreeTable('getSelections')[0]; var row = $("#" + table.options.id).bootstrapTreeTable('getSelections')[0];
if ($.common.isEmpty(row)) { if ($.common.isEmpty(row)) {
$.modal.alertWarning("请至少选择一条记录"); $.modal.alertWarning("请至少选择一条记录");
@ -1289,7 +1291,7 @@ var table = {
successCallback: function(result) { successCallback: function(result) {
if (result.code == web_status.SUCCESS) { if (result.code == web_status.SUCCESS) {
var parent = activeWindow(); var parent = activeWindow();
if($.common.isEmpty(parent.table)) { if ($.common.isEmpty(parent.table)) {
$.modal.msgSuccessReload(result.msg); $.modal.msgSuccessReload(result.msg);
} else if (parent.table.options.type == table_type.bootstrapTable) { } else if (parent.table.options.type == table_type.bootstrapTable) {
$.modal.close(); $.modal.close();
@ -1313,15 +1315,20 @@ var table = {
if (result.code == web_status.SUCCESS) { if (result.code == web_status.SUCCESS) {
var topWindow = $(window.parent.document); var topWindow = $(window.parent.document);
var currentId = $('.page-tabs-content', topWindow).find('.active').attr('data-panel'); var currentId = $('.page-tabs-content', topWindow).find('.active').attr('data-panel');
var $contentWindow = $('.RuoYi_iframe[data-id="' + currentId + '"]', topWindow)[0].contentWindow; var topWindow = $('.RuoYi_iframe[data-id="' + currentId + '"]', topWindow)[0];
$.modal.close(); if ($.common.isNotEmpty(topWindow) && $.common.isNotEmpty(currentId)) {
$contentWindow.$.modal.msgSuccess(result.msg); var $contentWindow = topWindow.contentWindow;
$contentWindow.$(".layui-layer-padding").removeAttr("style"); $contentWindow.$.modal.msgSuccess(result.msg);
if ($contentWindow.table.options.type == table_type.bootstrapTable) { $contentWindow.$(".layui-layer-padding").removeAttr("style");
$contentWindow.$.table.refresh(); if ($contentWindow.table.options.type == table_type.bootstrapTable) {
} else if ($contentWindow.table.options.type == table_type.bootstrapTreeTable) { $contentWindow.$.table.refresh();
$contentWindow.$.treeTable.refresh(); } else if ($contentWindow.table.options.type == table_type.bootstrapTreeTable) {
$contentWindow.$.treeTable.refresh();
}
} else {
$.modal.msgSuccess(result.msg);
} }
$.modal.close();
$.modal.closeTab(); $.modal.closeTab();
} else if (result.code == web_status.WARNING) { } else if (result.code == web_status.WARNING) {
$.modal.alertWarning(result.msg) $.modal.alertWarning(result.msg)
@ -1333,13 +1340,6 @@ var table = {
}, },
// 校验封装处理 // 校验封装处理
validate: { validate: {
// 判断返回标识是否唯一 false 为存在 true 为不存在
unique: function (value) {
if (value == "0") {
return true;
}
return false;
},
// 表单验证 // 表单验证
form: function (formId) { form: function (formId) {
var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId; var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId;
@ -1404,7 +1404,7 @@ var table = {
var node = tree.getNodesByParam("id", treeId, null)[0]; var node = tree.getNodesByParam("id", treeId, null)[0];
$.tree.selectByIdName(treeId, node); $.tree.selectByIdName(treeId, node);
// 回调tree方法 // 回调tree方法
if(typeof(options.callBack) === "function"){ if (typeof(options.callBack) === "function"){
options.callBack(tree); options.callBack(tree);
} }
}); });
@ -1493,7 +1493,7 @@ var table = {
// 不允许根父节点选择 // 不允许根父节点选择
notAllowParents: function(_tree) { notAllowParents: function(_tree) {
var nodes = _tree.getSelectedNodes(); var nodes = _tree.getSelectedNodes();
if(nodes.length == 0){ if (nodes.length == 0){
$.modal.msgError("请选择节点后提交"); $.modal.msgError("请选择节点后提交");
return false; return false;
} }
@ -1549,6 +1549,10 @@ var table = {
isNotEmpty: function (value) { isNotEmpty: function (value) {
return !$.common.isEmpty(value); return !$.common.isEmpty(value);
}, },
// 如果值是空,则返回指定默认字符串,否则返回字符串本身
nullToDefault: function (value, defaultValue) {
return $.common.isEmpty(value) ? defaultValue : value;
},
// 空对象转字符串 // 空对象转字符串
nullToStr: function(value) { nullToStr: function(value) {
if ($.common.isEmpty(value)) { if ($.common.isEmpty(value)) {
@ -1681,7 +1685,7 @@ var table = {
formToJSON: function(formId) { formToJSON: function(formId) {
var json = {}; var json = {};
$.each($("#" + formId).serializeArray(), function(i, field) { $.each($("#" + formId).serializeArray(), function(i, field) {
if(json[field.name]) { if (json[field.name]) {
json[field.name] += ("," + field.value); json[field.name] += ("," + field.value);
} else { } else {
json[field.name] = field.value; json[field.name] = field.value;

View File

@ -0,0 +1,91 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<th:block th:include="include :: header('进度条')" />
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>进度条 (Progress Bars)</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">选项1</a>
</li>
<li><a href="#">选项2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<!-- style: progress-bar-success/progress-bar-info/progress-bar-warning/progress-bar-danger -->
<h5>基本</h5>
<div class="progress">
<div style="width: 35%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="35" role="progressbar" class="progress-bar progress-bar-success">
<span class="sr-only">35% Complete (success)</span>
</div>
</div>
<div class="progress progress-bar-default">
<div style="width: 43%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="43" role="progressbar" class="progress-bar">
<span class="sr-only">43% Complete (success)</span>
</div>
</div>
<h5>条纹效果</h5>
<div class="progress progress-striped">
<div style="width: 50%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="50" role="progressbar" class="progress-bar progress-bar-warning">
<span class="sr-only">50% Complete (success)</span>
</div>
</div>
<h5>动画效果</h5>
<div class="progress progress-striped active">
<div style="width: 75%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="75" role="progressbar" class="progress-bar progress-bar-danger">
<span class="sr-only">75% Complete (success)</span>
</div>
</div>
<h5>堆叠效果</h5>
<div class="progress progress-striped active">
<div style="width: 30%" class="progress-bar progress-bar-success">
<span class="sr-only">30% Complete (success)</span>
</div>
<div style="width: 20%" class="progress-bar progress-bar-warning">
<span class="sr-only">20% Complete (warning)</span>
</div>
<div style="width: 40%" class="progress-bar progress-bar-danger">
<span class="sr-only">40% Complete (danger)</span>
</div>
</div>
<h5>带有提示标签的进度条</h5>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="95" aria-valuemin="0" aria-valuemax="100" style="width: 95%;">
95%
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script type="text/javascript">
$("[data-toggle='tooltip']").tooltip();
$("[data-toggle=popover]").popover();
</script>
</body>
</html>

View File

@ -17,7 +17,7 @@
<h2>若依后台管理系统</h2> <h2>若依后台管理系统</h2>
<p>ruoyi是一个完全响应式基于Bootstrap3.3.7最新版本开发的扁平化主题她采用了主流的左右两栏式布局使用了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.7最新版本开发的扁平化主题她采用了主流的左右两栏式布局使用了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.7.4 <b>当前版本:</b>v4.7.7
</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.7最新版本开发的扁平化主题她采用了主流的左右两栏式布局使用了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.7最新版本开发的扁平化主题她采用了主流的左右两栏式布局使用了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.7.4 <b>当前版本:</b>v4.7.7
</p> </p>
<p> <p>
<span class="label label-warning">开源免费</span> <span class="label label-warning">开源免费</span>

View File

@ -181,7 +181,7 @@ $('#smartwizard').smartWizard({
enableURLhash: true, // Enable selection of the step based on url hash enableURLhash: true, // Enable selection of the step based on url hash
transition: { transition: {
animation: 'none', // Effect on navigation, none/fade/slide-horizontal/slide-vertical/slide-swing animation: 'none', // Effect on navigation, none/fade/slide-horizontal/slide-vertical/slide-swing
speed: '400', // Transion animation speed speed: '400', // Transition animation speed
easing:'' // Transition animation easing. Not supported without a jQuery easing plugin easing:'' // Transition animation easing. Not supported without a jQuery easing plugin
}, },
toolbarSettings: { toolbarSettings: {

View File

@ -32,11 +32,14 @@
showRefresh: false, showRefresh: false,
showToggle: false, showToggle: false,
showColumns: false, showColumns: false,
onReorderRow: function (data) { onReorderRow: function (data, newRow, oldRow, el) {
//当拖拽结束后data为整个表格的数据 // 当拖拽结束后data为整个表格的数据
console.table(data) console.table(data)
// 当sidePagination: "server"时,拖拽行后顺序错乱,需要重新调用加载数据方法 // 当sidePagination: "server"时,拖拽行后顺序错乱,需要重新调用加载数据方法
$("#" + table.options.id).bootstrapTable('load', data); $("#" + table.options.id).bootstrapTable('load', {
total: el._xhr.responseJSON.total,
rows: data
});
return false; return false;
}, },
columns: [{ columns: [{

View File

@ -1,8 +1,11 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head> <head>
<th:block th:include="include :: header('主子表提交')" /> <th:block th:include="include :: header('主子表提交')" />
<th:block th:include="include :: datetimepicker-css" /> <th:block th:include="include :: datetimepicker-css" />
<style type="text/css">
table label.error{position: inherit;}select + label.error{z-index:1;right:40px;}
</style>
</head> </head>
<body class="gray-bg"> <body class="gray-bg">
<div class="main-content"> <div class="main-content">
@ -13,7 +16,7 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label is-required">客户名称:</label> <label class="col-sm-4 control-label is-required">客户名称:</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input name="name" placeholder="请输入客户名称" class="form-control" type="text" maxlength="30"> <input name="name" placeholder="请输入客户名称" class="form-control" type="text" maxlength="30" required>
</div> </div>
</div> </div>
</div> </div>
@ -31,9 +34,9 @@
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label is-required">手机号码:</label> <label class="col-sm-4 control-label">手机号码:</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="phonenumber" name="phonenumber" placeholder="请输入手机号码" class="form-control" type="text" maxlength="11"> <input id="phonenumber" name="phonenumber" placeholder="请输入手机号码" class="form-control isPhone" type="text" maxlength="11">
</div> </div>
</div> </div>
</div> </div>
@ -127,7 +130,7 @@
align: 'center', align: 'center',
title: '商品名称', title: '商品名称',
formatter: function(value, row, index) { formatter: function(value, row, index) {
var html = $.common.sprintf("<input class='form-control' type='text' name='goods[%s].name' value='%s'>", index, value); var html = $.common.sprintf("<input class='form-control goodsName' type='text' name='goods[%s].name' value='%s'>", index, value);
return html; return html;
} }
}, },
@ -136,7 +139,7 @@
align: 'center', align: 'center',
title: '商品重量', title: '商品重量',
formatter: function(value, row, index) { formatter: function(value, row, index) {
var html = $.common.sprintf("<input class='form-control' type='text' name='goods[%s].weight' value='%s'>", index, value); var html = $.common.sprintf("<input class='form-control goodsWeight' type='text' name='goods[%s].weight' value='%s'>", index, value);
return html; return html;
} }
}, },
@ -179,11 +182,21 @@
$.table.init(options); $.table.init(options);
}); });
/* 主子表-提交 */ $.validator.addMethod("goodsName", function(value, element) {
return !this.optional(element);
}, "商品名称必填。");
$.validator.addMethod("goodsWeight", function(value, element) {
return !this.optional(element) && (value <= 100 && value >= 0);
}, "商品重量长度区间0-100。");
/* 主子表-提交 */
function submitHandler(index, layero){ function submitHandler(index, layero){
var data = $("#form-add").serializeArray(); if ($.validate.form()) {
alert(JSON.stringify(data)) var data = $("#form-add").serializeArray();
$.operate.saveModal("/demo/operate/customer/add", data); alert(JSON.stringify(data))
$.operate.saveModal("/demo/operate/customer/add", data);
}
} }
$("input[name='birthday']").datetimepicker({ $("input[name='birthday']").datetimepicker({

View File

@ -7,19 +7,19 @@
<meta name="description" content=""> <meta name="description" content="">
<title th:text="${title}"></title> <title th:text="${title}"></title>
<link th:href="@{/css/bootstrap.min.css?v=3.3.7}" rel="stylesheet"/> <link th:href="@{/css/bootstrap.min.css?v=3.3.7}" rel="stylesheet"/>
<link th:href="@{/css/font-awesome.min.css?v=4.7.4}" rel="stylesheet"/> <link th:href="@{/css/font-awesome.min.css?v=4.7.0}" rel="stylesheet"/>
<!-- bootstrap-table 表格插件样式 --> <!-- bootstrap-table 表格插件样式 -->
<link th:href="@{/ajax/libs/bootstrap-table/bootstrap-table.min.css?v=1.18.3}" rel="stylesheet"/> <link th:href="@{/ajax/libs/bootstrap-table/bootstrap-table.min.css?v=1.18.3}" rel="stylesheet"/>
<link th:href="@{/css/animate.min.css?v=20210831}" rel="stylesheet"/> <link th:href="@{/css/animate.min.css?v=20210831}" rel="stylesheet"/>
<link th:href="@{/css/style.min.css?v=20210831}" rel="stylesheet"/> <link th:href="@{/css/style.min.css?v=20210831}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.4}" rel="stylesheet"/> <link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.7}" rel="stylesheet"/>
</head> </head>
<!-- 通用JS --> <!-- 通用JS -->
<div th:fragment="footer"> <div th:fragment="footer">
<script th:inline="javascript"> var ctx = [[@{/}]]; var lockscreen = [[${session.lockscreen}]]; if(lockscreen){window.top.location=ctx+"lockscreen";} </script> <script th:inline="javascript"> var ctx = [[@{/}]]; var lockscreen = [[${session.lockscreen}]]; if(lockscreen){window.top.location=ctx+"lockscreen";} </script>
<a id="scroll-up" href="#" class="btn btn-sm display"><i class="fa fa-angle-double-up"></i></a> <a id="scroll-up" href="#" class="btn btn-sm display"><i class="fa fa-angle-double-up"></i></a>
<script th:src="@{/js/jquery.min.js?v=3.6.0}"></script> <script th:src="@{/js/jquery.min.js?v=3.6.3}"></script>
<script th:src="@{/js/bootstrap.min.js?v=3.3.7}"></script> <script th:src="@{/js/bootstrap.min.js?v=3.3.7}"></script>
<!-- bootstrap-table 表格插件 --> <!-- bootstrap-table 表格插件 -->
<script th:src="@{/ajax/libs/bootstrap-table/bootstrap-table.min.js?v=1.18.3}"></script> <script th:src="@{/ajax/libs/bootstrap-table/bootstrap-table.min.js?v=1.18.3}"></script>
@ -35,9 +35,9 @@
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js?v=2.70.0}"></script> <script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js?v=2.70.0}"></script>
<script th:src="@{/ajax/libs/iCheck/icheck.min.js?v=1.0.3}"></script> <script th:src="@{/ajax/libs/iCheck/icheck.min.js?v=1.0.3}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js?v=3.5.1}"></script> <script th:src="@{/ajax/libs/layer/layer.min.js?v=3.5.1}"></script>
<script th:src="@{/ajax/libs/layui/layui.min.js?v=2.6.8}"></script> <script th:src="@{/ajax/libs/layui/layui.min.js?v=2.7.5}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.7.4}"></script> <script th:src="@{/ruoyi/js/common.js?v=4.7.7}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.4}"></script> <script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.7}"></script>
</div> </div>
<!-- ztree树插件 --> <!-- ztree树插件 -->
@ -108,10 +108,10 @@
<!-- fileinput文件上传插件 --> <!-- fileinput文件上传插件 -->
<div th:fragment="bootstrap-fileinput-css"> <div th:fragment="bootstrap-fileinput-css">
<link th:href="@{/ajax/libs/bootstrap-fileinput/fileinput.min.css?v=5.2.4}" rel="stylesheet"/> <link th:href="@{/ajax/libs/bootstrap-fileinput/fileinput.min.css?v=5.5.2}" rel="stylesheet"/>
</div> </div>
<div th:fragment="bootstrap-fileinput-js"> <div th:fragment="bootstrap-fileinput-js">
<script th:src="@{/ajax/libs/bootstrap-fileinput/fileinput.min.js?v=5.2.4}"></script> <script th:src="@{/ajax/libs/bootstrap-fileinput/fileinput.min.js?v=5.5.2}"></script>
</div> </div>
<!-- duallistbox双列表框插件 --> <!-- duallistbox双列表框插件 -->

View File

@ -14,7 +14,8 @@
<link th:href="@{/css/animate.min.css}" rel="stylesheet"/> <link th:href="@{/css/animate.min.css}" rel="stylesheet"/>
<link th:href="@{/css/style.min.css}" rel="stylesheet"/> <link th:href="@{/css/style.min.css}" rel="stylesheet"/>
<link th:href="@{/css/skins.css?v=20200902}" rel="stylesheet"/> <link th:href="@{/css/skins.css?v=20200902}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.4}" rel="stylesheet"/> <link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.7}" rel="stylesheet"/>
<style type="text/css">.fixed-sidebar .nav:not(.navbar-toolbar)>li.active{border-left:0px!important;}</style>
</head> </head>
<body class="fixed-sidebar full-height-layout gray-bg" th:classappend="${isMobile} ? 'canvas-menu'" style="overflow: hidden"> <body class="fixed-sidebar full-height-layout gray-bg" th:classappend="${isMobile} ? 'canvas-menu'" style="overflow: hidden">
<div id="wrapper"> <div id="wrapper">
@ -98,6 +99,7 @@
<li><a class="menuItem" th:href="@{/demo/form/grid}">栅格</a></li> <li><a class="menuItem" th:href="@{/demo/form/grid}">栅格</a></li>
<li><a class="menuItem" th:href="@{/demo/form/select}">下拉框</a></li> <li><a class="menuItem" th:href="@{/demo/form/select}">下拉框</a></li>
<li><a class="menuItem" th:href="@{/demo/form/timeline}">时间轴</a></li> <li><a class="menuItem" th:href="@{/demo/form/timeline}">时间轴</a></li>
<li><a class="menuItem" th:href="@{/demo/form/progress_bars}">进度条</a></li>
<li><a class="menuItem" th:href="@{/demo/form/basic}">基本表单</a></li> <li><a class="menuItem" th:href="@{/demo/form/basic}">基本表单</a></li>
<li><a class="menuItem" th:href="@{/demo/form/cards}">卡片列表</a></li> <li><a class="menuItem" th:href="@{/demo/form/cards}">卡片列表</a></li>
<li><a class="menuItem" th:href="@{/demo/form/jasny}">功能扩展</a></li> <li><a class="menuItem" th:href="@{/demo/form/jasny}">功能扩展</a></li>
@ -316,8 +318,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.7.4}"></script> <script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.7}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.7.4}"></script> <script th:src="@{/ruoyi/js/common.js?v=4.7.7}"></script>
<script th:src="@{/ruoyi/index.js?v=20201208}"></script> <script th:src="@{/ruoyi/index.js?v=20201208}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script> <script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
<script th:src="@{/js/resize-tabs.js}"></script> <script th:src="@{/js/resize-tabs.js}"></script>

View File

@ -14,7 +14,7 @@
<link th:href="@{/css/animate.min.css}" rel="stylesheet"/> <link th:href="@{/css/animate.min.css}" rel="stylesheet"/>
<link th:href="@{/css/style.min.css}" rel="stylesheet"/> <link th:href="@{/css/style.min.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.7.4}" rel="stylesheet"/> <link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.7}" rel="stylesheet"/>
</head> </head>
<body class="fixed-sidebar full-height-layout gray-bg" th:classappend="${isMobile} ? 'canvas-menu'" style="overflow: hidden"> <body class="fixed-sidebar full-height-layout gray-bg" th:classappend="${isMobile} ? 'canvas-menu'" style="overflow: hidden">
<div id="wrapper"> <div id="wrapper">
@ -80,6 +80,7 @@
<li><a class="menuItem" th:href="@{/demo/form/grid}">栅格</a></li> <li><a class="menuItem" th:href="@{/demo/form/grid}">栅格</a></li>
<li><a class="menuItem" th:href="@{/demo/form/select}">下拉框</a></li> <li><a class="menuItem" th:href="@{/demo/form/select}">下拉框</a></li>
<li><a class="menuItem" th:href="@{/demo/form/timeline}">时间轴</a></li> <li><a class="menuItem" th:href="@{/demo/form/timeline}">时间轴</a></li>
<li><a class="menuItem" th:href="@{/demo/form/progress_bars}">进度条</a></li>
<li><a class="menuItem" th:href="@{/demo/form/basic}">基本表单</a></li> <li><a class="menuItem" th:href="@{/demo/form/basic}">基本表单</a></li>
<li><a class="menuItem" th:href="@{/demo/form/cards}">卡片列表</a></li> <li><a class="menuItem" th:href="@{/demo/form/cards}">卡片列表</a></li>
<li><a class="menuItem" th:href="@{/demo/form/jasny}">功能扩展</a></li> <li><a class="menuItem" th:href="@{/demo/form/jasny}">功能扩展</a></li>
@ -263,8 +264,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.7.4}"></script> <script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.7}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.7.4}"></script> <script th:src="@{/ruoyi/js/common.js?v=4.7.7}"></script>
<script th:src="@{/ruoyi/index.js?v=20201208}"></script> <script th:src="@{/ruoyi/index.js?v=20201208}"></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">

View File

@ -38,7 +38,7 @@
<script src="../static/js/bootstrap.min.js" th:src="@{/js/bootstrap.min.js}"></script> <script src="../static/js/bootstrap.min.js" th:src="@{/js/bootstrap.min.js}"></script>
<script src="../static/js/three.min.js" th:src="@{/js/three.min.js}"></script> <script src="../static/js/three.min.js" th:src="@{/js/three.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/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.4}"></script> <script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.7}"></script>
</body> </body>
<script th:inline="javascript"> <script th:inline="javascript">
var ctx = [[@{/}]]; var ctx = [[@{/}]];

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.min.css" th:href="@{/css/style.min.css}" rel="stylesheet"/> <link href="../static/css/style.min.css" th:href="@{/css/style.min.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.7.4}" rel="stylesheet"/> <link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.7.7}" rel="stylesheet"/>
<!-- 360浏览器急速模式 --> <!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 --> <!-- 避免IE使用兼容模式 -->
@ -65,7 +65,7 @@
</div> </div>
<div class="signup-footer"> <div class="signup-footer">
<div class="pull-left"> <div class="pull-left">
Copyright © 2018-2022 ruoyi.vip All Rights Reserved. <br> Copyright © 2018-2023 ruoyi.vip All Rights Reserved. <br>
</div> </div>
</div> </div>
</div> </div>
@ -76,7 +76,7 @@
<script src="../static/ajax/libs/validate/jquery.validate.min.js" th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script> <script src="../static/ajax/libs/validate/jquery.validate.min.js" th:src="@{/ajax/libs/validate/jquery.validate.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.7.4}"></script> <script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.7}"></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

@ -79,7 +79,7 @@
<div class="ibox-content"> <div class="ibox-content">
<p><i class="fa fa-send-o"></i> 官网:<a href="http://www.ruoyi.vip" target="_blank">http://www.ruoyi.vip</a> <p><i class="fa fa-send-o"></i> 官网:<a href="http://www.ruoyi.vip" target="_blank">http://www.ruoyi.vip</a>
</p> </p>
<p><i class="fa fa-qq"></i> QQ群<s>满1389287</s> <s>满1679294</s> <s>满1529866</s> <s>满1772718</s> <s>满1366522</s> <s>满1382251</s> <s>满1145125</s> <s>满86752435</s> <s>满134072510</s> <s>满210336300</s> <s>满339522636</s> <s>满130035985</s> <s>满143151071</s> <s>满158781320</s> <s>满201531282</s> <s>满101526938</s> <s>满264355400</s> <s>满298522656</s> <s>满139845794</s> <a href="https://jq.qq.com/?_wv=1027&k=p86p2AJX" target="_blank">213650505</a> <p><i class="fa fa-qq"></i> QQ群<s>满1389287</s> <s>满1679294</s> <s>满1529866</s> <s>满1772718</s> <s>满1366522</s> <s>满1382251</s> <s>满1145125</s> <s>满86752435</s> <s>满134072510</s> <s>满210336300</s> <s>满339522636</s> <s>满130035985</s> <s>满143151071</s> <s>满158781320</s> <s>满201531282</s> <s>满101526938</s> <s>满264355400</s> <s>满298522656</s> <s>满139845794</s> <s>满185760789</s> <a href="https://jq.qq.com/?_wv=1027&k=7FplYUnR" target="_blank">175104288</a>
</p> </p>
<p><i class="fa fa-weixin"></i> 微信:<a href="javascript:;">/ *若依</a> <p><i class="fa fa-weixin"></i> 微信:<a href="javascript:;">/ *若依</a>
</p> </p>
@ -96,13 +96,132 @@
<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="#v477">v4.7.7</a><code class="pull-right">2023.04.14</code>
</h5>
</div>
<div id="v477" class="panel-collapse collapse in">
<div class="panel-body">
<ol>
<li>操作日志新增消耗时间属性</li>
<li>日志管理使用索引提升查询性能</li>
<li>日志注解支持排除指定的请求参数</li>
<li>新增监控页面图标显示</li>
<li>新增支持登录IP黑名单限制</li>
<li>更新fontawesome图标示例</li>
<li>屏蔽定时任务bean违规的字符</li>
<li>支持自定义隐藏属性列过滤子对象</li>
<li>连接池Druid支持新的配置connectTimeout和socketTimeout</li>
<li>升级jquery到最新版v3.6.3</li>
<li>升级layui到最新版本2.7.6</li>
<li>升级jasny-bootstrap到最新版4.0.0</li>
<li>升级oshi到最新版本6.4.1</li>
<li>升级druid到最新版本1.2.16</li>
<li>修复异步表格树子项排序问题</li>
<li>修复冻结列不支持IE浏览器的问题</li>
<li>修复主子表使用suggest插件无法新增问题</li>
<li>修复菜单栏快速点击导致展开折叠样式问题</li>
<li>修复用户多角色数据权限可能出现权限抬升的情况</li>
<li>修复异步加载表格树重置列表父节点展开异常问题</li>
<li>修复页签属性refresh为undefined时页面被刷新问题</li>
<li>移除apache/commons-fileupload依赖</li>
<li>优化前端属性提醒说明</li>
<li>优化用户导入更新时需获取用户编号问题</li>
<li>优化主子表根据序号删除方法加入表格ID参数</li>
<li>优化导出Excel时设置dictType属性重复查缓存问题</li>
<li>优化在线用户服务缓存改为从Bean容器获取不使用自动装配</li>
<li>优化表格示例行拖拽后列表底部总记录条数变成了undefined问题</li>
<li>其他细节优化</li>
</ol>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v476">v4.7.6</a><code class="pull-right">2022.12.16</code>
</h5>
</div>
<div id="v476" class="panel-collapse collapse">
<div class="panel-body">
<ol>
<li>定时任务违规的字符</li>
<li>忽略不必要的属性数据返回</li>
<li>导入更新用户数据前校验数据权限</li>
<li>修改参数键名时移除前缓存配置</li>
<li>修改用户登录账号进行重复验证</li>
<li>兼容Excel下拉框内容过多无法显示</li>
<li>升级oshi到最新版本6.4.0</li>
<li>升级kaptcha到最新版2.3.3</li>
<li>升级druid到最新版本1.2.15</li>
<li>升级shiro到最新版本1.10.1</li>
<li>升级pagehelper到最新版1.4.6</li>
<li>升级bootstrap-fileinput到最新版本5.5.2</li>
<li>修复sheet超出最大行数异常问题</li>
<li>修复关闭父页签后提交无法跳转的问题</li>
<li>修复操作日志类型多选导出不生效问题</li>
<li>修复导出包含空子列表数据异常的问题</li>
<li>优化树形表格层级显示</li>
<li>优化SQL关键字检查防止注入</li>
<li>优化用户管理重置时取消部门选择</li>
<li>优化代码生成同步后字典值NULL问题</li>
<li>优化导出对象的子列表为空会出现[]问题</li>
<li>优化select2搜索下拉后校验必填样式问题</li>
<li>其他细节优化</li>
</ol>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v475">v4.7.5</a><code class="pull-right">2022.09.05</code>
</h5>
</div>
<div id="v475" class="panel-collapse collapse">
<div class="panel-body">
<ol>
<li>Excel支持导出对象的子列表方法</li>
<li>数据逻辑删除不进行唯一验证</li>
<li>优化多角色数据权限匹配规则</li>
<li>新增主子表提交校验示例</li>
<li>支持自定义隐藏Excel属性列</li>
<li>Excel注解支持backgroundColor属性设置背景颜色</li>
<li>菜单配置刷新时Tab页签切换时刷新</li>
<li>增加对AjaxResult消息结果类型的判断</li>
<li>新增示例(进度条)</li>
<li>新增内容编码/解码方便插件集成使用</li>
<li>升级jquery到最新版3.6.1</li>
<li>升级layui到最新版本2.7.5</li>
<li>升级shiro到最新版本1.9.1</li>
<li>升级druid到最新版本1.2.11</li>
<li>升级pagehelper到最新版1.4.3</li>
<li>升级oshi到最新版本6.2.2</li>
<li>修复树表onLoadSuccess不生效的问题</li>
<li>修复用户分配角色大于默认页数丢失问题</li>
<li>定时任务支持执行父类方法</li>
<li>自动设置切换多个树表格实例配置</li>
<li>页签创建标题优先data-title属性</li>
<li>优化任务过期不执行调度</li>
<li>优化横向菜单下激活菜单样式</li>
<li>优化按钮打开窗口后按回车反复弹出</li>
<li>优化excel/scale属性导出单元格数值类型</li>
<li>优化druid开启wall过滤器出现的异常问题</li>
<li>优化多个相同角色数据导致权限SQL重复问题</li>
<li>其他细节优化</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="#v474">v4.7.4</a><code class="pull-right">2022.06.01</code> <a data-toggle="collapse" data-parent="#version" href="#v474">v4.7.4</a><code class="pull-right">2022.06.01</code>
</h5> </h5>
</div> </div>
<div id="v474" class="panel-collapse collapse in"> <div id="v474" class="panel-collapse collapse">
<div class="panel-body"> <div class="panel-body">
<ol> <ol>
<li>用户头像上传图片格式限制</li> <li>用户头像上传图片格式限制</li>

View File

@ -11,7 +11,7 @@
<div class="col-sm-4"> <div class="col-sm-4">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>缓存列表</h5> <h5><i class="fa fa-bars"></i> 缓存列表</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a href="javascript:getCacheNames()"><i class="fa fa-refresh"></i></a> <a href="javascript:getCacheNames()"><i class="fa fa-refresh"></i></a>
</div> </div>
@ -39,7 +39,7 @@
<div class="col-sm-4"> <div class="col-sm-4">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>键名列表</h5> <h5><i class="fa fa-key"></i> 键名列表</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a href="javascript:getCacheKeys('', true)"><i class="fa fa-refresh"></i></a> <a href="javascript:getCacheKeys('', true)"><i class="fa fa-refresh"></i></a>
</div> </div>
@ -53,8 +53,8 @@
<th>操作</th> <th>操作</th>
</tr> </tr>
</thead> </thead>
<tbody id="cacheKyes"> <tbody id="cacheKeys">
<tr th:fragment="fragment-cache-kyes" th:each="cacheKey, stat : ${cacheKyes}"> <tr th:fragment="fragment-cache-kyes" th:each="cacheKey, stat : ${cacheKeys}">
<td>[[${stat.index + 1}]]</td> <td>[[${stat.index + 1}]]</td>
<td style="word-wrap:break-word;word-break:break-all;" th:onclick="getCacheValue([[${cacheName}]], [[${cacheKey}]])">[[${cacheKey}]]</td> <td style="word-wrap:break-word;word-break:break-all;" th:onclick="getCacheValue([[${cacheName}]], [[${cacheKey}]])">[[${cacheKey}]]</td>
<td style="width: 50px"><a href="#" th:onclick="clearCacheKey([[${cacheName}]], [[${cacheKey}]])" title="清空"><i class="fa fa-trash-o text-danger"></i></a></td> <td style="width: 50px"><a href="#" th:onclick="clearCacheKey([[${cacheName}]], [[${cacheKey}]])" title="清空"><i class="fa fa-trash-o text-danger"></i></a></td>
@ -68,7 +68,7 @@
<div class="col-sm-4"> <div class="col-sm-4">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>缓存内容</h5> <h5><i class="fa fa-file-text"></i> 缓存内容</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a href="javascript:clearAll()"><i class="fa fa-refresh"></i> 清理全部</a> <a href="javascript:clearAll()"><i class="fa fa-refresh"></i> 清理全部</a>
</div> </div>
@ -125,7 +125,7 @@ function getCacheKeys(cacheName, isMsg) {
"fragment": 'fragment-cache-kyes' "fragment": 'fragment-cache-kyes'
}, },
success: function(data) { success: function(data) {
$("#cacheKyes").html(data); $("#cacheKeys").html(data);
$("#cacheName").val(_cacheName); $("#cacheName").val(_cacheName);
if (isMsg) { if (isMsg) {
$.modal.msgSuccess("刷新键名列表成功"); $.modal.msgSuccess("刷新键名列表成功");
@ -174,7 +174,7 @@ function clearCacheKey(cacheName, cacheKey) {
function clearAll(){ function clearAll(){
$.get(prefix + "/clearAll", function(result) { $.get(prefix + "/clearAll", function(result) {
if (result.code == web_status.SUCCESS) { if (result.code == web_status.SUCCESS) {
$.modal.msgSuccess("清理缓存成功") $.modal.msgSuccess("清理全部缓存成功")
} else { } else {
$.modal.msgError(result.msg); $.modal.msgError(result.msg);
} }

View File

@ -24,9 +24,9 @@
</li> </li>
<li class="select-time"> <li class="select-time">
<label>登录时间: </label> <label>登录时间: </label>
<input type="text" class="time-input" id="startTime" placeholder="开始时间" name="params[beginTime]"/> <input type="text" class="time-input" id="startTime" placeholder="开始时间"/>
<span>-</span> <span>-</span>
<input type="text" class="time-input" id="endTime" placeholder="结束时间" name="params[endTime]"/> <input type="text" class="time-input" id="endTime" placeholder="结束时间"/>
</li> </li>
<li> <li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a> <a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
@ -69,6 +69,7 @@
cleanUrl: prefix + "/clean", cleanUrl: prefix + "/clean",
removeUrl: prefix + "/remove", removeUrl: prefix + "/remove",
exportUrl: prefix + "/export", exportUrl: prefix + "/export",
queryParams: queryParams,
sortName: "loginTime", sortName: "loginTime",
sortOrder: "desc", sortOrder: "desc",
modalName: "登录日志", modalName: "登录日志",
@ -90,7 +91,10 @@
}, },
{ {
field: 'ipaddr', field: 'ipaddr',
title: '登录地址' title: '登录地址',
formatter: function(value, row, index) {
return $.table.tooltip(value);
}
}, },
{ {
field: 'loginLocation', field: 'loginLocation',
@ -125,6 +129,15 @@
$.table.init(options); $.table.init(options);
}); });
function queryParams(params) {
var search = $.table.queryParams(params);
search.params = {
beginTime : beginOfTime($("#startTime").val()),
endTime : endOfTime($("#endTime").val())
};
return search;
}
function unlock() { function unlock() {
$.operate.post(prefix + "/unlock?loginName=" + $.table.selectColumns("loginName")); $.operate.post(prefix + "/unlock?loginName=" + $.table.selectColumns("loginName"));
} }

View File

@ -19,12 +19,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label">请求地址:</label> <label class="col-sm-2 control-label">请求地址:</label>
<div class="form-control-static" th:text="${operLog.operUrl}"> <div class="form-control-static" th:text="${operLog.requestMethod} + ' - ' + ${operLog.operUrl} + ' ' + '(' + '耗时' + ${operLog.costTime} + '毫秒)'">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">请求方式:</label>
<div class="form-control-static" th:text="${operLog.requestMethod}">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -18,7 +18,7 @@
<label>操作人员: </label><input type="text" name="operName"/> <label>操作人员: </label><input type="text" name="operName"/>
</li> </li>
<li class="select-selectpicker"> <li class="select-selectpicker">
<label>操作类型: </label><select id="businessTypes" th:with="type=${@dict.getType('sys_oper_type')}" class="selectpicker" data-none-selected-text="请选择" multiple> <label>操作类型: </label><select id="businessTypes" name="businessTypes" th:with="type=${@dict.getType('sys_oper_type')}" class="selectpicker" data-none-selected-text="请选择" multiple>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option> <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select> </select>
</li> </li>
@ -30,9 +30,9 @@
</li> </li>
<li class="select-time"> <li class="select-time">
<label>操作时间: </label> <label>操作时间: </label>
<input type="text" class="time-input" id="startTime" placeholder="开始时间" name="params[beginTime]"/> <input type="text" class="time-input" id="startTime" placeholder="开始时间"/>
<span>-</span> <span>-</span>
<input type="text" class="time-input" id="endTime" placeholder="结束时间" name="params[endTime]"/> <input type="text" class="time-input" id="endTime" placeholder="结束时间"/>
</li> </li>
<li> <li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="searchPre()"><i class="fa fa-search"></i>&nbsp;搜索</a> <a class="btn btn-primary btn-rounded btn-sm" onclick="searchPre()"><i class="fa fa-search"></i>&nbsp;搜索</a>
@ -92,14 +92,17 @@
}, },
{ {
field: 'title', field: 'title',
title: '系统模块' title: '系统模块',
}, formatter: function(value, row, index) {
return $.table.tooltip(value);
}
},
{ {
field: 'businessType', field: 'businessType',
title: '操作类型', title: '操作类型',
align: 'center', align: 'center',
formatter: function(value, row, index) { formatter: function(value, row, index) {
return $.table.selectDictLabel(datas, value); return $.table.selectDictLabel(datas, value);
} }
}, },
{ {
@ -136,6 +139,14 @@
title: '操作时间', title: '操作时间',
sortable: true sortable: true
}, },
{
field: 'costTime',
title: '消耗时间',
sortable: true,
formatter: function(value, row, index) {
return $.common.sprintf("%s毫秒", value);
}
},
{ {
title: '操作', title: '操作',
align: 'center', align: 'center',
@ -151,6 +162,10 @@
function queryParams(params) { function queryParams(params) {
var search = $.table.queryParams(params); var search = $.table.queryParams(params);
search.params = {
beginTime : beginOfTime($("#startTime").val()),
endTime : endOfTime($("#endTime").val())
};
search.businessTypes = $.common.join($('#businessTypes').selectpicker('val')); search.businessTypes = $.common.join($('#businessTypes').selectpicker('val'));
return search; return search;
} }
@ -160,6 +175,7 @@
} }
function resetPre() { function resetPre() {
resetDate();
$("#operlog-form")[0].reset(); $("#operlog-form")[0].reset();
$("#businessTypes").selectpicker('refresh'); $("#businessTypes").selectpicker('refresh');
$.table.search('operlog-form', 'bootstrap-table'); $.table.search('operlog-form', 'bootstrap-table');

View File

@ -10,7 +10,7 @@
<div class="col-sm-6"> <div class="col-sm-6">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>CPU</h5> <h5><i class="fa fa-microchip"></i> CPU</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"><i class="fa fa-chevron-up"></i> <a class="collapse-link"><i class="fa fa-chevron-up"></i>
</a> </a>
@ -51,7 +51,7 @@
<div class="col-sm-6"> <div class="col-sm-6">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>内存</h5> <h5><i class="fa fa-ticket"></i> 内存</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"><i class="fa fa-chevron-up"></i></a> <a class="collapse-link"><i class="fa fa-chevron-up"></i></a>
<a class="close-link"><i class="fa fa-times"></i></a> <a class="close-link"><i class="fa fa-times"></i></a>
@ -98,7 +98,7 @@
<div class="col-sm-12"> <div class="col-sm-12">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>服务器信息</h5> <h5><i class="fa fa-windows"></i> 服务器信息</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"> <a class="collapse-link">
<i class="fa fa-chevron-up"></i> <i class="fa fa-chevron-up"></i>
@ -138,7 +138,7 @@
<div class="col-sm-12"> <div class="col-sm-12">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>Java虚拟机信息</h5> <h5><i class="fa fa-coffee"></i> Java虚拟机信息</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"> <a class="collapse-link">
<i class="fa fa-chevron-up"></i> <i class="fa fa-chevron-up"></i>
@ -191,7 +191,7 @@
<div class="col-sm-12"> <div class="col-sm-12">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>磁盘状态</h5> <h5><i class="fa fa-hdd-o"></i> 磁盘状态</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"> <a class="collapse-link">
<i class="fa fa-chevron-up"></i> <i class="fa fa-chevron-up"></i>

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.min.css" th:href="@{/css/style.min.css}" rel="stylesheet"/> <link href="../static/css/style.min.css" th:href="@{/css/style.min.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.7.4}" rel="stylesheet"/> <link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.7.7}" rel="stylesheet"/>
<!-- 360浏览器急速模式 --> <!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 --> <!-- 避免IE使用兼容模式 -->
@ -64,7 +64,7 @@
</div> </div>
<div class="signup-footer"> <div class="signup-footer">
<div class="pull-left"> <div class="pull-left">
&copy; 2018-2022 All Rights Reserved. RuoYi <br> &copy; 2018-2023 All Rights Reserved. RuoYi <br>
</div> </div>
</div> </div>
</div> </div>
@ -74,7 +74,7 @@
<script src="../static/ajax/libs/validate/jquery.validate.min.js" th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script> <script src="../static/ajax/libs/validate/jquery.validate.min.js" th:src="@{/ajax/libs/validate/jquery.validate.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.7.4}"></script> <script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.7}"></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.7.4}"></script> <script th:src="@{/ruoyi/js/common.js?v=4.7.7}"></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

@ -57,9 +57,6 @@
"configKey": function() { "configKey": function() {
return $.common.trim($("#configKey").val()); return $.common.trim($("#configKey").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },

View File

@ -61,9 +61,6 @@
"configKey": function() { "configKey": function() {
return $.common.trim($("#configKey").val()); return $.common.trim($("#configKey").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },

View File

@ -76,9 +76,6 @@
"deptName" : function() { "deptName" : function() {
return $.common.trim($("#deptName").val()); return $.common.trim($("#deptName").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },
@ -116,7 +113,7 @@
var options = { var options = {
title: '部门选择', title: '部门选择',
width: "380", width: "380",
url: prefix + "/selectDeptTree/" + treeId, url: prefix + "/selectDeptTree/" + treeId + "/0",
callBack: doSubmit callBack: doSubmit
}; };
$.modal.openOptions(options); $.modal.openOptions(options);

View File

@ -80,9 +80,6 @@
"deptName": function() { "deptName": function() {
return $.common.trim($("#deptName").val()); return $.common.trim($("#deptName").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },

View File

@ -32,7 +32,7 @@
var deptId = [[${deptId}]]; var deptId = [[${deptId}]];
var excludeId = [[${excludeId}]]; var excludeId = [[${excludeId}]];
$(function() { $(function() {
var url = $.common.isEmpty(excludeId) ? prefix + "/treeData": prefix + "/treeData/" + excludeId; var url = prefix + "/treeData/" + excludeId;
var options = { var options = {
url: url, url: url,
expandLevel: 2, expandLevel: 2,

View File

@ -16,6 +16,7 @@
<label class="col-sm-3 control-label is-required">字典类型:</label> <label class="col-sm-3 control-label is-required">字典类型:</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input class="form-control" type="text" name="dictType" id="dictType" required> <input class="form-control" type="text" name="dictType" id="dictType" required>
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 数据存储中的Key值sys_user_sex</span>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -52,9 +53,6 @@
name : function() { name : function() {
return $.common.trim($("#dictType").val()); return $.common.trim($("#dictType").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },

View File

@ -17,6 +17,7 @@
<label class="col-sm-3 control-label is-required">字典类型:</label> <label class="col-sm-3 control-label is-required">字典类型:</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input class="form-control" type="text" name="dictType" id="dictType" th:field="*{dictType}" required> <input class="form-control" type="text" name="dictType" id="dictType" th:field="*{dictType}" required>
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 数据存储中的Key值sys_user_sex</span>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -56,9 +57,6 @@
dictType : function() { dictType : function() {
return $.common.trim($("#dictType").val()); return $.common.trim($("#dictType").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },

View File

@ -31,7 +31,7 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">请求地址:</label> <label class="col-sm-3 control-label" title="访问的请求地址,如:`/system/user`,如外网地址需内链访问则以`http(s)://`开头">请求地址:<i class="fa fa-question-circle-o"></i></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="url" name="url" class="form-control" type="text"> <input id="url" name="url" class="form-control" type="text">
</div> </div>
@ -53,13 +53,13 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label is-required">显示排序:</label> <label class="col-sm-3 control-label is-required" title="数字越小越靠前">显示排序:<i class="fa fa-question-circle-o"></i></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input class="form-control" type="text" name="orderNum" required> <input class="form-control" type="text" name="orderNum" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">图标:</label> <label class="col-sm-3 control-label" title="单击选择需要使用的FontAwesome图标">图标:<i class="fa fa-question-circle-o"></i></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="icon" name="icon" class="form-control" type="text" placeholder="选择图标"> <input id="icon" name="icon" class="form-control" type="text" placeholder="选择图标">
<div class="ms-parent" style="width: 100%;"> <div class="ms-parent" style="width: 100%;">
@ -70,7 +70,7 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">菜单状态:</label> <label class="col-sm-3 control-label" title="选择隐藏则菜单将不会出现在侧边栏,也没有权限被访问">菜单状态:<i class="fa fa-question-circle-o"></i></label>
<div class="col-sm-3"> <div class="col-sm-3">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_show_hide')}"> <div class="radio-box" th:each="dict : ${@dict.getType('sys_show_hide')}">
<input type="radio" th:id="${dict.dictCode}" name="visible" th:value="${dict.dictValue}" th:checked="${dict.default}"> <input type="radio" th:id="${dict.dictCode}" name="visible" th:value="${dict.dictValue}" th:checked="${dict.default}">
@ -113,9 +113,6 @@
"menuName" : function() { "menuName" : function() {
return $.common.trim($("#menuName").val()); return $.common.trim($("#menuName").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },

View File

@ -32,7 +32,7 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">请求地址:</label> <label class="col-sm-3 control-label" title="访问的请求地址,如:`/system/user`,如外网地址需内链访问则以`http(s)://`开头">请求地址:<i class="fa fa-question-circle-o"></i></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="url" name="url" class="form-control" type="text" th:field="*{url}"> <input id="url" name="url" class="form-control" type="text" th:field="*{url}">
</div> </div>
@ -54,13 +54,13 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label is-required">显示排序:</label> <label class="col-sm-3 control-label is-required" title="数字越小越靠前">显示排序:<i class="fa fa-question-circle-o"></i></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input class="form-control" type="text" name="orderNum" th:field="*{orderNum}" required> <input class="form-control" type="text" name="orderNum" th:field="*{orderNum}" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">图标:</label> <label class="col-sm-3 control-label" title="单击选择需要使用的FontAwesome图标">图标:<i class="fa fa-question-circle-o"></i></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="icon" name="icon" class="form-control" type="text" placeholder="选择图标" th:field="*{icon}"> <input id="icon" name="icon" class="form-control" type="text" placeholder="选择图标" th:field="*{icon}">
<div class="ms-parent" style="width: 100%;"> <div class="ms-parent" style="width: 100%;">
@ -71,7 +71,7 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">菜单状态:</label> <label class="col-sm-3 control-label" title="选择隐藏则菜单将不会出现在侧边栏,也没有权限被访问">菜单状态:<i class="fa fa-question-circle-o"></i></label>
<div class="col-sm-3"> <div class="col-sm-3">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_show_hide')}"> <div class="radio-box" th:each="dict : ${@dict.getType('sys_show_hide')}">
<input type="radio" th:id="${dict.dictCode}" name="visible" th:value="${dict.dictValue}" th:field="*{visible}"> <input type="radio" th:id="${dict.dictCode}" name="visible" th:value="${dict.dictValue}" th:field="*{visible}">
@ -122,9 +122,6 @@
"menuName": function() { "menuName": function() {
return $.common.trim($("#menuName").val()); return $.common.trim($("#menuName").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },

View File

@ -57,9 +57,6 @@
"postName" : function() { "postName" : function() {
return $.common.trim($("#postName").val()); return $.common.trim($("#postName").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },
@ -72,9 +69,6 @@
"postCode" : function() { "postCode" : function() {
return $.common.trim($("#postCode").val()); return $.common.trim($("#postCode").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },

View File

@ -61,9 +61,6 @@
"postName" : function() { "postName" : function() {
return $.common.trim($("#postName").val()); return $.common.trim($("#postName").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },
@ -79,9 +76,6 @@
"postCode" : function() { "postCode" : function() {
return $.common.trim($("#postCode").val()); return $.common.trim($("#postCode").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },

View File

@ -81,9 +81,6 @@
"roleName" : function() { "roleName" : function() {
return $.common.trim($("#roleName").val()); return $.common.trim($("#roleName").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },
@ -96,9 +93,6 @@
"roleKey" : function() { "roleKey" : function() {
return $.common.trim($("#roleKey").val()); return $.common.trim($("#roleKey").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },

View File

@ -52,7 +52,7 @@
<script type="text/javascript"> <script type="text/javascript">
$(function() { $(function() {
var url = ctx + "system/dept/roleDeptTreeData?roleId=" + $("#roleId").val(); var url = ctx + "system/role/deptTreeData?roleId=" + $("#roleId").val();
var options = { var options = {
id: "deptTrees", id: "deptTrees",
url: url, url: url,

View File

@ -85,9 +85,6 @@
"roleName": function() { "roleName": function() {
return $.common.trim($("#roleName").val()); return $.common.trim($("#roleName").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },
@ -103,9 +100,6 @@
"roleKey": function() { "roleKey": function() {
return $.common.trim($("#roleKey").val()); return $.common.trim($("#roleKey").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },

View File

@ -163,9 +163,6 @@
"loginName": function() { "loginName": function() {
return $.common.trim($("#loginName").val()); return $.common.trim($("#loginName").val());
} }
},
dataFilter: function(data, type) {
return $.validate.unique(data);
} }
} }
}, },
@ -183,9 +180,6 @@
"email": function () { "email": function () {
return $.common.trim($("#email").val()); return $.common.trim($("#email").val());
} }
},
dataFilter: function (data, type) {
return $.validate.unique(data);
} }
} }
}, },
@ -199,9 +193,6 @@
"phonenumber": function () { "phonenumber": function () {
return $.common.trim($("#phonenumber").val()); return $.common.trim($("#phonenumber").val());
} }
},
dataFilter: function (data, type) {
return $.validate.unique(data);
} }
} }
}, },
@ -239,7 +230,7 @@
function selectDeptTree() { function selectDeptTree() {
var treeId = $("#treeId").val(); var treeId = $("#treeId").val();
var deptId = $.common.isEmpty(treeId) ? "100" : $("#treeId").val(); var deptId = $.common.isEmpty(treeId) ? "100" : $("#treeId").val();
var url = ctx + "system/dept/selectDeptTree/" + deptId; var url = ctx + "system/user/selectDeptTree/" + deptId;
var options = { var options = {
title: '选择部门', title: '选择部门',
width: "380", width: "380",
@ -250,7 +241,6 @@
} }
function doSubmit(index, layero){ function doSubmit(index, layero){
var tree = layero.find("iframe")[0].contentWindow.$._tree;
var body = $.modal.getChildFrame(index); var body = $.modal.getChildFrame(index);
$("#treeId").val(body.find('#treeId').val()); $("#treeId").val(body.find('#treeId').val());
$("#treeName").val(body.find('#treeName').val()); $("#treeName").val(body.find('#treeName').val());

View File

@ -100,9 +100,14 @@
/* 添加角色-提交 */ /* 添加角色-提交 */
function submitHandler(index, layero){ function submitHandler(index, layero){
var rows = $.table.selectFirstColumns(); var roleIds = [];
var data = { "userId": $("#userId").val(), "roleIds": rows.join() }; var data = $('#bootstrap-table').bootstrapTable('getData');
$.operate.saveTab(prefix + "/insertAuthRole", data); for (var i = 0; i < data.length; i++) {
if (data[i][0] || ($.common.isEmpty(data[i][0]) && data[i].flag)) {
roleIds.push(data[i].roleId)
}
}
$.operate.saveTab(prefix + "/insertAuthRole", { "userId": $("#userId").val(), "roleIds": roleIds.join() });
} }
</script> </script>
</body> </body>

View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('部门树选择')" />
<th:block th:include="include :: ztree-css" />
</head>
<style>
body{height:auto;font-family: "Microsoft YaHei";}
button{font-family: "SimSun","Helvetica Neue",Helvetica,Arial;}
</style>
<body class="hold-transition box box-main">
<input id="treeId" name="treeId" type="hidden" th:value="${dept.deptId}"/>
<input id="treeName" name="treeName" type="hidden" th:value="${dept.deptName}"/>
<div class="wrapper"><div class="treeShowHideButton" onclick="$.tree.toggleSearch();">
<label id="btnShow" title="显示搜索" style="display:none;"></label>
<label id="btnHide" title="隐藏搜索"></label>
</div>
<div class="treeSearchInput" id="search">
<label for="keyword">关键字:</label><input type="text" class="empty" id="keyword" maxlength="50">
<button class="btn" id="btn" onclick="$.tree.searchNode()"> 搜索 </button>
</div>
<div class="treeExpandCollapse">
<a href="#" onclick="$.tree.expand()">展开</a> /
<a href="#" onclick="$.tree.collapse()">折叠</a>
</div>
<div id="tree" class="ztree treeselect"></div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: ztree-js" />
<script th:inline="javascript">
var prefix = ctx + "system/user"
var deptId = [[${deptId}]];
$(function() {
var url = prefix + "/deptTreeData";
var options = {
url: url,
expandLevel: 2,
onClick : zOnClick
};
$.tree.init(options);
});
function zOnClick(event, treeId, treeNode) {
var treeId = treeNode.id;
var treeName = treeNode.name;
$("#treeId").val(treeId);
$("#treeName").val(treeName);
}
</script>
</body>
</html>

View File

@ -150,9 +150,6 @@
"email": function() { "email": function() {
return $.common.trim($("#email").val()); return $.common.trim($("#email").val());
} }
},
dataFilter: function (data, type) {
return $.validate.unique(data);
} }
} }
}, },
@ -169,9 +166,6 @@
"phonenumber": function() { "phonenumber": function() {
return $.common.trim($("#phonenumber").val()); return $.common.trim($("#phonenumber").val());
} }
},
dataFilter: function (data, type) {
return $.validate.unique(data);
} }
} }
}, },
@ -203,7 +197,7 @@
/* 用户管理-修改-选择部门树 */ /* 用户管理-修改-选择部门树 */
function selectDeptTree() { function selectDeptTree() {
var deptId = $.common.isEmpty($("#treeId").val()) ? "100" : $("#treeId").val(); var deptId = $.common.isEmpty($("#treeId").val()) ? "100" : $("#treeId").val();
var url = ctx + "system/dept/selectDeptTree/" + deptId; var url = ctx + "system/user/selectDeptTree/" + deptId;
var options = { var options = {
title: '选择部门', title: '选择部门',
width: "380", width: "380",
@ -214,7 +208,6 @@
} }
function doSubmit(index, layero){ function doSubmit(index, layero){
var tree = layero.find("iframe")[0].contentWindow.$._tree;
var body = $.modal.getChildFrame(index); var body = $.modal.getChildFrame(index);
$("#treeId").val(body.find('#treeId').val()); $("#treeId").val(body.find('#treeId').val());
$("#treeName").val(body.find('#treeName').val()); $("#treeName").val(body.find('#treeName').val());

View File

@ -197,9 +197,6 @@
"email": function() { "email": function() {
return $.common.trim($("#email").val()); return $.common.trim($("#email").val());
} }
},
dataFilter: function (data, type) {
return $.validate.unique(data);
} }
} }
}, },
@ -217,9 +214,6 @@
"phonenumber": function() { "phonenumber": function() {
return $.common.trim($("#phonenumber").val()); return $.common.trim($("#phonenumber").val());
} }
},
dataFilter: function (data, type) {
return $.validate.unique(data);
} }
} }
}, },

View File

@ -10,7 +10,7 @@
<div class="box box-main"> <div class="box box-main">
<div class="box-header"> <div class="box-header">
<div class="box-title"> <div class="box-title">
<i class="fa icon-grid"></i> 组织机构 <i class="fa fa-sitemap"></i> 组织机构
</div> </div>
<div class="box-tools pull-right"> <div class="box-tools pull-right">
<a type="button" class="btn btn-box-tool" href="#" onclick="dept()" title="管理部门"><i class="fa fa-edit"></i></a> <a type="button" class="btn btn-box-tool" href="#" onclick="dept()" title="管理部门"><i class="fa fa-edit"></i></a>
@ -54,7 +54,7 @@
</li> </li>
<li> <li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a> <a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a> <a class="btn btn-warning btn-rounded btn-sm" onclick="resetPre()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -191,7 +191,7 @@
function queryDeptTree() function queryDeptTree()
{ {
var url = ctx + "system/dept/treeData"; var url = ctx + "system/user/deptTreeData";
var options = { var options = {
url: url, url: url,
expandLevel: 2, expandLevel: 2,
@ -222,6 +222,16 @@
queryDeptTree(); queryDeptTree();
}); });
/* 自定义重置-表单重置/隐藏框/树节点选择色/搜索 */
function resetPre() {
resetDate();
$("#user-form")[0].reset();
$("#deptId").val("");
$("#parentId").val("");
$(".curSelectedNode").removeClass("curSelectedNode");
$.table.search();
}
/* 用户管理-部门 */ /* 用户管理-部门 */
function dept() { function dept() {
var url = ctx + "system/dept"; var url = ctx + "system/dept";

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.7.4</version> <version>4.7.7</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -77,12 +77,6 @@
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
</dependency> </dependency>
<!-- 文件上传工具类 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<!-- excel工具 --> <!-- excel工具 -->
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>

View File

@ -25,4 +25,9 @@ public @interface DataScope
* 用户表的别名 * 用户表的别名
*/ */
public String userAlias() default ""; public String userAlias() default "";
/**
* 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@RequiresPermissions获取多个权限用逗号分隔开来
*/
public String permission() default "";
} }

View File

@ -88,6 +88,11 @@ public @interface Excel
*/ */
public String[] combo() default {}; public String[] combo() default {};
/**
* 是否需要纵向合并单元格,应对需求:含有list集合单元格)
*/
public boolean needMerge() default false;
/** /**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
*/ */
@ -104,12 +109,27 @@ public @interface Excel
public boolean isStatistics() default false; public boolean isStatistics() default false;
/** /**
* 导出类型0数字 1字符串 * 导出类型0数字 1字符串 2图片
*/ */
public ColumnType cellType() default ColumnType.STRING; public ColumnType cellType() default ColumnType.STRING;
/** /**
* 导出字体颜 * 导出列头背景
*/
public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
/**
* 导出列头字体颜色
*/
public IndexedColors headerColor() default IndexedColors.WHITE;
/**
* 导出单元格背景色
*/
public IndexedColors backgroundColor() default IndexedColors.WHITE;
/**
* 导出单元格字体颜色
*/ */
public IndexedColors color() default IndexedColors.BLACK; public IndexedColors color() default IndexedColors.BLACK;

View File

@ -42,4 +42,9 @@ public @interface Log
* 是否保存响应的参数 * 是否保存响应的参数
*/ */
public boolean isSaveResponseData() default true; public boolean isSaveResponseData() default true;
/**
* 排除指定的请求参数
*/
public String[] excludeParamNames() default {};
} }

View File

@ -111,5 +111,5 @@ public class Constants
* 定时任务违规的字符 * 定时任务违规的字符
*/ */
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "com.ruoyi.common.utils.file" }; "org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config" };
} }

View File

@ -36,56 +36,16 @@ public class UserConstants
/** 是否为系统默认(是) */ /** 是否为系统默认(是) */
public static final String YES = "Y"; public static final String YES = "Y";
/** 是否唯一的返回标识 */
public final static boolean UNIQUE = true;
public final static boolean NOT_UNIQUE = false;
/** /**
* 用户名长度限制 * 用户名长度限制
*/ */
public static final int USERNAME_MIN_LENGTH = 2; public static final int USERNAME_MIN_LENGTH = 2;
public static final int USERNAME_MAX_LENGTH = 20; public static final int USERNAME_MAX_LENGTH = 20;
/** 登录名称是否唯一的返回结果码 */
public final static String USER_NAME_UNIQUE = "0";
public final static String USER_NAME_NOT_UNIQUE = "1";
/** 手机号码是否唯一的返回结果 */
public final static String USER_PHONE_UNIQUE = "0";
public final static String USER_PHONE_NOT_UNIQUE = "1";
/** e-mail 是否唯一的返回结果 */
public final static String USER_EMAIL_UNIQUE = "0";
public final static String USER_EMAIL_NOT_UNIQUE = "1";
/** 部门名称是否唯一的返回结果码 */
public final static String DEPT_NAME_UNIQUE = "0";
public final static String DEPT_NAME_NOT_UNIQUE = "1";
/** 角色名称是否唯一的返回结果码 */
public final static String ROLE_NAME_UNIQUE = "0";
public final static String ROLE_NAME_NOT_UNIQUE = "1";
/** 岗位名称是否唯一的返回结果码 */
public final static String POST_NAME_UNIQUE = "0";
public final static String POST_NAME_NOT_UNIQUE = "1";
/** 角色权限是否唯一的返回结果码 */
public final static String ROLE_KEY_UNIQUE = "0";
public final static String ROLE_KEY_NOT_UNIQUE = "1";
/** 岗位编码是否唯一的返回结果码 */
public final static String POST_CODE_UNIQUE = "0";
public final static String POST_CODE_NOT_UNIQUE = "1";
/** 菜单名称是否唯一的返回结果码 */
public final static String MENU_NAME_UNIQUE = "0";
public final static String MENU_NAME_NOT_UNIQUE = "1";
/** 字典类型是否唯一的返回结果码 */
public final static String DICT_TYPE_UNIQUE = "0";
public final static String DICT_TYPE_NOT_UNIQUE = "1";
/** 参数键名是否唯一的返回结果码 */
public final static String CONFIG_KEY_UNIQUE = "0";
public final static String CONFIG_KEY_NOT_UNIQUE = "1";
/** /**
* 密码长度限制 * 密码长度限制
*/ */

View File

@ -0,0 +1,27 @@
package com.ruoyi.common.core.context;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import com.ruoyi.common.core.text.Convert;
/**
* 权限信息
*
* @author ruoyi
*/
public class PermissionContextHolder
{
private static final String PERMISSION_CONTEXT_ATTRIBUTES = "PERMISSION_CONTEXT";
public static void setContext(String permission)
{
RequestContextHolder.currentRequestAttributes().setAttribute(PERMISSION_CONTEXT_ATTRIBUTES, permission,
RequestAttributes.SCOPE_REQUEST);
}
public static String getContext()
{
return Convert.toStr(RequestContextHolder.currentRequestAttributes().getAttribute(PERMISSION_CONTEXT_ATTRIBUTES,
RequestAttributes.SCOPE_REQUEST));
}
}

View File

@ -1,6 +1,7 @@
package com.ruoyi.common.core.domain; package com.ruoyi.common.core.domain;
import java.util.HashMap; import java.util.HashMap;
import java.util.Objects;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
@ -81,20 +82,6 @@ public class AjaxResult extends HashMap<String, Object>
} }
} }
/**
* 方便链式调用
*
* @param key 键
* @param value 值
* @return 数据对象
*/
@Override
public AjaxResult put(String key, Object value)
{
super.put(key, value);
return this;
}
/** /**
* 返回成功消息 * 返回成功消息
* *
@ -193,4 +180,38 @@ public class AjaxResult extends HashMap<String, Object>
{ {
return new AjaxResult(Type.ERROR, msg, data); return new AjaxResult(Type.ERROR, msg, data);
} }
/**
* 是否为成功消息
*
* @return 结果
*/
public boolean isSuccess()
{
return !isError();
}
/**
* 是否为错误消息
*
* @return 结果
*/
public boolean isError()
{
return Objects.equals(Type.ERROR.value, this.get(CODE_TAG));
}
/**
* 方便链式调用
*
* @param key 键
* @param value 值
* @return 数据对象
*/
@Override
public AjaxResult put(String key, Object value)
{
super.put(key, value);
return this;
}
} }

View File

@ -5,6 +5,8 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
/** /**
* Entity基类 * Entity基类
@ -16,6 +18,7 @@ public class BaseEntity implements Serializable
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 搜索值 */ /** 搜索值 */
@JsonIgnore
private String searchValue; private String searchValue;
/** 创建者 */ /** 创建者 */
@ -36,6 +39,7 @@ public class BaseEntity implements Serializable
private String remark; private String remark;
/** 请求参数 */ /** 请求参数 */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> params; private Map<String, Object> params;
public String getSearchValue() public String getSearchValue()

View File

@ -101,4 +101,14 @@ public class R<T> implements Serializable
{ {
this.data = data; this.data = data;
} }
public static <T> Boolean isError(R<T> ret)
{
return !isSuccess(ret);
}
public static <T> Boolean isSuccess(R<T> ret)
{
return R.SUCCESS == ret.getCode();
}
} }

View File

@ -131,7 +131,7 @@ public class SysDictData extends BaseEntity
public boolean getDefault() public boolean getDefault()
{ {
return UserConstants.YES.equals(this.isDefault) ? true : false; return UserConstants.YES.equals(this.isDefault);
} }
public String getIsDefault() public String getIsDefault()

View File

@ -1,5 +1,6 @@
package com.ruoyi.common.core.domain.entity; package com.ruoyi.common.core.domain.entity;
import java.util.Set;
import javax.validation.constraints.*; import javax.validation.constraints.*;
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;
@ -52,6 +53,9 @@ public class SysRole extends BaseEntity
/** 部门组(数据权限) */ /** 部门组(数据权限) */
private Long[] deptIds; private Long[] deptIds;
/** 角色菜单权限 */
private Set<String> permissions;
public SysRole() public SysRole()
{ {
@ -177,6 +181,16 @@ public class SysRole extends BaseEntity
this.deptIds = deptIds; this.deptIds = deptIds;
} }
public Set<String> getPermissions()
{
return permissions;
}
public void setPermissions(Set<String> permissions)
{
this.permissions = permissions;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -250,6 +250,7 @@ public class SysUser extends BaseEntity
this.password = password; this.password = password;
} }
@JsonIgnore
public String getSalt() public String getSalt()
{ {
return salt; return salt;

View File

@ -713,7 +713,7 @@ public class Convert
} }
if (value instanceof Double) if (value instanceof Double)
{ {
return new BigDecimal((Double) value); return BigDecimal.valueOf((Double) value);
} }
if (value instanceof Integer) if (value instanceof Integer)
{ {

View File

@ -7,7 +7,6 @@ package com.ruoyi.common.exception;
*/ */
public class GlobalException extends RuntimeException public class GlobalException extends RuntimeException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
@ -45,6 +44,7 @@ public class GlobalException extends RuntimeException
return this; return this;
} }
@Override
public String getMessage() public String getMessage()
{ {
return message; return message;

View File

@ -44,6 +44,7 @@ public final class ServiceException extends RuntimeException
return this; return this;
} }
@Override
public String getMessage() public String getMessage()
{ {
return message; return message;

View File

@ -0,0 +1,61 @@
package com.ruoyi.common.exception.file;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
* 文件上传异常类
*
* @author ruoyi
*/
public class FileUploadException extends Exception
{
private static final long serialVersionUID = 1L;
private final Throwable cause;
public FileUploadException()
{
this(null, null);
}
public FileUploadException(final String msg)
{
this(msg, null);
}
public FileUploadException(String msg, Throwable cause)
{
super(msg);
this.cause = cause;
}
@Override
public void printStackTrace(PrintStream stream)
{
super.printStackTrace(stream);
if (cause != null)
{
stream.println("Caused by:");
cause.printStackTrace(stream);
}
}
@Override
public void printStackTrace(PrintWriter writer)
{
super.printStackTrace(writer);
if (cause != null)
{
writer.println("Caused by:");
cause.printStackTrace(writer);
}
}
@Override
public Throwable getCause()
{
return cause;
}
}

View File

@ -1,7 +1,6 @@
package com.ruoyi.common.exception.file; package com.ruoyi.common.exception.file;
import java.util.Arrays; import java.util.Arrays;
import org.apache.commons.fileupload.FileUploadException;
/** /**
* 文件上传 误异常类 * 文件上传 误异常类

View File

@ -0,0 +1,16 @@
package com.ruoyi.common.exception.user;
/**
* 黑名单IP异常类
*
* @author ruoyi
*/
public class BlackListException extends UserException
{
private static final long serialVersionUID = 1L;
public BlackListException()
{
super("login.blocked", null);
}
}

View File

@ -145,16 +145,20 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
} }
/** /**
* 计算两个时间差 * 计算时间差
*
* @param endTime 最后时间
* @param startTime 开始时间
* @return 时间差(天/小时/分钟)
*/ */
public static String getDatePoor(Date endDate, Date nowDate) public static String timeDistance(Date endDate, Date startTime)
{ {
long nd = 1000 * 24 * 60 * 60; long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60; long nh = 1000 * 60 * 60;
long nm = 1000 * 60; long nm = 1000 * 60;
// long ns = 1000; // long ns = 1000;
// 获得两个时间的毫秒时间差异 // 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - nowDate.getTime(); long diff = endDate.getTime() - startTime.getTime();
// 计算差多少天 // 计算差多少天
long day = diff / nd; long day = diff / nd;
// 计算差多少小时 // 计算差多少小时

View File

@ -82,7 +82,7 @@ public class DictUtils
StringBuilder propertyString = new StringBuilder(); StringBuilder propertyString = new StringBuilder();
List<SysDictData> datas = getDictCache(dictType); List<SysDictData> datas = getDictCache(dictType);
if (StringUtils.containsAny(separator, dictValue) && StringUtils.isNotEmpty(datas)) if (StringUtils.containsAny(dictValue, separator) && StringUtils.isNotEmpty(datas))
{ {
for (SysDictData dict : datas) for (SysDictData dict : datas)
{ {
@ -122,7 +122,7 @@ public class DictUtils
StringBuilder propertyString = new StringBuilder(); StringBuilder propertyString = new StringBuilder();
List<SysDictData> datas = getDictCache(dictType); List<SysDictData> datas = getDictCache(dictType);
if (StringUtils.containsAny(separator, dictLabel) && StringUtils.isNotEmpty(datas)) if (StringUtils.containsAny(dictLabel, separator) && StringUtils.isNotEmpty(datas))
{ {
for (SysDictData dict : datas) for (SysDictData dict : datas)
{ {

View File

@ -11,6 +11,13 @@ import javax.servlet.http.HttpServletRequest;
*/ */
public class IpUtils public class IpUtils
{ {
public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";
// 匹配 ip
public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")";
public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))";
// 匹配网段
public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")";
/** /**
* 获取客户端IP * 获取客户端IP
* *
@ -247,7 +254,7 @@ public class IpUtils
} }
} }
} }
return ip; return StringUtils.substring(ip, 0, 255);
} }
/** /**
@ -260,4 +267,104 @@ public class IpUtils
{ {
return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
} }
/**
* 是否为IP
*/
public static boolean isIP(String ip)
{
return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP);
}
/**
* 是否为IP或 *为间隔的通配符地址
*/
public static boolean isIpWildCard(String ip)
{
return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD);
}
/**
* 检测参数是否在ip通配符里
*/
public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip)
{
String[] s1 = ipWildCard.split("\\.");
String[] s2 = ip.split("\\.");
boolean isMatchedSeg = true;
for (int i = 0; i < s1.length && !s1[i].equals("*"); i++)
{
if (!s1[i].equals(s2[i]))
{
isMatchedSeg = false;
break;
}
}
return isMatchedSeg;
}
/**
* 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串
*/
public static boolean isIPSegment(String ipSeg)
{
return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG);
}
/**
* 判断ip是否在指定网段中
*/
public static boolean ipIsInNetNoCheck(String iparea, String ip)
{
int idx = iparea.indexOf('-');
String[] sips = iparea.substring(0, idx).split("\\.");
String[] sipe = iparea.substring(idx + 1).split("\\.");
String[] sipt = ip.split("\\.");
long ips = 0L, ipe = 0L, ipt = 0L;
for (int i = 0; i < 4; ++i)
{
ips = ips << 8 | Integer.parseInt(sips[i]);
ipe = ipe << 8 | Integer.parseInt(sipe[i]);
ipt = ipt << 8 | Integer.parseInt(sipt[i]);
}
if (ips > ipe)
{
long t = ips;
ips = ipe;
ipe = t;
}
return ips <= ipt && ipt <= ipe;
}
/**
* 校验ip是否符合过滤串规则
*
* @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99`
* @param ip 校验IP地址
* @return boolean 结果
*/
public static boolean isMatchedIp(String filter, String ip)
{
if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip))
{
return false;
}
String[] ips = filter.split(";");
for (String iStr : ips)
{
if (isIP(iStr) && iStr.equals(ip))
{
return true;
}
else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip))
{
return true;
}
else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip))
{
return true;
}
}
return false;
}
} }

View File

@ -1,12 +1,16 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
/** /**
@ -173,4 +177,40 @@ public class ServletUtils
} }
return flag; return flag;
} }
/**
* 内容编码
*
* @param str 内容
* @return 编码后的内容
*/
public static String urlEncode(String str)
{
try
{
return URLEncoder.encode(str, Constants.UTF8);
}
catch (UnsupportedEncodingException e)
{
return StringUtils.EMPTY;
}
}
/**
* 内容解码
*
* @param str 内容
* @return 解码后的内容
*/
public static String urlDecode(String str)
{
try
{
return URLDecoder.decode(str, Constants.UTF8);
}
catch (UnsupportedEncodingException e)
{
return StringUtils.EMPTY;
}
}
} }

View File

@ -65,7 +65,7 @@ public class ShiroUtils
public static String getIp() public static String getIp()
{ {
return getSubject().getSession().getHost(); return StringUtils.substring(getSubject().getSession().getHost(), 0, 128);
} }
public static String getSessionId() public static String getSessionId()

View File

@ -324,6 +324,32 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
return list; return list;
} }
/**
* 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
*
* @param collection 给定的集合
* @param array 给定的数组
* @return boolean 结果
*/
public static boolean containsAny(Collection<String> collection, String... array)
{
if (isEmpty(collection) || isEmpty(array))
{
return false;
}
else
{
for (String str : array)
{
if (collection.contains(str))
{
return true;
}
}
return false;
}
}
/** /**
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写 * 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
* *

View File

@ -1,87 +0,0 @@
package com.ruoyi.common.utils;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import com.ruoyi.common.utils.StringUtils;
/**
* 配置处理工具类
*
* @author yml
*/
public class YamlUtil
{
public static Map<?, ?> loadYaml(String fileName) throws FileNotFoundException
{
InputStream in = YamlUtil.class.getClassLoader().getResourceAsStream(fileName);
return StringUtils.isNotEmpty(fileName) ? (LinkedHashMap<?, ?>) new Yaml().load(in) : null;
}
public static void dumpYaml(String fileName, Map<?, ?> map) throws IOException
{
if (StringUtils.isNotEmpty(fileName))
{
FileWriter fileWriter = new FileWriter(YamlUtil.class.getResource(fileName).getFile());
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml = new Yaml(options);
yaml.dump(map, fileWriter);
}
}
public static Object getProperty(Map<?, ?> map, Object qualifiedKey)
{
if (map != null && !map.isEmpty() && qualifiedKey != null)
{
String input = String.valueOf(qualifiedKey);
if (!"".equals(input))
{
if (input.contains("."))
{
int index = input.indexOf(".");
String left = input.substring(0, index);
String right = input.substring(index + 1, input.length());
return getProperty((Map<?, ?>) map.get(left), right);
}
else if (map.containsKey(input))
{
return map.get(input);
}
else
{
return null;
}
}
}
return null;
}
@SuppressWarnings("unchecked")
public static void setProperty(Map<?, ?> map, Object qualifiedKey, Object value)
{
if (map != null && !map.isEmpty() && qualifiedKey != null)
{
String input = String.valueOf(qualifiedKey);
if (!input.equals(""))
{
if (input.contains("."))
{
int index = input.indexOf(".");
String left = input.substring(0, index);
String right = input.substring(index + 1, input.length());
setProperty((Map<?, ?>) map.get(left), right, value);
}
else
{
((Map<Object, Object>) map).put(qualifiedKey, value);
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More