72 Commits

Author SHA1 Message Date
9d02f8f7e7 若依 v4.7.6 2022-12-16 08:50:57 +08:00
70205922fc 优化代码 2022-12-13 15:45:13 +08:00
f3d1f0afe2 修改参数键名时移除前缓存配置 2022-12-13 15:09:38 +08:00
7ee6ad8aec 升级pagehelper到最新版1.4.6 2022-12-13 14:23:20 +08:00
4ff9afac23 升级oshi到最新版本6.4.0 2022-12-13 14:21:58 +08:00
167970e5c4 优化SQL关键字检查防止注入 2022-12-13 13:17:17 +08:00
29395be19a !432 优化deleteFile方法返回值,接受File.delete的false返回值
Merge pull request !432 from 岳林/master
2022-12-12 05:48:17 +00:00
da01f093f8 优化deleteFile方法返回值,接受File.delete的false返回值 2022-12-12 09:41:38 +08:00
f53515eb70 升级druid到最新版本1.2.15 2022-12-07 11:55:23 +08:00
84dde0dcf2 升级kaptcha到最新版2.3.3 2022-12-07 10:58:07 +08:00
df1c283335 定时任务违规的字符 2022-12-03 11:32:41 +08:00
faa4bfaef3 升级oshi到最新版本6.3.2 2022-12-01 11:49:25 +08:00
eef7ef6544 !426 升级shiro到最新版本1.10.1
Merge pull request !426 from Hacker/N/A
2022-11-25 11:05:20 +00:00
22d42048ab 升级shiro到最新版本1.10.1
Signed-off-by: Hacker <721806280@qq.com>
2022-11-24 07:31:40 +00:00
e5b905c455 优化用户管理重置时取消部门选择(I621OJ) 2022-11-21 13:39:09 +08:00
c64f027e66 兼容Excel下拉框内容过多无法显示的问题(I61HCG) 2022-11-21 11:13:02 +08:00
96934ca139 修复操作日志类型多选导出不生效问题(I617FW) 2022-11-15 13:30:43 +08:00
f4c763c84d 升级druid到最新版本1.2.14 2022-11-14 11:47:57 +08:00
8cd0d9f366 忽略不必要的属性数据返回 2022-11-12 11:57:08 +08:00
6a7f727f70 优化导出对象的子列表为空会出现[]问题(I60904) 2022-11-11 10:35:32 +08:00
62381f0472 修复sheet超出最大行数异常问题 2022-11-07 11:27:12 +08:00
2952337f15 !420 update ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/session/OnlineSessionFactory.java.
Merge pull request !420 from chenjh/N/A
2022-11-07 03:22:59 +00:00
c719be609a update ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/session/OnlineSessionFactory.java.
ServletUtils.getRequest()应改request,可能为空

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

View File

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

24
pom.xml
View File

@ -5,28 +5,27 @@
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>4.7.4</version>
<version>4.7.6</version>
<name>ruoyi</name>
<url>http://www.ruoyi.vip</url>
<description>若依管理系统</description>
<properties>
<ruoyi.version>4.7.4</ruoyi.version>
<ruoyi.version>4.7.6</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<shiro.version>1.9.0</shiro.version>
<shiro.version>1.10.1</shiro.version>
<thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
<druid.version>1.2.8</druid.version>
<druid.version>1.2.15</druid.version>
<bitwalker.version>1.21</bitwalker.version>
<kaptcha.version>2.3.2</kaptcha.version>
<kaptcha.version>2.3.3</kaptcha.version>
<swagger.version>3.0.0</swagger.version>
<mybatis-spring-boot.version>2.2.2</mybatis-spring-boot.version>
<pagehelper.boot.version>1.4.1</pagehelper.boot.version>
<pagehelper.boot.version>1.4.6</pagehelper.boot.version>
<fastjson.version>1.2.83</fastjson.version>
<oshi.version>6.1.6</oshi.version>
<oshi.version>6.4.0</oshi.version>
<commons.io.version>2.11.0</commons.io.version>
<commons.fileupload.version>1.4</commons.fileupload.version>
<poi.version>4.1.2</poi.version>
@ -55,7 +54,7 @@
<!-- 验证码 -->
<dependency>
<groupId>com.github.penggle</groupId>
<groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
@ -95,13 +94,6 @@
<version>${bitwalker.version}</version>
</dependency>
<!-- SpringBoot集成mybatis框架 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot.version}</version>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>

View File

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

View File

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

View File

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

View File

@ -17,7 +17,6 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysDeptService;
@ -166,24 +165,13 @@ public class SysDeptController extends BaseController
*/
@GetMapping(value = { "/selectDeptTree/{deptId}", "/selectDeptTree/{deptId}/{excludeId}" })
public String selectDeptTree(@PathVariable("deptId") Long deptId,
@PathVariable(value = "excludeId", required = false) String excludeId, ModelMap mmap)
@PathVariable(value = "excludeId", required = false) Long excludeId, ModelMap mmap)
{
mmap.put("dept", deptService.selectDeptById(deptId));
mmap.put("excludeId", excludeId);
return prefix + "/tree";
}
/**
* 加载部门列表树
*/
@GetMapping("/treeData")
@ResponseBody
public List<Ztree> treeData()
{
List<Ztree> ztrees = deptService.selectDeptTree(new SysDept());
return ztrees;
}
/**
* 加载部门列表树(排除下级)
*/
@ -196,15 +184,4 @@ public class SysDeptController extends BaseController
List<Ztree> ztrees = deptService.selectDeptTreeExcludeChild(dept);
return ztrees;
}
/**
* 加载角色部门(数据权限)列表树
*/
@GetMapping("/roleDeptTreeData")
@ResponseBody
public List<Ztree> deptTreeData(SysRole role)
{
List<Ztree> ztrees = deptService.roleDeptTreeData(role);
return ztrees;
}
}

View File

@ -63,11 +63,7 @@ public class SysProfileController extends BaseController
public boolean checkPassword(String password)
{
SysUser user = getSysUser();
if (passwordService.matches(user, password))
{
return true;
}
return false;
return passwordService.matches(user, password);
}
@GetMapping("/resetPwd")

View File

