Compare commits
72 Commits
Author | SHA1 | Date | |
---|---|---|---|
9d02f8f7e7 | |||
70205922fc | |||
f3d1f0afe2 | |||
7ee6ad8aec | |||
4ff9afac23 | |||
167970e5c4 | |||
29395be19a | |||
da01f093f8 | |||
f53515eb70 | |||
84dde0dcf2 | |||
df1c283335 | |||
faa4bfaef3 | |||
eef7ef6544 | |||
22d42048ab | |||
e5b905c455 | |||
c64f027e66 | |||
96934ca139 | |||
f4c763c84d | |||
8cd0d9f366 | |||
6a7f727f70 | |||
62381f0472 | |||
2952337f15 | |||
c719be609a | |||
6253e41658 | |||
bd0e574268 | |||
6e176c807c | |||
2bdf12b1e1 | |||
67f2ba2aa9 | |||
c105f44eb9 | |||
e23a6919af | |||
b362e58646 | |||
db3e571af0 | |||
52fe19e933 | |||
7b3ab45ecc | |||
e337f685bc | |||
13287e02eb | |||
d4a33eab94 | |||
0ca327f538 | |||
31bd27fcf0 | |||
dcfc062c01 | |||
daa8286804 | |||
5a3714e9bc | |||
abe1f0d63e | |||
c95cb70af3 | |||
47bd3c4c10 | |||
1c8f55c2c1 | |||
0f9558a825 | |||
8a4d37e975 | |||
7fbabe1a8e | |||
53cd4867df | |||
7aa4872cb9 | |||
8fcc548d34 | |||
d318b719fc | |||
d6db5963d5 | |||
d5f4bba084 | |||
960dee7756 | |||
08f775da4b | |||
2a0fcdea21 | |||
3f0a34e20f | |||
289161b8c6 | |||
47b51fe965 | |||
0c0efc9455 | |||
dd86447176 | |||
3427223da2 | |||
1959b02220 | |||
acf8ea428f | |||
6e476e40af | |||
25d07b11cc | |||
36013e6139 | |||
87d3c9a93c | |||
d1b3f4f397 | |||
5c5961f1b4 |
@ -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群: [](https://jq.qq.com/?_wv=1027&k=5HBAaYN) [](https://jq.qq.com/?_wv=1027&k=5cHeRVW) [](https://jq.qq.com/?_wv=1027&k=53R0L5Z) [](https://jq.qq.com/?_wv=1027&k=5g75dCU) [](https://jq.qq.com/?_wv=1027&k=58cPoHA) [](https://jq.qq.com/?_wv=1027&k=5Ofd4Pb) [](https://jq.qq.com/?_wv=1027&k=5yugASz) [](https://jq.qq.com/?_wv=1027&k=5Rf3d2P) [](https://jq.qq.com/?_wv=1027&k=5ZIjaeP) [](https://jq.qq.com/?_wv=1027&k=5CJw1jY) [](https://jq.qq.com/?_wv=1027&k=5omzbKc) [](https://jq.qq.com/?_wv=1027&k=qPIKBb7s) [](https://jq.qq.com/?_wv=1027&k=4NsjKbtU) [](https://jq.qq.com/?_wv=1027&k=VD2pkz2G) [](https://jq.qq.com/?_wv=1027&k=HlshFwkJ) [](https://jq.qq.com/?_wv=1027&k=0ARRrO9V) [](https://jq.qq.com/?_wv=1027&k=up9k3ZXJ) [](https://jq.qq.com/?_wv=1027&k=540WfdEr) [](https://jq.qq.com/?_wv=1027&k=ss91fC4t) [](https://jq.qq.com/?_wv=1027&k=uUQpdY7J)
|
||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=5HBAaYN) [](https://jq.qq.com/?_wv=1027&k=5cHeRVW) [](https://jq.qq.com/?_wv=1027&k=53R0L5Z) [](https://jq.qq.com/?_wv=1027&k=5g75dCU) [](https://jq.qq.com/?_wv=1027&k=58cPoHA) [](https://jq.qq.com/?_wv=1027&k=5Ofd4Pb) [](https://jq.qq.com/?_wv=1027&k=5yugASz) [](https://jq.qq.com/?_wv=1027&k=5Rf3d2P) [](https://jq.qq.com/?_wv=1027&k=5ZIjaeP) [](https://jq.qq.com/?_wv=1027&k=5CJw1jY) [](https://jq.qq.com/?_wv=1027&k=5omzbKc) [](https://jq.qq.com/?_wv=1027&k=qPIKBb7s) [](https://jq.qq.com/?_wv=1027&k=4NsjKbtU) [](https://jq.qq.com/?_wv=1027&k=VD2pkz2G) [](https://jq.qq.com/?_wv=1027&k=HlshFwkJ) [](https://jq.qq.com/?_wv=1027&k=0ARRrO9V) [](https://jq.qq.com/?_wv=1027&k=up9k3ZXJ) [](https://jq.qq.com/?_wv=1027&k=540WfdEr) [](https://jq.qq.com/?_wv=1027&k=ss91fC4t) [](https://jq.qq.com/?_wv=1027&k=Cqd66IKe)
|
24
pom.xml
24
pom.xml
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -62,6 +62,15 @@ public class DemoFormController
|
||||
return prefix + "/timeline";
|
||||
}
|
||||
|
||||
/**
|
||||
* 进度条
|
||||
*/
|
||||
@GetMapping("/progress_bars")
|
||||
public String progress_bars()
|
||||
{
|
||||
return prefix + "/progress_bars";
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单校验
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ ruoyi:
|
||||
# 名称
|
||||
name: RuoYi
|
||||
# 版本
|
||||
version: 4.7.4
|
||||
version: 4.7.6
|
||||
# 版权年份
|
||||
copyrightYear: 2022
|
||||
# 实例演示开关
|
||||
|
@ -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 it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -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;
|
||||
}
|
||||
|
||||
/** 表格选中样式 **/
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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>
|
@ -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>
|
||||
|
@ -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: {
|
||||
|
@ -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({
|
||||
|
@ -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双列表框插件 -->
|
||||
|
@ -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>
|
||||
|
@ -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">
|
||||
|
@ -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 = [[@{/}]];
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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"];
|
||||
|
@ -116,7 +116,7 @@
|
||||
var options = {
|
||||
title: '部门选择',
|
||||
width: "380",
|
||||
url: prefix + "/selectDeptTree/" + treeId,
|
||||
url: prefix + "/selectDeptTree/" + treeId + "/0",
|
||||
callBack: doSubmit
|
||||
};
|
||||
$.modal.openOptions(options);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
|
@ -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>
|
||||
|
@ -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>
|
@ -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());
|
||||
|
@ -54,7 +54,7 @@
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i> 搜索</a>
|
||||
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i> 重置</a>
|
||||
<a class="btn btn-warning btn-rounded btn-sm" onclick="resetPre()"><i class="fa fa-refresh"></i> 重置</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() {
|
||||
|
@ -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>
|
||||
|
||||
|
@ -25,4 +25,9 @@ public @interface DataScope
|
||||
* 用户表的别名
|
||||
*/
|
||||
public String userAlias() default "";
|
||||
|
||||
/**
|
||||
* 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@RequiresPermissions获取,多个权限用逗号分隔开来
|
||||
*/
|
||||
public String permission() default "";
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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" };
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -44,6 +44,7 @@ public final class ServiceException extends RuntimeException
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage()
|
||||
{
|
||||
return message;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -116,8 +116,7 @@ public class FileUtils
|
||||
// 路径为文件且不为空则进行删除
|
||||
if (file.isFile() && file.exists())
|
||||
{
|
||||
file.delete();
|
||||
flag = true;
|
||||
flag = file.delete();
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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()";
|
||||
|
||||
/**
|
||||
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
|
||||
|
@ -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>
|
||||
|
@ -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()))
|
||||
|
@ -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());
|
||||
|
@ -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(), ","));
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
// 获取客户端浏览器
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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("创建表结构异常");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ public class GenTableColumn extends BaseEntity
|
||||
private String htmlType;
|
||||
|
||||
/** 字典类型 */
|
||||
private String dictType;
|
||||
private String dictType = "";
|
||||
|
||||
/** 排序 */
|
||||
private Integer sort;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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("任务不存在或已过期!");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,7 +74,7 @@ public interface ISysJobService
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public void run(SysJob job) throws SchedulerException;
|
||||
public boolean run(SysJob job) throws SchedulerException;
|
||||
|
||||
/**
|
||||
* 新增任务
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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()))
|
||||
|
@ -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";
|
||||
|
@ -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>
|
||||
|
||||
|
@ -18,6 +18,14 @@ public interface SysConfigMapper
|
||||
*/
|
||||
public SysConfig selectConfig(SysConfig config);
|
||||
|
||||
/**
|
||||
* 通过ID查询配置
|
||||
*
|
||||
* @param configId 参数ID
|
||||
* @return 参数配置信息
|
||||
*/
|
||||
public SysConfig selectConfigById(Long configId);
|
||||
|
||||
/**
|
||||
* 查询参数配置列表
|
||||
*
|
||||
|
@ -12,7 +12,7 @@ import com.ruoyi.common.core.domain.entity.SysDept;
|
||||
public interface SysDeptMapper
|
||||
{
|
||||
/**
|
||||
* 查询部门人数
|
||||
* 查询下级部门数量
|
||||
*
|
||||
* @param dept 部门信息
|
||||
* @return 结果
|
||||
|
@ -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查询菜单
|
||||
*
|
||||
|
@ -104,7 +104,7 @@ public interface SysUserMapper
|
||||
* @param loginName 登录名称
|
||||
* @return 结果
|
||||
*/
|
||||
public int checkLoginNameUnique(String loginName);
|
||||
public SysUser checkLoginNameUnique(String loginName);
|
||||
|
||||
/**
|
||||
* 校验手机号码是否唯一
|
||||
|
@ -45,7 +45,7 @@ public interface ISysDeptService
|
||||
public List<Ztree> roleDeptTreeData(SysRole role);
|
||||
|
||||
/**
|
||||
* 查询部门人数
|
||||
* 根据父部门ID查询下级部门数量
|
||||
*
|
||||
* @param parentId 父部门ID
|
||||
* @return 结果
|
||||
|
@ -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查询菜单
|
||||
*
|
||||
|
@ -143,10 +143,10 @@ public interface ISysUserService
|
||||
/**
|
||||
* 校验用户名称是否唯一
|
||||
*
|
||||
* @param loginName 登录名称
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
public String checkLoginNameUnique(String loginName);
|
||||
public String checkLoginNameUnique(SysUser user);
|
||||
|
||||
/**
|
||||
* 校验手机号码是否唯一
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 结果
|
||||
|
@ -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查询菜单
|
||||
*
|
||||
|
@ -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++;
|
||||
|
@ -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
|
||||
|
@ -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">
|
||||
|
@ -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
Reference in New Issue
Block a user