Compare commits

..

140 Commits

Author SHA1 Message Date
RuoYi c3a727b2fd 若依 3.8.5 2023-01-01 09:09:25 +08:00
RuoYi 19eaad0129 v3最新版本不需要render-after-expand 2022-12-23 16:08:23 +08:00
RuoYi 565cbb8c7a 升级pagehelper到最新版1.4.6 2022-12-13 19:42:39 +08:00
RuoYi b2cf949956 修改参数键名时移除前缓存配置 2022-12-13 19:40:48 +08:00
RuoYi 3fec133c69 升级oshi到最新版本6.4.0 2022-12-13 19:39:36 +08:00
RuoYi c9de6fcd82 优化代码 2022-12-13 19:39:19 +08:00
RuoYi 22ee2c2e94 删除fuse无效选项maxPatternLength 2022-12-08 10:21:48 +08:00
RuoYi f11db02ff8 修复代码生成图片/文件/单选时选择必填无法校验问题(I64IO2) 2022-12-08 10:19:38 +08:00
RuoYi d5f5c5d066 升级fastjson到最新版2.0.20 2022-12-08 10:13:39 +08:00
RuoYi 4536906b21 修复Vue3树形下拉不能默认选中(I64ESN) 2022-12-07 20:24:08 +08:00
RuoYi 9748e10339 升级druid到最新版本1.2.15 2022-12-07 11:41:44 +08:00
RuoYi b08a6ce3f6 升级kaptcha到最新版2.3.3 2022-12-07 10:45:50 +08:00
RuoYi 3039b745a9 升级echarts到最新版本5.4.0 2022-12-07 10:12:15 +08:00
RuoYi 39298d803c 添加新群号:170801498 2022-12-03 12:50:26 +08:00
RuoYi 09bb3e15c6 定时任务违规的字符 2022-12-03 12:48:51 +08:00
RuoYi 3b8a68c4cf 升级oshi到最新版本6.3.2 2022-12-03 12:43:37 +08:00
RuoYi 9aae863ce3 优化弹窗内容过多展示不全问题(I645RU) 2022-12-03 12:42:50 +08:00
若依 963247df43 !627 update ruoyi-ui/src/plugins/download.js.
Merge pull request !627 from Zeno/N/A
2022-12-01 08:21:29 +00:00
Zeno 7d874e31cf update ruoyi-ui/src/plugins/download.js.
修复文件名包含特殊字符(+、-、*...)的文件无法下载问题

Signed-off-by: Zeno <15270656234@163.com>
2022-11-28 10:29:38 +00:00
RuoYi 1bb6342bcb 修复Log注解GET请求记录不到参数问题 2022-11-22 10:41:40 +08:00
RuoYi 27acbe5b73 修复某些特性的环境生成代码变乱码TXT文件问题 2022-11-22 09:23:17 +08:00
RuoYi 6474a17100 消除Vue3控制台出现的警告信息 2022-11-21 19:10:25 +08:00
RuoYi 142f6ad6a0 兼容Excel下拉框内容过多无法显示的问题(I5XB6I) 2022-11-21 12:20:36 +08:00
RuoYi b4bdd4f306 开启TopNav没有子菜单隐藏侧边栏 2022-11-17 14:27:30 +08:00
RuoYi 74ba681fee 修复回显数据字典数组异常问题(I60UYQ) 2022-11-15 14:11:52 +08:00
若依 8f2b3ac465 !611 修复调度日志点击多次数据不变化的问题
Merge pull request !611 from 也曾为你像超人/N/A
2022-11-15 06:09:02 +00:00
RuoYi 7eee3b9f02 升级druid到最新版本1.2.14 2022-11-14 11:17:04 +08:00
RuoYi 27e34c2f0a 忽略不必要的属性数据返回 2022-11-12 11:26:48 +08:00
RuoYi 836180fe0e 优化导出对象的子列表为空会出现[]问题 2022-11-11 11:31:27 +08:00
RuoYi 06fbda5324 修复sheet超出最大行数异常问题 2022-11-07 11:20:02 +08:00
若依 bf313b17da !612 根据调度编号获取详细信息参数名改正
Merge pull request !612 from Rain/N/A
2022-10-31 05:51:48 +00:00
Rain a8b9485a29 根据调度编号获取详细信息参数名改正
Signed-off-by: Rain <938448486@qq.com>
2022-10-31 05:51:08 +00:00
也曾为你像超人 101e15d83f 修复调度日志点击多次数据不变化的问题
Signed-off-by: 也曾为你像超人 <1553592282@qq.com>
2022-10-31 05:45:21 +00:00
RuoYi ebb9f15a75 新增返回警告消息提示 2022-10-30 12:02:06 +08:00
RuoYi cd137bd9fc 升级fastjson到最新版2.0.16 2022-10-30 09:58:12 +08:00
若依 07bde5f88a !610 pagehelper-boot更新1.4.5
Merge pull request !610 from abbfun/N/A
2022-10-30 01:57:27 +00:00
abbfun 6fffa02acf pagehelper-boot更新1.4.5
Signed-off-by: abbfun <819589789@qq.com>
2022-10-29 14:45:55 +00:00
RuoYi dc48f9858b 修复table中更多按钮切换主题色未生效修复问题 2022-10-28 20:59:42 +08:00
RuoYi a6b2ac5dcd 升级oshi到最新版本6.3.0 2022-10-28 19:57:35 +08:00
若依 c0685b7f7f !608 编辑头像时生成为透明png图片
Merge pull request !608 from BlossomWave/N/A
2022-10-28 11:48:22 +00:00
若依 fb2d616c57 !609 优化代码
Merge pull request !609 from lihy2021/N/A
2022-10-28 11:44:27 +00:00
若依 6ff6853082 !606 重置时取消部门选中
Merge pull request !606 from 也曾为你像超人/N/A
2022-10-28 11:42:26 +00:00
若依 f8014ae969 !602 去除某些svg图标的fill="#bfbfbf"属性,避免菜单激活无法修改其填充颜色
Merge pull request !602 from 清溪先生/master
2022-10-28 11:39:13 +00:00
lihy2021 1de2b7a57e 优化代码 2022-10-27 01:25:39 +00:00
BlossomWave f01aa37394 update ruoyi-ui/src/views/system/user/profile/userAvatar.vue.
默认修改头像时如果上传的图片为png透明图片,生成的头像透明部分会变成黑色,修改了生成头像为png格式。可正常显示图片透明部分。

Signed-off-by: BlossomWave <316975215@qq.com>
2022-10-24 08:25:33 +00:00
也曾为你、像超人 4517dea98d 重置时取消部门选中
Signed-off-by: 也曾为你、像超人 <1553592282@qq.com>
2022-10-21 23:24:35 +00:00
RuoYi e21396870f 修正菜单状态注释信息 2022-10-21 11:56:15 +08:00
若依 b67f6a0fec !604 修复小屏幕上修改头像界面布局错位的问题
Merge pull request !604 from 也曾为你、像超人/master
2022-10-21 03:50:16 +00:00
若依 42d8104505 !603 update ruoyi-ui/src/views/system/user/index.vue.
Merge pull request !603 from kknd97/N/A
2022-10-21 03:46:49 +00:00
若依 f40a0eab23 !601 swagger-ui静态资源缓存
Merge pull request !601 from abbfun/N/A
2022-10-21 03:41:22 +00:00
刘元博 b6153d1aef 修正选择按钮宽度 2022-10-21 11:21:59 +08:00
若依 a2c585daa4 !605 升级fastjson到最新版2.0.15
Merge pull request !605 from Rain/N/A
2022-10-21 03:11:58 +00:00
Rain 5a60bf0b0a 升级fastjson到最新版2.0.15
Signed-off-by: Rain <938448486@qq.com>
2022-10-21 03:01:54 +00:00
刘元博 9dcddc7876 修复小屏幕上修改头像界面布局错位的问题 2022-10-20 19:18:10 +08:00
kknd97 b970185536 update ruoyi-ui/src/views/system/user/index.vue.
handleUpdate(row)方法中:this.form = response.data;语句
会导致【this.form.postIds = response.postIds;】和【this.form.roleIds = response.roleIds;】失效。
导致用户编辑对话框中,角色和部门多选框无法正常修改。
建议使用以下语句修改:
this.$set(this.form, "postIds", response.postIds);
this.$set(this.form, "roleIds", response.roleIds);

Signed-off-by: kknd97 <liujingwei@ln.chinamobile.com>
2022-10-20 06:27:02 +00:00
清溪先生 a64a029323 去除某些svg图标的fill="#bfbfbf"属性,避免菜单激活无法修改其填充颜色。
Signed-off-by: 清溪先生 <usfree2021@163.com>
2022-10-19 22:11:14 +08:00
abbfun 78f4d1c85b swagger-ui静态资源缓存
Signed-off-by: abbfun <819589789@qq.com>
2022-10-19 09:07:35 +00:00
RuoYi bf83fe568b 修复主题颜色在Drawer组件不会加载问题(I5VCF0) 2022-10-19 10:54:01 +08:00
RuoYi 6505432bf4 修复文件上传组件格式验证问题(I5V32H) 2022-10-12 19:33:58 +08:00
RuoYi a32a931d24 升级core-js到最新版本3.25.3 2022-10-10 09:22:47 +08:00
RuoYi 4d72fb4289 R isError and isSuccess static 2022-10-10 09:22:37 +08:00
若依 186c04d90a !595 解决导出时包含空子列表数据异常的问题
Merge pull request !595 from 也曾为你、像超人/N/A
2022-10-10 01:20:41 +00:00
也曾为你、像超人 c542b7ac32 解决导出时包含空子列表数据异常的问题
Signed-off-by: 也曾为你、像超人 <1553592282@qq.com>
2022-09-30 23:06:10 +00:00
RuoYi 3607e008a3 优化限流打印日志KEY(I5SQ09) 2022-09-28 19:32:55 +08:00
RuoYi 5b8edbf381 修复代码生成勾选属性无效问题 2022-09-28 19:31:52 +08:00
RuoYi 03f7bc0f3f 导入更新用户数据前校验数据权限 2022-09-28 19:26:16 +08:00
RuoYi e95a1245c5 若依 3.8.4 2022-09-26 08:29:03 +08:00
RuoYi d7441edae7 升级core-js到最新版本3.25.2 2022-09-22 11:13:49 +08:00
RuoYi 5053361a7f 升级fastjson到最新版2.0.14 2022-09-22 11:13:32 +08:00
若依 acbdd6365a !581 优化日志操作中重置按钮时重复查询的问题
Merge pull request !581 from 也曾为你、像超人/N/A
2022-09-19 06:41:36 +00:00
也曾为你、像超人 e781f88eca 优化日志操作中重置按钮时重复查询的问题
Signed-off-by: 也曾为你、像超人 <1553592282@qq.com>
2022-09-19 06:30:47 +00:00
RuoYi 86d16d070d 通用下载方法新增config配置选项(I5PNXE) 2022-09-19 13:09:21 +08:00
RuoYi 854b405d89 修改用户登录账号重复验证 2022-09-18 11:26:03 +08:00
RuoYi c3faa1a925 升级element-ui到最新版本2.15.10 2022-09-15 08:48:43 +08:00
RuoYi 37d6cc8146 优化代码生成同步后值NULL问题(I5OJDW) 2022-09-13 08:23:30 +08:00
RuoYi 2293822dc2 优化没有权限的用户编辑部门缺少数据(I5OF3O) 2022-09-12 17:22:23 +08:00
RuoYi f5bec70911 R add isError and isSuccess method 2022-09-12 17:22:07 +08:00
若依 87c53a049b !574 修复 issue#I5Q2ZO
Merge pull request !574 from 捏造的信仰/fix-I5Q2ZO
2022-09-09 01:45:12 +00:00
若依 5bcd2825b6 !568 style重复赋值
Merge pull request !568 from coverme/N/A
2022-09-09 01:25:22 +00:00
捏造的信仰 036144b9ea 插入 SysOperLog 时,限制 operUrl 属性的长度
Signed-off-by: 捏造的信仰 <yiding.he@gmail.com>
2022-09-07 03:00:51 +00:00
RuoYi 42d602b7a8 添加新群号:160110482 2022-08-28 20:09:25 +08:00
胡亚飞 d4b800036c style重复赋值
Signed-off-by: 胡亚飞 <huyafeily@aliyun.com>
2022-08-26 16:26:09 +00:00
若依 2f380f0c41 !564 修复执行任务时,若方法入口在任务的父类,则无法执行的问题
Merge pull request !564 from 捏造的信仰/fix-issue-I5NNXI
2022-08-26 00:42:03 +00:00
RuoYi 39efed1710 修复多文件上传报错出现的异常问题 2022-08-24 11:18:52 +08:00
RuoYi 9a895763d5 优化页面内嵌iframe切换tab不刷新数据 2022-08-23 20:59:26 +08:00
RuoYi 7347cbaedf 优化页面内嵌iframe切换tab不刷新数据 2022-08-23 17:29:09 +08:00
捏造的信仰 a78b5b7b2a 修复执行任务时,若方法入口在任务的父类,则无法执行的问题
实际项目开发中,可能会为所有定时任务类建一个共同的父类,任务的执行入口在父类定义,以便管理。此时使用 `getDeclaredMethod()` 是无法从子类找到要执行的方法的,而是要换用 `getMethod()` 方法。

Signed-off-by: 捏造的信仰 <yiding.he@gmail.com>
2022-08-23 05:36:29 +00:00
RuoYi 99d1760b98 优化代码 2022-08-22 15:27:58 +08:00
若依 4d71cfa90a !562 修复菜单管理已知问题
Merge pull request !562 from 稚屿/N/A
2022-08-22 06:20:18 +00:00
稚屿 e02f692359 修复菜单管理已知问题
问题描述:在菜单管理下,类型为菜单或者按钮的条目下点击修改按钮。
情况1,如果是类型为菜单,第一次点击修改按钮正常,则第二次点击另一个条目后面的修改按钮时报错!
情况2,如果是类型为按钮,第一次点击修改时正常,当点击取消按钮关闭弹窗时,浏览器报错!

报错代码:this.resetForm("form")

修复方案:添加遗漏的表单 prop 属性

