mirror of
https://github.com/yangzongzhuan/RuoYi.git
synced 2025-10-15 18:18:28 +00:00
Compare commits
35 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
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.5</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.5-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>
|
||||
|
||||
|
12
pom.xml
12
pom.xml
@@ -5,28 +5,28 @@
|
||||
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>4.7.4</version>
|
||||
<version>4.7.5</version>
|
||||
|
||||
<name>ruoyi</name>
|
||||
<url>http://www.ruoyi.vip</url>
|
||||
<description>若依管理系统</description>
|
||||
|
||||
<properties>
|
||||
<ruoyi.version>4.7.4</ruoyi.version>
|
||||
<ruoyi.version>4.7.5</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.9.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.11</druid.version>
|
||||
<bitwalker.version>1.21</bitwalker.version>
|
||||
<kaptcha.version>2.3.2</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.3</pagehelper.boot.version>
|
||||
<fastjson.version>1.2.83</fastjson.version>
|
||||
<oshi.version>6.1.6</oshi.version>
|
||||
<oshi.version>6.2.2</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>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.7.4</version>
|
||||
<version>4.7.5</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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
@@ -299,4 +305,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.5
|
||||
# 版权年份
|
||||
copyrightYear: 2022
|
||||
# 实例演示开关
|
||||
|
@@ -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>'
|
||||
|
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
@@ -508,7 +508,7 @@ div.ztree-border {
|
||||
left: calc(100% - 20px);
|
||||
background-color: #33cabb
|
||||
}
|
||||
|
||||
|
||||
.toggle-switch.switch-solid span {
|
||||
height: 20px;
|
||||
}
|
||||
@@ -843,7 +843,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 +872,7 @@ label {
|
||||
background-color: #eff3f8;
|
||||
}
|
||||
|
||||
.fixed-table-container thead th >.both{
|
||||
.fixed-table-container thead th >.both{
|
||||
display: inline-block
|
||||
}
|
||||
|
||||
@@ -1040,12 +1040,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 +1053,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);
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ var table = {
|
||||
// 设置实例配置
|
||||
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;
|
||||
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);
|
||||
}
|
||||
@@ -883,6 +883,9 @@ var table = {
|
||||
yes: callback,
|
||||
cancel: function(index) {
|
||||
return true;
|
||||
},
|
||||
success: function () {
|
||||
$(':focus').blur();
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -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);
|
||||
|
@@ -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.5
|
||||
</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.5
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-warning">开源免费</span>
|
||||
|
@@ -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.5}" 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.5}"></script>
|
||||
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.5}"></script>
|
||||
</div>
|
||||
|
||||
<!-- ztree树插件 -->
|
||||
|
@@ -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.5}" 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.5}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.7.5}"></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.5}" 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.5}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.7.5}"></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.5}"></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.5}" 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.5}"></script>
|
||||
<script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -96,13 +96,54 @@
|
||||
<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="#v475">v4.7.5</a><code class="pull-right">2022.09.05</code>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="v475" class="panel-collapse collapse in">
|
||||
<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);
|
||||
}
|
||||
|
@@ -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.5}" 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.5}"></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.5}"></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());
|
||||
|
@@ -191,7 +191,7 @@
|
||||
|
||||
function queryDeptTree()
|
||||
{
|
||||
var url = ctx + "system/dept/treeData";
|
||||
var url = ctx + "system/user/deptTreeData";
|
||||
var options = {
|
||||
url: url,
|
||||
expandLevel: 2,
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.7.4</version>
|
||||
<version>4.7.5</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;
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
|
||||
*
|
||||
|
@@ -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;
|
||||
@@ -148,6 +152,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 +187,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 +221,7 @@ public class ExcelUtil<T>
|
||||
createExcelField();
|
||||
createWorkbook();
|
||||
createTitle();
|
||||
createSubHead();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,13 +231,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 +652,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 +681,60 @@ 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 = i > 1 ? rowNo + 1 : rowNo + i;
|
||||
row = sheet.createRow(rowNo);
|
||||
// 得到导出对象.
|
||||
T vo = (T) list.get(i);
|
||||
Collection<?> subList = null;
|
||||
if (isSubListValue(vo))
|
||||
{
|
||||
subList = getListCellValue(vo);
|
||||
subMergedLastRowNum = subMergedLastRowNum + subList.size();
|
||||
}
|
||||
|
||||
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 +776,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,24 +785,60 @@ 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 = 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();
|
||||
@@ -704,6 +853,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 +869,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;
|
||||
}
|
||||
|
||||
@@ -833,7 +993,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 +1020,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))
|
||||
{
|
||||
@@ -928,7 +1093,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 +1130,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 +1343,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 +1604,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;
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.7.4</version>
|
||||
<version>4.7.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@@ -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()))
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.7.4</version>
|
||||
<version>4.7.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.7.4</version>
|
||||
<version>4.7.5</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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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.5}"></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.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@@ -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查询菜单
|
||||
*
|
||||
|
@@ -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查询菜单
|
||||
*
|
||||
|
@@ -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);
|
||||
|
@@ -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查询菜单
|
||||
*
|
||||
|
@@ -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
|
||||
|
@@ -73,12 +73,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<select id="checkRoleNameUnique" parameterType="String" resultMap="SysRoleResult">
|
||||
<include refid="selectRoleVo"/>
|
||||
where r.role_name=#{roleName} limit 1
|
||||
where r.role_name=#{roleName} and r.del_flag = '0' limit 1
|
||||
</select>
|
||||
|
||||
<select id="checkRoleKeyUnique" parameterType="String" resultMap="SysRoleResult">
|
||||
<include refid="selectRoleVo"/>
|
||||
where r.role_key=#{roleKey} limit 1
|
||||
where r.role_key=#{roleKey} and r.del_flag = '0' limit 1
|
||||
</select>
|
||||
|
||||
<delete id="deleteRoleById" parameterType="Long">
|
||||
|
@@ -125,29 +125,29 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<select id="selectUserByLoginName" parameterType="String" resultMap="SysUserResult">
|
||||
<include refid="selectUserVo"/>
|
||||
where u.login_name = #{userName}
|
||||
where u.login_name = #{userName} and u.del_flag = '0'
|
||||
</select>
|
||||
|
||||
<select id="selectUserByPhoneNumber" parameterType="String" resultMap="SysUserResult">
|
||||
<include refid="selectUserVo"/>
|
||||
where u.phonenumber = #{phonenumber}
|
||||
where u.phonenumber = #{phonenumber} and u.del_flag = '0'
|
||||
</select>
|
||||
|
||||
<select id="selectUserByEmail" parameterType="String" resultMap="SysUserResult">
|
||||
<include refid="selectUserVo"/>
|
||||
where u.email = #{email}
|
||||
where u.email = #{email} and u.del_flag = '0'
|
||||
</select>
|
||||
|
||||
<select id="checkLoginNameUnique" parameterType="String" resultType="int">
|
||||
select count(1) from sys_user where login_name=#{loginName} limit 1
|
||||
select count(1) from sys_user where login_name=#{loginName} and del_flag = '0' limit 1
|
||||
</select>
|
||||
|
||||
<select id="checkPhoneUnique" parameterType="String" resultMap="SysUserResult">
|
||||
select user_id, phonenumber from sys_user where phonenumber=#{phonenumber} limit 1
|
||||
select user_id, phonenumber from sys_user where phonenumber=#{phonenumber} and del_flag = '0' limit 1
|
||||
</select>
|
||||
|
||||
<select id="checkEmailUnique" parameterType="String" resultMap="SysUserResult">
|
||||
select user_id, email from sys_user where email=#{email} limit 1
|
||||
select user_id, email from sys_user where email=#{email} and del_flag = '0' limit 1
|
||||
</select>
|
||||
|
||||
<select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
|
||||
|
Reference in New Issue
Block a user