Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4613984fb4 | ||
|
|
893b29cae8 | ||
|
|
b99efad19c | ||
|
|
034e7ec9f0 | ||
|
|
72540d01ab | ||
|
|
85677a3349 | ||
|
|
b5301a3632 | ||
|
|
c2743f949e | ||
|
|
a7350294e8 | ||
|
|
6d531fb173 | ||
|
|
18517b6dc5 | ||
|
|
27889b0a14 | ||
|
|
6bd0dc8e05 | ||
|
|
248fe926c5 | ||
|
|
8c6546f5d8 | ||
|
|
b04eac0566 | ||
|
|
6984644313 | ||
|
|
174520d259 | ||
|
|
e4a22fabc5 | ||
|
|
d770e73e31 | ||
|
|
e73877f0a2 | ||
|
|
0086cc9f53 | ||
|
|
2f4c975615 | ||
|
|
bbfe5889ea | ||
|
|
8b2177673b | ||
|
|
eb0602033d | ||
|
|
210d75be8e | ||
|
|
ed1e7e69a8 | ||
|
|
e9ebf86ac8 | ||
|
|
8faea4836d | ||
|
|
30f821be49 | ||
|
|
3361f420c4 | ||
|
|
07357a8b75 | ||
|
|
c009c88a5b | ||
|
|
40715336e3 | ||
|
|
16ec346493 | ||
|
|
a11fb3ddf7 | ||
|
|
063ee7f773 | ||
|
|
008a461968 | ||
|
|
36f428d928 | ||
|
|
871c0a115d | ||
|
|
6c3f0c36ff | ||
|
|
26c76deb5f | ||
|
|
20e2b60370 | ||
|
|
503e9c3a8e | ||
|
|
cea74fec35 | ||
|
|
9cca7839bc | ||
|
|
8bcbdc3160 | ||
|
|
a9e38fa54d | ||
|
|
a5573315a1 | ||
|
|
d7ed5a1f73 | ||
|
|
4a53b718b1 |
@@ -0,0 +1 @@
|
||||
custom: http://doc.ruoyi.vip/ruoyi/other/donate.html
|
||||
@@ -25,6 +25,8 @@ target/
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### JRebel ###
|
||||
rebel.xml
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/*
|
||||
@@ -37,6 +39,7 @@ nbdist/
|
||||
# Others
|
||||
*.log
|
||||
*.xml.versionsBackup
|
||||
*.swp
|
||||
|
||||
!*/build/*.java
|
||||
!*/build/*.html
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
<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.3</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.3-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>
|
||||
|
||||
## 平台简介
|
||||
|
||||
一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适的。于是利用空闲休息时间开始自己写了一套后台系统。如此有了若依。她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,OA。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
|
||||
@@ -88,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)
|
||||
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)
|
||||
@@ -5,35 +5,33 @@
|
||||
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>4.7.2</version>
|
||||
<version>4.7.3</version>
|
||||
|
||||
<name>ruoyi</name>
|
||||
<url>http://www.ruoyi.vip</url>
|
||||
<description>若依管理系统</description>
|
||||
|
||||
<properties>
|
||||
<ruoyi.version>4.7.2</ruoyi.version>
|
||||
<ruoyi.version>4.7.3</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.8.0</shiro.version>
|
||||
<thymeleaf.version>3.0.14.RELEASE</thymeleaf.version>
|
||||
<thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
|
||||
<druid.version>1.2.8</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.0</mybatis-spring-boot.version>
|
||||
<pagehelper.boot.version>1.4.0</pagehelper.boot.version>
|
||||
<mybatis-spring-boot.version>2.2.2</mybatis-spring-boot.version>
|
||||
<pagehelper.boot.version>1.4.1</pagehelper.boot.version>
|
||||
<fastjson.version>1.2.79</fastjson.version>
|
||||
<oshi.version>5.8.6</oshi.version>
|
||||
<oshi.version>6.1.2</oshi.version>
|
||||
<jna.version>5.10.0</jna.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>
|
||||
<velocity.version>2.3</velocity.version>
|
||||
<log4j2.version>2.17.0</log4j2.version>
|
||||
</properties>
|
||||
|
||||
<!-- 依赖声明 -->
|
||||
@@ -44,7 +42,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>2.5.6</version>
|
||||
<version>2.5.10</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -84,19 +82,6 @@
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- thymeleaf模板引擎和spring框架的整合 -->
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf-spring5</artifactId>
|
||||
<version>${thymeleaf.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>${thymeleaf.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- thymeleaf模板引擎和shiro框架的整合 -->
|
||||
<dependency>
|
||||
<groupId>com.github.theborakompanioni</groupId>
|
||||
@@ -192,19 +177,6 @@
|
||||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- log4j日志组件 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-to-slf4j</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 定时任务-->
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.7.2</version>
|
||||
<version>4.7.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.common.config.RuoYiConfig;
|
||||
@@ -27,6 +28,7 @@ import com.ruoyi.common.utils.file.FileUtils;
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/common")
|
||||
public class CommonController
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
|
||||
@@ -42,7 +44,7 @@ public class CommonController
|
||||
* @param fileName 文件名称
|
||||
* @param delete 是否删除
|
||||
*/
|
||||
@GetMapping("common/download")
|
||||
@GetMapping("/download")
|
||||
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
|
||||
{
|
||||
try
|
||||
@@ -71,7 +73,7 @@ public class CommonController
|
||||
/**
|
||||
* 通用上传请求(单个)
|
||||
*/
|
||||
@PostMapping("/common/upload")
|
||||
@PostMapping("/upload")
|
||||
@ResponseBody
|
||||
public AjaxResult uploadFile(MultipartFile file) throws Exception
|
||||
{
|
||||
@@ -83,8 +85,10 @@ public class CommonController
|
||||
String fileName = FileUploadUtils.upload(filePath, file);
|
||||
String url = serverConfig.getUrl() + fileName;
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("fileName", fileName);
|
||||
ajax.put("url", url);
|
||||
ajax.put("fileName", fileName);
|
||||
ajax.put("newFileName", FileUtils.getName(fileName));
|
||||
ajax.put("originalFilename", file.getOriginalFilename());
|
||||
return ajax;
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -96,7 +100,7 @@ public class CommonController
|
||||
/**
|
||||
* 通用上传请求(多个)
|
||||
*/
|
||||
@PostMapping("/common/uploads")
|
||||
@PostMapping("/uploads")
|
||||
@ResponseBody
|
||||
public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
|
||||
{
|
||||
@@ -104,19 +108,25 @@ public class CommonController
|
||||
{
|
||||
// 上传文件路径
|
||||
String filePath = RuoYiConfig.getUploadPath();
|
||||
List<String> fileNames = new ArrayList<String>();
|
||||
List<String> urls = new ArrayList<String>();
|
||||
List<String> fileNames = new ArrayList<String>();
|
||||
List<String> newFileNames = new ArrayList<String>();
|
||||
List<String> originalFilenames = new ArrayList<String>();
|
||||
for (MultipartFile file : files)
|
||||
{
|
||||
// 上传并返回新文件名称
|
||||
String fileName = FileUploadUtils.upload(filePath, file);
|
||||
String url = serverConfig.getUrl() + fileName;
|
||||
fileNames.add(fileName);
|
||||
urls.add(url);
|
||||
fileNames.add(fileName);
|
||||
newFileNames.add(FileUtils.getName(fileName));
|
||||
originalFilenames.add(file.getOriginalFilename());
|
||||
}
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
|
||||
ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
|
||||
ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
|
||||
ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
|
||||
ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
|
||||
return ajax;
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -128,7 +138,7 @@ public class CommonController
|
||||
/**
|
||||
* 本地资源通用下载
|
||||
*/
|
||||
@GetMapping("/common/download/resource")
|
||||
@GetMapping("/download/resource")
|
||||
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception
|
||||
{
|
||||
|
||||
+247
@@ -65,6 +65,57 @@ public class DemoTableController extends BaseController
|
||||
users.add(new UserTableModel(26, "1000026", "测试26", "1", "15666666666", "ry@qq.com", 250.0, "1"));
|
||||
}
|
||||
|
||||
private final static List<AreaModel> areas = new ArrayList<AreaModel>();
|
||||
{
|
||||
areas.add(new AreaModel(1, 0, "广东省", "440000", "GDS", "GuangDongSheng", 1));
|
||||
areas.add(new AreaModel(2, 0, "湖南省", "430000", "HNS", "HuNanSheng", 1));
|
||||
areas.add(new AreaModel(3, 0, "河南省", "410000", "HNS", "HeNanSheng", 0));
|
||||
areas.add(new AreaModel(4, 0, "湖北省", "420000", "HBS", "HuBeiSheng", 0));
|
||||
areas.add(new AreaModel(5, 0, "辽宁省", "210000", "LNS", "LiaoNingSheng", 0));
|
||||
areas.add(new AreaModel(6, 0, "山东省", "370000", "SDS", "ShanDongSheng", 0));
|
||||
areas.add(new AreaModel(7, 0, "陕西省", "610000", "SXS", "ShanXiSheng", 0));
|
||||
areas.add(new AreaModel(8, 0, "贵州省", "520000", "GZS", "GuiZhouSheng", 0));
|
||||
areas.add(new AreaModel(9, 0, "上海市", "310000", "SHS", "ShangHaiShi", 0));
|
||||
areas.add(new AreaModel(10, 0, "重庆市", "500000", "CQS", "ChongQingShi", 0));
|
||||
areas.add(new AreaModel(11, 0, "若依省", "666666", "YYS", "RuoYiSheng", 0));
|
||||
areas.add(new AreaModel(12, 0, "安徽省", "340000", "AHS", "AnHuiSheng", 0));
|
||||
areas.add(new AreaModel(13, 0, "福建省", "350000", "FJS", "FuJianSheng", 0));
|
||||
areas.add(new AreaModel(14, 0, "海南省", "460000", "HNS", "HaiNanSheng", 0));
|
||||
areas.add(new AreaModel(15, 0, "江苏省", "320000", "JSS", "JiangSuSheng", 0));
|
||||
areas.add(new AreaModel(16, 0, "青海省", "630000", "QHS", "QingHaiSheng", 0));
|
||||
areas.add(new AreaModel(17, 0, "广西壮族自治区", "450000", "GXZZZZQ", "GuangXiZhuangZuZiZhiQu", 0));
|
||||
areas.add(new AreaModel(18, 0, "宁夏回族自治区", "640000", "NXHZZZQ", "NingXiaHuiZuZiZhiQu", 0));
|
||||
areas.add(new AreaModel(19, 0, "内蒙古自治区", "150000", "NMGZZQ", "NeiMengGuZiZhiQu", 0));
|
||||
areas.add(new AreaModel(20, 0, "新疆维吾尔自治区", "650000", "XJWWEZZQ", "XinJiangWeiWuErZiZhiQu", 0));
|
||||
areas.add(new AreaModel(21, 0, "江西省", "360000", "JXS", "JiangXiSheng", 0));
|
||||
areas.add(new AreaModel(22, 0, "浙江省", "330000", "ZJS", "ZheJiangSheng", 0));
|
||||
areas.add(new AreaModel(23, 0, "河北省", "130000", "HBS", "HeBeiSheng", 0));
|
||||
areas.add(new AreaModel(24, 0, "天津市", "120000", "TJS", "TianJinShi", 0));
|
||||
areas.add(new AreaModel(25, 0, "山西省", "140000", "SXS", "ShanXiSheng", 0));
|
||||
areas.add(new AreaModel(26, 0, "台湾省", "710000", "TWS", "TaiWanSheng", 0));
|
||||
areas.add(new AreaModel(27, 0, "甘肃省", "620000", "GSS", "GanSuSheng", 0));
|
||||
areas.add(new AreaModel(28, 0, "四川省", "510000", "SCS", "SiChuanSheng", 0));
|
||||
areas.add(new AreaModel(29, 0, "云南省", "530000", "YNS", "YunNanSheng", 0));
|
||||
areas.add(new AreaModel(30, 0, "北京市", "110000", "BJS", "BeiJingShi", 0));
|
||||
areas.add(new AreaModel(31, 0, "香港特别行政区", "810000", "XGTBXZQ", "XiangGangTeBieXingZhengQu", 0));
|
||||
areas.add(new AreaModel(32, 0, "澳门特别行政区", "820000", "AMTBXZQ", "AoMenTeBieXingZhengQu", 0));
|
||||
|
||||
areas.add(new AreaModel(100, 1, "深圳市", "440300", "SZS", "ShenZhenShi", 1));
|
||||
areas.add(new AreaModel(101, 1, "广州市", "440100", "GZS", "GuangZhouShi", 0));
|
||||
areas.add(new AreaModel(102, 1, "东莞市", "441900", "DGS", "DongGuanShi", 0));
|
||||
areas.add(new AreaModel(103, 2, "长沙市", "410005", "CSS", "ChangShaShi", 1));
|
||||
areas.add(new AreaModel(104, 2, "岳阳市", "414000", "YYS", "YueYangShi", 0));
|
||||
|
||||
areas.add(new AreaModel(1000, 100, "龙岗区", "518172", "LGQ", "LongGangQu", 0));
|
||||
areas.add(new AreaModel(1001, 100, "南山区", "518051", "NSQ", "NanShanQu", 0));
|
||||
areas.add(new AreaModel(1002, 100, "宝安区", "518101", "BAQ", "BaoAnQu", 0));
|
||||
areas.add(new AreaModel(1003, 100, "福田区", "518081", "FTQ", "FuTianQu", 0));
|
||||
areas.add(new AreaModel(1004, 103, "天心区", "410004", "TXQ", "TianXinQu", 0));
|
||||
areas.add(new AreaModel(1005, 103, "开福区", "410008", "KFQ", "KaiFuQu", 0));
|
||||
areas.add(new AreaModel(1006, 103, "芙蓉区", "410011", "FRQ", "FuRongQu", 0));
|
||||
areas.add(new AreaModel(1007, 103, "雨花区", "410011", "YHQ", "YuHuaQu", 0));
|
||||
}
|
||||
|
||||
private final static List<UserTableColumn> columns = new ArrayList<UserTableColumn>();
|
||||
{
|
||||
columns.add(new UserTableColumn("用户ID", "userId"));
|
||||
@@ -348,6 +399,15 @@ public class DemoTableController extends BaseController
|
||||
return prefix + "/customView";
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步加载表格树
|
||||
*/
|
||||
@GetMapping("/asynTree")
|
||||
public String asynTree()
|
||||
{
|
||||
return prefix + "/asynTree";
|
||||
}
|
||||
|
||||
/**
|
||||
* 表格其他操作
|
||||
*/
|
||||
@@ -412,6 +472,84 @@ public class DemoTableController extends BaseController
|
||||
rspData.setTotal(userList.size());
|
||||
return rspData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询树表数据
|
||||
*/
|
||||
@PostMapping("/tree/list")
|
||||
@ResponseBody
|
||||
public TableDataInfo treeList(AreaModel areaModel)
|
||||
{
|
||||
TableDataInfo rspData = new TableDataInfo();
|
||||
List<AreaModel> areaList = new ArrayList<AreaModel>(Arrays.asList(new AreaModel[areas.size()]));
|
||||
// 默认查询条件 parentId 0
|
||||
Collections.copy(areaList, areas);
|
||||
areaList.clear();
|
||||
if (StringUtils.isNotEmpty(areaModel.getAreaName()))
|
||||
{
|
||||
for (AreaModel area : areas)
|
||||
{
|
||||
if (area.getParentId() == 0 && area.getAreaName().equals(areaModel.getAreaName()))
|
||||
{
|
||||
areaList.add(area);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (AreaModel area : areas)
|
||||
{
|
||||
if (area.getParentId() == 0)
|
||||
{
|
||||
areaList.add(area);
|
||||
}
|
||||
}
|
||||
}
|
||||
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||
Integer pageNum = (pageDomain.getPageNum() - 1) * 10;
|
||||
Integer pageSize = pageDomain.getPageNum() * 10;
|
||||
if (pageSize > areaList.size())
|
||||
{
|
||||
pageSize = areaList.size();
|
||||
}
|
||||
rspData.setRows(areaList.subList(pageNum, pageSize));
|
||||
rspData.setTotal(areaList.size());
|
||||
return rspData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询树表子节点数据
|
||||
*/
|
||||
@PostMapping("/tree/listChild")
|
||||
@ResponseBody
|
||||
public List<AreaModel> listChild(AreaModel areaModel)
|
||||
{
|
||||
List<AreaModel> areaList = new ArrayList<AreaModel>(Arrays.asList(new AreaModel[areas.size()]));
|
||||
// 查询条件 parentId
|
||||
Collections.copy(areaList, areas);
|
||||
areaList.clear();
|
||||
if (StringUtils.isNotEmpty(areaModel.getAreaName()))
|
||||
{
|
||||
for (AreaModel area : areas)
|
||||
{
|
||||
if (area.getParentId().intValue() == areaModel.getParentId().intValue() && area.getAreaName().equals(areaModel.getAreaName()))
|
||||
{
|
||||
areaList.add(area);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (AreaModel area : areas)
|
||||
{
|
||||
if (area.getParentId().intValue() == areaModel.getParentId().intValue())
|
||||
{
|
||||
areaList.add(area);
|
||||
}
|
||||
}
|
||||
}
|
||||
return areaList;
|
||||
}
|
||||
}
|
||||
|
||||
class UserTableColumn
|
||||
@@ -597,3 +735,112 @@ class UserTableModel
|
||||
this.createTime = createTime;
|
||||
}
|
||||
}
|
||||
class AreaModel
|
||||
{
|
||||
/** 编号 */
|
||||
private Long id;
|
||||
|
||||
/** 父编号 */
|
||||
private Long parentId;
|
||||
|
||||
/** 区域名称 */
|
||||
private String areaName;
|
||||
|
||||
/** 区域代码 */
|
||||
private String areaCode;
|
||||
|
||||
/** 名称首字母 */
|
||||
private String simplePy;
|
||||
|
||||
/** 名称全拼 */
|
||||
private String pinYin;
|
||||
|
||||
/** 是否有子节点(0无 1有) */
|
||||
private Integer isTreeLeaf = 1;
|
||||
|
||||
public AreaModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public AreaModel(int id, int parentId, String areaName, String areaCode, String simplePy, String pinYin, Integer isTreeLeaf)
|
||||
{
|
||||
this.id = Long.valueOf(id);
|
||||
this.parentId = Long.valueOf(parentId);
|
||||
this.areaName = areaName;
|
||||
this.areaCode = areaCode;
|
||||
this.simplePy = simplePy;
|
||||
this.pinYin = pinYin;
|
||||
this.isTreeLeaf = isTreeLeaf;
|
||||
}
|
||||
|
||||
public Long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getParentId()
|
||||
{
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(Long parentId)
|
||||
{
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public String getAreaName()
|
||||
{
|
||||
return areaName;
|
||||
}
|
||||
|
||||
public void setAreaName(String areaName)
|
||||
{
|
||||
this.areaName = areaName;
|
||||
}
|
||||
|
||||
public String getAreaCode()
|
||||
{
|
||||
return areaCode;
|
||||
}
|
||||
|
||||
public void setAreaCode(String areaCode)
|
||||
{
|
||||
this.areaCode = areaCode;
|
||||
}
|
||||
|
||||
public String getSimplePy()
|
||||
{
|
||||
return simplePy;
|
||||
}
|
||||
|
||||
public void setSimplePy(String simplePy)
|
||||
{
|
||||
this.simplePy = simplePy;
|
||||
}
|
||||
|
||||
public String getPinYin()
|
||||
{
|
||||
return pinYin;
|
||||
}
|
||||
|
||||
public void setPinYin(String pinYin)
|
||||
{
|
||||
this.pinYin = pinYin;
|
||||
}
|
||||
|
||||
public Integer getIsTreeLeaf()
|
||||
{
|
||||
return isTreeLeaf;
|
||||
}
|
||||
|
||||
public void setIsTreeLeaf(Integer isTreeLeaf)
|
||||
{
|
||||
this.isTreeLeaf = isTreeLeaf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,16 +109,17 @@ public class SysDeptController extends BaseController
|
||||
@ResponseBody
|
||||
public AjaxResult editSave(@Validated SysDept dept)
|
||||
{
|
||||
Long deptId = dept.getDeptId();
|
||||
deptService.checkDeptDataScope(deptId);
|
||||
if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
|
||||
{
|
||||
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
||||
}
|
||||
else if (dept.getParentId().equals(dept.getDeptId()))
|
||||
else if (dept.getParentId().equals(deptId))
|
||||
{
|
||||
return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
|
||||
}
|
||||
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus())
|
||||
&& deptService.selectNormalChildrenDeptById(dept.getDeptId()) > 0)
|
||||
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
|
||||
{
|
||||
return AjaxResult.error("该部门包含未停用的子部门!");
|
||||
}
|
||||
@@ -143,6 +144,7 @@ public class SysDeptController extends BaseController
|
||||
{
|
||||
return AjaxResult.warn("部门存在用户,不允许删除");
|
||||
}
|
||||
deptService.checkDeptDataScope(deptId);
|
||||
return toAjax(deptService.deleteDeptById(deptId));
|
||||
}
|
||||
|
||||
|
||||
@@ -124,6 +124,7 @@ public class SysRoleController extends BaseController
|
||||
public AjaxResult editSave(@Validated SysRole role)
|
||||
{
|
||||
roleService.checkRoleAllowed(role);
|
||||
roleService.checkRoleDataScope(role.getRoleId());
|
||||
if (UserConstants.ROLE_NAME_NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
|
||||
{
|
||||
return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
|
||||
@@ -157,6 +158,7 @@ public class SysRoleController extends BaseController
|
||||
public AjaxResult authDataScopeSave(SysRole role)
|
||||
{
|
||||
roleService.checkRoleAllowed(role);
|
||||
roleService.checkRoleDataScope(role.getRoleId());
|
||||
role.setUpdateBy(getLoginName());
|
||||
if (roleService.authDataScope(role) > 0)
|
||||
{
|
||||
@@ -214,6 +216,7 @@ public class SysRoleController extends BaseController
|
||||
public AjaxResult changeStatus(SysRole role)
|
||||
{
|
||||
roleService.checkRoleAllowed(role);
|
||||
roleService.checkRoleDataScope(role.getRoleId());
|
||||
return toAjax(roleService.changeStatus(role));
|
||||
}
|
||||
|
||||
@@ -297,6 +300,7 @@ public class SysRoleController extends BaseController
|
||||
@ResponseBody
|
||||
public AjaxResult selectAuthUserAll(Long roleId, String userIds)
|
||||
{
|
||||
roleService.checkRoleDataScope(roleId);
|
||||
return toAjax(roleService.insertAuthUsers(roleId, userIds));
|
||||
}
|
||||
}
|
||||
@@ -169,6 +169,7 @@ public class SysUserController extends BaseController
|
||||
public AjaxResult editSave(@Validated SysUser user)
|
||||
{
|
||||
userService.checkUserAllowed(user);
|
||||
userService.checkUserDataScope(user.getUserId());
|
||||
if (StringUtils.isNotEmpty(user.getPhonenumber())
|
||||
&& UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
|
||||
{
|
||||
@@ -199,6 +200,7 @@ public class SysUserController extends BaseController
|
||||
public AjaxResult resetPwdSave(SysUser user)
|
||||
{
|
||||
userService.checkUserAllowed(user);
|
||||
userService.checkUserDataScope(user.getUserId());
|
||||
user.setSalt(ShiroUtils.randomSalt());
|
||||
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
|
||||
if (userService.resetUserPwd(user) > 0)
|
||||
@@ -235,6 +237,7 @@ public class SysUserController extends BaseController
|
||||
@ResponseBody
|
||||
public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
|
||||
{
|
||||
userService.checkUserDataScope(userId);
|
||||
userService.insertUserAuth(userId, roleIds);
|
||||
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
||||
return success();
|
||||
@@ -293,6 +296,7 @@ public class SysUserController extends BaseController
|
||||
public AjaxResult changeStatus(SysUser user)
|
||||
{
|
||||
userService.checkUserAllowed(user);
|
||||
userService.checkUserDataScope(user.getUserId());
|
||||
return toAjax(userService.changeStatus(user));
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,9 @@ ruoyi:
|
||||
# 名称
|
||||
name: RuoYi
|
||||
# 版本
|
||||
version: 4.7.2
|
||||
version: 4.7.3
|
||||
# 版权年份
|
||||
copyrightYear: 2021
|
||||
copyrightYear: 2022
|
||||
# 实例演示开关
|
||||
demoEnabled: true
|
||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||
|
||||
@@ -44,6 +44,13 @@
|
||||
return [].concat(this.map(lambda));
|
||||
};
|
||||
}
|
||||
|
||||
if (!document.currentScript) {
|
||||
document.currentScript = function() {
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
return scripts[scripts.length - 1];
|
||||
}();
|
||||
}
|
||||
|
||||
var $h, FileInput, getLoadingUrl = function () {
|
||||
var src = document.currentScript.src, srcPath = src.substring(0, src.lastIndexOf("/"));
|
||||
|
||||
+1
-485
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
+2
@@ -8,6 +8,7 @@ var Utils = $.fn.bootstrapTable.utils
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, {
|
||||
autoRefresh: false,
|
||||
showAutoRefresh: true,
|
||||
autoRefreshInterval: 60,
|
||||
autoRefreshSilent: true,
|
||||
autoRefreshStatus: true,
|
||||
@@ -17,6 +18,7 @@ $.extend($.fn.bootstrapTable.defaults, {
|
||||
$.extend($.fn.bootstrapTable.defaults.icons, {
|
||||
autoRefresh: {
|
||||
bootstrap3: 'glyphicon-time icon-time',
|
||||
bootstrap5: 'bi-clock',
|
||||
materialize: 'access_time',
|
||||
'bootstrap-table': 'icon-clock'
|
||||
}[$.fn.bootstrapTable.theme] || 'fa-clock'
|
||||
|
||||
+1
@@ -225,6 +225,7 @@ $.BootstrapTable = class extends $.BootstrapTable {
|
||||
const initFixedBody = ($fixedColumns, $fixedHeader) => {
|
||||
$fixedColumns.find('.fixed-table-body').remove()
|
||||
$fixedColumns.append(this.$tableBody.clone(true))
|
||||
$fixedColumns.find('.fixed-table-body table').removeAttr('id')
|
||||
|
||||
const $fixedBody = $fixedColumns.find('.fixed-table-body')
|
||||
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* @author zhixin wen <wenzhixin2010@gmail.com>
|
||||
* @author: Dustin Utecht
|
||||
* @github: https://github.com/UtechtDustin
|
||||
*/
|
||||
|
||||
var Utils = $.fn.bootstrapTable.utils
|
||||
@@ -105,4 +106,4 @@ $.BootstrapTable = class extends $.BootstrapTable {
|
||||
this.showCustomView = !this.showCustomView
|
||||
this.initBody()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+51
-47
@@ -43,6 +43,7 @@ $.extend($.fn.bootstrapTable.columnDefaults, {
|
||||
$.extend($.fn.bootstrapTable.defaults.icons, {
|
||||
export: {
|
||||
bootstrap3: 'glyphicon-export icon-share',
|
||||
bootstrap5: 'bi-download',
|
||||
materialize: 'file_download',
|
||||
'bootstrap-table': 'icon-download'
|
||||
}[$.fn.bootstrapTable.theme] || 'fa-download'
|
||||
@@ -91,30 +92,51 @@ $.BootstrapTable = class extends $.BootstrapTable {
|
||||
|
||||
this.buttons = Object.assign(this.buttons, {
|
||||
export: {
|
||||
html: exportTypes.length === 1 ? `
|
||||
<div class="export ${this.constants.classes.buttonsDropdown}"
|
||||
data-type="${exportTypes[0]}">
|
||||
<button class="${this.constants.buttonsClass}"
|
||||
aria-label="Export"
|
||||
type="button"
|
||||
title="${o.formatExport()}">
|
||||
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
|
||||
${o.showButtonText ? o.formatExport() : ''}
|
||||
</button>
|
||||
</div>
|
||||
` : `
|
||||
<div class="export ${this.constants.classes.buttonsDropdown}">
|
||||
<button class="${this.constants.buttonsClass} dropdown-toggle"
|
||||
aria-label="Export"
|
||||
${this.constants.dataToggle}="dropdown"
|
||||
type="button"
|
||||
title="${o.formatExport()}">
|
||||
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
|
||||
${o.showButtonText ? o.formatExport() : ''}
|
||||
${this.constants.html.dropdownCaret}
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
html:
|
||||
(() => {
|
||||
if (exportTypes.length === 1) {
|
||||
return `
|
||||
<div class="export ${this.constants.classes.buttonsDropdown}"
|
||||
data-type="${exportTypes[0]}">
|
||||
<button class="${this.constants.buttonsClass}"
|
||||
aria-label="Export"
|
||||
type="button"
|
||||
title="${o.formatExport()}">
|
||||
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
|
||||
${o.showButtonText ? o.formatExport() : ''}
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
const html = []
|
||||
|
||||
html.push(`
|
||||
<div class="export ${this.constants.classes.buttonsDropdown}">
|
||||
<button class="${this.constants.buttonsClass} dropdown-toggle"
|
||||
aria-label="Export"
|
||||
${this.constants.dataToggle}="dropdown"
|
||||
type="button"
|
||||
title="${o.formatExport()}">
|
||||
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
|
||||
${o.showButtonText ? o.formatExport() : ''}
|
||||
${this.constants.html.dropdownCaret}
|
||||
</button>
|
||||
${this.constants.html.toolbarDropdown[0]}
|
||||
`)
|
||||
|
||||
for (const type of exportTypes) {
|
||||
if (TYPE_NAME.hasOwnProperty(type)) {
|
||||
const $item = $(Utils.sprintf(this.constants.html.pageDropdownItem, '', TYPE_NAME[type]))
|
||||
|
||||
$item.attr('data-type', type)
|
||||
html.push($item.prop('outerHTML'))
|
||||
}
|
||||
}
|
||||
|
||||
html.push(this.constants.html.toolbarDropdown[1], '</div>')
|
||||
return html.join('')
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -126,32 +148,14 @@ $.BootstrapTable = class extends $.BootstrapTable {
|
||||
return
|
||||
}
|
||||
|
||||
let $menu = $(this.constants.html.toolbarDropdown.join(''))
|
||||
let $items = this.$export
|
||||
this.updateExportButton()
|
||||
let $exportButtons = this.$export.find('[data-type]')
|
||||
|
||||
if (exportTypes.length > 1) {
|
||||
this.$export.append($menu)
|
||||
|
||||
// themes support
|
||||
if ($menu.children().length) {
|
||||
$menu = $menu.children().eq(0)
|
||||
}
|
||||
for (const type of exportTypes) {
|
||||
if (TYPE_NAME.hasOwnProperty(type)) {
|
||||
const $item = $(Utils.sprintf(this.constants.html.pageDropdownItem,
|
||||
'', TYPE_NAME[type]))
|
||||
|
||||
$item.attr('data-type', type)
|
||||
$menu.append($item)
|
||||
}
|
||||
}
|
||||
|
||||
$items = $menu.children()
|
||||
if (exportTypes.length === 1) {
|
||||
$exportButtons = this.$export.find('button')
|
||||
}
|
||||
|
||||
this.updateExportButton()
|
||||
|
||||
$items.click(e => {
|
||||
$exportButtons.click(e => {
|
||||
e.preventDefault()
|
||||
|
||||
const type = $(e.currentTarget).data('type')
|
||||
|
||||
+2
-1
@@ -134,7 +134,8 @@ $.BootstrapTable = class extends $.BootstrapTable {
|
||||
|
||||
doPrint (data) {
|
||||
const formatValue = (row, i, column) => {
|
||||
const value = Utils.calculateObjectValue(column, column.printFormatter,
|
||||
const value = Utils.calculateObjectValue(column,
|
||||
column.printFormatter || column.formatter,
|
||||
[row[column.field], row, i], row[column.field])
|
||||
|
||||
return typeof value === 'undefined' || value === null ?
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ $.extend($.fn.bootstrapTable.defaults, {
|
||||
onDragStyle: null,
|
||||
onDropStyle: null,
|
||||
onDragClass: 'reorder_rows_onDragClass',
|
||||
dragHandle: '>tbody>tr>td',
|
||||
dragHandle: '>tbody>tr>td:not(.bs-checkbox)',
|
||||
useRowAttrFunc: false,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
onReorderRowsDrag (row) {
|
||||
|
||||
+2
@@ -43,6 +43,8 @@ $.BootstrapTable = class extends $.BootstrapTable {
|
||||
.on('column-switch.bs.table page-change.bs.table', () => {
|
||||
reInitResizable(this)
|
||||
})
|
||||
|
||||
reInitResizable(this)
|
||||
}
|
||||
|
||||
toggleView (...args) {
|
||||
|
||||
+342
-48
@@ -14,12 +14,14 @@
|
||||
}
|
||||
// 如果是初始化组件
|
||||
options = $.extend({}, $.fn.bootstrapTreeTable.defaults, options || {});
|
||||
target.hasSelectItem = false;// 是否有radio或checkbox
|
||||
target.data_list = null; //用于缓存格式化后的数据-按父分组
|
||||
target.data_obj = null; //用于缓存格式化后的数据-按id存对象
|
||||
target.hiddenColumns = []; //用于存放被隐藏列的field
|
||||
target.lastAjaxParams; //用户最后一次请求的参数
|
||||
target.isFixWidth=false; //是否有固定宽度
|
||||
target.hasSelectItem = false; // 是否有radio或checkbox
|
||||
target.data_list = null; // 用于缓存格式化后的数据-按父分组
|
||||
target.data_obj = null; // 用于缓存格式化后的数据-按id存对象
|
||||
target.hiddenColumns = []; // 用于存放被隐藏列的field
|
||||
target.lastAjaxParams; // 用户最后一次请求的参数
|
||||
target.isFixWidth=false; // 是否有固定宽度
|
||||
target.totalRows = 0; // 记录总数
|
||||
target.totalPages = 0; // 总页数
|
||||
// 初始化
|
||||
var init = function() {
|
||||
// 初始化容器
|
||||
@@ -148,12 +150,30 @@
|
||||
if (options.height) {
|
||||
$tbody.css("height", options.height);
|
||||
}
|
||||
if (options.pagination) {
|
||||
var $pagination = $('<div class="fixed-table-pagination"></div>');
|
||||
target.append($pagination);
|
||||
}
|
||||
}
|
||||
// 初始化数据服务
|
||||
var initServer = function(parms) {
|
||||
if (options.pagination) {
|
||||
if(parms == undefined || parms == null) {
|
||||
parms = {};
|
||||
}
|
||||
parms[options.parentCode] = options.rootIdValue;
|
||||
}
|
||||
// 加载数据前先清空
|
||||
target.data_list = {};
|
||||
target.data_obj = {};
|
||||
// 设置请求分页参数
|
||||
if (options.pagination) {
|
||||
var params = {};
|
||||
params.offset = options.pageSize * (options.pageNumber - 1);
|
||||
params.limit = options.pageSize;
|
||||
var curParams = { pageSize: params.limit, pageNum: params.offset / params.limit + 1 };
|
||||
parms = $.extend(curParams, parms);
|
||||
}
|
||||
var $tbody = target.find("tbody");
|
||||
// 添加加载loading
|
||||
var $loading = '<tr><td colspan="' + options.columns.length + '"><div style="display: block;text-align: center;">正在努力地加载数据中,请稍候……</div></td></tr>'
|
||||
@@ -163,16 +183,15 @@
|
||||
type: options.type,
|
||||
url: options.url,
|
||||
data: parms ? parms : options.ajaxParams,
|
||||
dataType: "JSON",
|
||||
dataType: "json",
|
||||
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>'
|
||||
$tbody.html(_errorMsg);
|
||||
},
|
||||
}
|
||||
});
|
||||
} else {
|
||||
renderTable(options.data);
|
||||
@@ -180,6 +199,17 @@
|
||||
}
|
||||
// 加载完数据后渲染表格
|
||||
var renderTable = function(data) {
|
||||
var list, totalPage = 0, currPage = 0;
|
||||
if (options.pagination) {
|
||||
list = data.rows; // 数据
|
||||
currPage = options.pageNumber; // 当前页
|
||||
totalPage = ~~((data.total - 1) / options.pageSize) + 1 // 总页数
|
||||
target.totalPages = totalPage;
|
||||
target.totalRows = data.total; // 总记录数
|
||||
} else {
|
||||
list = data;
|
||||
}
|
||||
data = list;
|
||||
var $tbody = target.find("tbody");
|
||||
// 先清空
|
||||
$tbody.html("");
|
||||
@@ -196,22 +226,24 @@
|
||||
if (rootNode) {
|
||||
$.each(rootNode, function(i, item) {
|
||||
var _child_row_id = "row_id_" + i
|
||||
recursionNode(item, 1, _child_row_id, "row_root");
|
||||
recursionNode(item, 1, _child_row_id, "row_root", item[options.code]);
|
||||
});
|
||||
}
|
||||
// 下边的操作主要是为了查询时让一些没有根节点的节点显示
|
||||
$.each(data, function(i, item) {
|
||||
if (!item.isShow) {
|
||||
var tr = renderRow(item, false, 1, "", "");
|
||||
var tr = renderRow(item, false, 1, "", "", options.pagination, item[options.code]);
|
||||
$tbody.append(tr);
|
||||
}
|
||||
});
|
||||
target.append($tbody);
|
||||
registerExpanderEvent();
|
||||
registerRowClickEvent();
|
||||
initHiddenColumns();
|
||||
// 动态设置表头宽度
|
||||
autoTheadWidth();
|
||||
if (options.pagination) {
|
||||
initPagination(totalPage, currPage);
|
||||
}
|
||||
// 移动端适配
|
||||
var treetableTable = $(target).parent('.treetable-table');
|
||||
var availableHeight = treetableTable.outerWidth();
|
||||
@@ -229,6 +261,180 @@
|
||||
$(target).attr('style','width:' + w +'px');
|
||||
}
|
||||
}
|
||||
// 初始化分页
|
||||
var initPagination = function (totalPage,currPage) {
|
||||
var $pagination = target.find(".fixed-table-pagination");
|
||||
$pagination.empty();
|
||||
var html = [];
|
||||
var pageFrom = (options.pageNumber - 1) * options.pageSize + 1;
|
||||
var pageTo = options.pageNumber * options.pageSize;
|
||||
if (pageTo > target.totalRows) {
|
||||
pageTo = target.totalRows;
|
||||
}
|
||||
html.push('<div class="pull-left pagination-detail">');
|
||||
html.push('<span class="pagination-info">' + formatShowingRows(pageFrom, pageTo, target.totalRows) + '</span>');
|
||||
var pageList = false;
|
||||
$.each(options.pageList, function (i, page) {
|
||||
if(target.totalRows > page){
|
||||
pageList = true;
|
||||
}
|
||||
})
|
||||
if(pageList){
|
||||
var _page_list = [];
|
||||
_page_list.push('<span class="page-list">');
|
||||
_page_list.push('<span class="btn-group dropup">');
|
||||
_page_list.push('<button type="button" class="btn btn-default btn-outline dropdown-toggle" data-toggle="dropdown">');
|
||||
_page_list.push('<span class="page-size">' + options.pageSize + '</span>');
|
||||
_page_list.push('<span class="caret"></span>');
|
||||
_page_list.push('</button>');
|
||||
_page_list.push('<ul class="dropdown-menu" role="menu">');
|
||||
$.each(options.pageList, function (i, page) {
|
||||
if(page == options.pageSize){
|
||||
_page_list.push('<li class="active"><a href="javascript:void(0)">' + page + '</a></li>');
|
||||
}
|
||||
else if(page >= target.totalRows && i === 1){
|
||||
_page_list.push('<li><a href="javascript:void(0)">' + page + '</a></li>');
|
||||
}
|
||||
else if(page <= target.totalRows){
|
||||
_page_list.push('<li><a href="javascript:void(0)">' + page + '</a></li>');
|
||||
}
|
||||
})
|
||||
_page_list.push('</ul>');
|
||||
_page_list.push('</span>');
|
||||
html.push(formatRecordsPerPage(_page_list.join('')))
|
||||
html.push('</span>');
|
||||
}
|
||||
html.push('</div>');
|
||||
|
||||
if(totalPage > 1){
|
||||
html.push('<div class="pull-right pagination">');
|
||||
html.push('<ul class="pagination pagination-outline">');
|
||||
html.push('<li class="page-pre"><a href="javascript:void(0)">' + options.paginationPreText + '</a></li>');
|
||||
var from, to;
|
||||
if (totalPage < 5) {
|
||||
from = 1;
|
||||
to = totalPage;
|
||||
} else {
|
||||
from = currPage - 2;
|
||||
to = from + 4;
|
||||
if (from < 1) {
|
||||
from = 1;
|
||||
to = 5;
|
||||
}
|
||||
if (to > totalPage) {
|
||||
to = totalPage;
|
||||
from = to - 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalPage >= 6) {
|
||||
if (currPage >= 3) {
|
||||
html.push('<li class="page-first' + (1 == currPage ? ' active' : '') + '">', '<a href="javascript:void(0)">', 1, '</a>', '</li>');
|
||||
from++;
|
||||
}
|
||||
if (currPage >= 4) {
|
||||
if (currPage == 4 || totalPage == 6 || totalPage == 7) {
|
||||
from--;
|
||||
} else {
|
||||
html.push('<li class="page-first-separator disabled">', '<a href="javascript:void(0)">...</a>', '</li>');
|
||||
}
|
||||
to--;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalPage >= 7) {
|
||||
if (currPage >= (totalPage - 2)) {
|
||||
from--;
|
||||
}
|
||||
}
|
||||
if (totalPage == 6) {
|
||||
if (currPage >= (totalPage - 2)) {
|
||||
to++;
|
||||
}
|
||||
} else if (totalPage >= 7) {
|
||||
if (totalPage == 7 || currPage >= (totalPage - 3)) {
|
||||
to++;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = from; i <= to; i++) {
|
||||
html.push('<li class="page-number' + (i == currPage ? ' active' : '') + '">', '<a href="javascript:void(0)">', i, '</a>', '</li>');
|
||||
}
|
||||
|
||||
if (totalPage >= 8) {
|
||||
if (currPage <= (totalPage - 4)) {
|
||||
html.push('<li class="page-last-separator disabled">', '<a href="javascript:void(0)">...</a>', '</li>');
|
||||
}
|
||||
}
|
||||
|
||||
if (totalPage >= 6) {
|
||||
if (currPage <= (totalPage - 3)) {
|
||||
html.push('<li class="page-last' + (totalPage === currPage ? ' active' : '') + '">', '<a href="javascript:void(0)">', totalPage, '</a>', '</li>');
|
||||
}
|
||||
}
|
||||
|
||||
html.push('<li class="page-next"><a href="javascript:void(0)">' + options.paginationNextText + '</a></li>');
|
||||
html.push('</ul></div>');
|
||||
}
|
||||
|
||||
$pagination.append(html.join(''));
|
||||
|
||||
var $pageList = $pagination.find('.page-list a');
|
||||
var $pre = $pagination.find('.page-pre');
|
||||
var $next = $pagination.find('.page-next');
|
||||
var $number = $pagination.find('.page-number');
|
||||
var $first = $pagination.find('.page-first');
|
||||
var $last = $pagination.find('.page-last');
|
||||
$pre.off('click').on('click', $.proxy(onPagePre, this));
|
||||
$pageList.off('click').on('click', $.proxy(onPageListChange, this));
|
||||
$number.off('click').on('click', $.proxy(onPageNumber, this));
|
||||
$first.off('click').on('click', $.proxy(onPageFirst, this));
|
||||
$last.off('click').on('click', $.proxy(onPageLast, this));
|
||||
$next.off('click').on('click', $.proxy(onPageNext, this));
|
||||
}
|
||||
var onPageListChange = function(event){
|
||||
var $this = $(event.currentTarget);
|
||||
$this.parent().addClass('active').siblings().removeClass('active');
|
||||
var $pagination = target.find(".fixed-table-pagination");
|
||||
options.pageSize = $this.text().toUpperCase() === target.totalRows ? target.totalRows : + $this.text();
|
||||
|
||||
if(target.totalRows < options.pageSize * options.pageNumber){
|
||||
options.pageNumber = 1;
|
||||
}
|
||||
$pagination.find('.page-size').text(options.pageSize);
|
||||
initServer();
|
||||
}
|
||||
var onPagePre = function(event){
|
||||
if ((options.pageNumber - 1) === 0) {
|
||||
options.pageNumber = target.totalPages;
|
||||
} else {
|
||||
options.pageNumber--;
|
||||
}
|
||||
initServer();
|
||||
}
|
||||
var onPageNumber = function(event){
|
||||
if (options.pageNumber == $(event.currentTarget).text()) {
|
||||
return;
|
||||
}
|
||||
options.pageNumber = $(event.currentTarget).text();
|
||||
initServer();
|
||||
}
|
||||
var onPageFirst = function(event){
|
||||
options.pageNumber = 1;
|
||||
initServer();
|
||||
}
|
||||
var onPageLast = function (event) {
|
||||
options.pageNumber = target.totalPages;
|
||||
initServer();
|
||||
}
|
||||
var onPageNext = function(event){
|
||||
if ((options.pageNumber + 1) > target.totalPages) {
|
||||
options.pageNumber = 1;
|
||||
} else {
|
||||
options.pageNumber++;
|
||||
}
|
||||
initServer();
|
||||
}
|
||||
// 动态设置表头宽度
|
||||
var autoTheadWidth = function(initFlag) {
|
||||
if(options.height>0){
|
||||
@@ -269,6 +475,14 @@
|
||||
$.each(data, function(index, item) {
|
||||
// 添加一个默认属性,用来判断当前节点有没有被显示
|
||||
item.isShow = false;
|
||||
// 是否分页
|
||||
if (options.pagination) {
|
||||
if (item.isTreeLeaf == undefined || item.isTreeLeaf == null) {
|
||||
item.isTreeLeaf = false;
|
||||
} else {
|
||||
item.isTreeLeaf = (item["isTreeLeaf"] == 1 ? true: false) || ((item["isTreeLeaf"] == 'true' || item["isTreeLeaf"] == true) ? true: false);
|
||||
}
|
||||
}
|
||||
// 顶级节点校验判断,兼容0,'0','',null
|
||||
var _defaultRootFlag = item[options.parentCode] == '0' ||
|
||||
item[options.parentCode] == 0 ||
|
||||
@@ -295,26 +509,26 @@
|
||||
});
|
||||
}
|
||||
// 递归获取子节点并且设置子节点
|
||||
var recursionNode = function(parentNode, lv, row_id, p_id) {
|
||||
var recursionNode = function(parentNode, lv, row_id, p_id, k) {
|
||||
var $tbody = target.find("tbody");
|
||||
var _ls = target.data_list["_n_" + parentNode[options.code]];
|
||||
var $tr = renderRow(parentNode, _ls ? true : false, lv, row_id, p_id);
|
||||
var $tr = renderRow(parentNode, _ls ? true : false, lv, row_id, p_id, options.pagination, k);
|
||||
$tbody.append($tr);
|
||||
if (_ls) {
|
||||
$.each(_ls, function(i, item) {
|
||||
var _child_row_id = row_id + "_" + i
|
||||
recursionNode(item, (lv + 1), _child_row_id, row_id)
|
||||
recursionNode(item, (lv + 1), _child_row_id, row_id, item[options.code])
|
||||
});
|
||||
}
|
||||
};
|
||||
// 绘制行
|
||||
var renderRow = function(item, isP, lv, row_id, p_id) {
|
||||
var renderRow = function(item, isP, lv, row_id, p_id, _pagination, k) {
|
||||
// 标记已显示
|
||||
item.isShow = true;
|
||||
item.row_id = row_id;
|
||||
item.p_id = p_id;
|
||||
item.lv = lv;
|
||||
var $tr = $('<tr id="' + row_id + '" pid="' + p_id + '"></tr>');
|
||||
var $tr = $('<tr id="' + row_id + '" data-id="' + k + '"pid="' + p_id + '"></tr>');
|
||||
var _icon = options.expanderCollapsedClass;
|
||||
if (options.expandAll) {
|
||||
$tr.css("display", "table");
|
||||
@@ -329,6 +543,10 @@
|
||||
$tr.css("display", "none");
|
||||
}
|
||||
_icon = options.expanderCollapsedClass;
|
||||
} else if (_pagination) {
|
||||
if (item.isTreeLeaf) {
|
||||
_icon = options.expanderCollapsedClass;
|
||||
}
|
||||
} else {
|
||||
$tr.css("display", "none");
|
||||
_icon = options.expanderCollapsedClass;
|
||||
@@ -375,12 +593,20 @@
|
||||
$td.text(getItemField(item, column.field));
|
||||
}
|
||||
if (options.expandColumn == index) {
|
||||
if (!isP) {
|
||||
$td.prepend('<span class="treetable-expander"></span>')
|
||||
} else {
|
||||
$td.prepend('<span class="treetable-expander ' + _icon + '"></span>')
|
||||
}
|
||||
for (var int = 0; int < (lv - 1); int++) {
|
||||
if (_pagination) {
|
||||
if (item["isTreeLeaf"]) {
|
||||
$td.prepend('<span class="treetable-expander ' + _icon + '"></span>');
|
||||
} else {
|
||||
$td.prepend('<span class="treetable-expander"></span>')
|
||||
}
|
||||
} else {
|
||||
if (!isP) {
|
||||
$td.prepend('<span class="treetable-expander"></span>')
|
||||
} else {
|
||||
$td.prepend('<span class="treetable-expander ' + _icon + '"></span>');
|
||||
}
|
||||
}
|
||||
for (var int = 0; int < (lv - options.expandColumn); int++) {
|
||||
$td.prepend('<span class="treetable-indent"></span>')
|
||||
}
|
||||
}
|
||||
@@ -440,6 +666,8 @@
|
||||
$(this).addClass("treetable-selected");
|
||||
}
|
||||
}
|
||||
var _rowData = target.data_obj["id_" + $(this).data('id')];
|
||||
calculateObjectValue(options, options.onClickRow, [_rowData], _rowData);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -452,26 +680,76 @@
|
||||
if (_isExpanded || _isCollapsed) {
|
||||
var tr = $(this).parent().parent();
|
||||
var row_id = tr.attr("id");
|
||||
var _ls = target.find("tbody").find("tr[id^='" + row_id + "_']"); //下所有
|
||||
if (_isExpanded) {
|
||||
$(this).removeClass(options.expanderExpandedClass);
|
||||
$(this).addClass(options.expanderCollapsedClass);
|
||||
if (_ls && _ls.length > 0) {
|
||||
$.each(_ls, function(index, item) {
|
||||
$(item).css("display", "none");
|
||||
});
|
||||
}
|
||||
var _id = tr.attr("data-id");
|
||||
var _ls = target.find("tbody").find("tr[id^='" + row_id + "_']");
|
||||
if (!options.pagination) {
|
||||
if (_isExpanded) {
|
||||
$(this).removeClass(options.expanderExpandedClass);
|
||||
$(this).addClass(options.expanderCollapsedClass);
|
||||
if (_ls && _ls.length > 0) {
|
||||
$.each(_ls, function(index, item) {
|
||||
$(item).css("display", "none");
|
||||
});
|
||||
}
|
||||
} else {
|
||||
$(this).removeClass(options.expanderCollapsedClass);
|
||||
$(this).addClass(options.expanderExpandedClass);
|
||||
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)) {
|
||||
$(item).css("display", "table");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$(this).removeClass(options.expanderCollapsedClass);
|
||||
$(this).addClass(options.expanderExpandedClass);
|
||||
var _ls = target.find("tbody").find("tr[id^='" + row_id + "_']");
|
||||
if (_ls && _ls.length > 0) {
|
||||
$.each(_ls, function(index, item) {
|
||||
// 父icon
|
||||
var _p_icon = $("#" + $(item).attr("pid")).children().eq(options.expandColumn).find(".treetable-expander");
|
||||
if (_p_icon.hasClass(options.expanderExpandedClass)) {
|
||||
$(item).css("display", "table");
|
||||
if (_isExpanded) {
|
||||
$.each(_ls, function(index, item) {
|
||||
$(item).css("display", "none");
|
||||
});
|
||||
} else {
|
||||
$.each(_ls, function(index, item) {
|
||||
var _icon = $(item).eq(options.expandColumn).find(".treetable-expander");
|
||||
if (_icon && _icon.hasClass(options.expanderExpandedClass)) {
|
||||
$(item).css("display", "table");
|
||||
} else {
|
||||
$(item).css("display", "table");
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (options.pagination) {
|
||||
var parms = {};
|
||||
parms[options.parentCode] = _id;
|
||||
if (options.dataUrl) {
|
||||
$.ajax({
|
||||
type: options.type,
|
||||
url: options.dataUrl,
|
||||
data: parms ? parms : options.ajaxParams,
|
||||
dataType: "json",
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
$("#" + row_id + "_load").remove();
|
||||
var list = data;
|
||||
data = list;
|
||||
target.appendData(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>'
|
||||
$("#" + row_id).after(_errorMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (_isExpanded) {
|
||||
$(this).removeClass(options.expanderExpandedClass);
|
||||
$(this).addClass(options.expanderCollapsedClass);
|
||||
} else {
|
||||
$(this).removeClass(options.expanderCollapsedClass);
|
||||
$(this).addClass(options.expanderExpandedClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -488,6 +766,9 @@
|
||||
target.appendData = function(data) {
|
||||
// 下边的操作主要是为了查询时让一些没有根节点的节点显示
|
||||
$.each(data, function(i, item) {
|
||||
if (options.pagination) {
|
||||
item.__nodes = (item["nodes"] == 1 ? true: false) || ((item["nodes"] == 'true' || item["nodes"] == true) ? true: false);
|
||||
}
|
||||
var _data = target.data_obj["id_" + item[options.code]];
|
||||
var _p_data = target.data_obj["id_" + item[options.parentCode]];
|
||||
var _c_list = target.data_list["_n_" + item[options.parentCode]];
|
||||
@@ -509,7 +790,7 @@
|
||||
}
|
||||
_lv = _p_data.lv + 1; //如果有父
|
||||
// 绘制行
|
||||
tr = renderRow(item, false, _lv, row_id, p_id);
|
||||
tr = renderRow(item, true, _lv, row_id, p_id, options.pagination, item[options.code]);
|
||||
|
||||
var _p_icon = $("#" + _p_data.row_id).children().eq(options.expandColumn).find(".treetable-expander");
|
||||
var _isExpanded = _p_icon.hasClass(options.expanderExpandedClass);
|
||||
@@ -531,12 +812,11 @@
|
||||
} else {
|
||||
// 计算父的同级下一行
|
||||
var _tmp_ls = _p_data.row_id.split("_");
|
||||
var _p_next = _p_data.row_id.substring(0, _p_data.row_id.length - 1) + (parseInt(_tmp_ls[_tmp_ls.length - 1]) + 1);
|
||||
// 画上
|
||||
$("#" + _p_next).before(tr);
|
||||
var _p_next = _p_data.row_id.substring(0, _p_data.row_id.length - (_tmp_ls[_tmp_ls.length - 1] + "").length) + (parseInt(_tmp_ls[_tmp_ls.length - 1]) + 1);
|
||||
$("#" + _p_data.row_id).after(tr);
|
||||
}
|
||||
} else {
|
||||
tr = renderRow(item, false, _lv, row_id, p_id);
|
||||
tr = renderRow(item, false, _lv, row_id, p_id, options.pagination, item[options.code]);
|
||||
if (_data) {
|
||||
$("#" + _data.row_id).before(tr);
|
||||
$("#" + _data.row_id).remove();
|
||||
@@ -660,6 +940,12 @@
|
||||
}
|
||||
return defaultValue;
|
||||
};
|
||||
var formatRecordsPerPage = function (pageNumber) {
|
||||
return '每页显示 ' + pageNumber + ' 条记录';
|
||||
};
|
||||
var formatShowingRows = function (pageFrom, pageTo, totalRows) {
|
||||
return '显示第 ' + pageFrom + ' 到第 ' + pageTo + ' 条记录,总共 ' + totalRows + ' 条记录。';
|
||||
};
|
||||
// 初始化
|
||||
init();
|
||||
return target;
|
||||
@@ -732,12 +1018,12 @@
|
||||
$.fn.bootstrapTreeTable.defaults = {
|
||||
code: 'code', // 选取记录返回的值,用于设置父子关系
|
||||
parentCode: 'parentCode', // 用于设置父子关系
|
||||
rootIdValue: null, // 设置根节点id值----可指定根节点,默认为null,"",0,"0"
|
||||
rootIdValue: 0, // 设置根节点id值----可指定根节点,默认为null,"",0,"0"
|
||||
data: null, // 构造table的数据集合
|
||||
type: "GET", // 请求数据的ajax类型
|
||||
url: null, // 请求数据的ajax的url
|
||||
ajaxParams: {}, // 请求数据的ajax的data属性
|
||||
expandColumn: 0, // 在哪一列上面显示展开按钮
|
||||
expandColumn: 1, // 在哪一列上面显示展开按钮
|
||||
expandAll: false, // 是否全部展开
|
||||
expandFirst: true, // 是否默认第一级展开--expandAll为false时生效
|
||||
striped: false, // 是否各行渐变色
|
||||
@@ -747,11 +1033,19 @@
|
||||
columns: [], // 列
|
||||
toolbar: null, // 顶部工具条
|
||||
height: 0, // 表格高度
|
||||
pagination: false, // 是否显示分页
|
||||
dataUrl: null, // 加载子节点异步请求数据url
|
||||
pageNumber: 1, // 当前页条数
|
||||
pageSize: 10, // 每页的记录行数
|
||||
onClickRow: null, // 单击某行事件
|
||||
pageList: [10, 25, 50], // 可供选择的每页的行数
|
||||
showTitle: true, // 是否采用title属性显示字段内容(被formatter格式化的字段不会显示)
|
||||
showSearch: true, // 是否显示检索信息
|
||||
showColumns: true, // 是否显示内容列下拉框
|
||||
showRefresh: true, // 是否显示刷新按钮
|
||||
expanderExpandedClass: 'glyphicon glyphicon-chevron-down', // 展开的按钮的图标
|
||||
paginationPreText: '‹',
|
||||
paginationNextText: '›',
|
||||
expanderExpandedClass: 'glyphicon glyphicon-chevron-down', // 展开的按钮的图标
|
||||
expanderCollapsedClass: 'glyphicon glyphicon-chevron-right', // 缩起的按钮的图标
|
||||
responseHandler: function(res) {
|
||||
return false;
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -948,6 +948,7 @@ table.rc-table-resizing thead > th > a {
|
||||
.bootstrap-tree-table .table{border-bottom: 0px solid #e7eaec!important;}
|
||||
.bootstrap-tree-table .table-bordered .treetable-thead th {border-left: 1px solid #e7eaec!important;}
|
||||
.bootstrap-tree-table .table-bordered .treetable-tbody td {border-right: 1px solid #e7eaec!important;}
|
||||
.bootstrap-tree-table .fixed-table-pagination .pagination-detail {margin-top: 10px;margin-bottom: 10px;}
|
||||
|
||||
/** 首页样式 **/
|
||||
.ax_close_max {
|
||||
|
||||
@@ -511,7 +511,7 @@ window.onload = function() {
|
||||
return _stopIt(event);
|
||||
}
|
||||
var type_e = elem.type.toUpperCase();
|
||||
if (name == 'INPUT' && (type_e != 'TEXT' && type_e != 'TEXTAREA' && type_e != 'PASSWORD' && type_e != 'FILE' && type_e != 'SEARCH' && type_e != 'NUMBER')) {
|
||||
if (name == 'INPUT' && (type_e != 'TEXT' && type_e != 'TEXTAREA' && type_e != 'PASSWORD' && type_e != 'FILE' && type_e != 'SEARCH' && type_e != 'NUMBER' && type_e != 'EMAIL')) {
|
||||
return _stopIt(event);
|
||||
}
|
||||
if (name == 'INPUT' && (elem.readOnly == true || elem.disabled == true)) {
|
||||
|
||||
@@ -539,6 +539,9 @@ var table = {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (actions.length === 0) {
|
||||
actions.push($.common.sprintf("<span>%s</span>", value))
|
||||
}
|
||||
return actions.join('');
|
||||
},
|
||||
// 回显数据字典(字符串数组)
|
||||
@@ -549,13 +552,18 @@ var table = {
|
||||
var currentSeparator = $.common.isEmpty(separator) ? "," : separator;
|
||||
var actions = [];
|
||||
$.each(value.split(currentSeparator), function(i, val) {
|
||||
var match = false
|
||||
$.each(datas, function(index, dict) {
|
||||
if (dict.dictValue == ('' + val)) {
|
||||
var listClass = $.common.equals("default", dict.listClass) || $.common.isEmpty(dict.listClass) ? "" : "badge badge-" + dict.listClass;
|
||||
actions.push($.common.sprintf("<span class='%s'>%s </span>", listClass, dict.dictLabel));
|
||||
actions.push($.common.sprintf("<span class='%s'>%s</span>", listClass, dict.dictLabel));
|
||||
match = true
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (!match) {
|
||||
actions.push($.common.sprintf("<span> %s </span>", val));
|
||||
}
|
||||
});
|
||||
return actions.join('');
|
||||
},
|
||||
@@ -588,10 +596,13 @@ var table = {
|
||||
id: "bootstrap-tree-table",
|
||||
type: 1, // 0 代表bootstrapTable 1代表bootstrapTreeTable
|
||||
height: 0,
|
||||
rootIdValue: null,
|
||||
rootIdValue: 0,
|
||||
ajaxParams: {},
|
||||
toolbar: "toolbar",
|
||||
striped: false,
|
||||
pagination: false,
|
||||
pageSize: 10,
|
||||
pageList: [10, 25, 50],
|
||||
expandColumn: 1,
|
||||
showSearch: true,
|
||||
showRefresh: true,
|
||||
@@ -612,6 +623,10 @@ var table = {
|
||||
ajaxParams: options.ajaxParams, // 请求数据的ajax的data属性
|
||||
rootIdValue: options.rootIdValue, // 设置指定根节点id值
|
||||
height: options.height, // 表格树的高度
|
||||
pagination: options.pagination, // 是否显示分页
|
||||
dataUrl: options.dataUrl, // 加载子节点异步请求数据url
|
||||
pageSize: options.pageSize, // 每页的记录行数
|
||||
pageList: options.pageList, // 可供选择的每页的行数
|
||||
expandColumn: options.expandColumn, // 在哪一列上面显示展开按钮
|
||||
striped: options.striped, // 是否显示行间隔色
|
||||
bordered: options.bordered, // 是否显示边框
|
||||
@@ -622,6 +637,7 @@ var table = {
|
||||
expandAll: options.expandAll, // 是否全部展开
|
||||
expandFirst: options.expandFirst, // 是否默认第一级展开--expandAll为false时生效
|
||||
columns: options.columns, // 显示列信息(*)
|
||||
onClickRow: options.onClickRow, // 单击某行事件
|
||||
responseHandler: $.treeTable.responseHandler, // 在加载服务器发送来的数据之前处理函数
|
||||
onLoadSuccess: $.treeTable.onLoadSuccess // 当所有数据被加载时触发处理函数
|
||||
});
|
||||
@@ -1313,7 +1329,7 @@ var table = {
|
||||
},
|
||||
// 校验封装处理
|
||||
validate: {
|
||||
// 判断返回标识是否唯一 false 不存在 true 存在
|
||||
// 判断返回标识是否唯一 false 为存在 true 为不存在
|
||||
unique: function (value) {
|
||||
if (value == "0") {
|
||||
return true;
|
||||
|
||||
@@ -33,11 +33,11 @@ function login() {
|
||||
if (r.code == web_status.SUCCESS) {
|
||||
location.href = ctx + 'index';
|
||||
} else {
|
||||
$.modal.closeLoading();
|
||||
$('.imgcode').click();
|
||||
$(".code").val("");
|
||||
$.modal.msg(r.msg);
|
||||
}
|
||||
$.modal.closeLoading();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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.2
|
||||
<b>当前版本:</b>v4.7.3
|
||||
</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.2
|
||||
<b>当前版本:</b>v4.7.3
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-warning">开源免费</span>
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
var rsp = data.response;
|
||||
log.info("return url:" + rsp.url)
|
||||
log.info("reutrn fileName:" + rsp.fileName)
|
||||
log.info("reutrn newFileName:" + rsp.newFileName)
|
||||
log.info("return originalFilename:" + rsp.originalFilename)
|
||||
}).on('fileremoved', function (event, id, index) {
|
||||
$("input[name='" + event.currentTarget.id + "']").val('')
|
||||
})
|
||||
@@ -62,6 +64,8 @@
|
||||
var rsp = data.response;
|
||||
log.info("return urls:" + rsp.urls)
|
||||
log.info("reutrn fileNames:" + rsp.fileNames)
|
||||
log.info("reutrn newFileNames:" + rsp.newFileNames)
|
||||
log.info("return originalFilenames:" + rsp.originalFilenames)
|
||||
}).on('fileremoved', function (event, id, index) {
|
||||
$("input[name='" + event.currentTarget.id + "']").val('')
|
||||
})
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
<body class="gray-bg">
|
||||
<div class="row border-bottom white-bg dashboard-header">
|
||||
<div class="col-sm-12">
|
||||
<p>ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。 <a href="http://echarts.baidu.com/doc/about.html" target="_blank">了解更多</a>
|
||||
<p>ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。 <a href="https://echarts.apache.org/handbook/zh/get-started/" target="_blank">了解更多</a>
|
||||
</p>
|
||||
<p>ECharts官网:<a href="http://echarts.baidu.com/" target="_blank">http://echarts.baidu.com/</a>
|
||||
<p>ECharts官网:<a href="https://echarts.apache.org/" target="_blank">https://echarts.apache.org/</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
|
||||
<head>
|
||||
<th:block th:include="include :: header('异步加载表格树')" />
|
||||
</head>
|
||||
<body class="gray-bg">
|
||||
<div class="container-div">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 search-collapse">
|
||||
<form id="formId">
|
||||
<div class="select-list">
|
||||
<ul>
|
||||
<li>
|
||||
<label>区域名称:</label>
|
||||
<input type="text" name="areaName"/>
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.treeTable.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>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="btn-group-sm" id="toolbar" role="group">
|
||||
<a class="btn btn-info" id="expandAllBtn">
|
||||
<i class="fa fa-exchange"></i> 展开/折叠
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-sm-12 select-table table-striped">
|
||||
<table id="bootstrap-tree-table"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script th:inline="javascript">
|
||||
var prefix = ctx + "demo/table";
|
||||
|
||||
$(function() {
|
||||
var options = {
|
||||
code: "id",
|
||||
parentCode: "parentId",
|
||||
uniqueId: "id",
|
||||
expandAll: false,
|
||||
expandFirst: false,
|
||||
expandColumn: 1,
|
||||
pagination: true, // 开启分页
|
||||
url: prefix + "/tree/list", // 列表请求
|
||||
dataUrl: prefix + "/tree/listChild", // 子节点异步请求
|
||||
onClickRow: onClickRow,
|
||||
columns: [{
|
||||
field: 'selectItem',
|
||||
radio: true
|
||||
},
|
||||
{
|
||||
field: 'areaName',
|
||||
title: '区域名称',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
field: 'areaCode',
|
||||
title: '区域代码',
|
||||
align: 'left'
|
||||
},
|
||||
{
|
||||
field: 'simplePy',
|
||||
title: '首字母简拼',
|
||||
align: 'left'
|
||||
},
|
||||
{
|
||||
field: 'pinYin',
|
||||
title: '名称全拼',
|
||||
align: 'left'
|
||||
}]
|
||||
};
|
||||
$.treeTable.init(options);
|
||||
});
|
||||
|
||||
function onClickRow(row, $element){
|
||||
// alert("单击行id:" + row.id + " name:" + row.name);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -7,6 +7,9 @@
|
||||
<div class="container-div">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 select-table table-striped">
|
||||
<!-- 点击事件的方式打开使用 detailViewIcon: false and detailViewByClick: true
|
||||
data-detail-view-icon="false"
|
||||
data-detail-view-by-click="true" -->
|
||||
<table id="bootstrap-table"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
<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.2}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/font-awesome.min.css?v=4.7.3}" 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.2}" rel="stylesheet"/>
|
||||
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.3}" rel="stylesheet"/>
|
||||
</head>
|
||||
|
||||
<!-- 通用JS -->
|
||||
@@ -36,8 +36,8 @@
|
||||
<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.2}"></script>
|
||||
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.2}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.7.3}"></script>
|
||||
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.3}"></script>
|
||||
</div>
|
||||
|
||||
<!-- ztree树插件 -->
|
||||
|
||||
@@ -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?v=20200902}" rel="stylesheet"/>
|
||||
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.2}" rel="stylesheet"/>
|
||||
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.3}" rel="stylesheet"/>
|
||||
</head>
|
||||
<body class="fixed-sidebar full-height-layout gray-bg" th:classappend="${isMobile} ? 'canvas-menu'" style="overflow: hidden">
|
||||
<div id="wrapper">
|
||||
@@ -146,6 +146,7 @@
|
||||
<li><a class="menuItem" th:href="@{/demo/table/print}">表格打印配置</a></li>
|
||||
<li><a class="menuItem" th:href="@{/demo/table/dynamicColumns}">表格动态列</a></li>
|
||||
<li><a class="menuItem" th:href="@{/demo/table/customView}">自定义视图分页</a></li>
|
||||
<li><a class="menuItem" th:href="@{/demo/table/asynTree}">异步加载表格树</a></li>
|
||||
<li><a class="menuItem" th:href="@{/demo/table/other}">表格其他操作</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -315,8 +316,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.2}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.7.2}"></script>
|
||||
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.3}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.7.3}"></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.2}" rel="stylesheet"/>
|
||||
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.3}" rel="stylesheet"/>
|
||||
</head>
|
||||
<body class="fixed-sidebar full-height-layout gray-bg" th:classappend="${isMobile} ? 'canvas-menu'" style="overflow: hidden">
|
||||
<div id="wrapper">
|
||||
@@ -127,6 +127,7 @@
|
||||
<li><a class="menuItem" th:href="@{/demo/table/print}">表格打印配置</a></li>
|
||||
<li><a class="menuItem" th:href="@{/demo/table/dynamicColumns}">表格动态列</a></li>
|
||||
<li><a class="menuItem" th:href="@{/demo/table/customView}">自定义视图分页</a></li>
|
||||
<li><a class="menuItem" th:href="@{/demo/table/asynTree}">异步加载表格树</a></li>
|
||||
<li><a class="menuItem" th:href="@{/demo/table/other}">表格其他操作</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -262,8 +263,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.2}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.7.2}"></script>
|
||||
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.3}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.7.3}"></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.2}"></script>
|
||||
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.3}"></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.2}" rel="stylesheet"/>
|
||||
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.7.3}" rel="stylesheet"/>
|
||||
<!-- 360浏览器急速模式 -->
|
||||
<meta name="renderer" content="webkit">
|
||||
<!-- 避免IE使用兼容模式 -->
|
||||
@@ -65,7 +65,7 @@
|
||||
</div>
|
||||
<div class="signup-footer">
|
||||
<div class="pull-left">
|
||||
Copyright © 2018-2021 ruoyi.vip All Rights Reserved. <br>
|
||||
Copyright © 2018-2022 ruoyi.vip All Rights Reserved. <br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -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.2}"></script>
|
||||
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.3}"></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> <a href="https://jq.qq.com/?_wv=1027&k=up9k3ZXJ" target="_blank">264355400</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> <a href="https://jq.qq.com/?_wv=1027&k=540WfdEr" target="_blank">298522656</a>
|
||||
</p>
|
||||
<p><i class="fa fa-weixin"></i> 微信:<a href="javascript:;">/ *若依</a>
|
||||
</p>
|
||||
@@ -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="#v473">v4.7.3</a><code class="pull-right">2022.03.01</code>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="v473" class="panel-collapse collapse in">
|
||||
<div class="panel-body">
|
||||
<ol>
|
||||
<li>表格树支持分页/异步加载</li>
|
||||
<li>代码生成预览支持复制内容</li>
|
||||
<li>定时任务默认保存到内存中执行</li>
|
||||
<li>代码生成同步保留必填/类型选项</li>
|
||||
<li>页面若未匹配到字典标签则返回原字典值</li>
|
||||
<li>用户访问控制时校验数据权限,防止越权</li>
|
||||
<li>导出Excel时屏蔽公式,防止CSV注入风险</li>
|
||||
<li>升级spring-boot到最新版本2.5.10</li>
|
||||
<li>升级spring-boot-mybatis到最新版2.2.2</li>
|
||||
<li>升级pagehelper到最新版1.4.1</li>
|
||||
<li>升级oshi到最新版本6.1.2</li>
|
||||
<li>升级bootstrap-table到最新版本1.19.1</li>
|
||||
<li>服务监控新增运行参数信息显示</li>
|
||||
<li>定时任务目标字符串验证包名白名单</li>
|
||||
<li>文件上传接口新增原/新文件名返回参数</li>
|
||||
<li>定时任务屏蔽违规的字符</li>
|
||||
<li>分页数据新增分页参数合理化参数</li>
|
||||
<li>表格父子视图添加点击事件打开示例</li>
|
||||
<li>优化上传文件名称命名规则</li>
|
||||
<li>优化加载字典缓存数据</li>
|
||||
<li>优化任务队列满时任务拒绝策略</li>
|
||||
<li>优化IE11上传预览不显示的问题</li>
|
||||
<li>优化Excel格式化不同类型的日期对象</li>
|
||||
<li>优化国际化配置多余的zh请求问题</li>
|
||||
<li>优化新版Chrome浏览器回退出现的遮罩层</li>
|
||||
<li>修复EMAIL类型回退键被禁止问题</li>
|
||||
<li>修复Xss注解字段值为空时的异常问题</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="#v472">v4.7.2</a><code class="pull-right">2021.12.23</code>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="v472" class="panel-collapse collapse in">
|
||||
<div id="v472" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<ol>
|
||||
<li>自定义xss校验注解实现</li>
|
||||
|
||||
@@ -174,6 +174,10 @@
|
||||
<td colspan="1">项目路径</td>
|
||||
<td colspan="3" th:text="${server.sys.userDir}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">运行参数</td>
|
||||
<td colspan="3" th:text="${server.jvm.inputArgs}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -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.2}" rel="stylesheet"/>
|
||||
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.7.3}" rel="stylesheet"/>
|
||||
<!-- 360浏览器急速模式 -->
|
||||
<meta name="renderer" content="webkit">
|
||||
<!-- 避免IE使用兼容模式 -->
|
||||
@@ -64,7 +64,7 @@
|
||||
</div>
|
||||
<div class="signup-footer">
|
||||
<div class="pull-left">
|
||||
© 2018-2021 All Rights Reserved. RuoYi <br>
|
||||
© 2018-2022 All Rights Reserved. RuoYi <br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -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.2}"></script>
|
||||
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.3}"></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.2}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.7.3}"></script>
|
||||
<script type="text/javascript">
|
||||
//皮肤样式列表
|
||||
var skins = ["skin-blue", "skin-green", "skin-purple", "skin-red", "skin-yellow"];
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.7.2</version>
|
||||
<version>4.7.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -49,7 +49,8 @@ public class ThreadPoolConfig
|
||||
protected ScheduledExecutorService scheduledExecutorService()
|
||||
{
|
||||
return new ScheduledThreadPoolExecutor(corePoolSize,
|
||||
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build())
|
||||
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy())
|
||||
{
|
||||
@Override
|
||||
protected void afterExecute(Runnable r, Throwable t)
|
||||
|
||||
@@ -57,26 +57,6 @@ public class Constants
|
||||
*/
|
||||
public static final String LOGIN_FAIL = "Error";
|
||||
|
||||
/**
|
||||
* 当前记录起始索引
|
||||
*/
|
||||
public static final String PAGE_NUM = "pageNum";
|
||||
|
||||
/**
|
||||
* 每页显示记录数
|
||||
*/
|
||||
public static final String PAGE_SIZE = "pageSize";
|
||||
|
||||
/**
|
||||
* 排序列
|
||||
*/
|
||||
public static final String ORDER_BY_COLUMN = "orderByColumn";
|
||||
|
||||
/**
|
||||
* 排序的方向 "desc" 或者 "asc".
|
||||
*/
|
||||
public static final String IS_ASC = "isAsc";
|
||||
|
||||
/**
|
||||
* 系统用户授权缓存
|
||||
*/
|
||||
@@ -110,16 +90,26 @@ public class Constants
|
||||
/**
|
||||
* RMI 远程方法调用
|
||||
*/
|
||||
public static final String LOOKUP_RMI = "rmi://";
|
||||
public static final String LOOKUP_RMI = "rmi:";
|
||||
|
||||
/**
|
||||
* LDAP 远程方法调用
|
||||
*/
|
||||
public static final String LOOKUP_LDAP = "ldap://";
|
||||
public static final String LOOKUP_LDAP = "ldap:";
|
||||
|
||||
/**
|
||||
* LDAPS 远程方法调用
|
||||
*/
|
||||
public static final String LOOKUP_LDAPS = "ldaps:";
|
||||
|
||||
/**
|
||||
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
|
||||
*/
|
||||
public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" };
|
||||
|
||||
/**
|
||||
* 定时任务违规的字符
|
||||
*/
|
||||
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
|
||||
"org.springframework.jndi" };
|
||||
"org.springframework", "org.apache", "com.ruoyi.common.utils.file" };
|
||||
}
|
||||
@@ -106,6 +106,9 @@ public class GenConstants
|
||||
/** 模糊查询 */
|
||||
public static final String QUERY_LIKE = "LIKE";
|
||||
|
||||
/** 相等查询 */
|
||||
public static final String QUERY_EQ = "EQ";
|
||||
|
||||
/** 需要 */
|
||||
public static final String REQUIRE = "1";
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ public class PageDomain
|
||||
/** 排序的方向desc或者asc */
|
||||
private String isAsc = "asc";
|
||||
|
||||
/** 分页参数合理化 */
|
||||
private Boolean reasonable = true;
|
||||
|
||||
public String getOrderBy()
|
||||
{
|
||||
if (StringUtils.isEmpty(orderByColumn))
|
||||
@@ -69,4 +72,18 @@ public class PageDomain
|
||||
{
|
||||
this.isAsc = isAsc;
|
||||
}
|
||||
|
||||
public Boolean getReasonable()
|
||||
{
|
||||
if (StringUtils.isNull(reasonable))
|
||||
{
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
return reasonable;
|
||||
}
|
||||
|
||||
public void setReasonable(Boolean reasonable)
|
||||
{
|
||||
this.reasonable = reasonable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.ruoyi.common.core.page;
|
||||
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
|
||||
/**
|
||||
@@ -10,16 +9,42 @@ import com.ruoyi.common.utils.ServletUtils;
|
||||
*/
|
||||
public class TableSupport
|
||||
{
|
||||
/**
|
||||
* 当前记录起始索引
|
||||
*/
|
||||
public static final String PAGE_NUM = "pageNum";
|
||||
|
||||
/**
|
||||
* 每页显示记录数
|
||||
*/
|
||||
public static final String PAGE_SIZE = "pageSize";
|
||||
|
||||
/**
|
||||
* 排序列
|
||||
*/
|
||||
public static final String ORDER_BY_COLUMN = "orderByColumn";
|
||||
|
||||
/**
|
||||
* 排序的方向 "desc" 或者 "asc".
|
||||
*/
|
||||
public static final String IS_ASC = "isAsc";
|
||||
|
||||
/**
|
||||
* 分页参数合理化
|
||||
*/
|
||||
public static final String REASONABLE = "reasonable";
|
||||
|
||||
/**
|
||||
* 封装分页对象
|
||||
*/
|
||||
public static PageDomain getPageDomain()
|
||||
{
|
||||
PageDomain pageDomain = new PageDomain();
|
||||
pageDomain.setPageNum(ServletUtils.getParameterToInt(Constants.PAGE_NUM));
|
||||
pageDomain.setPageSize(ServletUtils.getParameterToInt(Constants.PAGE_SIZE));
|
||||
pageDomain.setOrderByColumn(ServletUtils.getParameter(Constants.ORDER_BY_COLUMN));
|
||||
pageDomain.setIsAsc(ServletUtils.getParameter(Constants.IS_ASC));
|
||||
pageDomain.setPageNum(ServletUtils.getParameterToInt(PAGE_NUM));
|
||||
pageDomain.setPageSize(ServletUtils.getParameterToInt(PAGE_SIZE));
|
||||
pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN));
|
||||
pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC));
|
||||
pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE));
|
||||
return pageDomain;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ public class AddressUtils
|
||||
|
||||
public static String getRealAddressByIP(String ip)
|
||||
{
|
||||
String address = UNKNOWN;
|
||||
// 内网不查询
|
||||
if (IpUtils.internalIp(ip))
|
||||
{
|
||||
@@ -50,6 +49,6 @@ public class AddressUtils
|
||||
log.error("获取地理位置异常 {}", e);
|
||||
}
|
||||
}
|
||||
return address;
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,11 @@ package com.ruoyi.common.utils;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
@@ -22,7 +27,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
|
||||
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
|
||||
|
||||
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
|
||||
private static String[] parsePatterns = {
|
||||
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
|
||||
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
|
||||
@@ -121,7 +126,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取服务器启动时间
|
||||
*/
|
||||
@@ -160,4 +165,23 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
|
||||
// long sec = diff % nd % nh % nm / ns;
|
||||
return day + "天" + hour + "小时" + min + "分钟";
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加 LocalDateTime ==> Date
|
||||
*/
|
||||
public static Date toDate(LocalDateTime temporalAccessor)
|
||||
{
|
||||
ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
|
||||
return Date.from(zdt.toInstant());
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加 LocalDate ==> Date
|
||||
*/
|
||||
public static Date toDate(LocalDate temporalAccessor)
|
||||
{
|
||||
LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
|
||||
ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
|
||||
return Date.from(zdt.toInstant());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,7 @@ public class DictUtils
|
||||
Object cacheObj = CacheUtils.get(getCacheName(), getCacheKey(key));
|
||||
if (StringUtils.isNotNull(cacheObj))
|
||||
{
|
||||
List<SysDictData> DictDatas = StringUtils.cast(cacheObj);
|
||||
return DictDatas;
|
||||
return StringUtils.cast(cacheObj);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -91,7 +90,7 @@ public class DictUtils
|
||||
{
|
||||
if (value.equals(dict.getDictValue()))
|
||||
{
|
||||
propertyString.append(dict.getDictLabel() + separator);
|
||||
propertyString.append(dict.getDictLabel()).append(separator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -131,7 +130,7 @@ public class DictUtils
|
||||
{
|
||||
if (label.equals(dict.getDictLabel()))
|
||||
{
|
||||
propertyString.append(dict.getDictValue() + separator);
|
||||
propertyString.append(dict.getDictValue()).append(separator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,7 @@ public class ExceptionUtil
|
||||
{
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw, true));
|
||||
String str = sw.toString();
|
||||
return str;
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
public static String getRootErrorMessage(Exception e)
|
||||
|
||||
@@ -23,7 +23,8 @@ public class PageUtils extends PageHelper
|
||||
if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
|
||||
{
|
||||
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
|
||||
PageHelper.startPage(pageNum, pageSize, orderBy);
|
||||
Boolean reasonable = pageDomain.getReasonable();
|
||||
PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,22 @@ public class ServletUtils
|
||||
return Convert.toInt(getRequest().getParameter(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Boolean参数
|
||||
*/
|
||||
public static Boolean getParameterToBool(String name)
|
||||
{
|
||||
return Convert.toBool(getRequest().getParameter(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Boolean参数
|
||||
*/
|
||||
public static Boolean getParameterToBool(String name, Boolean defaultValue)
|
||||
{
|
||||
return Convert.toBool(getRequest().getParameter(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取request
|
||||
*/
|
||||
@@ -113,13 +129,13 @@ public class ServletUtils
|
||||
public static boolean isAjaxRequest(HttpServletRequest request)
|
||||
{
|
||||
String accept = request.getHeader("accept");
|
||||
if (accept != null && accept.indexOf("application/json") != -1)
|
||||
if (accept != null && accept.contains("application/json"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
String xRequestedWith = request.getHeader("X-Requested-With");
|
||||
if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1)
|
||||
if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -131,11 +147,7 @@ public class ServletUtils
|
||||
}
|
||||
|
||||
String ajax = request.getParameter("__ajax");
|
||||
if (StringUtils.inStringIgnoreCase(ajax, "json", "xml"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return StringUtils.inStringIgnoreCase(ajax, "json", "xml");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -552,4 +552,53 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
||||
{
|
||||
return (T) obj;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。
|
||||
*
|
||||
* @param num 数字对象
|
||||
* @param size 字符串指定长度
|
||||
* @return 返回数字的字符串格式,该字符串为指定长度。
|
||||
*/
|
||||
public static final String padl(final Number num, final int size)
|
||||
{
|
||||
return padl(num.toString(), size, '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。
|
||||
*
|
||||
* @param s 原始字符串
|
||||
* @param size 字符串指定长度
|
||||
* @param c 用于补齐的字符
|
||||
* @return 返回指定长度的字符串,由原字符串左补齐或截取得到。
|
||||
*/
|
||||
public static final String padl(final String s, final int size, final char c)
|
||||
{
|
||||
final StringBuilder sb = new StringBuilder(size);
|
||||
if (s != null)
|
||||
{
|
||||
final int len = s.length();
|
||||
if (s.length() <= size)
|
||||
{
|
||||
for (int i = size - len; i > 0; i--)
|
||||
{
|
||||
sb.append(c);
|
||||
}
|
||||
sb.append(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
return s.substring(len - size, len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = size; i > 0; i--)
|
||||
{
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.ruoyi.common.utils.file;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.common.config.RuoYiConfig;
|
||||
@@ -11,7 +12,7 @@ import com.ruoyi.common.exception.file.FileSizeLimitExceededException;
|
||||
import com.ruoyi.common.exception.file.InvalidExtensionException;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.uuid.IdUtils;
|
||||
import com.ruoyi.common.utils.uuid.Seq;
|
||||
|
||||
/**
|
||||
* 文件上传工具类
|
||||
@@ -100,7 +101,7 @@ public class FileUploadUtils
|
||||
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
|
||||
InvalidExtensionException
|
||||
{
|
||||
int fileNamelength = file.getOriginalFilename().length();
|
||||
int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
|
||||
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
|
||||
{
|
||||
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
|
||||
@@ -112,8 +113,7 @@ public class FileUploadUtils
|
||||
|
||||
File desc = getAbsoluteFile(baseDir, fileName);
|
||||
file.transferTo(desc);
|
||||
String pathFileName = getPathFileName(baseDir, fileName);
|
||||
return pathFileName;
|
||||
return getPathFileName(baseDir, fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,10 +121,8 @@ public class FileUploadUtils
|
||||
*/
|
||||
public static final String extractFilename(MultipartFile file)
|
||||
{
|
||||
String fileName = file.getOriginalFilename();
|
||||
String extension = getExtension(file);
|
||||
fileName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
|
||||
return fileName;
|
||||
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
|
||||
FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
|
||||
}
|
||||
|
||||
public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
|
||||
@@ -145,8 +143,7 @@ public class FileUploadUtils
|
||||
{
|
||||
int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
|
||||
String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
|
||||
String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
|
||||
return pathFileName;
|
||||
return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,7 +158,7 @@ public class FileUploadUtils
|
||||
throws FileSizeLimitExceededException, InvalidExtensionException
|
||||
{
|
||||
long size = file.getSize();
|
||||
if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE)
|
||||
if (size > DEFAULT_MAX_SIZE)
|
||||
{
|
||||
throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
|
||||
}
|
||||
@@ -227,7 +224,7 @@ public class FileUploadUtils
|
||||
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
|
||||
if (StringUtils.isEmpty(extension))
|
||||
{
|
||||
extension = MimeTypeUtils.getExtension(file.getContentType());
|
||||
extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType()));
|
||||
}
|
||||
return extension;
|
||||
}
|
||||
|
||||
@@ -253,4 +253,22 @@ public class FileUtils
|
||||
}
|
||||
return strFileExtendName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取名称
|
||||
*
|
||||
* @param fileName 路径名称
|
||||
* @return 没有文件路径的名称
|
||||
*/
|
||||
public static String getName(String fileName)
|
||||
{
|
||||
if (fileName == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int lastUnixPos = fileName.lastIndexOf('/');
|
||||
int lastWindowsPos = fileName.lastIndexOf('\\');
|
||||
int index = Math.max(lastUnixPos, lastWindowsPos);
|
||||
return fileName.substring(index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.ruoyi.common.utils.file;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
@@ -59,13 +58,12 @@ public class ImageUtils
|
||||
/**
|
||||
* 读取文件为字节数据
|
||||
*
|
||||
* @param key 地址
|
||||
* @param url 地址
|
||||
* @return 字节数据
|
||||
*/
|
||||
public static byte[] readFile(String url)
|
||||
{
|
||||
InputStream in = null;
|
||||
ByteArrayOutputStream baos = null;
|
||||
try
|
||||
{
|
||||
if (url.startsWith("http"))
|
||||
@@ -95,7 +93,6 @@ public class ImageUtils
|
||||
finally
|
||||
{
|
||||
IOUtils.closeQuietly(in);
|
||||
IOUtils.closeQuietly(baos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.net.ConnectException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.cert.X509Certificate;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
@@ -130,9 +131,8 @@ public class HttpUtils
|
||||
StringBuilder result = new StringBuilder();
|
||||
try
|
||||
{
|
||||
String urlNameString = url;
|
||||
log.info("sendPost - {}", urlNameString);
|
||||
URL realUrl = new URL(urlNameString);
|
||||
log.info("sendPost - {}", url);
|
||||
URL realUrl = new URL(url);
|
||||
URLConnection conn = realUrl.openConnection();
|
||||
conn.setRequestProperty("accept", "*/*");
|
||||
conn.setRequestProperty("connection", "Keep-Alive");
|
||||
@@ -144,7 +144,7 @@ public class HttpUtils
|
||||
out = new PrintWriter(conn.getOutputStream());
|
||||
out.print(param);
|
||||
out.flush();
|
||||
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
|
||||
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null)
|
||||
{
|
||||
@@ -218,7 +218,7 @@ public class HttpUtils
|
||||
{
|
||||
if (ret != null && !ret.trim().equals(""))
|
||||
{
|
||||
result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8"));
|
||||
result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
log.info("recv - {}", result);
|
||||
|
||||
@@ -9,6 +9,8 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
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.Comparator;
|
||||
@@ -86,6 +88,8 @@ public class ExcelUtil<T>
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
|
||||
|
||||
public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
|
||||
|
||||
/**
|
||||
* Excel sheet最大行数,默认65536
|
||||
*/
|
||||
@@ -130,7 +134,7 @@ public class ExcelUtil<T>
|
||||
* 当前行号
|
||||
*/
|
||||
private int rownum;
|
||||
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
@@ -312,7 +316,7 @@ public class ExcelUtil<T>
|
||||
String dateFormat = field.getAnnotation(Excel.class).dateFormat();
|
||||
if (StringUtils.isNotEmpty(dateFormat))
|
||||
{
|
||||
val = DateUtils.parseDateToStr(dateFormat, (Date) val);
|
||||
val = parseDateToStr(dateFormat, (Date) val);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -407,7 +411,7 @@ public class ExcelUtil<T>
|
||||
{
|
||||
return exportExcel(list, sheetName, StringUtils.EMPTY);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对list数据源将其里面的数据导入到excel表单
|
||||
*
|
||||
@@ -708,7 +712,13 @@ public class ExcelUtil<T>
|
||||
{
|
||||
if (ColumnType.STRING == attr.cellType())
|
||||
{
|
||||
cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix());
|
||||
String cellValue = Convert.toStr(value);
|
||||
// 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。
|
||||
if (StringUtils.containsAny(cellValue, FORMULA_STR))
|
||||
{
|
||||
cellValue = StringUtils.replaceEach(cellValue, FORMULA_STR, new String[] { "\t=", "\t-", "\t+", "\t@" });
|
||||
}
|
||||
cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix());
|
||||
}
|
||||
else if (ColumnType.NUMERIC == attr.cellType())
|
||||
{
|
||||
@@ -813,7 +823,7 @@ public class ExcelUtil<T>
|
||||
String dictType = attr.dictType();
|
||||
if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
|
||||
{
|
||||
cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value));
|
||||
cell.setCellValue(parseDateToStr(dateFormat, (Date) value));
|
||||
}
|
||||
else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
|
||||
{
|
||||
@@ -1111,7 +1121,7 @@ public class ExcelUtil<T>
|
||||
if (StringUtils.isNotEmpty(excel.targetAttr()))
|
||||
{
|
||||
String target = excel.targetAttr();
|
||||
if (target.indexOf(".") > -1)
|
||||
if (target.contains("."))
|
||||
{
|
||||
String[] targets = target.split("[.]");
|
||||
for (String name : targets)
|
||||
@@ -1206,7 +1216,7 @@ public class ExcelUtil<T>
|
||||
for (Object[] os : this.fields)
|
||||
{
|
||||
Excel excel = (Excel) os[1];
|
||||
maxHeight = maxHeight > excel.height() ? maxHeight : excel.height();
|
||||
maxHeight = Math.max(maxHeight, excel.height());
|
||||
}
|
||||
return (short) (maxHeight * 20);
|
||||
}
|
||||
@@ -1386,4 +1396,37 @@ public class ExcelUtil<T>
|
||||
}
|
||||
return sheetIndexPicMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化不同类型的日期对象
|
||||
*
|
||||
* @param dateFormat 日期格式
|
||||
* @param val 被格式化的日期对象
|
||||
* @return 格式化后的日期字符
|
||||
*/
|
||||
public String parseDateToStr(String dateFormat, Object val)
|
||||
{
|
||||
if (val == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
String str;
|
||||
if (val instanceof Date)
|
||||
{
|
||||
str = DateUtils.parseDateToStr(dateFormat, (Date) val);
|
||||
}
|
||||
else if (val instanceof LocalDateTime)
|
||||
{
|
||||
str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDateTime) val));
|
||||
}
|
||||
else if (val instanceof LocalDate)
|
||||
{
|
||||
str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDate) val));
|
||||
}
|
||||
else
|
||||
{
|
||||
str = val.toString();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ruoyi.common.utils.security;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -55,7 +56,7 @@ public class Md5Utils
|
||||
{
|
||||
try
|
||||
{
|
||||
return new String(toHex(md5(s)).getBytes("UTF-8"), "UTF-8");
|
||||
return new String(toHex(md5(s)).getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -50,9 +50,9 @@ public class SqlUtil
|
||||
return;
|
||||
}
|
||||
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
|
||||
for (int i = 0; i < sqlKeywords.length; i++)
|
||||
for (String sqlKeyword : sqlKeywords)
|
||||
{
|
||||
if (StringUtils.indexOfIgnoreCase(value, sqlKeywords[i]) > -1)
|
||||
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1)
|
||||
{
|
||||
throw new UtilException("参数存在SQL注入风险");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.ruoyi.common.utils.uuid;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* @author ruoyi 序列生成类
|
||||
*/
|
||||
public class Seq
|
||||
{
|
||||
// 通用序列类型
|
||||
public static final String commSeqType = "COMMON";
|
||||
|
||||
// 上传序列类型
|
||||
public static final String uploadSeqType = "UPLOAD";
|
||||
|
||||
// 通用接口序列数
|
||||
private static AtomicInteger commSeq = new AtomicInteger(1);
|
||||
|
||||
// 上传接口序列数
|
||||
private static AtomicInteger uploadSeq = new AtomicInteger(1);
|
||||
|
||||
// 机器标识
|
||||
private static String machineCode = "A";
|
||||
|
||||
/**
|
||||
* 获取通用序列号
|
||||
*
|
||||
* @return 序列值
|
||||
*/
|
||||
public static String getId()
|
||||
{
|
||||
return getId(commSeqType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串
|
||||
*
|
||||
* @return 序列值
|
||||
*/
|
||||
public static String getId(String type)
|
||||
{
|
||||
AtomicInteger atomicInt = commSeq;
|
||||
if (uploadSeqType.equals(type))
|
||||
{
|
||||
atomicInt = uploadSeq;
|
||||
}
|
||||
return getId(atomicInt, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串
|
||||
*
|
||||
* @param atomicInt 序列数
|
||||
* @param length 数值长度
|
||||
* @return 序列值
|
||||
*/
|
||||
public static String getId(AtomicInteger atomicInt, int length)
|
||||
{
|
||||
String result = DateUtils.dateTimeNow();
|
||||
result += machineCode;
|
||||
result += getSeq(atomicInt, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数
|
||||
*
|
||||
* @return 序列值
|
||||
*/
|
||||
private synchronized static String getSeq(AtomicInteger atomicInt, int length)
|
||||
{
|
||||
// 先取值再+1
|
||||
int value = atomicInt.getAndIncrement();
|
||||
|
||||
// 如果更新后值>=10 的 (length)幂次方则重置为1
|
||||
int maxSeq = (int) Math.pow(10, length);
|
||||
if (atomicInt.get() >= maxSeq)
|
||||
{
|
||||
atomicInt.set(1);
|
||||
}
|
||||
// 转字符串,用0左补齐
|
||||
return StringUtils.padl(value, length);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ruoyi.common.xss;
|
||||
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -12,15 +13,19 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class XssValidator implements ConstraintValidator<Xss, String>
|
||||
{
|
||||
private final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />";
|
||||
private static final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />";
|
||||
|
||||
@Override
|
||||
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext)
|
||||
{
|
||||
if (StringUtils.isBlank(value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return !containsHtml(value);
|
||||
}
|
||||
|
||||
public boolean containsHtml(String value)
|
||||
public static boolean containsHtml(String value)
|
||||
{
|
||||
Pattern pattern = Pattern.compile(HTML_PATTERN);
|
||||
Matcher matcher = pattern.matcher(value);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.7.2</version>
|
||||
<version>4.7.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -119,4 +119,12 @@ public class Jvm
|
||||
{
|
||||
return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate());
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行参数
|
||||
*/
|
||||
public String getInputArgs()
|
||||
{
|
||||
return ManagementFactory.getRuntimeMXBean().getInputArguments().toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.7.2</version>
|
||||
<version>4.7.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
+26
-6
@@ -7,6 +7,7 @@ import java.io.StringWriter;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
@@ -299,7 +300,7 @@ public class GenTableServiceImpl implements IGenTableService
|
||||
{
|
||||
GenTable table = genTableMapper.selectGenTableByName(tableName);
|
||||
List<GenTableColumn> tableColumns = table.getColumns();
|
||||
List<String> tableColumnNames = tableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
|
||||
Map<String, GenTableColumn> tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity()));
|
||||
|
||||
List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
|
||||
if (StringUtils.isEmpty(dbTableColumns))
|
||||
@@ -309,15 +310,34 @@ public class GenTableServiceImpl implements IGenTableService
|
||||
List<String> dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
|
||||
|
||||
dbTableColumns.forEach(column -> {
|
||||
if (!tableColumnNames.contains(column.getColumnName()))
|
||||
GenUtils.initColumnField(column, table);
|
||||
if (tableColumnMap.containsKey(column.getColumnName()))
|
||||
{
|
||||
GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName());
|
||||
column.setColumnId(prevColumn.getColumnId());
|
||||
if (column.isList())
|
||||
{
|
||||
// 如果是列表,继续保留查询方式/字典类型选项
|
||||
column.setDictType(prevColumn.getDictType());
|
||||
column.setQueryType(prevColumn.getQueryType());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk()
|
||||
&& (column.isInsert() || column.isEdit())
|
||||
&& ((column.isUsableColumn()) || (!column.isSuperColumn())))
|
||||
{
|
||||
// 如果是(新增/修改&非主键/非忽略及父属性),继续保留必填/显示类型选项
|
||||
column.setIsRequired(prevColumn.getIsRequired());
|
||||
column.setHtmlType(prevColumn.getHtmlType());
|
||||
}
|
||||
genTableColumnMapper.updateGenTableColumn(column);
|
||||
}
|
||||
else
|
||||
{
|
||||
GenUtils.initColumnField(column, table);
|
||||
genTableColumnMapper.insertGenTableColumn(column);
|
||||
}
|
||||
});
|
||||
|
||||
List<GenTableColumn> delColumns = tableColumns.stream()
|
||||
.filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList());
|
||||
List<GenTableColumn> delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList());
|
||||
if (StringUtils.isNotEmpty(delColumns))
|
||||
{
|
||||
genTableColumnMapper.deleteGenTableColumns(delColumns);
|
||||
@@ -486,7 +506,7 @@ public class GenTableServiceImpl implements IGenTableService
|
||||
String treeName = paramsObj.getString(GenConstants.TREE_NAME);
|
||||
String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID);
|
||||
String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME);
|
||||
|
||||
|
||||
genTable.setTreeCode(treeCode);
|
||||
genTable.setTreeParentCode(treeParentCode);
|
||||
genTable.setTreeName(treeName);
|
||||
|
||||
@@ -42,6 +42,7 @@ public class GenUtils
|
||||
column.setJavaField(StringUtils.toCamelCase(columnName));
|
||||
// 设置默认类型
|
||||
column.setJavaType(GenConstants.TYPE_STRING);
|
||||
column.setQueryType(GenConstants.QUERY_EQ);
|
||||
|
||||
if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType))
|
||||
{
|
||||
@@ -146,8 +147,7 @@ public class GenUtils
|
||||
{
|
||||
int lastIndex = packageName.lastIndexOf(".");
|
||||
int nameLength = packageName.length();
|
||||
String moduleName = StringUtils.substring(packageName, lastIndex + 1, nameLength);
|
||||
return moduleName;
|
||||
return StringUtils.substring(packageName, lastIndex + 1, nameLength);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,8 +160,7 @@ public class GenUtils
|
||||
{
|
||||
int lastIndex = tableName.lastIndexOf("_");
|
||||
int nameLength = tableName.length();
|
||||
String businessName = StringUtils.substring(tableName, lastIndex + 1, nameLength);
|
||||
return businessName;
|
||||
return StringUtils.substring(tableName, lastIndex + 1, nameLength);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,4 +249,4 @@ public class GenUtils
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,8 +249,7 @@ public class VelocityUtils
|
||||
public static String getPackagePrefix(String packageName)
|
||||
{
|
||||
int lastIndex = packageName.lastIndexOf(".");
|
||||
String basePackage = StringUtils.substring(packageName, 0, lastIndex);
|
||||
return basePackage;
|
||||
return StringUtils.substring(packageName, 0, lastIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,7 +297,7 @@ public class VelocityUtils
|
||||
/**
|
||||
* 获取上级菜单ID字段
|
||||
*
|
||||
* @param options 生成其他选项
|
||||
* @param paramsObj 生成其他选项
|
||||
* @return 上级菜单ID字段
|
||||
*/
|
||||
public static String getParentMenuId(JSONObject paramsObj)
|
||||
@@ -314,7 +313,7 @@ public class VelocityUtils
|
||||
/**
|
||||
* 获取树编码
|
||||
*
|
||||
* @param options 生成其他选项
|
||||
* @param paramsObj 生成其他选项
|
||||
* @return 树编码
|
||||
*/
|
||||
public static String getTreecode(JSONObject paramsObj)
|
||||
@@ -329,7 +328,7 @@ public class VelocityUtils
|
||||
/**
|
||||
* 获取树父编码
|
||||
*
|
||||
* @param options 生成其他选项
|
||||
* @param paramsObj 生成其他选项
|
||||
* @return 树父编码
|
||||
*/
|
||||
public static String getTreeParentCode(JSONObject paramsObj)
|
||||
@@ -344,7 +343,7 @@ public class VelocityUtils
|
||||
/**
|
||||
* 获取树名称
|
||||
*
|
||||
* @param options 生成其他选项
|
||||
* @param paramsObj 生成其他选项
|
||||
* @return 树名称
|
||||
*/
|
||||
public static String getTreeName(JSONObject paramsObj)
|
||||
@@ -382,4 +381,4 @@ public class VelocityUtils
|
||||
}
|
||||
return num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,11 +148,12 @@
|
||||
$.each(result.data, function(index, value) {
|
||||
var templateName = index.substring(index.lastIndexOf("/") + 1, index.length).replace(/\.vm/g, "");
|
||||
if(!$.common.equals("sql", templateName) && !$.common.equals("tree.html", templateName) && !$.common.equals("sub-domain.java", templateName)){
|
||||
var language = templateName.substring(templateName.lastIndexOf(".") + 1);
|
||||
var highCode = hljs.highlight(language, value).value;
|
||||
items.push({
|
||||
title: templateName , content: "<pre class=\"layui-code\"><code>" + highCode + "</code></pre>"
|
||||
})
|
||||
var codeName = templateName.replace(".", "");
|
||||
var language = templateName.substring(templateName.lastIndexOf(".") + 1);
|
||||
var highCode = hljs.highlight(language, value).value;
|
||||
items.push({
|
||||
title: templateName , content: "<pre class=\"layui-code\"><a style=\"float:right\" href=\"javascript:copyText('" + codeName + "')\"><i class=\"fa fa-copy\"></i> 复制</a><code id=\"" + codeName + "\">" + highCode + "</code></pre><textarea id=\"t_" + codeName + "\" style='position: absolute;top: 0;left: 0;opacity: 0;z-index: -10;'></textarea><script>function copyText(codeName){var text = document.getElementById(codeName).innerText;var input = document.getElementById(\"t_\"+codeName);input.value = text;input.select();document.execCommand(\"copy\");$.modal.msgSuccess(\"复制成功\");}<\/script>"
|
||||
})
|
||||
}
|
||||
});
|
||||
top.layer.tab({
|
||||
|
||||
@@ -103,7 +103,6 @@
|
||||
createUrl: prefix + "/add/{id}",
|
||||
updateUrl: prefix + "/edit/{id}",
|
||||
removeUrl: prefix + "/remove/{id}",
|
||||
exportUrl: prefix + "/export",
|
||||
modalName: "${functionName}",
|
||||
columns: [{
|
||||
field: 'selectItem',
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.7.2</version>
|
||||
<version>4.7.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,57 +1,57 @@
|
||||
package com.ruoyi.quartz.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效)
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class ScheduleConfig
|
||||
{
|
||||
@Bean
|
||||
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource)
|
||||
{
|
||||
SchedulerFactoryBean factory = new SchedulerFactoryBean();
|
||||
factory.setDataSource(dataSource);
|
||||
|
||||
// quartz参数
|
||||
Properties prop = new Properties();
|
||||
prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler");
|
||||
prop.put("org.quartz.scheduler.instanceId", "AUTO");
|
||||
// 线程池配置
|
||||
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
|
||||
prop.put("org.quartz.threadPool.threadCount", "20");
|
||||
prop.put("org.quartz.threadPool.threadPriority", "5");
|
||||
// JobStore配置
|
||||
prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
|
||||
// 集群配置
|
||||
prop.put("org.quartz.jobStore.isClustered", "true");
|
||||
prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
|
||||
prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
|
||||
prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
|
||||
|
||||
// sqlserver 启用
|
||||
// prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
|
||||
prop.put("org.quartz.jobStore.misfireThreshold", "12000");
|
||||
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
|
||||
factory.setQuartzProperties(prop);
|
||||
|
||||
factory.setSchedulerName("RuoyiScheduler");
|
||||
// 延时启动
|
||||
factory.setStartupDelay(1);
|
||||
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
|
||||
// 可选,QuartzScheduler
|
||||
// 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
|
||||
factory.setOverwriteExistingJobs(true);
|
||||
// 设置自动启动,默认为true
|
||||
factory.setAutoStartup(true);
|
||||
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
//package com.ruoyi.quartz.config;
|
||||
//
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
||||
//import javax.sql.DataSource;
|
||||
//import java.util.Properties;
|
||||
//
|
||||
///**
|
||||
// * 定时任务配置(单机部署建议默认走内存,如需集群需要创建qrtz数据库表/打开类注释)
|
||||
// *
|
||||
// * @author ruoyi
|
||||
// */
|
||||
//@Configuration
|
||||
//public class ScheduleConfig
|
||||
//{
|
||||
// @Bean
|
||||
// public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource)
|
||||
// {
|
||||
// SchedulerFactoryBean factory = new SchedulerFactoryBean();
|
||||
// factory.setDataSource(dataSource);
|
||||
//
|
||||
// // quartz参数
|
||||
// Properties prop = new Properties();
|
||||
// prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler");
|
||||
// prop.put("org.quartz.scheduler.instanceId", "AUTO");
|
||||
// // 线程池配置
|
||||
// prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
|
||||
// prop.put("org.quartz.threadPool.threadCount", "20");
|
||||
// prop.put("org.quartz.threadPool.threadPriority", "5");
|
||||
// // JobStore配置
|
||||
// prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore");
|
||||
// // 集群配置
|
||||
// prop.put("org.quartz.jobStore.isClustered", "true");
|
||||
// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
|
||||
// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
|
||||
// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
|
||||
//
|
||||
// // sqlserver 启用
|
||||
// // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
|
||||
// prop.put("org.quartz.jobStore.misfireThreshold", "12000");
|
||||
// prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
|
||||
// factory.setQuartzProperties(prop);
|
||||
//
|
||||
// factory.setSchedulerName("RuoyiScheduler");
|
||||
// // 延时启动
|
||||
// factory.setStartupDelay(1);
|
||||
// factory.setApplicationContextSchedulerContextKey("applicationContextKey");
|
||||
// // 可选,QuartzScheduler
|
||||
// // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
|
||||
// factory.setOverwriteExistingJobs(true);
|
||||
// // 设置自动启动,默认为true
|
||||
// factory.setAutoStartup(true);
|
||||
//
|
||||
// return factory;
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.quartz.domain.SysJob;
|
||||
import com.ruoyi.quartz.service.ISysJobService;
|
||||
import com.ruoyi.quartz.util.CronUtils;
|
||||
import com.ruoyi.quartz.util.ScheduleUtils;
|
||||
|
||||
/**
|
||||
* 调度任务信息操作处理
|
||||
@@ -138,20 +139,24 @@ public class SysJobController extends BaseController
|
||||
}
|
||||
else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI))
|
||||
{
|
||||
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi://'调用");
|
||||
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用");
|
||||
}
|
||||
else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_LDAP))
|
||||
else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS }))
|
||||
{
|
||||
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap://'调用");
|
||||
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用");
|
||||
}
|
||||
else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS }))
|
||||
{
|
||||
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)//'调用");
|
||||
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用");
|
||||
}
|
||||
else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR))
|
||||
{
|
||||
return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规");
|
||||
}
|
||||
else if (!ScheduleUtils.whiteList(job.getInvokeTarget()))
|
||||
{
|
||||
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内");
|
||||
}
|
||||
job.setCreateBy(getLoginName());
|
||||
return toAjax(jobService.insertJob(job));
|
||||
}
|
||||
@@ -182,20 +187,24 @@ public class SysJobController extends BaseController
|
||||
}
|
||||
else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI))
|
||||
{
|
||||
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi://'调用");
|
||||
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用");
|
||||
}
|
||||
else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_LDAP))
|
||||
else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS }))
|
||||
{
|
||||
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap://'调用");
|
||||
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap'调用");
|
||||
}
|
||||
else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS }))
|
||||
{
|
||||
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)//'调用");
|
||||
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用");
|
||||
}
|
||||
else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR))
|
||||
{
|
||||
return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规");
|
||||
}
|
||||
else if (!ScheduleUtils.whiteList(job.getInvokeTarget()))
|
||||
{
|
||||
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不在白名单内");
|
||||
}
|
||||
return toAjax(jobService.updateJob(job));
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,11 @@ import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.quartz.TriggerBuilder;
|
||||
import org.quartz.TriggerKey;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.constant.ScheduleConstants;
|
||||
import com.ruoyi.common.exception.job.TaskException;
|
||||
import com.ruoyi.common.exception.job.TaskException.Code;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.quartz.domain.SysJob;
|
||||
|
||||
/**
|
||||
@@ -110,4 +112,21 @@ public class ScheduleUtils
|
||||
+ "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查包名是否为白名单配置
|
||||
*
|
||||
* @param invokeTarget 目标字符串
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean whiteList(String invokeTarget)
|
||||
{
|
||||
String packageName = StringUtils.substringBefore(invokeTarget, "(");
|
||||
int count = StringUtils.countMatches(packageName, ".");
|
||||
if (count > 1)
|
||||
{
|
||||
return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -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.2}"></script>
|
||||
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.3}"></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.2</version>
|
||||
<version>4.7.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ public interface SysUserMapper
|
||||
public List<SysUser> selectUserList(SysUser sysUser);
|
||||
|
||||
/**
|
||||
* 根据条件分页查询未已配用户角色列表
|
||||
* 根据条件分页查询已配用户角色列表
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 用户信息集合信息
|
||||
|
||||
@@ -54,7 +54,6 @@ public interface ISysConfigService
|
||||
* 批量删除参数配置信息
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
public void deleteConfigByIds(String ids);
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@ public interface ISysDictDataService
|
||||
* 批量删除字典数据
|
||||
*
|
||||
* @param ids 需要删除的数据
|
||||
* @return 结果
|
||||
*/
|
||||
public void deleteDictDataByIds(String ids);
|
||||
|
||||
|
||||
@@ -55,8 +55,6 @@ public interface ISysDictTypeService
|
||||
* 批量删除字典类型
|
||||
*
|
||||
* @param ids 需要删除的数据
|
||||
* @return 结果
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
public void deleteDictTypeByIds(String ids);
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ public interface ISysLogininforService
|
||||
* 批量删除系统登录日志
|
||||
*
|
||||
* @param ids 需要删除的数据
|
||||
* @return
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteLogininforByIds(String ids);
|
||||
|
||||
|
||||
@@ -46,9 +46,8 @@ public interface ISysPostService
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
public int deletePostByIds(String ids) throws Exception;
|
||||
public int deletePostByIds(String ids);
|
||||
|
||||
/**
|
||||
* 新增保存岗位信息
|
||||
|
||||
@@ -123,7 +123,6 @@ public class SysConfigServiceImpl implements ISysConfigService
|
||||
* 批量删除参数配置对象
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public void deleteConfigByIds(String ids)
|
||||
|
||||
@@ -61,7 +61,6 @@ public class SysDictDataServiceImpl implements ISysDictDataService
|
||||
* 批量删除字典数据
|
||||
*
|
||||
* @param ids 需要删除的数据
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public void deleteDictDataByIds(String ids)
|
||||
|
||||
+8
-5
@@ -1,7 +1,10 @@
|
||||
package com.ruoyi.system.service.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.PostConstruct;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -115,7 +118,6 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
|
||||
* 批量删除字典类型
|
||||
*
|
||||
* @param ids 需要删除的数据
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public void deleteDictTypeByIds(String ids)
|
||||
@@ -139,11 +141,12 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
|
||||
@Override
|
||||
public void loadingDictCache()
|
||||
{
|
||||
List<SysDictType> dictTypeList = dictTypeMapper.selectDictTypeAll();
|
||||
for (SysDictType dict : dictTypeList)
|
||||
SysDictData dictData = new SysDictData();
|
||||
dictData.setStatus("0");
|
||||
Map<String, List<SysDictData>> dictDataMap = dictDataMapper.selectDictDataList(dictData).stream().collect(Collectors.groupingBy(SysDictData::getDictType));
|
||||
for (Map.Entry<String, List<SysDictData>> entry : dictDataMap.entrySet())
|
||||
{
|
||||
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType());
|
||||
DictUtils.setDictCache(dict.getDictType(), dictDatas);
|
||||
DictUtils.setDictCache(entry.getKey(), entry.getValue().stream().sorted(Comparator.comparing(SysDictData::getDictSort)).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ public class SysLogininforServiceImpl implements ISysLogininforService
|
||||
* 批量删除系统登录日志
|
||||
*
|
||||
* @param ids 需要删除的数据
|
||||
* @return
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteLogininforByIds(String ids)
|
||||
|
||||
@@ -384,6 +384,6 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||
*/
|
||||
private boolean hasChild(List<SysMenu> list, SysMenu t)
|
||||
{
|
||||
return getChildList(list, t).size() > 0 ? true : false;
|
||||
return getChildList(list, t).size() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public class SysPostServiceImpl implements ISysPostService
|
||||
* 批量删除岗位信息
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @throws Exception
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deletePostByIds(String ids)
|
||||
|
||||
@@ -159,6 +159,7 @@ public class SysRoleServiceImpl implements ISysRoleService
|
||||
for (Long roleId : roleIds)
|
||||
{
|
||||
checkRoleAllowed(new SysRole(roleId));
|
||||
checkRoleDataScope(roleId);
|
||||
SysRole role = selectRoleById(roleId);
|
||||
if (countUserRoleByRoleId(roleId) > 0)
|
||||
{
|
||||
@@ -393,7 +394,7 @@ public class SysRoleServiceImpl implements ISysRoleService
|
||||
* 批量选择授权用户角色
|
||||
*
|
||||
* @param roleId 角色ID
|
||||
* @param userIds 需要删除的用户数据ID
|
||||
* @param userIds 需要授权的用户数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
|
||||
@@ -193,6 +193,7 @@ public class SysUserServiceImpl implements ISysUserService
|
||||
for (Long userId : userIds)
|
||||
{
|
||||
checkUserAllowed(new SysUser(userId));
|
||||
checkUserDataScope(userId);
|
||||
}
|
||||
// 删除用户与角色关联
|
||||
userRoleMapper.deleteUserRole(userIds);
|
||||
|
||||
Reference in New Issue
Block a user