@ -15,6 +15,7 @@ import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
@ -22,6 +23,7 @@ import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
@ -42,6 +44,9 @@ public class SysRoleController extends BaseController
@Autowired
private ISysUserService userService;
@Autowired
private ISysDeptService deptService;
@RequiresPermissions("system:role:view")
@GetMapping()
public String role()
@ -303,4 +308,16 @@ public class SysRoleController extends BaseController
roleService.checkRoleDataScope(roleId);
return toAjax(roleService.insertAuthUsers(roleId, userIds));
}
/**
* 加载角色部门(数据权限)列表树
*/
@RequiresPermissions("system:role:edit")
@GetMapping("/deptTreeData")
@ResponseBody
public List<Ztree> deptTreeData(SysRole role)
{
List<Ztree> ztrees = deptService.roleDeptTreeData(role);
return ztrees;
}
}

View File

@ -18,6 +18,8 @@ import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
@ -28,6 +30,7 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
@ -48,6 +51,9 @@ public class SysUserController extends BaseController
@Autowired
private ISysRoleService roleService;
@Autowired
private ISysDeptService deptService;
@Autowired
private ISysPostService postService;
@ -124,7 +130,7 @@ public class SysUserController extends BaseController
@ResponseBody
public AjaxResult addSave(@Validated SysUser user)
{
if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user.getLoginName())))
if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user)))
{
return error("新增用户'" + user.getLoginName() + "'失败,登录账号已存在");
}
@ -170,7 +176,11 @@ public class SysUserController extends BaseController
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
if (StringUtils.isNotEmpty(user.getPhonenumber())
if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user)))
{
return error("修改用户'" + user.getLoginName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{
return error("修改用户'" + user.getLoginName() + "'失败,手机号码已存在");
@ -263,7 +273,7 @@ public class SysUserController extends BaseController
@ResponseBody
public String checkLoginNameUnique(SysUser user)
{
return userService.checkLoginNameUnique(user.getLoginName());
return userService.checkLoginNameUnique(user);
}
/**
@ -299,4 +309,29 @@ public class SysUserController extends BaseController
userService.checkUserDataScope(user.getUserId());
return toAjax(userService.changeStatus(user));
}
/**
* 加载部门列表树
*/
@RequiresPermissions("system:user:list")
@GetMapping("/deptTreeData")
@ResponseBody
public List<Ztree> deptTreeData()
{
List<Ztree> ztrees = deptService.selectDeptTree(new SysDept());
return ztrees;
}
/**
* 选择部门树
*
* @param deptId 部门ID
*/
@RequiresPermissions("system:user:list")
@GetMapping("/selectDeptTree/{deptId}")
public String selectDeptTree(@PathVariable("deptId") Long deptId, ModelMap mmap)
{
mmap.put("dept", deptService.selectDeptById(deptId));
return prefix + "/deptTree";
}
}

View File

@ -3,7 +3,7 @@ ruoyi:
# 名称
name: RuoYi
# 版本
version: 4.7.4
version: 4.7.6
# 版权年份
copyrightYear: 2022
# 实例演示开关

View File

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -187,6 +187,7 @@
success: function(data, textStatus, jqXHR) {
data = calculateObjectValue(options, options.responseHandler, [data], data);
renderTable(data);
calculateObjectValue(options, options.onLoadSuccess, [data], data);
},
error: function(xhr, textStatus) {
var _errorMsg = '<tr><td colspan="' + options.columns.length + '"><div style="display: block;text-align: center;">' + xhr.responseText + '</div></td></tr>'
@ -697,7 +698,8 @@
if (_ls && _ls.length > 0) {
$.each(_ls, function(index, item) {
var _p_icon = $("#" + $(item).attr("pid")).children().eq(options.expandColumn).find(".treetable-expander");
if (_p_icon.hasClass(options.expanderExpandedClass)) {
var _p_display = $("#" + $(item).attr("pid")).css('display');
if (_p_icon.hasClass(options.expanderExpandedClass) && _p_display == 'table') {
$(item).css("display", "table");
}
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -338,7 +338,7 @@ label.error {
.input-group label.error {
z-index:99;
right: 42px
right: 42px;
}
.input-group input.error + label.error + .input-group-addon>i {
@ -347,10 +347,14 @@ label.error {
.input-group.date label.error {
z-index:99;
right: 42px
right: 42px;
}
.Validform_error,input.error,textarea.error,select.error {
.select2-hidden-accessible + label.error {
right: 38px;
}
.Validform_error,input.error,textarea.error,select.error,label.error+.select2-container--bootstrap .select2-selection--single {
background-color: #fbe2e2;
border-color: #c66161;
color: #c00
@ -508,7 +512,7 @@ div.ztree-border {
left: calc(100% - 20px);
background-color: #33cabb
}
.toggle-switch.switch-solid span {
height: 20px;
}
@ -843,7 +847,7 @@ label {
.table-bordered table>thead>tr>th:first-child, .table-bordered table>tbody>tr>td:first-child {
border-left: 1px solid #ddd;
}
.table-bordered table>thead>tr>th:last-child, .table-bordered table>tbody>tr>td:last-child {
border-right: 1px solid #ddd;
}
@ -872,7 +876,7 @@ label {
background-color: #eff3f8;
}
.fixed-table-container thead th >.both{
.fixed-table-container thead th >.both{
display: inline-block
}
@ -1040,12 +1044,12 @@ table.rc-table-resizing thead > th > a {
}
/** 表格列拖拽样式 **/
.dragtable-sortable {
.dragtable-sortable {
list-style-type: none; margin: 0; padding: 0; -moz-user-select: none;
}
.dragtable-sortable li {
margin: 0; padding: 0; float: left; font-size: 1em; background: white;
margin: 0; padding: 0; float: left; font-size: 1em; background: white;
}
.dragtable-sortable th, .dragtable-sortable td{
@ -1053,26 +1057,26 @@ table.rc-table-resizing thead > th > a {
}
.dragtable-sortable li:first-child th, .dragtable-sortable li:first-child td {
border-left: 1px solid #CCC;
border-left: 1px solid #CCC;
}
.ui-sortable-helper {
opacity: 0.7;filter: alpha(opacity=70);
}
.ui-sortable-placeholder {
.ui-sortable-placeholder {
-moz-box-shadow: 4px 5px 4px #C6C6C6 inset;
-webkit-box-shadow: 4px 5px 4px #C6C6C6 inset;
box-shadow: 4px 5px 4px #C6C6C6 inset;
border-bottom: 1px solid #CCCCCC;
border-top: 1px solid #CCCCCC;
visibility: visible !important;
background: #EFEFEF !important;
background: #EFEFEF !important;
visibility: visible !important;
}
.ui-sortable-placeholder * {
opacity: 0.0; visibility: hidden;
.ui-sortable-placeholder * {
opacity: 0.0; visibility: hidden;
}
/** 表格选中样式 **/

View File

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

View File

@ -10,8 +10,8 @@ var table = {
options: {},
// 设置实例配置
set: function(id) {
if($.common.getLength(table.config) > 1 && $.common.isNotEmpty(event)) {
var tableId = $.common.isEmpty(id) ? $(event.currentTarget).parents(".bootstrap-table").find("table.table").attr("id") : id;
if ($.common.getLength(table.config) > 1 && $.common.isNotEmpty(event)) {
var tableId = $.common.isEmpty(id) ? $(event.currentTarget).parents(".bootstrap-table").find("table.table").attr("id") || $(event.currentTarget).parents(".bootstrap-tree-table").find("table.table").attr("id") : id;
if ($.common.isNotEmpty(tableId)) {
table.options = table.get(tableId);
}
@ -221,13 +221,13 @@ var table = {
if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) {
func = $.inArray(e.type, ['check', 'check-all']) > -1 ? 'union' : 'difference';
var selectedIds = table.rememberSelectedIds[table.options.id];
if($.common.isNotEmpty(selectedIds)) {
if ($.common.isNotEmpty(selectedIds)) {
table.rememberSelectedIds[table.options.id] = _[func](selectedIds, rowIds);
} else {
table.rememberSelectedIds[table.options.id] = _[func]([], rowIds);
}
var selectedRows = table.rememberSelecteds[table.options.id];
if($.common.isNotEmpty(selectedRows)) {
if ($.common.isNotEmpty(selectedRows)) {
table.rememberSelecteds[table.options.id] = _[func](selectedRows, rows);
} else {
table.rememberSelecteds[table.options.id] = _[func]([], rows);
@ -249,7 +249,7 @@ var table = {
$(optionsIds).off("click").on("click", '.img-circle', function() {
var src = $(this).attr('src');
var target = $(this).data('target');
if($.common.equals("self", target)) {
if ($.common.equals("self", target)) {
var height = $(this).data('height');
var width = $(this).data('width');
top.layer.open({
@ -363,7 +363,7 @@ var table = {
if ($.common.isNotEmpty(pageSize)) {
params.pageSize = pageSize;
}
if($.common.isNotEmpty(tableId)){
if ($.common.isNotEmpty(tableId)){
$("#" + tableId).bootstrapTable('refresh', params);
} else{
$("#" + table.options.id).bootstrapTable('refresh', params);
@ -493,7 +493,7 @@ var table = {
});
if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) {
var selectedRows = table.rememberSelecteds[table.options.id];
if($.common.isNotEmpty(selectedRows)) {
if ($.common.isNotEmpty(selectedRows)) {
rows = $.map(table.rememberSelecteds[table.options.id], function (row) {
return $.common.getItemField(row, column);
});
@ -522,7 +522,7 @@ var table = {
});
if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) {
var selectedRows = table.rememberSelecteds[table.options.id];
if($.common.isNotEmpty(selectedRows)) {
if ($.common.isNotEmpty(selectedRows)) {
rows = $.map(selectedRows, function (row) {
return $.common.getItemField(row, table.options.columns[1].field);
});
@ -812,7 +812,7 @@ var table = {
},
// 获取iframe页的DOM
getChildFrame: function (index) {
if($.common.isEmpty(index)){
if ($.common.isEmpty(index)){
var index = parent.layer.getFrameIndex(window.name);
return parent.layer.getChildFrame('body', index);
} else {
@ -821,7 +821,7 @@ var table = {
},
// 关闭窗体
close: function (index) {
if($.common.isEmpty(index)){
if ($.common.isEmpty(index)){
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
} else {
@ -883,6 +883,9 @@ var table = {
yes: callback,
cancel: function(index) {
return true;
},
success: function () {
$(':focus').blur();
}
});
},
@ -904,7 +907,7 @@ var table = {
}
}
var btnCallback = {};
if(options.btn instanceof Array){
if (options.btn instanceof Array){
for (var i = 1, len = options.btn.length; i < len; i++) {
var btn = options["btn" + (i + 1)];
if (btn) {
@ -929,6 +932,9 @@ var table = {
yes: options.yes,
cancel: function () {
return true;
},
success: function () {
$(':focus').blur();
}
}, btnCallback));
if ($.common.isNotEmpty(options.full) && options.full === true) {
@ -972,6 +978,9 @@ var table = {
},
cancel: function(index) {
return true;
},
success: function () {
$(':focus').blur();
}
});
top.layer.full(index);
@ -1086,7 +1095,7 @@ var table = {
table.set();
$.modal.confirm("确定删除该条" + table.options.modalName + "信息吗?", function() {
var url = $.common.isEmpty(id) ? table.options.removeUrl : table.options.removeUrl.replace("{id}", id);
if(table.options.type == table_type.bootstrapTreeTable) {
if (table.options.type == table_type.bootstrapTreeTable) {
$.operate.get(url);
} else {
var data = { "ids": id };
@ -1139,7 +1148,7 @@ var table = {
// 修改信息
edit: function(id) {
table.set();
if($.common.isEmpty(id) && table.options.type == table_type.bootstrapTreeTable) {
if ($.common.isEmpty(id) && table.options.type == table_type.bootstrapTreeTable) {
var row = $("#" + table.options.id).bootstrapTreeTable('getSelections')[0];
if ($.common.isEmpty(row)) {
$.modal.alertWarning("请至少选择一条记录");
@ -1163,7 +1172,7 @@ var table = {
if ($.common.isNotEmpty(id)) {
url = table.options.updateUrl.replace("{id}", id);
} else {
if(table.options.type == table_type.bootstrapTreeTable) {
if (table.options.type == table_type.bootstrapTreeTable) {
var row = $("#" + table.options.id).bootstrapTreeTable('getSelections')[0];
if ($.common.isEmpty(row)) {
$.modal.alertWarning("请至少选择一条记录");
@ -1289,7 +1298,7 @@ var table = {
successCallback: function(result) {
if (result.code == web_status.SUCCESS) {
var parent = activeWindow();
if($.common.isEmpty(parent.table)) {
if ($.common.isEmpty(parent.table)) {
$.modal.msgSuccessReload(result.msg);
} else if (parent.table.options.type == table_type.bootstrapTable) {
$.modal.close();
@ -1313,15 +1322,20 @@ var table = {
if (result.code == web_status.SUCCESS) {
var topWindow = $(window.parent.document);
var currentId = $('.page-tabs-content', topWindow).find('.active').attr('data-panel');
var $contentWindow = $('.RuoYi_iframe[data-id="' + currentId + '"]', topWindow)[0].contentWindow;
$.modal.close();
$contentWindow.$.modal.msgSuccess(result.msg);
$contentWindow.$(".layui-layer-padding").removeAttr("style");
if ($contentWindow.table.options.type == table_type.bootstrapTable) {
$contentWindow.$.table.refresh();
} else if ($contentWindow.table.options.type == table_type.bootstrapTreeTable) {
$contentWindow.$.treeTable.refresh();
var topWindow = $('.RuoYi_iframe[data-id="' + currentId + '"]', topWindow)[0];
if ($.common.isNotEmpty(topWindow) && $.common.isNotEmpty(currentId)) {
var $contentWindow = topWindow.contentWindow;
$contentWindow.$.modal.msgSuccess(result.msg);
$contentWindow.$(".layui-layer-padding").removeAttr("style");
if ($contentWindow.table.options.type == table_type.bootstrapTable) {
$contentWindow.$.table.refresh();
} else if ($contentWindow.table.options.type == table_type.bootstrapTreeTable) {
$contentWindow.$.treeTable.refresh();
}
} else {
$.modal.msgSuccess(result.msg);
}
$.modal.close();
$.modal.closeTab();
} else if (result.code == web_status.WARNING) {
$.modal.alertWarning(result.msg)
@ -1404,7 +1418,7 @@ var table = {
var node = tree.getNodesByParam("id", treeId, null)[0];
$.tree.selectByIdName(treeId, node);
// 回调tree方法
if(typeof(options.callBack) === "function"){
if (typeof(options.callBack) === "function"){
options.callBack(tree);
}
});
@ -1493,7 +1507,7 @@ var table = {
// 不允许根父节点选择
notAllowParents: function(_tree) {
var nodes = _tree.getSelectedNodes();
if(nodes.length == 0){
if (nodes.length == 0){
$.modal.msgError("请选择节点后提交");
return false;
}
@ -1681,7 +1695,7 @@ var table = {
formToJSON: function(formId) {
var json = {};
$.each($("#" + formId).serializeArray(), function(i, field) {
if(json[field.name]) {
if (json[field.name]) {
json[field.name] += ("," + field.value);
} else {
json[field.name] = field.value;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -79,7 +79,7 @@
<div class="ibox-content">
<p><i class="fa fa-send-o"></i> 官网:<a href="http://www.ruoyi.vip" target="_blank">http://www.ruoyi.vip</a>
</p>
<p><i class="fa fa-qq"></i> QQ群<s>满1389287</s> <s>满1679294</s> <s>满1529866</s> <s>满1772718</s> <s>满1366522</s> <s>满1382251</s> <s>满1145125</s> <s>满86752435</s> <s>满134072510</s> <s>满210336300</s> <s>满339522636</s> <s>满130035985</s> <s>满143151071</s> <s>满158781320</s> <s>满201531282</s> <s>满101526938</s> <s>满264355400</s> <s>满298522656</s> <s>满139845794</s> <a href="https://jq.qq.com/?_wv=1027&k=p86p2AJX" target="_blank">213650505</a>
<p><i class="fa fa-qq"></i> QQ群<s>满1389287</s> <s>满1679294</s> <s>满1529866</s> <s>满1772718</s> <s>满1366522</s> <s>满1382251</s> <s>满1145125</s> <s>满86752435</s> <s>满134072510</s> <s>满210336300</s> <s>满339522636</s> <s>满130035985</s> <s>满143151071</s> <s>满158781320</s> <s>满201531282</s> <s>满101526938</s> <s>满264355400</s> <s>满298522656</s> <s>满139845794</s> <a href="https://jq.qq.com/?_wv=1027&k=Cqd66IKe" target="_blank">185760789</a>
</p>
<p><i class="fa fa-weixin"></i> 微信:<a href="javascript:;">/ *若依</a>
</p>
@ -96,13 +96,90 @@
<div class="ibox-content no-padding">
<div class="panel-body">
<div class="panel-group" id="version">
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v476">v4.7.6</a><code class="pull-right">2022.12.16</code>
</h5>
</div>
<div id="v476" class="panel-collapse collapse in">
<div class="panel-body">
<ol>
<li>定时任务违规的字符</li>
<li>忽略不必要的属性数据返回</li>
<li>导入更新用户数据前校验数据权限</li>
<li>修改参数键名时移除前缓存配置</li>
<li>修改用户登录账号进行重复验证</li>
<li>兼容Excel下拉框内容过多无法显示</li>
<li>升级oshi到最新版本6.4.0</li>
<li>升级kaptcha到最新版2.3.3</li>
<li>升级druid到最新版本1.2.15</li>
<li>升级shiro到最新版本1.10.1</li>
<li>升级pagehelper到最新版1.4.6</li>
<li>升级bootstrap-fileinput到最新版本5.5.2</li>
<li>修复sheet超出最大行数异常问题</li>
<li>修复关闭父页签后提交无法跳转的问题</li>
<li>修复操作日志类型多选导出不生效问题</li>
<li>修复导出包含空子列表数据异常的问题</li>
<li>优化树形表格层级显示</li>
<li>优化SQL关键字检查防止注入</li>
<li>优化用户管理重置时取消部门选择</li>
<li>优化代码生成同步后字典值NULL问题</li>
<li>优化导出对象的子列表为空会出现[]问题</li>
<li>优化select2搜索下拉后校验必填样式问题</li>
<li>其他细节优化</li>
</ol>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v475">v4.7.5</a><code class="pull-right">2022.09.05</code>
</h5>
</div>
<div id="v475" class="panel-collapse collapse">
<div class="panel-body">
<ol>
<li>Excel支持导出对象的子列表方法</li>
<li>数据逻辑删除不进行唯一验证</li>
<li>优化多角色数据权限匹配规则</li>
<li>新增主子表提交校验示例</li>
<li>支持自定义隐藏Excel属性列</li>
<li>Excel注解支持backgroundColor属性设置背景颜色</li>
<li>菜单配置刷新时Tab页签切换时刷新</li>
<li>增加对AjaxResult消息结果类型的判断</li>
<li>新增示例(进度条)</li>
<li>新增内容编码/解码方便插件集成使用</li>
<li>升级jquery到最新版3.6.1</li>
<li>升级layui到最新版本2.7.5</li>
<li>升级shiro到最新版本1.9.1</li>
<li>升级druid到最新版本1.2.11</li>
<li>升级pagehelper到最新版1.4.3</li>
<li>升级oshi到最新版本6.2.2</li>
<li>修复树表onLoadSuccess不生效的问题</li>
<li>修复用户分配角色大于默认页数丢失问题</li>
<li>定时任务支持执行父类方法</li>
<li>自动设置切换多个树表格实例配置</li>
<li>页签创建标题优先data-title属性</li>
<li>优化任务过期不执行调度</li>
<li>优化横向菜单下激活菜单样式</li>
<li>优化按钮打开窗口后按回车反复弹出</li>
<li>优化excel/scale属性导出单元格数值类型</li>
<li>优化druid开启wall过滤器出现的异常问题</li>
<li>优化多个相同角色数据导致权限SQL重复问题</li>
<li>其他细节优化</li>
</ol>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v474">v4.7.4</a><code class="pull-right">2022.06.01</code>
</h5>
</div>
<div id="v474" class="panel-collapse collapse in">
<div id="v474" class="panel-collapse collapse">
<div class="panel-body">
<ol>
<li>用户头像上传图片格式限制</li>

View File

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

View File

@ -18,7 +18,7 @@
<label>操作人员: </label><input type="text" name="operName"/>
</li>
<li class="select-selectpicker">
<label>操作类型: </label><select id="businessTypes" th:with="type=${@dict.getType('sys_oper_type')}" class="selectpicker" data-none-selected-text="请选择" multiple>
<label>操作类型: </label><select id="businessTypes" name="businessTypes" th:with="type=${@dict.getType('sys_oper_type')}" class="selectpicker" data-none-selected-text="请选择" multiple>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>

View File

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

View File

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

View File

@ -116,7 +116,7 @@
var options = {
title: '部门选择',
width: "380",
url: prefix + "/selectDeptTree/" + treeId,
url: prefix + "/selectDeptTree/" + treeId + "/0",
callBack: doSubmit
};
$.modal.openOptions(options);

View File

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

View File

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

View File

@ -239,7 +239,7 @@
function selectDeptTree() {
var treeId = $("#treeId").val();
var deptId = $.common.isEmpty(treeId) ? "100" : $("#treeId").val();
var url = ctx + "system/dept/selectDeptTree/" + deptId;
var url = ctx + "system/user/selectDeptTree/" + deptId;
var options = {
title: '选择部门',
width: "380",
@ -250,7 +250,6 @@
}
function doSubmit(index, layero){
var tree = layero.find("iframe")[0].contentWindow.$._tree;
var body = $.modal.getChildFrame(index);
$("#treeId").val(body.find('#treeId').val());
$("#treeName").val(body.find('#treeName').val());

View File

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

View File

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

View File

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

View File

@ -54,7 +54,7 @@
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="resetPre()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
@ -191,7 +191,7 @@
function queryDeptTree()
{
var url = ctx + "system/dept/treeData";
var url = ctx + "system/user/deptTreeData";
var options = {
url: url,
expandLevel: 2,
@ -221,6 +221,15 @@
$('#btnRefresh').click(function() {
queryDeptTree();
});
/* 自定义重置-表单重置/隐藏框/树节点选择色/搜索 */
function resetPre() {
$("#user-form")[0].reset();
$("#deptId").val("");
$("#parentId").val("");
$(".curSelectedNode").removeClass("curSelectedNode");
$.table.search();
}
/* 用户管理-部门 */
function dept() {

View File

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

View File

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

View File

@ -88,6 +88,11 @@ public @interface Excel
*/
public String[] combo() default {};
/**
* 是否需要纵向合并单元格,应对需求:含有list集合单元格)
*/
public boolean needMerge() default false;
/**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
*/
@ -102,14 +107,29 @@ public @interface Excel
* 是否自动统计数据,在最后追加一行统计数据总和
*/
public boolean isStatistics() default false;
/**
* 导出类型0数字 1字符串
* 导出类型0数字 1字符串 2图片
*/
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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -324,6 +324,32 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
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;
}
}
/**
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
*

View File

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

View File

@ -102,8 +102,8 @@ public class FileUploadUtils
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
InvalidExtensionException
{
int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
int fileNameLength = Objects.requireNonNull(file.getOriginalFilename()).length();
if (fileNameLength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
{
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
}

View File

@ -116,8 +116,7 @@ public class FileUtils
// 路径为文件且不为空则进行删除
if (file.isFile() && file.exists())
{
file.delete();
flag = true;
flag = file.delete();
}
return flag;
}

View File

@ -7,12 +7,14 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
@ -22,7 +24,9 @@ import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
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.HSSFPicture;
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.HorizontalAlignment;
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.Row;
import org.apache.poi.ss.usermodel.Sheet;
@ -148,6 +153,26 @@ public class ExcelUtil<T>
*/
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 String[] excludeFields;
public ExcelUtil(Class<T> 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)
{
if (list == null)
@ -181,6 +222,7 @@ public class ExcelUtil<T>
createExcelField();
createWorkbook();
createTitle();
createSubHead();
}
/**
@ -190,13 +232,48 @@ public class ExcelUtil<T>
{
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);
titleRow.setHeightInPoints(30);
Cell titleCell = titleRow.createCell(0);
titleCell.setCellStyle(styles.get("title"));
titleCell.setCellValue(title);
sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(),
this.fields.size() - 1));
sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol));
}
}
/**
* 创建对象的子列表名称
*/
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)
{
Field field = (Field) os[0];
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))
{
@ -593,21 +682,67 @@ public class ExcelUtil<T>
* @param index 序号
* @param row 单元格行
*/
@SuppressWarnings("unchecked")
public void fillExcelData(int index, Row row)
{
int startNo = index * sheetSize;
int endNo = Math.min(startNo + sheetSize, list.size());
int rowNo = (1 + rownum) - startNo;
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);
Collection<?> subList = null;
if (isSubList())
{
if (isSubListValue(vo))
{
subList = getListCellValue(vo);
subMergedLastRowNum = subMergedLastRowNum + subList.size();
}
else
{
subMergedFirstRowNum++;
subMergedLastRowNum++;
}
}
int column = 0;
for (Object[] os : fields)
{
Field field = (Field) os[0];
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);
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.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
@ -672,28 +793,62 @@ public class ExcelUtil<T>
style.setFont(totalFont);
styles.put("total", style);
styles.putAll(annotationStyles(wb));
styles.putAll(annotationHeaderStyles(wb, styles));
styles.putAll(annotationDataStyles(wb));
return styles;
}
/**
* 根据Excel注解创建表格样式
* 根据Excel注解创建表格样式
*
* @param wb 工作薄对象
* @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>();
for (Object[] os : fields)
{
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))
{
CellStyle style = wb.createCellStyle();
style = wb.createCellStyle();
style.setAlignment(excel.align());
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderRight(BorderStyle.THIN);
@ -704,6 +859,8 @@ public class ExcelUtil<T>
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderBottom(BorderStyle.THIN);
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillForegroundColor(excel.backgroundColor().getIndex());
Font dataFont = wb.createFont();
dataFont.setFontName("Arial");
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.setCellValue(attr.name());
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;
}
@ -746,6 +912,10 @@ public class ExcelUtil<T>
{
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());
}
else if (ColumnType.NUMERIC == attr.cellType())
@ -813,8 +983,16 @@ public class ExcelUtil<T>
}
if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0)
{
// 提示信息或只能选择不能输入的列内容.
setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);
if (attr.combo().length > 15 || StringUtils.join(attr.combo()).length() > 255)
{
// 如果下拉数大于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 = 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);
@ -855,7 +1038,7 @@ public class ExcelUtil<T>
}
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))
{
@ -913,6 +1096,58 @@ public class ExcelUtil<T>
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=未知
*
@ -928,7 +1163,7 @@ public class ExcelUtil<T>
for (String item : convertSource)
{
String[] itemArray = item.split("=");
if (StringUtils.containsAny(separator, propertyValue))
if (StringUtils.containsAny(propertyValue, separator))
{
for (String value : propertyValue.split(separator))
{
@ -965,7 +1200,7 @@ public class ExcelUtil<T>
for (String item : convertSource)
{
String[] itemArray = item.split("=");
if (StringUtils.containsAny(separator, propertyValue))
if (StringUtils.containsAny(propertyValue, separator))
{
for (String value : propertyValue.split(separator))
{
@ -1178,29 +1413,39 @@ public class ExcelUtil<T>
tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
for (Field field : tempFields)
{
// 单注解
if (field.isAnnotationPresent(Excel.class))
if (!ArrayUtils.contains(this.excludeFields, field.getName()))
{
Excel attr = field.getAnnotation(Excel.class);
if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
{
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)
// 单注解
if (field.isAnnotationPresent(Excel.class))
{
Excel attr = field.getAnnotation(Excel.class);
if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
{
field.setAccessible(true);
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;
}
/**
* 是否有对象的子列表
*/
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;
}
}

View File

@ -13,7 +13,7 @@ public class SqlUtil
/**
* 定义常用的 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()";
/**
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.7.4</version>
<version>4.7.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -17,8 +17,8 @@
<dependencies>
<!-- SpringBoot Web容器 -->
<dependency>
<!-- SpringBoot Web容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
@ -37,7 +37,7 @@
<!-- 验证码 -->
<dependency>
<groupId>com.github.penggle</groupId>
<groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId>
<exclusions>
<exclusion>

View File

@ -1,13 +1,17 @@
package com.ruoyi.framework.aspectj;
import java.util.ArrayList;
import java.util.List;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.context.PermissionContextHolder;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
@ -66,8 +70,9 @@ public class DataScopeAspect
// 如果是超级管理员,则不过滤数据
if (!currentUser.isAdmin())
{
String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext());
dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
controllerDataScope.userAlias());
controllerDataScope.userAlias(), permission);
}
}
}
@ -79,14 +84,25 @@ public class DataScopeAspect
* @param user 用户
* @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();
List<String> conditions = new ArrayList<String>();
for (SysRole role : user.getRoles())
{
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))
{
sqlString = new StringBuilder();
@ -117,9 +133,10 @@ public class DataScopeAspect
else
{
// 数据权限为仅本人且没有userAlias别名不查询任何数据
sqlString.append(" OR 1=0 ");
sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
}
}
conditions.add(dataScope);
}
if (StringUtils.isNotBlank(sqlString.toString()))

View File

@ -82,7 +82,7 @@ public class LogAspect
// 请求的地址
String ip = ShiroUtils.getIp();
operLog.setOperIp(ip);
operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
if (currentUser != null)
{
operLog.setOperName(currentUser.getLoginName());

View File

@ -0,0 +1,30 @@
package com.ruoyi.framework.aspectj;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.context.PermissionContextHolder;
import com.ruoyi.common.utils.StringUtils;
/**
* 自定义权限拦截器,将权限字符串放到当前请求中以便用于多个角色匹配符合要求的权限
*
* @author ruoyi
*/
@Aspect
@Component
public class PermissionsAspect
{
@Before("@annotation(controllerRequiresPermissions)")
public void doBefore(JoinPoint point, RequiresPermissions controllerRequiresPermissions) throws Throwable
{
handleRequiresPermissions(point, controllerRequiresPermissions);
}
protected void handleRequiresPermissions(final JoinPoint joinPoint, RequiresPermissions requiresPermissions)
{
PermissionContextHolder.setContext(StringUtils.join(requiresPermissions.value(), ","));
}
}

View File

@ -1,10 +1,13 @@
package com.ruoyi.framework.shiro.service;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.ShiroConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.exception.user.CaptchaException;
@ -19,6 +22,7 @@ import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.system.service.ISysUserService;
/**
@ -35,6 +39,9 @@ public class SysLoginService
@Autowired
private ISysUserService userService;
@Autowired
private ISysMenuService menuService;
/**
* 登录
*/
@ -104,6 +111,7 @@ public class SysLoginService
passwordService.validate(user, password);
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
setRolePermission(user);
recordLoginInfo(user.getUserId());
return user;
}
@ -128,6 +136,25 @@ public class SysLoginService
}
*/
/**
* 设置角色权限
*
* @param user 用户信息
*/
public void setRolePermission(SysUser user)
{
List<SysRole> roles = user.getRoles();
if (!roles.isEmpty() && roles.size() > 1)
{
// 多角色设置permissions属性以便数据权限匹配权限
for (SysRole role : roles)
{
Set<String> rolePerms = menuService.selectPermsByRoleId(role.getRoleId());
role.setPermissions(rolePerms);
}
}
}
/**
* 记录登录信息
*

View File

@ -58,7 +58,7 @@ public class SysRegisterService
{
msg = "账户长度必须在2到20个字符之间";
}
else if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(loginName)))
else if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user)))
{
msg = "保存用户'" + loginName + "'失败,注册账号已存在";
}
@ -67,7 +67,7 @@ public class SysRegisterService
user.setPwdUpdateDate(DateUtils.getNowDate());
user.setUserName(loginName);
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
user.setPassword(passwordService.encryptPassword(loginName, password, user.getSalt()));
boolean regFlag = userService.registerUser(user);
if (!regFlag)
{

View File

@ -7,7 +7,6 @@ import org.apache.shiro.session.mgt.SessionFactory;
import org.apache.shiro.web.session.mgt.WebSessionContext;
import org.springframework.stereotype.Component;
import com.ruoyi.common.utils.IpUtils;
import com.ruoyi.common.utils.ServletUtils;
import eu.bitwalker.useragentutils.UserAgent;
/**
@ -28,7 +27,7 @@ public class OnlineSessionFactory implements SessionFactory
HttpServletRequest request = (HttpServletRequest) sessionContext.getServletRequest();
if (request != null)
{
UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
// 获取客户端操作系统
String os = userAgent.getOperatingSystem().getName();
// 获取客户端浏览器

View File

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

View File

@ -222,7 +222,7 @@ public class GenController extends BaseController
catch (Exception e)
{
logger.error(e.getMessage(), e);
return AjaxResult.error("创建表结构异常[" + e.getMessage() + "]");
return AjaxResult.error("创建表结构异常");
}
}

View File

@ -63,7 +63,7 @@ public class GenTableColumn extends BaseEntity
private String htmlType;
/** 字典类型 */
private String dictType;
private String dictType = "";
/** 排序 */
private Integer sort;

View File

@ -130,9 +130,9 @@ public class GenTableServiceImpl implements IGenTableService
int row = genTableMapper.updateGenTable(genTable);
if (row > 0)
{
for (GenTableColumn cenTableColumn : genTable.getColumns())
for (GenTableColumn genTableColumn : genTable.getColumns())
{
genTableColumnMapper.updateGenTableColumn(cenTableColumn);
genTableColumnMapper.updateGenTableColumn(genTableColumn);
}
}
}

View File

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

View File

@ -111,8 +111,8 @@ public class SysJobController extends BaseController
@ResponseBody
public AjaxResult run(SysJob job) throws SchedulerException
{
jobService.run(job);
return success();
boolean result = jobService.run(job);
return result ? success() : error("任务不存在或已过期!");
}
/**

View File

@ -74,7 +74,7 @@ public interface ISysJobService
* @param job 调度信息
* @return 结果
*/
public void run(SysJob job) throws SchedulerException;
public boolean run(SysJob job) throws SchedulerException;
/**
* 新增任务

View File

@ -177,14 +177,21 @@ public class SysJobServiceImpl implements ISysJobService
*/
@Override
@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();
SysJob tmpObj = selectJobById(job.getJobId());
// 参数
JobDataMap dataMap = new JobDataMap();
dataMap.put(ScheduleConstants.TASK_PROPERTIES, tmpObj);
scheduler.triggerJob(ScheduleUtils.getJobKey(jobId, tmpObj.getJobGroup()), dataMap);
JobKey jobKey = ScheduleUtils.getJobKey(jobId, tmpObj.getJobGroup());
if (scheduler.checkExists(jobKey))
{
result = true;
scheduler.triggerJob(jobKey, dataMap);
}
return result;
}
/**

View File

@ -66,7 +66,7 @@ public abstract class AbstractQuartzJob implements Job
* 执行后
*
* @param context 工作执行上下文对象
* @param sysScheduleJob 系统计划任务
* @param sysJob 系统计划任务
*/
protected void after(JobExecutionContext context, SysJob sysJob, Exception e)
{

View File

@ -52,12 +52,12 @@ public class JobInvokeUtil
{
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));
}
else
{
Method method = bean.getClass().getDeclaredMethod(methodName);
Method method = bean.getClass().getMethod(methodName);
method.invoke(bean);
}
}

View File

@ -83,7 +83,12 @@ public class ScheduleUtils
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()))

View File

@ -1131,7 +1131,7 @@
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.4}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.6}"></script>
<script th:src="@{/js/cron.js}"></script>
<script th:inline="javascript">
var prefix = [[@{/}]] + "monitor/job";

View File

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

View File

@ -18,6 +18,14 @@ public interface SysConfigMapper
*/
public SysConfig selectConfig(SysConfig config);
/**
* 通过ID查询配置
*
* @param configId 参数ID
* @return 参数配置信息
*/
public SysConfig selectConfigById(Long configId);
/**
* 查询参数配置列表
*

View File

@ -12,7 +12,7 @@ import com.ruoyi.common.core.domain.entity.SysDept;
public interface SysDeptMapper
{
/**
* 查询部门人数
* 查询下级部门数量
*
* @param dept 部门信息
* @return 结果

View File

@ -49,6 +49,14 @@ public interface SysMenuMapper
*/
public List<String> selectPermsByUserId(Long userId);
/**
* 根据角色ID查询权限
*
* @param roleId 角色ID
* @return 权限列表
*/
public List<String> selectPermsByRoleId(Long roleId);
/**
* 根据角色ID查询菜单
*

View File

@ -104,7 +104,7 @@ public interface SysUserMapper
* @param loginName 登录名称
* @return 结果
*/
public int checkLoginNameUnique(String loginName);
public SysUser checkLoginNameUnique(String loginName);
/**
* 校验手机号码是否唯一

View File

@ -45,7 +45,7 @@ public interface ISysDeptService
public List<Ztree> roleDeptTreeData(SysRole role);
/**
* 查询部门人数
* 根据父部门ID查询下级部门数量
*
* @param parentId 父部门ID
* @return 结果

View File

@ -48,6 +48,14 @@ public interface ISysMenuService
*/
public Set<String> selectPermsByUserId(Long userId);
/**
* 根据角色ID查询权限
*
* @param roleId 角色ID
* @return 权限列表
*/
public Set<String> selectPermsByRoleId(Long roleId);
/**
* 根据角色ID查询菜单
*

View File

@ -143,10 +143,10 @@ public interface ISysUserService
/**
* 校验用户名称是否唯一
*
* @param loginName 登录名称
* @param user 用户信息
* @return 结果
*/
public String checkLoginNameUnique(String loginName);
public String checkLoginNameUnique(SysUser user);
/**
* 校验手机号码是否唯一

View File

@ -111,6 +111,12 @@ public class SysConfigServiceImpl implements ISysConfigService
@Override
public int updateConfig(SysConfig config)
{
SysConfig temp = configMapper.selectConfigById(config.getConfigId());
if (!StringUtils.equals(temp.getConfigKey(), config.getConfigKey()))
{
CacheUtils.remove(getCacheName(), getCacheKey(temp.getConfigKey()));
}
int row = configMapper.updateConfig(config);
if (row > 0)
{

View File

@ -1,7 +1,6 @@
package com.ruoyi.system.service.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -71,18 +70,12 @@ public class SysDeptServiceImpl implements ISysDeptService
public List<Ztree> selectDeptTreeExcludeChild(SysDept dept)
{
Long excludeId = dept.getExcludeId();
List<SysDept> deptList = deptMapper.selectDeptList(dept);
Iterator<SysDept> it = deptList.iterator();
while (it.hasNext())
List<SysDept> depts = deptMapper.selectDeptList(dept);
if (excludeId.intValue() > 0)
{
SysDept d = (SysDept) it.next();
if (d.getDeptId().intValue() == excludeId
|| ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), excludeId + ""))
{
it.remove();
}
depts.removeIf(d -> d.getDeptId().intValue() == excludeId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), excludeId + ""));
}
List<Ztree> ztrees = initZtree(deptList);
List<Ztree> ztrees = initZtree(depts);
return ztrees;
}
@ -97,7 +90,7 @@ public class SysDeptServiceImpl implements ISysDeptService
{
Long roleId = role.getRoleId();
List<Ztree> ztrees = new ArrayList<Ztree>();
List<SysDept> deptList = selectDeptList(new SysDept());
List<SysDept> deptList = SpringUtils.getAopProxy(this).selectDeptList(new SysDept());
if (StringUtils.isNotNull(roleId))
{
List<String> roleDeptList = deptMapper.selectRoleDeptTree(roleId);
@ -153,7 +146,7 @@ public class SysDeptServiceImpl implements ISysDeptService
}
/**
* 查询部门人数
* 根据父部门ID查询下级部门数量
*
* @param parentId 部门ID
* @return 结果

View File

@ -121,6 +121,27 @@ public class SysMenuServiceImpl implements ISysMenuService
return permsSet;
}
/**
* 根据角色ID查询权限
*
* @param roleId 角色ID
* @return 权限列表
*/
@Override
public Set<String> selectPermsByRoleId(Long roleId)
{
List<String> perms = menuMapper.selectPermsByRoleId(roleId);
Set<String> permsSet = new HashSet<>();
for (String perm : perms)
{
if (StringUtils.isNotEmpty(perm))
{
permsSet.addAll(Arrays.asList(perm.trim().split(",")));
}
}
return permsSet;
}
/**
* 根据角色ID查询菜单
*

View File

@ -347,16 +347,17 @@ public class SysUserServiceImpl implements ISysUserService
}
/**
* 校验登录名称是否唯一
* 校验用户名称是否唯一
*
* @param loginName 用户
* @return
* @param user 用户信息
* @return 结果
*/
@Override
public String checkLoginNameUnique(String loginName)
public String checkLoginNameUnique(SysUser user)
{
int count = userMapper.checkLoginNameUnique(loginName);
if (count > 0)
Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
SysUser info = userMapper.checkLoginNameUnique(user.getLoginName());
if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue())
{
return UserConstants.USER_NAME_NOT_UNIQUE;
}
@ -505,6 +506,8 @@ public class SysUserServiceImpl implements ISysUserService
else if (isUpdateSupport)
{
BeanValidators.validateWithException(validator, user);
checkUserAllowed(user);
checkUserDataScope(user.getUserId());
user.setUpdateBy(operName);
this.updateUser(user);
successNum++;

View File

@ -59,6 +59,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where>
</select>
<select id="selectConfigById" parameterType="Long" resultMap="SysConfigResult">
<include refid="selectConfigVo"/>
where config_id = #{configId}
</select>
<select id="checkConfigKeyUnique" parameterType="String" resultMap="SysConfigResult">
<include refid="selectConfigVo"/>
where config_key = #{configKey} limit 1

View File

@ -68,7 +68,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="checkDeptNameUnique" resultMap="SysDeptResult">
<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 id="selectDeptById" parameterType="Long" resultMap="SysDeptResult">

View File

@ -70,6 +70,13 @@
where m.visible = '0' and r.status = '0' and ur.user_id = #{userId}
</select>
<select id="selectPermsByRoleId" 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.visible = '0' and rm.role_id = #{roleId}
</select>
<select id="selectMenuTree" parameterType="Long" resultType="String">
select concat(m.menu_id, ifnull(m.perms,'')) as perms
from sys_menu m

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