Signed-off-by: 稚屿 <1491182878@qq.com>
2022-08-22 06:19:08 +00:00
RuoYi 77ec8d1c9a 修复代码生成权限父编号错误(I5NATP) 2022-08-22 12:21:07 +08:00
RuoYi 66ce21ec29 升级fastjson到最新版2.0.12 2022-08-22 12:04:01 +08:00
RuoYi 27e0937235 支持多权限字符匹配角色数据权限 2022-08-22 12:03:51 +08:00
RuoYi aadb7a41cb 优化Context信息,防止泄漏问题 2022-08-22 10:24:20 +08:00
RuoYi 9b3767a954 优化多角色数据权限匹配规则 2022-08-21 22:53:57 +08:00
RuoYi 851dc54b49 修复图片预览组件src属性为null值控制台报错问题(I5KBAS) 2022-08-15 12:07:24 +08:00
RuoYi cf2c4e02c6 字典管理操作类型新增其他 2022-08-14 09:40:36 +08:00
RuoYi 88b5715eae 升级oshi到最新版本6.2.2 2022-08-12 12:17:48 +08:00
RuoYi 5b05d4a123 个人中心修改密码去除多余的user传递 2022-08-12 12:17:28 +08:00
RuoYi 893ef39401 防止用户个人信息修改部门 2022-08-12 12:16:30 +08:00
RuoYi 890ad682d7 优化修改资料头像被覆盖的问题(I5LK04) 2022-08-11 13:22:55 +08:00
RuoYi b9f45057b8 操作日志记录支持排除敏感属性字段 2022-08-10 18:01:02 +08:00
RuoYi 89008c28df 升级fastjson到最新版2.0.11 2022-08-10 14:03:35 +08:00
RuoYi af7d0a3409 优化导出对象的子列表判断条件 2022-08-10 13:59:57 +08:00
RuoYi 1cd2eef899 优化excel/scale属性导出单元格数值类型 2022-08-09 08:02:24 +08:00
若依 8c7b93ec4f !547 fix: 账户解锁接口去掉多余的 /
Merge pull request !547 from iacker/N/A
2022-08-08 23:44:57 +00:00
iacker 3f7bf545b5 fix: 账户解锁接口去掉多余的 / 2022-08-08 13:55:08 +00:00
RuoYi cbedec7ca6 登录日志新增解锁账户功能 2022-08-08 09:23:52 +08:00
RuoYi fb1bac2114 新增删除Hash中的某条数据 2022-08-07 19:31:04 +08:00
RuoYi d0f399a66a 优化xss过滤后格式出现的异常 2022-08-07 19:30:54 +08:00
RuoYi e73dbd470a Excel注解支持导出对象的子列表方法 2022-08-07 18:33:04 +08:00
RuoYi e0cd5381e2 数据逻辑删除不进行唯一验证 2022-08-03 16:48:55 +08:00
RuoYi aee5d417ed 支持配置密码最大错误次数/锁定时间 2022-07-30 14:01:38 +08:00
RuoYi 250c5ba226 优化任务过期不执行调度 2022-07-29 20:28:59 +08:00
若依 b91c848962 !538 优化表格上右侧工具条(搜索按钮显隐&右侧样式凸出)
Merge pull request !538 from abbfun/N/A
2022-07-29 12:28:38 +00:00
abbfun d4475d0e8d 优化表格上右侧工具条(搜索按钮显隐&右侧样式凸出)
无搜索条件时可通过search隐藏搜索按钮,工具条组右侧样式超出5px(相对于底部表格),其父节点gutter代码生成默认10,此处也默认10,使工具组样式左右一致
2022-07-27 09:05:31 +00:00
RuoYi aff54ab5fe 自定义数据权限不排除重复 2022-07-26 20:02:17 +08:00
RuoYi 06177addf5 添加新群号:104748341 2022-07-25 18:45:51 +08:00
若依 9f3b91fe57 !535 所有的覆写方法,必须加@Override注解
Merge pull request !535 from 天才的逻辑/master
2022-07-25 10:32:48 +00:00
若依 80d25863db !536 防止主键字段名与'row'或'ids'一致导致报错的问题。
Merge pull request !536 from 张政/N/A
2022-07-25 10:32:42 +00:00
张政 cf8a7f8678 防止主键字段名与'row'或'ids'一致导致报错的问题。 2022-07-23 08:29:52 +00:00
RuoYi 86fc709b03 升级pagehelper到最新版1.4.3 2022-07-22 14:54:38 +08:00
b8b58cb202 所有的覆写方法,必须加@Override注解 2022-07-22 10:57:00 +08:00
96970ff951 所有的覆写方法,必须加@Override注解 2022-07-22 10:35:31 +08:00
RuoYi 7cc9d17424 支持自定义隐藏Excel属性列 2022-07-21 13:52:05 +08:00
RuoYi bc8b5f1079 优化布局设置使用el-drawer抽屉显示 2022-07-21 08:50:48 +08:00
RuoYi 5ec5e1a65d 优化字典数据使用store存取 2022-07-20 19:38:16 +08:00
RuoYi 1f0e742710 Excel注解支持backgroundColor属性设置背景色 2022-07-20 09:39:58 +08:00
RuoYi 28b9fbb4d2 优化多个相同角色数据导致权限SQL重复问题 2022-07-19 15:55:03 +08:00
RuoYi 2c79dc906e 升级oshi到最新版本6.2.1 2022-07-14 19:49:32 +08:00
RuoYi 1852017ecc 修改验证码开关变量名 2022-07-14 19:49:00 +08:00
若依 424d11896a !531 去除生成验证码多余的逻辑判断
Merge pull request !531 from 稚屿/N/A
2022-07-14 09:28:46 +00:00
稚屿 edefee46b2 去除生成验证码多余的逻辑判断 2022-07-13 01:00:44 +00:00
RuoYi c7c3da2038 升级fastjson到最新版2.0.9 2022-07-12 18:07:05 +08:00
RuoYi eb9f3d3772 修改验证码开关变量名 2022-07-12 18:04:49 +08:00
若依 1a61790407 !523 修改错误的变量名
Merge pull request !523 from SG/N/A
2022-07-12 10:02:50 +00:00
若依 fe98fba5b5 !527 调增数组格式声明,random随机转换修正
Merge pull request !527 from 靖少毅/jsy20220705
2022-07-12 10:01:56 +00:00
靖少毅 4eb8809a8a 调增数组格式声明,random随机转换修正 2022-07-05 16:43:55 +08:00
疯狂的狮子Li 0a893d196e update 优化魔法值 2022-07-05 02:06:31 +00:00
SG ec45cf04af 修改错误的变量名 2022-07-01 13:56:44 +00:00
156 changed files with 3047 additions and 1952 deletions
+3 -3
View File
@@ -1,11 +1,11 @@
<p align="center"> <p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png"> <img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
</p> </p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.3</h1> <h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.5</h1>
<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4> <h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
<p align="center"> <p align="center">
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a> <a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.3-brightgreen.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.5-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p> </p>
@@ -94,4 +94,4 @@
## 若依前后端分离交流群 ## 若依前后端分离交流群
QQ群: [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/139821253-blue.svg)](https://jq.qq.com/?_wv=1027&k=njiWDmkj) 点击按钮入群。 QQ群: [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) 点击按钮入群。
+8 -16
View File
@@ -6,26 +6,25 @@
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.8.3</version> <version>3.8.5</version>
<name>ruoyi</name> <name>ruoyi</name>
<url>http://www.ruoyi.vip</url> <url>http://www.ruoyi.vip</url>
<description>若依管理系统</description> <description>若依管理系统</description>
<properties> <properties>
<ruoyi.version>3.8.3</ruoyi.version> <ruoyi.version>3.8.5</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<druid.version>1.2.11</druid.version> <druid.version>1.2.15</druid.version>
<bitwalker.version>1.21</bitwalker.version> <bitwalker.version>1.21</bitwalker.version>
<swagger.version>3.0.0</swagger.version> <swagger.version>3.0.0</swagger.version>
<kaptcha.version>2.3.2</kaptcha.version> <kaptcha.version>2.3.3</kaptcha.version>
<mybatis-spring-boot.version>2.2.2</mybatis-spring-boot.version> <pagehelper.boot.version>1.4.6</pagehelper.boot.version>
<pagehelper.boot.version>1.4.1</pagehelper.boot.version> <fastjson.version>2.0.20</fastjson.version>
<fastjson.version>2.0.8</fastjson.version> <oshi.version>6.4.0</oshi.version>
<oshi.version>6.1.6</oshi.version>
<commons.io.version>2.11.0</commons.io.version> <commons.io.version>2.11.0</commons.io.version>
<commons.fileupload.version>1.4</commons.fileupload.version> <commons.fileupload.version>1.4</commons.fileupload.version>
<commons.collections.version>3.2.2</commons.collections.version> <commons.collections.version>3.2.2</commons.collections.version>
@@ -61,13 +60,6 @@
<version>${bitwalker.version}</version> <version>${bitwalker.version}</version>
</dependency> </dependency>
<!-- SpringBoot集成mybatis框架 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot.version}</version>
</dependency>
<!-- pagehelper 分页插件 --> <!-- pagehelper 分页插件 -->
<dependency> <dependency>
<groupId>com.github.pagehelper</groupId> <groupId>com.github.pagehelper</groupId>
@@ -146,7 +138,7 @@
<!-- 验证码 --> <!-- 验证码 -->
<dependency> <dependency>
<groupId>com.github.penggle</groupId> <groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId> <artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version> <version>${kaptcha.version}</version>
</dependency> </dependency>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.8.3</version> <version>3.8.5</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>
@@ -46,9 +46,9 @@ public class CaptchaController
public AjaxResult getCode(HttpServletResponse response) throws IOException public AjaxResult getCode(HttpServletResponse response) throws IOException
{ {
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
boolean captchaOnOff = configService.selectCaptchaOnOff(); boolean captchaEnabled = configService.selectCaptchaEnabled();
ajax.put("captchaOnOff", captchaOnOff); ajax.put("captchaEnabled", captchaEnabled);
if (!captchaOnOff) if (!captchaEnabled)
{ {
return ajax; return ajax;
} }
@@ -41,6 +41,7 @@ public class CacheController
caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码")); caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码"));
caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交")); caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交"));
caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理")); caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理"));
caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数"));
} }
@PreAuthorize("@ss.hasPermi('monitor:cache:list')") @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@@ -78,8 +79,8 @@ public class CacheController
@GetMapping("/getKeys/{cacheName}") @GetMapping("/getKeys/{cacheName}")
public AjaxResult getCacheKeys(@PathVariable String cacheName) public AjaxResult getCacheKeys(@PathVariable String cacheName)
{ {
Set<String> cacheKyes = redisTemplate.keys(cacheName + "*"); Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
return AjaxResult.success(cacheKyes); return AjaxResult.success(cacheKeys);
} }
@PreAuthorize("@ss.hasPermi('monitor:cache:list')") @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@@ -16,6 +16,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.service.SysPasswordService;
import com.ruoyi.system.domain.SysLogininfor; import com.ruoyi.system.domain.SysLogininfor;
import com.ruoyi.system.service.ISysLogininforService; import com.ruoyi.system.service.ISysLogininforService;
@@ -31,6 +32,9 @@ public class SysLogininforController extends BaseController
@Autowired @Autowired
private ISysLogininforService logininforService; private ISysLogininforService logininforService;
@Autowired
private SysPasswordService passwordService;
@PreAuthorize("@ss.hasPermi('monitor:logininfor:list')") @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysLogininfor logininfor) public TableDataInfo list(SysLogininfor logininfor)
@@ -64,6 +68,15 @@ public class SysLogininforController extends BaseController
public AjaxResult clean() public AjaxResult clean()
{ {
logininforService.cleanLogininfor(); logininforService.cleanLogininfor();
return AjaxResult.success(); return success();
}
@PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')")
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
@GetMapping("/unlock/{userName}")
public AjaxResult unlock(@PathVariable("userName") String userName)
{
passwordService.clearLoginRecordCache(userName);
return success();
} }
} }
@@ -64,6 +64,6 @@ public class SysOperlogController extends BaseController
public AjaxResult clean() public AjaxResult clean()
{ {
operLogService.cleanOperLog(); operLogService.cleanOperLog();
return AjaxResult.success(); return success();
} }
} }
@@ -87,6 +87,6 @@ public class SysUserOnlineController extends BaseController
public AjaxResult forceLogout(@PathVariable String tokenId) public AjaxResult forceLogout(@PathVariable String tokenId)
{ {
redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId); redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
return AjaxResult.success(); return success();
} }
} }
@@ -64,7 +64,7 @@ public class SysConfigController extends BaseController
@GetMapping(value = "/{configId}") @GetMapping(value = "/{configId}")
public AjaxResult getInfo(@PathVariable Long configId) public AjaxResult getInfo(@PathVariable Long configId)
{ {
return AjaxResult.success(configService.selectConfigById(configId)); return success(configService.selectConfigById(configId));
} }
/** /**
@@ -73,7 +73,7 @@ public class SysConfigController extends BaseController
@GetMapping(value = "/configKey/{configKey}") @GetMapping(value = "/configKey/{configKey}")
public AjaxResult getConfigKey(@PathVariable String configKey) public AjaxResult getConfigKey(@PathVariable String configKey)
{ {
return AjaxResult.success(configService.selectConfigByKey(configKey)); return success(configService.selectConfigByKey(configKey));
} }
/** /**
@@ -86,7 +86,7 @@ public class SysConfigController extends BaseController
{ {
if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
{ {
return AjaxResult.error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
} }
config.setCreateBy(getUsername()); config.setCreateBy(getUsername());
return toAjax(configService.insertConfig(config)); return toAjax(configService.insertConfig(config));
@@ -102,7 +102,7 @@ public class SysConfigController extends BaseController
{ {
if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
{ {
return AjaxResult.error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
} }
config.setUpdateBy(getUsername()); config.setUpdateBy(getUsername());
return toAjax(configService.updateConfig(config)); return toAjax(configService.updateConfig(config));
@@ -129,6 +129,6 @@ public class SysConfigController extends BaseController
public AjaxResult refreshCache() public AjaxResult refreshCache()
{ {
configService.resetConfigCache(); configService.resetConfigCache();
return AjaxResult.success(); return success();
} }
} }
@@ -1,6 +1,5 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -43,7 +42,7 @@ public class SysDeptController extends BaseController
public AjaxResult list(SysDept dept) public AjaxResult list(SysDept dept)
{ {
List<SysDept> depts = deptService.selectDeptList(dept); List<SysDept> depts = deptService.selectDeptList(dept);
return AjaxResult.success(depts); return success(depts);
} }
/** /**
@@ -54,17 +53,8 @@ public class SysDeptController extends BaseController
public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId)
{ {
List<SysDept> depts = deptService.selectDeptList(new SysDept()); List<SysDept> depts = deptService.selectDeptList(new SysDept());
Iterator<SysDept> it = depts.iterator(); depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""));
while (it.hasNext()) return success(depts);
{
SysDept d = (SysDept) it.next();
if (d.getDeptId().intValue() == deptId
|| ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""))
{
it.remove();
}
}
return AjaxResult.success(depts);
} }
/** /**
@@ -75,30 +65,7 @@ public class SysDeptController extends BaseController
public AjaxResult getInfo(@PathVariable Long deptId) public AjaxResult getInfo(@PathVariable Long deptId)
{ {
deptService.checkDeptDataScope(deptId); deptService.checkDeptDataScope(deptId);
return AjaxResult.success(deptService.selectDeptById(deptId)); return success(deptService.selectDeptById(deptId));
}
/**
* 获取部门下拉树列表
*/
@GetMapping("/treeselect")
public AjaxResult treeselect(SysDept dept)
{
List<SysDept> depts = deptService.selectDeptList(dept);
return AjaxResult.success(deptService.buildDeptTreeSelect(depts));
}
/**
* 加载对应角色部门列表树
*/
@GetMapping(value = "/roleDeptTreeselect/{roleId}")
public AjaxResult roleDeptTreeselect(@PathVariable("roleId") Long roleId)
{
List<SysDept> depts = deptService.selectDeptList(new SysDept());
AjaxResult ajax = AjaxResult.success();
ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
ajax.put("depts", deptService.buildDeptTreeSelect(depts));
return ajax;
} }
/** /**
@@ -111,7 +78,7 @@ public class SysDeptController extends BaseController
{ {
if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
{ {
return AjaxResult.error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
} }
dept.setCreateBy(getUsername()); dept.setCreateBy(getUsername());
return toAjax(deptService.insertDept(dept)); return toAjax(deptService.insertDept(dept));
@@ -129,15 +96,15 @@ public class SysDeptController extends BaseController
deptService.checkDeptDataScope(deptId); deptService.checkDeptDataScope(deptId);
if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
{ {
return AjaxResult.error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
} }
else if (dept.getParentId().equals(deptId)) else if (dept.getParentId().equals(deptId))
{ {
return AjaxResult.error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
} }
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0) else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
{ {
return AjaxResult.error("该部门包含未停用的子部门!"); return error("该部门包含未停用的子部门!");
} }
dept.setUpdateBy(getUsername()); dept.setUpdateBy(getUsername());
return toAjax(deptService.updateDept(dept)); return toAjax(deptService.updateDept(dept));
@@ -153,11 +120,11 @@ public class SysDeptController extends BaseController
{ {
if (deptService.hasChildByDeptId(deptId)) if (deptService.hasChildByDeptId(deptId))
{ {
return AjaxResult.error("存在下级部门,不允许删除"); return warn("存在下级部门,不允许删除");
} }
if (deptService.checkDeptExistUser(deptId)) if (deptService.checkDeptExistUser(deptId))
{ {
return AjaxResult.error("部门存在用户,不允许删除"); return warn("部门存在用户,不允许删除");
} }
deptService.checkDeptDataScope(deptId); deptService.checkDeptDataScope(deptId);
return toAjax(deptService.deleteDeptById(deptId)); return toAjax(deptService.deleteDeptById(deptId));
@@ -66,7 +66,7 @@ public class SysDictDataController extends BaseController
@GetMapping(value = "/{dictCode}") @GetMapping(value = "/{dictCode}")
public AjaxResult getInfo(@PathVariable Long dictCode) public AjaxResult getInfo(@PathVariable Long dictCode)
{ {
return AjaxResult.success(dictDataService.selectDictDataById(dictCode)); return success(dictDataService.selectDictDataById(dictCode));
} }
/** /**
@@ -80,7 +80,7 @@ public class SysDictDataController extends BaseController
{ {
data = new ArrayList<SysDictData>(); data = new ArrayList<SysDictData>();
} }
return AjaxResult.success(data); return success(data);
} }
/** /**
@@ -61,7 +61,7 @@ public class SysDictTypeController extends BaseController
@GetMapping(value = "/{dictId}") @GetMapping(value = "/{dictId}")
public AjaxResult getInfo(@PathVariable Long dictId) public AjaxResult getInfo(@PathVariable Long dictId)
{ {
return AjaxResult.success(dictTypeService.selectDictTypeById(dictId)); return success(dictTypeService.selectDictTypeById(dictId));
} }
/** /**
@@ -74,7 +74,7 @@ public class SysDictTypeController extends BaseController
{ {
if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
{ {
return AjaxResult.error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
} }
dict.setCreateBy(getUsername()); dict.setCreateBy(getUsername());
return toAjax(dictTypeService.insertDictType(dict)); return toAjax(dictTypeService.insertDictType(dict));
@@ -90,7 +90,7 @@ public class SysDictTypeController extends BaseController
{ {
if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
{ {
return AjaxResult.error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
} }
dict.setUpdateBy(getUsername()); dict.setUpdateBy(getUsername());
return toAjax(dictTypeService.updateDictType(dict)); return toAjax(dictTypeService.updateDictType(dict));
@@ -117,7 +117,7 @@ public class SysDictTypeController extends BaseController
public AjaxResult refreshCache() public AjaxResult refreshCache()
{ {
dictTypeService.resetDictCache(); dictTypeService.resetDictCache();
return AjaxResult.success(); return success();
} }
/** /**
@@ -127,6 +127,6 @@ public class SysDictTypeController extends BaseController
public AjaxResult optionselect() public AjaxResult optionselect()
{ {
List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll(); List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll();
return AjaxResult.success(dictTypes); return success(dictTypes);
} }
} }
@@ -41,7 +41,7 @@ public class SysMenuController extends BaseController
public AjaxResult list(SysMenu menu) public AjaxResult list(SysMenu menu)
{ {
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId()); List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
return AjaxResult.success(menus); return success(menus);
} }
/** /**
@@ -51,7 +51,7 @@ public class SysMenuController extends BaseController
@GetMapping(value = "/{menuId}") @GetMapping(value = "/{menuId}")
public AjaxResult getInfo(@PathVariable Long menuId) public AjaxResult getInfo(@PathVariable Long menuId)
{ {
return AjaxResult.success(menuService.selectMenuById(menuId)); return success(menuService.selectMenuById(menuId));
} }
/** /**
@@ -61,7 +61,7 @@ public class SysMenuController extends BaseController
public AjaxResult treeselect(SysMenu menu) public AjaxResult treeselect(SysMenu menu)
{ {
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId()); List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
return AjaxResult.success(menuService.buildMenuTreeSelect(menus)); return success(menuService.buildMenuTreeSelect(menus));
} }
/** /**
@@ -87,11 +87,11 @@ public class SysMenuController extends BaseController
{ {
if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
{ {
return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} }
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
{ {
return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
} }
menu.setCreateBy(getUsername()); menu.setCreateBy(getUsername());
return toAjax(menuService.insertMenu(menu)); return toAjax(menuService.insertMenu(menu));
@@ -107,15 +107,15 @@ public class SysMenuController extends BaseController
{ {
if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
{ {
return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} }
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
{ {
return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
} }
else if (menu.getMenuId().equals(menu.getParentId())) else if (menu.getMenuId().equals(menu.getParentId()))
{ {
return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
} }
menu.setUpdateBy(getUsername()); menu.setUpdateBy(getUsername());
return toAjax(menuService.updateMenu(menu)); return toAjax(menuService.updateMenu(menu));
@@ -131,11 +131,11 @@ public class SysMenuController extends BaseController
{ {
if (menuService.hasChildByMenuId(menuId)) if (menuService.hasChildByMenuId(menuId))
{ {
return AjaxResult.error("存在子菜单,不允许删除"); return warn("存在子菜单,不允许删除");
} }
if (menuService.checkMenuExistRole(menuId)) if (menuService.checkMenuExistRole(menuId))
{ {
return AjaxResult.error("菜单已分配,不允许删除"); return warn("菜单已分配,不允许删除");
} }
return toAjax(menuService.deleteMenuById(menuId)); return toAjax(menuService.deleteMenuById(menuId));
} }
@@ -51,7 +51,7 @@ public class SysNoticeController extends BaseController
@GetMapping(value = "/{noticeId}") @GetMapping(value = "/{noticeId}")
public AjaxResult getInfo(@PathVariable Long noticeId) public AjaxResult getInfo(@PathVariable Long noticeId)
{ {
return AjaxResult.success(noticeService.selectNoticeById(noticeId)); return success(noticeService.selectNoticeById(noticeId));
} }
/** /**
@@ -64,7 +64,7 @@ public class SysPostController extends BaseController
@GetMapping(value = "/{postId}") @GetMapping(value = "/{postId}")
public AjaxResult getInfo(@PathVariable Long postId) public AjaxResult getInfo(@PathVariable Long postId)
{ {
return AjaxResult.success(postService.selectPostById(postId)); return success(postService.selectPostById(postId));
} }
/** /**
@@ -77,11 +77,11 @@ public class SysPostController extends BaseController
{ {
if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
{ {
return AjaxResult.error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
} }
else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post)))
{ {
return AjaxResult.error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
} }
post.setCreateBy(getUsername()); post.setCreateBy(getUsername());
return toAjax(postService.insertPost(post)); return toAjax(postService.insertPost(post));
@@ -97,11 +97,11 @@ public class SysPostController extends BaseController
{ {
if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
{ {
return AjaxResult.error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
} }
else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post)))
{ {
return AjaxResult.error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
} }
post.setUpdateBy(getUsername()); post.setUpdateBy(getUsername());
return toAjax(postService.updatePost(post)); return toAjax(postService.updatePost(post));
@@ -125,6 +125,6 @@ public class SysPostController extends BaseController
public AjaxResult optionselect() public AjaxResult optionselect()
{ {
List<SysPost> posts = postService.selectPostAll(); List<SysPost> posts = postService.selectPostAll();
return AjaxResult.success(posts); return success(posts);
} }
} }
@@ -66,15 +66,17 @@ public class SysProfileController extends BaseController
if (StringUtils.isNotEmpty(user.getPhonenumber()) if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{ {
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
} }
if (StringUtils.isNotEmpty(user.getEmail()) if (StringUtils.isNotEmpty(user.getEmail())
&& UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
{ {
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
} }
user.setUserId(sysUser.getUserId()); user.setUserId(sysUser.getUserId());
user.setPassword(null); user.setPassword(null);
user.setAvatar(null);
user.setDeptId(null);
if (userService.updateUserProfile(user) > 0) if (userService.updateUserProfile(user) > 0)
{ {
// 更新缓存用户信息 // 更新缓存用户信息
@@ -83,9 +85,9 @@ public class SysProfileController extends BaseController
sysUser.setEmail(user.getEmail()); sysUser.setEmail(user.getEmail());
sysUser.setSex(user.getSex()); sysUser.setSex(user.getSex());
tokenService.setLoginUser(loginUser); tokenService.setLoginUser(loginUser);
return AjaxResult.success(); return success();
} }
return AjaxResult.error("修改个人信息异常,请联系管理员"); return error("修改个人信息异常,请联系管理员");
} }
/** /**
@@ -100,20 +102,20 @@ public class SysProfileController extends BaseController
String password = loginUser.getPassword(); String password = loginUser.getPassword();
if (!SecurityUtils.matchesPassword(oldPassword, password)) if (!SecurityUtils.matchesPassword(oldPassword, password))
{ {
return AjaxResult.error("修改密码失败,旧密码错误"); return error("修改密码失败,旧密码错误");
} }
if (SecurityUtils.matchesPassword(newPassword, password)) if (SecurityUtils.matchesPassword(newPassword, password))
{ {
return AjaxResult.error("新密码不能与旧密码相同"); return error("新密码不能与旧密码相同");
} }
if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0) if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0)
{ {
// 更新缓存用户密码 // 更新缓存用户密码
loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword)); loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));
tokenService.setLoginUser(loginUser); tokenService.setLoginUser(loginUser);
return AjaxResult.success(); return success();
} }
return AjaxResult.error("修改密码异常,请联系管理员"); return error("修改密码异常,请联系管理员");
} }
/** /**
@@ -137,6 +139,6 @@ public class SysProfileController extends BaseController
return ajax; return ajax;
} }
} }
return AjaxResult.error("上传图片异常,请联系管理员"); return error("上传图片异常,请联系管理员");
} }
} }
@@ -17,6 +17,7 @@ import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
@@ -27,6 +28,7 @@ import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.service.SysPermissionService; import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.domain.SysUserRole; import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
@@ -44,13 +46,16 @@ public class SysRoleController extends BaseController
@Autowired @Autowired
private TokenService tokenService; private TokenService tokenService;
@Autowired @Autowired
private SysPermissionService permissionService; private SysPermissionService permissionService;
@Autowired @Autowired
private ISysUserService userService; private ISysUserService userService;
@Autowired
private ISysDeptService deptService;
@PreAuthorize("@ss.hasPermi('system:role:list')") @PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysRole role) public TableDataInfo list(SysRole role)
@@ -78,7 +83,7 @@ public class SysRoleController extends BaseController
public AjaxResult getInfo(@PathVariable Long roleId) public AjaxResult getInfo(@PathVariable Long roleId)
{ {
roleService.checkRoleDataScope(roleId); roleService.checkRoleDataScope(roleId);
return AjaxResult.success(roleService.selectRoleById(roleId)); return success(roleService.selectRoleById(roleId));
} }
/** /**
@@ -91,11 +96,11 @@ public class SysRoleController extends BaseController
{ {
if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
{ {
return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
} }
else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role)))
{ {
return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
} }
role.setCreateBy(getUsername()); role.setCreateBy(getUsername());
return toAjax(roleService.insertRole(role)); return toAjax(roleService.insertRole(role));
@@ -114,11 +119,11 @@ public class SysRoleController extends BaseController
roleService.checkRoleDataScope(role.getRoleId()); roleService.checkRoleDataScope(role.getRoleId());
if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
{ {
return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
} }
else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role)))
{ {
return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
} }
role.setUpdateBy(getUsername()); role.setUpdateBy(getUsername());
@@ -132,9 +137,9 @@ public class SysRoleController extends BaseController
loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName())); loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
tokenService.setLoginUser(loginUser); tokenService.setLoginUser(loginUser);
} }
return AjaxResult.success(); return success();
} }
return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
} }
/** /**
@@ -182,7 +187,7 @@ public class SysRoleController extends BaseController
@GetMapping("/optionselect") @GetMapping("/optionselect")
public AjaxResult optionselect() public AjaxResult optionselect()
{ {
return AjaxResult.success(roleService.selectRoleAll()); return success(roleService.selectRoleAll());
} }
/** /**
@@ -242,4 +247,17 @@ public class SysRoleController extends BaseController
roleService.checkRoleDataScope(roleId); roleService.checkRoleDataScope(roleId);
return toAjax(roleService.insertAuthUsers(roleId, userIds)); return toAjax(roleService.insertAuthUsers(roleId, userIds));
} }
/**
* 获取对应角色部门树列表
*/
@PreAuthorize("@ss.hasPermi('system:role:query')")
@GetMapping(value = "/deptTree/{roleId}")
public AjaxResult deptTree(@PathVariable("roleId") Long roleId)
{
AjaxResult ajax = AjaxResult.success();
ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
return ajax;
}
} }
@@ -20,6 +20,7 @@ import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
@@ -27,6 +28,7 @@ import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService; import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
@@ -46,6 +48,9 @@ public class SysUserController extends BaseController
@Autowired @Autowired
private ISysRoleService roleService; private ISysRoleService roleService;
@Autowired
private ISysDeptService deptService;
@Autowired @Autowired
private ISysPostService postService; private ISysPostService postService;
@@ -80,7 +85,7 @@ public class SysUserController extends BaseController
List<SysUser> userList = util.importExcel(file.getInputStream()); List<SysUser> userList = util.importExcel(file.getInputStream());
String operName = getUsername(); String operName = getUsername();
String message = userService.importUser(userList, updateSupport, operName); String message = userService.importUser(userList, updateSupport, operName);
return AjaxResult.success(message); return success(message);
} }
@PostMapping("/importTemplate") @PostMapping("/importTemplate")
@@ -120,19 +125,19 @@ public class SysUserController extends BaseController
@PostMapping @PostMapping
public AjaxResult add(@Validated @RequestBody SysUser user) public AjaxResult add(@Validated @RequestBody SysUser user)
{ {
if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName()))) if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user)))
{ {
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
} }
else if (StringUtils.isNotEmpty(user.getPhonenumber()) else if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{ {
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
} }
else if (StringUtils.isNotEmpty(user.getEmail()) else if (StringUtils.isNotEmpty(user.getEmail())
&& UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
{ {
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
} }
user.setCreateBy(getUsername()); user.setCreateBy(getUsername());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
@@ -149,15 +154,19 @@ public class SysUserController extends BaseController
{ {
userService.checkUserAllowed(user); userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId()); userService.checkUserDataScope(user.getUserId());
if (StringUtils.isNotEmpty(user.getPhonenumber()) if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user)))
{
return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{ {
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
} }
else if (StringUtils.isNotEmpty(user.getEmail()) else if (StringUtils.isNotEmpty(user.getEmail())
&& UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
{ {
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
} }
user.setUpdateBy(getUsername()); user.setUpdateBy(getUsername());
return toAjax(userService.updateUser(user)); return toAjax(userService.updateUser(user));
@@ -234,4 +243,14 @@ public class SysUserController extends BaseController
userService.insertUserAuth(userId, roleIds); userService.insertUserAuth(userId, roleIds);
return success(); return success();
} }
/**
* 获取部门树列表
*/
@PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/deptTree")
public AjaxResult deptTree(SysDept dept)
{
return success(deptService.selectDeptTreeList(dept));
}
} }
@@ -1,24 +0,0 @@
package com.ruoyi.web.controller.tool;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.core.controller.BaseController;
/**
* swagger 接口
*
* @author ruoyi
*/
@Controller
@RequestMapping("/tool/swagger")
public class SwaggerController extends BaseController
{
@PreAuthorize("@ss.hasPermi('tool:swagger:view')")
@GetMapping()
public String index()
{
return redirect("/swagger-ui.html");
}
}
+10 -2
View File
@@ -3,9 +3,9 @@ ruoyi:
# 名称 # 名称
name: RuoYi name: RuoYi
# 版本 # 版本
version: 3.8.3 version: 3.8.5
# 版权年份 # 版权年份
copyrightYear: 2022 copyrightYear: 2023
# 实例演示开关 # 实例演示开关
demoEnabled: true demoEnabled: true
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath # 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
@@ -39,6 +39,14 @@ logging:
com.ruoyi: debug com.ruoyi: debug
org.springframework: warn org.springframework: warn
# 用户配置
user:
password:
# 密码最大错误次数
maxRetryCount: 5
# 密码锁定时间(默认10分钟)
lockTime: 10
# Spring配置 # Spring配置
spring: spring:
# 资源信息 # 资源信息
@@ -5,7 +5,7 @@ user.jcaptcha.expire=验证码已失效
user.not.exists=用户不存在/密码错误 user.not.exists=用户不存在/密码错误
user.password.not.match=用户不存在/密码错误 user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=密码输入错误{0}次 user.password.retry.limit.count=密码输入错误{0}次
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定10分钟 user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
user.password.delete=对不起,您的账号已被删除 user.password.delete=对不起,您的账号已被删除
user.blocked=用户已封禁,请联系管理员 user.blocked=用户已封禁,请联系管理员
role.blocked=角色已封禁,请联系管理员 role.blocked=角色已封禁,请联系管理员
+8 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.8.3</version> <version>3.8.5</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -58,6 +58,13 @@
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
</dependency> </dependency>
<!-- 动态数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 阿里JSON解析器 --> <!-- 阿里JSON解析器 -->
<dependency> <dependency>
@@ -25,4 +25,9 @@ public @interface DataScope
* 用户表的别名 * 用户表的别名
*/ */
public String userAlias() default ""; public String userAlias() default "";
/**
* 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来
*/
public String permission() default "";
} }
@@ -88,6 +88,11 @@ public @interface Excel
*/ */
public String[] combo() default {}; public String[] combo() default {};
/**
* 是否需要纵向合并单元格,应对需求:含有list集合单元格)
*/
public boolean needMerge() default false;
/** /**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
*/ */
@@ -104,12 +109,27 @@ public @interface Excel
public boolean isStatistics() default false; public boolean isStatistics() default false;
/** /**
* 导出类型(0数字 1字符串) * 导出类型(0数字 1字符串 2图片
*/ */
public ColumnType cellType() default ColumnType.STRING; public ColumnType cellType() default ColumnType.STRING;
/** /**
* 导出字体颜 * 导出列头背景
*/
public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
/**
* 导出列头字体颜色
*/
public IndexedColors headerColor() default IndexedColors.WHITE;
/**
* 导出单元格背景色
*/
public IndexedColors backgroundColor() default IndexedColors.WHITE;
/**
* 导出单元格字体颜色
*/ */
public IndexedColors color() default IndexedColors.BLACK; public IndexedColors color() default IndexedColors.BLACK;
@@ -128,22 +148,6 @@ public @interface Excel
*/ */
public String[] args() default {}; public String[] args() default {};
public enum Align
{
AUTO(0), LEFT(1), CENTER(2), RIGHT(3);
private final int value;
Align(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
/** /**
* 字段类型(0:导出导入;1:仅导出;2:仅导入) * 字段类型(0:导出导入;1:仅导出;2:仅导入)
*/ */
@@ -36,4 +36,9 @@ public class CacheConstants
* 限流 redis key * 限流 redis key
*/ */
public static final String RATE_LIMIT_KEY = "rate_limit:"; public static final String RATE_LIMIT_KEY = "rate_limit:";
/**
* 登录账户密码错误次数 redis key
*/
public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
} }
@@ -19,6 +19,11 @@ public class Constants
*/ */
public static final String GBK = "GBK"; public static final String GBK = "GBK";
/**
* www主域
*/
public static final String WWW = "www.";
/** /**
* http请求 * http请求
*/ */
@@ -133,5 +138,5 @@ public class Constants
* 定时任务违规的字符 * 定时任务违规的字符
*/ */
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "com.ruoyi.common.utils.file" }; "org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config" };
} }
@@ -86,4 +86,9 @@ public class HttpStatus
* 接口未实现 * 接口未实现
*/ */
public static final int NOT_IMPLEMENTED = 501; public static final int NOT_IMPLEMENTED = 501;
/**
* 系统警告消息
*/
public static final int WARN = 601;
} }
@@ -113,6 +113,14 @@ public class BaseController
{ {
return AjaxResult.success(message); return AjaxResult.success(message);
} }
/**
* 返回成功消息
*/
public AjaxResult success(Object data)
{
return AjaxResult.success(data);
}
/** /**
* 返回失败消息 * 返回失败消息
@@ -122,6 +130,14 @@ public class BaseController
return AjaxResult.error(message); return AjaxResult.error(message);
} }
/**
* 返回警告消息
*/
public AjaxResult warn(String message)
{
return AjaxResult.warn(message);
}
/** /**
* 响应返回结果 * 响应返回结果
* *
@@ -101,10 +101,33 @@ public class AjaxResult extends HashMap<String, Object>
return new AjaxResult(HttpStatus.SUCCESS, msg, data); return new AjaxResult(HttpStatus.SUCCESS, msg, data);
} }
/**
* 返回警告消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static AjaxResult warn(String msg)
{
return AjaxResult.warn(msg, null);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static AjaxResult warn(String msg, Object data)
{
return new AjaxResult(HttpStatus.WARN, msg, data);
}
/** /**
* 返回错误消息 * 返回错误消息
* *
* @return * @return 错误消息
*/ */
public static AjaxResult error() public static AjaxResult error()
{ {
@@ -115,7 +138,7 @@ public class AjaxResult extends HashMap<String, Object>
* 返回错误消息 * 返回错误消息
* *
* @param msg 返回内容 * @param msg 返回内容
* @return 警告消息 * @return 错误消息
*/ */
public static AjaxResult error(String msg) public static AjaxResult error(String msg)
{ {
@@ -127,7 +150,7 @@ public class AjaxResult extends HashMap<String, Object>
* *
* @param msg 返回内容 * @param msg 返回内容
* @param data 数据对象 * @param data 数据对象
* @return 警告消息 * @return 错误消息
*/ */
public static AjaxResult error(String msg, Object data) public static AjaxResult error(String msg, Object data)
{ {
@@ -139,7 +162,7 @@ public class AjaxResult extends HashMap<String, Object>
* *
* @param code 状态码 * @param code 状态码
* @param msg 返回内容 * @param msg 返回内容
* @return 警告消息 * @return 错误消息
*/ */
public static AjaxResult error(int code, String msg) public static AjaxResult error(int code, String msg)
{ {
@@ -5,6 +5,8 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
/** /**
* Entity基类 * Entity基类
@@ -16,6 +18,7 @@ public class BaseEntity implements Serializable
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 搜索值 */ /** 搜索值 */
@JsonIgnore
private String searchValue; private String searchValue;
/** 创建者 */ /** 创建者 */
@@ -36,6 +39,7 @@ public class BaseEntity implements Serializable
private String remark; private String remark;
/** 请求参数 */ /** 请求参数 */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> params; private Map<String, Object> params;
public String getSearchValue() public String getSearchValue()
@@ -102,4 +102,14 @@ public class R<T> implements Serializable
{ {
this.data = data; this.data = data;
} }
public static <T> Boolean isError(R<T> ret)
{
return !isSuccess(ret);
}
public static <T> Boolean isSuccess(R<T> ret)
{
return R.SUCCESS == ret.getCode();
}
} }
@@ -131,7 +131,7 @@ public class SysDictData extends BaseEntity
public boolean getDefault() public boolean getDefault()
{ {
return UserConstants.YES.equals(this.isDefault) ? true : false; return UserConstants.YES.equals(this.isDefault);
} }
public String getIsDefault() public String getIsDefault()
@@ -54,7 +54,7 @@ public class SysMenu extends BaseEntity
/** 显示状态(0显示 1隐藏) */ /** 显示状态(0显示 1隐藏) */
private String visible; private String visible;
/** 菜单状态(0显示 1隐藏 */ /** 菜单状态(0正常 1停用 */
private String status; private String status;
/** 权限字符串 */ /** 权限字符串 */
@@ -1,6 +1,8 @@
package com.ruoyi.common.core.domain.entity; package com.ruoyi.common.core.domain.entity;
import java.util.Set;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@@ -31,7 +33,7 @@ public class SysRole extends BaseEntity
/** 角色排序 */ /** 角色排序 */
@Excel(name = "角色排序") @Excel(name = "角色排序")
private String roleSort; private Integer roleSort;
/** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */ /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
@Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限") @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
@@ -59,6 +61,9 @@ public class SysRole extends BaseEntity
/** 部门组(数据权限) */ /** 部门组(数据权限) */
private Long[] deptIds; private Long[] deptIds;
/** 角色菜单权限 */
private Set<String> permissions;
public SysRole() public SysRole()
{ {
@@ -113,13 +118,13 @@ public class SysRole extends BaseEntity
this.roleKey = roleKey; this.roleKey = roleKey;
} }
@NotBlank(message = "显示顺序不能为空") @NotNull(message = "显示顺序不能为空")
public String getRoleSort() public Integer getRoleSort()
{ {
return roleSort; return roleSort;
} }
public void setRoleSort(String roleSort) public void setRoleSort(Integer roleSort)
{ {
this.roleSort = roleSort; this.roleSort = roleSort;
} }
@@ -203,7 +208,17 @@ public class SysRole extends BaseEntity
{ {
this.deptIds = deptIds; this.deptIds = deptIds;
} }
public Set<String> getPermissions()
{
return permissions;
}
public void setPermissions(Set<String> permissions)
{
this.permissions = permissions;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@@ -74,6 +74,28 @@ public class RedisCache
return redisTemplate.expire(key, timeout, unit); return redisTemplate.expire(key, timeout, unit);
} }
/**
* 获取有效时间
*
* @param key Redis键
* @return 有效时间
*/
public long getExpire(final String key)
{
return redisTemplate.getExpire(key);
}
/**
* 判断 key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public Boolean hasKey(String key)
{
return redisTemplate.hasKey(key);
}
/** /**
* 获得缓存的基本对象。 * 获得缓存的基本对象。
* *
@@ -102,9 +124,9 @@ public class RedisCache
* @param collection 多个对象 * @param collection 多个对象
* @return * @return
*/ */
public long deleteObject(final Collection collection) public boolean deleteObject(final Collection collection)
{ {
return redisTemplate.delete(collection); return redisTemplate.delete(collection) > 0;
} }
/** /**
@@ -209,18 +231,6 @@ public class RedisCache
return opsForHash.get(key, hKey); return opsForHash.get(key, hKey);
} }
/**
* 删除Hash中的数据
*
* @param key
* @param hKey
*/
public void delCacheMapValue(final String key, final String hKey)
{
HashOperations hashOperations = redisTemplate.opsForHash();
hashOperations.delete(key, hKey);
}
/** /**
* 获取多个Hash中的数据 * 获取多个Hash中的数据
* *
@@ -233,6 +243,18 @@ public class RedisCache
return redisTemplate.opsForHash().multiGet(key, hKeys); return redisTemplate.opsForHash().multiGet(key, hKeys);
} }
/**
* 删除Hash中的某条数据
*
* @param key Redis键
* @param hKey Hash键
* @return 是否成功
*/
public boolean deleteCacheMapValue(final String key, final String hKey)
{
return redisTemplate.opsForHash().delete(key, hKey) > 0;
}
/** /**
* 获得缓存的基本对象列表 * 获得缓存的基本对象列表
* *
@@ -713,7 +713,7 @@ public class Convert
} }
if (value instanceof Double) if (value instanceof Double)
{ {
return new BigDecimal((Double) value); return BigDecimal.valueOf((Double) value);
} }
if (value instanceof Integer) if (value instanceof Integer)
{ {
@@ -894,7 +894,7 @@ public class Convert
*/ */
public static String toSBC(String input, Set<Character> notConvertSet) public static String toSBC(String input, Set<Character> notConvertSet)
{ {
char c[] = input.toCharArray(); char[] c = input.toCharArray();
for (int i = 0; i < c.length; i++) for (int i = 0; i < c.length; i++)
{ {
if (null != notConvertSet && notConvertSet.contains(c[i])) if (null != notConvertSet && notConvertSet.contains(c[i]))
@@ -936,7 +936,7 @@ public class Convert
*/ */
public static String toDBC(String text, Set<Character> notConvertSet) public static String toDBC(String text, Set<Character> notConvertSet)
{ {
char c[] = text.toCharArray(); char[] c = text.toCharArray();
for (int i = 0; i < c.length; i++) for (int i = 0; i < c.length; i++)
{ {
if (null != notConvertSet && notConvertSet.contains(c[i])) if (null != notConvertSet && notConvertSet.contains(c[i]))
@@ -7,7 +7,6 @@ package com.ruoyi.common.exception;
*/ */
public class GlobalException extends RuntimeException public class GlobalException extends RuntimeException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
@@ -45,6 +44,7 @@ public class GlobalException extends RuntimeException
return this; return this;
} }
@Override
public String getMessage() public String getMessage()
{ {
return message; return message;
@@ -49,6 +49,7 @@ public final class ServiceException extends RuntimeException
return detailMessage; return detailMessage;
} }
@Override
public String getMessage() public String getMessage()
{ {
return message; return message;
@@ -0,0 +1,16 @@
package com.ruoyi.common.exception.user;
/**
* 用户错误最大次数异常类
*
* @author ruoyi
*/
public class UserPasswordRetryLimitExceedException extends UserException
{
private static final long serialVersionUID = 1L;
public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime)
{
super("user.password.retry.limit.exceed", new Object[] { retryLimitCount, lockTime });
}
}
@@ -0,0 +1,24 @@
package com.ruoyi.common.filter;
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
/**
* 排除JSON敏感属性
*
* @author ruoyi
*/
public class PropertyPreExcludeFilter extends SimplePropertyPreFilter
{
public PropertyPreExcludeFilter()
{
}
public PropertyPreExcludeFilter addExcludes(String... filters)
{
for (int i = 0; i < filters.length; i++)
{
this.getExcludes().add(filters[i]);
}
return this;
}
}
@@ -10,6 +10,7 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletRequestWrapper;
import com.ruoyi.common.utils.http.HttpHelper; import com.ruoyi.common.utils.http.HttpHelper;
import com.ruoyi.common.constant.Constants;
/** /**
* 构建可重复读取inputStream的request * 构建可重复读取inputStream的request
@@ -23,10 +24,10 @@ public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException
{ {
super(request); super(request);
request.setCharacterEncoding("UTF-8"); request.setCharacterEncoding(Constants.UTF8);
response.setCharacterEncoding("UTF-8"); response.setCharacterEncoding(Constants.UTF8);
body = HttpHelper.getBodyString(request).getBytes("UTF-8"); body = HttpHelper.getBodyString(request).getBytes(Constants.UTF8);
} }
@Override @Override
@@ -12,6 +12,7 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.enums.HttpMethod;
/** /**
* 防止XSS攻击的过滤器 * 防止XSS攻击的过滤器
@@ -59,7 +60,7 @@ public class XssFilter implements Filter
String url = request.getServletPath(); String url = request.getServletPath();
String method = request.getMethod(); String method = request.getMethod();
// GET DELETE 不过滤 // GET DELETE 不过滤
if (method == null || method.matches("GET") || method.matches("DELETE")) if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method))
{ {
return true; return true;
} }
@@ -34,13 +34,13 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
if (values != null) if (values != null)
{ {
int length = values.length; int length = values.length;
String[] escapseValues = new String[length]; String[] escapesValues = new String[length];
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
{ {
// 防xss攻击和过滤前后空格 // 防xss攻击和过滤前后空格
escapseValues[i] = EscapeUtil.clean(values[i]).trim(); escapesValues[i] = EscapeUtil.clean(values[i]).trim();
} }
return escapseValues; return escapesValues;
} }
return super.getParameterValues(name); return super.getParameterValues(name);
} }
@@ -4,6 +4,10 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
@@ -68,6 +72,34 @@ public class ServletUtils
return Convert.toBool(getRequest().getParameter(name), defaultValue); return Convert.toBool(getRequest().getParameter(name), defaultValue);
} }
/**
* 获得所有请求参数
*
* @param request 请求对象{@link ServletRequest}
* @return Map
*/
public static Map<String, String[]> getParams(ServletRequest request)
{
final Map<String, String[]> map = request.getParameterMap();
return Collections.unmodifiableMap(map);
}
/**
* 获得所有请求参数
*
* @param request 请求对象{@link ServletRequest}
* @return Map
*/
public static Map<String, String> getParamMap(ServletRequest request)
{
Map<String, String> params = new HashMap<>();
for (Map.Entry<String, String[]> entry : getParams(request).entrySet())
{
params.put(entry.getKey(), StringUtils.join(entry.getValue(), ","));
}
return params;
}
/** /**
* 获取request * 获取request
*/ */
@@ -324,6 +324,32 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
return list; return list;
} }
/**
* 判断给定的set列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
*
* @param set 给定的集合
* @param array 给定的数组
* @return boolean 结果
*/
public static boolean containsAny(Collection<String> collection, String... array)
{
if (isEmpty(collection) || isEmpty(array))
{
return false;
}
else
{
for (String str : array)
{
if (collection.contains(str))
{
return true;
}
}
return false;
}
}
/** /**
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写 * 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
* *
@@ -116,8 +116,7 @@ public class FileUtils
// 路径为文件且不为空则进行删除 // 路径为文件且不为空则进行删除
if (file.isFile() && file.exists()) if (file.isFile() && file.exists())
{ {
file.delete(); flag = file.delete();
flag = true;
} }
return flag; return flag;
} }
@@ -289,5 +288,4 @@ public class FileUtils
String baseName = FilenameUtils.getBaseName(fileName); String baseName = FilenameUtils.getBaseName(fileName);
return baseName; return baseName;
} }
} }
@@ -387,7 +387,7 @@ public final class HTMLFilter
{ {
paramValue = processParamProtocol(paramValue); paramValue = processParamProtocol(paramValue);
} }
params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\""); params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\\\"");
} }
} }
@@ -7,12 +7,14 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@@ -22,7 +24,9 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.RegExUtils; import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor; import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPicture; import org.apache.poi.hssf.usermodel.HSSFPicture;
import org.apache.poi.hssf.usermodel.HSSFPictureData; import org.apache.poi.hssf.usermodel.HSSFPictureData;
@@ -44,6 +48,7 @@ import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.PictureData; import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
@@ -148,6 +153,26 @@ public class ExcelUtil<T>
*/ */
private short maxHeight; private short maxHeight;
/**
* 合并后最后行数
*/
private int subMergedLastRowNum = 0;
/**
* 合并后开始行数
*/
private int subMergedFirstRowNum = 1;
/**
* 对象的子列表方法
*/
private Method subMethod;
/**
* 对象的子列表属性
*/
private List<Field> subFields;
/** /**
* 统计列表 * 统计列表
*/ */
@@ -163,11 +188,27 @@ public class ExcelUtil<T>
*/ */
public Class<T> clazz; public Class<T> clazz;
/**
* 需要排除列属性
*/
public String[] excludeFields;
public ExcelUtil(Class<T> clazz) public ExcelUtil(Class<T> clazz)
{ {
this.clazz = clazz; this.clazz = clazz;
} }
/**
* 隐藏Excel中列属性
*
* @param fields 列属性名 示例[单个"name"/多个"id","name"]
* @throws Exception
*/
public void hideColumn(String... fields)
{
this.excludeFields = fields;
}
public void init(List<T> list, String sheetName, String title, Type type) public void init(List<T> list, String sheetName, String title, Type type)
{ {
if (list == null) if (list == null)
@@ -181,6 +222,7 @@ public class ExcelUtil<T>
createExcelField(); createExcelField();
createWorkbook(); createWorkbook();
createTitle(); createTitle();
createSubHead();
} }
/** /**
@@ -190,13 +232,48 @@ public class ExcelUtil<T>
{ {
if (StringUtils.isNotEmpty(title)) if (StringUtils.isNotEmpty(title))
{ {
subMergedFirstRowNum++;
subMergedLastRowNum++;
int titleLastCol = this.fields.size() - 1;
if (isSubList())
{
titleLastCol = titleLastCol + subFields.size() - 1;
}
Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0); Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0);
titleRow.setHeightInPoints(30); titleRow.setHeightInPoints(30);
Cell titleCell = titleRow.createCell(0); Cell titleCell = titleRow.createCell(0);
titleCell.setCellStyle(styles.get("title")); titleCell.setCellStyle(styles.get("title"));
titleCell.setCellValue(title); titleCell.setCellValue(title);
sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol));
this.fields.size() - 1)); }
}
/**
* 创建对象的子列表名称
*/
public void createSubHead()
{
if (isSubList())
{
subMergedFirstRowNum++;
subMergedLastRowNum++;
Row subRow = sheet.createRow(rownum);
int excelNum = 0;
for (Object[] objects : fields)
{
Excel attr = (Excel) objects[1];
Cell headCell1 = subRow.createCell(excelNum);
headCell1.setCellValue(attr.name());
headCell1.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
excelNum++;
}
int headFirstRow = excelNum - 1;
int headLastRow = headFirstRow + subFields.size() - 1;
if (headLastRow > headFirstRow)
{
sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, headFirstRow, headLastRow));
}
rownum++;
} }
} }
@@ -576,8 +653,20 @@ public class ExcelUtil<T>
// 写入各个字段的列头名称 // 写入各个字段的列头名称
for (Object[] os : fields) for (Object[] os : fields)
{ {
Field field = (Field) os[0];
Excel excel = (Excel) os[1]; Excel excel = (Excel) os[1];
this.createCell(excel, row, column++); if (Collection.class.isAssignableFrom(field.getType()))
{
for (Field subField : subFields)
{
Excel subExcel = subField.getAnnotation(Excel.class);
this.createHeadCell(subExcel, row, column++);
}
}
else
{
this.createHeadCell(excel, row, column++);
}
} }
if (Type.EXPORT.equals(type)) if (Type.EXPORT.equals(type))
{ {
@@ -593,21 +682,67 @@ public class ExcelUtil<T>
* @param index 序号 * @param index 序号
* @param row 单元格行 * @param row 单元格行
*/ */
@SuppressWarnings("unchecked")
public void fillExcelData(int index, Row row) public void fillExcelData(int index, Row row)
{ {
int startNo = index * sheetSize; int startNo = index * sheetSize;
int endNo = Math.min(startNo + sheetSize, list.size()); int endNo = Math.min(startNo + sheetSize, list.size());
int rowNo = (1 + rownum) - startNo;
for (int i = startNo; i < endNo; i++) for (int i = startNo; i < endNo; i++)
{ {
row = sheet.createRow(i + 1 + rownum - startNo); rowNo = isSubList() ? (i > 1 ? rowNo + 1 : rowNo + i) : i + 1 + rownum - startNo;
row = sheet.createRow(rowNo);
// 得到导出对象. // 得到导出对象.
T vo = (T) list.get(i); T vo = (T) list.get(i);
Collection<?> subList = null;
if (isSubList())
{
if (isSubListValue(vo))
{
subList = getListCellValue(vo);
subMergedLastRowNum = subMergedLastRowNum + subList.size();
}
else
{
subMergedFirstRowNum++;
subMergedLastRowNum++;
}
}
int column = 0; int column = 0;
for (Object[] os : fields) for (Object[] os : fields)
{ {
Field field = (Field) os[0]; Field field = (Field) os[0];
Excel excel = (Excel) os[1]; Excel excel = (Excel) os[1];
this.addCell(excel, row, vo, field, column++); if (Collection.class.isAssignableFrom(field.getType()) && StringUtils.isNotNull(subList))
{
boolean subFirst = false;
for (Object obj : subList)
{
if (subFirst)
{
rowNo++;
row = sheet.createRow(rowNo);
}
List<Field> subFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Excel.class);
int subIndex = 0;
for (Field subField : subFields)
{
if (subField.isAnnotationPresent(Excel.class))
{
subField.setAccessible(true);
Excel attr = subField.getAnnotation(Excel.class);
this.addCell(attr, row, (T) obj, subField, column + subIndex);
}
subIndex++;
}
subFirst = true;
}
this.subMergedFirstRowNum = this.subMergedFirstRowNum + subList.size();
}
else
{
this.addCell(excel, row, vo, field, column++);
}
} }
} }
} }
@@ -649,20 +784,6 @@ public class ExcelUtil<T>
style.setFont(dataFont); style.setFont(dataFont);
styles.put("data", style); styles.put("data", style);
style = wb.createCellStyle();
style.cloneStyleFrom(styles.get("data"));
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
Font headerFont = wb.createFont();
headerFont.setFontName("Arial");
headerFont.setFontHeightInPoints((short) 10);
headerFont.setBold(true);
headerFont.setColor(IndexedColors.WHITE.getIndex());
style.setFont(headerFont);
styles.put("header", style);
style = wb.createCellStyle(); style = wb.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER); style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER);
@@ -672,28 +793,62 @@ public class ExcelUtil<T>
style.setFont(totalFont); style.setFont(totalFont);
styles.put("total", style); styles.put("total", style);
styles.putAll(annotationStyles(wb)); styles.putAll(annotationHeaderStyles(wb, styles));
styles.putAll(annotationDataStyles(wb));
return styles; return styles;
} }
/** /**
* 根据Excel注解创建表格样式 * 根据Excel注解创建表格样式
* *
* @param wb 工作薄对象 * @param wb 工作薄对象
* @return 自定义样式列表 * @return 自定义样式列表
*/ */
private Map<String, CellStyle> annotationStyles(Workbook wb) private Map<String, CellStyle> annotationHeaderStyles(Workbook wb, Map<String, CellStyle> styles)
{
Map<String, CellStyle> headerStyles = new HashMap<String, CellStyle>();
for (Object[] os : fields)
{
Excel excel = (Excel) os[1];
String key = StringUtils.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor());
if (!headerStyles.containsKey(key))
{
CellStyle style = wb.createCellStyle();
style.cloneStyleFrom(styles.get("data"));
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setFillForegroundColor(excel.headerBackgroundColor().index);
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
Font headerFont = wb.createFont();
headerFont.setFontName("Arial");
headerFont.setFontHeightInPoints((short) 10);
headerFont.setBold(true);
headerFont.setColor(excel.headerColor().index);
style.setFont(headerFont);
headerStyles.put(key, style);
}
}
return headerStyles;
}
/**
* 根据Excel注解创建表格列样式
*
* @param wb 工作薄对象
* @return 自定义样式列表
*/
private Map<String, CellStyle> annotationDataStyles(Workbook wb)
{ {
Map<String, CellStyle> styles = new HashMap<String, CellStyle>(); Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
for (Object[] os : fields) for (Object[] os : fields)
{ {
Excel excel = (Excel) os[1]; Excel excel = (Excel) os[1];
String key = "data_" + excel.align() + "_" + excel.color(); String key = StringUtils.format("data_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor());
if (!styles.containsKey(key)) if (!styles.containsKey(key))
{ {
CellStyle style = wb.createCellStyle(); CellStyle style = wb.createCellStyle();
style = wb.createCellStyle();
style.setAlignment(excel.align()); style.setAlignment(excel.align());
style.setVerticalAlignment(VerticalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderRight(BorderStyle.THIN); style.setBorderRight(BorderStyle.THIN);
@@ -704,6 +859,8 @@ public class ExcelUtil<T>
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderBottom(BorderStyle.THIN); style.setBorderBottom(BorderStyle.THIN);
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillForegroundColor(excel.backgroundColor().getIndex());
Font dataFont = wb.createFont(); Font dataFont = wb.createFont();
dataFont.setFontName("Arial"); dataFont.setFontName("Arial");
dataFont.setFontHeightInPoints((short) 10); dataFont.setFontHeightInPoints((short) 10);
@@ -718,14 +875,23 @@ public class ExcelUtil<T>
/** /**
* 创建单元格 * 创建单元格
*/ */
public Cell createCell(Excel attr, Row row, int column) public Cell createHeadCell(Excel attr, Row row, int column)
{ {
// 创建列 // 创建列
Cell cell = row.createCell(column); Cell cell = row.createCell(column);
// 写入列信息 // 写入列信息
cell.setCellValue(attr.name()); cell.setCellValue(attr.name());
setDataValidation(attr, row, column); setDataValidation(attr, row, column);
cell.setCellStyle(styles.get("header")); cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
if (isSubList())
{
// 填充默认样式,防止合并单元格样式失效
sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor())));
if (attr.needMerge())
{
sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column));
}
}
return cell; return cell;
} }
@@ -746,6 +912,10 @@ public class ExcelUtil<T>
{ {
cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0"); cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0");
} }
if (value instanceof Collection && StringUtils.equals("[]", cellValue))
{
cellValue = StringUtils.EMPTY;
}
cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix()); cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix());
} }
else if (ColumnType.NUMERIC == attr.cellType()) else if (ColumnType.NUMERIC == attr.cellType())
@@ -813,8 +983,16 @@ public class ExcelUtil<T>
} }
if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0) if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0)
{ {
// 提示信息或只能选择不能输入的列内容. if (attr.combo().length > 15 || StringUtils.join(attr.combo()).length() > 255)
setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); {
// 如果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,避免生成的模板下拉值获取不到
setXSSFValidationWithHidden(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);
}
else
{
// 提示信息或只能选择不能输入的列内容.
setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);
}
} }
} }
@@ -833,7 +1011,12 @@ public class ExcelUtil<T>
{ {
// 创建cell // 创建cell
cell = row.createCell(column); cell = row.createCell(column);
cell.setCellStyle(styles.get("data_" + attr.align() + "_" + attr.color())); if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge())
{
CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column);
sheet.addMergedRegion(cellAddress);
}
cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor())));
// 用于读取对象中的属性 // 用于读取对象中的属性
Object value = getTargetValue(vo, field, attr); Object value = getTargetValue(vo, field, attr);
@@ -855,7 +1038,7 @@ public class ExcelUtil<T>
} }
else if (value instanceof BigDecimal && -1 != attr.scale()) else if (value instanceof BigDecimal && -1 != attr.scale())
{ {
cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).toString()); cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue());
} }
else if (!attr.handler().equals(ExcelHandlerAdapter.class)) else if (!attr.handler().equals(ExcelHandlerAdapter.class))
{ {
@@ -913,6 +1096,58 @@ public class ExcelUtil<T>
sheet.addValidationData(dataValidation); sheet.addValidationData(dataValidation);
} }
/**
* 设置某些列的值只能输入预制的数据,显示下拉框(兼容超出一定数量的下拉框).
*
* @param sheet 要设置的sheet.
* @param textlist 下拉框显示的内容
* @param promptContent 提示内容
* @param firstRow 开始行
* @param endRow 结束行
* @param firstCol 开始列
* @param endCol 结束列
*/
public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol)
{
String hideSheetName = "combo_" + firstCol + "_" + endCol;
Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据
for (int i = 0; i < textlist.length; i++)
{
hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]);
}
// 创建名称,可被其他单元格引用
Name name = wb.createName();
name.setNameName(hideSheetName + "_data");
name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length);
DataValidationHelper helper = sheet.getDataValidationHelper();
// 加载下拉列表内容
DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data");
// 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
// 数据有效性对象
DataValidation dataValidation = helper.createValidation(constraint, regions);
if (StringUtils.isNotEmpty(promptContent))
{
// 如果设置了提示信息则鼠标放上去提示
dataValidation.createPromptBox("", promptContent);
dataValidation.setShowPromptBox(true);
}
// 处理Excel兼容性问题
if (dataValidation instanceof XSSFDataValidation)
{
dataValidation.setSuppressDropDownArrow(true);
dataValidation.setShowErrorBox(true);
}
else
{
dataValidation.setSuppressDropDownArrow(false);
}
sheet.addValidationData(dataValidation);
// 设置hiddenSheet隐藏
wb.setSheetHidden(wb.getSheetIndex(hideSheet), true);
}
/** /**
* 解析导出值 0=男,1=女,2=未知 * 解析导出值 0=男,1=女,2=未知
* *
@@ -928,7 +1163,7 @@ public class ExcelUtil<T>
for (String item : convertSource) for (String item : convertSource)
{ {
String[] itemArray = item.split("="); String[] itemArray = item.split("=");
if (StringUtils.containsAny(separator, propertyValue)) if (StringUtils.containsAny(propertyValue, separator))
{ {
for (String value : propertyValue.split(separator)) for (String value : propertyValue.split(separator))
{ {
@@ -965,7 +1200,7 @@ public class ExcelUtil<T>
for (String item : convertSource) for (String item : convertSource)
{ {
String[] itemArray = item.split("="); String[] itemArray = item.split("=");
if (StringUtils.containsAny(separator, propertyValue)) if (StringUtils.containsAny(propertyValue, separator))
{ {
for (String value : propertyValue.split(separator)) for (String value : propertyValue.split(separator))
{ {
@@ -1178,29 +1413,39 @@ public class ExcelUtil<T>
tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
for (Field field : tempFields) for (Field field : tempFields)
{ {
// 单注解 if (!ArrayUtils.contains(this.excludeFields, field.getName()))
if (field.isAnnotationPresent(Excel.class))
{ {
Excel attr = field.getAnnotation(Excel.class); // 单注解
if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) if (field.isAnnotationPresent(Excel.class))
{
field.setAccessible(true);
fields.add(new Object[] { field, attr });
}
}
// 多注解
if (field.isAnnotationPresent(Excels.class))
{
Excels attrs = field.getAnnotation(Excels.class);
Excel[] excels = attrs.value();
for (Excel attr : excels)
{ {
Excel attr = field.getAnnotation(Excel.class);
if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
{ {
field.setAccessible(true); field.setAccessible(true);
fields.add(new Object[] { field, attr }); fields.add(new Object[] { field, attr });
} }
if (Collection.class.isAssignableFrom(field.getType()))
{
subMethod = getSubMethod(field.getName(), clazz);
ParameterizedType pt = (ParameterizedType) field.getGenericType();
Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class);
}
}
// 多注解
if (field.isAnnotationPresent(Excels.class))
{
Excels attrs = field.getAnnotation(Excels.class);
Excel[] excels = attrs.value();
for (Excel attr : excels)
{
if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
{
field.setAccessible(true);
fields.add(new Object[] { field, attr });
}
}
} }
} }
} }
@@ -1429,4 +1674,61 @@ public class ExcelUtil<T>
} }
return str; return str;
} }
/**
* 是否有对象的子列表
*/
public boolean isSubList()
{
return StringUtils.isNotNull(subFields) && subFields.size() > 0;
}
/**
* 是否有对象的子列表,集合不为空
*/
public boolean isSubListValue(T vo)
{
return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0;
}
/**
* 获取集合的值
*/
public Collection<?> getListCellValue(Object obj)
{
Object value;
try
{
value = subMethod.invoke(obj, new Object[] {});
}
catch (Exception e)
{
return new ArrayList<Object>();
}
return (Collection<?>) value;
}
/**
* 获取对象的子列表方法
*
* @param name 名称
* @param pojoClass 类对象
* @return 子列表方法
*/
public Method getSubMethod(String name, Class<?> pojoClass)
{
StringBuffer getMethodName = new StringBuffer("get");
getMethodName.append(name.substring(0, 1).toUpperCase());
getMethodName.append(name.substring(1));
Method method = null;
try
{
method = pojoClass.getMethod(getMethodName.toString(), new Class[] {});
}
catch (Exception e)
{
log.error("获取对象异常{}", e.getMessage());
}
return method;
}
} }
@@ -13,7 +13,7 @@ public class SqlUtil
/** /**
* 定义常用的 sql关键字 * 定义常用的 sql关键字
*/ */
public static String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare "; public static String SQL_REGEX = "and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |+|user()";
/** /**
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序) * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
+2 -2
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.8.3</version> <version>3.8.5</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -37,7 +37,7 @@
<!-- 验证码 --> <!-- 验证码 -->
<dependency> <dependency>
<groupId>com.github.penggle</groupId> <groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId> <artifactId>kaptcha</artifactId>
<exclusions> <exclusions>
<exclusion> <exclusion>
@@ -1,5 +1,7 @@
package com.ruoyi.framework.aspectj; package com.ruoyi.framework.aspectj;
import java.util.ArrayList;
import java.util.List;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Before;
@@ -9,8 +11,10 @@ import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.security.context.PermissionContextHolder;
/** /**
* 数据过滤处理 * 数据过滤处理
@@ -68,8 +72,9 @@ public class DataScopeAspect
// 如果是超级管理员,则不过滤数据 // 如果是超级管理员,则不过滤数据
if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin())
{ {
String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext());
dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
controllerDataScope.userAlias()); controllerDataScope.userAlias(), permission);
} }
} }
} }
@@ -79,15 +84,27 @@ public class DataScopeAspect
* *
* @param joinPoint 切点 * @param joinPoint 切点
* @param user 用户 * @param user 用户
* @param userAlias 别名 * @param deptAlias 部门别名
* @param userAlias 用户别名
* @param permission 权限字符
*/ */
public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias) public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission)
{ {
StringBuilder sqlString = new StringBuilder(); StringBuilder sqlString = new StringBuilder();
List<String> conditions = new ArrayList<String>();
for (SysRole role : user.getRoles()) for (SysRole role : user.getRoles())
{ {
String dataScope = role.getDataScope(); String dataScope = role.getDataScope();
if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope))
{
continue;
}
if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions())
&& !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
{
continue;
}
if (DATA_SCOPE_ALL.equals(dataScope)) if (DATA_SCOPE_ALL.equals(dataScope))
{ {
sqlString = new StringBuilder(); sqlString = new StringBuilder();
@@ -121,6 +138,7 @@ public class DataScopeAspect
sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
} }
} }
conditions.add(dataScope);
} }
if (StringUtils.isNotBlank(sqlString.toString())) if (StringUtils.isNotBlank(sqlString.toString()))
@@ -13,16 +13,16 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerMapping;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.BusinessStatus; import com.ruoyi.common.enums.BusinessStatus;
import com.ruoyi.common.enums.HttpMethod; import com.ruoyi.common.enums.HttpMethod;
import com.ruoyi.common.filter.PropertyPreExcludeFilter;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.manager.AsyncManager; import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory; import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.domain.SysOperLog; import com.ruoyi.system.domain.SysOperLog;
@@ -38,6 +38,9 @@ public class LogAspect
{ {
private static final Logger log = LoggerFactory.getLogger(LogAspect.class); private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
/** 排除敏感属性字段 */
public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
/** /**
* 处理完请求后执行 * 处理完请求后执行
* *
@@ -74,7 +77,7 @@ public class LogAspect
// 请求的地址 // 请求的地址
String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
operLog.setOperIp(ip); operLog.setOperIp(ip);
operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
if (loginUser != null) if (loginUser != null)
{ {
operLog.setOperName(loginUser.getUsername()); operLog.setOperName(loginUser.getUsername());
@@ -99,7 +102,6 @@ public class LogAspect
catch (Exception exp) catch (Exception exp)
{ {
// 记录本地异常日志 // 记录本地异常日志
log.error("==前置通知异常==");
log.error("异常信息:{}", exp.getMessage()); log.error("异常信息:{}", exp.getMessage());
exp.printStackTrace(); exp.printStackTrace();
} }
@@ -149,8 +151,8 @@ public class LogAspect
} }
else else
{ {
Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000)); operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter()), 0, 2000));
} }
} }
@@ -168,7 +170,7 @@ public class LogAspect
{ {
try try
{ {
Object jsonObj = JSON.toJSON(o); String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter());
params += jsonObj.toString() + " "; params += jsonObj.toString() + " ";
} }
catch (Exception e) catch (Exception e)
@@ -180,6 +182,14 @@ public class LogAspect
return params.trim(); return params.trim();
} }
/**
* 忽略敏感属性
*/
public PropertyPreExcludeFilter excludePropertyPreFilter()
{
return new PropertyPreExcludeFilter().addExcludes(EXCLUDE_PROPERTIES);
}
/** /**
* 判断是否需要过滤的对象。 * 判断是否需要过滤的对象。
* *
@@ -50,7 +50,6 @@ public class RateLimiterAspect
@Before("@annotation(rateLimiter)") @Before("@annotation(rateLimiter)")
public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable
{ {
String key = rateLimiter.key();
int time = rateLimiter.time(); int time = rateLimiter.time();
int count = rateLimiter.count(); int count = rateLimiter.count();
@@ -63,7 +62,7 @@ public class RateLimiterAspect
{ {
throw new ServiceException("访问过于频繁,请稍候再试"); throw new ServiceException("访问过于频繁,请稍候再试");
} }
log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), key); log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), combineKey);
} }
catch (ServiceException e) catch (ServiceException e)
{ {
@@ -5,7 +5,7 @@ import com.google.code.kaptcha.text.impl.DefaultTextCreator;
/** /**
* 验证码文本生成器 * 验证码文本生成器
* *
* @author ruoyi * @author ruoyi
*/ */
public class KaptchaTextCreator extends DefaultTextCreator public class KaptchaTextCreator extends DefaultTextCreator
@@ -20,7 +20,7 @@ public class KaptchaTextCreator extends DefaultTextCreator
int x = random.nextInt(10); int x = random.nextInt(10);
int y = random.nextInt(10); int y = random.nextInt(10);
StringBuilder suChinese = new StringBuilder(); StringBuilder suChinese = new StringBuilder();
int randomoperands = (int) Math.round(Math.random() * 2); int randomoperands = random.nextInt(3);
if (randomoperands == 0) if (randomoperands == 0)
{ {
result = x * y; result = x * y;
@@ -30,7 +30,7 @@ public class KaptchaTextCreator extends DefaultTextCreator
} }
else if (randomoperands == 1) else if (randomoperands == 1)
{ {
if (!(x == 0) && y % x == 0) if ((x != 0) && y % x == 0)
{ {
result = y / x; result = y / x;
suChinese.append(CNUMBERS[y]); suChinese.append(CNUMBERS[y]);
@@ -45,7 +45,7 @@ public class KaptchaTextCreator extends DefaultTextCreator
suChinese.append(CNUMBERS[y]); suChinese.append(CNUMBERS[y]);
} }
} }
else if (randomoperands == 2) else
{ {
if (x >= y) if (x >= y)
{ {
@@ -62,13 +62,6 @@ public class KaptchaTextCreator extends DefaultTextCreator
suChinese.append(CNUMBERS[x]); suChinese.append(CNUMBERS[x]);
} }
} }
else
{
result = x + y;
suChinese.append(CNUMBERS[x]);
suChinese.append("+");
suChinese.append(CNUMBERS[y]);
}
suChinese.append("=?@" + result); suChinese.append("=?@" + result);
return suChinese.toString(); return suChinese.toString();
} }
@@ -1,8 +1,10 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter; import org.springframework.web.filter.CorsFilter;
@@ -33,7 +35,8 @@ public class ResourcesConfig implements WebMvcConfigurer
/** swagger配置 */ /** swagger配置 */
registry.addResourceHandler("/swagger-ui/**") registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/"); .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
.setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());;
} }
/** /**
@@ -102,6 +102,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
httpSecurity httpSecurity
// CSRF禁用,因为不使用session // CSRF禁用,因为不使用session
.csrf().disable() .csrf().disable()
// 禁用HTTP响应标头
.headers().cacheControl().disable().and()
// 认证失败处理类 // 认证失败处理类
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// 基于token,所以不需要session // 基于token,所以不需要session
@@ -109,7 +111,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
// 过滤请求 // 过滤请求
.authorizeRequests() .authorizeRequests()
// 对于登录login 注册register 验证码captchaImage 允许匿名访问 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/register", "/captchaImage").anonymous() .antMatchers("/login", "/register", "/captchaImage").permitAll()
// 静态资源,可匿名访问 // 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
@@ -0,0 +1,28 @@
package com.ruoyi.framework.security.context;
import org.springframework.security.core.Authentication;
/**
* 身份验证信息
*
* @author ruoyi
*/
public class AuthenticationContextHolder
{
private static final ThreadLocal<Authentication> contextHolder = new ThreadLocal<>();
public static Authentication getContext()
{
return contextHolder.get();
}
public static void setContext(Authentication context)
{
contextHolder.set(context);
}
public static void clearContext()
{
contextHolder.remove();
}
}
@@ -0,0 +1,27 @@
package com.ruoyi.framework.security.context;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import com.ruoyi.common.core.text.Convert;
/**
* 权限信息
*
* @author ruoyi
*/
public class PermissionContextHolder
{
private static final String PERMISSION_CONTEXT_ATTRIBUTES = "PERMISSION_CONTEXT";
public static void setContext(String permission)
{
RequestContextHolder.currentRequestAttributes().setAttribute(PERMISSION_CONTEXT_ATTRIBUTES, permission,
RequestAttributes.SCOPE_REQUEST);
}
public static String getContext()
{
return Convert.toStr(RequestContextHolder.currentRequestAttributes().getAttribute(PERMISSION_CONTEXT_ATTRIBUTES,
RequestAttributes.SCOPE_REQUEST));
}
}
@@ -10,7 +10,6 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
@@ -48,6 +47,6 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
// 记录用户退出日志 // 记录用户退出日志
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功")); AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
} }
ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "退出成功"))); ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success("退出成功")));
} }
} }
@@ -7,6 +7,7 @@ import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.security.context.PermissionContextHolder;
/** /**
* RuoYi首创 自定义权限实现,ss取自SpringSecurity首字母 * RuoYi首创 自定义权限实现,ss取自SpringSecurity首字母
@@ -43,6 +44,7 @@ public class PermissionService
{ {
return false; return false;
} }
PermissionContextHolder.setContext(permission);
return hasPermissions(loginUser.getPermissions(), permission); return hasPermissions(loginUser.getPermissions(), permission);
} }
@@ -74,6 +76,7 @@ public class PermissionService
{ {
return false; return false;
} }
PermissionContextHolder.setContext(permissions);
Set<String> authorities = loginUser.getPermissions(); Set<String> authorities = loginUser.getPermissions();
for (String permission : permissions.split(PERMISSION_DELIMETER)) for (String permission : permissions.split(PERMISSION_DELIMETER))
{ {
@@ -23,6 +23,7 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.framework.manager.AsyncManager; import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory; import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.security.context.AuthenticationContextHolder;
import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
@@ -60,9 +61,9 @@ public class SysLoginService
*/ */
public String login(String username, String password, String code, String uuid) public String login(String username, String password, String code, String uuid)
{ {
boolean captchaOnOff = configService.selectCaptchaOnOff(); boolean captchaEnabled = configService.selectCaptchaEnabled();
// 验证码开关 // 验证码开关
if (captchaOnOff) if (captchaEnabled)
{ {
validateCaptcha(username, code, uuid); validateCaptcha(username, code, uuid);
} }
@@ -70,9 +71,10 @@ public class SysLoginService
Authentication authentication = null; Authentication authentication = null;
try try
{ {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
AuthenticationContextHolder.setContext(authenticationToken);
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager authentication = authenticationManager.authenticate(authenticationToken);
.authenticate(new UsernamePasswordAuthenticationToken(username, password));
} }
catch (Exception e) catch (Exception e)
{ {
@@ -87,6 +89,10 @@ public class SysLoginService
throw new ServiceException(e.getMessage()); throw new ServiceException(e.getMessage());
} }
} }
finally
{
AuthenticationContextHolder.clearContext();
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
LoginUser loginUser = (LoginUser) authentication.getPrincipal(); LoginUser loginUser = (LoginUser) authentication.getPrincipal();
recordLoginInfo(loginUser.getUserId()); recordLoginInfo(loginUser.getUserId());
@@ -0,0 +1,94 @@
package com.ruoyi.framework.web.service;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.security.context.AuthenticationContextHolder;
/**
* 登录密码方法
*
* @author ruoyi
*/
@Component
public class SysPasswordService
{
@Autowired
private RedisCache redisCache;
@Value(value = "${user.password.maxRetryCount}")
private int maxRetryCount;
@Value(value = "${user.password.lockTime}")
private int lockTime;
/**
* 登录账户密码错误次数缓存键名
*
* @param username 用户名
* @return 缓存键key
*/
private String getCacheKey(String username)
{
return CacheConstants.PWD_ERR_CNT_KEY + username;
}
public void validate(SysUser user)
{
Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
String username = usernamePasswordAuthenticationToken.getName();
String password = usernamePasswordAuthenticationToken.getCredentials().toString();
Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
if (retryCount == null)
{
retryCount = 0;
}
if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime)));
throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
}
if (!matches(user, password))
{
retryCount = retryCount + 1;
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
MessageUtils.message("user.password.retry.limit.count", retryCount)));
redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
throw new UserPasswordNotMatchException();
}
else
{
clearLoginRecordCache(username);
}
}
public boolean matches(SysUser user, String rawPassword)
{
return SecurityUtils.matchesPassword(rawPassword, user.getPassword());
}
public void clearLoginRecordCache(String loginName)
{
if (redisCache.hasKey(getCacheKey(loginName)))
{
redisCache.deleteObject(getCacheKey(loginName));
}
}
}
@@ -1,9 +1,11 @@
package com.ruoyi.framework.web.service; package com.ruoyi.framework.web.service;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.service.ISysMenuService; import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
@@ -59,7 +61,21 @@ public class SysPermissionService
} }
else else
{ {
perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId())); List<SysRole> roles = user.getRoles();
if (!roles.isEmpty() && roles.size() > 1)
{
// 多角色设置permissions属性,以便数据权限匹配权限
for (SysRole role : roles)
{
Set<String> rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId());
role.setPermissions(rolePerms);
perms.addAll(rolePerms);
}
}
else
{
perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
}
} }
return perms; return perms;
} }
@@ -41,10 +41,12 @@ public class SysRegisterService
public String register(RegisterBody registerBody) public String register(RegisterBody registerBody)
{ {
String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword(); String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword();
SysUser sysUser = new SysUser();
sysUser.setUserName(username);
boolean captchaOnOff = configService.selectCaptchaOnOff();
// 验证码开关 // 验证码开关
if (captchaOnOff) boolean captchaEnabled = configService.selectCaptchaEnabled();
if (captchaEnabled)
{ {
validateCaptcha(username, registerBody.getCode(), registerBody.getUuid()); validateCaptcha(username, registerBody.getCode(), registerBody.getUuid());
} }
@@ -67,16 +69,14 @@ public class SysRegisterService
{ {
msg = "密码长度必须在5到20个字符之间"; msg = "密码长度必须在5到20个字符之间";
} }
else if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(username))) else if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(sysUser)))
{ {
msg = "保存用户'" + username + "'失败,注册账号已存在"; msg = "保存用户'" + username + "'失败,注册账号已存在";
} }
else else
{ {
SysUser sysUser = new SysUser();
sysUser.setUserName(username);
sysUser.setNickName(username); sysUser.setNickName(username);
sysUser.setPassword(SecurityUtils.encryptPassword(registerBody.getPassword())); sysUser.setPassword(SecurityUtils.encryptPassword(password));
boolean regFlag = userService.registerUser(sysUser); boolean regFlag = userService.registerUser(sysUser);
if (!regFlag) if (!regFlag)
{ {
@@ -84,8 +84,7 @@ public class SysRegisterService
} }
else else
{ {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER, AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success")));
MessageUtils.message("user.register.success")));
} }
} }
return msg; return msg;
@@ -26,6 +26,9 @@ public class UserDetailsServiceImpl implements UserDetailsService
@Autowired @Autowired
private ISysUserService userService; private ISysUserService userService;
@Autowired
private SysPasswordService passwordService;
@Autowired @Autowired
private SysPermissionService permissionService; private SysPermissionService permissionService;
@@ -50,6 +53,8 @@ public class UserDetailsServiceImpl implements UserDetailsService
throw new ServiceException("对不起,您的账号:" + username + " 已停用"); throw new ServiceException("对不起,您的账号:" + username + " 已停用");
} }
passwordService.validate(user);
return createLoginUser(user); return createLoginUser(user);
} }
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.8.3</version> <version>3.8.5</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -69,7 +69,7 @@ public class GenController extends BaseController
map.put("info", table); map.put("info", table);
map.put("rows", list); map.put("rows", list);
map.put("tables", tables); map.put("tables", tables);
return AjaxResult.success(map); return success(map);
} }
/** /**
@@ -110,7 +110,7 @@ public class GenController extends BaseController
// 查询表信息 // 查询表信息
List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames); List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);
genTableService.importGenTable(tableList); genTableService.importGenTable(tableList);
return AjaxResult.success(); return success();
} }
/** /**
@@ -123,7 +123,7 @@ public class GenController extends BaseController
{ {
genTableService.validateEdit(genTable); genTableService.validateEdit(genTable);
genTableService.updateGenTable(genTable); genTableService.updateGenTable(genTable);
return AjaxResult.success(); return success();
} }
/** /**
@@ -135,7 +135,7 @@ public class GenController extends BaseController
public AjaxResult remove(@PathVariable Long[] tableIds) public AjaxResult remove(@PathVariable Long[] tableIds)
{ {
genTableService.deleteGenTableByIds(tableIds); genTableService.deleteGenTableByIds(tableIds);
return AjaxResult.success(); return success();
} }
/** /**
@@ -146,7 +146,7 @@ public class GenController extends BaseController
public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException
{ {
Map<String, String> dataMap = genTableService.previewCode(tableId); Map<String, String> dataMap = genTableService.previewCode(tableId);
return AjaxResult.success(dataMap); return success(dataMap);
} }
/** /**
@@ -170,7 +170,7 @@ public class GenController extends BaseController
public AjaxResult genCode(@PathVariable("tableName") String tableName) public AjaxResult genCode(@PathVariable("tableName") String tableName)
{ {
genTableService.generatorCode(tableName); genTableService.generatorCode(tableName);
return AjaxResult.success(); return success();
} }
/** /**
@@ -182,7 +182,7 @@ public class GenController extends BaseController
public AjaxResult synchDb(@PathVariable("tableName") String tableName) public AjaxResult synchDb(@PathVariable("tableName") String tableName)
{ {
genTableService.synchDb(tableName); genTableService.synchDb(tableName);
return AjaxResult.success(); return success();
} }
/** /**
@@ -92,19 +92,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<update id="updateGenTableColumn" parameterType="GenTableColumn"> <update id="updateGenTableColumn" parameterType="GenTableColumn">
update gen_table_column update gen_table_column
<set> <set>
column_comment = #{columnComment}, <if test="columnComment != null">column_comment = #{columnComment},</if>
java_type = #{javaType}, <if test="javaType != null">java_type = #{javaType},</if>
java_field = #{javaField}, <if test="javaField != null">java_field = #{javaField},</if>
is_insert = #{isInsert}, <if test="isInsert != null">is_insert = #{isInsert},</if>
is_edit = #{isEdit}, <if test="isEdit != null">is_edit = #{isEdit},</if>
is_list = #{isList}, <if test="isList != null">is_list = #{isList},</if>
is_query = #{isQuery}, <if test="isQuery != null">is_query = #{isQuery},</if>
is_required = #{isRequired}, <if test="isRequired != null">is_required = #{isRequired},</if>
query_type = #{queryType}, <if test="queryType != null">query_type = #{queryType},</if>
html_type = #{htmlType}, <if test="htmlType != null">html_type = #{htmlType},</if>
dict_type = #{dictType}, <if test="dictType != null">dict_type = #{dictType},</if>
sort = #{sort}, <if test="sort != null">sort = #{sort},</if>
update_by = #{updateBy}, <if test="updateBy != null">update_by = #{updateBy},</if>
update_time = sysdate() update_time = sysdate()
</set> </set>
where column_id = #{columnId} where column_id = #{columnId}
@@ -53,7 +53,7 @@ public class ${ClassName}Controller extends BaseController
public AjaxResult list(${ClassName} ${className}) public AjaxResult list(${ClassName} ${className})
{ {
List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
return AjaxResult.success(list); return success(list);
} }
#end #end
@@ -77,7 +77,7 @@ public class ${ClassName}Controller extends BaseController
@GetMapping(value = "/{${pkColumn.javaField}}") @GetMapping(value = "/{${pkColumn.javaField}}")
public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField})
{ {
return AjaxResult.success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField})); return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}));
} }
/** /**
@@ -187,11 +187,11 @@
<el-input v-model="form.${field}" placeholder="请输入${comment}" /> <el-input v-model="form.${field}" placeholder="请输入${comment}" />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "imageUpload") #elseif($column.htmlType == "imageUpload")
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<image-upload v-model="form.${field}"/> <image-upload v-model="form.${field}"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "fileUpload") #elseif($column.htmlType == "fileUpload")
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<file-upload v-model="form.${field}"/> <file-upload v-model="form.${field}"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "editor") #elseif($column.htmlType == "editor")
@@ -205,8 +205,11 @@
v-for="dict in dict.type.${dictType}" v-for="dict in dict.type.${dictType}"
:key="dict.value" :key="dict.value"
:label="dict.label" :label="dict.label"
#if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end #if($column.javaType == "Integer" || $column.javaType == "Long")
:value="parseInt(dict.value)"
#else
:value="dict.value"
#end
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -217,7 +220,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "checkbox" && "" != $dictType) #elseif($column.htmlType == "checkbox" && "" != $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-checkbox-group v-model="form.${field}"> <el-checkbox-group v-model="form.${field}">
<el-checkbox <el-checkbox
v-for="dict in dict.type.${dictType}" v-for="dict in dict.type.${dictType}"
@@ -228,24 +231,27 @@
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "checkbox" && $dictType) #elseif($column.htmlType == "checkbox" && $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-checkbox-group v-model="form.${field}"> <el-checkbox-group v-model="form.${field}">
<el-checkbox>请选择字典生成</el-checkbox> <el-checkbox>请选择字典生成</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "radio" && "" != $dictType) #elseif($column.htmlType == "radio" && "" != $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-radio-group v-model="form.${field}"> <el-radio-group v-model="form.${field}">
<el-radio <el-radio
v-for="dict in dict.type.${dictType}" v-for="dict in dict.type.${dictType}"
:key="dict.value" :key="dict.value"
#if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end #if($column.javaType == "Integer" || $column.javaType == "Long")
:label="parseInt(dict.value)"
#else
:label="dict.value"
#end
>{{dict.label}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "radio" && $dictType) #elseif($column.htmlType == "radio" && $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-radio-group v-model="form.${field}"> <el-radio-group v-model="form.${field}">
<el-radio label="1">请选择字典生成</el-radio> <el-radio label="1">请选择字典生成</el-radio>
</el-radio-group> </el-radio-group>
@@ -335,7 +341,7 @@ export default {
#set($comment=$column.columnComment) #set($comment=$column.columnComment)
#end #end
$column.javaField: [ $column.javaField: [
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end } { required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
]#if($foreach.count != $columns.size()),#end ]#if($foreach.count != $columns.size()),#end
#end #end
#end #end
@@ -398,10 +404,7 @@ export default {
reset() { reset() {
this.form = { this.form = {
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "radio") #if($column.htmlType == "checkbox")
$column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($foreach.count != $columns.size()),#end
#elseif($column.htmlType == "checkbox")
$column.javaField: []#if($foreach.count != $columns.size()),#end $column.javaField: []#if($foreach.count != $columns.size()),#end
#else #else
$column.javaField: null#if($foreach.count != $columns.size()),#end $column.javaField: null#if($foreach.count != $columns.size()),#end
@@ -198,11 +198,11 @@
<el-input v-model="form.${field}" placeholder="请输入${comment}" /> <el-input v-model="form.${field}" placeholder="请输入${comment}" />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "imageUpload") #elseif($column.htmlType == "imageUpload")
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<image-upload v-model="form.${field}"/> <image-upload v-model="form.${field}"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "fileUpload") #elseif($column.htmlType == "fileUpload")
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<file-upload v-model="form.${field}"/> <file-upload v-model="form.${field}"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "editor") #elseif($column.htmlType == "editor")
@@ -216,8 +216,11 @@
v-for="dict in dict.type.${dictType}" v-for="dict in dict.type.${dictType}"
:key="dict.value" :key="dict.value"
:label="dict.label" :label="dict.label"
#if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end #if($column.javaType == "Integer" || $column.javaType == "Long")
:value="parseInt(dict.value)"
#else
:value="dict.value"
#end
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -228,7 +231,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "checkbox" && "" != $dictType) #elseif($column.htmlType == "checkbox" && "" != $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-checkbox-group v-model="form.${field}"> <el-checkbox-group v-model="form.${field}">
<el-checkbox <el-checkbox
v-for="dict in dict.type.${dictType}" v-for="dict in dict.type.${dictType}"
@@ -239,24 +242,27 @@
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "checkbox" && $dictType) #elseif($column.htmlType == "checkbox" && $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-checkbox-group v-model="form.${field}"> <el-checkbox-group v-model="form.${field}">
<el-checkbox>请选择字典生成</el-checkbox> <el-checkbox>请选择字典生成</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "radio" && "" != $dictType) #elseif($column.htmlType == "radio" && "" != $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-radio-group v-model="form.${field}"> <el-radio-group v-model="form.${field}">
<el-radio <el-radio
v-for="dict in dict.type.${dictType}" v-for="dict in dict.type.${dictType}"
:key="dict.value" :key="dict.value"
#if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end #if($column.javaType == "Integer" || $column.javaType == "Long")
:label="parseInt(dict.value)"
#else
:label="dict.value"
#end
>{{dict.label}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "radio" && $dictType) #elseif($column.htmlType == "radio" && $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-radio-group v-model="form.${field}"> <el-radio-group v-model="form.${field}">
<el-radio label="1">请选择字典生成</el-radio> <el-radio label="1">请选择字典生成</el-radio>
</el-radio-group> </el-radio-group>
@@ -412,7 +418,7 @@ export default {
#set($comment=$column.columnComment) #set($comment=$column.columnComment)
#end #end
$column.javaField: [ $column.javaField: [
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end } { required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
]#if($foreach.count != $columns.size()),#end ]#if($foreach.count != $columns.size()),#end
#end #end
#end #end
@@ -456,9 +462,7 @@ export default {
reset() { reset() {
this.form = { this.form = {
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "radio") #if($column.htmlType == "checkbox")
$column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($foreach.count != $columns.size()),#end
#elseif($column.htmlType == "checkbox")
$column.javaField: []#if($foreach.count != $columns.size()),#end $column.javaField: []#if($foreach.count != $columns.size()),#end
#else #else
$column.javaField: null#if($foreach.count != $columns.size()),#end $column.javaField: null#if($foreach.count != $columns.size()),#end
@@ -136,24 +136,9 @@
#end #end
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-button <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button>
type="text" <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['${moduleName}:${businessName}:add']">新增</el-button>
icon="Edit" <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button>
@click="handleUpdate(scope.row)"
v-hasPermi="['${moduleName}:${businessName}:edit']"
>修改</el-button>
<el-button
type="text"
icon="Plus"
@click="handleAdd(scope.row)"
v-hasPermi="['${moduleName}:${businessName}:add']"
>新增</el-button>
<el-button
type="text"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['${moduleName}:${businessName}:remove']"
>删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@@ -188,11 +173,11 @@
<el-input v-model="form.${field}" placeholder="请输入${comment}" /> <el-input v-model="form.${field}" placeholder="请输入${comment}" />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "imageUpload") #elseif($column.htmlType == "imageUpload")
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<image-upload v-model="form.${field}"/> <image-upload v-model="form.${field}"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "fileUpload") #elseif($column.htmlType == "fileUpload")
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<file-upload v-model="form.${field}"/> <file-upload v-model="form.${field}"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "editor") #elseif($column.htmlType == "editor")
@@ -206,8 +191,11 @@
v-for="dict in ${dictType}" v-for="dict in ${dictType}"
:key="dict.value" :key="dict.value"
:label="dict.label" :label="dict.label"
#if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end #if($column.javaType == "Integer" || $column.javaType == "Long")
:value="parseInt(dict.value)"
#else
:value="dict.value"
#end
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -218,7 +206,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "checkbox" && "" != $dictType) #elseif($column.htmlType == "checkbox" && "" != $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-checkbox-group v-model="form.${field}"> <el-checkbox-group v-model="form.${field}">
<el-checkbox <el-checkbox
v-for="dict in ${dictType}" v-for="dict in ${dictType}"
@@ -229,24 +217,27 @@
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "checkbox" && $dictType) #elseif($column.htmlType == "checkbox" && $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-checkbox-group v-model="form.${field}"> <el-checkbox-group v-model="form.${field}">
<el-checkbox>请选择字典生成</el-checkbox> <el-checkbox>请选择字典生成</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "radio" && "" != $dictType) #elseif($column.htmlType == "radio" && "" != $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-radio-group v-model="form.${field}"> <el-radio-group v-model="form.${field}">
<el-radio <el-radio
v-for="dict in ${dictType}" v-for="dict in ${dictType}"
:key="dict.value" :key="dict.value"
#if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end #if($column.javaType == "Integer" || $column.javaType == "Long")
:label="parseInt(dict.value)"
#else
:label="dict.value"
#end
>{{dict.label}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "radio" && $dictType) #elseif($column.htmlType == "radio" && $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-radio-group v-model="form.${field}"> <el-radio-group v-model="form.${field}">
<el-radio label="1">请选择字典生成</el-radio> <el-radio label="1">请选择字典生成</el-radio>
</el-radio-group> </el-radio-group>
@@ -322,7 +313,7 @@ const data = reactive({
#set($comment=$column.columnComment) #set($comment=$column.columnComment)
#end #end
$column.javaField: [ $column.javaField: [
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end } { required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
]#if($foreach.count != $columns.size()),#end ]#if($foreach.count != $columns.size()),#end
#end #end
#end #end
@@ -375,10 +366,7 @@ function cancel() {
function reset() { function reset() {
form.value = { form.value = {
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "radio") #if($column.htmlType == "checkbox")
$column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($foreach.count != $columns.size()),#end
#elseif($column.htmlType == "checkbox")
$column.javaField: []#if($foreach.count != $columns.size()),#end $column.javaField: []#if($foreach.count != $columns.size()),#end
#else #else
$column.javaField: null#if($foreach.count != $columns.size()),#end $column.javaField: null#if($foreach.count != $columns.size()),#end
@@ -148,18 +148,8 @@
#end #end
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-button <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button>
type="text" <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button>
icon="Edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['${moduleName}:${businessName}:edit']"
>修改</el-button>
<el-button
type="text"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['${moduleName}:${businessName}:remove']"
>删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@@ -191,11 +181,11 @@
<el-input v-model="form.${field}" placeholder="请输入${comment}" /> <el-input v-model="form.${field}" placeholder="请输入${comment}" />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "imageUpload") #elseif($column.htmlType == "imageUpload")
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<image-upload v-model="form.${field}"/> <image-upload v-model="form.${field}"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "fileUpload") #elseif($column.htmlType == "fileUpload")
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<file-upload v-model="form.${field}"/> <file-upload v-model="form.${field}"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "editor") #elseif($column.htmlType == "editor")
@@ -209,8 +199,11 @@
v-for="dict in ${dictType}" v-for="dict in ${dictType}"
:key="dict.value" :key="dict.value"
:label="dict.label" :label="dict.label"
#if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end #if($column.javaType == "Integer" || $column.javaType == "Long")
:value="parseInt(dict.value)"
#else
:value="dict.value"
#end
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -221,7 +214,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "checkbox" && "" != $dictType) #elseif($column.htmlType == "checkbox" && "" != $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-checkbox-group v-model="form.${field}"> <el-checkbox-group v-model="form.${field}">
<el-checkbox <el-checkbox
v-for="dict in ${dictType}" v-for="dict in ${dictType}"
@@ -232,24 +225,27 @@
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "checkbox" && $dictType) #elseif($column.htmlType == "checkbox" && $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-checkbox-group v-model="form.${field}"> <el-checkbox-group v-model="form.${field}">
<el-checkbox>请选择字典生成</el-checkbox> <el-checkbox>请选择字典生成</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "radio" && "" != $dictType) #elseif($column.htmlType == "radio" && "" != $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-radio-group v-model="form.${field}"> <el-radio-group v-model="form.${field}">
<el-radio <el-radio
v-for="dict in ${dictType}" v-for="dict in ${dictType}"
:key="dict.value" :key="dict.value"
#if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end #if($column.javaType == "Integer" || $column.javaType == "Long")
:label="parseInt(dict.value)"
#else
:label="dict.value"
#end
>{{dict.label}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "radio" && $dictType) #elseif($column.htmlType == "radio" && $dictType)
<el-form-item label="${comment}"> <el-form-item label="${comment}" prop="${field}">
<el-radio-group v-model="form.${field}"> <el-radio-group v-model="form.${field}">
<el-radio label="1">请选择字典生成</el-radio> <el-radio label="1">请选择字典生成</el-radio>
</el-radio-group> </el-radio-group>
@@ -398,7 +394,7 @@ const data = reactive({
#set($comment=$column.columnComment) #set($comment=$column.columnComment)
#end #end
$column.javaField: [ $column.javaField: [
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end } { required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
]#if($foreach.count != $columns.size()),#end ]#if($foreach.count != $columns.size()),#end
#end #end
#end #end
@@ -442,9 +438,7 @@ function cancel() {
function reset() { function reset() {
form.value = { form.value = {
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "radio") #if($column.htmlType == "checkbox")
$column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($foreach.count != $columns.size()),#end
#elseif($column.htmlType == "checkbox")
$column.javaField: []#if($foreach.count != $columns.size()),#end $column.javaField: []#if($foreach.count != $columns.size()),#end
#else #else
$column.javaField: null#if($foreach.count != $columns.size()),#end $column.javaField: null#if($foreach.count != $columns.size()),#end
@@ -492,8 +486,8 @@ function handleAdd() {
/** 修改按钮操作 */ /** 修改按钮操作 */
function handleUpdate(row) { function handleUpdate(row) {
reset(); reset();
const ${pkColumn.javaField} = row.${pkColumn.javaField} || ids.value const _${pkColumn.javaField} = row.${pkColumn.javaField} || ids.value
get${BusinessName}(${pkColumn.javaField}).then(response => { get${BusinessName}(_${pkColumn.javaField}).then(response => {
form.value = response.data; form.value = response.data;
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "checkbox") #if($column.htmlType == "checkbox")
@@ -539,9 +533,9 @@ function submitForm() {
/** 删除按钮操作 */ /** 删除按钮操作 */
function handleDelete(row) { function handleDelete(row) {
const ${pkColumn.javaField}s = row.${pkColumn.javaField} || ids.value; const _${pkColumn.javaField}s = row.${pkColumn.javaField} || ids.value;
proxy.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + ${pkColumn.javaField}s + '"的数据项?').then(function() { proxy.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + _${pkColumn.javaField}s + '"的数据项?').then(function() {
return del${BusinessName}(${pkColumn.javaField}s); return del${BusinessName}(_${pkColumn.javaField}s);
}).then(() => { }).then(() => {
getList(); getList();
proxy.#[[$modal]]#.msgSuccess("删除成功"); proxy.#[[$modal]]#.msgSuccess("删除成功");
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.8.3</version> <version>3.8.5</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -71,7 +71,7 @@ public class SysJobController extends BaseController
@GetMapping(value = "/{jobId}") @GetMapping(value = "/{jobId}")
public AjaxResult getInfo(@PathVariable("jobId") Long jobId) public AjaxResult getInfo(@PathVariable("jobId") Long jobId)
{ {
return AjaxResult.success(jobService.selectJobById(jobId)); return success(jobService.selectJobById(jobId));
} }
/** /**
@@ -167,8 +167,8 @@ public class SysJobController extends BaseController
@PutMapping("/run") @PutMapping("/run")
public AjaxResult run(@RequestBody SysJob job) throws SchedulerException public AjaxResult run(@RequestBody SysJob job) throws SchedulerException
{ {
jobService.run(job); boolean result = jobService.run(job);
return AjaxResult.success(); return result ? success() : error("任务不存在或已过期!");
} }
/** /**
@@ -180,6 +180,6 @@ public class SysJobController extends BaseController
public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException
{ {
jobService.deleteJobByIds(jobIds); jobService.deleteJobByIds(jobIds);
return AjaxResult.success(); return success();
} }
} }
@@ -60,10 +60,10 @@ public class SysJobLogController extends BaseController
* 根据调度编号获取详细信息 * 根据调度编号获取详细信息
*/ */
@PreAuthorize("@ss.hasPermi('monitor:job:query')") @PreAuthorize("@ss.hasPermi('monitor:job:query')")
@GetMapping(value = "/{configId}") @GetMapping(value = "/{jobLogId}")
public AjaxResult getInfo(@PathVariable Long jobLogId) public AjaxResult getInfo(@PathVariable Long jobLogId)
{ {
return AjaxResult.success(jobLogService.selectJobLogById(jobLogId)); return success(jobLogService.selectJobLogById(jobLogId));
} }
@@ -87,6 +87,6 @@ public class SysJobLogController extends BaseController
public AjaxResult clean() public AjaxResult clean()
{ {
jobLogService.cleanJobLog(); jobLogService.cleanJobLog();
return AjaxResult.success(); return success();
} }
} }
@@ -74,7 +74,7 @@ public interface ISysJobService
* @param job 调度信息 * @param job 调度信息
* @return 结果 * @return 结果
*/ */
public void run(SysJob job) throws SchedulerException; public boolean run(SysJob job) throws SchedulerException;
/** /**
* 新增任务 * 新增任务
@@ -174,15 +174,22 @@ public class SysJobServiceImpl implements ISysJobService
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void run(SysJob job) throws SchedulerException public boolean run(SysJob job) throws SchedulerException
{ {
boolean result = false;
Long jobId = job.getJobId(); Long jobId = job.getJobId();
String jobGroup = job.getJobGroup(); String jobGroup = job.getJobGroup();
SysJob properties = selectJobById(job.getJobId()); SysJob properties = selectJobById(job.getJobId());
// 参数 // 参数
JobDataMap dataMap = new JobDataMap(); JobDataMap dataMap = new JobDataMap();
dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties); dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties);
scheduler.triggerJob(ScheduleUtils.getJobKey(jobId, jobGroup), dataMap); JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup);
if (scheduler.checkExists(jobKey))
{
result = true;
scheduler.triggerJob(jobKey, dataMap);
}
return result;
} }
/** /**
@@ -52,12 +52,12 @@ public class JobInvokeUtil
{ {
if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0)
{ {
Method method = bean.getClass().getDeclaredMethod(methodName, getMethodParamsType(methodParams)); Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams));
method.invoke(bean, getMethodParamsValue(methodParams)); method.invoke(bean, getMethodParamsValue(methodParams));
} }
else else
{ {
Method method = bean.getClass().getDeclaredMethod(methodName); Method method = bean.getClass().getMethod(methodName);
method.invoke(bean); method.invoke(bean);
} }
} }
@@ -83,7 +83,12 @@ public class ScheduleUtils
scheduler.deleteJob(getJobKey(jobId, jobGroup)); scheduler.deleteJob(getJobKey(jobId, jobGroup));
} }
scheduler.scheduleJob(jobDetail, trigger); // 判断任务是否过期
if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression())))
{
// 执行调度任务
scheduler.scheduleJob(jobDetail, trigger);
}
// 暂停任务 // 暂停任务
if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue()))
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.8.3</version> <version>3.8.5</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -1,6 +1,7 @@
package com.ruoyi.system.domain; package com.ruoyi.system.domain;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@@ -31,7 +32,7 @@ public class SysPost extends BaseEntity
/** 岗位排序 */ /** 岗位排序 */
@Excel(name = "岗位排序") @Excel(name = "岗位排序")
private String postSort; private Integer postSort;
/** 状态(0正常 1停用) */ /** 状态(0正常 1停用) */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用") @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
@@ -74,13 +75,13 @@ public class SysPost extends BaseEntity
this.postName = postName; this.postName = postName;
} }
@NotBlank(message = "显示顺序不能为空") @NotNull(message = "显示顺序不能为空")
public String getPostSort() public Integer getPostSort()
{ {
return postSort; return postSort;
} }
public void setPostSort(String postSort) public void setPostSort(Integer postSort)
{ {
this.postSort = postSort; this.postSort = postSort;
} }
@@ -18,6 +18,14 @@ public interface SysConfigMapper
*/ */
public SysConfig selectConfig(SysConfig config); public SysConfig selectConfig(SysConfig config);
/**
* 通过ID查询配置
*
* @param configId 参数ID
* @return 参数配置信息
*/
public SysConfig selectConfigById(Long configId);
/** /**
* 查询参数配置列表 * 查询参数配置列表
* *
@@ -34,6 +34,14 @@ public interface SysMenuMapper
*/ */
public List<SysMenu> selectMenuListByUserId(SysMenu menu); public List<SysMenu> selectMenuListByUserId(SysMenu menu);
/**
* 根据角色ID查询权限
*
* @param roleId 角色ID
* @return 权限列表
*/
public List<String> selectMenuPermsByRoleId(Long roleId);
/** /**
* 根据用户ID查询权限 * 根据用户ID查询权限
* *
@@ -107,7 +107,7 @@ public interface SysUserMapper
* @param userName 用户名称 * @param userName 用户名称
* @return 结果 * @return 结果
*/ */
public int checkUserNameUnique(String userName); public SysUser checkUserNameUnique(String userName);
/** /**
* 校验手机号码是否唯一 * 校验手机号码是否唯一
@@ -31,7 +31,7 @@ public interface ISysConfigService
* *
* @return true开启,false关闭 * @return true开启,false关闭
*/ */
public boolean selectCaptchaOnOff(); public boolean selectCaptchaEnabled();
/** /**
* 查询参数配置列表 * 查询参数配置列表
@@ -19,6 +19,14 @@ public interface ISysDeptService
*/ */
public List<SysDept> selectDeptList(SysDept dept); public List<SysDept> selectDeptList(SysDept dept);
/**
* 查询部门树结构信息
*
* @param dept 部门信息
* @return 部门树信息集合
*/
public List<TreeSelect> selectDeptTreeList(SysDept dept);
/** /**
* 构建前端所需要树结构 * 构建前端所需要树结构
* *
@@ -38,6 +38,14 @@ public interface ISysMenuService
*/ */
public Set<String> selectMenuPermsByUserId(Long userId); public Set<String> selectMenuPermsByUserId(Long userId);
/**
* 根据角色ID查询权限
*
* @param roleId 角色ID
* @return 权限列表
*/
public Set<String> selectMenuPermsByRoleId(Long roleId);
/** /**
* 根据用户ID查询菜单树信息 * 根据用户ID查询菜单树信息
* *
@@ -69,10 +69,10 @@ public interface ISysUserService
/** /**
* 校验用户名称是否唯一 * 校验用户名称是否唯一
* *
* @param userName 用户名称 * @param user 用户信息
* @return 结果 * @return 结果
*/ */
public String checkUserNameUnique(String userName); public String checkUserNameUnique(SysUser user);
/** /**
* 校验手机号码是否唯一 * 校验手机号码是否唯一
@@ -86,14 +86,14 @@ public class SysConfigServiceImpl implements ISysConfigService
* @return true开启,false关闭 * @return true开启,false关闭
*/ */
@Override @Override
public boolean selectCaptchaOnOff() public boolean selectCaptchaEnabled()
{ {
String captchaOnOff = selectConfigByKey("sys.account.captchaOnOff"); String captchaEnabled = selectConfigByKey("sys.account.captchaEnabled");
if (StringUtils.isEmpty(captchaOnOff)) if (StringUtils.isEmpty(captchaEnabled))
{ {
return true; return true;
} }
return Convert.toBool(captchaOnOff); return Convert.toBool(captchaEnabled);
} }
/** /**
@@ -134,6 +134,12 @@ public class SysConfigServiceImpl implements ISysConfigService
@Override @Override
public int updateConfig(SysConfig config) public int updateConfig(SysConfig config)
{ {
SysConfig temp = configMapper.selectConfigById(config.getConfigId());
if (!StringUtils.equals(temp.getConfigKey(), config.getConfigKey()))
{
redisCache.deleteObject(getCacheKey(temp.getConfigKey()));
}
int row = configMapper.updateConfig(config); int row = configMapper.updateConfig(config);
if (row > 0) if (row > 0)
{ {
@@ -48,6 +48,19 @@ public class SysDeptServiceImpl implements ISysDeptService
return deptMapper.selectDeptList(dept); return deptMapper.selectDeptList(dept);
} }
/**
* 查询部门树结构信息
*
* @param dept 部门信息
* @return 部门树信息集合
*/
@Override
public List<TreeSelect> selectDeptTreeList(SysDept dept)
{
List<SysDept> depts = SpringUtils.getAopProxy(this).selectDeptList(dept);
return buildDeptTreeSelect(depts);
}
/** /**
* 构建前端所需要树结构 * 构建前端所需要树结构
* *
@@ -58,11 +71,7 @@ public class SysDeptServiceImpl implements ISysDeptService
public List<SysDept> buildDeptTree(List<SysDept> depts) public List<SysDept> buildDeptTree(List<SysDept> depts)
{ {
List<SysDept> returnList = new ArrayList<SysDept>(); List<SysDept> returnList = new ArrayList<SysDept>();
List<Long> tempList = new ArrayList<Long>(); List<Long> tempList = depts.stream().map(SysDept::getDeptId).collect(Collectors.toList());
for (SysDept dept : depts)
{
tempList.add(dept.getDeptId());
}
for (SysDept dept : depts) for (SysDept dept : depts)
{ {
// 如果是顶级节点, 遍历该父节点的所有子节点 // 如果是顶级节点, 遍历该父节点的所有子节点
@@ -100,6 +100,27 @@ public class SysMenuServiceImpl implements ISysMenuService
return permsSet; return permsSet;
} }
/**
* 根据角色ID查询权限
*
* @param roleId 角色ID
* @return 权限列表
*/
@Override
public Set<String> selectMenuPermsByRoleId(Long roleId)
{
List<String> perms = menuMapper.selectMenuPermsByRoleId(roleId);
Set<String> permsSet = new HashSet<>();
for (String perm : perms)
{
if (StringUtils.isNotEmpty(perm))
{
permsSet.addAll(Arrays.asList(perm.trim().split(",")));
}
}
return permsSet;
}
/** /**
* 根据用户ID查询菜单 * 根据用户ID查询菜单
* *
@@ -202,11 +223,7 @@ public class SysMenuServiceImpl implements ISysMenuService
public List<SysMenu> buildMenuTree(List<SysMenu> menus) public List<SysMenu> buildMenuTree(List<SysMenu> menus)
{ {
List<SysMenu> returnList = new ArrayList<SysMenu>(); List<SysMenu> returnList = new ArrayList<SysMenu>();
List<Long> tempList = new ArrayList<Long>(); List<Long> tempList = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList());
for (SysMenu dept : menus)
{
tempList.add(dept.getMenuId());
}
for (Iterator<SysMenu> iterator = menus.iterator(); iterator.hasNext();) for (Iterator<SysMenu> iterator = menus.iterator(); iterator.hasNext();)
{ {
SysMenu menu = (SysMenu) iterator.next(); SysMenu menu = (SysMenu) iterator.next();
@@ -458,8 +475,8 @@ public class SysMenuServiceImpl implements ISysMenuService
/** /**
* 递归列表 * 递归列表
* *
* @param list * @param list 分类表
* @param t * @param t 子节点
*/ */
private void recursionFn(List<SysMenu> list, SysMenu t) private void recursionFn(List<SysMenu> list, SysMenu t)
{ {
@@ -504,11 +521,11 @@ public class SysMenuServiceImpl implements ISysMenuService
/** /**
* 内链域名特殊字符替换 * 内链域名特殊字符替换
* *
* @return * @return 替换后的内链域名
*/ */
public String innerLinkReplaceEach(String path) public String innerLinkReplaceEach(String path)
{ {
return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS }, return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, "." },
new String[] { "", "" }); new String[] { "", "", "", "/" });
} }
} }
@@ -161,14 +161,15 @@ public class SysUserServiceImpl implements ISysUserService
/** /**
* 校验用户名称是否唯一 * 校验用户名称是否唯一
* *
* @param userName 用户名称 * @param user 用户信息
* @return 结果 * @return 结果
*/ */
@Override @Override
public String checkUserNameUnique(String userName) public String checkUserNameUnique(SysUser user)
{ {
int count = userMapper.checkUserNameUnique(userName); Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
if (count > 0) SysUser info = userMapper.checkUserNameUnique(user.getUserName());
if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue())
{ {
return UserConstants.NOT_UNIQUE; return UserConstants.NOT_UNIQUE;
} }
@@ -507,6 +508,8 @@ public class SysUserServiceImpl implements ISysUserService
else if (isUpdateSupport) else if (isUpdateSupport)
{ {
BeanValidators.validateWithException(validator, user); BeanValidators.validateWithException(validator, user);
checkUserAllowed(user);
checkUserDataScope(user.getUserId());
user.setUpdateBy(operName); user.setUpdateBy(operName);
this.updateUser(user); this.updateUser(user);
successNum++; successNum++;
@@ -59,6 +59,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where> </where>
</select> </select>
<select id="selectConfigById" parameterType="Long" resultMap="SysConfigResult">
<include refid="selectConfigVo"/>
where config_id = #{configId}
</select>
<select id="checkConfigKeyUnique" parameterType="String" resultMap="SysConfigResult"> <select id="checkConfigKeyUnique" parameterType="String" resultMap="SysConfigResult">
<include refid="selectConfigVo"/> <include refid="selectConfigVo"/>
where config_key = #{configKey} limit 1 where config_key = #{configKey} limit 1
@@ -59,8 +59,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select> </select>
<select id="selectDeptById" parameterType="Long" resultMap="SysDeptResult"> <select id="selectDeptById" parameterType="Long" resultMap="SysDeptResult">
<include refid="selectDeptVo"/> select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status,
where dept_id = #{deptId} (select dept_name from sys_dept where dept_id = d.parent_id) parent_name
from sys_dept d
where d.dept_id = #{deptId}
</select> </select>
<select id="checkDeptExistUser" parameterType="Long" resultType="int"> <select id="checkDeptExistUser" parameterType="Long" resultType="int">
@@ -82,7 +84,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="checkDeptNameUnique" resultMap="SysDeptResult"> <select id="checkDeptNameUnique" resultMap="SysDeptResult">
<include refid="selectDeptVo"/> <include refid="selectDeptVo"/>
where dept_name=#{deptName} and parent_id = #{parentId} limit 1 where dept_name=#{deptName} and parent_id = #{parentId} and del_flag = '0' limit 1
</select> </select>
<insert id="insertDept" parameterType="SysDept"> <insert id="insertDept" parameterType="SysDept">
@@ -111,6 +111,13 @@
where m.status = '0' and r.status = '0' and ur.user_id = #{userId} where m.status = '0' and r.status = '0' and ur.user_id = #{userId}
</select> </select>
<select id="selectMenuPermsByRoleId" parameterType="Long" resultType="String">
select distinct m.perms
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
where m.status = '0' and rm.role_id = #{roleId}
</select>
<select id="selectMenuById" parameterType="Long" resultMap="SysMenuResult"> <select id="selectMenuById" parameterType="Long" resultMap="SysMenuResult">
<include refid="selectMenuVo"/> <include refid="selectMenuVo"/>
where menu_id = #{menuId} where menu_id = #{menuId}
@@ -77,7 +77,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<set> <set>
<if test="postCode != null and postCode != ''">post_code = #{postCode},</if> <if test="postCode != null and postCode != ''">post_code = #{postCode},</if>
<if test="postName != null and postName != ''">post_name = #{postName},</if> <if test="postName != null and postName != ''">post_name = #{postName},</if>
<if test="postSort != null and postSort != ''">post_sort = #{postSort},</if> <if test="postSort != null">post_sort = #{postSort},</if>
<if test="status != null and status != ''">status = #{status},</if> <if test="status != null and status != ''">status = #{status},</if>
<if test="remark != null">remark = #{remark},</if> <if test="remark != null">remark = #{remark},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
@@ -91,7 +91,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="postId != null and postId != 0">post_id,</if> <if test="postId != null and postId != 0">post_id,</if>
<if test="postCode != null and postCode != ''">post_code,</if> <if test="postCode != null and postCode != ''">post_code,</if>
<if test="postName != null and postName != ''">post_name,</if> <if test="postName != null and postName != ''">post_name,</if>
<if test="postSort != null and postSort != ''">post_sort,</if> <if test="postSort != null">post_sort,</if>
<if test="status != null and status != ''">status,</if> <if test="status != null and status != ''">status,</if>
<if test="remark != null and remark != ''">remark,</if> <if test="remark != null and remark != ''">remark,</if>
<if test="createBy != null and createBy != ''">create_by,</if> <if test="createBy != null and createBy != ''">create_by,</if>
@@ -100,7 +100,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="postId != null and postId != 0">#{postId},</if> <if test="postId != null and postId != 0">#{postId},</if>
<if test="postCode != null and postCode != ''">#{postCode},</if> <if test="postCode != null and postCode != ''">#{postCode},</if>
<if test="postName != null and postName != ''">#{postName},</if> <if test="postName != null and postName != ''">#{postName},</if>
<if test="postSort != null and postSort != ''">#{postSort},</if> <if test="postSort != null">#{postSort},</if>
<if test="status != null and status != ''">#{status},</if> <if test="status != null and status != ''">#{status},</if>
<if test="remark != null and remark != ''">#{remark},</if> <if test="remark != null and remark != ''">#{remark},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if> <if test="createBy != null and createBy != ''">#{createBy},</if>
@@ -85,12 +85,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="checkRoleNameUnique" parameterType="String" resultMap="SysRoleResult"> <select id="checkRoleNameUnique" parameterType="String" resultMap="SysRoleResult">
<include refid="selectRoleVo"/> <include refid="selectRoleVo"/>
where r.role_name=#{roleName} limit 1 where r.role_name=#{roleName} and r.del_flag = '0' limit 1
</select> </select>
<select id="checkRoleKeyUnique" parameterType="String" resultMap="SysRoleResult"> <select id="checkRoleKeyUnique" parameterType="String" resultMap="SysRoleResult">
<include refid="selectRoleVo"/> <include refid="selectRoleVo"/>
where r.role_key=#{roleKey} limit 1 where r.role_key=#{roleKey} and r.del_flag = '0' limit 1
</select> </select>
<insert id="insertRole" parameterType="SysRole" useGeneratedKeys="true" keyProperty="roleId"> <insert id="insertRole" parameterType="SysRole" useGeneratedKeys="true" keyProperty="roleId">
@@ -98,7 +98,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="roleId != null and roleId != 0">role_id,</if> <if test="roleId != null and roleId != 0">role_id,</if>
<if test="roleName != null and roleName != ''">role_name,</if> <if test="roleName != null and roleName != ''">role_name,</if>
<if test="roleKey != null and roleKey != ''">role_key,</if> <if test="roleKey != null and roleKey != ''">role_key,</if>
<if test="roleSort != null and roleSort != ''">role_sort,</if> <if test="roleSort != null">role_sort,</if>
<if test="dataScope != null and dataScope != ''">data_scope,</if> <if test="dataScope != null and dataScope != ''">data_scope,</if>
<if test="menuCheckStrictly != null">menu_check_strictly,</if> <if test="menuCheckStrictly != null">menu_check_strictly,</if>
<if test="deptCheckStrictly != null">dept_check_strictly,</if> <if test="deptCheckStrictly != null">dept_check_strictly,</if>
@@ -110,7 +110,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="roleId != null and roleId != 0">#{roleId},</if> <if test="roleId != null and roleId != 0">#{roleId},</if>
<if test="roleName != null and roleName != ''">#{roleName},</if> <if test="roleName != null and roleName != ''">#{roleName},</if>
<if test="roleKey != null and roleKey != ''">#{roleKey},</if> <if test="roleKey != null and roleKey != ''">#{roleKey},</if>
<if test="roleSort != null and roleSort != ''">#{roleSort},</if> <if test="roleSort != null">#{roleSort},</if>
<if test="dataScope != null and dataScope != ''">#{dataScope},</if> <if test="dataScope != null and dataScope != ''">#{dataScope},</if>
<if test="menuCheckStrictly != null">#{menuCheckStrictly},</if> <if test="menuCheckStrictly != null">#{menuCheckStrictly},</if>
<if test="deptCheckStrictly != null">#{deptCheckStrictly},</if> <if test="deptCheckStrictly != null">#{deptCheckStrictly},</if>
@@ -126,7 +126,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<set> <set>
<if test="roleName != null and roleName != ''">role_name = #{roleName},</if> <if test="roleName != null and roleName != ''">role_name = #{roleName},</if>
<if test="roleKey != null and roleKey != ''">role_key = #{roleKey},</if> <if test="roleKey != null and roleKey != ''">role_key = #{roleKey},</if>
<if test="roleSort != null and roleSort != ''">role_sort = #{roleSort},</if> <if test="roleSort != null">role_sort = #{roleSort},</if>
<if test="dataScope != null and dataScope != ''">data_scope = #{dataScope},</if> <if test="dataScope != null and dataScope != ''">data_scope = #{dataScope},</if>
<if test="menuCheckStrictly != null">menu_check_strictly = #{menuCheckStrictly},</if> <if test="menuCheckStrictly != null">menu_check_strictly = #{menuCheckStrictly},</if>
<if test="deptCheckStrictly != null">dept_check_strictly = #{deptCheckStrictly},</if> <if test="deptCheckStrictly != null">dept_check_strictly = #{deptCheckStrictly},</if>
@@ -139,7 +139,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</update> </update>
<delete id="deleteRoleById" parameterType="Long"> <delete id="deleteRoleById" parameterType="Long">
update sys_role set del_flag = '2' where role_id = #{roleId} update sys_role set del_flag = '2' where role_id = #{roleId}
</delete> </delete>
<delete id="deleteRoleByIds" parameterType="Long"> <delete id="deleteRoleByIds" parameterType="Long">
@@ -122,7 +122,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult"> <select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
<include refid="selectUserVo"/> <include refid="selectUserVo"/>
where u.user_name = #{userName} where u.user_name = #{userName} and u.del_flag = '0'
</select> </select>
<select id="selectUserById" parameterType="Long" resultMap="SysUserResult"> <select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
@@ -130,16 +130,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where u.user_id = #{userId} where u.user_id = #{userId}
</select> </select>
<select id="checkUserNameUnique" parameterType="String" resultType="int"> <select id="checkUserNameUnique" parameterType="String" resultMap="SysUserResult">
select count(1) from sys_user where user_name = #{userName} limit 1 select user_id, user_name from sys_user where user_name = #{userName} and del_flag = '0' limit 1
</select> </select>
<select id="checkPhoneUnique" parameterType="String" resultMap="SysUserResult"> <select id="checkPhoneUnique" parameterType="String" resultMap="SysUserResult">
select user_id, phonenumber from sys_user where phonenumber = #{phonenumber} limit 1 select user_id, phonenumber from sys_user where phonenumber = #{phonenumber} and del_flag = '0' limit 1
</select> </select>
<select id="checkEmailUnique" parameterType="String" resultMap="SysUserResult"> <select id="checkEmailUnique" parameterType="String" resultMap="SysUserResult">
select user_id, email from sys_user where email = #{email} limit 1 select user_id, email from sys_user where email = #{email} and del_flag = '0' limit 1
</select> </select>
<insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId"> <insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId">
@@ -208,7 +208,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</update> </update>
<delete id="deleteUserById" parameterType="Long"> <delete id="deleteUserById" parameterType="Long">
update sys_user set del_flag = '2' where user_id = #{userId} update sys_user set del_flag = '2' where user_id = #{userId}
</delete> </delete>
<delete id="deleteUserByIds" parameterType="Long"> <delete id="deleteUserByIds" parameterType="Long">
+4 -4
View File
@@ -1,6 +1,6 @@
{ {
"name": "ruoyi", "name": "ruoyi",
"version": "3.8.3", "version": "3.8.5",
"description": "若依管理系统", "description": "若依管理系统",
"author": "若依", "author": "若依",
"license": "MIT", "license": "MIT",
@@ -39,9 +39,9 @@
"@riophae/vue-treeselect": "0.4.0", "@riophae/vue-treeselect": "0.4.0",
"axios": "0.24.0", "axios": "0.24.0",
"clipboard": "2.0.8", "clipboard": "2.0.8",
"core-js": "3.19.1", "core-js": "3.25.3",
"echarts": "4.9.0", "echarts": "5.4.0",
"element-ui": "2.15.8", "element-ui": "2.15.10",
"file-saver": "2.0.5", "file-saver": "2.0.5",
"fuse.js": "6.4.3", "fuse.js": "6.4.3",
"highlight.js": "9.18.5", "highlight.js": "9.18.5",

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