104 Commits
Author SHA1 Message Date
RuoYi 680ad3a5e0 若依 v4.5.1 2020-11-18 09:36:21 +08:00
RuoYi a825075dd5 全局配置保持和其他应用命名相同 2020-11-17 10:34:04 +08:00
RuoYi 18f6366f2e 阻止任意文件下载漏洞 2020-11-17 09:33:36 +08:00
RuoYi 6ca8c712e3 升级shiro到最新版1.7.0 阻止权限绕过漏洞 2020-11-16 15:10:51 +08:00
RuoYi cefb14e521 新增表格行触发事件(onCheck、onUncheck、onCheckAll、onUncheckAll) 2020-11-12 10:30:15 +08:00
RuoYi c27ea9d3f4 修复多页签关闭非当前选项出现空白问题 2020-11-11 12:17:16 +08:00
RuoYi 80bf31dcbc 升级druid到最新版本v1.2.2 2020-11-05 14:01:19 +08:00
RuoYi 79ab6b558a 2020年双十一云服务器优惠,错过又要等一年 2020-11-04 16:54:55 +08:00
RuoYi 1c83adc507 去除多余的代码 2020-11-04 16:54:36 +08:00
RuoYi 4b265bb193 代码生成预览支持高亮显示 2020-11-04 12:02:51 +08:00
RuoYi 057a390bff mapperLocations配置支持分隔符 2020-11-02 17:05:08 +08:00
若依andGitee f32dd2bd07 !224 MyBatisConfig mapperLocations 不能识别 , 分隔
Merge pull request !224 from GodOfBug/master
2020-11-02 17:01:43 +08:00
GodOfBug 06cde445b5 修复mapperLocations问题 2020-11-02 16:21:35 +08:00
RuoYi 7a6a109a8c 权限调整 2020-10-22 19:58:32 +08:00
Ricky a955d38ef1 个人中心头像和上传头像增加默认图片 2020-10-22 18:07:59 +08:00
RuoYi 685e090f2f 权限调整 2020-10-22 17:13:10 +08:00
Ricky 207126847e 个人中心头像和上传头像增加默认图片 2020-10-22 09:40:31 +08:00
RuoYi 64a0a05b14 若依 v4.5.0 2020-10-20 09:41:15 +08:00
RuoYi 5332756526 修复代码生成模板文件上传组件缺少ctx的问题 2020-10-19 13:32:13 +08:00
Ricky 260370c328 修复代码生成模板文件上传组件缺少ctx的问题 2020-10-19 12:44:55 +08:00
RuoYi 707b51b247 格式化前端代码 2020-10-18 12:05:21 +08:00
RuoYi 896cbb0842 关闭缓存统计信息 2020-10-17 19:24:27 +08:00
RuoYi d59bd8b8c4 修正拼写错误 2020-10-17 17:55:36 +08:00
RuoYi ee8a9ad78b 去除用户手机邮箱部门必填验证 2020-10-17 09:58:55 +08:00
RuoYi 509a6e1a73 注册账号设置默认用户名称及密码最后更新时间 2020-10-17 09:56:08 +08:00
RuoYi 64c865cc70 添加检查密码范围支持的特殊字符包括:~!@#$%^&*()-=_+ 2020-10-16 10:04:51 +08:00
RuoYi 471c8825ba 账号密码支持自定义更新周期 2020-10-15 17:34:26 +08:00
RuoYi e0523d1c2d 初始密码支持自定义修改策略 2020-10-15 13:27:46 +08:00
RuoYi aa0c930682 用户修改新密码不能与旧密码相同 2020-10-15 13:15:08 +08:00
RuoYi 182c377ecb 调整sql默认时间 2020-10-15 13:06:19 +08:00
RuoYi 3f9d0cf2ea 新增日期格式化方法 2020-10-14 14:38:37 +08:00
若依andGitee 951a4d3707 !222 解决代码生成没有bit类型的问题
Merge pull request !222 from natsuki-kining/master
2020-10-13 18:02:10 +08:00
natsuki_kining 0139ed2a07 解决代码生成没有bit类型的问题 2020-10-13 17:35:02 +08:00
RuoYi 74ec5204fe 树结构加载添加callBack回调方法 2020-10-13 12:05:06 +08:00
Ricky 7d8b7ba2d5 解决用户管理页面滚动返回顶部条失效 2020-10-12 11:47:15 +08:00
RuoYi 406889ae07 升级pagehelper到最新版1.3.0 2020-10-10 16:25:51 +08:00
Ricky be47059951 回显数据字典(字符串数组)增加空值判断 2020-10-10 12:01:19 +08:00
RuoYi 5fd26b2d47 升级druid到最新版本v1.2.1 2020-10-09 11:51:45 +08:00
RuoYi 12f4d99dcf 升级fastjson到最新版1.2.74 2020-10-09 11:50:38 +08:00
RuoYi 6019db240a 更换过期二维码 2020-10-09 11:50:10 +08:00
RuoYi 1f0b417d9d 修改前端密码长度校验和错误提示不符问题 2020-10-06 16:42:10 +08:00
RuoYi 22efbd0bcf jna指定版本 2020-10-03 11:51:36 +08:00
RuoYi 5a769dbdb2 update README.md 2020-09-30 19:29:17 +08:00
RuoYi 63f394b0e9 优化代码 2020-09-30 15:57:06 +08:00
若依andGitee 80ff14f88f !211 代码生成增加createBy、updateBy
Merge pull request !211 from Wanchen/master
2020-09-30 15:55:04 +08:00
若依andGitee a12b54dcbf !214 AjaxResult重写put方法,以方便链式调用
Merge pull request !214 from 刘星/master
2020-09-30 15:52:36 +08:00
若依andGitee d2059ee282 !217 增强验证码校验的语义,更易懂
Merge pull request !217 from Gszekt/N/A
2020-09-30 15:43:55 +08:00
若依andGitee a5d9dd8068 !220 修改session同步逻辑错误
Merge pull request !220 from Gszekt/master
2020-09-29 19:55:47 +08:00
GszektandGitee 145660138c 修改session同步逻辑错误 2020-09-29 19:23:37 +08:00
RuoYi 74445e76c3 添加导入数据弹出窗体自定义宽高 2020-09-29 17:48:37 +08:00
RuoYi 03c952d819 用户信息参数返回忽略掉密码字段 2020-09-29 17:08:36 +08:00
GszektandGitee 8610033c26 增强验证码校验的语义,更易懂 2020-09-28 20:27:57 +08:00
RuoYi 613a21edd0 升级bootstrap-fileinput到最新版本5.1.2 2020-09-24 20:11:28 +08:00
RuoYi 0c93087b58 升级oshi到最新版本v5.2.5 2020-09-22 18:16:27 +08:00
RuoYi aa8e0e765d 修正文字错误 2020-09-22 11:00:10 +08:00
RuoYi b277995c64 修正文字错误 2020-09-22 10:59:24 +08:00
RuoYi dc2a723c1b 修正语义错误&删除多余方法 2020-09-22 09:53:08 +08:00
RuoYi ffb2d2bc87 修改主子表提交示例代码 2020-09-22 09:26:40 +08:00
liuxing dd0c5a2bfb AjaxResult重写put方法,以方便链式调用 2020-09-19 12:23:30 +08:00
RuoYi 8c1e893657 升级springboot到2.1.17 提升安全性 2020-09-18 16:42:44 +08:00
Ricky 5d73b1d8de 优化$.modal.close方法 2020-09-18 12:13:31 +08:00
RuoYi 59a45cf5ad 导入excel整形值校验优化 2020-09-17 17:10:17 +08:00
RuoYi acfb6a56bb 菜单&数据权限新增(展开/折叠 全选/全不选 父子联动) 2020-09-16 11:47:22 +08:00
RuoYi b7e20b48cb 表单向导插件更换为jquery-smartwizard 2020-09-15 17:39:54 +08:00
Ricky 4e5923a763 替换表单向导插件为jquery-smartwizard 2020-09-15 16:55:13 +08:00
RuoYi c523be9f34 新增表格列宽拖动插件 2020-09-15 14:09:29 +08:00
Ricky ded9916649 优化页脚显示控制的判断表达式 2020-09-15 09:51:17 +08:00
RuoYi b20ad52d6a 输入框组验证错误后置图标提示颜色 2020-09-14 15:45:03 +08:00
RuoYi e118d94b24 限制系统内置参数不允许删除 2020-09-14 15:00:29 +08:00
RuoYi 1a46a430b6 添加新群号 2020-09-14 10:33:55 +08:00
RuoYi 3cff281172 新增是否开启页脚功能 2020-09-11 17:00:12 +08:00
Ricky a1ded39bb6 修复窗体大小改变后浮动提示框失效问题 2020-09-11 13:33:24 +08:00
Ricky dab0a4f0d0 修复点击左上角返回首页,浏览器刷新导致之前的菜单重新弹出;超出字符提示增加换行 2020-09-11 10:44:03 +08:00
Ricky 3039601c42 修复点击左上角返回首页,浏览器刷新导致之前的菜单重新弹出;超出字符提示增加换行 2020-09-11 10:42:54 +08:00
Ricky 5c40ca6eb8 修复菜单收起时当前选中菜单和展开的子菜单间存在间隔 2020-09-10 14:45:41 +08:00
Ricky a1e7c5be0c 修复菜单收起时当前选中菜单和展开的子菜单间存在间隔 2020-09-10 13:56:56 +08:00
RuoYi 7e615f6c84 新增表格参数(通过自定义函数设置标题样式headerStyle) 2020-09-10 11:19:16 +08:00
Ricky c90e6f5fba 调整字符串格式化(%s )参数为空时转为空字符串 2020-09-10 09:10:12 +08:00
Wan Chen 9b40918a35 代码生成增加createBy、updateBy 2020-09-09 18:28:29 +08:00
RuoYi fc2b73f2a8 Excel导出类型NUMERIC支持精度浮点类型 2020-09-09 11:27:02 +08:00
RuoYi 7b3517f699 降级druid到版本v1.1.22,防止出现一些错误 2020-09-09 10:07:42 +08:00
RuoYi 510feabe4b 修改页签行高 2020-09-07 12:04:09 +08:00
若依andGitee b4c27fa22b !205 update ruoyi-admin/src/main/resources/templates/index-topnav.html.
Merge pull request !205 from Hacker/N/A
2020-09-04 17:01:01 +08:00
Ricky b3c3759e55 数据字典缓存空值处理 2020-09-04 15:37:58 +08:00
HackerandGitee 4ec66e6a9f update ruoyi-admin/src/main/resources/templates/index-topnav.html.
实例菜单开关控制
2020-09-04 14:03:41 +08:00
RuoYi 6b67ebb818 升级druid到最新版本v1.1.23 2020-09-04 13:46:39 +08:00
RuoYi 5d41851048 去除mini菜单窗口底部波浪线 2020-09-04 13:46:28 +08:00
Ricky 255799ea3a 生成代码补充必填样式 2020-09-04 11:56:54 +08:00
Ricky 8a5744f492 新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单) 2020-09-04 11:36:45 +08:00
RuoYi 468fa72041 新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单) 2020-09-03 20:36:54 +08:00
RuoYi b4aa7232a0 新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单) 2020-09-03 15:41:29 +08:00
RuoYi 2b0e3546ff 新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单) 2020-09-03 12:57:44 +08:00
RuoYi bf1e52fd9d 新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单) 2020-09-03 10:03:49 +08:00
RuoYi 947120d136 新增表格参数(通过自定义函数设置页脚样式footerStyle) 2020-08-29 11:44:24 +08:00
RuoYi ae7c436730 上传媒体类型添加视频格式 2020-08-29 11:43:36 +08:00
RuoYi 3dc4cb78e5 数据权限判断参数类型 2020-08-28 15:37:16 +08:00
RuoYi 118cd15204 修正数据库字符串类型nvarchar 2020-08-28 14:14:50 +08:00
RuoYi b9c4796a27 优化递归子节点 2020-08-28 10:30:02 +08:00
Ricky 2f25abaaf2 修复多表格搜索formId无效 2020-08-27 13:28:58 +08:00
Ricky cc35627ab1 添加Ajax局部刷新demo 2020-08-26 16:33:19 +08:00
RuoYi adcdd046d2 导出Excel调整targetAttr获取值方法,防止get方法不规范 2020-08-26 15:39:19 +08:00
RuoYi 00392e6809 生成页面时不忽略remark属性 2020-08-26 14:12:55 +08:00
RuoYi d506a69290 字典数据列表页添加关闭按钮 2020-08-26 13:35:36 +08:00
RuoYi feec4f236e Excel注解支持自动统计数据总和 2020-08-26 11:17:37 +08:00
146 changed files with 6022 additions and 4894 deletions
+26 -23
View File
@@ -2,11 +2,14 @@
一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适的。于是利用空闲休息时间开始自己写了一套后台系统。如此有了若依。她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,OA。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
性别男,若依是给还没有出生女儿取的名字(寓意:你若不离不弃,我必生死相依)
性别男,若依是给女儿取的名字(寓意:你若不离不弃,我必生死相依)
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
* 感谢 [hplus](https://gitee.com/hplus_admin/hplus) 后台主题 UI 框架。
* 前后端分离版本,请移步[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
* 阿里云优惠券:[点我进入](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)  
* 感谢 [hplus](https://gitee.com/hplus_admin/hplus) 后台主题 UI 框架。
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)  
* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)  
## 内置功能
@@ -40,43 +43,43 @@
<table>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/25b5e333768d013d45a990c152dbe4d9d6e.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/e29fd81b2d43b517f99535564af41f9d1d5.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-42e518aa72a24d228427a1261cb3679f395.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-7f20dd0edba25e5187c5c4dd3ec7d3d9797.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/629f1510fb6205f773c8c284863406b694f.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/9124eda87df0e72427cd63f458b813e3363.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-2dae3d87f6a8ca05057db059cd9a411d51d.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-ea4d98423471e55fba784694e45d12bd4bb.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/438c59467afd0097cfbe9c89db932661687.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/72a015041db6843aca7f7b273688cb346f8.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-7f6c6e9f5873efca09bd2870ee8468b8fce.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-c708b65f2c382a03f69fe1efa8d341e6cff.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/ecb5f1c9929f1933f733f796749b2df73d9.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/e4283d500eb10e8dd8701e7742f7facb065.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-9ab586c47dd5c7b92bca0d727962c90e3b8.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-ef954122a2080e02013112db21754b955c6.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/2531dbf419a1b114e1177f8d2a120b8a9c3.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/8b740a42dddc1e5a8a150d97c5060df258b.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-088edb4d531e122415a1e2342bccb1a9691.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-f886fe19bd820c0efae82f680223cac196c.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/00e642dc3515919b3760968cc496a12a849.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/f72d28a3e60413a4e1b5c7c2f45f962fd65.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-c7a2eb71fa65d6e660294b4bccca613d638.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-e60137fb0787defe613bd83331dc4755a70.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/19222e495869a2a99fc31c5d2bd4539e1e7.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/264d25176f4e22b4b38e95fe6ce73775299.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-7c51c1b5758f0a0f92ed3c60469b7526f9f.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-15181aed45bb2461aa97b594cbf2f86ea5f.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/d85fbb59be27fb33f68bdbb6e8bc967c97b.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/bb902d2c54bad02a052e9a05e5f22a93df1.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-83326ad52ea63f67233d126226738054d98.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-3bd6d31e913b70df00107db51d64ef81df7.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/30cda883bb9a7f74f1454314e64f949942d.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/deebaaa8d6b14a419ed5911f49e3f222a6f.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-70a2225836bc82042a6785edf6299e2586a.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-0184d6ab01fdc6667a14327fcaf8b46345d.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/bed2b98a44e7ae820c2885329e711965c28.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-64d8086dc2c02c8f71170290482f7640098.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-6d73c2140ce694e3de4c05035fdc1868d4c.png"/></td>
</tr>
</table>
@@ -84,4 +87,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群: [![加入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)
+22 -9
View File
@@ -5,27 +5,28 @@
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>4.4.0</version>
<version>4.5.1</version>
<name>ruoyi</name>
<url>http://www.ruoyi.vip</url>
<description>若依管理系统</description>
<properties>
<ruoyi.version>4.4.0</ruoyi.version>
<ruoyi.version>4.5.1</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<shiro.version>1.6.0</shiro.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<shiro.version>1.7.0</shiro.version>
<thymeleaf.extras.shiro.version>2.0.0</thymeleaf.extras.shiro.version>
<mybatis.boot.version>1.3.2</mybatis.boot.version>
<druid.version>1.1.14</druid.version>
<druid.version>1.2.2</druid.version>
<bitwalker.version>1.19</bitwalker.version>
<kaptcha.version>2.3.2</kaptcha.version>
<swagger.version>2.9.2</swagger.version>
<pagehelper.boot.version>1.2.5</pagehelper.boot.version>
<fastjson.version>1.2.73</fastjson.version>
<oshi.version>3.9.1</oshi.version>
<pagehelper.boot.version>1.3.0</pagehelper.boot.version>
<fastjson.version>1.2.74</fastjson.version>
<oshi.version>5.2.5</oshi.version>
<jna.version>5.5.0</jna.version>
<commons.io.version>2.5</commons.io.version>
<commons.fileupload.version>1.3.3</commons.fileupload.version>
<poi.version>3.17</poi.version>
@@ -40,7 +41,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.1.RELEASE</version>
<version>2.1.17.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -108,6 +109,18 @@
<version>${oshi.version}</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna.version}</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>${jna.version}</version>
</dependency>
<!-- swagger2-->
<dependency>
<groupId>io.springfox</groupId>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.4.0</version>
<version>4.5.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
@@ -43,16 +43,15 @@ public class CommonController
{
try
{
if (!FileUtils.isValidFilename(fileName))
if (!FileUtils.checkAllowDownload(fileName))
{
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
}
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
String filePath = Global.getDownloadPath() + fileName;
String filePath = RuoYiConfig.getDownloadPath() + fileName;
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, realFileName);
FileUtils.writeBytes(filePath, response.getOutputStream());
if (delete)
{
@@ -75,7 +74,7 @@ public class CommonController
try
{
// 上传文件路径
String filePath = Global.getUploadPath();
String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
@@ -97,16 +96,25 @@ public class CommonController
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
throws Exception
{
// 本地资源路径
String localPath = Global.getProfile();
// 数据库资源地址
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
// 下载名称
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, downloadName);
FileUtils.writeBytes(downloadPath, response.getOutputStream());
try
{
if (!FileUtils.checkAllowDownload(resource))
{
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
}
// 本地资源路径
String localPath = RuoYiConfig.getProfile();
// 数据库资源地址
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
// 下载名称
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, downloadName);
FileUtils.writeBytes(downloadPath, response.getOutputStream());
}
catch (Exception e)
{
log.error("下载文件失败", e);
}
}
}
@@ -5,11 +5,15 @@ import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.CxSelect;
import com.ruoyi.common.json.JSONObject;
import com.ruoyi.common.json.JSONObject.JSONArray;
import com.ruoyi.common.utils.StringUtils;
/**
* 表单相关
@@ -217,6 +221,47 @@ public class DemoFormController
return prefix + "/cxselect";
}
/**
* 局部刷新
*/
@GetMapping("/localrefresh")
public String localRefresh(ModelMap mmap)
{
JSONArray list = new JSONArray();
JSONObject item = new JSONObject();
item.put("name", "这条任务数据是由ModelMap传递到页面的,点击添加按钮后会将这条数据替换为新数据");
item.put("type", "默认");
item.put("date", "2020.06.10");
list.add(item);
mmap.put("tasks",list);
mmap.put("min",2);
mmap.put("max",10);
return prefix + "/localrefresh";
}
/**
* 局部刷新-添加任务
* @param fragment 页面中的模板名称
* @param taskName 任务名称
*/
@PostMapping("/localrefresh/task")
public String localRefreshTask(String fragment,String taskName,ModelMap mmap)
{
JSONArray list = new JSONArray();
JSONObject item = new JSONObject();
item.put("name", StringUtils.defaultIfBlank(taskName, "通过电话销售过程中了解各盛市的设备仪器使用、采购情况及相关重要追踪人"));
item.put("type", "新增");
item.put("date", "2018.06.10");
list.add(item);
item = new JSONObject();
item.put("name", "提高自己电话营销技巧,灵活专业地与客户进行电话交流");
item.put("type", "新增");
item.put("date", "2018.06.12");
list.add(item);
mmap.put("tasks",list);
return prefix + "/localrefresh::" + fragment;
}
/**
* 模拟数据
*/
@@ -214,6 +214,15 @@ public class DemoTableController extends BaseController
return prefix + "/reorder";
}
/**
* 表格列宽拖动
*/
@GetMapping("/resizable")
public String resizable()
{
return prefix + "/resizable";
}
/**
* 表格行内编辑操作
*/
@@ -250,6 +259,15 @@ public class DemoTableController extends BaseController
return prefix + "/print";
}
/**
* 表格标题格式化
*/
@GetMapping("/headerStyle")
public String headerStyle()
{
return prefix + "/headerStyle";
}
/**
* 表格其他操作
*/
@@ -52,7 +52,7 @@ public class SysLogininforController extends BaseController
return getDataTable(list);
}
@Log(title = "日志", businessType = BusinessType.EXPORT)
@Log(title = "日志", businessType = BusinessType.EXPORT)
@RequiresPermissions("monitor:logininfor:export")
@PostMapping("/export")
@ResponseBody
@@ -60,11 +60,11 @@ public class SysLogininforController extends BaseController
{
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
return util.exportExcel(list, "日志");
return util.exportExcel(list, "日志");
}
@RequiresPermissions("monitor:logininfor:remove")
@Log(title = "日志", businessType = BusinessType.DELETE)
@Log(title = "日志", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
@@ -73,7 +73,7 @@ public class SysLogininforController extends BaseController
}
@RequiresPermissions("monitor:logininfor:remove")
@Log(title = "日志", businessType = BusinessType.CLEAN)
@Log(title = "日志", businessType = BusinessType.CLEAN)
@PostMapping("/clean")
@ResponseBody
public AjaxResult clean()
@@ -88,7 +88,7 @@ public class SysLogininforController extends BaseController
@ResponseBody
public AjaxResult unlock(String loginName)
{
passwordService.unlock(loginName);
passwordService.clearLoginRecordCache(loginName);
return success();
}
}
@@ -16,9 +16,9 @@ import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.OnlineStatus;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.framework.shiro.session.OnlineSession;
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysUserOnline;
import com.ruoyi.system.service.ISysUserOnlineService;
@@ -76,7 +76,7 @@ public class SysUserOnlineController extends BaseController
}
if (sessionId.equals(ShiroUtils.getSessionId()))
{
return error("当前登用户无法强退");
return error("当前登用户无法强退");
}
onlineSessionDAO.delete(onlineSession);
online.setStatus(OnlineStatus.off_line);
@@ -17,8 +17,8 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.service.ISysConfigService;
@@ -16,11 +16,11 @@ import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
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.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysDept;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.service.ISysDeptService;
/**
@@ -14,11 +14,11 @@ import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysDictData;
import com.ruoyi.system.service.ISysDictDataService;
/**
@@ -16,11 +16,11 @@ import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysDictType;
import com.ruoyi.system.service.ISysDictTypeService;
/**
@@ -1,15 +1,24 @@
package com.ruoyi.web.controller.system;
import java.util.Date;
import java.util.List;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import com.ruoyi.common.config.Global;
import org.springframework.web.bind.annotation.PathVariable;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysMenu;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.CookieUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysMenuService;
@@ -39,23 +48,74 @@ public class SysIndexController extends BaseController
mmap.put("user", user);
mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme"));
mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName"));
mmap.put("copyrightYear", Global.getCopyrightYear());
mmap.put("demoEnabled", Global.isDemoEnabled());
return "index";
mmap.put("ignoreFooter", configService.selectConfigByKey("sys.index.ignoreFooter"));
mmap.put("copyrightYear", RuoYiConfig.getCopyrightYear());
mmap.put("demoEnabled", RuoYiConfig.isDemoEnabled());
mmap.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
mmap.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
// 菜单导航显示风格
String menuStyle = configService.selectConfigByKey("sys.index.menuStyle");
// 移动端,默认使左侧导航菜单,否则取默认配置
String indexStyle = ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")) ? "index" : menuStyle;
// 优先Cookie配置导航菜单
Cookie[] cookies = ServletUtils.getRequest().getCookies();
for (Cookie cookie : cookies)
{
if (StringUtils.isNotEmpty(cookie.getName()) && "nav-style".equalsIgnoreCase(cookie.getName()))
{
indexStyle = cookie.getValue();
break;
}
}
String webIndex = "topnav".equalsIgnoreCase(indexStyle) ? "index-topnav" : "index";
return webIndex;
}
// 切换主题
@GetMapping("/system/switchSkin")
public String switchSkin(ModelMap mmap)
public String switchSkin()
{
return "skin";
}
// 切换菜单
@GetMapping("/system/menuStyle/{style}")
public void menuStyle(@PathVariable String style, HttpServletResponse response)
{
CookieUtils.setCookie(response, "nav-style", style);
}
// 系统介绍
@GetMapping("/system/main")
public String main(ModelMap mmap)
{
mmap.put("version", Global.getVersion());
mmap.put("version", RuoYiConfig.getVersion());
return "main";
}
// 检查初始密码是否提醒修改
public boolean initPasswordIsModify(Date pwdUpdateDate)
{
int initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
return initPasswordModify == 1 && pwdUpdateDate == null;
}
// 检查密码是否过期
public boolean passwordIsExpiration(Date pwdUpdateDate)
{
int passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
if (passwordValidateDays > 0)
{
if (StringUtils.isNull(pwdUpdateDate))
{
// 如果从未修改过初始密码,直接提醒过期
return true;
}
Date nowDate = DateUtils.getNowDate();
return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays;
}
return false;
}
}
@@ -16,10 +16,11 @@ import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysMenu;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.service.ISysMenuService;
/**
@@ -70,7 +71,7 @@ public class SysMenuController extends BaseController
{
return AjaxResult.warn("菜单已分配,不允许删除");
}
ShiroUtils.clearCachedAuthorizationInfo();
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.deleteMenuById(menuId));
}
@@ -109,7 +110,7 @@ public class SysMenuController extends BaseController
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
menu.setCreateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.insertMenu(menu));
}
@@ -137,7 +138,7 @@ public class SysMenuController extends BaseController
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
menu.setUpdateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.updateMenu(menu));
}
@@ -15,7 +15,7 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.system.domain.SysNotice;
import com.ruoyi.system.service.ISysNoticeService;
@@ -17,8 +17,8 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.service.ISysPostService;
@@ -12,15 +12,15 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysUserService;
/**
@@ -81,21 +81,23 @@ public class SysProfileController extends BaseController
public AjaxResult resetPwd(String oldPassword, String newPassword)
{
SysUser user = ShiroUtils.getSysUser();
if (StringUtils.isNotEmpty(newPassword) && passwordService.matches(user, oldPassword))
{
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
if (userService.resetUserPwd(user) > 0)
{
ShiroUtils.setSysUser(userService.selectUserById(user.getUserId()));
return success();
}
return error();
}
else
if (!passwordService.matches(user, oldPassword))
{
return error("修改密码失败,旧密码错误");
}
if (passwordService.matches(user, newPassword))
{
return error("新密码不能与旧密码相同");
}
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
user.setPwdUpdateDate(DateUtils.getNowDate());
if (userService.resetUserPwd(user) > 0)
{
ShiroUtils.setSysUser(userService.selectUserById(user.getUserId()));
return success();
}
return error("修改密码异常,请联系管理员");
}
/**
@@ -154,7 +156,7 @@ public class SysProfileController extends BaseController
{
if (!file.isEmpty())
{
String avatar = FileUploadUtils.upload(Global.getAvatarPath(), file);
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file);
currentUser.setAvatar(avatar);
if (userService.updateUserInfo(currentUser) > 0)
{
@@ -8,8 +8,8 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.framework.shiro.service.SysRegisterService;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysConfigService;
/**
@@ -15,12 +15,13 @@ import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
@@ -97,7 +98,7 @@ public class SysRoleController extends BaseController
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setCreateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(roleService.insertRole(role));
}
@@ -131,7 +132,7 @@ public class SysRoleController extends BaseController
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setUpdateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(roleService.updateRole(role));
}
@@ -17,13 +17,14 @@ import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
@@ -125,11 +126,13 @@ public class SysUserController extends BaseController
{
return error("新增用户'" + user.getLoginName() + "'失败,登录账号已存在");
}
else if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
else if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{
return error("新增用户'" + user.getLoginName() + "'失败,手机号码已存在");
}
else if (UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
else if (StringUtils.isNotEmpty(user.getEmail())
&& UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
{
return error("新增用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
}
@@ -162,11 +165,13 @@ public class SysUserController extends BaseController
public AjaxResult editSave(@Validated SysUser user)
{
userService.checkUserAllowed(user);
if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{
return error("修改用户'" + user.getLoginName() + "'失败,手机号码已存在");
}
else if (UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
else if (StringUtils.isNotEmpty(user.getEmail())
&& UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
{
return error("修改用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
}
@@ -3,7 +3,7 @@ package com.ruoyi.web.core.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.RuoYiConfig;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
@@ -61,9 +61,9 @@ public class SwaggerConfig
// 描述
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
// 作者信息
.contact(new Contact(Global.getName(), null, null))
.contact(new Contact(RuoYiConfig.getName(), null, null))
// 版本
.version("版本号:" + Global.getVersion())
.version("版本号:" + RuoYiConfig.getVersion())
.build();
}
}
@@ -3,7 +3,7 @@ ruoyi:
# 名称
name: RuoYi
# 版本
version: 4.4.0
version: 4.5.1
# 版权年份
copyrightYear: 2019
# 实例演示开关
@@ -28,7 +28,7 @@
timeToIdleSeconds="600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
statistics="false">
</cache>
<!-- 系统活跃用户缓存 -->
@@ -39,7 +39,7 @@
diskPersistent="false"
timeToLiveSeconds="0"
timeToIdleSeconds="0"
statistics="true">
statistics="false">
</cache>
<!-- 系统缓存 -->
@@ -47,7 +47,7 @@
maxEntriesLocalHeap="1000"
eternal="true"
overflowToDisk="true"
statistics="true">
statistics="false">
</cache>
<!-- 系统参数缓存 -->
@@ -55,7 +55,7 @@
maxEntriesLocalHeap="1000"
eternal="true"
overflowToDisk="true"
statistics="true">
statistics="false">
</cache>
<!-- 系统字典缓存 -->
@@ -63,19 +63,18 @@
maxEntriesLocalHeap="1000"
eternal="true"
overflowToDisk="true"
statistics="true">
statistics="false">
</cache>
<!-- 系统会话缓存 -->
<cache name="shiro-activeSessionCache"
maxElementsInMemory="10000"
overflowToDisk="true"
eternal="true"
maxEntriesLocalHeap="10000"
overflowToDisk="false"
eternal="false"
diskPersistent="false"
timeToLiveSeconds="0"
timeToIdleSeconds="0"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="600">
</cache>
statistics="false"/>
</ehcache>
@@ -1,11 +1,11 @@
/*!
* bootstrap-fileinput v5.0.4
* bootstrap-fileinput v5.1.2
* http://plugins.krajee.com/file-input
*
* Krajee default styling for bootstrap-fileinput.
*
* Author: Kartik Visweswaran
* Copyright: 2014 - 2019, Kartik Visweswaran, Krajee.com
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
*
* Licensed under the BSD-3-Clause
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
@@ -60,10 +60,9 @@
height: 16px;
}
.krajee-default .file-thumb-progress .progress, .krajee-default .file-thumb-progress .progress-bar {
height: 20px;
.file-thumb-progress .progress, .file-thumb-progress .progress-bar {
font-family: Verdana, Helvetica, sans-serif;
font-size: 9px;
font-size: 0.7rem;
}
.krajee-default .file-thumb-progress .progress, .kv-upload-progress .progress {
@@ -205,8 +204,8 @@
.krajee-default.file-preview-frame {
margin: 8px;
border: 1px solid rgba(0,0,0,0.2);
box-shadow: 0 0 10px 0 rgba(0,0,0,0.2);
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
padding: 6px;
float: left;
text-align: center;
@@ -237,8 +236,8 @@
}
.krajee-default.file-preview-frame:not(.file-preview-error):hover {
border: 1px solid rgba(0,0,0,0.3);
box-shadow: 0 0 10px 0 rgba(0,0,0,0.4);
border: 1px solid rgba(0, 0, 0, 0.3);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4);
}
.krajee-default .file-preview-text {
@@ -292,7 +291,6 @@
}
.krajee-default .file-thumb-progress {
height: 11px;
top: 37px;
left: 0;
right: 0;
@@ -318,7 +316,7 @@
}
.kv-upload-progress .progress-bar {
height: 20px;
height: 11px;
font-family: Verdana, Helvetica, sans-serif;
}
@@ -340,13 +338,13 @@
.file-zoom-dialog .btn-navigate {
padding: 0;
margin: 0;
margin: -60px 0 0;
font-size: 60px;
background: transparent;
text-decoration: none;
outline: none;
opacity: 0.7;
top: 45%;
font-size: 4em;
top: 50%;
color: #1c94c4;
}
@@ -402,6 +400,7 @@
.file-drop-zone {
border: 1px dashed #aaa;
min-height: 260px;
border-radius: 4px;
text-align: center;
vertical-align: middle;
@@ -424,6 +423,7 @@
.file-drop-zone-title {
color: #aaa;
font-size: 1.6em;
text-align:center;
padding: 85px 10px;
cursor: default;
}
@@ -467,8 +467,8 @@
}
.file-zoom-content {
height: 480px;
text-align: center;
min-height: 300px;
}
.file-zoom-content .file-preview-image {
@@ -532,19 +532,29 @@
padding-right: 20px;
}
.file-sortable .file-drag-handle {
cursor: move;
opacity: 1;
.clickable .file-drop-zone-title {
cursor: pointer;
}
.file-sortable .file-drag-handle:hover {
opacity: 0.7;
}
.clickable .file-drop-zone-title {
cursor: pointer;
.file-sortable .file-drag-handle {
cursor: grab;
opacity: 1;
}
.file-preview-initial.sortable-chosen {
.file-grabbing, .file-grabbing * {
cursor: not-allowed !important;
}
.file-grabbing .file-preview-thumbnails * {
cursor: grabbing !important;
}
.file-preview-frame.sortable-chosen {
background-color: #d9edf7;
border-color: #17a2b8;
box-shadow: none !important;
}
File diff suppressed because it is too large Load Diff
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
File diff suppressed because one or more lines are too long
@@ -0,0 +1,79 @@
/**
* GitHub Gist Theme
* Author : Anthony Attard - https://github.com/AnthonyAttard
* Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro
*/
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #d73a49;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #6f42c1;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
.hljs-number {
color: #005cc5;
}
.hljs-string {
color: #032f62;
}
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
@@ -1,381 +0,0 @@
/*
Common
*/
.wizard,
.tabcontrol
{
display: block;
width: 100%;
overflow: hidden;
}
.wizard a,
.tabcontrol a
{
outline: 0;
}
.wizard ul,
.tabcontrol ul
{
list-style: none !important;
padding: 0;
margin: 0;
}
.wizard ul > li,
.tabcontrol ul > li
{
display: block;
padding: 0;
}
/* Accessibility */
.wizard > .steps .current-info,
.tabcontrol > .steps .current-info
{
position: absolute;
left: -999em;
}
.wizard > .content > .title,
.tabcontrol > .content > .title
{
position: absolute;
left: -999em;
}
/*
Wizard
*/
.wizard > .steps
{
position: relative;
display: block;
width: 100%;
}
.wizard.vertical > .steps
{
display: inline;
float: left;
width: 30%;
}
.wizard > .steps > ul > li
{
width: 25%;
}
.wizard > .steps > ul > li,
.wizard > .actions > ul > li
{
float: left;
}
.wizard.vertical > .steps > ul > li
{
float: none;
width: 100%;
}
.wizard > .steps a,
.wizard > .steps a:hover,
.wizard > .steps a:active
{
display: block;
width: auto;
margin: 0 0.5em 0.5em;
padding: 8px;
text-decoration: none;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.wizard > .steps .disabled a,
.wizard > .steps .disabled a:hover,
.wizard > .steps .disabled a:active
{
background: #eee;
color: #aaa;
cursor: default;
}
.wizard > .steps .current a,
.wizard > .steps .current a:hover,
.wizard > .steps .current a:active
{
background: #1AB394;
color: #fff;
cursor: default;
}
.wizard > .steps .done a,
.wizard > .steps .done a:hover,
.wizard > .steps .done a:active
{
background: #6fd1bd;
color: #fff;
}
.wizard > .steps .error a,
.wizard > .steps .error a:hover,
.wizard > .steps .error a:active
{
background: #ED5565 ;
color: #fff;
}
.wizard > .content
{
background: #eee;
display: block;
margin: 5px 5px 10px 5px;
min-height: 120px;
overflow: hidden;
position: relative;
width: auto;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.wizard-big.wizard > .content {
min-height: 320px;
}
.wizard.vertical > .content
{
display: inline;
float: left;
margin: 0 2.5% 0.5em 2.5%;
width: 65%;
}
.wizard > .content > .body
{
float: left;
position: absolute;
width: 95%;
height: 95%;
padding: 2.5%;
}
.wizard > .content > .body ul
{
list-style: disc !important;
}
.wizard > .content > .body ul > li
{
display: list-item;
}
.wizard > .content > .body > iframe
{
border: 0 none;
width: 100%;
height: 100%;
}
.wizard > .content > .body input
{
display: block;
border: 1px solid #ccc;
}
.wizard > .content > .body input[type="checkbox"]
{
display: inline-block;
}
.wizard > .content > .body input.error
{
background: rgb(251, 227, 228);
border: 1px solid #fbc2c4;
color: #8a1f11;
}
.wizard > .content > .body label
{
display: inline-block;
margin-bottom: 0.5em;
}
.wizard > .content > .body label.error
{
color: #8a1f11;
display: inline-block;
margin-left: 1.5em;
}
.wizard > .actions
{
position: relative;
display: block;
text-align: right;
width: 100%;
}
.wizard.vertical > .actions
{
display: inline;
float: right;
margin: 0 2.5%;
width: 95%;
}
.wizard > .actions > ul
{
display: inline-block;
text-align: right;
}
.wizard > .actions > ul > li
{
margin: 0 0.5em;
}
.wizard.vertical > .actions > ul > li
{
margin: 0 0 0 1em;
}
.wizard > .actions a,
.wizard > .actions a:hover,
.wizard > .actions a:active
{
background: #1AB394;
color: #fff;
display: block;
padding: 0.5em 1em;
text-decoration: none;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.wizard > .actions .disabled a,
.wizard > .actions .disabled a:hover,
.wizard > .actions .disabled a:active
{
background: #eee;
color: #aaa;
}
.wizard > .loading
{
}
.wizard > .loading .spinner
{
}
/*
Tabcontrol
*/
.tabcontrol > .steps
{
position: relative;
display: block;
width: 100%;
}
.tabcontrol > .steps > ul
{
position: relative;
margin: 6px 0 0 0;
top: 1px;
z-index: 1;
}
.tabcontrol > .steps > ul > li
{
float: left;
margin: 5px 2px 0 0;
padding: 1px;
-webkit-border-top-left-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topleft: 5px;
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.tabcontrol > .steps > ul > li:hover
{
background: #edecec;
border: 1px solid #bbb;
padding: 0;
}
.tabcontrol > .steps > ul > li.current
{
background: #fff;
border: 1px solid #bbb;
border-bottom: 0 none;
padding: 0 0 1px 0;
margin-top: 0;
}
.tabcontrol > .steps > ul > li > a
{
color: #5f5f5f;
display: inline-block;
border: 0 none;
margin: 0;
padding: 10px 30px;
text-decoration: none;
}
.tabcontrol > .steps > ul > li > a:hover
{
text-decoration: none;
}
.tabcontrol > .steps > ul > li.current > a
{
padding: 15px 30px 10px 30px;
}
.tabcontrol > .content
{
position: relative;
display: inline-block;
width: 100%;
height: 35em;
overflow: hidden;
border-top: 1px solid #bbb;
padding-top: 20px;
}
.tabcontrol > .content > .body
{
float: left;
position: absolute;
width: 95%;
height: 95%;
padding: 2.5%;
}
.tabcontrol > .content > .body ul
{
list-style: disc !important;
}
.tabcontrol > .content > .body ul > li
{
display: list-item;
}
label.error { position:inherit; }
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -4,6 +4,14 @@
* NAME - blue/green/purple/red/yellow
*
*/
.nav-tabs {
border-bottom: 0px;
}
.navbar .navbar-toolbar>li>a {
border: none !important;
}
/** 蓝色主题 skin-blue **/
.navbar, .skin-blue .navbar {
background-color: #3c8dbc
@@ -93,7 +101,7 @@
background: #1a2226
}
.skin-blue .nav>li.active {
.skin-blue .nav:not(.navbar-toolbar)>li.active {
color: #fff;
background: #293846;
border-left: 3px solid #3c8dbc;
@@ -103,6 +111,13 @@
border-left: none;
}
.skin-blue .dropdown-menu > .active > a, .skin-blue .dropdown-menu > .active > a:hover, .skin-blue .dropdown-menu > .active > a:focus {
color: #fff !important;
text-decoration: none;
outline: 0;
background-color: #3c8dbc;
}
.skin-blue .sidebar a {
color: #b8c7ce
}
@@ -268,7 +283,7 @@
background: #1a2226;
}
.skin-green .nav>li.active {
.skin-green .nav:not(.navbar-toolbar)>li.active {
color: #fff;
background: #293846;
border-left: 3px solid #00a65a;
@@ -278,6 +293,13 @@
border-left: none;
}
.skin-green .dropdown-menu > .active > a, .skin-green .dropdown-menu > .active > a:hover, .skin-green .dropdown-menu > .active > a:focus {
color: #fff !important;
text-decoration: none;
outline: 0;
background-color: #00a65a;
}
.skin-green .sidebar a {
color: #b8c7ce
}
@@ -415,7 +437,7 @@
background: #1a2226
}
.skin-red .nav>li.active {
.skin-red .nav:not(.navbar-toolbar)>li.active {
color: #fff;
border-left: 3px solid #dd4b39;
background: #293846;
@@ -425,6 +447,13 @@
border-left: none;
}
.skin-red .dropdown-menu > .active > a, .skin-red .dropdown-menu > .active > a:hover, .skin-red .dropdown-menu > .active > a:focus {
color: #fff !important;
text-decoration: none;
outline: 0;
background-color: #dd4b39;
}
.skin-red .content-tabs {
border-bottom: 1px solid #e5e5e5;
}
@@ -566,7 +595,7 @@
background: #1a2226
}
.skin-yellow .nav>li.active {
.skin-yellow .nav:not(.navbar-toolbar)>li.active {
color: #fff;
background: #293846;
border-left: 3px solid #f39c12;
@@ -576,6 +605,13 @@
border-left: none;
}
.skin-yellow .dropdown-menu > .active > a, .skin-yellow .dropdown-menu > .active > a:hover, .skin-yellow .dropdown-menu > .active > a:focus {
color: #fff !important;
text-decoration: none;
outline: 0;
background-color: #f39c12;
}
.skin-yellow .content-tabs {
border-bottom: 1px solid #e5e5e5;
}
@@ -717,7 +753,7 @@
background: #1a2226
}
.skin-purple .nav>li.active {
.skin-purple .nav:not(.navbar-toolbar)>li.active {
color: #fff;
background: #293846;
border-left: 3px solid #605ca8;
@@ -727,6 +763,13 @@
border-left: none;
}
.skin-purple .dropdown-menu > .active > a, .skin-purple .dropdown-menu > .active > a:hover, .skin-purple .dropdown-menu > .active > a:focus {
color: #fff !important;
text-decoration: none;
outline: 0;
background-color: #605ca8;
}
.skin-purple .content-tabs {
border-bottom: 1px solid #e5e5e5;
}
@@ -790,7 +833,7 @@
color: #fff
}
.theme-dark .nav>li.active {
.theme-dark .nav:not(.navbar-toolbar)>li.active {
background: #293846;
}
@@ -812,7 +855,7 @@
color: #555
}
.theme-light .nav>li.active{
.theme-light .nav:not(.navbar-toolbar)>li.active{
background: #f9fafc;
}
@@ -903,7 +946,7 @@
color: #a3b1cc
}
.theme-blue .nav>li.active{
.theme-blue .nav:not(.navbar-toolbar)>li.active{
background-color: rgba(15,41,80,1);
}
@@ -46,18 +46,18 @@ a:focus {
/*white-space: nowrap;*/
}
.nav.navbar-right>li>a {
.nav.navbar-right>li>a, .nav.navbar-left>li>a {
color: #fff;
font-size: 14px;
height: 50px;
padding: 18px 15px;
padding: 15px 15px;
}
.nav>li.active>a {
color: #ffffff;
}
.nav.navbar-right>li>a>.label {
.nav.navbar-right>li>a>.label, .nav.navbar-left>li>a>.label {
position: absolute;
top: 9px;
right: 5px;
@@ -66,7 +66,7 @@ a:focus {
padding: 2px 4px;
line-height: .9;
}
.nav.navbar-right>li>a:hover {
.nav.navbar-right>li>a:hover, .nav.navbar-left>li>a:hover {
background-color: #367fa9;
color: #fff;
}
@@ -280,6 +280,8 @@ body.body-small .navbar-top-links li:last-child {
.nav-second-level li, .nav-third-level li {
border-bottom: none !important;
padding-left: 2px;
padding-right: 2px;
}
.nav-second-level li a {
@@ -288,7 +290,7 @@ body.body-small .navbar-top-links li:last-child {
}
.nav-third-level li a {
padding-left: 62px;
padding-left: 70px;
}
.nav-second-level li:last-child {
@@ -307,6 +309,10 @@ body.mini-navbar .navbar-default .nav>li>.nav-second-level li a {
border-radius: 0 2px 2px 0;
}
body.mini-navbar .navbar-default .nav>li>.nav-third-level li a {
padding-left: 31px;
}
.fixed-nav .slimScrollDiv #side-menu {
padding-bottom: 60px;
position: relative;
@@ -473,13 +479,12 @@ body.body-small.fixed-sidebar.mini-navbar .navbar-static-side {
border-left-width: 0;
}
/*伸缩菜单*/
/* 伸缩菜单 */
.fixed-sidebar.mini-navbar .nav li:hover>a> span.nav-label {
top: 0px;
padding: 10px 10px 10px 10px;
text-align: center;
background-color: #243747;
border-bottom: dashed 1px #fff;
}
.fixed-sidebar.mini-navbar .nav li:hover>.nav-second-level {
@@ -495,6 +500,15 @@ body.body-small.fixed-sidebar.mini-navbar .navbar-static-side {
min-width: 140px;
border-radius: 2px;
}
.fixed-sidebar.mini-navbar .nav li.active:hover>.nav-second-level, .fixed-sidebar.mini-navbar .nav li.active:hover>a> span.nav-label {
left: 67px;
}
.fixed-sidebar.mini-navbar .nav .nav-second-level a> span, .fixed-sidebar.mini-navbar .nav .nav-third-level a> span {
display: inline-block;
}
/*伸缩菜单结束*/
body.fixed-sidebar.mini-navbar .navbar-default .nav>li>.nav-second-level li a {
@@ -1161,6 +1175,8 @@ button.dim:active:before {
/* TOOLTIPS */
.tooltip-inner {
background-color: #2F4050;
word-break: break-all;
overflow-wrap: break-word;
}
.tooltip.top .tooltip-arrow {
@@ -3254,7 +3270,7 @@ body.body-small .footer.fixed {
position: relative;
height: 39px;
background: #fafafa;
line-height: 38px;
line-height: 39px;
}
.content-tabs .roll-nav, .page-tabs-list {
@@ -6873,7 +6889,7 @@ body.rtls .top-navigation .footer.fixed, body.rtls.top-navigation .footer.fixed
}
.navbar-header {
width: 10%;
/* width: 10%; */
height: 50px;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 137 KiB

@@ -0,0 +1 @@
(function(c,a,e){var b,d="resizeTabs",f={navSelector:".nav-tabs",itemSelector:">li",dropdownSelector:">.dropdown",dropdownItemSelector:"li",tabParentSelector:"",tabSelector:".tab-pane",activeClassName:"active",noNavClassName:".no-menu",fnCallback:""};b=function(j,i){var h=this.$tabs=e(j),k=this.options=e.extend(true,{},f,i),g=this.$nav=h.find(k.navSelector),l=this.$dropdown=g.find(k.dropdownSelector);this.$items=g.find(k.itemSelector).filter(function(){return !e(this).is(l)});this.$dropdownItems=l.find(k.dropdownItemSelector);if(k.tabParentSelector!==""){this.$tabPanel=e(k.tabParentSelector).find(k.tabSelector)}else{this.$tabPanel=h.find(k.tabSelector)}this.init()};b.prototype={init:function(){var j=this.itemsLenth=this.$items.length,h;if(j===0){throw"There should be some tags here "}if(this.$dropdown.length===0){this.flag=true;this.$nav.append('<li class="dropdown" role="presentation">'+'<a class="dropdown-toggle" data-toggle="dropdown" href="#" aria-expanded="false">'+'<i class="glyphicon glyphicon-align-justify"></i> <b class="caret"></b></a><ul class="dropdown-menu" role="menu"></ul></li>');this.$dropdown=this.$nav.find(this.options.dropdownSelector);this.$dropdown.css("opacity",0);h=this.$dropdown.width();h=h===0?90:h;this.$dropdown.addClass("hidden").css("opacity",1)}else{h=this.$dropdown.width()}this.breakpoints=[];for(var g=0;g<j+1;g++){var k=this.$items.eq(g).width(),l=0;switch(g){case 0:l=k+h;break;case j-1:l=this.breakpoints[g-1]+k-h;break;case j:l=this.breakpoints[g-1]+h;break;default:l=this.breakpoints[g-1]+k}this.breakpoints.push(l)}if(typeof this.options.fnCallback==="function"){this.options.fnCallback(this.$tabs)}this.bind();this.layout()},layout:function(){if(this.breakpoints.length<=0){return}var l=this.$tabs.width()-500,j=0,h=this,g=this.options.activeClassName,m=this.$tabPanel.filter("."+g).index(),k=function(p){var o=p;if(p===h.itemsLenth){o=p-1}for(;o<h.itemsLenth;o++){if(h.flag){h.$dropdown.find("ul").append(h.$items.eq(o).prop("outerHTML"))}else{h.$dropdown.find("ul>li"+h.options.noNavClassName+":first").before(h.$items.eq(o).prop("outerHTML"))}h.$items.eq(o).hide()}},n=function(p){for(var o=0;o<h.itemsLenth+1;o++){if(o<p){h.$items.eq(o).show()}else{k(p);h.$dropdown.find("ul>li").show();break}}h.$dropdownItems=h.$dropdown.find(h.options.dropdownItemSelector)};for(;j<this.breakpoints.length;j++){if(this.breakpoints[j]>l){break}}this.$items.removeClass(g);this.$dropdownItems.removeClass(g);this.$dropdown.removeClass(g);if(j===this.breakpoints.length){if(this.flag){this.$dropdown.addClass("hidden")}else{this.$dropdown.find("ul>li:not(li"+this.options.noNavClassName+")").remove()}this.$items.show();if(m!=-1){this.$items.eq(m-1).addClass(g)}}else{this.$dropdown.removeClass("hidden");if(this.flag){this.$dropdown.find("ul>li").remove()}else{this.$dropdown.find("ul>li:not(li"+this.options.noNavClassName+")").remove()}n(j);if(m<j){if(m!=-1){this.$items.eq(m-1).addClass(g)}}else{this.$dropdown.addClass(g);this.$dropdownItems.eq(m-j).addClass(g)}}},throttle:function(h,g){var k=h,j,i=true;return function(){var m=arguments,l=this;if(i){k.apply(l,m);i=false}if(j){return false}j=setInterval(function(){clearInterval(j);j=null;k.apply(l,m)},g||500)}},bind:function(){var g=this;e(c).resize(function(){g.throttle(function(){g.layout()},1000)()})}};e.fn[d]=function(g){if(typeof g==="string"){var i=g,h=Array.prototype.slice.call(arguments,1);if(/^_/.test(i)){console.error("No such method : "+g)}else{return this.each(function(){var j=e.data(this,d);if(j&&typeof j[i]==="function"){j[i].apply(j,h)}})}}else{return this.each(function(){if(!e.data(this,d)){e.data(this,d,new b(this,g))}else{e.data(this,d).init()}})}}})(window,document,jQuery);$("#navMenu").resizeTabs({tabParentSelector:"#side-menu"});
@@ -341,6 +341,10 @@ label.error {
right: 42px
}
.input-group input.error + label.error + .input-group-addon>i {
color: #ed5565;
}
.input-group.date label.error {
z-index:99;
right: 3px
@@ -439,6 +443,14 @@ label.error {
background-position: -180px 0
}
/* ztree */
div.ztree-border {
margin-top: 10px;
border: 1px solid #e5e6e7;
background: #FFFFFF none;
border-radius:4px;
}
/* 切换开关 */
.toggle-switch {
display: -webkit-inline-box;
@@ -868,6 +880,26 @@ label {
height: 32px!important;
}
/** 表格列宽拖动样式 **/
.rc-handle-container {
position: relative;
}
.rc-handle {
position: absolute;
width: 7px;
cursor: ew-resize;
margin-left: -3px;
z-index: 2;
}
table.rc-table-resizing {
cursor: ew-resize;
}
table.rc-table-resizing thead,
table.rc-table-resizing thead > th,
table.rc-table-resizing thead > th > a {
cursor: ew-resize;
}
/** 表格冻结列样式 **/
.fixed-columns, .fixed-columns-right {
position: absolute;
@@ -1056,6 +1088,23 @@ label {
visibility: visible;
}
/* 设置菜单样式 */
.menu-content {
padding: 10px 10px 10px 25px !important;
}
.tab-content > .tab-pane {
display: none;
}
.tab-content > .active {
display: block;
}
.height-full {
height: 100% !important;
}
/* 设置滚动条样式 */
::-webkit-scrollbar {
width:10px!important;
@@ -24,9 +24,9 @@ $(function() {
// 菜单切换
$('.navbar-minimalize').click(function() {
if (isMobile) {
$("body").toggleClass("canvas-menu");
$("body").toggleClass("canvas-menu");
} else {
$("body").toggleClass("mini-navbar");
$("body").toggleClass("mini-navbar");
}
SmoothlyMenu();
});
@@ -62,12 +62,12 @@ $(window).bind("load resize", function() {
$('.navbar-static-side').fadeOut();
} else {
if($('body').hasClass('canvas-menu')) {
$('body').addClass('fixed-sidebar');
$('body').removeClass('canvas-menu');
$("body").removeClass("mini-navbar");
$("nav .logo").removeClass("hide");
$(".slimScrollDiv").css({ "overflow": "visible" });
$('.navbar-static-side').fadeIn();
$('body').addClass('fixed-sidebar');
$('body').removeClass('canvas-menu');
$("body").removeClass("mini-navbar");
$("nav .logo").removeClass("hide");
$(".slimScrollDiv").css({ "overflow": "visible" });
$('.navbar-static-side').fadeIn();
}
}
});
@@ -81,8 +81,15 @@ function syncMenuTab(dataId) {
$dataObj.parents("li").addClass("active").siblings().removeClass("active").find('li').removeClass("active");
$dataObj.parents("ul").css('height', 'auto').height();
$dataObj.click();
// 顶部菜单同步处理
var tabStr = $dataObj.parents(".tab-pane").attr("id");
if ($.common.isNotEmpty(tabStr)) {
var sepIndex = tabStr.lastIndexOf('_');
var menuId = tabStr.substring(sepIndex + 1, tabStr.length);
$("#tab_" + menuId + " a").click();
}
}
}
}
}
function NavToggle() {
@@ -90,12 +97,11 @@ function NavToggle() {
}
function fixedSidebar() {
$('#side-menu').hide();
$("nav .logo").addClass("hide");
$('#side-menu').hide();
$("nav .logo").addClass("hide");
setTimeout(function() {
$('#side-menu').fadeIn(500);
},
100);
}, 100);
}
function SmoothlyMenu() {
@@ -168,10 +174,7 @@ $(function() {
} else if (marginLeftVal > (visibleWidth - $(element).outerWidth(true) - $(element).prev().outerWidth(true))) {
scrollVal = marginLeftVal - $(element).prev().outerWidth(true);
}
$('.page-tabs-content').animate({
marginLeft: 0 - scrollVal + 'px'
},
"fast");
$('.page-tabs-content').animate({ marginLeft: 0 - scrollVal + 'px' }, "fast");
}
//查看左侧隐藏的选项卡
@@ -201,10 +204,7 @@ $(function() {
scrollVal = calSumWidth($(tabElement).prevAll());
}
}
$('.page-tabs-content').animate({
marginLeft: 0 - scrollVal + 'px'
},
"fast");
$('.page-tabs-content').animate({ marginLeft: 0 - scrollVal + 'px' }, "fast");
}
//查看右侧隐藏的选项卡
@@ -232,10 +232,7 @@ $(function() {
}
scrollVal = calSumWidth($(tabElement).prevAll());
if (scrollVal > 0) {
$('.page-tabs-content').animate({
marginLeft: 0 - scrollVal + 'px'
},
"fast");
$('.page-tabs-content').animate({ marginLeft: 0 - scrollVal + 'px' }, "fast");
}
}
}
@@ -256,7 +253,8 @@ $(function() {
var $dataObj = $('a[href$="' + decodeURI(dataUrl) + '"]');
if (!$dataObj.hasClass("noactive")) {
$('.nav ul').removeClass("in");
$('.tab-pane li').removeClass("active");
$('.nav ul').removeClass("in");
$dataObj.parents("ul").addClass("in")
$dataObj.parents("li").addClass("active").siblings().removeClass("active").find('li').removeClass("active");
$dataObj.parents("ul").css('height', 'auto').height();
@@ -340,10 +338,7 @@ $(function() {
var marginLeftVal = parseInt($('.page-tabs-content').css('margin-left'));
if (marginLeftVal < 0) {
$('.page-tabs-content').animate({
marginLeft: (marginLeftVal + currentWidth) + 'px'
},
"fast");
$('.page-tabs-content').animate({ marginLeft: (marginLeftVal + currentWidth) + 'px' }, "fast");
}
// 移除当前选项卡
@@ -387,7 +382,7 @@ $(function() {
$(this).show().siblings('.RuoYi_iframe').hide();
return false;
}
});
});
}
}
}
@@ -442,14 +437,14 @@ $(function() {
var currentId = $('.page-tabs-content').find('.active').attr('data-id');
var target = $('.RuoYi_iframe[data-id="' + currentId + '"]');
var url = target.attr('src');
target.attr('src', url).ready();
target.attr('src', url).ready();
}
// 页签全屏
function fullScreenTab() {
var currentId = $('.page-tabs-content').find('.active').attr('data-id');
var target = $('.RuoYi_iframe[data-id="' + currentId + '"]');
target.fullScreen(true);
target.fullScreen(true);
}
// 关闭当前选项卡
@@ -463,7 +458,7 @@ $(function() {
$('.RuoYi_iframe[data-id="' + $(this).data('id') + '"]').remove();
$(this).remove();
});
$('.page-tabs-content').css("margin-left", "0");
$('.page-tabs-content').animate({ marginLeft: '0px' }, "fast");
}
// 关闭全部选项卡
@@ -530,11 +525,11 @@ $(function() {
// 设置锚点
function setIframeUrl(href) {
if($.common.equals("history", mode)) {
storage.set('publicPath', href);
storage.set('publicPath', href);
} else {
var nowUrl = window.location.href;
var newUrl = nowUrl.substring(0, nowUrl.indexOf("#"));
window.location.href = newUrl + "#" + href;
var nowUrl = window.location.href;
var newUrl = nowUrl.substring(0, nowUrl.indexOf("#"));
window.location.href = newUrl + "#" + href;
}
}
@@ -561,14 +556,14 @@ $(function() {
name: "关闭当前",
icon: "fa-close",
callback: function(key, opt) {
opt.$trigger.find('i').trigger("click");
opt.$trigger.find('i').trigger("click");
}
},
"close_other": {
name: "关闭其他",
icon: "fa-window-close-o",
callback: function(key, opt) {
setActiveTab(this);
setActiveTab(this);
tabCloseOther();
}
},
@@ -576,23 +571,23 @@ $(function() {
name: "关闭左侧",
icon: "fa-reply",
callback: function(key, opt) {
setActiveTab(this);
this.prevAll('.menuTab').not(":last").each(function() {
if ($(this).hasClass('active')) {
setActiveTab(this);
}
$('.RuoYi_iframe[data-id="' + $(this).data('id') + '"]').remove();
$(this).remove();
});
$('.page-tabs-content').css("margin-left", "0");
setActiveTab(this);
this.prevAll('.menuTab').not(":last").each(function() {
if ($(this).hasClass('active')) {
setActiveTab(this);
}
$('.RuoYi_iframe[data-id="' + $(this).data('id') + '"]').remove();
$(this).remove();
});
$('.page-tabs-content').animate({ marginLeft: '0px' }, "fast");
}
},
"close_right": {
name: "关闭右侧",
icon: "fa-share",
callback: function(key, opt) {
setActiveTab(this);
this.nextAll('.menuTab').each(function() {
setActiveTab(this);
this.nextAll('.menuTab').each(function() {
$('.menuTab[data-id="' + $(this).data('id') + '"]').remove();
$(this).remove();
});
@@ -610,18 +605,18 @@ $(function() {
name: "全屏显示",
icon: "fa-arrows-alt",
callback: function(key, opt) {
setActiveTab(this);
setActiveTab(this);
var target = $('.RuoYi_iframe[data-id="' + this.data('id') + '"]');
target.fullScreen(true);
target.fullScreen(true);
}
},
"refresh": {
name: "刷新页面",
icon: "fa-refresh",
callback: function(key, opt) {
setActiveTab(this);
var target = $('.RuoYi_iframe[data-id="' + this.data('id') + '"]');
var url = target.attr('src');
setActiveTab(this);
var target = $('.RuoYi_iframe[data-id="' + this.data('id') + '"]');
var url = target.attr('src');
$.modal.loading("数据加载中,请稍后...");
target.attr('src', url).load(function () {
$.modal.closeLoading();
@@ -632,7 +627,7 @@ $(function() {
name: "新窗口打开",
icon: "fa-link",
callback: function(key, opt) {
var target = $('.RuoYi_iframe[data-id="' + this.data('id') + '"]');
var target = $('.RuoYi_iframe[data-id="' + this.data('id') + '"]');
window.open(target.attr('src'));
}
},
@@ -4,195 +4,195 @@
*/
$(function() {
// layer扩展皮肤
if (window.layer !== undefined) {
layer.config({
extend: 'moon/style.css',
skin: 'layer-ext-moon'
});
}
// layer扩展皮肤
if (window.layer !== undefined) {
layer.config({
extend: 'moon/style.css',
skin: 'layer-ext-moon'
});
}
// 回到顶部绑定
if ($.fn.toTop !== undefined) {
$('#scroll-up').toTop();
}
// 回到顶部绑定
if ($.fn.toTop !== undefined) {
$('#scroll-up').toTop();
}
// select2复选框事件绑定
if ($.fn.select2 !== undefined) {
// select2复选框事件绑定
if ($.fn.select2 !== undefined) {
$.fn.select2.defaults.set( "theme", "bootstrap" );
$("select.form-control:not(.noselect2)").each(function () {
$(this).select2().on("change", function () {
$(this).valid();
})
})
}
$("select.form-control:not(.noselect2)").each(function () {
$(this).select2().on("change", function () {
$(this).valid();
})
})
}
// iCheck单选框及复选框事件绑定
if ($.fn.iCheck !== undefined) {
$(".check-box:not(.noicheck),.radio-box:not(.noicheck)").each(function() {
// iCheck单选框及复选框事件绑定
if ($.fn.iCheck !== undefined) {
$(".check-box:not(.noicheck),.radio-box:not(.noicheck)").each(function() {
$(this).iCheck({
checkboxClass: 'icheckbox-blue',
radioClass: 'iradio-blue',
})
})
}
}
// 气泡弹出框特效(移到元素时)
$(document).on("mouseenter", '.table [data-toggle="popover"]', function() {
var _this = this;
$(this).popover("show");
$(".popover").on("mouseleave", function() {
$(_this).popover('hide');
});
})
// 气泡弹出框特效(移到元素时)
$(document).on("mouseenter", '.table [data-toggle="popover"]', function() {
var _this = this;
$(this).popover("show");
$(".popover").on("mouseleave", function() {
$(_this).popover('hide');
});
})
// 气泡弹出框特效(离开元素时)
$(document).on("mouseleave", '.table [data-toggle="popover"]', function() {
var _this = this;
setTimeout(function() {
if (!$(".popover:hover").length) $(_this).popover("hide");
}, 100);
});
// 气泡弹出框特效(离开元素时)
$(document).on("mouseleave", '.table [data-toggle="popover"]', function() {
var _this = this;
setTimeout(function() {
if (!$(".popover:hover").length) $(_this).popover("hide");
}, 100);
});
// 取消回车自动提交表单
$(document).on("keypress", ":input:not(textarea):not([type=submit])", function(event) {
// 取消回车自动提交表单
$(document).on("keypress", ":input:not(textarea):not([type=submit])", function(event) {
if (event.keyCode == 13) {
event.preventDefault();
}
});
// laydate 时间控件绑定
if ($(".select-time").length > 0) {
layui.use('laydate', function() {
var laydate = layui.laydate;
var startDate = laydate.render({
elem: '#startTime',
max: $('#endTime').val(),
theme: 'molv',
trigger: 'click',
done: function(value, date) {
// 结束时间大于开始时间
if (value !== '') {
endDate.config.min.year = date.year;
endDate.config.min.month = date.month - 1;
endDate.config.min.date = date.date;
} else {
endDate.config.min.year = '';
endDate.config.min.month = '';
endDate.config.min.date = '';
}
}
});
var endDate = laydate.render({
elem: '#endTime',
min: $('#startTime').val(),
theme: 'molv',
trigger: 'click',
done: function(value, date) {
// 开始时间小于结束时间
if (value !== '') {
startDate.config.max.year = date.year;
startDate.config.max.month = date.month - 1;
startDate.config.max.date = date.date;
} else {
startDate.config.max.year = '2099';
startDate.config.max.month = '12';
startDate.config.max.date = '31';
}
}
});
});
}
// laydate 时间控件绑定
if ($(".select-time").length > 0) {
layui.use('laydate', function() {
var laydate = layui.laydate;
var startDate = laydate.render({
elem: '#startTime',
max: $('#endTime').val(),
theme: 'molv',
trigger: 'click',
done: function(value, date) {
// 结束时间大于开始时间
if (value !== '') {
endDate.config.min.year = date.year;
endDate.config.min.month = date.month - 1;
endDate.config.min.date = date.date;
} else {
endDate.config.min.year = '';
endDate.config.min.month = '';
endDate.config.min.date = '';
}
}
});
var endDate = laydate.render({
elem: '#endTime',
min: $('#startTime').val(),
theme: 'molv',
trigger: 'click',
done: function(value, date) {
// 开始时间小于结束时间
if (value !== '') {
startDate.config.max.year = date.year;
startDate.config.max.month = date.month - 1;
startDate.config.max.date = date.date;
} else {
startDate.config.max.year = '2099';
startDate.config.max.month = '12';
startDate.config.max.date = '31';
}
}
});
});
}
// laydate time-input 时间控件绑定
if ($(".time-input").length > 0) {
layui.use('laydate', function () {
var com = layui.laydate;
$(".time-input").each(function (index, item) {
var time = $(item);
// 控制控件外观
var type = time.attr("data-type") || 'date';
// 控制回显格式
var format = time.attr("data-format") || 'yyyy-MM-dd';
// 控制日期控件按钮
var buttons = time.attr("data-btn") || 'clear|now|confirm', newBtnArr = [];
// 日期控件选择完成后回调处理
var callback = time.attr("data-callback") || {};
if (buttons) {
if (buttons.indexOf("|") > 0) {
var btnArr = buttons.split("|"), btnLen = btnArr.length;
for (var j = 0; j < btnLen; j++) {
if ("clear" === btnArr[j] || "now" === btnArr[j] || "confirm" === btnArr[j]) {
newBtnArr.push(btnArr[j]);
}
}
} else {
if ("clear" === buttons || "now" === buttons || "confirm" === buttons) {
newBtnArr.push(buttons);
}
}
} else {
newBtnArr = ['clear', 'now', 'confirm'];
}
com.render({
elem: item,
theme: 'molv',
trigger: 'click',
type: type,
format: format,
btns: newBtnArr,
done: function (value, data) {
if (typeof window[callback] != 'undefined'
&& window[callback] instanceof Function) {
window[callback](value, data);
}
}
});
});
});
}
// laydate time-input 时间控件绑定
if ($(".time-input").length > 0) {
layui.use('laydate', function () {
var com = layui.laydate;
$(".time-input").each(function (index, item) {
var time = $(item);
// 控制控件外观
var type = time.attr("data-type") || 'date';
// 控制回显格式
var format = time.attr("data-format") || 'yyyy-MM-dd';
// 控制日期控件按钮
var buttons = time.attr("data-btn") || 'clear|now|confirm', newBtnArr = [];
// 日期控件选择完成后回调处理
var callback = time.attr("data-callback") || {};
if (buttons) {
if (buttons.indexOf("|") > 0) {
var btnArr = buttons.split("|"), btnLen = btnArr.length;
for (var j = 0; j < btnLen; j++) {
if ("clear" === btnArr[j] || "now" === btnArr[j] || "confirm" === btnArr[j]) {
newBtnArr.push(btnArr[j]);
}
}
} else {
if ("clear" === buttons || "now" === buttons || "confirm" === buttons) {
newBtnArr.push(buttons);
}
}
} else {
newBtnArr = ['clear', 'now', 'confirm'];
}
com.render({
elem: item,
theme: 'molv',
trigger: 'click',
type: type,
format: format,
btns: newBtnArr,
done: function (value, data) {
if (typeof window[callback] != 'undefined'
&& window[callback] instanceof Function) {
window[callback](value, data);
}
}
});
});
});
}
// tree 关键字搜索绑定
if ($("#keyword").length > 0) {
$("#keyword").bind("focus", function focusKey(e) {
if ($("#keyword").hasClass("empty")) {
$("#keyword").removeClass("empty");
}
}).bind("blur", function blurKey(e) {
if ($("#keyword").val() === "") {
$("#keyword").addClass("empty");
}
$.tree.searchNode(e);
}).bind("input propertychange", $.tree.searchNode);
}
// tree 关键字搜索绑定
if ($("#keyword").length > 0) {
$("#keyword").bind("focus", function focusKey(e) {
if ($("#keyword").hasClass("empty")) {
$("#keyword").removeClass("empty");
}
}).bind("blur", function blurKey(e) {
if ($("#keyword").val() === "") {
$("#keyword").addClass("empty");
}
$.tree.searchNode(e);
}).bind("input propertychange", $.tree.searchNode);
}
// tree表格树 展开/折叠
var expandFlag;
$("#expandAllBtn").click(function() {
var dataExpand = $.common.isEmpty(table.options.expandAll) ? true : table.options.expandAll;
expandFlag = $.common.isEmpty(expandFlag) ? dataExpand : expandFlag;
if (!expandFlag) {
$.bttTable.bootstrapTreeTable('expandAll');
} else {
$.bttTable.bootstrapTreeTable('collapseAll');
}
expandFlag = expandFlag ? false: true;
})
// tree表格树 展开/折叠
var expandFlag;
$("#expandAllBtn").click(function() {
var dataExpand = $.common.isEmpty(table.options.expandAll) ? true : table.options.expandAll;
expandFlag = $.common.isEmpty(expandFlag) ? dataExpand : expandFlag;
if (!expandFlag) {
$.bttTable.bootstrapTreeTable('expandAll');
} else {
$.bttTable.bootstrapTreeTable('collapseAll');
}
expandFlag = expandFlag ? false: true;
})
// 按下ESC按钮关闭弹层
$('body', document).on('keyup', function(e) {
if (e.which === 27) {
$.modal.closeAll();
}
});
// 按下ESC按钮关闭弹层
$('body', document).on('keyup', function(e) {
if (e.which === 27) {
$.modal.closeAll();
}
});
});
(function ($) {
'use strict';
$.fn.toTop = function(opt) {
var elem = this;
var win = $(window);
var doc = $('html, body');
var win = (opt && opt.hasOwnProperty('win')) ? opt.win : $(window);
var doc = (opt && opt.hasOwnProperty('doc')) ? opt.doc : $('html, body');
var options = $.extend({
autohide: true,
offset: 50,
@@ -233,8 +233,8 @@ $(function() {
/** 刷新选项卡 */
var refreshItem = function(){
var topWindow = $(window.parent.document);
var currentId = $('.page-tabs-content', topWindow).find('.active').attr('data-id');
var target = $('.RuoYi_iframe[data-id="' + currentId + '"]', topWindow);
var currentId = $('.page-tabs-content', topWindow).find('.active').attr('data-id');
var target = $('.RuoYi_iframe[data-id="' + currentId + '"]', topWindow);
var url = target.attr('src');
target.attr('src', url).ready();
}
@@ -243,29 +243,29 @@ var refreshItem = function(){
var closeItem = function(dataId){
var topWindow = $(window.parent.document);
if($.common.isNotEmpty(dataId)){
window.parent.$.modal.closeLoading();
// 根据dataId关闭指定选项卡
$('.menuTab[data-id="' + dataId + '"]', topWindow).remove();
// 移除相应tab对应的内容区
$('.mainContent .RuoYi_iframe[data-id="' + dataId + '"]', topWindow).remove();
return;
window.parent.$.modal.closeLoading();
// 根据dataId关闭指定选项卡
$('.menuTab[data-id="' + dataId + '"]', topWindow).remove();
// 移除相应tab对应的内容区
$('.mainContent .RuoYi_iframe[data-id="' + dataId + '"]', topWindow).remove();
return;
}
var panelUrl = window.frameElement.getAttribute('data-panel');
$('.page-tabs-content .active i', topWindow).click();
if($.common.isNotEmpty(panelUrl)){
$('.menuTab[data-id="' + panelUrl + '"]', topWindow).addClass('active').siblings('.menuTab').removeClass('active');
$('.mainContent .RuoYi_iframe', topWindow).each(function() {
if ($(this).data('id') == panelUrl) {
$(this).show().siblings('.RuoYi_iframe').hide();
return false;
$('.menuTab[data-id="' + panelUrl + '"]', topWindow).addClass('active').siblings('.menuTab').removeClass('active');
$('.mainContent .RuoYi_iframe', topWindow).each(function() {
if ($(this).data('id') == panelUrl) {
$(this).show().siblings('.RuoYi_iframe').hide();
return false;
}
});
}
});
}
}
/** 创建选项卡 */
function createMenuItem(dataUrl, menuName) {
var panelUrl = window.frameElement.getAttribute('data-id');
var panelUrl = window.frameElement.getAttribute('data-id');
dataIndex = $.common.random(1, 100),
flag = true;
if (dataUrl == undefined || $.trim(dataUrl).length == 0) return false;
@@ -300,7 +300,7 @@ function createMenuItem(dataUrl, menuName) {
window.parent.$.modal.loading("数据加载中,请稍后...");
$('.mainContent iframe:visible', topWindow).load(function () {
window.parent.$.modal.closeLoading();
window.parent.$.modal.closeLoading();
});
// 添加选项卡
@@ -312,7 +312,7 @@ function createMenuItem(dataUrl, menuName) {
// 滚动到指定选项卡
function scrollToTab(element) {
var topWindow = $(window.parent.document);
var topWindow = $(window.parent.document);
var marginLeftVal = calSumWidth($(element).prevAll()),
marginRightVal = calSumWidth($(element).nextAll());
// 可视区域非tab宽度
@@ -349,28 +349,28 @@ function calSumWidth(elements) {
/** 密码规则范围验证 */
function checkpwd(chrtype, password) {
if (chrtype == 1) {
if(!$.common.numValid(password)){
$.modal.alertWarning("密码只能为0-9数字");
return false;
}
} else if (chrtype == 2) {
if(!$.common.enValid(password)){
$.modal.alertWarning("密码只能为a-z和A-Z字母");
return false;
}
} else if (chrtype == 3) {
if(!$.common.enNumValid(password)){
$.modal.alertWarning("密码必须包含字母以及数字");
return false;
}
} else if (chrtype == 4) {
if(!$.common.charValid(password)){
$.modal.alertWarning("密码必须包含字母、数字、以及特殊符号-、_");
return false;
}
}
return true;
if (chrtype == 1) {
if(!$.common.numValid(password)){
$.modal.alertWarning("密码只能为0-9数字");
return false;
}
} else if (chrtype == 2) {
if(!$.common.enValid(password)){
$.modal.alertWarning("密码只能为a-z和A-Z字母");
return false;
}
} else if (chrtype == 3) {
if(!$.common.enNumValid(password)){
$.modal.alertWarning("密码必须包含字母以及数字");
return false;
}
} else if (chrtype == 4) {
if(!$.common.charValid(password)){
$.modal.alertWarning("密码必须包含字母、数字、以及特殊符号<font color='red'>~!@#$%^&*()-=_+</font>");
return false;
}
}
return true;
}
// 日志打印封装处理
@@ -411,21 +411,21 @@ var sub = {
var count = $("#" + table.options.id).bootstrapTable('getData').length;
var params = new Array();
for (var dataIndex = 0; dataIndex <= count; dataIndex++) {
var columns = $('#' + table.options.id + ' tr[data-index="' + dataIndex + '"] td');
var obj = new Object();
for (var i = 0; i < columns.length; i++) {
var inputValue = $(columns[i]).find('input');
var selectValue = $(columns[i]).find('select');
var key = table.options.columns[i].field;
if ($.common.isNotEmpty(inputValue.val())) {
obj[key] = inputValue.val();
} else if ($.common.isNotEmpty(selectValue.val())) {
obj[key] = selectValue.val();
} else {
obj[key] = "";
}
}
params.push({ index: dataIndex, row: obj });
var columns = $('#' + table.options.id + ' tr[data-index="' + dataIndex + '"] td');
var obj = new Object();
for (var i = 0; i < columns.length; i++) {
var inputValue = $(columns[i]).find('input');
var selectValue = $(columns[i]).find('select');
var key = table.options.columns[i].field;
if ($.common.isNotEmpty(inputValue.val())) {
obj[key] = inputValue.val();
} else if ($.common.isNotEmpty(selectValue.val())) {
obj[key] = selectValue.val();
} else {
obj[key] = "";
}
}
params.push({ index: dataIndex, row: obj });
}
$("#" + table.options.id).bootstrapTable("updateRow", params);
},
@@ -441,16 +441,35 @@ var sub = {
}
};
// 动态加载css文件
function loadCss(file, headElem) {
var link = document.createElement('link');
link.href = file;
link.rel = 'stylesheet';
link.type = 'text/css';
if (headElem) headElem.appendChild(link);
else document.getElementsByTagName('head')[0].appendChild(link);
}
// 动态加载js文件
function loadJs(file, headElem) {
var script = document.createElement('script');
script.src = file;
script.type = 'text/javascript';
if (headElem) headElem.appendChild(script);
else document.getElementsByTagName('head')[0].appendChild(script);
}
/** 设置全局ajax处理 */
$.ajaxSetup({
complete: function(XMLHttpRequest, textStatus) {
if (textStatus == 'timeout') {
$.modal.alertWarning("服务器超时,请稍后再试!");
$.modal.enable();
$.modal.alertWarning("服务器超时,请稍后再试!");
$.modal.enable();
$.modal.closeLoading();
} else if (textStatus == "parsererror" || textStatus == "error") {
$.modal.alertWarning("服务器错误,请联系管理员!");
$.modal.enable();
$.modal.alertWarning("服务器错误,请联系管理员!");
$.modal.enable();
$.modal.closeLoading();
}
}
File diff suppressed because it is too large Load Diff
@@ -1,22 +1,22 @@
$(function() {
validateKickout();
validateKickout();
validateRule();
$('.imgcode').click(function() {
var url = ctx + "captcha/captchaImage?type=" + captchaType + "&s=" + Math.random();
$(".imgcode").attr("src", url);
});
$('.imgcode').click(function() {
var url = ctx + "captcha/captchaImage?type=" + captchaType + "&s=" + Math.random();
$(".imgcode").attr("src", url);
});
});
$.validator.setDefaults({
submitHandler: function() {
login();
login();
}
});
function login() {
$.modal.loading($("#btnSubmit").data("loading"));
var username = $.common.trim($("input[name='username']").val());
$.modal.loading($("#btnSubmit").data("loading"));
var username = $.common.trim($("input[name='username']").val());
var password = $.common.trim($("input[name='password']").val());
var validateCode = $("input[name='validateCode']").val();
var rememberMe = $("input[name='rememberme']").is(':checked');
@@ -65,26 +65,26 @@ function validateRule() {
}
function validateKickout() {
if (getParam("kickout") == 1) {
layer.alert("<font color='red'>您已在别处登录,请您修改密码或重新登录</font>", {
icon: 0,
title: "系统提示"
},
function(index) {
//关闭弹窗
layer.close(index);
if (top != self) {
top.location = self.location;
} else {
var url  =  location.search;
if (url) {
var oldUrl  = window.location.href;
var newUrl  = oldUrl.substring(0,  oldUrl.indexOf('?'));
self.location  = newUrl;
}
}
});
}
if (getParam("kickout") == 1) {
layer.alert("<font color='red'>您已在别处登录,请您修改密码或重新登录</font>", {
icon: 0,
title: "系统提示"
},
function(index) {
//关闭弹窗
layer.close(index);
if (top != self) {
top.location = self.location;
} else {
var url  =  location.search;
if (url) {
var oldUrl  = window.location.href;
var newUrl  = oldUrl.substring(0,  oldUrl.indexOf('?'));
self.location  = newUrl;
}
}
});
}
}
function getParam(paramName) {
@@ -2,9 +2,9 @@
$(function() {
validateRule();
$('.imgcode').click(function() {
var url = ctx + "captcha/captchaImage?type=" + captchaType + "&s=" + Math.random();
$(".imgcode").attr("src", url);
});
var url = ctx + "captcha/captchaImage?type=" + captchaType + "&s=" + Math.random();
$(".imgcode").attr("src", url);
});
});
$.validator.setDefaults({
@@ -14,8 +14,8 @@ $.validator.setDefaults({
});
function register() {
$.modal.loading($("#btnSubmit").data("loading"));
var username = $.common.trim($("input[name='username']").val());
$.modal.loading($("#btnSubmit").data("loading"));
var username = $.common.trim($("input[name='username']").val());
var password = $.common.trim($("input[name='password']").val());
var validateCode = $("input[name='validateCode']").val();
$.ajax({
@@ -29,14 +29,14 @@ function register() {
success: function(r) {
if (r.code == 0) {
layer.alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", {
icon: 1,
title: "系统提示"
},
function(index) {
//关闭弹窗
layer.close(index);
location.href = ctx + 'login';
});
icon: 1,
title: "系统提示"
},
function(index) {
//关闭弹窗
layer.close(index);
location.href = ctx + 'login';
});
} else {
$.modal.closeLoading();
$('.imgcode').click();
@@ -48,7 +48,7 @@ function register() {
}
function validateRule() {
var icon = "<i class='fa fa-times-circle'></i> ";
var icon = "<i class='fa fa-times-circle'></i> ";
$("#registerForm").validate({
rules: {
username: {
@@ -0,0 +1,61 @@
<!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-4">
<div class="ibox">
<div class="ibox-content">
<h3>任务列表</h3>
<p class="small">
<i class="fa fa-hand-o-up"></i>
点击刷新按钮刷新数据到列表中
</p>
<div class="input-group">
<input id="task-name" type="text" placeholder="任务名称" class="input input-sm form-control">
<span class="input-group-btn">
<button type="button" class="btn btn-sm btn-white" onclick="refresh()">
<i class="fa fa-refresh"></i>
刷新
</button>
</span>
</div>
<div id="tasklist">
<ul class="sortable-list connectList agile-list" th:fragment="fragment-tasklist">
<li th:if="${tasks != null}" th:each="item : ${tasks}" class="warning-element">
[[${item.name}]]
<div class="agile-detail">
<a href="#" class="pull-right btn btn-xs btn-white">[[${item.type}]]</a>
<i class="fa fa-clock-o"></i>
[[${item.date}]]
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script>
function refresh(){
$.ajax({
type: "post",
url: ctx + "demo/form/localrefresh/task",
data: {
"taskName": $("#task-name").val(),
"fragment":'fragment-tasklist'
},
success: function(data) {
$("#tasklist").html(data);
}
});
}
</script>
</body>
</html>
@@ -17,7 +17,7 @@
<h2>若依后台管理系统</h2>
<p>ruoyi是一个完全响应式,基于Bootstrap3.3.6最新版本开发的扁平化主题,她采用了主流的左右两栏式布局,使用了Html5+CSS3等现代技术,她提供了诸多的强大的可以重新组合的UI组件,并集成了最新的jQuery版本(v2.1.1),当然,也集成了很多功能强大,用途广泛的就jQuery插件,她可以用于所有的Web应用程序,如<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p>
<p>
<b>当前版本:</b>v4.4.0
<b>当前版本:</b>v4.5.1
</p>
<p>
<span class="label label-warning">免费开源</span>
@@ -56,7 +56,7 @@
<h3>你好,若依 </h3>
<p>H+是一个完全响应式,基于Bootstrap3.3.6最新版本开发的扁平化主题,她采用了主流的左右两栏式布局,使用了Html5+CSS3等现代技术,她提供了诸多的强大的可以重新组合的UI组件,并集成了最新的jQuery版本(v2.1.1),当然,也集成了很多功能强大,用途广泛的就jQuery插件,她可以用于所有的Web应用程序,如<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p>
<p>
<b>当前版本:</b>v4.4.0
<b>当前版本:</b>v4.5.1
</p>
<p>
<span class="label label-warning">开源免费</span>
@@ -334,7 +334,7 @@
<div class="col-sm-6">
<div class="jumbotron">
<h1>超大屏幕</h1>
<p>Bootstrap 支持的另一个特性,超大屏幕(Jumbotron)。顾名思义该组件可以增加标题的大小,并为登页面内容添加更多的外边距(margin)。使用超大屏幕(Jumbotron)的步骤如下:</p>
<p>Bootstrap 支持的另一个特性,超大屏幕(Jumbotron)。顾名思义该组件可以增加标题的大小,并为登页面内容添加更多的外边距(margin)。使用超大屏幕(Jumbotron)的步骤如下:</p>
<div class="alert alert-warning">
<ol>
<li>创建一个带有 class .jumbotron. 的容器</li>
@@ -49,6 +49,14 @@
"/img/profile.jpg"
]
});
$("#fileinput-demo-1").on("fileuploaded", function(event, data, proviewId, index) {
console.info(event);
console.info(data);
console.info(proviewId);
console.info(index);
});
});
</script>
</body>
@@ -1,192 +1,332 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<th:block th:include="include :: header('基本表单')" />
<th:block th:include="include :: jquery-steps-css" />
<th:block th:include="include :: header('表单向导')" />
<th:block th:include="include :: jquery-smartwizard-css" />
<style type="text/css">
/* 如果要让工具栏固定在页面底部,使用下面的样式,不需要的可以注释 */
.sw>.toolbar-bottom{
z-index: 100;
bottom: 0px;
left: 0;
width: 100%;
position: fixed;
text-align: right;
background: #fff;
box-shadow: 0 -2px 6px 1px hsla(223,8%,83%,.5);
border-top: 1px solid #e3e4e8;
}
/* 如果设置了是否自动调节高度为false,需要加滚动条 */
.sw>.tab-content{
overflow-x: hidden;
overflow-y: auto;
}
</style>
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-5">
<div class="jumbotron">
<h1>表单向导</h1>
<p>Smart UI 部件允许您快速创建表单向导接口。</p>
<p><a href="https://github.com/rstaib/jquery-steps" target="_blank" class="btn btn-primary btn-lg" role="button">了解 jQuery Steps</a>
</p>
</div>
</div>
<div class="col-sm-7">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>基础表单向导</h5>
</div>
<div class="ibox-content">
<p>
这是一个简单的表单向导示例
</p>
<div id="wizard">
<h1>第一步</h1>
<div class="step-content">
<div class="text-center m-t-md">
<h2>第一步</h2>
<p>
这是第一步的内容
</p>
</div>
</div>
<div class="wrapper wrapper-content animated fadeInRight" style="height: 100%;">
<div class="row">
<div class="col-sm-12">
<div class="ibox">
<div class="ibox-title">
<h5>
表单向导
<small>https://github.com/techlab/jquery-smartwizard</small>
</h5>
</div>
<div class="ibox-content">
<div class="row select-list" style="padding-left: 15px; margin-bottom: 10px;">
<ul>
<li>
选择样式:
<select id="theme-selector">
<option value="default">Default</option>
<option value="arrows" selected>Arrows</option>
<option value="dots">Dots</option>
<option value="progress">Progress</option>
</select>
</li>
<!-- 快速操作栏按钮 -->
<li>
<div class="btn-group-sm" role="group">
<a class="btn btn-info" id="prev-btn"> 上一步 </a>
<a class="btn btn-success" id="next-btn"> 下一步 </a>
<a class="btn btn-danger" id="reset-btn"> 重置 </a>
</div>
</li>
</ul>
<h1>第二步</h1>
<div class="step-content">
<div class="text-center m-t-md">
<h2>第二步</h2>
<p>
这是第二步的内容
</p>
</div>
</div>
</div>
<div id="smartwizard">
<ul class="nav">
<li class="nav-item">
<a class="nav-link" href="#step-1"> 第一步 </a>
</li>
<li class="nav-item">
<a class="nav-link" href="#step-2"> 第二步 </a>
</li>
<li class="nav-item">
<a class="nav-link" href="#step-3"> 第三步 </a>
</li>
<li class="nav-item">
<a class="nav-link" href="#step-4"> 第四步 </a>
</li>
</ul>
<div class="tab-content">
<div id="step-1" class="tab-pane" role="tabpanel" aria-labelledby="step-1">
<div>
<form class="form form-horizontal m-t">
<div class="form-group">
<label class="col-sm-3 control-label">姓氏:</label>
<div class="col-sm-8">
<input id="firstname" name="firstname" class="form-control" type="text">
<span class="help-block m-b-none">
<i class="fa fa-info-circle"></i>
这里写点提示的内容
</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">名字:</label>
<div class="col-sm-8">
<input id="lastname" name="lastname" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">用户名:</label>
<div class="col-sm-8">
<input id="username" name="username" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">密码:</label>
<div class="col-sm-8">
<input id="password" name="password" class="form-control" type="password">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">确认密码:</label>
<div class="col-sm-8">
<input id="confirm_password" name="confirm_password" class="form-control" type="password">
<span class="help-block m-b-none">
<i class="fa fa-info-circle"></i>
请再次输入您的密码
</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">E-mail</label>
<div class="col-sm-8">
<input id="email" name="email" class="form-control" type="email">
</div>
</div>
</form>
</div>
</div>
<div id="step-2" class="tab-pane" role="tabpanel" aria-labelledby="step-2">
<div>
<form class="form form-horizontal m-t">
<div class="form-group">
<label class="col-sm-3 control-label">性别:</label>
<div class="col-sm-8">
<select name="sex" class="form-control m-b" th:with="type=${@dict.getType('sys_user_sex')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">时间:</label>
<div class="col-sm-8">
<input id="time" name="time" class="form-control time-input" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">状态:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_normal_disable')}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
</div>
</form>
</div>
</div>
<div id="step-3" class="tab-pane" role="tabpanel" aria-labelledby="step-3">
<div class="m-t-md">
<p>1、如果需要工具栏在页面底部显示, 将style中下面的部分取消注释<blockquote>.sw>.toolbar-bottom </blockquote></p>
<p>2、如果设置了自动调节高度为false, 将style中下面的部分取消注释<blockquote>.sw>.tab-content </blockquote></p>
<p>3、工具栏的按钮样式会被表单插件中.btn样式覆盖导致bootstrap中的按钮样式无效, 如果需要改变按钮样式可以自己定义并提高优先级</blockquote></p>
</div>
</div>
<div id="step-4" class="tab-pane" role="tabpanel" aria-labelledby="step-4">
<div class="m-t-md">
<h3>测试多行显示</h3>
<pre style="overflow-x: hidden;">
$('#smartwizard').smartWizard({
selected: 0, // Initial selected step, 0 = first step
theme: 'default', // theme for the wizard, related css need to include for other than default theme
justified: true, // Nav menu justification. true/false
darkMode:false, // Enable/disable Dark Mode if the theme supports. true/false
autoAdjustHeight: true, // Automatically adjust content height
cycleSteps: false, // Allows to cycle the navigation of steps
backButtonSupport: true, // Enable the back button support
enableURLhash: true, // Enable selection of the step based on url hash
transition: {
animation: 'none', // Effect on navigation, none/fade/slide-horizontal/slide-vertical/slide-swing
speed: '400', // Transion animation speed
easing:'' // Transition animation easing. Not supported without a jQuery easing plugin
},
toolbarSettings: {
toolbarPosition: 'bottom', // none, top, bottom, both
toolbarButtonPosition: 'right', // left, right, center
showNextButton: true, // show/hide a Next button
showPreviousButton: true, // show/hide a Previous button
toolbarExtraButtons: [] // Extra buttons to show on toolbar, array of jQuery input/buttons elements
},
anchorSettings: {
anchorClickable: true, // Enable/Disable anchor navigation
enableAllAnchors: false, // Activates all anchors clickable all times
markDoneStep: true, // Add done state on navigation
markAllPreviousStepsAsDone: true, // When a step selected by url hash, all previous steps are marked done
removeDoneStepOnNavigateBack: false, // While navigate back done step after active step will be cleared
enableAnchorOnDoneStep: true // Enable/Disable the done steps navigation
},
keyboardSettings: {
keyNavigation: true, // Enable/Disable keyboard navigation(left and right keys are used if enabled)
keyLeft: [37], // Left key code
keyRight: [39] // Right key code
},
lang: { // Language variables for button
next: 'Next',
previous: 'Previous'
},
disabledSteps: [], // Array Steps disabled
errorSteps: [], // Highlight step with errors
hiddenSteps: [] // Hidden steps
});
</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<h1>第三步</h1>
<div class="step-content">
<div class="text-center m-t-md">
<h2>第三步</h2>
<p>
这是第三步的内容
</p>
</div>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: jquery-smartwizard-js" />
<script>
$(document).ready(function() {
// 工具栏按钮
var btnFinish = $('<a id="btn-finish"></a>').text('完成')
.addClass('btn btn-info')
.on('click', function(){ submit(); });
var btnCancel = $('<a id="btn-cancel"></a>').text('取消')
.addClass('btn btn-danger')
.on('click', function(){ $('#smartwizard').smartWizard("reset"); });
// 下面两个按钮是为了因为插件默认的是botton,这里换成<a>,也可以选择用样式替换,或者不替换
var btnNext = $('<a id="btn-next"></a>').text('下一步')
.addClass('btn btn-info')
.on('click', function(){ $('#smartwizard').smartWizard("next");});
var btnPrev = $('<a id="btn-prev"></a>').text('上一步')
.addClass('btn btn-success disabled')
.on('click', function(){ $('#smartwizard').smartWizard("prev"); });
// 初始化表单向导组件
$('#smartwizard').smartWizard({
theme: 'arrows', // default, arrows, dots, progress
autoAdjustHeight : false, // 自动调整高度, 默认true
enableURLhash:false, //开启URL hash,开启后点击浏览器前进后退按钮会执行下一步和上一步操作
transition: {
animation: 'slide-horizontal', // Effect on navigation, none/fade/slide-horizontal/slide-vertical/slide-swing
},
toolbarSettings: {
showNextButton: false,// 因为上面自定义了下一步按钮, 所以隐藏掉插件自带的按钮, 如果不使用自定义按钮, 需要改为true或者去掉该属性
showPreviousButton: false,// 因为上面自定义了上一步按钮, 所以隐藏掉插件自带的按钮, 如果不使用自定义按钮, 需要改为true或者去掉该属性
toolbarExtraButtons: [btnCancel,btnPrev,btnNext,btnFinish]// 扩展的按钮集合
}
});
});
function submit(){
var data = {};
$('.form').each(function (index, form){
// 这里可以使用$.common.formToJSON(formId); 需要在form上加id
$.each($(form).serializeArray(), function(i, field) {
if(data[field.name]) {
data[field.name] += ("," + field.value);
} else {
data[field.name] = field.value;
}
});
});
alert(JSON.stringify(data))
}
// 显示步骤时将触发事件
$("#smartwizard").on("showStep", function(e, anchorObject, stepNumber, stepDirection, stepPosition) {
// 下面按钮是快速操作栏的
$("#prev-btn").removeClass('disabled');
$("#next-btn").removeClass('disabled');
// 下面按钮是工具栏的
$("#btn-prev").removeClass('disabled');
$("#btn-next").removeClass('disabled');
$("#btn-finish").removeClass('disabled');
if(stepPosition === 'first') {
$("#prev-btn").addClass('disabled');// 快速操作栏(演示用)
$("#btn-prev").addClass('disabled');
$("#btn-finish").addClass('disabled');
} else if(stepPosition === 'last') {
$("#next-btn").addClass('disabled');// 快速操作栏(演示用)
$("#btn-next").addClass('disabled');
} else {
$("#prev-btn").removeClass('disabled');// 快速操作栏(演示用)
$("#next-btn").removeClass('disabled');// 快速操作栏(演示用)
$("#btn-prev").removeClass('disabled');
$("#btn-next").removeClass('disabled');
$("#btn-finish").addClass('disabled');
}
});
// 该事件在离开某个步骤之前触发
$("#smartwizard").on("leaveStep", function(e, anchorObject, currentStepNumber, nextStepNumber, stepDirection) {
if(stepDirection == 'forward'){
var form = $("#step-" + (currentStepNumber + 1)).find('.form');
if(form.length > 0){
return form.validate().form();
}
return true;
}
return true;
});
$("#theme-selector").on("change", function() {
// Change theme
var options = {
theme : $(this).val()
};
$('#smartwizard').smartWizard("setOptions", options);
return true;
});
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="ibox">
<div class="ibox-title">
<h5>带验证的表单向导</h5>
</div>
<div class="ibox-content">
<h2>
带验证的表单向导
</h2>
<p>
下面这个示例展示了如何在表单向导中使用 jQuery Validation 插件
</p>
$("#reset-btn").on("click", function() {
// Reset wizard
$('#smartwizard').smartWizard("reset");
return true;
});
<form id="form" action="" class="wizard-big">
<h1>账户</h1>
<fieldset>
<h2>账户信息</h2>
<div class="row">
<div class="col-sm-8">
<div class="form-group">
<label>用户名 *</label>
<input id="userName" name="userName" type="text" class="form-control required">
</div>
<div class="form-group">
<label>密码 *</label>
<input id="password" name="password" type="text" class="form-control required">
</div>
<div class="form-group">
<label>确认密码 *</label>
<input id="confirm" name="confirm" type="text" class="form-control required">
</div>
</div>
<div class="col-sm-4">
<div class="text-center">
<div style="margin-top: 20px">
<i class="fa fa-sign-in" style="font-size: 180px;color: #e5e5e5 "></i>
</div>
</div>
</div>
</div>
$("#prev-btn").on("click", function() {
// Navigate previous
$('#smartwizard').smartWizard("prev");
return true;
});
</fieldset>
<h1>个人资料</h1>
<fieldset>
<h2>个人资料信息</h2>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label>姓名 *</label>
<input id="name" name="name" type="text" class="form-control required">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label>Email *</label>
<input id="email" name="email" type="text" class="form-control required email">
</div>
<div class="form-group">
<label>地址 *</label>
<input id="address" name="address" type="text" class="form-control">
</div>
</div>
</div>
</fieldset>
<h1>警告</h1>
<fieldset>
<div class="text-center" style="margin-top: 120px">
<h2>你是火星人 :-)</h2>
</div>
</fieldset>
<h1>完成</h1>
<fieldset>
<h2>条款</h2>
<input id="acceptTerms" name="acceptTerms" type="checkbox" class="required">
<label for="acceptTerms">我同意注册条款</label>
</fieldset>
</form>
</div>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: jquery-steps-js" />
<script>
$(document).ready(function () {
$("#wizard").steps();
$("#form").steps({
bodyTag: "fieldset", onStepChanging: function (event, currentIndex, newIndex) {
if (currentIndex > newIndex) {
return true
}
if (newIndex === 3 && Number($("#age").val()) < 18) {
return false
}
var form = $(this);
if (currentIndex < newIndex) {
$(".body:eq(" + newIndex + ") label.error", form).remove();
$(".body:eq(" + newIndex + ") .error", form).removeClass("error")
}
form.validate().settings.ignore = ":disabled,:hidden";
return form.valid()
}, onStepChanged: function (event, currentIndex, priorIndex) {
if (currentIndex === 2 && Number($("#age").val()) >= 18) {
$(this).steps("next")
}
if (currentIndex === 2 && priorIndex === 3) {
$(this).steps("previous")
}
}, onFinishing: function (event, currentIndex) {
var form = $(this);
form.validate().settings.ignore = ":disabled";
return form.valid()
}, onFinished: function (event, currentIndex) {
var form = $(this);
form.submit()
}
}).validate({
errorPlacement: function (error, element) {
element.before(error)
}, rules: {confirm: {equalTo: "#password"}}
})
});
$("#next-btn").on("click", function() {
// Navigate next
$('#smartwizard').smartWizard("next");
return true;
});
</script>
</body>
</html>
@@ -24,6 +24,10 @@
showRefresh: false,
showToggle: false,
showColumns: false,
onCheck: onCheck,
onUncheck: onUncheck,
onCheckAll: onCheckAll,
onUncheckAll: onUncheckAll,
onClickRow: onClickRow,
onDblClickRow: onDblClickRow,
onClickCell: onClickCell,
@@ -95,6 +99,28 @@
alert("双击格name" + field + " value" + value);
}
function onCheck(row, $element){
alert("选中行userId" + row.userId + " userName" + row.userName);
}
function onUncheck(row, $element){
alert("取消行userId" + row.userId + " userName" + row.userName);
}
function onCheckAll(rowsAfter, rowsBefore){
var rows = $.map(rowsAfter, function(row) {
return $.common.getItemField(row, "userId");
});
alert("全选行:" + rows);
}
function onUncheckAll(rowsAfter, rowsBefore){
var rows = $.map(rowsBefore, function(row) {
return $.common.getItemField(row, "userId");
});
alert("取消行:" + rows);
}
function responseHandler(res){
alert("请求获取数据后处理回调函数");
}
@@ -24,6 +24,7 @@
showRefresh: false,
showToggle: false,
showColumns: false,
footerStyle: footerStyle,
columns: [{
checkbox: true
},
@@ -78,6 +79,17 @@
};
$.table.init(options);
});
function footerStyle(column) {
return {
// userBalance: {
// classes: 'class'
// },
userBalance: {
css: { color: 'red', 'font-weight': 'normal' }
}
}[column.field]
}
</script>
</body>
</html>
@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('表格标题格式化')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<div th:include="include :: footer"></div>
<script th:inline="javascript">
var prefix = ctx + "demo/table";
var datas = [[${@dict.getType('sys_normal_disable')}]];
$(function() {
var options = {
url: prefix + "/list",
showSearch: false,
showRefresh: false,
showToggle: false,
showColumns: false,
headerStyle: headerStyle,
columns: [{
checkbox: true
},
{
field : 'userId',
title : '用户ID'
},
{
field : 'userCode',
title : '用户编号'
},
{
field : 'userName',
title : '用户姓名'
},
{
field : 'userPhone',
title : '用户手机'
},
{
field : 'userEmail',
title : '用户邮箱'
},
{
field : 'userBalance',
title : '用户余额'
},
{
field: 'status',
title: '用户状态',
align: 'center',
formatter: function(value, row, index) {
return $.table.selectDictLabel(datas, value);
}
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs" href="#"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs" href="#"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
function headerStyle(column) {
return {
userId: {
classes: 'uppercase'
},
userName: {
css: { background: 'yellow' }
},
userBalance: {
css: { color: 'red' }
}
} [column.field]
}
</script>
</body>
</html>
@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('表格列宽拖动')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 select-table table-bordered">
<table id="bootstrap-table" data-resizable="true"></table>
</div>
</div>
</div>
<div th:include="include :: footer"></div>
<th:block th:include="include :: bootstrap-table-resizable-js" />
<script th:inline="javascript">
var prefix = ctx + "demo/table";
var datas = [[${@dict.getType('sys_normal_disable')}]];
$(function() {
var options = {
url: prefix + "/list",
showSearch: false,
showRefresh: false,
showToggle: false,
showColumns: false,
columns: [{
checkbox: true
},
{
field : 'userId',
title : '用户ID'
},
{
field : 'userCode',
title : '用户编号'
},
{
field : 'userName',
title : '用户姓名'
},
{
field : 'userPhone',
title : '用户手机'
},
{
field : 'userEmail',
title : '用户邮箱'
},
{
field : 'userBalance',
title : '用户余额'
},
{
field: 'status',
title: '用户状态',
align: 'center',
formatter: function(value, row, index) {
return $.table.selectDictLabel(datas, value);
}
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs" href="#"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs" href="#"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
</script>
</body>
</html>
@@ -164,14 +164,6 @@
autoclose: true
});
function bindDatetimepicker() {
$("input[name$='date']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true,
pickerPosition:'top-right'
});
}
function addColumn() {
var count = $("#" + table.options.id).bootstrapTable('getData').length;
@@ -188,9 +180,16 @@
type: "",
}
});
bindDatetimepicker();
}
$("#bootstrap-table").on("post-body.bs.table", function (e, args) {
$("input[name$='date']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true,
pickerPosition:'top-right'
});
});
</script>
</body>
</html>
@@ -12,8 +12,8 @@
<!-- bootstrap-table 表格插件样式 -->
<link th:href="@{/ajax/libs/bootstrap-table/bootstrap-table.min.css?v=20200727}" rel="stylesheet"/>
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
<link th:href="@{/css/style.css?v=20200727}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.4.0}" rel="stylesheet"/>
<link th:href="@{/css/style.css?v=20200903}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.5.1}" rel="stylesheet"/>
</head>
<!-- 通用JS -->
@@ -36,8 +36,8 @@
<script th:src="@{/ajax/libs/iCheck/icheck.min.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ajax/libs/layui/layui.js}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.4.0}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.4.0}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.5.1}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.5.1}"></script>
<script th:inline="javascript"> var ctx = [[@{/}]]; </script>
</div>
@@ -147,12 +147,12 @@
<script th:src="@{/ajax/libs/jsonview/jquery.jsonview.js}"></script>
</div>
<!-- jquery.steps表单向导插件 -->
<div th:fragment="jquery-steps-css">
<link th:href="@{/ajax/libs/staps/jquery.steps.css}" rel="stylesheet"/>
<!-- jquery.smartwizard表单向导插件 -->
<div th:fragment="jquery-smartwizard-css">
<link th:href="@{/ajax/libs/smartwizard/smart_wizard_all.min.css}" rel="stylesheet"/>
</div>
<div th:fragment="jquery-steps-js">
<script th:src="@{/ajax/libs/staps/jquery.steps.min.js}"></script>
<div th:fragment="jquery-smartwizard-js">
<script th:src="@{/ajax/libs/smartwizard/jquery.smartWizard.min.js}"></script>
</div>
<!-- ECharts百度统计图表插件 -->
@@ -176,6 +176,12 @@
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder/jquery.tablednd.js}"></script>
</div>
<!-- 表格列宽拖动插件 -->
<div th:fragment="bootstrap-table-resizable-js">
<script th:src="@{/ajax/libs/bootstrap-table/extensions/resizable/jquery.resizableColumns.min.js}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/resizable/bootstrap-table-resizable.min.js}"></script>
</div>
<!-- 表格行内编辑插件 -->
<div th:fragment="bootstrap-editable-css">
<link th:href="@{/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.css}" rel="stylesheet"/>
@@ -0,0 +1,423 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="renderer" content="webkit">
<title>若依系统首页</title>
<!-- 避免IE使用兼容模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link th:href="@{favicon.ico}" rel="shortcut icon"/>
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
<link th:href="@{/css/jquery.contextMenu.min.css}" rel="stylesheet"/>
<link th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
<link th:href="@{/css/style.css}" rel="stylesheet"/>
<link th:href="@{/css/skins.css?v=20200902}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.5.1}" rel="stylesheet"/>
</head>
<body class="fixed-sidebar full-height-layout gray-bg" style="overflow: hidden">
<div id="wrapper">
<!--左侧导航开始-->
<nav class="navbar-default navbar-static-side" role="navigation">
<div class="nav-close">
<i class="fa fa-times-circle"></i>
</div>
<a th:href="@{/index}">
<li class="logo hidden-xs">
<span class="logo-lg">RuoYi</span>
</li>
</a>
<div class="sidebar-collapse tab-content" id="side-menu">
<div class="user-panel">
<a class="menuItem noactive" title="个人中心" th:href="@{/system/user/profile}">
<div class="hide" th:text="个人中心"></div>
<div class="pull-left image">
<img th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="this.src='img/profile.jpg'" class="img-circle" alt="User Image">
</div>
</a>
<div class="pull-left info">
<p>[[${user.loginName}]]</p>
<a href="#"><i class="fa fa-circle text-success"></i> 在线</a>
<a th:href="@{logout}" style="padding-left:5px;"><i class="fa fa-sign-out text-danger"></i> 注销</a>
</div>
</div>
<!-- 左侧菜单 -->
<th:block th:each="menu : ${menus}">
<div class="tab-pane fade height-full" th:id="|menu_${menu.menuId}|">
<ul class="nav">
<li th:each="cmenu : ${menu.children}">
<a class="menu-content" th:if="${#lists.isEmpty(cmenu.children)}" th:href="@{${cmenu.url}}" th:classappend="${#strings.isEmpty(cmenu.target)} ? |menuItem| : ${cmenu.target}">
<i th:class="${cmenu.icon} + ' fa-fw'"></i> <span class="nav-label">[[${cmenu.menuName}]]</span>
</a>
<a class="menu-content" th:if="${not #lists.isEmpty(cmenu.children)}" href="#">
<i th:class="${cmenu.icon} + ' fa-fw'"></i>
<span class="nav-label">[[${cmenu.menuName}]]</span>
<span class="fa arrow"></span>
</a>
<ul th:if="${not #lists.isEmpty(cmenu.children)}" class="nav nav-second-level collapse">
<li th:each="emenu : ${cmenu.children}">
<a th:if="${#lists.isEmpty(emenu.children)}" th:href="@{${emenu.url}}" th:class="${#strings.isEmpty(emenu.target)} ? |menuItem| : ${emenu.target}">
<i th:class="${emenu.icon} + ' fa-fw'"></i>
[[${emenu.menuName}]]
</a>
<a th:if="${not #lists.isEmpty(emenu.children)}" href="#">
<i th:class="${emenu.icon} + ' fa-fw'"></i>
[[${emenu.menuName}]]
<span class="fa arrow"></span>
</a>
<ul th:if="${not #lists.isEmpty(emenu.children)}" class="nav nav-third-level collapse">
<li th:each="fmenu : ${emenu.children}"><a th:if="${#lists.isEmpty(fmenu.children)}" th:class="${#strings.isEmpty(fmenu.target)} ? |menuItem| : ${fmenu.target}" th:href="@{${fmenu.url}}">[[${fmenu.menuName}]]</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</th:block>
<!-- 首页菜单 -->
<div class="tab-pane fade height-full" id="index">
<ul class="nav">
<li>
<a class="menuItem" th:href="@{/system/main}">
<i class="fa fa-home"></i> <span class="nav-label">首页</span></a>
</li>
</ul>
</div>
<!-- 实例演示菜单 -->
<div class="tab-pane fade height-full" id="demo" th:if="${demoEnabled}">
<ul class="nav">
<li>
<a href="#"><i class="fa fa-edit"></i> <span class="nav-label">表单</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level collapse">
<li><a class="menuItem" th:href="@{/demo/form/button}">按钮</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/timeline}">时间轴</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/jasny}">功能扩展</a></li>
<li><a class="menuItem" th:href="@{/demo/form/sortable}">拖动排序</a></li>
<li><a class="menuItem" th:href="@{/demo/form/tabs_panels}">选项卡 & 面板</a></li>
<li><a class="menuItem" th:href="@{/demo/form/validate}">表单校验</a></li>
<li><a class="menuItem" th:href="@{/demo/form/wizard}">表单向导</a></li>
<li><a class="menuItem" th:href="@{/demo/form/upload}">文件上传</a></li>
<li><a class="menuItem" th:href="@{/demo/form/datetime}">日期和时间</a></li>
<li><a class="menuItem" th:href="@{/demo/form/summernote}">富文本编辑器</a></li>
<li><a class="menuItem" th:href="@{/demo/form/duallistbox}">左右互选组件</a></li>
<li><a class="menuItem" th:href="@{/demo/form/autocomplete}">搜索自动补全</a></li>
<li><a class="menuItem" th:href="@{/demo/form/cxselect}">多级联动下拉</a></li>
<li><a class="menuItem" th:href="@{/demo/form/localrefresh}">Ajax局部刷新</a></li>
</ul>
</li>
<li>
<a href="#"><i class="fa fa-table"></i> <span class="nav-label">表格</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level collapse">
<li><a class="menuItem" th:href="@{/demo/table/search}">查询条件</a></li>
<li><a class="menuItem" th:href="@{/demo/table/footer}">数据汇总</a></li>
<li><a class="menuItem" th:href="@{/demo/table/groupHeader}">组合表头</a></li>
<li><a class="menuItem" th:href="@{/demo/table/export}">表格导出</a></li>
<li><a class="menuItem" th:href="@{/demo/table/remember}">翻页记住选择</a></li>
<li><a class="menuItem" th:href="@{/demo/table/pageGo}">跳转至指定页</a></li>
<li><a class="menuItem" th:href="@{/demo/table/params}">自定义查询参数</a></li>
<li><a class="menuItem" th:href="@{/demo/table/multi}">初始多表格</a></li>
<li><a class="menuItem" th:href="@{/demo/table/button}">点击按钮加载表格</a></li>
<li><a class="menuItem" th:href="@{/demo/table/data}">直接加载表格数据</a></li>
<li><a class="menuItem" th:href="@{/demo/table/fixedColumns}">表格冻结列</a></li>
<li><a class="menuItem" th:href="@{/demo/table/event}">自定义触发事件</a></li>
<li><a class="menuItem" th:href="@{/demo/table/headerStyle}">表格标题格式化</a></li>
<li><a class="menuItem" th:href="@{/demo/table/detail}">表格细节视图</a></li>
<li><a class="menuItem" th:href="@{/demo/table/child}">表格父子视图</a></li>
<li><a class="menuItem" th:href="@{/demo/table/image}">表格图片预览</a></li>
<li><a class="menuItem" th:href="@{/demo/table/curd}">动态增删改查</a></li>
<li><a class="menuItem" th:href="@{/demo/table/reorder}">表格拖拽操作</a></li>
<li><a class="menuItem" th:href="@{/demo/table/resizable}">表格列宽拖动</a></li>
<li><a class="menuItem" th:href="@{/demo/table/editable}">表格行内编辑</a></li>
<li><a class="menuItem" th:href="@{/demo/table/subdata}">主子表提交</a></li>
<li><a class="menuItem" th:href="@{/demo/table/refresh}">表格自动刷新</a></li>
<li><a class="menuItem" th:href="@{/demo/table/print}">表格打印配置</a></li>
<li><a class="menuItem" th:href="@{/demo/table/other}">表格其他操作</a></li>
</ul>
</li>
<li>
<a href="#"><i class="fa fa-flask"></i> <span class="nav-label">弹框</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level collapse">
<li><a class="menuItem" th:href="@{/demo/modal/dialog}">模态窗口</a></li>
<li><a class="menuItem" th:href="@{/demo/modal/layer}">弹层组件</a></li>
<li><a class="menuItem" th:href="@{/demo/modal/table}">弹层表格</a></li>
</ul>
</li>
<li>
<a href="#"><i class="fa fa-wpforms"></i> <span class="nav-label">操作</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level collapse">
<li><a class="menuItem" th:href="@{/demo/operate/table}">表格</a></li>
<li><a class="menuItem" th:href="@{/demo/operate/other}">其他</a></li>
</ul>
</li>
<li>
<a href="#"><i class="fa fa-bar-chart-o"></i> <span class="nav-label">报表</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level collapse">
<li><a class="menuItem" th:href="@{/demo/report/echarts}">百度ECharts</a></li>
<li><a class="menuItem" th:href="@{/demo/report/peity}">peity</a></li>
<li><a class="menuItem" th:href="@{/demo/report/sparkline}">sparkline</a></li>
<li><a class="menuItem" th:href="@{/demo/report/metrics}">图表组合</a></li>
</ul>
</li>
<li>
<a href="#"><i class="fa fa-book"></i> <span class="nav-label">图标</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level collapse">
<li><a class="menuItem" th:href="@{/demo/icon/fontawesome}">Font Awesome</a></li>
<li><a class="menuItem" th:href="@{/demo/icon/glyphicons}">Glyphicons</a></li>
</ul>
</li>
<li>
<a href="#"><i class="fa fa-navicon"></i> <span class="nav-label">四层菜单</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level collapse">
<li>
<a href="#" id="damian">三级菜单1<span class="fa arrow"></span></a>
<ul class="nav nav-third-level collapse">
<li>
<a href="#">四级菜单1</a>
</li>
<li>
<a href="#">四级菜单2</a>
</li>
</ul>
</li>
<li><a href="#">三级菜单2</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<!--左侧导航结束-->
<!--右侧部分开始-->
<div id="page-wrapper" class="gray-bg dashbard-1">
<div class="row border-bottom">
<nav class="navbar navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-header">
<a class="navbar-minimalize minimalize-styl-2" style="color:#FFF;" href="#" title="收起菜单">
<i class="fa fa-bars"></i>
</a>
</div>
<!-- 顶部栏 -->
<div id="navMenu">
<ul class="nav navbar-toolbar nav-tabs navbar-left hidden-xs">
<!-- 顶部菜单列表 -->
<th:block th:each="menu : ${menus}">
<li role="presentation" th:id="|tab_${menu.menuId}|">
<a data-toggle="tab" th:class="@{${!#strings.isEmpty(menu.target) && menu.target == 'menuBlank'} ? 'menuBlank'}" th:href="@{${!#strings.isEmpty(menu.target) && menu.target == 'menuBlank'} ? ${menu.url} : |#menu_${menu.menuId}|}">
<i th:class="${menu.icon}"></i> <span>[[${menu.menuName}]]</span>
</a>
</li>
</th:block>
<li role="presentation" id="tab_index">
<a data-toggle="tab" href="#index">
<i class="fa fa-area-chart"></i> <span>统计报表</span>
</a>
</li>
<li role="presentation" id="tab_demo" th:if="${demoEnabled}">
<a data-toggle="tab" href="#demo">
<i class="fa fa-desktop"></i> <span>实例演示</span>
</a>
</li>
</ul>
</div>
<!-- 右侧栏 -->
<ul class="nav navbar-top-links navbar-right welcome-message">
<li><a title="视频教程" href="http://doc.ruoyi.vip/ruoyi/document/spjc.html" target="_blank"><i class="fa fa-video-camera"></i> 视频教程</a></li>
<li><a title="开发文档" href="http://doc.ruoyi.vip" target="_blank"><i class="fa fa-question-circle"></i> 开发文档</a></li>
<li><a title="全屏显示" href="javascript:void(0)" id="fullScreen"><i class="fa fa-arrows-alt"></i> 全屏显示</a></li>
<li class="dropdown user-menu">
<a href="javascript:void(0)" class="dropdown-toggle" data-hover="dropdown">
<img th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="this.src='img/profile.jpg'" class="user-image">
<span class="hidden-xs">[[${#strings.defaultString(user.userName, '-')}]]</span>
</a>
<ul class="dropdown-menu">
<li class="mt5">
<a th:href="@{/system/user/profile}" class="menuItem">
<i class="fa fa-user"></i> 个人中心</a>
</li>
<li>
<a onclick="resetPwd()">
<i class="fa fa-key"></i> 修改密码</a>
</li>
<li>
<a onclick="switchSkin()">
<i class="fa fa-dashboard"></i> 切换主题</a>
</li>
<li>
<a onclick="toggleMenu()">
<i class="fa fa-toggle-off"></i> 左侧菜单</a>
</li>
<li class="divider"></li>
<li>
<a th:href="@{logout}">
<i class="fa fa-sign-out"></i> 退出登录</a>
</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="row content-tabs">
<button class="roll-nav roll-left tabLeft">
<i class="fa fa-backward"></i>
</button>
<nav class="page-tabs menuTabs">
<div class="page-tabs-content">
<a href="javascript:;" class="active menuTab" th:data-id="@{/system/main}">首页</a>
</div>
</nav>
<button class="roll-nav roll-right tabRight">
<i class="fa fa-forward"></i>
</button>
<a href="javascript:void(0);" class="roll-nav roll-right tabReload"><i class="fa fa-refresh"></i> 刷新</a>
</div>
<a id="ax_close_max" class="ax_close_max" href="#" title="关闭全屏"> <i class="fa fa-times-circle-o"></i> </a>
<div class="row mainContent" id="content-main" th:style="${#bools.isFalse(ignoreFooter)} ? |height: calc(100% - 91px)|">
<iframe class="RuoYi_iframe" name="iframe0" width="100%" height="100%" th:data-id="@{/system/main}"
th:src="@{/system/main}" frameborder="0" seamless></iframe>
</div>
<div th:if="${ignoreFooter}" class="footer">
<div class="pull-right">© [[${copyrightYear}]] RuoYi Copyright </div>
</div>
</div>
<!--右侧部分结束-->
</div>
<!-- 全局js -->
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>
<script th:src="@{/js/plugins/metisMenu/jquery.metisMenu.js}"></script>
<script th:src="@{/js/plugins/slimscroll/jquery.slimscroll.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/layer/layer.min.js}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.5.1}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.5.1}"></script>
<script th:src="@{/ruoyi/index.js?v=20200902}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
<script th:src="@{/js/resize-tabs.js}"></script>
<script th:inline="javascript">
var ctx = [[@{/}]];
// 皮肤缓存
var skin = storage.get("skin");
// history(表示去掉地址的#)否则地址以"#"形式展示
var mode = "history";
// 历史访问路径缓存
var historyPath = storage.get("historyPath");
// 是否页签与菜单联动
var isLinkage = true;
// 本地主题优先,未设置取系统配置
if($.common.isNotEmpty(skin)){
$("body").addClass(skin.split('|')[0]);
$("body").addClass(skin.split('|')[1]);
} else {
$("body").addClass([[${sideTheme}]]);
$("body").addClass([[${skinName}]]);
}
/* 用户管理-重置密码 */
function resetPwd() {
var url = ctx + 'system/user/profile/resetPwd';
$.modal.open("重置密码", url, '770', '380');
}
/* 切换主题 */
function switchSkin() {
layer.open({
type : 2,
shadeClose : true,
title : "切换主题",
area : ["530px", "386px"],
content : [ctx + "system/switchSkin", 'no']
})
}
/* 切换菜单 */
function toggleMenu() {
$.modal.confirm("确认要切换成左侧菜单吗?", function() {
$.get(ctx + 'system/menuStyle/default', function(result) {
window.location.reload();
});
})
}
/** 刷新时访问路径页签 */
function applyPath(url) {
var $dataObj = $('a[href$="' + decodeURI(url) + '"]');
$dataObj.click();
if (!$dataObj.hasClass("noactive")) {
$dataObj.parent("li").addClass("selected").parents("li").addClass("active").end().parents("ul").addClass("in");
}
// 顶部菜单同步处理
var tabStr = $dataObj.parents(".tab-pane").attr("id");
if ($.common.isNotEmpty(tabStr)) {
var sepIndex = tabStr.lastIndexOf('_');
var menuId = tabStr.substring(sepIndex + 1, tabStr.length);
$("#tab_" + menuId + " a").click();
}
}
$(function() {
if($.common.equals("history", mode) && window.performance.navigation.type == 1) {
var url = storage.get('publicPath');
if ($.common.isNotEmpty(url)) {
applyPath(url);
} else {
$(".navbar-toolbar li a").eq(0).click();
}
} else {
var hash = location.hash;
if ($.common.isNotEmpty(hash)) {
var url = hash.substring(1, hash.length);
applyPath(url);
} else {
if($.common.equals("history", mode)) {
storage.set('publicPath', "");
}
$(".navbar-toolbar li a").eq(0).click();
}
}
/* 初始密码提示 */
if([[${isDefaultModifyPwd}]]) {
layer.confirm("您的密码还是初始密码,请修改密码!", {
icon: 0,
title: "安全提示",
btn: ['确认' , '取消'],
offset: ['30%']
}, function (index) {
resetPwd();
layer.close(index);
});
}
/* 过期密码提示 */
if([[${isPasswordExpired}]]) {
layer.confirm("您的密码已过期,请尽快修改密码!", {
icon: 0,
title: "安全提示",
btn: ['确认' , '取消'],
offset: ['30%']
}, function (index) {
resetPwd();
layer.close(index);
});
}
});
</script>
</body>
</html>
@@ -14,7 +14,7 @@
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
<link th:href="@{/css/style.css}" rel="stylesheet"/>
<link th:href="@{/css/skins.css}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.4.0}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.5.1}" rel="stylesheet"/>
</head>
<body class="fixed-sidebar full-height-layout gray-bg" style="overflow: hidden">
<div id="wrapper">
@@ -93,6 +93,7 @@
<li><a class="menuItem" th:href="@{/demo/form/duallistbox}">左右互选组件</a></li>
<li><a class="menuItem" th:href="@{/demo/form/autocomplete}">搜索自动补全</a></li>
<li><a class="menuItem" th:href="@{/demo/form/cxselect}">多级联动下拉</a></li>
<li><a class="menuItem" th:href="@{/demo/form/localrefresh}">Ajax局部刷新</a></li>
</ul>
</li>
<li> <a>表格<span class="fa arrow"></span></a>
@@ -109,11 +110,13 @@
<li><a class="menuItem" th:href="@{/demo/table/data}">直接加载表格数据</a></li>
<li><a class="menuItem" th:href="@{/demo/table/fixedColumns}">表格冻结列</a></li>
<li><a class="menuItem" th:href="@{/demo/table/event}">自定义触发事件</a></li>
<li><a class="menuItem" th:href="@{/demo/table/headerStyle}">表格标题格式化</a></li>
<li><a class="menuItem" th:href="@{/demo/table/detail}">表格细节视图</a></li>
<li><a class="menuItem" th:href="@{/demo/table/child}">表格父子视图</a></li>
<li><a class="menuItem" th:href="@{/demo/table/image}">表格图片预览</a></li>
<li><a class="menuItem" th:href="@{/demo/table/curd}">动态增删改查</a></li>
<li><a class="menuItem" th:href="@{/demo/table/reorder}">表格拖拽操作</a></li>
<li><a class="menuItem" th:href="@{/demo/table/resizable}">表格列宽拖动</a></li>
<li><a class="menuItem" th:href="@{/demo/table/editable}">表格行内编辑</a></li>
<li><a class="menuItem" th:href="@{/demo/table/subdata}">主子表提交</a></li>
<li><a class="menuItem" th:href="@{/demo/table/refresh}">表格自动刷新</a></li>
@@ -203,6 +206,10 @@
<a onclick="switchSkin()">
<i class="fa fa-dashboard"></i> 切换主题</a>
</li>
<li>
<a onclick="toggleMenu()">
<i class="fa fa-toggle-off"></i> 横向菜单</a>
</li>
<li class="divider"></li>
<li>
<a th:href="@{logout}">
@@ -230,11 +237,12 @@
<a id="ax_close_max" class="ax_close_max" href="#" title="关闭全屏"> <i class="fa fa-times-circle-o"></i> </a>
<div class="row mainContent" id="content-main">
<div class="row mainContent" id="content-main" th:style="${#bools.isFalse(ignoreFooter)} ? |height: calc(100% - 91px)|">
<iframe class="RuoYi_iframe" name="iframe0" width="100%" height="100%" th:data-id="@{/system/main}"
th:src="@{/system/main}" frameborder="0" seamless></iframe>
</div>
<div class="footer">
<div th:if="${ignoreFooter}" class="footer">
<div class="pull-right">© [[${copyrightYear}]] RuoYi Copyright </div>
</div>
</div>
@@ -248,8 +256,8 @@
<script th:src="@{/js/jquery.contextMenu.min.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="@{/ruoyi/js/ry-ui.js?v=4.4.0}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.4.0}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.5.1}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.5.1}"></script>
<script th:src="@{/ruoyi/index.js}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
<script th:inline="javascript">
@@ -277,6 +285,7 @@ function resetPwd() {
var url = ctx + 'system/user/profile/resetPwd';
$.modal.open("重置密码", url, '770', '380');
}
/* 切换主题 */
function switchSkin() {
layer.open({
@@ -288,6 +297,15 @@ function switchSkin() {
})
}
/* 切换菜单 */
function toggleMenu() {
$.modal.confirm("确认要切换成横向菜单吗?", function() {
$.get(ctx + 'system/menuStyle/topnav', function(result) {
window.location.reload();
});
})
}
/** 刷新时访问路径页签 */
function applyPath(url) {
$('a[href$="' + decodeURI(url) + '"]').click();
@@ -307,8 +325,38 @@ $(function() {
if ($.common.isNotEmpty(hash)) {
var url = hash.substring(1, hash.length);
applyPath(url);
} else {
if($.common.equals("history", mode)) {
storage.set('publicPath', "");
}
}
}
/* 初始密码提示 */
if([[${isDefaultModifyPwd}]]) {
layer.confirm("您的密码还是初始密码,请修改密码!", {
icon: 0,
title: "安全提示",
btn: ['确认' , '取消'],
offset: ['30%']
}, function (index) {
resetPwd();
layer.close(index);
});
}
/* 过期密码提示 */
if([[${isPasswordExpired}]]) {
layer.confirm("您的密码已过期,请尽快修改密码!", {
icon: 0,
title: "安全提示",
btn: ['确认' , '取消'],
offset: ['30%']
}, function (index) {
resetPwd();
layer.close(index);
});
}
});
</script>
</body>
@@ -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/style.css" th:href="@{/css/style.css}" rel="stylesheet"/>
<link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.4.0}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.5.1}" rel="stylesheet"/>
<!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 -->
@@ -78,7 +78,7 @@
<script src="../static/ajax/libs/validate/messages_zh.min.js" th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script>
<script src="../static/ajax/libs/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/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.4.0}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.5.1}"></script>
<script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script>
</body>
</html>
@@ -20,6 +20,7 @@
<br><a target="_blank" href="https://www.aliyun.com/minisite/goods?userCode=brki8iof">https://www.aliyun.com/minisite/goods?userCode=brki8iof</a><br>
领取腾讯云通用云产品2860优惠券
<br><a target="_blank" href="https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console">https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console</a><br>
阿里云服务器折扣区 <a target="_blank" href="http://aly.ruoyi.vip">☛☛点我进入☚☚</a> &nbsp;&nbsp;&nbsp; 腾讯云服务器秒杀区 <a target="_blank" href="http://txy.ruoyi.vip">☛☛点我进入☚☚</a><br>
<h4 class="text-danger">云产品通用红包,可叠加官网常规优惠使用。(仅限新用户)</h4>
</blockquote>
@@ -79,7 +80,7 @@
<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>
<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> <a href="https://jq.qq.com/?_wv=1027&k=5omzbKc" target="_blank">339522636</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> <a href="https://jq.qq.com/?_wv=1027&k=qPIKBb7s" target="_blank">130035985</a>
</p>
<p><i class="fa fa-weixin"></i> 微信:<a href="javascript:;">/ *若依</a>
</p>
@@ -96,13 +97,98 @@
<div class="ibox-content no-padding">
<div class="panel-body">
<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="#v451">v4.5.1</a><code class="pull-right">2020.11.18</code>
</h5>
</div>
<div id="v451" class="panel-collapse collapse in">
<div class="panel-body">
<ol>
<li>阻止任意文件下载漏洞</li>
<li>升级shiro到最新版1.7.0 阻止权限绕过漏洞</li>
<li>升级druid到最新版本v1.2.2</li>
<li>新增表格行触发事件(onCheck、onUncheck、onCheckAll、onUncheckAll</li>
<li>修复多页签关闭非当前选项出现空白问题</li>
<li>代码生成预览支持高亮显示</li>
<li>mapperLocations配置支持分隔符</li>
<li>权限信息调整</li>
<li>个人中心头像和上传头像增加默认图片</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="#v45">v4.5.0</a><code class="pull-right">2020.10.20</code>
</h5>
</div>
<div id="v45" class="panel-collapse collapse">
<div class="panel-body">
<ol>
<li>新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单)</li>
<li>菜单&数据权限新增(展开/折叠 全选/全不选 父子联动)</li>
<li>账号密码支持自定义更新周期</li>
<li>初始密码支持自定义修改策略</li>
<li>新增校验用户修改新密码不能与旧密码相同</li>
<li>添加检查密码范围支持的特殊字符包括:~!@#$%^&*()-=_+</li>
<li>注册账号设置默认用户名称及密码最后更新时间</li>
<li>去除用户手机邮箱部门必填验证</li>
<li>新增日期格式化方法</li>
<li>代码生成添加bit类型</li>
<li>树结构加载添加callBack回调方法</li>
<li>修复用户管理页面滚动返回顶部条失效</li>
<li>修复代码生成模板文件上传组件缺少ctx的问题</li>
<li>限制系统内置参数不允许删除</li>
<li>新增表格列宽拖动插件</li>
<li>新增Ajax局部刷新demo</li>
<li>新增是否开启页脚功能</li>
<li>新增表格参数(通过自定义函数设置标题样式headerStyle</li>
<li>新增表格参数(通过自定义函数设置页脚样式footerStyle</li>
<li>修复窗体大小改变后浮动提示框失效问题</li>
<li>生成代码补充必填样式</li>
<li>生成页面时不忽略remark属性</li>
<li>字典数据列表页添加关闭按钮</li>
<li>Excel注解支持自动统计数据总和</li>
<li>升级springboot到2.1.17 提升安全性</li>
<li>升级pagehelper到最新版1.3.0</li>
<li>升级druid到最新版本v1.2.1</li>
<li>升级fastjson到最新版1.2.74</li>
<li>升级bootstrap-fileinput到最新版本5.1.2</li>
<li>升级oshi到最新版本v5.2.5</li>
<li>表单向导插件更换为jquery-smartwizard</li>
<li>修改主子表提交示例代码防止渲染失效</li>
<li>添加导入数据弹出窗体自定义宽高</li>
<li>用户信息参数返回忽略掉密码字段</li>
<li>优化关闭窗体添加index参数</li>
<li>回显数据字典(字符串数组)增加空值判断</li>
<li>修改前端密码长度校验和错误提示不符问题</li>
<li>AjaxResult重写put方法,以方便链式调用</li>
<li>增强验证码校验的语义,更易懂</li>
<li>导入excel整形值校验优化</li>
<li>Excel导出类型NUMERIC支持精度浮点类型</li>
<li>导出Excel调整targetAttr获取值方法,防止get方法不规范</li>
<li>输入框组验证错误后置图标提示颜色</li>
<li>上传媒体类型添加视频格式</li>
<li>数据权限判断参数类型</li>
<li>修正数据库字符串类型nvarchar</li>
<li>优化递归子节点</li>
<li>修复多表格搜索formId无效</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="#v44">v4.4.0</a><code class="pull-right">2020.08.24</code>
</h5>
</div>
<div id="v44" class="panel-collapse collapse in">
<div id="v44" class="panel-collapse collapse">
<div class="panel-body">
<ol>
<li>升级bootstrapTable到最新版本1.17.1</li>
@@ -707,7 +793,7 @@
<div id="v21" class="panel-collapse collapse">
<div class="panel-body">
<ol>
<li>新增登超时提醒</li>
<li>新增登超时提醒</li>
<li>修复定时器热部署转换问题</li>
<li>修复登录验证码校验无效问题</li>
<li>定时任务新增立即执行一次</li>
@@ -778,7 +864,7 @@
<div class="panel-body">
<ol>
<li>优化登录失败刷新验证码</li>
<li>新增用户登地址时间</li>
<li>新增用户登地址时间</li>
<li>修复ajax超时退出问题</li>
<li>新增html调用数据字典(若依首创)</li>
<li>调整系统部分样式</li>
@@ -1078,7 +1164,7 @@
type: 1,
closeBtn:false,
shadeClose:true,
area: ['600px', 'auto'],
area: ['600px', '360px'],
content: html
});
});
@@ -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/style.css" th:href="@{/css/style.css}" rel="stylesheet"/>
<link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.4.0}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.5.1}" rel="stylesheet"/>
<!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 -->
@@ -77,7 +77,7 @@
<script src="../static/ajax/libs/validate/messages_zh.min.js" th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script>
<script src="../static/ajax/libs/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/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.4.0}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.5.1}"></script>
<script src="../static/ruoyi/register.js" th:src="@{/ruoyi/register.js}"></script>
</body>
</html>
@@ -140,7 +140,7 @@
</ul>
</body>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.4.0}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.5.1}"></script>
<script type="text/javascript">
//皮肤样式列表
var skins = ["skin-blue", "skin-green", "skin-purple", "skin-red", "skin-yellow"];
@@ -73,8 +73,8 @@
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
sortName: "createTime",
sortOrder: "desc",
sortName: "configId",
sortOrder: "asc",
modalName: "参数",
columns: [{
checkbox: true
@@ -47,6 +47,9 @@
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:dict:export">
<i class="fa fa-download"></i> 导出
</a>
<a class="btn btn-danger" onclick="closeItem()">
<i class="fa fa-reply-all"></i> 关闭
</a>
</div>
<div class="col-sm-12 select-table table-striped">
@@ -75,8 +75,8 @@
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
sortName: "createTime",
sortOrder: "desc",
sortName: "dictId",
sortOrder: "asc",
modalName: "类型",
columns: [{
checkbox: true
@@ -42,9 +42,15 @@
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">菜单权限</label>
<label class="col-sm-3 control-label">菜单权限</label>
<div class="col-sm-8">
<div id="menuTrees" class="ztree"></div>
<label class="check-box">
<input type="checkbox" value="1">展开/折叠</label>
<label class="check-box">
<input type="checkbox" value="2">全选/全不选</label>
<label class="check-box">
<input type="checkbox" value="3" checked>父子联动</label>
<div id="menuTrees" class="ztree ztree-border"></div>
</div>
</div>
</form>
@@ -111,6 +117,30 @@
focusCleanup: true
});
$('input').on('ifChanged', function(obj){
var type = $(this).val();
var checked = obj.currentTarget.checked;
if (type == 1) {
if (checked) {
$._tree.expandAll(true);
} else {
$._tree.expandAll(false);
}
} else if (type == "2") {
if (checked) {
$._tree.checkAllNodes(true);
} else {
$._tree.checkAllNodes(false);
}
} else if (type == "3") {
if (checked) {
$._tree.setting.check.chkboxType = { "Y": "ps", "N": "ps" };
} else {
$._tree.setting.check.chkboxType = { "Y": "", "N": "" };
}
}
})
function submitHandler() {
if ($.validate.form()) {
add();
@@ -34,9 +34,15 @@
</div>
</div>
<div class="form-group" id="authDataScope" th:style="'display:' + @{(*{dataScope=='2'} ? 'block' : 'none')} + ''">
<label class="col-sm-3 control-label">数据权限</label>
<label class="col-sm-3 control-label">数据权限</label>
<div class="col-sm-8">
<div id="deptTrees" class="ztree"></div>
<label class="check-box">
<input type="checkbox" value="1" checked>展开/折叠</label>
<label class="check-box">
<input type="checkbox" value="2">全选/全不选</label>
<label class="check-box">
<input type="checkbox" value="3" checked>父子联动</label>
<div id="deptTrees" class="ztree ztree-border"></div>
</div>
</div>
</form>
@@ -55,6 +61,30 @@
};
$.tree.init(options);
});
$('input').on('ifChanged', function(obj){
var type = $(this).val();
var checked = obj.currentTarget.checked;
if (type == 1) {
if (checked) {
$._tree.expandAll(true);
} else {
$._tree.expandAll(false);
}
} else if (type == "2") {
if (checked) {
$._tree.checkAllNodes(true);
} else {
$._tree.checkAllNodes(false);
}
} else if (type == "3") {
if (checked) {
$._tree.setting.check.chkboxType = { "Y": "ps", "N": "ps" };
} else {
$._tree.setting.check.chkboxType = { "Y": "", "N": "" };
}
}
})
function submitHandler() {
if ($.validate.form()) {
@@ -43,9 +43,15 @@
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">菜单权限</label>
<label class="col-sm-3 control-label">菜单权限</label>
<div class="col-sm-8">
<div id="menuTrees" class="ztree"></div>
<label class="check-box">
<input type="checkbox" value="1">展开/折叠</label>
<label class="check-box">
<input type="checkbox" value="2">全选/全不选</label>
<label class="check-box">
<input type="checkbox" value="3" checked>父子联动</label>
<div id="menuTrees" class="ztree ztree-border"></div>
</div>
</div>
</form>
@@ -117,6 +123,30 @@
},
focusCleanup: true
});
$('input').on('ifChanged', function(obj){
var type = $(this).val();
var checked = obj.currentTarget.checked;
if (type == 1) {
if (checked) {
$._tree.expandAll(true);
} else {
$._tree.expandAll(false);
}
} else if (type == "2") {
if (checked) {
$._tree.checkAllNodes(true);
} else {
$._tree.checkAllNodes(false);
}
} else if (type == "3") {
if (checked) {
$._tree.setting.check.chkboxType = { "Y": "ps", "N": "ps" };
} else {
$._tree.setting.check.chkboxType = { "Y": "", "N": "" };
}
}
})
function edit() {
var roleId = $("input[name='roleId']").val();
@@ -20,10 +20,10 @@
</div>
<div class="col-sm-6">
<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="input-group">
<input name="deptName" onclick="selectDeptTree()" id="treeName" type="text" placeholder="请选择归属部门" class="form-control" required>
<input name="deptName" onclick="selectDeptTree()" id="treeName" type="text" placeholder="请选择归属部门" class="form-control">
<span class="input-group-addon"><i class="fa fa-search"></i></span>
</div>
</div>
@@ -33,10 +33,10 @@
<div class="row">
<div class="col-sm-6">
<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="input-group">
<input id="phonenumber" name="phonenumber" placeholder="请输入手机号码" class="form-control" type="text" maxlength="11" required>
<input id="phonenumber" name="phonenumber" placeholder="请输入手机号码" class="form-control" type="text" maxlength="11">
<span class="input-group-addon"><i class="fa fa-mobile"></i></span>
</div>
</div>
@@ -44,10 +44,10 @@
</div>
<div class="col-sm-6">
<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="input-group">
<input id="email" name="email" class="form-control email" type="text" maxlength="50" placeholder="请输入邮箱" required>
<input id="email" name="email" class="form-control email" type="text" maxlength="50" placeholder="请输入邮箱">
<span class="input-group-addon"><i class="fa fa-envelope"></i></span>
</div>
</div>
@@ -251,12 +251,10 @@
function doSubmit(index, layero){
var tree = layero.find("iframe")[0].contentWindow.$._tree;
if ($.tree.notAllowParents(tree)) {
var body = layer.getChildFrame('body', index);
$("#treeId").val(body.find('#treeId').val());
$("#treeName").val(body.find('#treeName').val());
layer.close(index);
}
var body = layer.getChildFrame('body', index);
$("#treeId").val(body.find('#treeId').val());
$("#treeName").val(body.find('#treeName').val());
layer.close(index);
}
$(function() {
@@ -21,10 +21,10 @@
</div>
<div class="col-sm-6">
<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="input-group">
<input class="form-control" type="text" name="deptName" onclick="selectDeptTree()" id="treeName" th:field="*{dept.deptName}" required>
<input class="form-control" type="text" name="deptName" onclick="selectDeptTree()" id="treeName" th:field="*{dept.deptName}">
<span class="input-group-addon"><i class="fa fa-search"></i></span>
</div>
</div>
@@ -34,10 +34,10 @@
<div class="row">
<div class="col-sm-6">
<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="input-group">
<input name="phonenumber" placeholder="请输入手机号码" class="form-control" type="text" maxlength="11" th:field="*{phonenumber}" required>
<input name="phonenumber" placeholder="请输入手机号码" class="form-control" type="text" maxlength="11" th:field="*{phonenumber}">
<span class="input-group-addon"><i class="fa fa-mobile"></i></span>
</div>
</div>
@@ -45,10 +45,10 @@
</div>
<div class="col-sm-6">
<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="input-group">
<input name="email" class="form-control email" type="text" maxlength="50" placeholder="请输入邮箱" th:field="*{email}" required>
<input name="email" class="form-control email" type="text" maxlength="50" placeholder="请输入邮箱" th:field="*{email}">
<span class="input-group-addon"><i class="fa fa-envelope"></i></span>
</div>
</div>
@@ -215,12 +215,10 @@
function doSubmit(index, layero){
var tree = layero.find("iframe")[0].contentWindow.$._tree;
if ($.tree.notAllowParents(tree)) {
var body = layer.getChildFrame('body', index);
$("#treeId").val(body.find('#treeId').val());
$("#treeName").val(body.find('#treeName').val());
layer.close(index);
}
var body = layer.getChildFrame('body', index);
$("#treeId").val(body.find('#treeId').val());
$("#treeName").val(body.find('#treeName').val());
layer.close(index);
}
$(function() {
@@ -134,7 +134,7 @@
<div class="row container">
<div class="col-md-10">
<div class="imageBox">
<img id="avatar" th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" >
<img id="avatar" th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="'this.src=\'' + @{'/img/profile.jpg'} + '\''">
</div>
<div class="action">
<div class="new-contentarea tc">
@@ -16,7 +16,7 @@
</div>
<div class="ibox-content">
<div class="text-center">
<p class="user-info-head" onclick="avatar()"><img class="img-circle img-lg" th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}"></p>
<p class="user-info-head" onclick="avatar()"><img class="img-circle img-lg" th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="'this.src=\'' + @{'/img/profile.jpg'} + '\''"></p>
<p><a href="javascript:avatar()">修改头像</a></p>
</div>
<ul class="list-group list-group-striped">
@@ -270,7 +270,7 @@
},
newPassword: {
required: "请输入新密码",
minlength: "密码不能小于6个字符",
minlength: "密码不能小于5个字符",
maxlength: "密码不能大于20个字符"
},
confirmPassword: {
@@ -69,7 +69,7 @@
},
newPassword: {
required: "请输入新密码",
minlength: "密码不能小于6个字符",
minlength: "密码不能小于5个字符",
maxlength: "密码不能大于20个字符"
},
confirmPassword: {
@@ -101,6 +101,14 @@
panehHidden = true;
}
$('body').layout({ initClosed: panehHidden, west__size: 185 });
// 回到顶部绑定
if ($.fn.toTop !== undefined) {
var opt = {
win:$('.ui-layout-center'),
doc:$('.ui-layout-center')
};
$('#scroll-up').toTop(opt);
}
queryUserList();
queryDeptTree();
});
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.4.0</version>
<version>4.5.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -100,6 +100,11 @@ public @interface Excel
*/
public String targetAttr() default "";
/**
* 是否自动统计数据,在最后追加一行统计数据总和
*/
public boolean isStatistics() default false;
/**
* 字段类型0导出导入1仅导出2仅导入
*/
@@ -10,7 +10,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@ConfigurationProperties(prefix = "ruoyi")
public class Global
public class RuoYiConfig
{
/** 项目名称 */
private static String name;
@@ -37,7 +37,7 @@ public class Global
public void setName(String name)
{
Global.name = name;
RuoYiConfig.name = name;
}
public static String getVersion()
@@ -47,7 +47,7 @@ public class Global
public void setVersion(String version)
{
Global.version = version;
RuoYiConfig.version = version;
}
public static String getCopyrightYear()
@@ -57,7 +57,7 @@ public class Global
public void setCopyrightYear(String copyrightYear)
{
Global.copyrightYear = copyrightYear;
RuoYiConfig.copyrightYear = copyrightYear;
}
public static boolean isDemoEnabled()
@@ -67,7 +67,7 @@ public class Global
public void setDemoEnabled(boolean demoEnabled)
{
Global.demoEnabled = demoEnabled;
RuoYiConfig.demoEnabled = demoEnabled;
}
public static String getProfile()
@@ -77,7 +77,7 @@ public class Global
public void setProfile(String profile)
{
Global.profile = profile;
RuoYiConfig.profile = profile;
}
public static boolean isAddressEnabled()
@@ -87,7 +87,7 @@ public class Global
public void setAddressEnabled(boolean addressEnabled)
{
Global.addressEnabled = addressEnabled;
RuoYiConfig.addressEnabled = addressEnabled;
}
/**
@@ -32,7 +32,7 @@ public class GenConstants
public static final String PARENT_MENU_NAME = "parentMenuName";
/** 数据库字符串类型 */
public static final String[] COLUMNTYPE_STR = { "char", "varchar", "narchar", "varchar2", "tinytext", "text",
public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2", "tinytext", "text",
"mediumtext", "longtext" };
/** 数据库时间类型 */
@@ -40,7 +40,7 @@ public class GenConstants
/** 数据库数字类型 */
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
"bigint", "float", "float", "double", "decimal" };
"bit", "bigint", "float", "float", "double", "decimal" };
/** 页面不需要编辑字段 */
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
@@ -5,7 +5,7 @@ import com.ruoyi.common.utils.StringUtils;
/**
* 操作消息提醒
*
*
* @author ruoyi
*/
public class AjaxResult extends HashMap<String, Object>
@@ -54,7 +54,7 @@ public class AjaxResult extends HashMap<String, Object>
/**
* 初始化一个新创建的 AjaxResult 对象
*
*
* @param type 状态类型
* @param msg 返回内容
*/
@@ -66,7 +66,7 @@ public class AjaxResult extends HashMap<String, Object>
/**
* 初始化一个新创建的 AjaxResult 对象
*
*
* @param type 状态类型
* @param msg 返回内容
* @param data 数据对象
@@ -81,9 +81,23 @@ 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;
}
/**
* 返回成功消息
*
*
* @return 成功消息
*/
public static AjaxResult success()
@@ -93,7 +107,7 @@ public class AjaxResult extends HashMap<String, Object>
/**
* 返回成功数据
*
*
* @return 成功消息
*/
public static AjaxResult success(Object data)
@@ -103,7 +117,7 @@ public class AjaxResult extends HashMap<String, Object>
/**
* 返回成功消息
*
*
* @param msg 返回内容
* @return 成功消息
*/
@@ -114,7 +128,7 @@ public class AjaxResult extends HashMap<String, Object>
/**
* 返回成功消息
*
*
* @param msg 返回内容
* @param data 数据对象
* @return 成功消息
@@ -126,7 +140,7 @@ public class AjaxResult extends HashMap<String, Object>
/**
* 返回警告消息
*
*
* @param msg 返回内容
* @return 警告消息
*/
@@ -137,7 +151,7 @@ public class AjaxResult extends HashMap<String, Object>
/**
* 返回警告消息
*
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
@@ -149,7 +163,7 @@ public class AjaxResult extends HashMap<String, Object>
/**
* 返回错误消息
*
*
* @return
*/
public static AjaxResult error()
@@ -159,7 +173,7 @@ public class AjaxResult extends HashMap<String, Object>
/**
* 返回错误消息
*
*
* @param msg 返回内容
* @return 警告消息
*/
@@ -170,7 +184,7 @@ public class AjaxResult extends HashMap<String, Object>
/**
* 返回错误消息
*
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
@@ -1,4 +1,4 @@
package com.ruoyi.system.domain;
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -1,4 +1,4 @@
package com.ruoyi.system.domain;
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -1,4 +1,4 @@
package com.ruoyi.system.domain;
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -1,4 +1,4 @@
package com.ruoyi.system.domain;
package com.ruoyi.common.core.domain.entity;
import java.util.List;
import java.util.ArrayList;
@@ -1,4 +1,4 @@
package com.ruoyi.system.domain;
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -1,10 +1,11 @@
package com.ruoyi.system.domain;
package com.ruoyi.common.core.domain.entity;
import java.util.Date;
import java.util.List;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excel.Type;
@@ -73,14 +74,17 @@ public class SysUser extends BaseEntity
/** 删除标志(0代表存在 2代表删除) */
private String delFlag;
/** 最后登IP */
@Excel(name = "最后登IP", type = Type.EXPORT)
/** 最后登IP */
@Excel(name = "最后登IP", type = Type.EXPORT)
private String loginIp;
/** 最后登时间 */
@Excel(name = "最后登时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
/** 最后登时间 */
@Excel(name = "最后登时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
private Date loginDate;
/** 密码最后更新时间 */
private Date pwdUpdateDate;
/** 部门对象 */
@Excels({
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
@@ -232,6 +236,7 @@ public class SysUser extends BaseEntity
this.avatar = avatar;
}
@JsonIgnore
public String getPassword()
{
return password;
@@ -292,6 +297,16 @@ public class SysUser extends BaseEntity
this.loginDate = loginDate;
}
public Date getPwdUpdateDate()
{
return pwdUpdateDate;
}
public void setPwdUpdateDate(Date pwdUpdateDate)
{
this.pwdUpdateDate = pwdUpdateDate;
}
public SysDept getDept()
{
if (dept == null)
@@ -68,4 +68,14 @@ public class InvalidExtensionException extends FileUploadException
super(allowedExtension, extension, filename);
}
}
public static class InvalidVideoExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
}
@@ -3,7 +3,7 @@ package com.ruoyi.common.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.http.HttpUtils;
@@ -30,7 +30,7 @@ public class AddressUtils
{
return "内网IP";
}
if (Global.isAddressEnabled())
if (RuoYiConfig.isAddressEnabled())
{
try
{
@@ -0,0 +1,138 @@
package com.ruoyi.common.utils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Cookie工具类
*
* @author ruoyi
*/
public class CookieUtils
{
/**
* 设置 Cookie生成时间为1天
*
* @param name 名称
* @param value
*/
public static void setCookie(HttpServletResponse response, String name, String value)
{
setCookie(response, name, value, 60 * 60 * 24);
}
/**
* 设置 Cookie
*
* @param name 名称
* @param value
* @param maxAge 生存时间单位秒
* @param uri 路径
*/
public static void setCookie(HttpServletResponse response, String name, String value, String path)
{
setCookie(response, name, value, path, 60 * 60 * 24);
}
/**
* 设置 Cookie
*
* @param name 名称
* @param value
* @param maxAge 生存时间单位秒
* @param uri 路径
*/
public static void setCookie(HttpServletResponse response, String name, String value, int maxAge)
{
setCookie(response, name, value, "/", maxAge);
}
/**
* 设置 Cookie
*
* @param name 名称
* @param value
* @param maxAge 生存时间单位秒
* @param uri 路径
*/
public static void setCookie(HttpServletResponse response, String name, String value, String path, int maxAge)
{
Cookie cookie = new Cookie(name, null);
cookie.setPath(path);
cookie.setMaxAge(maxAge);
try
{
cookie.setValue(URLEncoder.encode(value, "utf-8"));
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
response.addCookie(cookie);
}
/**
* 获得指定Cookie的值
*
* @param name 名称
* @return
*/
public static String getCookie(HttpServletRequest request, String name)
{
return getCookie(request, null, name, false);
}
/**
* 获得指定Cookie的值并删除
*
* @param name 名称
* @return
*/
public static String getCookie(HttpServletRequest request, HttpServletResponse response, String name)
{
return getCookie(request, response, name, true);
}
/**
* 获得指定Cookie的值
*
* @param request 请求对象
* @param response 响应对象
* @param name 名字
* @param isRemove 是否移除
* @return
*/
public static String getCookie(HttpServletRequest request, HttpServletResponse response, String name,
boolean isRemove)
{
String value = null;
Cookie[] cookies = request.getCookies();
if (cookies != null)
{
for (Cookie cookie : cookies)
{
if (cookie.getName().equals(name))
{
try
{
value = URLDecoder.decode(cookie.getValue(), "utf-8");
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
if (isRemove)
{
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
}
}
return value;
}
}
@@ -131,6 +131,14 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
return new Date(time);
}
/**
* 计算相差天数
*/
public static int differentDaysByMillisecond(Date date1, Date date2)
{
return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
}
/**
* 计算两个时间差
*/
@@ -1,11 +1,9 @@
package com.ruoyi.system.utils;
package com.ruoyi.common.utils;
import java.util.List;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.CacheUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictData;
/**
* 字典工具类
@@ -1,4 +1,4 @@
package com.ruoyi.framework.util;
package com.ruoyi.common.utils;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -8,7 +8,6 @@ import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.json.JSON;
import com.ruoyi.common.utils.IpUtils;
/**
* 处理并记录日志文件
@@ -16,6 +16,11 @@ import com.ruoyi.common.core.text.Convert;
*/
public class ServletUtils
{
/**
* 定义移动端请求的所有可能类型
*/
private final static String[] agent = { "Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser" };
/**
* 获取String参数
*/
@@ -132,4 +137,28 @@ public class ServletUtils
}
return false;
}
/**
* 判断User-Agent 是不是来自于手机
*/
public static boolean checkAgentIsMobile(String ua)
{
boolean flag = false;
if (!ua.contains("Windows NT") || (ua.contains("Windows NT") && ua.contains("compatible; MSIE 9.0;")))
{
// 排除 苹果桌面系统
if (!ua.contains("Windows NT") && !ua.contains("Macintosh"))
{
for (String item : agent)
{
if (ua.contains(item))
{
flag = true;
break;
}
}
}
}
return flag;
}
}
@@ -1,16 +1,13 @@
package com.ruoyi.framework.util;
package com.ruoyi.common.utils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.framework.shiro.realm.UserRealm;
import com.ruoyi.system.domain.SysUser;
/**
* shiro 工具类
@@ -56,13 +53,6 @@ public class ShiroUtils
subject.runAs(newPrincipalCollection);
}
public static void clearCachedAuthorizationInfo()
{
RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
UserRealm realm = (UserRealm) rsm.getRealms().iterator().next();
realm.clearCachedAuthorizationInfo();
}
public static Long getUserId()
{
return getSysUser().getUserId().longValue();
@@ -0,0 +1,47 @@
package com.ruoyi.common.utils.file;
import java.io.File;
import org.apache.commons.lang3.StringUtils;
/**
* 文件类型工具类
*
* @author ruoyi
*/
public class FileTypeUtils
{
/**
* 获取文件类型
* <p>
* 例如: ruoyi.txt, 返回: txt
*
* @param file 文件名
* @return 后缀不含".")
*/
public static String getFileType(File file)
{
if (null == file)
{
return StringUtils.EMPTY;
}
return getFileType(file.getName());
}
/**
* 获取文件类型
* <p>
* 例如: ruoyi.txt, 返回: txt
*
* @param fileName 文件名
* @return 后缀不含".")
*/
public static String getFileType(String fileName)
{
int separatorIndex = fileName.lastIndexOf(".");
if (separatorIndex < 0)
{
return "";
}
return fileName.substring(separatorIndex + 1).toLowerCase();
}
}
@@ -4,7 +4,7 @@ import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException;
import com.ruoyi.common.exception.file.FileSizeLimitExceededException;
@@ -33,7 +33,7 @@ public class FileUploadUtils
/**
* 默认上传的地址
*/
private static String defaultBaseDir = Global.getProfile();
private static String defaultBaseDir = RuoYiConfig.getProfile();
public static void setDefaultBaseDir(String defaultBaseDir)
{
@@ -131,20 +131,19 @@ public class FileUploadUtils
{
File desc = new File(uploadDir + File.separator + fileName);
if (!desc.getParentFile().exists())
{
desc.getParentFile().mkdirs();
}
if (!desc.exists())
{
desc.createNewFile();
if (!desc.getParentFile().exists())
{
desc.getParentFile().mkdirs();
}
}
return desc;
}
private static final String getPathFileName(String uploadDir, String fileName) throws IOException
{
int dirLastIndex = Global.getProfile().length() + 1;
int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
return pathFileName;
@@ -186,6 +185,11 @@ public class FileUploadUtils
throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
fileName);
}
else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
{
throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
fileName);
}
else
{
throw new InvalidExtensionException(allowedExtension, extension, fileName);
@@ -10,6 +10,8 @@ import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import com.ruoyi.common.utils.StringUtils;
/**
* 文件处理工具类
@@ -106,6 +108,30 @@ public class FileUtils extends org.apache.commons.io.FileUtils
return filename.matches(FILENAME_PATTERN);
}
/**
* 检查文件是否可下载
*
* @param resource 需要下载的文件
* @return true 正常 false 非法
*/
public static boolean checkAllowDownload(String resource)
{
// 禁止目录上跳级别
if (StringUtils.contains(resource, ".."))
{
return false;
}
// 检查允许下载的文件规则
if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
{
return true;
}
// 不在允许下载的文件规则
return false;
}
/**
* 下载文件名重新编码
*
@@ -113,8 +139,7 @@ public class FileUtils extends org.apache.commons.io.FileUtils
* @param fileName 文件名
* @return 编码后的文件名
*/
public static String setFileDownloadHeader(HttpServletRequest request, String fileName)
throws UnsupportedEncodingException
public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
{
final String agent = request.getHeader("USER-AGENT");
String filename = fileName;
@@ -16,7 +16,7 @@ public class MimeTypeUtils
public static final String IMAGE_BMP = "image/bmp";
public static final String IMAGE_GIF = "image/gif";
public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" };
public static final String[] FLASH_EXTENSION = { "swf", "flv" };
@@ -24,6 +24,8 @@ public class MimeTypeUtils
public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
"asf", "rm", "rmvb" };
public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" };
public static final String[] DEFAULT_ALLOWED_EXTENSION = {
// 图片
"bmp", "gif", "jpg", "jpeg", "png",
@@ -31,6 +33,8 @@ public class MimeTypeUtils
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
// 压缩文件
"rar", "zip", "gz", "bz2",
// 视频格式
"mp4", "avi", "rmvb",
// pdf
"pdf" };
@@ -6,7 +6,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
@@ -16,6 +15,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
@@ -45,14 +45,14 @@ import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.annotation.Excels;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
/**
* Excel相关处理
@@ -103,6 +103,16 @@ public class ExcelUtil<T>
*/
private List<Object[]> fields;
/**
* 统计列表
*/
private Map<Integer, Double> statistics = new HashMap<Integer, Double>();
/**
* 数字格式
*/
private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
/**
* 实体对象
*/
@@ -238,19 +248,19 @@ public class ExcelUtil<T>
}
}
}
else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType))
else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val)))
{
val = Convert.toInt(val);
}
else if ((Long.TYPE == fieldType) || (Long.class == fieldType))
else if (Long.TYPE == fieldType || Long.class == fieldType)
{
val = Convert.toLong(val);
}
else if ((Double.TYPE == fieldType) || (Double.class == fieldType))
else if (Double.TYPE == fieldType || Double.class == fieldType)
{
val = Convert.toDouble(val);
}
else if ((Float.TYPE == fieldType) || (Float.class == fieldType))
else if (Float.TYPE == fieldType || Float.class == fieldType)
{
val = Convert.toFloat(val);
}
@@ -347,6 +357,7 @@ public class ExcelUtil<T>
if (Type.EXPORT.equals(type))
{
fillExcelData(index, row);
addStatisticsRow();
}
}
String filename = encodingFilename(sheetName);
@@ -453,6 +464,15 @@ public class ExcelUtil<T>
headerFont.setColor(IndexedColors.WHITE.getIndex());
style.setFont(headerFont);
styles.put("header", style);
style = wb.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
Font totalFont = wb.createFont();
totalFont.setFontName("Arial");
totalFont.setFontHeightInPoints((short) 10);
style.setFont(totalFont);
styles.put("total", style);
return styles;
}
@@ -488,7 +508,7 @@ public class ExcelUtil<T>
else if (ColumnType.NUMERIC == attr.cellType())
{
cell.setCellType(CellType.NUMERIC);
cell.setCellValue(Integer.parseInt(value + ""));
cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value));
}
}
@@ -565,6 +585,7 @@ public class ExcelUtil<T>
// 设置列类型
setCellVo(value, attr, cell);
}
addStatisticsData(column, Convert.toStr(value), attr);
}
}
catch (Exception e)
@@ -724,10 +745,7 @@ public class ExcelUtil<T>
*/
public static String convertDictByExp(String dictValue, String dictType, String separator) throws Exception
{
Object bean = SpringUtils.getBean("dictUtils");
String methodName = "getDictLabel";
Method method = bean.getClass().getDeclaredMethod(methodName, String.class, String.class, String.class);
return Convert.toStr(method.invoke(bean, dictType, dictValue, separator));
return DictUtils.getDictLabel(dictType, dictValue, separator);
}
/**
@@ -740,10 +758,54 @@ public class ExcelUtil<T>
*/
public static String reverseDictByExp(String dictLabel, String dictType, String separator) throws Exception
{
Object bean = SpringUtils.getBean("dictUtils");
String methodName = "getDictValue";
Method method = bean.getClass().getDeclaredMethod(methodName, String.class, String.class, String.class);
return Convert.toStr(method.invoke(bean, dictType, dictLabel, separator));
return DictUtils.getDictValue(dictType, dictLabel, separator);
}
/**
* 合计统计信息
*/
private void addStatisticsData(Integer index, String text, Excel entity)
{
if (entity != null && entity.isStatistics())
{
Double temp = 0D;
if (!statistics.containsKey(index))
{
statistics.put(index, temp);
}
try
{
temp = Double.valueOf(text);
}
catch (NumberFormatException e)
{
}
statistics.put(index, statistics.get(index) + temp);
}
}
/**
* 创建统计行
*/
public void addStatisticsRow()
{
if (statistics.size() > 0)
{
Cell cell = null;
Row row = sheet.createRow(sheet.getLastRowNum() + 1);
Set<Integer> keys = statistics.keySet();
cell = row.createCell(0);
cell.setCellStyle(styles.get("total"));
cell.setCellValue("合计");
for (Integer key : keys)
{
cell = row.createCell(key);
cell.setCellStyle(styles.get("total"));
cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key)));
}
statistics.clear();
}
}
/**
@@ -762,7 +824,7 @@ public class ExcelUtil<T>
*/
public String getAbsoluteFile(String filename)
{
String downloadPath = Global.getDownloadPath() + filename;
String downloadPath = RuoYiConfig.getDownloadPath() + filename;
File desc = new File(downloadPath);
if (!desc.getParentFile().exists())
{
@@ -815,9 +877,9 @@ public class ExcelUtil<T>
if (StringUtils.isNotEmpty(name))
{
Class<?> clazz = o.getClass();
String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
Method method = clazz.getMethod(methodName);
o = method.invoke(o);
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
o = field.get(o);
}
return o;
}
+1 -11
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.4.0</version>
<version>4.5.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -71,16 +71,6 @@
<artifactId>oshi-core</artifactId>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
</dependency>
<!-- 系统模块-->
<dependency>
<groupId>com.ruoyi</groupId>

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