Compare commits
No commits in common. "master" and "v3.3" have entirely different histories.
|
|
@ -1 +0,0 @@
|
||||||
custom: http://doc.ruoyi.vip/ruoyi/other/donate.html
|
|
||||||
|
|
@ -25,8 +25,6 @@ target/
|
||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
|
|
||||||
### JRebel ###
|
|
||||||
rebel.xml
|
|
||||||
### NetBeans ###
|
### NetBeans ###
|
||||||
nbproject/private/
|
nbproject/private/
|
||||||
build/*
|
build/*
|
||||||
|
|
@ -39,7 +37,6 @@ nbdist/
|
||||||
# Others
|
# Others
|
||||||
*.log
|
*.log
|
||||||
*.xml.versionsBackup
|
*.xml.versionsBackup
|
||||||
*.swp
|
|
||||||
|
|
||||||
!*/build/*.java
|
!*/build/*.java
|
||||||
!*/build/*.html
|
!*/build/*.html
|
||||||
|
|
|
||||||
78
README.md
78
README.md
|
|
@ -1,26 +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.9</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.9-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。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
|
一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适的。于是利用空闲休息时间开始自己写了一套后台系统。如此有了若依。她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,OA。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
|
||||||
|
|
||||||
性别男,若依是给女儿取的名字(寓意:你若不离不弃,我必生死相依)
|
性别男,若依是给还没有出生女儿取的名字(寓意:你若不离不弃,我必生死相依)
|
||||||
|
|
||||||
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
|
若依基于hplus和inspinia两套后台系统模板开发。有需要可自行到群内下载。
|
||||||
|
|
||||||
* 前后端分离版本,请移步[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
|
> 如需单应用,请移步 [RuoYi-fast](https://gitee.com/y_project/RuoYi-fast) `(保持同步更新)`,如需Oracle版本,请移步 [RuoYi-oracle](http://doc.ruoyi.vip/#/standard/xmkz) `(不定时更新)`
|
||||||
* 感谢 [hplus](https://gitee.com/hplus_admin/hplus) 后台主题 UI 框架。
|
|
||||||
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)
|
> 阿里云通用云产品1888优惠券 :[点我领取](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=brki8iof) 腾讯云通用云产品2860优惠券 :[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console) `(仅限新用户)`
|
||||||
* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)
|
|
||||||
|
|
||||||
## 内置功能
|
## 内置功能
|
||||||
|
|
||||||
|
|
@ -36,67 +24,57 @@
|
||||||
10. 登录日志:系统登录日志记录查询包含登录异常。
|
10. 登录日志:系统登录日志记录查询包含登录异常。
|
||||||
11. 在线用户:当前系统中活跃用户状态监控。
|
11. 在线用户:当前系统中活跃用户状态监控。
|
||||||
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
|
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
|
||||||
13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。
|
13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。
|
||||||
14. 系统接口:根据业务代码自动生成相关的api接口文档。
|
14. 系统接口:根据业务代码自动生成相关的api接口文档。
|
||||||
15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
|
15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
|
||||||
16. 缓存监控:对系统的缓存查询,删除、清空等操作。
|
16. 在线构建器:拖动表单元素生成相应的HTML代码。
|
||||||
17. 在线构建器:拖动表单元素生成相应的HTML代码。
|
17. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
|
||||||
18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
|
|
||||||
|
|
||||||
## 在线体验
|
## 在线体验
|
||||||
|
> admin/admin123
|
||||||
- admin/admin123
|
> 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
|
||||||
- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
|
|
||||||
|
|
||||||
演示地址:http://ruoyi.vip
|
演示地址:http://ruoyi.vip
|
||||||
|
|
||||||
文档地址:http://doc.ruoyi.vip
|
文档地址:http://doc.ruoyi.vip
|
||||||
|
|
||||||
## 演示图
|
## 演示图
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-42e518aa72a24d228427a1261cb3679f395.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/25b5e333768d013d45a990c152dbe4d9d6e.jpg"/></td>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-7f20dd0edba25e5187c5c4dd3ec7d3d9797.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/5ac52ccc07a59f12205948c9408791f5c5b.jpg"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-2dae3d87f6a8ca05057db059cd9a411d51d.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/66f8b5b24720dabe0e11ae84bd1ad4b038e.jpg"/></td>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-ea4d98423471e55fba784694e45d12bd4bb.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/a46f34786bc9fc400697b6f3677be5bb3f0.jpg"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-7f6c6e9f5873efca09bd2870ee8468b8fce.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/6010201b078dbc9e1d8c09c6a3e53f4344c.jpg"/></td>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-c708b65f2c382a03f69fe1efa8d341e6cff.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/058928ad3a6e6de67b43d62d42dbf071355.jpg"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-9ab586c47dd5c7b92bca0d727962c90e3b8.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/21acdcade5e306f2c5d7ae26993b4e6bd06.jpg"/></td>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-ef954122a2080e02013112db21754b955c6.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/ad5ea3c4c2ea2e91d1f05f6cc384cbad2a1.jpg"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-088edb4d531e122415a1e2342bccb1a9691.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/6ca845cca1701fbf71881efe4f341c82f99.jpg"/></td>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-f886fe19bd820c0efae82f680223cac196c.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/e3aeb8fff585594f6e947218e14f2806ea1.jpg"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-c7a2eb71fa65d6e660294b4bccca613d638.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/197ddc2fdffc27020f8624bd7ca1a971f61.jpg"/></td>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-e60137fb0787defe613bd83331dc4755a70.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/a2dabea752d7d70aede20908dee0b419829.jpg"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-7c51c1b5758f0a0f92ed3c60469b7526f9f.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/c5699c5726b5aebde71a37bb5163d840bc2.jpg"/></td>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-15181aed45bb2461aa97b594cbf2f86ea5f.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/24740d59377e826d0d8664ebad66dc84abd.jpg"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-83326ad52ea63f67233d126226738054d98.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/bbe7fe1048d29217ba73bd3ed88d6743b55.jpg"/></td>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-3bd6d31e913b70df00107db51d64ef81df7.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/5f3d39a141f21f81b90536f391b8408f1fa.jpg"/></td>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-70a2225836bc82042a6785edf6299e2586a.png"/></td>
|
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-0184d6ab01fdc6667a14327fcaf8b46345d.png"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-64d8086dc2c02c8f71170290482f7640098.png"/></td>
|
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
## 若依交流群
|
## 若依交流群
|
||||||
|
|
||||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=5HBAaYN) [](https://jq.qq.com/?_wv=1027&k=5cHeRVW) [](https://jq.qq.com/?_wv=1027&k=53R0L5Z) [](https://jq.qq.com/?_wv=1027&k=5g75dCU) [](https://jq.qq.com/?_wv=1027&k=58cPoHA) [](https://jq.qq.com/?_wv=1027&k=5Ofd4Pb) [](https://jq.qq.com/?_wv=1027&k=5yugASz) [](https://jq.qq.com/?_wv=1027&k=5Rf3d2P) [](https://jq.qq.com/?_wv=1027&k=5ZIjaeP) [](https://jq.qq.com/?_wv=1027&k=5CJw1jY) [](https://jq.qq.com/?_wv=1027&k=5omzbKc) [](https://jq.qq.com/?_wv=1027&k=qPIKBb7s) [](https://jq.qq.com/?_wv=1027&k=4NsjKbtU) [](https://jq.qq.com/?_wv=1027&k=VD2pkz2G) [](https://jq.qq.com/?_wv=1027&k=HlshFwkJ) [](https://jq.qq.com/?_wv=1027&k=0ARRrO9V) [](https://jq.qq.com/?_wv=1027&k=up9k3ZXJ) [](https://jq.qq.com/?_wv=1027&k=540WfdEr) [](https://jq.qq.com/?_wv=1027&k=ss91fC4t) [](https://jq.qq.com/?_wv=1027&k=Cqd66IKe) [](https://jq.qq.com/?_wv=1027&k=7FplYUnR) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=lqMHu_5Fskm7H2S1vNAQTtzAUokVydwc&authKey=ptw0Fpch5pbNocML3CIJKKqZBaq2DI7cusKuzIgfMNiY3t9Pvd9hP%2BA8WYx3yaY1&noverify=0&group_code=174942938) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=blYlRDmwZXSXI5pVrPPU7ZJ1stFJ6Q2Q&authKey=ForGBWffHVlPt9NE3d7g4DoOIouBh%2BqvAj2lp1CLReHfZAUaK7SRrdwsChKpRJDJ&noverify=0&group_code=287843737)
|
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) 点击按钮入群。
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
@echo off
|
@echo off
|
||||||
echo.
|
echo.
|
||||||
echo [信息] 清理工程target生成路径。
|
echo [信息] 清理生成路径。
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
%~d0
|
|
||||||
cd %~dp0
|
cd %~dp0
|
||||||
|
cd..
|
||||||
|
|
||||||
cd ..
|
|
||||||
call mvn clean
|
call mvn clean
|
||||||
|
|
||||||
|
cd bin
|
||||||
pause
|
pause
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
@echo off
|
@echo off
|
||||||
echo.
|
echo.
|
||||||
echo [信息] 打包Web工程,生成war/jar包文件。
|
echo [信息] 打包工程,生成jar包文件。
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
%~d0
|
|
||||||
cd %~dp0
|
cd %~dp0
|
||||||
|
cd..
|
||||||
|
|
||||||
cd ..
|
|
||||||
call mvn clean package -Dmaven.test.skip=true
|
call mvn clean package -Dmaven.test.skip=true
|
||||||
|
|
||||||
pause
|
pause
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
@echo off
|
@echo off
|
||||||
echo.
|
echo.
|
||||||
echo [信息] 使用Jar命令运行Web工程。
|
echo [信息] 运行Web工程。
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
cd %~dp0
|
cd %~dp0
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,6 @@
|
||||||
|
|
||||||
注:如对模板有特殊需求,可自行修改。编辑src/main/ resources/templates/vm目录下
|
注:如对模板有特殊需求,可自行修改。编辑src/main/ resources/templates/vm目录下
|
||||||
|
|
||||||
|
|
||||||
3.1.4 日志配置
|
|
||||||
编辑src/main/ resources目录下的logback.yml 文件
|
|
||||||
<property name="log.path" value="/home/ruoyi/logs" />
|
|
||||||
改为自己需要的路径
|
|
||||||
|
|
||||||
3.2 启动及验证
|
3.2 启动及验证
|
||||||
启动RuoYiApplication.java 出现如下图表示启动成功
|
启动RuoYiApplication.java 出现如下图表示启动成功
|
||||||
|
|
||||||
|
|
@ -54,7 +48,7 @@
|
||||||
若能正确展示登录页面,并能成功登录,登录后菜单及页面展示正常,则表明环境搭建成功。
|
若能正确展示登录页面,并能成功登录,登录后菜单及页面展示正常,则表明环境搭建成功。
|
||||||
默认密码为 admin/admin123
|
默认密码为 admin/admin123
|
||||||
|
|
||||||
演示地址:http://ruoyi.vip
|
演示地址:http://www.ruoyi.club
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
515
pom.xml
515
pom.xml
|
|
@ -1,254 +1,263 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
<modelVersion>4.0.0</modelVersion>
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.ruoyi</groupId>
|
|
||||||
<artifactId>ruoyi</artifactId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>4.7.9</version>
|
<artifactId>ruoyi</artifactId>
|
||||||
|
<version>3.3</version>
|
||||||
<name>ruoyi</name>
|
|
||||||
<url>http://www.ruoyi.vip</url>
|
<name>ruoyi</name>
|
||||||
<description>若依管理系统</description>
|
<url>http://www.ruoyi.vip</url>
|
||||||
|
<description>若依管理系统</description>
|
||||||
<properties>
|
|
||||||
<ruoyi.version>4.7.9</ruoyi.version>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<ruoyi.version>3.3</ruoyi.version>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<java.version>1.8</java.version>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
|
<java.version>1.8</java.version>
|
||||||
<shiro.version>1.13.0</shiro.version>
|
<shiro.version>1.4.0</shiro.version>
|
||||||
<spring-framework.version>5.3.33</spring-framework.version>
|
<thymeleaf.extras.shiro.version>2.0.0</thymeleaf.extras.shiro.version>
|
||||||
<thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
|
<mybatis.boot.version>1.3.2</mybatis.boot.version>
|
||||||
<druid.version>1.2.23</druid.version>
|
<druid.version>1.1.14</druid.version>
|
||||||
<bitwalker.version>1.21</bitwalker.version>
|
<bitwalker.version>1.19</bitwalker.version>
|
||||||
<kaptcha.version>2.3.3</kaptcha.version>
|
<kaptcha.version>2.3.2</kaptcha.version>
|
||||||
<swagger.version>3.0.0</swagger.version>
|
<swagger.version>2.7.0</swagger.version>
|
||||||
<pagehelper.boot.version>1.4.7</pagehelper.boot.version>
|
<pagehelper.boot.version>1.2.5</pagehelper.boot.version>
|
||||||
<fastjson.version>1.2.83</fastjson.version>
|
<oshi.version>3.9.1</oshi.version>
|
||||||
<oshi.version>6.6.1</oshi.version>
|
<commons.io.version>2.5</commons.io.version>
|
||||||
<commons.io.version>2.13.0</commons.io.version>
|
<commons.fileupload.version>1.3.3</commons.fileupload.version>
|
||||||
<poi.version>4.1.2</poi.version>
|
<commons.beanutils.version>1.9.3</commons.beanutils.version>
|
||||||
<velocity.version>2.3</velocity.version>
|
<jsoup.version>1.11.3</jsoup.version>
|
||||||
</properties>
|
<poi.version>3.17</poi.version>
|
||||||
|
<velocity.version>1.7</velocity.version>
|
||||||
<!-- 依赖声明 -->
|
</properties>
|
||||||
<dependencyManagement>
|
|
||||||
<dependencies>
|
<!-- 依赖声明 -->
|
||||||
|
<dependencyManagement>
|
||||||
<!-- SpringFramework的依赖配置-->
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
<!-- SpringBoot的依赖配置-->
|
||||||
<artifactId>spring-framework-bom</artifactId>
|
<dependency>
|
||||||
<version>${spring-framework.version}</version>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<type>pom</type>
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
<scope>import</scope>
|
<version>2.1.1.RELEASE</version>
|
||||||
</dependency>
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
<!-- SpringBoot的依赖配置-->
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
<!--阿里数据库连接池 -->
|
||||||
<artifactId>spring-boot-dependencies</artifactId>
|
<dependency>
|
||||||
<version>2.5.15</version>
|
<groupId>com.alibaba</groupId>
|
||||||
<type>pom</type>
|
<artifactId>druid-spring-boot-starter</artifactId>
|
||||||
<scope>import</scope>
|
<version>${druid.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 阿里数据库连接池 -->
|
<!--验证码 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba</groupId>
|
<groupId>com.github.penggle</groupId>
|
||||||
<artifactId>druid-spring-boot-starter</artifactId>
|
<artifactId>kaptcha</artifactId>
|
||||||
<version>${druid.version}</version>
|
<version>${kaptcha.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 验证码 -->
|
<!--Shiro核心框架 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>pro.fessional</groupId>
|
<groupId>org.apache.shiro</groupId>
|
||||||
<artifactId>kaptcha</artifactId>
|
<artifactId>shiro-core</artifactId>
|
||||||
<version>${kaptcha.version}</version>
|
<version>${shiro.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Shiro核心框架 -->
|
<!-- Shiro使用Srping框架 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.shiro</groupId>
|
<groupId>org.apache.shiro</groupId>
|
||||||
<artifactId>shiro-core</artifactId>
|
<artifactId>shiro-spring</artifactId>
|
||||||
<version>${shiro.version}</version>
|
<version>${shiro.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Shiro使用Spring框架 -->
|
<!-- Shiro使用EhCache缓存框架 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.shiro</groupId>
|
<groupId>org.apache.shiro</groupId>
|
||||||
<artifactId>shiro-spring</artifactId>
|
<artifactId>shiro-ehcache</artifactId>
|
||||||
<version>${shiro.version}</version>
|
<version>${shiro.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Shiro使用EhCache缓存框架 -->
|
<!-- thymeleaf模板引擎和shiro框架的整合 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.shiro</groupId>
|
<groupId>com.github.theborakompanioni</groupId>
|
||||||
<artifactId>shiro-ehcache</artifactId>
|
<artifactId>thymeleaf-extras-shiro</artifactId>
|
||||||
<version>${shiro.version}</version>
|
<version>${thymeleaf.extras.shiro.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- thymeleaf模板引擎和shiro框架的整合 -->
|
<!-- 解析客户端操作系统、浏览器等 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.theborakompanioni</groupId>
|
<groupId>eu.bitwalker</groupId>
|
||||||
<artifactId>thymeleaf-extras-shiro</artifactId>
|
<artifactId>UserAgentUtils</artifactId>
|
||||||
<version>${thymeleaf.extras.shiro.version}</version>
|
<version>${bitwalker.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 解析客户端操作系统、浏览器等 -->
|
<!-- pagehelper 分页插件 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>eu.bitwalker</groupId>
|
<groupId>com.github.pagehelper</groupId>
|
||||||
<artifactId>UserAgentUtils</artifactId>
|
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||||
<version>${bitwalker.version}</version>
|
<version>${pagehelper.boot.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- pagehelper 分页插件 -->
|
<!-- 获取系统信息 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.pagehelper</groupId>
|
<groupId>com.github.oshi</groupId>
|
||||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
<artifactId>oshi-core</artifactId>
|
||||||
<version>${pagehelper.boot.version}</version>
|
<version>${oshi.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 获取系统信息 -->
|
<!-- swagger2-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.oshi</groupId>
|
<groupId>io.springfox</groupId>
|
||||||
<artifactId>oshi-core</artifactId>
|
<artifactId>springfox-swagger2</artifactId>
|
||||||
<version>${oshi.version}</version>
|
<version>${swagger.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Swagger3依赖 -->
|
<!-- swagger2-UI-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.springfox</groupId>
|
<groupId>io.springfox</groupId>
|
||||||
<artifactId>springfox-boot-starter</artifactId>
|
<artifactId>springfox-swagger-ui</artifactId>
|
||||||
<version>${swagger.version}</version>
|
<version>${swagger.version}</version>
|
||||||
<exclusions>
|
</dependency>
|
||||||
<exclusion>
|
|
||||||
<groupId>io.swagger</groupId>
|
<!--io常用工具类 -->
|
||||||
<artifactId>swagger-models</artifactId>
|
<dependency>
|
||||||
</exclusion>
|
<groupId>commons-io</groupId>
|
||||||
</exclusions>
|
<artifactId>commons-io</artifactId>
|
||||||
</dependency>
|
<version>${commons.io.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- io常用工具类 -->
|
|
||||||
<dependency>
|
<!--文件上传工具类 -->
|
||||||
<groupId>commons-io</groupId>
|
<dependency>
|
||||||
<artifactId>commons-io</artifactId>
|
<groupId>commons-fileupload</groupId>
|
||||||
<version>${commons.io.version}</version>
|
<artifactId>commons-fileupload</artifactId>
|
||||||
</dependency>
|
<version>${commons.fileupload.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- excel工具 -->
|
|
||||||
<dependency>
|
<!-- 简化反射封工具类 -->
|
||||||
<groupId>org.apache.poi</groupId>
|
<dependency>
|
||||||
<artifactId>poi-ooxml</artifactId>
|
<groupId>commons-beanutils</groupId>
|
||||||
<version>${poi.version}</version>
|
<artifactId>commons-beanutils</artifactId>
|
||||||
</dependency>
|
<version>${commons.beanutils.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- velocity代码生成使用模板 -->
|
|
||||||
<dependency>
|
<!-- HTML解析器 -->
|
||||||
<groupId>org.apache.velocity</groupId>
|
<dependency>
|
||||||
<artifactId>velocity-engine-core</artifactId>
|
<groupId>org.jsoup</groupId>
|
||||||
<version>${velocity.version}</version>
|
<artifactId>jsoup</artifactId>
|
||||||
</dependency>
|
<version>${jsoup.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- 阿里JSON解析器 -->
|
|
||||||
<dependency>
|
<!-- excel工具 -->
|
||||||
<groupId>com.alibaba</groupId>
|
<dependency>
|
||||||
<artifactId>fastjson</artifactId>
|
<groupId>org.apache.poi</groupId>
|
||||||
<version>${fastjson.version}</version>
|
<artifactId>poi-ooxml</artifactId>
|
||||||
</dependency>
|
<version>${poi.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- 定时任务-->
|
|
||||||
<dependency>
|
<!--velocity代码生成使用模板 -->
|
||||||
<groupId>com.ruoyi</groupId>
|
<dependency>
|
||||||
<artifactId>ruoyi-quartz</artifactId>
|
<groupId>org.apache.velocity</groupId>
|
||||||
<version>${ruoyi.version}</version>
|
<artifactId>velocity</artifactId>
|
||||||
</dependency>
|
<version>${velocity.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- 代码生成-->
|
|
||||||
<dependency>
|
<!-- 定时任务-->
|
||||||
<groupId>com.ruoyi</groupId>
|
<dependency>
|
||||||
<artifactId>ruoyi-generator</artifactId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>${ruoyi.version}</version>
|
<artifactId>ruoyi-quartz</artifactId>
|
||||||
</dependency>
|
<version>${ruoyi.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- 核心模块-->
|
|
||||||
<dependency>
|
<!-- 代码生成-->
|
||||||
<groupId>com.ruoyi</groupId>
|
<dependency>
|
||||||
<artifactId>ruoyi-framework</artifactId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>${ruoyi.version}</version>
|
<artifactId>ruoyi-generator</artifactId>
|
||||||
</dependency>
|
<version>${ruoyi.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- 系统模块-->
|
|
||||||
<dependency>
|
<!-- 核心模块-->
|
||||||
<groupId>com.ruoyi</groupId>
|
<dependency>
|
||||||
<artifactId>ruoyi-system</artifactId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>${ruoyi.version}</version>
|
<artifactId>ruoyi-framework</artifactId>
|
||||||
</dependency>
|
<version>${ruoyi.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- 通用工具-->
|
|
||||||
<dependency>
|
<!-- 系统模块-->
|
||||||
<groupId>com.ruoyi</groupId>
|
<dependency>
|
||||||
<artifactId>ruoyi-common</artifactId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>${ruoyi.version}</version>
|
<artifactId>ruoyi-system</artifactId>
|
||||||
</dependency>
|
<version>${ruoyi.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
|
||||||
</dependencyManagement>
|
<!-- 通用工具-->
|
||||||
|
<dependency>
|
||||||
<modules>
|
<groupId>com.ruoyi</groupId>
|
||||||
<module>ruoyi-admin</module>
|
<artifactId>ruoyi-common</artifactId>
|
||||||
<module>ruoyi-framework</module>
|
<version>${ruoyi.version}</version>
|
||||||
<module>ruoyi-system</module>
|
</dependency>
|
||||||
<module>ruoyi-quartz</module>
|
|
||||||
<module>ruoyi-generator</module>
|
</dependencies>
|
||||||
<module>ruoyi-common</module>
|
</dependencyManagement>
|
||||||
</modules>
|
|
||||||
<packaging>pom</packaging>
|
<modules>
|
||||||
|
<module>ruoyi-admin</module>
|
||||||
|
<module>ruoyi-framework</module>
|
||||||
<dependencies>
|
<module>ruoyi-system</module>
|
||||||
|
<module>ruoyi-quartz</module>
|
||||||
</dependencies>
|
<module>ruoyi-generator</module>
|
||||||
|
<module>ruoyi-common</module>
|
||||||
<build>
|
</modules>
|
||||||
<plugins>
|
<packaging>pom</packaging>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<dependencies>
|
||||||
<version>3.1</version>
|
|
||||||
<configuration>
|
|
||||||
<source>${java.version}</source>
|
|
||||||
<target>${java.version}</target>
|
</dependencies>
|
||||||
<encoding>${project.build.sourceEncoding}</encoding>
|
|
||||||
</configuration>
|
<build>
|
||||||
</plugin>
|
<plugins>
|
||||||
</plugins>
|
<plugin>
|
||||||
</build>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<repositories>
|
<configuration>
|
||||||
<repository>
|
<source>${java.version}</source>
|
||||||
<id>public</id>
|
<target>${java.version}</target>
|
||||||
<name>aliyun nexus</name>
|
<encoding>${project.build.sourceEncoding}</encoding>
|
||||||
<url>https://maven.aliyun.com/repository/public</url>
|
</configuration>
|
||||||
<releases>
|
</plugin>
|
||||||
<enabled>true</enabled>
|
</plugins>
|
||||||
</releases>
|
</build>
|
||||||
</repository>
|
|
||||||
</repositories>
|
<repositories>
|
||||||
|
<repository>
|
||||||
<pluginRepositories>
|
<id>public</id>
|
||||||
<pluginRepository>
|
<name>aliyun nexus</name>
|
||||||
<id>public</id>
|
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
|
||||||
<name>aliyun nexus</name>
|
<releases>
|
||||||
<url>https://maven.aliyun.com/repository/public</url>
|
<enabled>true</enabled>
|
||||||
<releases>
|
</releases>
|
||||||
<enabled>true</enabled>
|
</repository>
|
||||||
</releases>
|
</repositories>
|
||||||
<snapshots>
|
|
||||||
<enabled>false</enabled>
|
<pluginRepositories>
|
||||||
</snapshots>
|
<pluginRepository>
|
||||||
</pluginRepository>
|
<id>public</id>
|
||||||
</pluginRepositories>
|
<name>aliyun nexus</name>
|
||||||
|
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</pluginRepository>
|
||||||
|
</pluginRepositories>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -5,18 +5,18 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>4.7.9</version>
|
<version>3.3</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<artifactId>ruoyi-admin</artifactId>
|
<artifactId>ruoyi-admin</artifactId>
|
||||||
|
|
||||||
<description>
|
<description>
|
||||||
web服务入口
|
web服务入口
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<!-- SpringBoot集成thymeleaf模板 -->
|
<!-- SpringBoot集成thymeleaf模板 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
|
@ -24,49 +24,42 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- spring-boot-devtools -->
|
<!-- spring-boot-devtools -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-devtools</artifactId>
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
<optional>true</optional> <!-- 表示依赖不会传递 -->
|
<optional>true</optional> <!-- 表示依赖不会传递 -->
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- swagger3-->
|
<!-- swagger2-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.springfox</groupId>
|
<groupId>io.springfox</groupId>
|
||||||
<artifactId>springfox-boot-starter</artifactId>
|
<artifactId>springfox-swagger2</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- swagger2-UI-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.springfox</groupId>
|
||||||
|
<artifactId>springfox-swagger-ui</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- 防止进入swagger页面报类型转换错误,排除3.0.0中的引用,手动增加1.6.2版本 -->
|
<!-- 核心模块-->
|
||||||
<dependency>
|
|
||||||
<groupId>io.swagger</groupId>
|
|
||||||
<artifactId>swagger-models</artifactId>
|
|
||||||
<version>1.6.2</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Mysql驱动包 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>mysql</groupId>
|
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- 核心模块-->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi-framework</artifactId>
|
<artifactId>ruoyi-framework</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 定时任务-->
|
<!-- 定时任务-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi-quartz</artifactId>
|
<artifactId>ruoyi-quartz</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 代码生成-->
|
<!-- 代码生成-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi-generator</artifactId>
|
<artifactId>ruoyi-generator</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
@ -74,10 +67,9 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
<version>2.5.15</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
|
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
|
|
@ -92,44 +84,11 @@
|
||||||
<version>3.0.0</version>
|
<version>3.0.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||||
<warName>${project.artifactId}</warName>
|
<warName>${artifactId}</warName>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- YUI Compressor (CSS/JS压缩)
|
|
||||||
<plugin>
|
|
||||||
<groupId>net.alchim31.maven</groupId>
|
|
||||||
<artifactId>yuicompressor-maven-plugin</artifactId>
|
|
||||||
<version>1.5.1</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>compress</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<encoding>UTF-8</encoding>
|
|
||||||
<jswarn>false</jswarn>
|
|
||||||
<nosuffix>true</nosuffix>
|
|
||||||
<linebreakpos>50000</linebreakpos>
|
|
||||||
<sourceDirectory>src/main/resources/static</sourceDirectory>
|
|
||||||
<force>true</force>
|
|
||||||
<includes>
|
|
||||||
<include>**/*.js</include>
|
|
||||||
<include>**/*.css</include>
|
|
||||||
</includes>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/*.min.js</exclude>
|
|
||||||
<exclude>**/*.min.css</exclude>
|
|
||||||
<exclude>**/fileinput.js</exclude>
|
|
||||||
<exclude>**/validate/**</exclude>
|
|
||||||
<exclude>**/bootstrap-table/**</exclude>
|
|
||||||
</excludes>
|
|
||||||
</configuration>
|
|
||||||
</plugin> -->
|
|
||||||
</plugins>
|
</plugins>
|
||||||
<finalName>${project.artifactId}</finalName>
|
<finalName>${artifactId}</finalName>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.ruoyi;
|
package com.ruoyi;
|
||||||
|
|
||||||
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
|
@ -10,6 +11,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
||||||
|
@MapperScan("com.ruoyi.*.mapper")
|
||||||
public class RuoYiApplication
|
public class RuoYiApplication
|
||||||
{
|
{
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,19 @@
|
||||||
package com.ruoyi.web.controller.common;
|
package com.ruoyi.web.controller.common;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.List;
|
import java.net.URLEncoder;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
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.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.ruoyi.common.config.RuoYiConfig;
|
import com.ruoyi.common.config.Global;
|
||||||
import com.ruoyi.common.config.ServerConfig;
|
import com.ruoyi.common.config.ServerConfig;
|
||||||
import com.ruoyi.common.constant.Constants;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||||
|
|
@ -28,36 +25,40 @@ import com.ruoyi.common.utils.file.FileUtils;
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/common")
|
|
||||||
public class CommonController
|
public class CommonController
|
||||||
{
|
{
|
||||||
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
|
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传路径
|
||||||
|
*/
|
||||||
|
public static final String UPLOAD_PATH = "/profile/upload/";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ServerConfig serverConfig;
|
private ServerConfig serverConfig;
|
||||||
|
|
||||||
private static final String FILE_DELIMETER = ",";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用下载请求
|
* 通用下载请求
|
||||||
*
|
*
|
||||||
* @param fileName 文件名称
|
* @param fileName 文件名称
|
||||||
* @param delete 是否删除
|
* @param delete 是否删除
|
||||||
*/
|
*/
|
||||||
@GetMapping("/download")
|
@GetMapping("common/download")
|
||||||
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
|
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!FileUtils.checkAllowDownload(fileName))
|
if (!FileUtils.isValidFilename(fileName))
|
||||||
{
|
{
|
||||||
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
|
throw new Exception(StringUtils.format(" 文件名称({})非法,不允许下载。 ", fileName));
|
||||||
}
|
}
|
||||||
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
|
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
|
||||||
String filePath = RuoYiConfig.getDownloadPath() + fileName;
|
String filePath = Global.getDownloadPath() + fileName;
|
||||||
|
|
||||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
response.setCharacterEncoding("utf-8");
|
||||||
FileUtils.setAttachmentResponseHeader(response, realFileName);
|
response.setContentType("multipart/form-data");
|
||||||
|
response.setHeader("Content-Disposition",
|
||||||
|
"attachment;fileName=" + setFileDownloadHeader(request, realFileName));
|
||||||
FileUtils.writeBytes(filePath, response.getOutputStream());
|
FileUtils.writeBytes(filePath, response.getOutputStream());
|
||||||
if (delete)
|
if (delete)
|
||||||
{
|
{
|
||||||
|
|
@ -71,24 +72,22 @@ public class CommonController
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用上传请求(单个)
|
* 通用上传请求
|
||||||
*/
|
*/
|
||||||
@PostMapping("/upload")
|
@PostMapping("/common/upload")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult uploadFile(MultipartFile file) throws Exception
|
public AjaxResult uploadFile(MultipartFile file) throws Exception
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 上传文件路径
|
// 上传文件路径
|
||||||
String filePath = RuoYiConfig.getUploadPath();
|
String filePath = Global.getUploadPath();
|
||||||
// 上传并返回新文件名称
|
// 上传并返回新文件名称
|
||||||
String fileName = FileUploadUtils.upload(filePath, file);
|
String fileName = FileUploadUtils.upload(filePath, file);
|
||||||
String url = serverConfig.getUrl() + fileName;
|
String url = serverConfig.getUrl() + UPLOAD_PATH + fileName;
|
||||||
AjaxResult ajax = AjaxResult.success();
|
AjaxResult ajax = AjaxResult.success();
|
||||||
ajax.put("url", url);
|
|
||||||
ajax.put("fileName", fileName);
|
ajax.put("fileName", fileName);
|
||||||
ajax.put("newFileName", FileUtils.getName(fileName));
|
ajax.put("url", url);
|
||||||
ajax.put("originalFilename", file.getOriginalFilename());
|
|
||||||
return ajax;
|
return ajax;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
@ -97,70 +96,31 @@ public class CommonController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
|
||||||
* 通用上传请求(多个)
|
|
||||||
*/
|
|
||||||
@PostMapping("/uploads")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
|
|
||||||
{
|
{
|
||||||
try
|
final String agent = request.getHeader("USER-AGENT");
|
||||||
|
String filename = fileName;
|
||||||
|
if (agent.contains("MSIE"))
|
||||||
{
|
{
|
||||||
// 上传文件路径
|
// IE浏览器
|
||||||
String filePath = RuoYiConfig.getUploadPath();
|
filename = URLEncoder.encode(filename, "utf-8");
|
||||||
List<String> urls = new ArrayList<String>();
|
filename = filename.replace("+", " ");
|
||||||
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;
|
|
||||||
urls.add(url);
|
|
||||||
fileNames.add(fileName);
|
|
||||||
newFileNames.add(FileUtils.getName(fileName));
|
|
||||||
originalFilenames.add(file.getOriginalFilename());
|
|
||||||
}
|
|
||||||
AjaxResult ajax = AjaxResult.success();
|
|
||||||
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)
|
else if (agent.contains("Firefox"))
|
||||||
{
|
{
|
||||||
return AjaxResult.error(e.getMessage());
|
// 火狐浏览器
|
||||||
|
filename = new String(fileName.getBytes(), "ISO8859-1");
|
||||||
}
|
}
|
||||||
}
|
else if (agent.contains("Chrome"))
|
||||||
|
|
||||||
/**
|
|
||||||
* 本地资源通用下载
|
|
||||||
*/
|
|
||||||
@GetMapping("/download/resource")
|
|
||||||
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
if (!FileUtils.checkAllowDownload(resource))
|
// google浏览器
|
||||||
{
|
filename = URLEncoder.encode(filename, "utf-8");
|
||||||
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
|
|
||||||
}
|
|
||||||
// 本地资源路径
|
|
||||||
String localPath = RuoYiConfig.getProfile();
|
|
||||||
// 数据库资源地址
|
|
||||||
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
|
|
||||||
// 下载名称
|
|
||||||
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
|
|
||||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
|
||||||
FileUtils.setAttachmentResponseHeader(response, downloadName);
|
|
||||||
FileUtils.writeBytes(downloadPath, response.getOutputStream());
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
else
|
||||||
{
|
{
|
||||||
log.error("下载文件失败", e);
|
// 其它浏览器
|
||||||
|
filename = URLEncoder.encode(filename, "utf-8");
|
||||||
}
|
}
|
||||||
|
return filename;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
package com.ruoyi.web.controller.demo.controller;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模态窗口
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/demo/modal")
|
|
||||||
public class DemoDialogController
|
|
||||||
{
|
|
||||||
private String prefix = "demo/modal";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模态窗口
|
|
||||||
*/
|
|
||||||
@GetMapping("/dialog")
|
|
||||||
public String dialog()
|
|
||||||
{
|
|
||||||
return prefix + "/dialog";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 弹层组件
|
|
||||||
*/
|
|
||||||
@GetMapping("/layer")
|
|
||||||
public String layer()
|
|
||||||
{
|
|
||||||
return prefix + "/layer";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 表单
|
|
||||||
*/
|
|
||||||
@GetMapping("/form")
|
|
||||||
public String form()
|
|
||||||
{
|
|
||||||
return prefix + "/form";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 表格
|
|
||||||
*/
|
|
||||||
@GetMapping("/table")
|
|
||||||
public String table()
|
|
||||||
{
|
|
||||||
return prefix + "/table";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 表格check
|
|
||||||
*/
|
|
||||||
@GetMapping("/check")
|
|
||||||
public String check()
|
|
||||||
{
|
|
||||||
return prefix + "/table/check";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 表格radio
|
|
||||||
*/
|
|
||||||
@GetMapping("/radio")
|
|
||||||
public String radio()
|
|
||||||
{
|
|
||||||
return prefix + "/table/radio";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 表格回传父窗体
|
|
||||||
*/
|
|
||||||
@GetMapping("/parent")
|
|
||||||
public String parent()
|
|
||||||
{
|
|
||||||
return prefix + "/table/parent";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多层窗口frame1
|
|
||||||
*/
|
|
||||||
@GetMapping("/frame1")
|
|
||||||
public String frame1()
|
|
||||||
{
|
|
||||||
return prefix + "/table/frame1";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多层窗口frame2
|
|
||||||
*/
|
|
||||||
@GetMapping("/frame2")
|
|
||||||
public String frame2()
|
|
||||||
{
|
|
||||||
return prefix + "/table/frame2";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,35 +0,0 @@
|
||||||
package com.ruoyi.web.controller.demo.controller;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 图标相关
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/demo/icon")
|
|
||||||
public class DemoIconController
|
|
||||||
{
|
|
||||||
private String prefix = "demo/icon";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FontAwesome图标
|
|
||||||
*/
|
|
||||||
@GetMapping("/fontawesome")
|
|
||||||
public String fontAwesome()
|
|
||||||
{
|
|
||||||
return prefix + "/fontawesome";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Glyphicons图标
|
|
||||||
*/
|
|
||||||
@GetMapping("/glyphicons")
|
|
||||||
public String glyphicons()
|
|
||||||
{
|
|
||||||
return prefix + "/glyphicons";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,326 +0,0 @@
|
||||||
package com.ruoyi.web.controller.demo.controller;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.ModelMap;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
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.core.controller.BaseController;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.common.core.page.PageDomain;
|
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
|
||||||
import com.ruoyi.common.core.page.TableSupport;
|
|
||||||
import com.ruoyi.common.core.text.Convert;
|
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
|
||||||
import com.ruoyi.web.controller.demo.domain.CustomerModel;
|
|
||||||
import com.ruoyi.web.controller.demo.domain.UserOperateModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 操作控制
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/demo/operate")
|
|
||||||
public class DemoOperateController extends BaseController
|
|
||||||
{
|
|
||||||
private String prefix = "demo/operate";
|
|
||||||
|
|
||||||
private final static Map<Integer, UserOperateModel> users = new LinkedHashMap<Integer, UserOperateModel>();
|
|
||||||
{
|
|
||||||
users.put(1, new UserOperateModel(1, "1000001", "测试1", "0", "15888888888", "ry@qq.com", 150.0, "0"));
|
|
||||||
users.put(2, new UserOperateModel(2, "1000002", "测试2", "1", "15666666666", "ry@qq.com", 180.0, "1"));
|
|
||||||
users.put(3, new UserOperateModel(3, "1000003", "测试3", "0", "15666666666", "ry@qq.com", 110.0, "1"));
|
|
||||||
users.put(4, new UserOperateModel(4, "1000004", "测试4", "1", "15666666666", "ry@qq.com", 220.0, "1"));
|
|
||||||
users.put(5, new UserOperateModel(5, "1000005", "测试5", "0", "15666666666", "ry@qq.com", 140.0, "1"));
|
|
||||||
users.put(6, new UserOperateModel(6, "1000006", "测试6", "1", "15666666666", "ry@qq.com", 330.0, "1"));
|
|
||||||
users.put(7, new UserOperateModel(7, "1000007", "测试7", "0", "15666666666", "ry@qq.com", 160.0, "1"));
|
|
||||||
users.put(8, new UserOperateModel(8, "1000008", "测试8", "1", "15666666666", "ry@qq.com", 170.0, "1"));
|
|
||||||
users.put(9, new UserOperateModel(9, "1000009", "测试9", "0", "15666666666", "ry@qq.com", 180.0, "1"));
|
|
||||||
users.put(10, new UserOperateModel(10, "1000010", "测试10", "0", "15666666666", "ry@qq.com", 210.0, "1"));
|
|
||||||
users.put(11, new UserOperateModel(11, "1000011", "测试11", "1", "15666666666", "ry@qq.com", 110.0, "1"));
|
|
||||||
users.put(12, new UserOperateModel(12, "1000012", "测试12", "0", "15666666666", "ry@qq.com", 120.0, "1"));
|
|
||||||
users.put(13, new UserOperateModel(13, "1000013", "测试13", "1", "15666666666", "ry@qq.com", 380.0, "1"));
|
|
||||||
users.put(14, new UserOperateModel(14, "1000014", "测试14", "0", "15666666666", "ry@qq.com", 280.0, "1"));
|
|
||||||
users.put(15, new UserOperateModel(15, "1000015", "测试15", "0", "15666666666", "ry@qq.com", 570.0, "1"));
|
|
||||||
users.put(16, new UserOperateModel(16, "1000016", "测试16", "1", "15666666666", "ry@qq.com", 260.0, "1"));
|
|
||||||
users.put(17, new UserOperateModel(17, "1000017", "测试17", "1", "15666666666", "ry@qq.com", 210.0, "1"));
|
|
||||||
users.put(18, new UserOperateModel(18, "1000018", "测试18", "1", "15666666666", "ry@qq.com", 340.0, "1"));
|
|
||||||
users.put(19, new UserOperateModel(19, "1000019", "测试19", "1", "15666666666", "ry@qq.com", 160.0, "1"));
|
|
||||||
users.put(20, new UserOperateModel(20, "1000020", "测试20", "1", "15666666666", "ry@qq.com", 220.0, "1"));
|
|
||||||
users.put(21, new UserOperateModel(21, "1000021", "测试21", "1", "15666666666", "ry@qq.com", 120.0, "1"));
|
|
||||||
users.put(22, new UserOperateModel(22, "1000022", "测试22", "1", "15666666666", "ry@qq.com", 130.0, "1"));
|
|
||||||
users.put(23, new UserOperateModel(23, "1000023", "测试23", "1", "15666666666", "ry@qq.com", 490.0, "1"));
|
|
||||||
users.put(24, new UserOperateModel(24, "1000024", "测试24", "1", "15666666666", "ry@qq.com", 570.0, "1"));
|
|
||||||
users.put(25, new UserOperateModel(25, "1000025", "测试25", "1", "15666666666", "ry@qq.com", 250.0, "1"));
|
|
||||||
users.put(26, new UserOperateModel(26, "1000026", "测试26", "1", "15666666666", "ry@qq.com", 250.0, "1"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 表格
|
|
||||||
*/
|
|
||||||
@GetMapping("/table")
|
|
||||||
public String table()
|
|
||||||
{
|
|
||||||
return prefix + "/table";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 其他
|
|
||||||
*/
|
|
||||||
@GetMapping("/other")
|
|
||||||
public String other()
|
|
||||||
{
|
|
||||||
return prefix + "/other";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询数据
|
|
||||||
*/
|
|
||||||
@PostMapping("/list")
|
|
||||||
@ResponseBody
|
|
||||||
public TableDataInfo list(UserOperateModel userModel)
|
|
||||||
{
|
|
||||||
TableDataInfo rspData = new TableDataInfo();
|
|
||||||
List<UserOperateModel> userList = new ArrayList<UserOperateModel>(users.values());
|
|
||||||
// 查询条件过滤
|
|
||||||
if (StringUtils.isNotEmpty(userModel.getSearchValue()))
|
|
||||||
{
|
|
||||||
userList.clear();
|
|
||||||
for (Map.Entry<Integer, UserOperateModel> entry : users.entrySet())
|
|
||||||
{
|
|
||||||
if (entry.getValue().getUserName().equals(userModel.getSearchValue()))
|
|
||||||
{
|
|
||||||
userList.add(entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (StringUtils.isNotEmpty(userModel.getUserName()))
|
|
||||||
{
|
|
||||||
userList.clear();
|
|
||||||
for (Map.Entry<Integer, UserOperateModel> entry : users.entrySet())
|
|
||||||
{
|
|
||||||
if (entry.getValue().getUserName().equals(userModel.getUserName()))
|
|
||||||
{
|
|
||||||
userList.add(entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PageDomain pageDomain = TableSupport.buildPageRequest();
|
|
||||||
if (null == pageDomain.getPageNum() || null == pageDomain.getPageSize())
|
|
||||||
{
|
|
||||||
rspData.setRows(userList);
|
|
||||||
rspData.setTotal(userList.size());
|
|
||||||
return rspData;
|
|
||||||
}
|
|
||||||
Integer pageNum = (pageDomain.getPageNum() - 1) * 10;
|
|
||||||
Integer pageSize = pageDomain.getPageNum() * 10;
|
|
||||||
if (pageSize > userList.size())
|
|
||||||
{
|
|
||||||
pageSize = userList.size();
|
|
||||||
}
|
|
||||||
rspData.setRows(userList.subList(pageNum, pageSize));
|
|
||||||
rspData.setTotal(userList.size());
|
|
||||||
return rspData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增用户
|
|
||||||
*/
|
|
||||||
@GetMapping("/add")
|
|
||||||
public String add(ModelMap mmap)
|
|
||||||
{
|
|
||||||
return prefix + "/add";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增保存用户
|
|
||||||
*/
|
|
||||||
@PostMapping("/add")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult addSave(UserOperateModel user)
|
|
||||||
{
|
|
||||||
Integer userId = users.size() + 1;
|
|
||||||
user.setUserId(userId);
|
|
||||||
return AjaxResult.success(users.put(userId, user));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增保存主子表信息
|
|
||||||
*/
|
|
||||||
@PostMapping("/customer/add")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult addSave(CustomerModel customerModel)
|
|
||||||
{
|
|
||||||
System.out.println(customerModel.toString());
|
|
||||||
return AjaxResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改用户
|
|
||||||
*/
|
|
||||||
@GetMapping("/edit/{userId}")
|
|
||||||
public String edit(@PathVariable("userId") Integer userId, ModelMap mmap)
|
|
||||||
{
|
|
||||||
mmap.put("user", users.get(userId));
|
|
||||||
return prefix + "/edit";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改保存用户
|
|
||||||
*/
|
|
||||||
@PostMapping("/edit")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult editSave(UserOperateModel user)
|
|
||||||
{
|
|
||||||
return AjaxResult.success(users.put(user.getUserId(), user));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出
|
|
||||||
*/
|
|
||||||
@PostMapping("/export")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult export(UserOperateModel user)
|
|
||||||
{
|
|
||||||
List<UserOperateModel> list = new ArrayList<UserOperateModel>(users.values());
|
|
||||||
ExcelUtil<UserOperateModel> util = new ExcelUtil<UserOperateModel>(UserOperateModel.class);
|
|
||||||
return util.exportExcel(list, "用户数据");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下载模板
|
|
||||||
*/
|
|
||||||
@GetMapping("/importTemplate")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult importTemplate()
|
|
||||||
{
|
|
||||||
ExcelUtil<UserOperateModel> util = new ExcelUtil<UserOperateModel>(UserOperateModel.class);
|
|
||||||
return util.importTemplateExcel("用户数据");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导入数据
|
|
||||||
*/
|
|
||||||
@PostMapping("/importData")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
|
|
||||||
{
|
|
||||||
ExcelUtil<UserOperateModel> util = new ExcelUtil<UserOperateModel>(UserOperateModel.class);
|
|
||||||
List<UserOperateModel> userList = util.importExcel(file.getInputStream());
|
|
||||||
String message = importUser(userList, updateSupport);
|
|
||||||
return AjaxResult.success(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除用户
|
|
||||||
*/
|
|
||||||
@PostMapping("/remove")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult remove(String ids)
|
|
||||||
{
|
|
||||||
Integer[] userIds = Convert.toIntArray(ids);
|
|
||||||
for (Integer userId : userIds)
|
|
||||||
{
|
|
||||||
users.remove(userId);
|
|
||||||
}
|
|
||||||
return AjaxResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查看详细
|
|
||||||
*/
|
|
||||||
@GetMapping("/detail/{userId}")
|
|
||||||
public String detail(@PathVariable("userId") Integer userId, ModelMap mmap)
|
|
||||||
{
|
|
||||||
mmap.put("user", users.get(userId));
|
|
||||||
return prefix + "/detail";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/clean")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult clean()
|
|
||||||
{
|
|
||||||
users.clear();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导入用户数据
|
|
||||||
*
|
|
||||||
* @param userList 用户数据列表
|
|
||||||
* @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public String importUser(List<UserOperateModel> userList, Boolean isUpdateSupport)
|
|
||||||
{
|
|
||||||
if (StringUtils.isNull(userList) || userList.size() == 0)
|
|
||||||
{
|
|
||||||
throw new ServiceException("导入用户数据不能为空!");
|
|
||||||
}
|
|
||||||
int successNum = 0;
|
|
||||||
int failureNum = 0;
|
|
||||||
StringBuilder successMsg = new StringBuilder();
|
|
||||||
StringBuilder failureMsg = new StringBuilder();
|
|
||||||
for (UserOperateModel user : userList)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 验证是否存在这个用户
|
|
||||||
boolean userFlag = false;
|
|
||||||
for (Map.Entry<Integer, UserOperateModel> entry : users.entrySet())
|
|
||||||
{
|
|
||||||
if (entry.getValue().getUserName().equals(user.getUserName()))
|
|
||||||
{
|
|
||||||
userFlag = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!userFlag)
|
|
||||||
{
|
|
||||||
Integer userId = users.size() + 1;
|
|
||||||
user.setUserId(userId);
|
|
||||||
users.put(userId, user);
|
|
||||||
successNum++;
|
|
||||||
successMsg.append("<br/>" + successNum + "、用户 " + user.getUserName() + " 导入成功");
|
|
||||||
}
|
|
||||||
else if (isUpdateSupport)
|
|
||||||
{
|
|
||||||
users.put(user.getUserId(), user);
|
|
||||||
successNum++;
|
|
||||||
successMsg.append("<br/>" + successNum + "、用户 " + user.getUserName() + " 更新成功");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
failureNum++;
|
|
||||||
failureMsg.append("<br/>" + failureNum + "、用户 " + user.getUserName() + " 已存在");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
failureNum++;
|
|
||||||
String msg = "<br/>" + failureNum + "、账号 " + user.getUserName() + " 导入失败:";
|
|
||||||
failureMsg.append(msg + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (failureNum > 0)
|
|
||||||
{
|
|
||||||
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
|
|
||||||
throw new ServiceException(failureMsg.toString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
|
|
||||||
}
|
|
||||||
return successMsg.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
package com.ruoyi.web.controller.demo.controller;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 报表
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/demo/report")
|
|
||||||
public class DemoReportController
|
|
||||||
{
|
|
||||||
private String prefix = "demo/report";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 百度ECharts
|
|
||||||
*/
|
|
||||||
@GetMapping("/echarts")
|
|
||||||
public String echarts()
|
|
||||||
{
|
|
||||||
return prefix + "/echarts";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 图表插件
|
|
||||||
*/
|
|
||||||
@GetMapping("/peity")
|
|
||||||
public String peity()
|
|
||||||
{
|
|
||||||
return prefix + "/peity";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 线状图插件
|
|
||||||
*/
|
|
||||||
@GetMapping("/sparkline")
|
|
||||||
public String sparkline()
|
|
||||||
{
|
|
||||||
return prefix + "/sparkline";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 图表组合
|
|
||||||
*/
|
|
||||||
@GetMapping("/metrics")
|
|
||||||
public String metrics()
|
|
||||||
{
|
|
||||||
return prefix + "/metrics";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,116 +0,0 @@
|
||||||
package com.ruoyi.web.controller.demo.domain;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户测试信息
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public class CustomerModel
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 客户姓名
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户手机
|
|
||||||
*/
|
|
||||||
private String phonenumber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户性别
|
|
||||||
*/
|
|
||||||
private String sex;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户生日
|
|
||||||
*/
|
|
||||||
private String birthday;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户描述
|
|
||||||
*/
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品信息
|
|
||||||
*/
|
|
||||||
private List<GoodsModel> goods;
|
|
||||||
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name)
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPhonenumber()
|
|
||||||
{
|
|
||||||
return phonenumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPhonenumber(String phonenumber)
|
|
||||||
{
|
|
||||||
this.phonenumber = phonenumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getSex()
|
|
||||||
{
|
|
||||||
return sex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSex(String sex)
|
|
||||||
{
|
|
||||||
this.sex = sex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBirthday()
|
|
||||||
{
|
|
||||||
return birthday;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBirthday(String birthday)
|
|
||||||
{
|
|
||||||
this.birthday = birthday;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRemark()
|
|
||||||
{
|
|
||||||
return remark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRemark(String remark)
|
|
||||||
{
|
|
||||||
this.remark = remark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GoodsModel> getGoods()
|
|
||||||
{
|
|
||||||
return goods;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGoods(List<GoodsModel> goods)
|
|
||||||
{
|
|
||||||
this.goods = goods;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
|
||||||
.append("name", getName())
|
|
||||||
.append("phonenumber", getPhonenumber())
|
|
||||||
.append("sex", getSex())
|
|
||||||
.append("birthday", getBirthday())
|
|
||||||
.append("goods", getGoods())
|
|
||||||
.append("remark", getRemark())
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
package com.ruoyi.web.controller.demo.domain;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品测试信息
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public class GoodsModel
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 商品名称
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品重量
|
|
||||||
*/
|
|
||||||
private Integer weight;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品价格
|
|
||||||
*/
|
|
||||||
private Double price;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品日期
|
|
||||||
*/
|
|
||||||
private Date date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品种类
|
|
||||||
*/
|
|
||||||
private String type;
|
|
||||||
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name)
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getWeight()
|
|
||||||
{
|
|
||||||
return weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWeight(Integer weight)
|
|
||||||
{
|
|
||||||
this.weight = weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Double getPrice()
|
|
||||||
{
|
|
||||||
return price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrice(Double price)
|
|
||||||
{
|
|
||||||
this.price = price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getDate()
|
|
||||||
{
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDate(Date date)
|
|
||||||
{
|
|
||||||
this.date = date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType()
|
|
||||||
{
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(String type)
|
|
||||||
{
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
|
||||||
.append("name", getName())
|
|
||||||
.append("weight", getWeight())
|
|
||||||
.append("price", getPrice())
|
|
||||||
.append("date", getDate())
|
|
||||||
.append("type", getType())
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,149 +0,0 @@
|
||||||
package com.ruoyi.web.controller.demo.domain;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import com.ruoyi.common.annotation.Excel;
|
|
||||||
import com.ruoyi.common.annotation.Excel.Type;
|
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
|
||||||
|
|
||||||
public class UserOperateModel extends BaseEntity
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private int userId;
|
|
||||||
|
|
||||||
@Excel(name = "用户编号")
|
|
||||||
private String userCode;
|
|
||||||
|
|
||||||
@Excel(name = "用户姓名")
|
|
||||||
private String userName;
|
|
||||||
|
|
||||||
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
|
|
||||||
private String userSex;
|
|
||||||
|
|
||||||
@Excel(name = "用户手机")
|
|
||||||
private String userPhone;
|
|
||||||
|
|
||||||
@Excel(name = "用户邮箱")
|
|
||||||
private String userEmail;
|
|
||||||
|
|
||||||
@Excel(name = "用户余额")
|
|
||||||
private double userBalance;
|
|
||||||
|
|
||||||
@Excel(name = "用户状态", readConverterExp = "0=正常,1=停用")
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
public UserOperateModel()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserOperateModel(int userId, String userCode, String userName, String userSex, String userPhone,
|
|
||||||
String userEmail, double userBalance, String status)
|
|
||||||
{
|
|
||||||
this.userId = userId;
|
|
||||||
this.userCode = userCode;
|
|
||||||
this.userName = userName;
|
|
||||||
this.userSex = userSex;
|
|
||||||
this.userPhone = userPhone;
|
|
||||||
this.userEmail = userEmail;
|
|
||||||
this.userBalance = userBalance;
|
|
||||||
this.status = status;
|
|
||||||
this.createTime = DateUtils.getNowDate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getUserId()
|
|
||||||
{
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserId(int userId)
|
|
||||||
{
|
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserCode()
|
|
||||||
{
|
|
||||||
return userCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserCode(String userCode)
|
|
||||||
{
|
|
||||||
this.userCode = userCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserName()
|
|
||||||
{
|
|
||||||
return userName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserName(String userName)
|
|
||||||
{
|
|
||||||
this.userName = userName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserSex()
|
|
||||||
{
|
|
||||||
return userSex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserSex(String userSex)
|
|
||||||
{
|
|
||||||
this.userSex = userSex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserPhone()
|
|
||||||
{
|
|
||||||
return userPhone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserPhone(String userPhone)
|
|
||||||
{
|
|
||||||
this.userPhone = userPhone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserEmail()
|
|
||||||
{
|
|
||||||
return userEmail;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserEmail(String userEmail)
|
|
||||||
{
|
|
||||||
this.userEmail = userEmail;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getUserBalance()
|
|
||||||
{
|
|
||||||
return userBalance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserBalance(double userBalance)
|
|
||||||
{
|
|
||||||
this.userBalance = userBalance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus()
|
|
||||||
{
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(String status)
|
|
||||||
{
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Date getCreateTime()
|
|
||||||
{
|
|
||||||
return createTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCreateTime(Date createTime)
|
|
||||||
{
|
|
||||||
this.createTime = createTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
package com.ruoyi.web.controller.monitor;
|
|
||||||
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.ModelMap;
|
|
||||||
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 com.ruoyi.common.core.controller.BaseController;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.framework.web.service.CacheService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 缓存监控
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/monitor/cache")
|
|
||||||
public class CacheController extends BaseController
|
|
||||||
{
|
|
||||||
private String prefix = "monitor/cache";
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private CacheService cacheService;
|
|
||||||
|
|
||||||
@RequiresPermissions("monitor:cache:view")
|
|
||||||
@GetMapping()
|
|
||||||
public String cache(ModelMap mmap)
|
|
||||||
{
|
|
||||||
mmap.put("cacheNames", cacheService.getCacheNames());
|
|
||||||
return prefix + "/cache";
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresPermissions("monitor:cache:view")
|
|
||||||
@PostMapping("/getNames")
|
|
||||||
public String getCacheNames(String fragment, ModelMap mmap)
|
|
||||||
{
|
|
||||||
mmap.put("cacheNames", cacheService.getCacheNames());
|
|
||||||
return prefix + "/cache::" + fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresPermissions("monitor:cache:view")
|
|
||||||
@PostMapping("/getKeys")
|
|
||||||
public String getCacheKeys(String fragment, String cacheName, ModelMap mmap)
|
|
||||||
{
|
|
||||||
mmap.put("cacheName", cacheName);
|
|
||||||
mmap.put("cacheKeys", cacheService.getCacheKeys(cacheName));
|
|
||||||
return prefix + "/cache::" + fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresPermissions("monitor:cache:view")
|
|
||||||
@PostMapping("/getValue")
|
|
||||||
public String getCacheValue(String fragment, String cacheName, String cacheKey, ModelMap mmap)
|
|
||||||
{
|
|
||||||
mmap.put("cacheName", cacheName);
|
|
||||||
mmap.put("cacheKey", cacheKey);
|
|
||||||
mmap.put("cacheValue", cacheService.getCacheValue(cacheName, cacheKey));
|
|
||||||
return prefix + "/cache::" + fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresPermissions("monitor:cache:view")
|
|
||||||
@PostMapping("/clearCacheName")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult clearCacheName(String cacheName, ModelMap mmap)
|
|
||||||
{
|
|
||||||
cacheService.clearCacheName(cacheName);
|
|
||||||
return AjaxResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresPermissions("monitor:cache:view")
|
|
||||||
@PostMapping("/clearCacheKey")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult clearCacheKey(String cacheName, String cacheKey, ModelMap mmap)
|
|
||||||
{
|
|
||||||
cacheService.clearCacheKey(cacheName, cacheKey);
|
|
||||||
return AjaxResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresPermissions("monitor:cache:view")
|
|
||||||
@GetMapping("/clearAll")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult clearAll(ModelMap mmap)
|
|
||||||
{
|
|
||||||
cacheService.clearAll();
|
|
||||||
return AjaxResult.success();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -15,12 +15,12 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||||
@RequestMapping("/monitor/data")
|
@RequestMapping("/monitor/data")
|
||||||
public class DruidController extends BaseController
|
public class DruidController extends BaseController
|
||||||
{
|
{
|
||||||
private String prefix = "/druid";
|
private String prefix = "/monitor/druid";
|
||||||
|
|
||||||
@RequiresPermissions("monitor:data:view")
|
@RequiresPermissions("monitor:data:view")
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
public String index()
|
public String index()
|
||||||
{
|
{
|
||||||
return redirect(prefix + "/index.html");
|
return redirect(prefix + "/index");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.ruoyi.web.controller.monitor;
|
package com.ruoyi.web.controller.monitor;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
|
@ -32,9 +31,6 @@ public class SysLogininforController extends BaseController
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysLogininforService logininforService;
|
private ISysLogininforService logininforService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SysPasswordService passwordService;
|
|
||||||
|
|
||||||
@RequiresPermissions("monitor:logininfor:view")
|
@RequiresPermissions("monitor:logininfor:view")
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
public String logininfor()
|
public String logininfor()
|
||||||
|
|
@ -52,7 +48,7 @@ public class SysLogininforController extends BaseController
|
||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Log(title = "登录日志", businessType = BusinessType.EXPORT)
|
@Log(title = "登陆日志", businessType = BusinessType.EXPORT)
|
||||||
@RequiresPermissions("monitor:logininfor:export")
|
@RequiresPermissions("monitor:logininfor:export")
|
||||||
@PostMapping("/export")
|
@PostMapping("/export")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
|
@ -60,11 +56,11 @@ public class SysLogininforController extends BaseController
|
||||||
{
|
{
|
||||||
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
|
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
|
||||||
ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
|
ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
|
||||||
return util.exportExcel(list, "登录日志");
|
return util.exportExcel(list, "登陆日志");
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresPermissions("monitor:logininfor:remove")
|
@RequiresPermissions("monitor:logininfor:remove")
|
||||||
@Log(title = "登录日志", businessType = BusinessType.DELETE)
|
@Log(title = "登陆日志", businessType = BusinessType.DELETE)
|
||||||
@PostMapping("/remove")
|
@PostMapping("/remove")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult remove(String ids)
|
public AjaxResult remove(String ids)
|
||||||
|
|
@ -73,7 +69,7 @@ public class SysLogininforController extends BaseController
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresPermissions("monitor:logininfor:remove")
|
@RequiresPermissions("monitor:logininfor:remove")
|
||||||
@Log(title = "登录日志", businessType = BusinessType.CLEAN)
|
@Log(title = "登陆日志", businessType = BusinessType.CLEAN)
|
||||||
@PostMapping("/clean")
|
@PostMapping("/clean")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult clean()
|
public AjaxResult clean()
|
||||||
|
|
@ -81,14 +77,4 @@ public class SysLogininforController extends BaseController
|
||||||
logininforService.cleanLogininfor();
|
logininforService.cleanLogininfor();
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresPermissions("monitor:logininfor:unlock")
|
|
||||||
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
|
|
||||||
@PostMapping("/unlock")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult unlock(String loginName)
|
|
||||||
{
|
|
||||||
passwordService.clearLoginRecordCache(loginName);
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ public class SysOperlogController extends BaseController
|
||||||
return util.exportExcel(list, "操作日志");
|
return util.exportExcel(list, "操作日志");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Log(title = "操作日志", businessType = BusinessType.DELETE)
|
|
||||||
@RequiresPermissions("monitor:operlog:remove")
|
@RequiresPermissions("monitor:operlog:remove")
|
||||||
@PostMapping("/remove")
|
@PostMapping("/remove")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,23 @@
|
||||||
package com.ruoyi.web.controller.monitor;
|
package com.ruoyi.web.controller.monitor;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.shiro.authz.annotation.Logical;
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.core.text.Convert;
|
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.enums.OnlineStatus;
|
import com.ruoyi.common.enums.OnlineStatus;
|
||||||
import com.ruoyi.common.utils.ShiroUtils;
|
|
||||||
import com.ruoyi.framework.shiro.session.OnlineSession;
|
import com.ruoyi.framework.shiro.session.OnlineSession;
|
||||||
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
|
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
|
||||||
|
import com.ruoyi.framework.util.ShiroUtils;
|
||||||
import com.ruoyi.system.domain.SysUserOnline;
|
import com.ruoyi.system.domain.SysUserOnline;
|
||||||
import com.ruoyi.system.service.ISysUserOnlineService;
|
import com.ruoyi.system.service.ISysUserOnlineService;
|
||||||
|
|
||||||
|
|
@ -56,13 +55,13 @@ public class SysUserOnlineController extends BaseController
|
||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresPermissions(value = { "monitor:online:batchForceLogout", "monitor:online:forceLogout" }, logical = Logical.OR)
|
@RequiresPermissions("monitor:online:batchForceLogout")
|
||||||
@Log(title = "在线用户", businessType = BusinessType.FORCE)
|
@Log(title = "在线用户", businessType = BusinessType.FORCE)
|
||||||
@PostMapping("/batchForceLogout")
|
@PostMapping("/batchForceLogout")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult batchForceLogout(String ids)
|
public AjaxResult batchForceLogout(@RequestParam("ids[]") String[] ids)
|
||||||
{
|
{
|
||||||
for (String sessionId : Convert.toStrArray(ids))
|
for (String sessionId : ids)
|
||||||
{
|
{
|
||||||
SysUserOnline online = userOnlineService.selectOnlineById(sessionId);
|
SysUserOnline online = userOnlineService.selectOnlineById(sessionId);
|
||||||
if (online == null)
|
if (online == null)
|
||||||
|
|
@ -76,13 +75,40 @@ public class SysUserOnlineController extends BaseController
|
||||||
}
|
}
|
||||||
if (sessionId.equals(ShiroUtils.getSessionId()))
|
if (sessionId.equals(ShiroUtils.getSessionId()))
|
||||||
{
|
{
|
||||||
return error("当前登录用户无法强退");
|
return error("当前登陆用户无法强退");
|
||||||
}
|
}
|
||||||
onlineSessionDAO.delete(onlineSession);
|
onlineSession.setStatus(OnlineStatus.off_line);
|
||||||
|
onlineSessionDAO.update(onlineSession);
|
||||||
online.setStatus(OnlineStatus.off_line);
|
online.setStatus(OnlineStatus.off_line);
|
||||||
userOnlineService.saveOnline(online);
|
userOnlineService.saveOnline(online);
|
||||||
userOnlineService.removeUserCache(online.getLoginName(), sessionId);
|
|
||||||
}
|
}
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresPermissions("monitor:online:forceLogout")
|
||||||
|
@Log(title = "在线用户", businessType = BusinessType.FORCE)
|
||||||
|
@PostMapping("/forceLogout")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult forceLogout(String sessionId)
|
||||||
|
{
|
||||||
|
SysUserOnline online = userOnlineService.selectOnlineById(sessionId);
|
||||||
|
if (sessionId.equals(ShiroUtils.getSessionId()))
|
||||||
|
{
|
||||||
|
return error("当前登陆用户无法强退");
|
||||||
|
}
|
||||||
|
if (online == null)
|
||||||
|
{
|
||||||
|
return error("用户已下线");
|
||||||
|
}
|
||||||
|
OnlineSession onlineSession = (OnlineSession) onlineSessionDAO.readSession(online.getSessionId());
|
||||||
|
if (onlineSession == null)
|
||||||
|
{
|
||||||
|
return error("用户已下线");
|
||||||
|
}
|
||||||
|
onlineSession.setStatus(OnlineStatus.off_line);
|
||||||
|
onlineSessionDAO.update(onlineSession);
|
||||||
|
online.setStatus(OnlineStatus.off_line);
|
||||||
|
userOnlineService.saveOnline(online);
|
||||||
|
return success();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
@ -17,6 +16,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
|
import com.ruoyi.framework.util.ShiroUtils;
|
||||||
import com.ruoyi.system.domain.SysConfig;
|
import com.ruoyi.system.domain.SysConfig;
|
||||||
import com.ruoyi.system.service.ISysConfigService;
|
import com.ruoyi.system.service.ISysConfigService;
|
||||||
|
|
||||||
|
|
@ -81,20 +81,15 @@ public class SysConfigController extends BaseController
|
||||||
@Log(title = "参数管理", businessType = BusinessType.INSERT)
|
@Log(title = "参数管理", businessType = BusinessType.INSERT)
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult addSave(@Validated SysConfig config)
|
public AjaxResult addSave(SysConfig config)
|
||||||
{
|
{
|
||||||
if (!configService.checkConfigKeyUnique(config))
|
config.setCreateBy(ShiroUtils.getLoginName());
|
||||||
{
|
|
||||||
return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
|
|
||||||
}
|
|
||||||
config.setCreateBy(getLoginName());
|
|
||||||
return toAjax(configService.insertConfig(config));
|
return toAjax(configService.insertConfig(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改参数配置
|
* 修改参数配置
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("system:config:edit")
|
|
||||||
@GetMapping("/edit/{configId}")
|
@GetMapping("/edit/{configId}")
|
||||||
public String edit(@PathVariable("configId") Long configId, ModelMap mmap)
|
public String edit(@PathVariable("configId") Long configId, ModelMap mmap)
|
||||||
{
|
{
|
||||||
|
|
@ -109,13 +104,9 @@ public class SysConfigController extends BaseController
|
||||||
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
|
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
|
||||||
@PostMapping("/edit")
|
@PostMapping("/edit")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult editSave(@Validated SysConfig config)
|
public AjaxResult editSave(SysConfig config)
|
||||||
{
|
{
|
||||||
if (!configService.checkConfigKeyUnique(config))
|
config.setUpdateBy(ShiroUtils.getLoginName());
|
||||||
{
|
|
||||||
return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
|
|
||||||
}
|
|
||||||
config.setUpdateBy(getLoginName());
|
|
||||||
return toAjax(configService.updateConfig(config));
|
return toAjax(configService.updateConfig(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,21 +119,7 @@ public class SysConfigController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult remove(String ids)
|
public AjaxResult remove(String ids)
|
||||||
{
|
{
|
||||||
configService.deleteConfigByIds(ids);
|
return toAjax(configService.deleteConfigByIds(ids));
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 刷新参数缓存
|
|
||||||
*/
|
|
||||||
@RequiresPermissions("system:config:remove")
|
|
||||||
@Log(title = "参数管理", businessType = BusinessType.CLEAN)
|
|
||||||
@GetMapping("/refreshCache")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult refreshCache()
|
|
||||||
{
|
|
||||||
configService.resetConfigCache();
|
|
||||||
return success();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -150,7 +127,7 @@ public class SysConfigController extends BaseController
|
||||||
*/
|
*/
|
||||||
@PostMapping("/checkConfigKeyUnique")
|
@PostMapping("/checkConfigKeyUnique")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public boolean checkConfigKeyUnique(SysConfig config)
|
public String checkConfigKeyUnique(SysConfig config)
|
||||||
{
|
{
|
||||||
return configService.checkConfigKeyUnique(config);
|
return configService.checkConfigKeyUnique(config);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,20 +5,20 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.Ztree;
|
import com.ruoyi.common.core.domain.Ztree;
|
||||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.framework.util.ShiroUtils;
|
||||||
|
import com.ruoyi.system.domain.SysDept;
|
||||||
|
import com.ruoyi.system.domain.SysRole;
|
||||||
import com.ruoyi.system.service.ISysDeptService;
|
import com.ruoyi.system.service.ISysDeptService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -43,7 +43,7 @@ public class SysDeptController extends BaseController
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresPermissions("system:dept:list")
|
@RequiresPermissions("system:dept:list")
|
||||||
@PostMapping("/list")
|
@GetMapping("/list")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<SysDept> list(SysDept dept)
|
public List<SysDept> list(SysDept dept)
|
||||||
{
|
{
|
||||||
|
|
@ -57,10 +57,6 @@ public class SysDeptController extends BaseController
|
||||||
@GetMapping("/add/{parentId}")
|
@GetMapping("/add/{parentId}")
|
||||||
public String add(@PathVariable("parentId") Long parentId, ModelMap mmap)
|
public String add(@PathVariable("parentId") Long parentId, ModelMap mmap)
|
||||||
{
|
{
|
||||||
if (!getSysUser().isAdmin())
|
|
||||||
{
|
|
||||||
parentId = getSysUser().getDeptId();
|
|
||||||
}
|
|
||||||
mmap.put("dept", deptService.selectDeptById(parentId));
|
mmap.put("dept", deptService.selectDeptById(parentId));
|
||||||
return prefix + "/add";
|
return prefix + "/add";
|
||||||
}
|
}
|
||||||
|
|
@ -72,24 +68,18 @@ public class SysDeptController extends BaseController
|
||||||
@RequiresPermissions("system:dept:add")
|
@RequiresPermissions("system:dept:add")
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult addSave(@Validated SysDept dept)
|
public AjaxResult addSave(SysDept dept)
|
||||||
{
|
{
|
||||||
if (!deptService.checkDeptNameUnique(dept))
|
dept.setCreateBy(ShiroUtils.getLoginName());
|
||||||
{
|
|
||||||
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
|
||||||
}
|
|
||||||
dept.setCreateBy(getLoginName());
|
|
||||||
return toAjax(deptService.insertDept(dept));
|
return toAjax(deptService.insertDept(dept));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改部门
|
* 修改
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("system:dept:edit")
|
|
||||||
@GetMapping("/edit/{deptId}")
|
@GetMapping("/edit/{deptId}")
|
||||||
public String edit(@PathVariable("deptId") Long deptId, ModelMap mmap)
|
public String edit(@PathVariable("deptId") Long deptId, ModelMap mmap)
|
||||||
{
|
{
|
||||||
deptService.checkDeptDataScope(deptId);
|
|
||||||
SysDept dept = deptService.selectDeptById(deptId);
|
SysDept dept = deptService.selectDeptById(deptId);
|
||||||
if (StringUtils.isNotNull(dept) && 100L == deptId)
|
if (StringUtils.isNotNull(dept) && 100L == deptId)
|
||||||
{
|
{
|
||||||
|
|
@ -100,29 +90,15 @@ public class SysDeptController extends BaseController
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改保存部门
|
* 保存
|
||||||
*/
|
*/
|
||||||
@Log(title = "部门管理", businessType = BusinessType.UPDATE)
|
@Log(title = "部门管理", businessType = BusinessType.UPDATE)
|
||||||
@RequiresPermissions("system:dept:edit")
|
@RequiresPermissions("system:dept:edit")
|
||||||
@PostMapping("/edit")
|
@PostMapping("/edit")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult editSave(@Validated SysDept dept)
|
public AjaxResult editSave(SysDept dept)
|
||||||
{
|
{
|
||||||
Long deptId = dept.getDeptId();
|
dept.setUpdateBy(ShiroUtils.getLoginName());
|
||||||
deptService.checkDeptDataScope(deptId);
|
|
||||||
if (!deptService.checkDeptNameUnique(dept))
|
|
||||||
{
|
|
||||||
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
|
||||||
}
|
|
||||||
else if (dept.getParentId().equals(deptId))
|
|
||||||
{
|
|
||||||
return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
|
|
||||||
}
|
|
||||||
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
|
|
||||||
{
|
|
||||||
return AjaxResult.error("该部门包含未停用的子部门!");
|
|
||||||
}
|
|
||||||
dept.setUpdateBy(getLoginName());
|
|
||||||
return toAjax(deptService.updateDept(dept));
|
return toAjax(deptService.updateDept(dept));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -143,7 +119,6 @@ public class SysDeptController extends BaseController
|
||||||
{
|
{
|
||||||
return AjaxResult.warn("部门存在用户,不允许删除");
|
return AjaxResult.warn("部门存在用户,不允许删除");
|
||||||
}
|
}
|
||||||
deptService.checkDeptDataScope(deptId);
|
|
||||||
return toAjax(deptService.deleteDeptById(deptId));
|
return toAjax(deptService.deleteDeptById(deptId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,36 +127,40 @@ public class SysDeptController extends BaseController
|
||||||
*/
|
*/
|
||||||
@PostMapping("/checkDeptNameUnique")
|
@PostMapping("/checkDeptNameUnique")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public boolean checkDeptNameUnique(SysDept dept)
|
public String checkDeptNameUnique(SysDept dept)
|
||||||
{
|
{
|
||||||
return deptService.checkDeptNameUnique(dept);
|
return deptService.checkDeptNameUnique(dept);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 选择部门树
|
* 选择部门树
|
||||||
*
|
|
||||||
* @param deptId 部门ID
|
|
||||||
* @param excludeId 排除ID
|
|
||||||
*/
|
*/
|
||||||
@GetMapping(value = { "/selectDeptTree/{deptId}", "/selectDeptTree/{deptId}/{excludeId}" })
|
@GetMapping("/selectDeptTree/{deptId}")
|
||||||
public String selectDeptTree(@PathVariable("deptId") Long deptId,
|
public String selectDeptTree(@PathVariable("deptId") Long deptId, ModelMap mmap)
|
||||||
@PathVariable(value = "excludeId", required = false) Long excludeId, ModelMap mmap)
|
|
||||||
{
|
{
|
||||||
mmap.put("dept", deptService.selectDeptById(deptId));
|
mmap.put("dept", deptService.selectDeptById(deptId));
|
||||||
mmap.put("excludeId", excludeId);
|
|
||||||
return prefix + "/tree";
|
return prefix + "/tree";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载部门列表树(排除下级)
|
* 加载部门列表树
|
||||||
*/
|
*/
|
||||||
@GetMapping("/treeData/{excludeId}")
|
@GetMapping("/treeData")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<Ztree> treeDataExcludeChild(@PathVariable(value = "excludeId", required = false) Long excludeId)
|
public List<Ztree> treeData()
|
||||||
{
|
{
|
||||||
SysDept dept = new SysDept();
|
List<Ztree> ztrees = deptService.selectDeptTree(new SysDept());
|
||||||
dept.setExcludeId(excludeId);
|
return ztrees;
|
||||||
List<Ztree> ztrees = deptService.selectDeptTreeExcludeChild(dept);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载角色部门(数据权限)列表树
|
||||||
|
*/
|
||||||
|
@GetMapping("/roleDeptTreeData")
|
||||||
|
@ResponseBody
|
||||||
|
public List<Ztree> deptTreeData(SysRole role)
|
||||||
|
{
|
||||||
|
List<Ztree> ztrees = deptService.roleDeptTreeData(role);
|
||||||
return ztrees;
|
return ztrees;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
@ -14,10 +13,11 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.entity.SysDictData;
|
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
|
import com.ruoyi.framework.util.ShiroUtils;
|
||||||
|
import com.ruoyi.system.domain.SysDictData;
|
||||||
import com.ruoyi.system.service.ISysDictDataService;
|
import com.ruoyi.system.service.ISysDictDataService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -79,16 +79,15 @@ public class SysDictDataController extends BaseController
|
||||||
@RequiresPermissions("system:dict:add")
|
@RequiresPermissions("system:dict:add")
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult addSave(@Validated SysDictData dict)
|
public AjaxResult addSave(SysDictData dict)
|
||||||
{
|
{
|
||||||
dict.setCreateBy(getLoginName());
|
dict.setCreateBy(ShiroUtils.getLoginName());
|
||||||
return toAjax(dictDataService.insertDictData(dict));
|
return toAjax(dictDataService.insertDictData(dict));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改字典类型
|
* 修改字典类型
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("system:dict:edit")
|
|
||||||
@GetMapping("/edit/{dictCode}")
|
@GetMapping("/edit/{dictCode}")
|
||||||
public String edit(@PathVariable("dictCode") Long dictCode, ModelMap mmap)
|
public String edit(@PathVariable("dictCode") Long dictCode, ModelMap mmap)
|
||||||
{
|
{
|
||||||
|
|
@ -103,9 +102,9 @@ public class SysDictDataController extends BaseController
|
||||||
@RequiresPermissions("system:dict:edit")
|
@RequiresPermissions("system:dict:edit")
|
||||||
@PostMapping("/edit")
|
@PostMapping("/edit")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult editSave(@Validated SysDictData dict)
|
public AjaxResult editSave(SysDictData dict)
|
||||||
{
|
{
|
||||||
dict.setUpdateBy(getLoginName());
|
dict.setUpdateBy(ShiroUtils.getLoginName());
|
||||||
return toAjax(dictDataService.updateDictData(dict));
|
return toAjax(dictDataService.updateDictData(dict));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,7 +114,6 @@ public class SysDictDataController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult remove(String ids)
|
public AjaxResult remove(String ids)
|
||||||
{
|
{
|
||||||
dictDataService.deleteDictDataByIds(ids);
|
return toAjax(dictDataService.deleteDictDataByIds(ids));
|
||||||
return success();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
@ -14,11 +13,11 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.Ztree;
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysDictType;
|
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
|
import com.ruoyi.framework.util.ShiroUtils;
|
||||||
|
import com.ruoyi.system.domain.SysDictType;
|
||||||
import com.ruoyi.system.service.ISysDictTypeService;
|
import com.ruoyi.system.service.ISysDictTypeService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -80,20 +79,15 @@ public class SysDictTypeController extends BaseController
|
||||||
@RequiresPermissions("system:dict:add")
|
@RequiresPermissions("system:dict:add")
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult addSave(@Validated SysDictType dict)
|
public AjaxResult addSave(SysDictType dict)
|
||||||
{
|
{
|
||||||
if (!dictTypeService.checkDictTypeUnique(dict))
|
dict.setCreateBy(ShiroUtils.getLoginName());
|
||||||
{
|
|
||||||
return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
|
|
||||||
}
|
|
||||||
dict.setCreateBy(getLoginName());
|
|
||||||
return toAjax(dictTypeService.insertDictType(dict));
|
return toAjax(dictTypeService.insertDictType(dict));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改字典类型
|
* 修改字典类型
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("system:dict:edit")
|
|
||||||
@GetMapping("/edit/{dictId}")
|
@GetMapping("/edit/{dictId}")
|
||||||
public String edit(@PathVariable("dictId") Long dictId, ModelMap mmap)
|
public String edit(@PathVariable("dictId") Long dictId, ModelMap mmap)
|
||||||
{
|
{
|
||||||
|
|
@ -108,13 +102,9 @@ public class SysDictTypeController extends BaseController
|
||||||
@RequiresPermissions("system:dict:edit")
|
@RequiresPermissions("system:dict:edit")
|
||||||
@PostMapping("/edit")
|
@PostMapping("/edit")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult editSave(@Validated SysDictType dict)
|
public AjaxResult editSave(SysDictType dict)
|
||||||
{
|
{
|
||||||
if (!dictTypeService.checkDictTypeUnique(dict))
|
dict.setUpdateBy(ShiroUtils.getLoginName());
|
||||||
{
|
|
||||||
return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
|
|
||||||
}
|
|
||||||
dict.setUpdateBy(getLoginName());
|
|
||||||
return toAjax(dictTypeService.updateDictType(dict));
|
return toAjax(dictTypeService.updateDictType(dict));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,21 +114,14 @@ public class SysDictTypeController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult remove(String ids)
|
public AjaxResult remove(String ids)
|
||||||
{
|
{
|
||||||
dictTypeService.deleteDictTypeByIds(ids);
|
try
|
||||||
return success();
|
{
|
||||||
}
|
return toAjax(dictTypeService.deleteDictTypeByIds(ids));
|
||||||
|
}
|
||||||
/**
|
catch (Exception e)
|
||||||
* 刷新字典缓存
|
{
|
||||||
*/
|
return error(e.getMessage());
|
||||||
@RequiresPermissions("system:dict:remove")
|
}
|
||||||
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
|
|
||||||
@GetMapping("/refreshCache")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult refreshCache()
|
|
||||||
{
|
|
||||||
dictTypeService.resetDictCache();
|
|
||||||
return success();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -158,31 +141,8 @@ public class SysDictTypeController extends BaseController
|
||||||
*/
|
*/
|
||||||
@PostMapping("/checkDictTypeUnique")
|
@PostMapping("/checkDictTypeUnique")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public boolean checkDictTypeUnique(SysDictType dictType)
|
public String checkDictTypeUnique(SysDictType dictType)
|
||||||
{
|
{
|
||||||
return dictTypeService.checkDictTypeUnique(dictType);
|
return dictTypeService.checkDictTypeUnique(dictType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 选择字典树
|
|
||||||
*/
|
|
||||||
@GetMapping("/selectDictTree/{columnId}/{dictType}")
|
|
||||||
public String selectDeptTree(@PathVariable("columnId") Long columnId, @PathVariable("dictType") String dictType,
|
|
||||||
ModelMap mmap)
|
|
||||||
{
|
|
||||||
mmap.put("columnId", columnId);
|
|
||||||
mmap.put("dict", dictTypeService.selectDictTypeByType(dictType));
|
|
||||||
return prefix + "/tree";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 加载字典列表树
|
|
||||||
*/
|
|
||||||
@GetMapping("/treeData")
|
|
||||||
@ResponseBody
|
|
||||||
public List<Ztree> treeData()
|
|
||||||
{
|
|
||||||
List<Ztree> ztrees = dictTypeService.selectDictTree(new SysDictType());
|
|
||||||
return ztrees;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,15 @@
|
||||||
package com.ruoyi.web.controller.system;
|
package com.ruoyi.web.controller.system;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.servlet.http.Cookie;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import com.ruoyi.common.config.Global;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
import com.ruoyi.common.config.RuoYiConfig;
|
|
||||||
import com.ruoyi.common.constant.ShiroConstants;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.framework.util.ShiroUtils;
|
||||||
import com.ruoyi.common.core.domain.entity.SysMenu;
|
import com.ruoyi.system.domain.SysMenu;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.system.domain.SysUser;
|
||||||
import com.ruoyi.common.core.text.Convert;
|
|
||||||
import com.ruoyi.common.utils.CookieUtils;
|
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
|
||||||
import com.ruoyi.common.utils.ServletUtils;
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
|
||||||
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
|
||||||
import com.ruoyi.system.service.ISysConfigService;
|
|
||||||
import com.ruoyi.system.service.ISysMenuService;
|
import com.ruoyi.system.service.ISysMenuService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -37,142 +23,25 @@ public class SysIndexController extends BaseController
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysMenuService menuService;
|
private ISysMenuService menuService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ISysConfigService configService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SysPasswordService passwordService;
|
|
||||||
|
|
||||||
// 系统首页
|
// 系统首页
|
||||||
@GetMapping("/index")
|
@GetMapping("/index")
|
||||||
public String index(ModelMap mmap)
|
public String index(ModelMap mmap)
|
||||||
{
|
{
|
||||||
// 取身份信息
|
// 取身份信息
|
||||||
SysUser user = getSysUser();
|
SysUser user = ShiroUtils.getSysUser();
|
||||||
// 根据用户id取出菜单
|
// 根据用户id取出菜单
|
||||||
List<SysMenu> menus = menuService.selectMenusByUser(user);
|
List<SysMenu> menus = menuService.selectMenusByUser(user);
|
||||||
mmap.put("menus", menus);
|
mmap.put("menus", menus);
|
||||||
mmap.put("user", user);
|
mmap.put("user", user);
|
||||||
mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme"));
|
mmap.put("copyrightYear", Global.getCopyrightYear());
|
||||||
mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName"));
|
return "index";
|
||||||
Boolean footer = Convert.toBool(configService.selectConfigByKey("sys.index.footer"), true);
|
|
||||||
Boolean tagsView = Convert.toBool(configService.selectConfigByKey("sys.index.tagsView"), true);
|
|
||||||
mmap.put("footer", footer);
|
|
||||||
mmap.put("tagsView", tagsView);
|
|
||||||
mmap.put("mainClass", contentMainClass(footer, tagsView));
|
|
||||||
mmap.put("copyrightYear", RuoYiConfig.getCopyrightYear());
|
|
||||||
mmap.put("demoEnabled", RuoYiConfig.isDemoEnabled());
|
|
||||||
mmap.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
|
|
||||||
mmap.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
|
|
||||||
mmap.put("isMobile", ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")));
|
|
||||||
|
|
||||||
// 菜单导航显示风格
|
|
||||||
String menuStyle = configService.selectConfigByKey("sys.index.menuStyle");
|
|
||||||
// 移动端,默认使左侧导航菜单,否则取默认配置
|
|
||||||
String indexStyle = ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")) ? "index" : menuStyle;
|
|
||||||
|
|
||||||
// 优先Cookie配置导航菜单
|
|
||||||
Cookie[] cookies = ServletUtils.getRequest().getCookies();
|
|
||||||
for (Cookie cookie : cookies)
|
|
||||||
{
|
|
||||||
if (StringUtils.isNotEmpty(cookie.getName()) && "nav-style".equalsIgnoreCase(cookie.getName()))
|
|
||||||
{
|
|
||||||
indexStyle = cookie.getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String webIndex = "topnav".equalsIgnoreCase(indexStyle) ? "index-topnav" : "index";
|
|
||||||
return webIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 锁定屏幕
|
|
||||||
@GetMapping("/lockscreen")
|
|
||||||
public String lockscreen(ModelMap mmap)
|
|
||||||
{
|
|
||||||
mmap.put("user", getSysUser());
|
|
||||||
ServletUtils.getSession().setAttribute(ShiroConstants.LOCK_SCREEN, true);
|
|
||||||
return "lock";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 解锁屏幕
|
|
||||||
@PostMapping("/unlockscreen")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult unlockscreen(String password)
|
|
||||||
{
|
|
||||||
SysUser user = getSysUser();
|
|
||||||
if (StringUtils.isNull(user))
|
|
||||||
{
|
|
||||||
return AjaxResult.error("服务器超时,请重新登录");
|
|
||||||
}
|
|
||||||
if (passwordService.matches(user, password))
|
|
||||||
{
|
|
||||||
ServletUtils.getSession().removeAttribute(ShiroConstants.LOCK_SCREEN);
|
|
||||||
return AjaxResult.success();
|
|
||||||
}
|
|
||||||
return AjaxResult.error("密码不正确,请重新输入。");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 切换主题
|
|
||||||
@GetMapping("/system/switchSkin")
|
|
||||||
public String switchSkin()
|
|
||||||
{
|
|
||||||
return "skin";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 切换菜单
|
|
||||||
@GetMapping("/system/menuStyle/{style}")
|
|
||||||
public void menuStyle(@PathVariable String style, HttpServletResponse response)
|
|
||||||
{
|
|
||||||
CookieUtils.setCookie(response, "nav-style", style);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 系统介绍
|
// 系统介绍
|
||||||
@GetMapping("/system/main")
|
@GetMapping("/system/main")
|
||||||
public String main(ModelMap mmap)
|
public String main(ModelMap mmap)
|
||||||
{
|
{
|
||||||
mmap.put("version", RuoYiConfig.getVersion());
|
mmap.put("version", Global.getVersion());
|
||||||
return "main";
|
return "main";
|
||||||
}
|
}
|
||||||
|
|
||||||
// content-main class
|
|
||||||
public String contentMainClass(Boolean footer, Boolean tagsView)
|
|
||||||
{
|
|
||||||
if (!footer && !tagsView)
|
|
||||||
{
|
|
||||||
return "tagsview-footer-hide";
|
|
||||||
}
|
|
||||||
else if (!footer)
|
|
||||||
{
|
|
||||||
return "footer-hide";
|
|
||||||
}
|
|
||||||
else if (!tagsView)
|
|
||||||
{
|
|
||||||
return "tagsview-hide";
|
|
||||||
}
|
|
||||||
return StringUtils.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查初始密码是否提醒修改
|
|
||||||
public boolean initPasswordIsModify(Date pwdUpdateDate)
|
|
||||||
{
|
|
||||||
Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
|
|
||||||
return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查密码是否过期
|
|
||||||
public boolean passwordIsExpiration(Date pwdUpdateDate)
|
|
||||||
{
|
|
||||||
Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
|
|
||||||
if (passwordValidateDays != null && passwordValidateDays > 0)
|
|
||||||
{
|
|
||||||
if (StringUtils.isNull(pwdUpdateDate))
|
|
||||||
{
|
|
||||||
// 如果从未修改过初始密码,直接提醒过期
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Date nowDate = DateUtils.getNowDate();
|
|
||||||
return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,82 +1,65 @@
|
||||||
package com.ruoyi.web.controller.system;
|
package com.ruoyi.web.controller.system;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.apache.shiro.authc.AuthenticationException;
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||||
import org.apache.shiro.subject.Subject;
|
import org.apache.shiro.subject.Subject;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import com.ruoyi.common.utils.ServletUtils;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.common.core.text.Convert;
|
/**
|
||||||
import com.ruoyi.common.utils.ServletUtils;
|
* 登录验证
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
*
|
||||||
import com.ruoyi.framework.web.service.ConfigService;
|
* @author ruoyi
|
||||||
|
*/
|
||||||
/**
|
@Controller
|
||||||
* 登录验证
|
public class SysLoginController extends BaseController
|
||||||
*
|
{
|
||||||
* @author ruoyi
|
@GetMapping("/login")
|
||||||
*/
|
public String login(HttpServletRequest request, HttpServletResponse response)
|
||||||
@Controller
|
{
|
||||||
public class SysLoginController extends BaseController
|
// 如果是Ajax请求,返回Json字符串。
|
||||||
{
|
if (ServletUtils.isAjaxRequest(request))
|
||||||
/**
|
{
|
||||||
* 是否开启记住我功能
|
return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
|
||||||
*/
|
}
|
||||||
@Value("${shiro.rememberMe.enabled: false}")
|
|
||||||
private boolean rememberMe;
|
return "login";
|
||||||
|
}
|
||||||
@Autowired
|
|
||||||
private ConfigService configService;
|
@PostMapping("/login")
|
||||||
|
@ResponseBody
|
||||||
@GetMapping("/login")
|
public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
|
||||||
public String login(HttpServletRequest request, HttpServletResponse response, ModelMap mmap)
|
{
|
||||||
{
|
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
|
||||||
// 如果是Ajax请求,返回Json字符串。
|
Subject subject = SecurityUtils.getSubject();
|
||||||
if (ServletUtils.isAjaxRequest(request))
|
try
|
||||||
{
|
{
|
||||||
return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
|
subject.login(token);
|
||||||
}
|
return success();
|
||||||
// 是否开启记住我
|
}
|
||||||
mmap.put("isRemembered", rememberMe);
|
catch (AuthenticationException e)
|
||||||
// 是否开启用户注册
|
{
|
||||||
mmap.put("isAllowRegister", Convert.toBool(configService.getKey("sys.account.registerUser"), false));
|
String msg = "用户或密码错误";
|
||||||
return "login";
|
if (StringUtils.isNotEmpty(e.getMessage()))
|
||||||
}
|
{
|
||||||
|
msg = e.getMessage();
|
||||||
@PostMapping("/login")
|
}
|
||||||
@ResponseBody
|
return error(msg);
|
||||||
public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
|
}
|
||||||
{
|
}
|
||||||
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
|
|
||||||
Subject subject = SecurityUtils.getSubject();
|
@GetMapping("/unauth")
|
||||||
try
|
public String unauth()
|
||||||
{
|
{
|
||||||
subject.login(token);
|
return "/error/unauth";
|
||||||
return success();
|
}
|
||||||
}
|
}
|
||||||
catch (AuthenticationException e)
|
|
||||||
{
|
|
||||||
String msg = "用户或密码错误";
|
|
||||||
if (StringUtils.isNotEmpty(e.getMessage()))
|
|
||||||
{
|
|
||||||
msg = e.getMessage();
|
|
||||||
}
|
|
||||||
return error(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/unauth")
|
|
||||||
public String unauth()
|
|
||||||
{
|
|
||||||
return "error/unauth";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
@ -15,11 +14,10 @@ import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.Ztree;
|
import com.ruoyi.common.core.domain.Ztree;
|
||||||
import com.ruoyi.common.core.domain.entity.SysMenu;
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.ShiroUtils;
|
import com.ruoyi.framework.util.ShiroUtils;
|
||||||
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
|
import com.ruoyi.system.domain.SysMenu;
|
||||||
|
import com.ruoyi.system.domain.SysRole;
|
||||||
import com.ruoyi.system.service.ISysMenuService;
|
import com.ruoyi.system.service.ISysMenuService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -44,12 +42,11 @@ public class SysMenuController extends BaseController
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresPermissions("system:menu:list")
|
@RequiresPermissions("system:menu:list")
|
||||||
@PostMapping("/list")
|
@GetMapping("/list")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<SysMenu> list(SysMenu menu)
|
public List<SysMenu> list(SysMenu menu)
|
||||||
{
|
{
|
||||||
Long userId = ShiroUtils.getUserId();
|
List<SysMenu> menuList = menuService.selectMenuList(menu);
|
||||||
List<SysMenu> menuList = menuService.selectMenuList(menu, userId);
|
|
||||||
return menuList;
|
return menuList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,7 +67,7 @@ public class SysMenuController extends BaseController
|
||||||
{
|
{
|
||||||
return AjaxResult.warn("菜单已分配,不允许删除");
|
return AjaxResult.warn("菜单已分配,不允许删除");
|
||||||
}
|
}
|
||||||
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
ShiroUtils.clearCachedAuthorizationInfo();
|
||||||
return toAjax(menuService.deleteMenuById(menuId));
|
return toAjax(menuService.deleteMenuById(menuId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,21 +99,16 @@ public class SysMenuController extends BaseController
|
||||||
@RequiresPermissions("system:menu:add")
|
@RequiresPermissions("system:menu:add")
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult addSave(@Validated SysMenu menu)
|
public AjaxResult addSave(SysMenu menu)
|
||||||
{
|
{
|
||||||
if (!menuService.checkMenuNameUnique(menu))
|
menu.setCreateBy(ShiroUtils.getLoginName());
|
||||||
{
|
ShiroUtils.clearCachedAuthorizationInfo();
|
||||||
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
|
|
||||||
}
|
|
||||||
menu.setCreateBy(getLoginName());
|
|
||||||
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
|
||||||
return toAjax(menuService.insertMenu(menu));
|
return toAjax(menuService.insertMenu(menu));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改菜单
|
* 修改菜单
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("system:menu:edit")
|
|
||||||
@GetMapping("/edit/{menuId}")
|
@GetMapping("/edit/{menuId}")
|
||||||
public String edit(@PathVariable("menuId") Long menuId, ModelMap mmap)
|
public String edit(@PathVariable("menuId") Long menuId, ModelMap mmap)
|
||||||
{
|
{
|
||||||
|
|
@ -131,14 +123,10 @@ public class SysMenuController extends BaseController
|
||||||
@RequiresPermissions("system:menu:edit")
|
@RequiresPermissions("system:menu:edit")
|
||||||
@PostMapping("/edit")
|
@PostMapping("/edit")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult editSave(@Validated SysMenu menu)
|
public AjaxResult editSave(SysMenu menu)
|
||||||
{
|
{
|
||||||
if (!menuService.checkMenuNameUnique(menu))
|
menu.setUpdateBy(ShiroUtils.getLoginName());
|
||||||
{
|
ShiroUtils.clearCachedAuthorizationInfo();
|
||||||
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
|
|
||||||
}
|
|
||||||
menu.setUpdateBy(getLoginName());
|
|
||||||
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
|
||||||
return toAjax(menuService.updateMenu(menu));
|
return toAjax(menuService.updateMenu(menu));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,7 +144,7 @@ public class SysMenuController extends BaseController
|
||||||
*/
|
*/
|
||||||
@PostMapping("/checkMenuNameUnique")
|
@PostMapping("/checkMenuNameUnique")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public boolean checkMenuNameUnique(SysMenu menu)
|
public String checkMenuNameUnique(SysMenu menu)
|
||||||
{
|
{
|
||||||
return menuService.checkMenuNameUnique(menu);
|
return menuService.checkMenuNameUnique(menu);
|
||||||
}
|
}
|
||||||
|
|
@ -168,8 +156,7 @@ public class SysMenuController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<Ztree> roleMenuTreeData(SysRole role)
|
public List<Ztree> roleMenuTreeData(SysRole role)
|
||||||
{
|
{
|
||||||
Long userId = ShiroUtils.getUserId();
|
List<Ztree> ztrees = menuService.roleMenuTreeData(role);
|
||||||
List<Ztree> ztrees = menuService.roleMenuTreeData(role, userId);
|
|
||||||
return ztrees;
|
return ztrees;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,10 +165,9 @@ public class SysMenuController extends BaseController
|
||||||
*/
|
*/
|
||||||
@GetMapping("/menuTreeData")
|
@GetMapping("/menuTreeData")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<Ztree> menuTreeData()
|
public List<Ztree> menuTreeData(SysRole role)
|
||||||
{
|
{
|
||||||
Long userId = ShiroUtils.getUserId();
|
List<Ztree> ztrees = menuService.menuTreeData();
|
||||||
List<Ztree> ztrees = menuService.menuTreeData(userId);
|
|
||||||
return ztrees;
|
return ztrees;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
@ -16,6 +15,7 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.framework.util.ShiroUtils;
|
||||||
import com.ruoyi.system.domain.SysNotice;
|
import com.ruoyi.system.domain.SysNotice;
|
||||||
import com.ruoyi.system.service.ISysNoticeService;
|
import com.ruoyi.system.service.ISysNoticeService;
|
||||||
|
|
||||||
|
|
@ -69,16 +69,15 @@ public class SysNoticeController extends BaseController
|
||||||
@Log(title = "通知公告", businessType = BusinessType.INSERT)
|
@Log(title = "通知公告", businessType = BusinessType.INSERT)
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult addSave(@Validated SysNotice notice)
|
public AjaxResult addSave(SysNotice notice)
|
||||||
{
|
{
|
||||||
notice.setCreateBy(getLoginName());
|
notice.setCreateBy(ShiroUtils.getLoginName());
|
||||||
return toAjax(noticeService.insertNotice(notice));
|
return toAjax(noticeService.insertNotice(notice));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改公告
|
* 修改公告
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("system:notice:edit")
|
|
||||||
@GetMapping("/edit/{noticeId}")
|
@GetMapping("/edit/{noticeId}")
|
||||||
public String edit(@PathVariable("noticeId") Long noticeId, ModelMap mmap)
|
public String edit(@PathVariable("noticeId") Long noticeId, ModelMap mmap)
|
||||||
{
|
{
|
||||||
|
|
@ -93,23 +92,12 @@ public class SysNoticeController extends BaseController
|
||||||
@Log(title = "通知公告", businessType = BusinessType.UPDATE)
|
@Log(title = "通知公告", businessType = BusinessType.UPDATE)
|
||||||
@PostMapping("/edit")
|
@PostMapping("/edit")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult editSave(@Validated SysNotice notice)
|
public AjaxResult editSave(SysNotice notice)
|
||||||
{
|
{
|
||||||
notice.setUpdateBy(getLoginName());
|
notice.setUpdateBy(ShiroUtils.getLoginName());
|
||||||
return toAjax(noticeService.updateNotice(notice));
|
return toAjax(noticeService.updateNotice(notice));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询公告详细
|
|
||||||
*/
|
|
||||||
@RequiresPermissions("system:notice:list")
|
|
||||||
@GetMapping("/view/{noticeId}")
|
|
||||||
public String view(@PathVariable("noticeId") Long noticeId, ModelMap mmap)
|
|
||||||
{
|
|
||||||
mmap.put("notice", noticeService.selectNoticeById(noticeId));
|
|
||||||
return prefix + "/view";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除公告
|
* 删除公告
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
@ -17,6 +16,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
|
import com.ruoyi.framework.util.ShiroUtils;
|
||||||
import com.ruoyi.system.domain.SysPost;
|
import com.ruoyi.system.domain.SysPost;
|
||||||
import com.ruoyi.system.service.ISysPostService;
|
import com.ruoyi.system.service.ISysPostService;
|
||||||
|
|
||||||
|
|
@ -94,24 +94,15 @@ public class SysPostController extends BaseController
|
||||||
@Log(title = "岗位管理", businessType = BusinessType.INSERT)
|
@Log(title = "岗位管理", businessType = BusinessType.INSERT)
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult addSave(@Validated SysPost post)
|
public AjaxResult addSave(SysPost post)
|
||||||
{
|
{
|
||||||
if (!postService.checkPostNameUnique(post))
|
post.setCreateBy(ShiroUtils.getLoginName());
|
||||||
{
|
|
||||||
return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
|
|
||||||
}
|
|
||||||
else if (!postService.checkPostCodeUnique(post))
|
|
||||||
{
|
|
||||||
return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
|
|
||||||
}
|
|
||||||
post.setCreateBy(getLoginName());
|
|
||||||
return toAjax(postService.insertPost(post));
|
return toAjax(postService.insertPost(post));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改岗位
|
* 修改岗位
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("system:post:edit")
|
|
||||||
@GetMapping("/edit/{postId}")
|
@GetMapping("/edit/{postId}")
|
||||||
public String edit(@PathVariable("postId") Long postId, ModelMap mmap)
|
public String edit(@PathVariable("postId") Long postId, ModelMap mmap)
|
||||||
{
|
{
|
||||||
|
|
@ -126,17 +117,9 @@ public class SysPostController extends BaseController
|
||||||
@Log(title = "岗位管理", businessType = BusinessType.UPDATE)
|
@Log(title = "岗位管理", businessType = BusinessType.UPDATE)
|
||||||
@PostMapping("/edit")
|
@PostMapping("/edit")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult editSave(@Validated SysPost post)
|
public AjaxResult editSave(SysPost post)
|
||||||
{
|
{
|
||||||
if (!postService.checkPostNameUnique(post))
|
post.setUpdateBy(ShiroUtils.getLoginName());
|
||||||
{
|
|
||||||
return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
|
|
||||||
}
|
|
||||||
else if (!postService.checkPostCodeUnique(post))
|
|
||||||
{
|
|
||||||
return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
|
|
||||||
}
|
|
||||||
post.setUpdateBy(getLoginName());
|
|
||||||
return toAjax(postService.updatePost(post));
|
return toAjax(postService.updatePost(post));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,7 +128,7 @@ public class SysPostController extends BaseController
|
||||||
*/
|
*/
|
||||||
@PostMapping("/checkPostNameUnique")
|
@PostMapping("/checkPostNameUnique")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public boolean checkPostNameUnique(SysPost post)
|
public String checkPostNameUnique(SysPost post)
|
||||||
{
|
{
|
||||||
return postService.checkPostNameUnique(post);
|
return postService.checkPostNameUnique(post);
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +138,7 @@ public class SysPostController extends BaseController
|
||||||
*/
|
*/
|
||||||
@PostMapping("/checkPostCodeUnique")
|
@PostMapping("/checkPostCodeUnique")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public boolean checkPostCodeUnique(SysPost post)
|
public String checkPostCodeUnique(SysPost post)
|
||||||
{
|
{
|
||||||
return postService.checkPostCodeUnique(post);
|
return postService.checkPostCodeUnique(post);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,17 +12,15 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.config.RuoYiConfig;
|
import com.ruoyi.common.config.Global;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
|
||||||
import com.ruoyi.common.utils.ShiroUtils;
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||||
import com.ruoyi.common.utils.file.MimeTypeUtils;
|
|
||||||
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
||||||
|
import com.ruoyi.framework.util.ShiroUtils;
|
||||||
|
import com.ruoyi.system.domain.SysUser;
|
||||||
import com.ruoyi.system.service.ISysUserService;
|
import com.ruoyi.system.service.ISysUserService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -50,7 +48,7 @@ public class SysProfileController extends BaseController
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
public String profile(ModelMap mmap)
|
public String profile(ModelMap mmap)
|
||||||
{
|
{
|
||||||
SysUser user = getSysUser();
|
SysUser user = ShiroUtils.getSysUser();
|
||||||
mmap.put("user", user);
|
mmap.put("user", user);
|
||||||
mmap.put("roleGroup", userService.selectUserRoleGroup(user.getUserId()));
|
mmap.put("roleGroup", userService.selectUserRoleGroup(user.getUserId()));
|
||||||
mmap.put("postGroup", userService.selectUserPostGroup(user.getUserId()));
|
mmap.put("postGroup", userService.selectUserPostGroup(user.getUserId()));
|
||||||
|
|
@ -61,14 +59,18 @@ public class SysProfileController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public boolean checkPassword(String password)
|
public boolean checkPassword(String password)
|
||||||
{
|
{
|
||||||
SysUser user = getSysUser();
|
SysUser user = ShiroUtils.getSysUser();
|
||||||
return passwordService.matches(user, password);
|
if (passwordService.matches(user, password))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/resetPwd")
|
@GetMapping("/resetPwd")
|
||||||
public String resetPwd(ModelMap mmap)
|
public String resetPwd(ModelMap mmap)
|
||||||
{
|
{
|
||||||
SysUser user = getSysUser();
|
SysUser user = ShiroUtils.getSysUser();
|
||||||
mmap.put("user", userService.selectUserById(user.getUserId()));
|
mmap.put("user", userService.selectUserById(user.getUserId()));
|
||||||
return prefix + "/resetPwd";
|
return prefix + "/resetPwd";
|
||||||
}
|
}
|
||||||
|
|
@ -78,24 +80,22 @@ public class SysProfileController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult resetPwd(String oldPassword, String newPassword)
|
public AjaxResult resetPwd(String oldPassword, String newPassword)
|
||||||
{
|
{
|
||||||
SysUser user = getSysUser();
|
SysUser user = ShiroUtils.getSysUser();
|
||||||
if (!passwordService.matches(user, oldPassword))
|
if (StringUtils.isNotEmpty(newPassword) && passwordService.matches(user, oldPassword))
|
||||||
|
{
|
||||||
|
user.setSalt(ShiroUtils.randomSalt());
|
||||||
|
user.setPassword(passwordService.encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
|
||||||
|
if (userService.resetUserPwd(user) > 0)
|
||||||
|
{
|
||||||
|
ShiroUtils.setSysUser(userService.selectUserById(user.getUserId()));
|
||||||
|
return success();
|
||||||
|
}
|
||||||
|
return error();
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return error("修改密码失败,旧密码错误");
|
return error("修改密码失败,旧密码错误");
|
||||||
}
|
}
|
||||||
if (passwordService.matches(user, newPassword))
|
|
||||||
{
|
|
||||||
return error("新密码不能与旧密码相同");
|
|
||||||
}
|
|
||||||
user.setSalt(ShiroUtils.randomSalt());
|
|
||||||
user.setPassword(passwordService.encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
|
|
||||||
user.setPwdUpdateDate(DateUtils.getNowDate());
|
|
||||||
if (userService.resetUserPwd(user) > 0)
|
|
||||||
{
|
|
||||||
setSysUser(userService.selectUserById(user.getUserId()));
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
return error("修改密码异常,请联系管理员");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -104,7 +104,7 @@ public class SysProfileController extends BaseController
|
||||||
@GetMapping("/edit")
|
@GetMapping("/edit")
|
||||||
public String edit(ModelMap mmap)
|
public String edit(ModelMap mmap)
|
||||||
{
|
{
|
||||||
SysUser user = getSysUser();
|
SysUser user = ShiroUtils.getSysUser();
|
||||||
mmap.put("user", userService.selectUserById(user.getUserId()));
|
mmap.put("user", userService.selectUserById(user.getUserId()));
|
||||||
return prefix + "/edit";
|
return prefix + "/edit";
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +115,7 @@ public class SysProfileController extends BaseController
|
||||||
@GetMapping("/avatar")
|
@GetMapping("/avatar")
|
||||||
public String avatar(ModelMap mmap)
|
public String avatar(ModelMap mmap)
|
||||||
{
|
{
|
||||||
SysUser user = getSysUser();
|
SysUser user = ShiroUtils.getSysUser();
|
||||||
mmap.put("user", userService.selectUserById(user.getUserId()));
|
mmap.put("user", userService.selectUserById(user.getUserId()));
|
||||||
return prefix + "/avatar";
|
return prefix + "/avatar";
|
||||||
}
|
}
|
||||||
|
|
@ -128,22 +128,14 @@ public class SysProfileController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult update(SysUser user)
|
public AjaxResult update(SysUser user)
|
||||||
{
|
{
|
||||||
SysUser currentUser = getSysUser();
|
SysUser currentUser = ShiroUtils.getSysUser();
|
||||||
currentUser.setUserName(user.getUserName());
|
currentUser.setUserName(user.getUserName());
|
||||||
currentUser.setEmail(user.getEmail());
|
currentUser.setEmail(user.getEmail());
|
||||||
currentUser.setPhonenumber(user.getPhonenumber());
|
currentUser.setPhonenumber(user.getPhonenumber());
|
||||||
currentUser.setSex(user.getSex());
|
currentUser.setSex(user.getSex());
|
||||||
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
|
|
||||||
{
|
|
||||||
return error("修改用户'" + currentUser.getLoginName() + "'失败,手机号码已存在");
|
|
||||||
}
|
|
||||||
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
|
|
||||||
{
|
|
||||||
return error("修改用户'" + currentUser.getLoginName() + "'失败,邮箱账号已存在");
|
|
||||||
}
|
|
||||||
if (userService.updateUserInfo(currentUser) > 0)
|
if (userService.updateUserInfo(currentUser) > 0)
|
||||||
{
|
{
|
||||||
setSysUser(userService.selectUserById(currentUser.getUserId()));
|
ShiroUtils.setSysUser(userService.selectUserById(currentUser.getUserId()));
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
return error();
|
return error();
|
||||||
|
|
@ -157,16 +149,16 @@ public class SysProfileController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult updateAvatar(@RequestParam("avatarfile") MultipartFile file)
|
public AjaxResult updateAvatar(@RequestParam("avatarfile") MultipartFile file)
|
||||||
{
|
{
|
||||||
SysUser currentUser = getSysUser();
|
SysUser currentUser = ShiroUtils.getSysUser();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!file.isEmpty())
|
if (!file.isEmpty())
|
||||||
{
|
{
|
||||||
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
|
String avatar = FileUploadUtils.upload(Global.getAvatarPath(), file);
|
||||||
currentUser.setAvatar(avatar);
|
currentUser.setAvatar(avatar);
|
||||||
if (userService.updateUserInfo(currentUser) > 0)
|
if (userService.updateUserInfo(currentUser) > 0)
|
||||||
{
|
{
|
||||||
setSysUser(userService.selectUserById(currentUser.getUserId()));
|
ShiroUtils.setSysUser(userService.selectUserById(currentUser.getUserId()));
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
package com.ruoyi.web.controller.system;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
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.ResponseBody;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
|
||||||
import com.ruoyi.framework.shiro.service.SysRegisterService;
|
|
||||||
import com.ruoyi.system.service.ISysConfigService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 注册验证
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
public class SysRegisterController extends BaseController
|
|
||||||
{
|
|
||||||
@Autowired
|
|
||||||
private SysRegisterService registerService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ISysConfigService configService;
|
|
||||||
|
|
||||||
@GetMapping("/register")
|
|
||||||
public String register()
|
|
||||||
{
|
|
||||||
return "register";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/register")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult ajaxRegister(SysUser user)
|
|
||||||
{
|
|
||||||
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
|
|
||||||
{
|
|
||||||
return error("当前系统没有开启注册功能!");
|
|
||||||
}
|
|
||||||
String msg = registerService.register(user);
|
|
||||||
return StringUtils.isEmpty(msg) ? success() : error(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,7 +5,6 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
@ -14,15 +13,13 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.Ztree;
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
|
import com.ruoyi.framework.util.ShiroUtils;
|
||||||
|
import com.ruoyi.system.domain.SysRole;
|
||||||
|
import com.ruoyi.system.domain.SysUser;
|
||||||
import com.ruoyi.system.domain.SysUserRole;
|
import com.ruoyi.system.domain.SysUserRole;
|
||||||
import com.ruoyi.system.service.ISysDeptService;
|
|
||||||
import com.ruoyi.system.service.ISysRoleService;
|
import com.ruoyi.system.service.ISysRoleService;
|
||||||
import com.ruoyi.system.service.ISysUserService;
|
import com.ruoyi.system.service.ISysUserService;
|
||||||
|
|
||||||
|
|
@ -43,9 +40,6 @@ public class SysRoleController extends BaseController
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysUserService userService;
|
private ISysUserService userService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ISysDeptService deptService;
|
|
||||||
|
|
||||||
@RequiresPermissions("system:role:view")
|
@RequiresPermissions("system:role:view")
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
public String role()
|
public String role()
|
||||||
|
|
@ -90,18 +84,10 @@ public class SysRoleController extends BaseController
|
||||||
@Log(title = "角色管理", businessType = BusinessType.INSERT)
|
@Log(title = "角色管理", businessType = BusinessType.INSERT)
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult addSave(@Validated SysRole role)
|
public AjaxResult addSave(SysRole role)
|
||||||
{
|
{
|
||||||
if (!roleService.checkRoleNameUnique(role))
|
role.setCreateBy(ShiroUtils.getLoginName());
|
||||||
{
|
ShiroUtils.clearCachedAuthorizationInfo();
|
||||||
return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
|
|
||||||
}
|
|
||||||
else if (!roleService.checkRoleKeyUnique(role))
|
|
||||||
{
|
|
||||||
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
|
|
||||||
}
|
|
||||||
role.setCreateBy(getLoginName());
|
|
||||||
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
|
||||||
return toAjax(roleService.insertRole(role));
|
return toAjax(roleService.insertRole(role));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -109,11 +95,9 @@ public class SysRoleController extends BaseController
|
||||||
/**
|
/**
|
||||||
* 修改角色
|
* 修改角色
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("system:role:edit")
|
|
||||||
@GetMapping("/edit/{roleId}")
|
@GetMapping("/edit/{roleId}")
|
||||||
public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap)
|
public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap)
|
||||||
{
|
{
|
||||||
roleService.checkRoleDataScope(roleId);
|
|
||||||
mmap.put("role", roleService.selectRoleById(roleId));
|
mmap.put("role", roleService.selectRoleById(roleId));
|
||||||
return prefix + "/edit";
|
return prefix + "/edit";
|
||||||
}
|
}
|
||||||
|
|
@ -125,20 +109,10 @@ public class SysRoleController extends BaseController
|
||||||
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
|
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
|
||||||
@PostMapping("/edit")
|
@PostMapping("/edit")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult editSave(@Validated SysRole role)
|
public AjaxResult editSave(SysRole role)
|
||||||
{
|
{
|
||||||
roleService.checkRoleAllowed(role);
|
role.setUpdateBy(ShiroUtils.getLoginName());
|
||||||
roleService.checkRoleDataScope(role.getRoleId());
|
ShiroUtils.clearCachedAuthorizationInfo();
|
||||||
if (!roleService.checkRoleNameUnique(role))
|
|
||||||
{
|
|
||||||
return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
|
|
||||||
}
|
|
||||||
else if (!roleService.checkRoleKeyUnique(role))
|
|
||||||
{
|
|
||||||
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
|
|
||||||
}
|
|
||||||
role.setUpdateBy(getLoginName());
|
|
||||||
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
|
||||||
return toAjax(roleService.updateRole(role));
|
return toAjax(roleService.updateRole(role));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,15 +135,7 @@ public class SysRoleController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult authDataScopeSave(SysRole role)
|
public AjaxResult authDataScopeSave(SysRole role)
|
||||||
{
|
{
|
||||||
roleService.checkRoleAllowed(role);
|
return toAjax(roleService.authDataScope(role));
|
||||||
roleService.checkRoleDataScope(role.getRoleId());
|
|
||||||
role.setUpdateBy(getLoginName());
|
|
||||||
if (roleService.authDataScope(role) > 0)
|
|
||||||
{
|
|
||||||
setSysUser(userService.selectUserById(getUserId()));
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
return error();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresPermissions("system:role:remove")
|
@RequiresPermissions("system:role:remove")
|
||||||
|
|
@ -178,7 +144,14 @@ public class SysRoleController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult remove(String ids)
|
public AjaxResult remove(String ids)
|
||||||
{
|
{
|
||||||
return toAjax(roleService.deleteRoleByIds(ids));
|
try
|
||||||
|
{
|
||||||
|
return toAjax(roleService.deleteRoleByIds(ids));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return error(e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -186,7 +159,7 @@ public class SysRoleController extends BaseController
|
||||||
*/
|
*/
|
||||||
@PostMapping("/checkRoleNameUnique")
|
@PostMapping("/checkRoleNameUnique")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public boolean checkRoleNameUnique(SysRole role)
|
public String checkRoleNameUnique(SysRole role)
|
||||||
{
|
{
|
||||||
return roleService.checkRoleNameUnique(role);
|
return roleService.checkRoleNameUnique(role);
|
||||||
}
|
}
|
||||||
|
|
@ -196,7 +169,7 @@ public class SysRoleController extends BaseController
|
||||||
*/
|
*/
|
||||||
@PostMapping("/checkRoleKeyUnique")
|
@PostMapping("/checkRoleKeyUnique")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public boolean checkRoleKeyUnique(SysRole role)
|
public String checkRoleKeyUnique(SysRole role)
|
||||||
{
|
{
|
||||||
return roleService.checkRoleKeyUnique(role);
|
return roleService.checkRoleKeyUnique(role);
|
||||||
}
|
}
|
||||||
|
|
@ -219,8 +192,6 @@ public class SysRoleController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult changeStatus(SysRole role)
|
public AjaxResult changeStatus(SysRole role)
|
||||||
{
|
{
|
||||||
roleService.checkRoleAllowed(role);
|
|
||||||
roleService.checkRoleDataScope(role.getRoleId());
|
|
||||||
return toAjax(roleService.changeStatus(role));
|
return toAjax(roleService.changeStatus(role));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,7 +222,6 @@ public class SysRoleController extends BaseController
|
||||||
/**
|
/**
|
||||||
* 取消授权
|
* 取消授权
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("system:role:edit")
|
|
||||||
@Log(title = "角色管理", businessType = BusinessType.GRANT)
|
@Log(title = "角色管理", businessType = BusinessType.GRANT)
|
||||||
@PostMapping("/authUser/cancel")
|
@PostMapping("/authUser/cancel")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
|
@ -263,7 +233,6 @@ public class SysRoleController extends BaseController
|
||||||
/**
|
/**
|
||||||
* 批量取消授权
|
* 批量取消授权
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("system:role:edit")
|
|
||||||
@Log(title = "角色管理", businessType = BusinessType.GRANT)
|
@Log(title = "角色管理", businessType = BusinessType.GRANT)
|
||||||
@PostMapping("/authUser/cancelAll")
|
@PostMapping("/authUser/cancelAll")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
|
@ -298,25 +267,11 @@ public class SysRoleController extends BaseController
|
||||||
/**
|
/**
|
||||||
* 批量选择用户授权
|
* 批量选择用户授权
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("system:role:edit")
|
|
||||||
@Log(title = "角色管理", businessType = BusinessType.GRANT)
|
@Log(title = "角色管理", businessType = BusinessType.GRANT)
|
||||||
@PostMapping("/authUser/selectAll")
|
@PostMapping("/authUser/selectAll")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult selectAuthUserAll(Long roleId, String userIds)
|
public AjaxResult selectAuthUserAll(Long roleId, String userIds)
|
||||||
{
|
{
|
||||||
roleService.checkRoleDataScope(roleId);
|
|
||||||
return toAjax(roleService.insertAuthUsers(roleId, userIds));
|
return toAjax(roleService.insertAuthUsers(roleId, userIds));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 加载角色部门(数据权限)列表树
|
|
||||||
*/
|
|
||||||
@RequiresPermissions("system:role:edit")
|
|
||||||
@GetMapping("/deptTreeData")
|
|
||||||
@ResponseBody
|
|
||||||
public List<Ztree> deptTreeData(SysRole role)
|
|
||||||
{
|
|
||||||
List<Ztree> ztrees = deptService.roleDeptTreeData(role);
|
|
||||||
return ztrees;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
package com.ruoyi.web.controller.system;
|
package com.ruoyi.web.controller.system;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
@ -17,20 +14,13 @@ import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.Ztree;
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.core.text.Convert;
|
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
|
||||||
import com.ruoyi.common.utils.ShiroUtils;
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
||||||
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
|
import com.ruoyi.framework.util.ShiroUtils;
|
||||||
import com.ruoyi.system.service.ISysDeptService;
|
import com.ruoyi.system.domain.SysUser;
|
||||||
import com.ruoyi.system.service.ISysPostService;
|
import com.ruoyi.system.service.ISysPostService;
|
||||||
import com.ruoyi.system.service.ISysRoleService;
|
import com.ruoyi.system.service.ISysRoleService;
|
||||||
import com.ruoyi.system.service.ISysUserService;
|
import com.ruoyi.system.service.ISysUserService;
|
||||||
|
|
@ -51,9 +41,6 @@ public class SysUserController extends BaseController
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysRoleService roleService;
|
private ISysRoleService roleService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ISysDeptService deptService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysPostService postService;
|
private ISysPostService postService;
|
||||||
|
|
@ -97,7 +84,8 @@ public class SysUserController extends BaseController
|
||||||
{
|
{
|
||||||
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
|
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
|
||||||
List<SysUser> userList = util.importExcel(file.getInputStream());
|
List<SysUser> userList = util.importExcel(file.getInputStream());
|
||||||
String message = userService.importUser(userList, updateSupport, getLoginName());
|
String operName = ShiroUtils.getSysUser().getLoginName();
|
||||||
|
String message = userService.importUser(userList, updateSupport, operName);
|
||||||
return AjaxResult.success(message);
|
return AjaxResult.success(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,7 +104,7 @@ public class SysUserController extends BaseController
|
||||||
@GetMapping("/add")
|
@GetMapping("/add")
|
||||||
public String add(ModelMap mmap)
|
public String add(ModelMap mmap)
|
||||||
{
|
{
|
||||||
mmap.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
|
mmap.put("roles", roleService.selectRoleAll());
|
||||||
mmap.put("posts", postService.selectPostAll());
|
mmap.put("posts", postService.selectPostAll());
|
||||||
return prefix + "/add";
|
return prefix + "/add";
|
||||||
}
|
}
|
||||||
|
|
@ -128,58 +116,30 @@ public class SysUserController extends BaseController
|
||||||
@Log(title = "用户管理", businessType = BusinessType.INSERT)
|
@Log(title = "用户管理", businessType = BusinessType.INSERT)
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult addSave(@Validated SysUser user)
|
public AjaxResult addSave(SysUser user)
|
||||||
{
|
{
|
||||||
deptService.checkDeptDataScope(user.getDeptId());
|
if (StringUtils.isNotNull(user.getUserId()) && SysUser.isAdmin(user.getUserId()))
|
||||||
roleService.checkRoleDataScope(user.getRoleIds());
|
|
||||||
if (!userService.checkLoginNameUnique(user))
|
|
||||||
{
|
{
|
||||||
return error("新增用户'" + user.getLoginName() + "'失败,登录账号已存在");
|
return error("不允许修改超级管理员用户");
|
||||||
}
|
|
||||||
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
|
|
||||||
{
|
|
||||||
return error("新增用户'" + user.getLoginName() + "'失败,手机号码已存在");
|
|
||||||
}
|
|
||||||
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
|
|
||||||
{
|
|
||||||
return error("新增用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
|
|
||||||
}
|
}
|
||||||
user.setSalt(ShiroUtils.randomSalt());
|
user.setSalt(ShiroUtils.randomSalt());
|
||||||
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
|
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
|
||||||
user.setPwdUpdateDate(DateUtils.getNowDate());
|
user.setCreateBy(ShiroUtils.getLoginName());
|
||||||
user.setCreateBy(getLoginName());
|
|
||||||
return toAjax(userService.insertUser(user));
|
return toAjax(userService.insertUser(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改用户
|
* 修改用户
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("system:user:edit")
|
|
||||||
@GetMapping("/edit/{userId}")
|
@GetMapping("/edit/{userId}")
|
||||||
public String edit(@PathVariable("userId") Long userId, ModelMap mmap)
|
public String edit(@PathVariable("userId") Long userId, ModelMap mmap)
|
||||||
{
|
{
|
||||||
userService.checkUserDataScope(userId);
|
|
||||||
List<SysRole> roles = roleService.selectRolesByUserId(userId);
|
|
||||||
mmap.put("user", userService.selectUserById(userId));
|
mmap.put("user", userService.selectUserById(userId));
|
||||||
mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
|
mmap.put("roles", roleService.selectRolesByUserId(userId));
|
||||||
mmap.put("posts", postService.selectPostsByUserId(userId));
|
mmap.put("posts", postService.selectPostsByUserId(userId));
|
||||||
return prefix + "/edit";
|
return prefix + "/edit";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询用户详细
|
|
||||||
*/
|
|
||||||
@RequiresPermissions("system:user:list")
|
|
||||||
@GetMapping("/view/{userId}")
|
|
||||||
public String view(@PathVariable("userId") Long userId, ModelMap mmap)
|
|
||||||
{
|
|
||||||
userService.checkUserDataScope(userId);
|
|
||||||
mmap.put("user", userService.selectUserById(userId));
|
|
||||||
mmap.put("roleGroup", userService.selectUserRoleGroup(userId));
|
|
||||||
mmap.put("postGroup", userService.selectUserPostGroup(userId));
|
|
||||||
return prefix + "/view";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改保存用户
|
* 修改保存用户
|
||||||
*/
|
*/
|
||||||
|
|
@ -187,30 +147,18 @@ public class SysUserController extends BaseController
|
||||||
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
|
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
|
||||||
@PostMapping("/edit")
|
@PostMapping("/edit")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult editSave(@Validated SysUser user)
|
public AjaxResult editSave(SysUser user)
|
||||||
{
|
{
|
||||||
userService.checkUserAllowed(user);
|
if (StringUtils.isNotNull(user.getUserId()) && SysUser.isAdmin(user.getUserId()))
|
||||||
userService.checkUserDataScope(user.getUserId());
|
|
||||||
deptService.checkDeptDataScope(user.getDeptId());
|
|
||||||
roleService.checkRoleDataScope(user.getRoleIds());
|
|
||||||
if (!userService.checkLoginNameUnique(user))
|
|
||||||
{
|
{
|
||||||
return error("修改用户'" + user.getLoginName() + "'失败,登录账号已存在");
|
return error("不允许修改超级管理员用户");
|
||||||
}
|
}
|
||||||
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
|
user.setUpdateBy(ShiroUtils.getLoginName());
|
||||||
{
|
|
||||||
return error("修改用户'" + user.getLoginName() + "'失败,手机号码已存在");
|
|
||||||
}
|
|
||||||
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
|
|
||||||
{
|
|
||||||
return error("修改用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
|
|
||||||
}
|
|
||||||
user.setUpdateBy(getLoginName());
|
|
||||||
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
|
||||||
return toAjax(userService.updateUser(user));
|
return toAjax(userService.updateUser(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresPermissions("system:user:resetPwd")
|
@RequiresPermissions("system:user:resetPwd")
|
||||||
|
@Log(title = "重置密码", businessType = BusinessType.UPDATE)
|
||||||
@GetMapping("/resetPwd/{userId}")
|
@GetMapping("/resetPwd/{userId}")
|
||||||
public String resetPwd(@PathVariable("userId") Long userId, ModelMap mmap)
|
public String resetPwd(@PathVariable("userId") Long userId, ModelMap mmap)
|
||||||
{
|
{
|
||||||
|
|
@ -224,49 +172,9 @@ public class SysUserController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult resetPwdSave(SysUser user)
|
public AjaxResult resetPwdSave(SysUser user)
|
||||||
{
|
{
|
||||||
userService.checkUserAllowed(user);
|
|
||||||
userService.checkUserDataScope(user.getUserId());
|
|
||||||
user.setSalt(ShiroUtils.randomSalt());
|
user.setSalt(ShiroUtils.randomSalt());
|
||||||
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
|
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
|
||||||
if (userService.resetUserPwd(user) > 0)
|
return toAjax(userService.resetUserPwd(user));
|
||||||
{
|
|
||||||
if (ShiroUtils.getUserId().longValue() == user.getUserId().longValue())
|
|
||||||
{
|
|
||||||
setSysUser(userService.selectUserById(user.getUserId()));
|
|
||||||
}
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
return error();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进入授权角色页
|
|
||||||
*/
|
|
||||||
@GetMapping("/authRole/{userId}")
|
|
||||||
public String authRole(@PathVariable("userId") Long userId, ModelMap mmap)
|
|
||||||
{
|
|
||||||
SysUser user = userService.selectUserById(userId);
|
|
||||||
// 获取用户所属的角色列表
|
|
||||||
List<SysRole> roles = roleService.selectRolesByUserId(userId);
|
|
||||||
mmap.put("user", user);
|
|
||||||
mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
|
|
||||||
return prefix + "/authRole";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户授权角色
|
|
||||||
*/
|
|
||||||
@RequiresPermissions("system:user:edit")
|
|
||||||
@Log(title = "用户管理", businessType = BusinessType.GRANT)
|
|
||||||
@PostMapping("/authRole/insertAuthRole")
|
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
|
|
||||||
{
|
|
||||||
userService.checkUserDataScope(userId);
|
|
||||||
roleService.checkRoleDataScope(roleIds);
|
|
||||||
userService.insertUserAuth(userId, roleIds);
|
|
||||||
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
|
||||||
return success();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresPermissions("system:user:remove")
|
@RequiresPermissions("system:user:remove")
|
||||||
|
|
@ -275,11 +183,14 @@ public class SysUserController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult remove(String ids)
|
public AjaxResult remove(String ids)
|
||||||
{
|
{
|
||||||
if (ArrayUtils.contains(Convert.toLongArray(ids), getUserId()))
|
try
|
||||||
{
|
{
|
||||||
return error("当前用户不能删除");
|
return toAjax(userService.deleteUserByIds(ids));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return error(e.getMessage());
|
||||||
}
|
}
|
||||||
return toAjax(userService.deleteUserByIds(ids));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -287,9 +198,9 @@ public class SysUserController extends BaseController
|
||||||
*/
|
*/
|
||||||
@PostMapping("/checkLoginNameUnique")
|
@PostMapping("/checkLoginNameUnique")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public boolean checkLoginNameUnique(SysUser user)
|
public String checkLoginNameUnique(SysUser user)
|
||||||
{
|
{
|
||||||
return userService.checkLoginNameUnique(user);
|
return userService.checkLoginNameUnique(user.getLoginName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -297,7 +208,7 @@ public class SysUserController extends BaseController
|
||||||
*/
|
*/
|
||||||
@PostMapping("/checkPhoneUnique")
|
@PostMapping("/checkPhoneUnique")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public boolean checkPhoneUnique(SysUser user)
|
public String checkPhoneUnique(SysUser user)
|
||||||
{
|
{
|
||||||
return userService.checkPhoneUnique(user);
|
return userService.checkPhoneUnique(user);
|
||||||
}
|
}
|
||||||
|
|
@ -307,7 +218,7 @@ public class SysUserController extends BaseController
|
||||||
*/
|
*/
|
||||||
@PostMapping("/checkEmailUnique")
|
@PostMapping("/checkEmailUnique")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public boolean checkEmailUnique(SysUser user)
|
public String checkEmailUnique(SysUser user)
|
||||||
{
|
{
|
||||||
return userService.checkEmailUnique(user);
|
return userService.checkEmailUnique(user);
|
||||||
}
|
}
|
||||||
|
|
@ -321,33 +232,6 @@ public class SysUserController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult changeStatus(SysUser user)
|
public AjaxResult changeStatus(SysUser user)
|
||||||
{
|
{
|
||||||
userService.checkUserAllowed(user);
|
|
||||||
userService.checkUserDataScope(user.getUserId());
|
|
||||||
return toAjax(userService.changeStatus(user));
|
return toAjax(userService.changeStatus(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 加载部门列表树
|
|
||||||
*/
|
|
||||||
@RequiresPermissions("system:user:list")
|
|
||||||
@GetMapping("/deptTreeData")
|
|
||||||
@ResponseBody
|
|
||||||
public List<Ztree> deptTreeData()
|
|
||||||
{
|
|
||||||
List<Ztree> ztrees = deptService.selectDeptTree(new SysDept());
|
|
||||||
return ztrees;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 选择部门树
|
|
||||||
*
|
|
||||||
* @param deptId 部门ID
|
|
||||||
*/
|
|
||||||
@RequiresPermissions("system:user:list")
|
|
||||||
@GetMapping("/selectDeptTree/{deptId}")
|
|
||||||
public String selectDeptTree(@PathVariable("deptId") Long deptId, ModelMap mmap)
|
|
||||||
{
|
|
||||||
mmap.put("dept", deptService.selectDeptById(deptId));
|
|
||||||
return prefix + "/deptTree";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -19,6 +19,6 @@ public class SwaggerController extends BaseController
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
public String index()
|
public String index()
|
||||||
{
|
{
|
||||||
return redirect("/swagger-ui/index.html");
|
return redirect("/swagger-ui.html");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,152 +1,116 @@
|
||||||
package com.ruoyi.web.controller.tool;
|
package com.ruoyi.web.controller.tool;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
import io.swagger.annotations.ApiImplicitParams;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* swagger 用户测试方法
|
* swagger 测试方法
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@Api("用户信息管理")
|
@Api("用户信息管理")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/test/user")
|
@RequestMapping("/test/*")
|
||||||
public class TestController extends BaseController
|
public class TestController extends BaseController
|
||||||
{
|
{
|
||||||
private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
|
private final static List<Test> testList = new ArrayList<>();
|
||||||
{
|
{
|
||||||
users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
|
testList.add(new Test("1", "admin", "admin123"));
|
||||||
users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
|
testList.add(new Test("2", "ry", "admin123"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("获取用户列表")
|
@ApiOperation("获取列表")
|
||||||
@GetMapping("/list")
|
@GetMapping("list")
|
||||||
public R<List<UserEntity>> userList()
|
public List<Test> testList()
|
||||||
{
|
{
|
||||||
List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
|
return testList;
|
||||||
return R.ok(userList);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ApiOperation("获取用户详细")
|
|
||||||
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
|
|
||||||
@GetMapping("/{userId}")
|
|
||||||
public R<UserEntity> getUser(@PathVariable Integer userId)
|
|
||||||
{
|
|
||||||
if (!users.isEmpty() && users.containsKey(userId))
|
|
||||||
{
|
|
||||||
return R.ok(users.get(userId));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return R.fail("用户不存在");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("新增用户")
|
@ApiOperation("新增用户")
|
||||||
@ApiImplicitParams({
|
@PostMapping("save")
|
||||||
@ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class),
|
public AjaxResult save(Test test)
|
||||||
@ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class),
|
|
||||||
@ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class),
|
|
||||||
@ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class)
|
|
||||||
})
|
|
||||||
@PostMapping("/save")
|
|
||||||
public R<String> save(UserEntity user)
|
|
||||||
{
|
{
|
||||||
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
|
return testList.add(test) ? success() : error();
|
||||||
{
|
|
||||||
return R.fail("用户ID不能为空");
|
|
||||||
}
|
|
||||||
users.put(user.getUserId(), user);
|
|
||||||
return R.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("更新用户")
|
@ApiOperation("更新用户")
|
||||||
@PutMapping("/update")
|
@ApiImplicitParam(name = "Test", value = "单个用户信息", dataType = "Test")
|
||||||
public R<String> update(@RequestBody UserEntity user)
|
@PutMapping("update")
|
||||||
|
public AjaxResult update(Test test)
|
||||||
{
|
{
|
||||||
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
|
return testList.remove(test) && testList.add(test) ? success() : error();
|
||||||
{
|
|
||||||
return R.fail("用户ID不能为空");
|
|
||||||
}
|
|
||||||
if (users.isEmpty() || !users.containsKey(user.getUserId()))
|
|
||||||
{
|
|
||||||
return R.fail("用户不存在");
|
|
||||||
}
|
|
||||||
users.remove(user.getUserId());
|
|
||||||
users.put(user.getUserId(), user);
|
|
||||||
return R.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("删除用户信息")
|
@ApiOperation("删除用户")
|
||||||
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
|
@ApiImplicitParam(name = "Tests", value = "单个用户信息", dataType = "Test")
|
||||||
@DeleteMapping("/{userId}")
|
@DeleteMapping("delete")
|
||||||
public R<String> delete(@PathVariable Integer userId)
|
public AjaxResult delete(Test test)
|
||||||
{
|
{
|
||||||
if (!users.isEmpty() && users.containsKey(userId))
|
return testList.remove(test) ? success() : error();
|
||||||
{
|
|
||||||
users.remove(userId);
|
|
||||||
return R.ok();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return R.fail("用户不存在");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiModel(value = "UserEntity", description = "用户实体")
|
class Test
|
||||||
class UserEntity
|
|
||||||
{
|
{
|
||||||
@ApiModelProperty("用户ID")
|
private String userId;
|
||||||
private Integer userId;
|
|
||||||
|
|
||||||
@ApiModelProperty("用户名称")
|
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
@ApiModelProperty("用户密码")
|
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
@ApiModelProperty("用户手机")
|
public Test()
|
||||||
private String mobile;
|
|
||||||
|
|
||||||
public UserEntity()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserEntity(Integer userId, String username, String password, String mobile)
|
public Test(String userId, String username, String password)
|
||||||
{
|
{
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.mobile = mobile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getUserId()
|
@Override
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if (this == o)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Test test = (Test) o;
|
||||||
|
|
||||||
|
return userId != null ? userId.equals(test.userId) : test.userId == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
int result = userId != null ? userId.hashCode() : 0;
|
||||||
|
result = 31 * result + (username != null ? username.hashCode() : 0);
|
||||||
|
result = 31 * result + (password != null ? password.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserId()
|
||||||
{
|
{
|
||||||
return userId;
|
return userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserId(Integer userId)
|
public void setUserId(String userId)
|
||||||
{
|
{
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
}
|
}
|
||||||
|
|
@ -170,14 +134,4 @@ class UserEntity
|
||||||
{
|
{
|
||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMobile()
|
|
||||||
{
|
|
||||||
return mobile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMobile(String mobile)
|
|
||||||
{
|
|
||||||
this.mobile = mobile;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
package com.ruoyi.web.core.config;
|
package com.ruoyi.web.core.config;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import com.ruoyi.common.config.RuoYiConfig;
|
import com.ruoyi.common.config.Global;
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import springfox.documentation.builders.ApiInfoBuilder;
|
import springfox.documentation.builders.ApiInfoBuilder;
|
||||||
import springfox.documentation.builders.PathSelectors;
|
import springfox.documentation.builders.PathSelectors;
|
||||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||||
|
|
@ -12,6 +10,7 @@ import springfox.documentation.service.ApiInfo;
|
||||||
import springfox.documentation.service.Contact;
|
import springfox.documentation.service.Contact;
|
||||||
import springfox.documentation.spi.DocumentationType;
|
import springfox.documentation.spi.DocumentationType;
|
||||||
import springfox.documentation.spring.web.plugins.Docket;
|
import springfox.documentation.spring.web.plugins.Docket;
|
||||||
|
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Swagger2的接口配置
|
* Swagger2的接口配置
|
||||||
|
|
@ -19,29 +18,21 @@ import springfox.documentation.spring.web.plugins.Docket;
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@EnableSwagger2
|
||||||
public class SwaggerConfig
|
public class SwaggerConfig
|
||||||
{
|
{
|
||||||
/** 是否开启swagger */
|
|
||||||
@Value("${swagger.enabled}")
|
|
||||||
private boolean enabled;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建API
|
* 创建API
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public Docket createRestApi()
|
public Docket createRestApi()
|
||||||
{
|
{
|
||||||
return new Docket(DocumentationType.OAS_30)
|
return new Docket(DocumentationType.SWAGGER_2)
|
||||||
// 是否启用Swagger
|
// 详细定制
|
||||||
.enable(enabled)
|
|
||||||
// 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
|
|
||||||
.apiInfo(apiInfo())
|
.apiInfo(apiInfo())
|
||||||
// 设置哪些接口暴露给Swagger展示
|
|
||||||
.select()
|
.select()
|
||||||
// 扫描所有有注解的api,用这种方式更灵活
|
// 指定当前包路径
|
||||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
.apis(RequestHandlerSelectors.basePackage("com.ruoyi.web.controller.tool"))
|
||||||
// 扫描指定包中的swagger注解
|
|
||||||
//.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
|
|
||||||
// 扫描所有 .apis(RequestHandlerSelectors.any())
|
// 扫描所有 .apis(RequestHandlerSelectors.any())
|
||||||
.paths(PathSelectors.any())
|
.paths(PathSelectors.any())
|
||||||
.build();
|
.build();
|
||||||
|
|
@ -54,14 +45,10 @@ public class SwaggerConfig
|
||||||
{
|
{
|
||||||
// 用ApiInfoBuilder进行定制
|
// 用ApiInfoBuilder进行定制
|
||||||
return new ApiInfoBuilder()
|
return new ApiInfoBuilder()
|
||||||
// 设置标题
|
|
||||||
.title("标题:若依管理系统_接口文档")
|
.title("标题:若依管理系统_接口文档")
|
||||||
// 描述
|
|
||||||
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
|
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
|
||||||
// 作者信息
|
.contact(new Contact(Global.getName(), null, null))
|
||||||
.contact(new Contact(RuoYiConfig.getName(), null, null))
|
.version("版本号:" + Global.getVersion())
|
||||||
// 版本
|
|
||||||
.version("版本号:" + RuoYiConfig.getVersion())
|
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,6 @@ spring:
|
||||||
maxActive: 20
|
maxActive: 20
|
||||||
# 配置获取连接等待超时的时间
|
# 配置获取连接等待超时的时间
|
||||||
maxWait: 60000
|
maxWait: 60000
|
||||||
# 配置连接超时时间
|
|
||||||
connectTimeout: 30000
|
|
||||||
# 配置网络超时时间
|
|
||||||
socketTimeout: 60000
|
|
||||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||||
timeBetweenEvictionRunsMillis: 60000
|
timeBetweenEvictionRunsMillis: 60000
|
||||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||||
|
|
@ -45,10 +41,7 @@ spring:
|
||||||
enabled: true
|
enabled: true
|
||||||
# 设置白名单,不填则允许所有访问
|
# 设置白名单,不填则允许所有访问
|
||||||
allow:
|
allow:
|
||||||
url-pattern: /druid/*
|
url-pattern: /monitor/druid/*
|
||||||
# 控制台管理用户名和密码
|
|
||||||
login-username: ruoyi
|
|
||||||
login-password: 123456
|
|
||||||
filter:
|
filter:
|
||||||
stat:
|
stat:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
|
||||||
|
|
@ -3,39 +3,35 @@ ruoyi:
|
||||||
# 名称
|
# 名称
|
||||||
name: RuoYi
|
name: RuoYi
|
||||||
# 版本
|
# 版本
|
||||||
version: 4.7.9
|
version: 3.3.0
|
||||||
# 版权年份
|
# 版权年份
|
||||||
copyrightYear: 2024
|
copyrightYear: 2019
|
||||||
# 实例演示开关
|
# 文件上传
|
||||||
demoEnabled: true
|
profile: D:/profile/
|
||||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
|
||||||
profile: D:/ruoyi/uploadPath
|
|
||||||
# 获取ip地址开关
|
# 获取ip地址开关
|
||||||
addressEnabled: false
|
addressEnabled: true
|
||||||
|
|
||||||
# 开发环境配置
|
# 开发环境配置
|
||||||
server:
|
server:
|
||||||
# 服务器的HTTP端口,默认为80
|
# 服务端口
|
||||||
port: 80
|
port: 80
|
||||||
servlet:
|
servlet:
|
||||||
# 应用的访问路径
|
# 项目contextPath
|
||||||
context-path: /
|
context-path: /
|
||||||
tomcat:
|
tomcat:
|
||||||
# tomcat的URI编码
|
# tomcat的URI编码
|
||||||
uri-encoding: UTF-8
|
uri-encoding: UTF-8
|
||||||
# 连接数满后的排队数,默认为100
|
# tomcat最大线程数,默认为200
|
||||||
accept-count: 1000
|
max-threads: 800
|
||||||
threads:
|
# Tomcat启动初始化的线程数,默认值25
|
||||||
# tomcat最大线程数,默认为200
|
min-spare-threads: 30
|
||||||
max: 800
|
|
||||||
# Tomcat启动初始化的线程数,默认值10
|
|
||||||
min-spare: 100
|
|
||||||
|
|
||||||
# 日志配置
|
# 日志配置
|
||||||
logging:
|
logging:
|
||||||
level:
|
level:
|
||||||
com.ruoyi: debug
|
com.ruoyi: debug
|
||||||
org.springframework: warn
|
org.springframework: WARN
|
||||||
|
org.spring.springboot.dao: debug
|
||||||
|
|
||||||
# 用户配置
|
# 用户配置
|
||||||
user:
|
user:
|
||||||
|
|
@ -54,19 +50,17 @@ spring:
|
||||||
# 资源信息
|
# 资源信息
|
||||||
messages:
|
messages:
|
||||||
# 国际化资源文件路径
|
# 国际化资源文件路径
|
||||||
basename: static/i18n/messages
|
basename: i18n/messages
|
||||||
jackson:
|
jackson:
|
||||||
time-zone: GMT+8
|
time-zone: GMT+8
|
||||||
date-format: yyyy-MM-dd HH:mm:ss
|
date-format: yyyy-MM-dd HH:mm:ss
|
||||||
profiles:
|
profiles:
|
||||||
active: druid
|
active: druid
|
||||||
# 文件上传
|
# 文件上传
|
||||||
servlet:
|
servlet:
|
||||||
multipart:
|
multipart:
|
||||||
# 单个文件大小
|
max-file-size: 30MB
|
||||||
max-file-size: 10MB
|
max-request-size: 30MB
|
||||||
# 设置总上传的文件大小
|
|
||||||
max-request-size: 20MB
|
|
||||||
# 服务模块
|
# 服务模块
|
||||||
devtools:
|
devtools:
|
||||||
restart:
|
restart:
|
||||||
|
|
@ -75,18 +69,19 @@ spring:
|
||||||
|
|
||||||
# MyBatis
|
# MyBatis
|
||||||
mybatis:
|
mybatis:
|
||||||
# 搜索指定包别名
|
# 搜索指定包别名
|
||||||
typeAliasesPackage: com.ruoyi.**.domain
|
typeAliasesPackage: com.ruoyi
|
||||||
# 配置mapper的扫描,找到所有的mapper.xml映射文件
|
# 配置mapper的扫描,找到所有的mapper.xml映射文件
|
||||||
mapperLocations: classpath*:mapper/**/*Mapper.xml
|
mapperLocations: classpath*:mapper/**/*Mapper.xml
|
||||||
# 加载全局的配置文件
|
# 加载全局的配置文件
|
||||||
configLocation: classpath:mybatis/mybatis-config.xml
|
configLocation: classpath:mapper/mybatis-config.xml
|
||||||
|
|
||||||
# PageHelper分页插件
|
# PageHelper分页插件
|
||||||
pagehelper:
|
pagehelper:
|
||||||
helperDialect: mysql
|
helperDialect: mysql
|
||||||
|
reasonable: true
|
||||||
supportMethodsArguments: true
|
supportMethodsArguments: true
|
||||||
params: count=countSql
|
params: count=countSql
|
||||||
|
|
||||||
# Shiro
|
# Shiro
|
||||||
shiro:
|
shiro:
|
||||||
|
|
@ -99,44 +94,30 @@ shiro:
|
||||||
indexUrl: /index
|
indexUrl: /index
|
||||||
# 验证码开关
|
# 验证码开关
|
||||||
captchaEnabled: true
|
captchaEnabled: true
|
||||||
# 验证码类型 math 数字计算 char 字符验证
|
# 验证码类型 math 数组计算 char 字符
|
||||||
captchaType: math
|
captchaType: math
|
||||||
cookie:
|
cookie:
|
||||||
# 设置Cookie的域名 默认空,即当前访问的域名
|
# 设置Cookie的域名 默认空,即当前访问的域名
|
||||||
domain:
|
domain:
|
||||||
# 设置cookie的有效访问路径
|
# 设置cookie的有效访问路径
|
||||||
path: /
|
path: /
|
||||||
# 设置HttpOnly属性
|
# 设置HttpOnly属性
|
||||||
httpOnly: true
|
httpOnly: true
|
||||||
# 设置Cookie的过期时间,天为单位
|
# 设置Cookie的过期时间,天为单位
|
||||||
maxAge: 30
|
maxAge: 30
|
||||||
# 设置密钥,务必保持唯一性(生成方式,直接拷贝到main运行即可)Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) (默认启动生成随机秘钥,随机秘钥会导致之前客户端RememberMe Cookie无效,如设置固定秘钥RememberMe Cookie则有效)
|
|
||||||
cipherKey:
|
|
||||||
session:
|
session:
|
||||||
# Session超时时间,-1代表永不过期(默认30分钟)
|
# Session超时时间(默认30分钟)
|
||||||
expireTime: 30
|
expireTime: 30
|
||||||
# 同步session到数据库的周期(默认1分钟)
|
# 同步session到数据库的周期(默认1分钟)
|
||||||
dbSyncPeriod: 1
|
dbSyncPeriod: 1
|
||||||
# 相隔多久检查一次session的有效性,默认就是10分钟
|
# 相隔多久检查一次session的有效性,默认就是10分钟
|
||||||
validationInterval: 10
|
validationInterval: 10
|
||||||
# 同一个用户最大会话数,比如2的意思是同一个账号允许最多同时两个人登录(默认-1不限制)
|
|
||||||
maxSession: -1
|
|
||||||
# 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
|
|
||||||
kickoutAfter: false
|
|
||||||
rememberMe:
|
|
||||||
# 是否开启记住我
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# 防止XSS攻击
|
# 防止XSS攻击
|
||||||
xss:
|
xss:
|
||||||
# 过滤开关
|
# 过滤开关
|
||||||
enabled: true
|
enabled: true
|
||||||
# 排除链接(多个用逗号分隔)
|
# 排除链接(多个用逗号分隔)
|
||||||
excludes: /system/notice/*
|
excludes: /system/notice/*
|
||||||
# 匹配链接
|
# 匹配链接
|
||||||
urlPatterns: /system/*,/monitor/*,/tool/*
|
urlPatterns: /system/*,/monitor/*,/tool/*
|
||||||
|
|
||||||
# Swagger配置
|
|
||||||
swagger:
|
|
||||||
# 是否开启swagger
|
|
||||||
enabled: true
|
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,7 @@
|
||||||
|
|
||||||
<!-- 磁盘缓存位置 -->
|
<!-- 磁盘缓存位置 -->
|
||||||
<diskStore path="java.io.tmpdir"/>
|
<diskStore path="java.io.tmpdir"/>
|
||||||
|
|
||||||
<!-- maxEntriesLocalHeap:堆内存中最大缓存对象数,0没有限制 -->
|
|
||||||
<!-- maxElementsInMemory: 在内存中缓存的element的最大数目。-->
|
|
||||||
<!-- eternal:elements是否永久有效,如果为true,timeouts将被忽略,element将永不过期 -->
|
|
||||||
<!-- timeToIdleSeconds:失效前的空闲秒数,当eternal为false时,这个属性才有效,0为不限制 -->
|
|
||||||
<!-- timeToLiveSeconds:失效前的存活秒数,创建时间到失效时间的间隔为存活时间,当eternal为false时,这个属性才有效,0为不限制 -->
|
|
||||||
<!-- overflowToDisk: 如果内存中数据超过内存限制,是否要缓存到磁盘上 -->
|
|
||||||
<!-- statistics:是否收集统计信息。如果需要监控缓存使用情况,应该打开这个选项。默认为关闭(统计会影响性能)。设置statistics="true"开启统计 -->
|
|
||||||
|
|
||||||
<!-- 默认缓存 -->
|
<!-- 默认缓存 -->
|
||||||
<defaultCache
|
<defaultCache
|
||||||
maxEntriesLocalHeap="1000"
|
maxEntriesLocalHeap="1000"
|
||||||
|
|
@ -28,64 +20,8 @@
|
||||||
timeToIdleSeconds="600"
|
timeToIdleSeconds="600"
|
||||||
timeToLiveSeconds="0"
|
timeToLiveSeconds="0"
|
||||||
overflowToDisk="false"
|
overflowToDisk="false"
|
||||||
statistics="false">
|
statistics="true">
|
||||||
</cache>
|
</cache>
|
||||||
|
|
||||||
<!-- 系统活跃用户缓存 -->
|
|
||||||
<cache name="sys-userCache"
|
|
||||||
maxEntriesLocalHeap="10000"
|
|
||||||
overflowToDisk="false"
|
|
||||||
eternal="false"
|
|
||||||
diskPersistent="false"
|
|
||||||
timeToLiveSeconds="0"
|
|
||||||
timeToIdleSeconds="0"
|
|
||||||
statistics="false">
|
|
||||||
</cache>
|
|
||||||
|
|
||||||
<!-- 系统用户授权缓存 没必要过期 -->
|
|
||||||
<cache name="sys-authCache"
|
|
||||||
maxEntriesLocalHeap="10000"
|
|
||||||
overflowToDisk="false"
|
|
||||||
eternal="false"
|
|
||||||
diskPersistent="false"
|
|
||||||
timeToLiveSeconds="0"
|
|
||||||
timeToIdleSeconds="0"
|
|
||||||
memoryStoreEvictionPolicy="LRU"
|
|
||||||
statistics="false"/>
|
|
||||||
|
|
||||||
<!-- 系统缓存 -->
|
|
||||||
<cache name="sys-cache"
|
|
||||||
maxEntriesLocalHeap="1000"
|
|
||||||
eternal="true"
|
|
||||||
overflowToDisk="true"
|
|
||||||
statistics="false">
|
|
||||||
</cache>
|
|
||||||
|
|
||||||
<!-- 系统参数缓存 -->
|
|
||||||
<cache name="sys-config"
|
|
||||||
maxEntriesLocalHeap="1000"
|
|
||||||
eternal="true"
|
|
||||||
overflowToDisk="true"
|
|
||||||
statistics="false">
|
|
||||||
</cache>
|
|
||||||
|
|
||||||
<!-- 系统字典缓存 -->
|
|
||||||
<cache name="sys-dict"
|
|
||||||
maxEntriesLocalHeap="1000"
|
|
||||||
eternal="true"
|
|
||||||
overflowToDisk="true"
|
|
||||||
statistics="false">
|
|
||||||
</cache>
|
|
||||||
|
|
||||||
<!-- 系统会话缓存 -->
|
|
||||||
<cache name="shiro-activeSessionCache"
|
|
||||||
maxEntriesLocalHeap="10000"
|
|
||||||
overflowToDisk="false"
|
|
||||||
eternal="false"
|
|
||||||
diskPersistent="false"
|
|
||||||
timeToLiveSeconds="0"
|
|
||||||
timeToIdleSeconds="0"
|
|
||||||
statistics="false"/>
|
|
||||||
|
|
||||||
</ehcache>
|
</ehcache>
|
||||||
|
|
||||||
|
|
@ -8,7 +8,6 @@ user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定10分钟
|
||||||
user.password.delete=对不起,您的账号已被删除
|
user.password.delete=对不起,您的账号已被删除
|
||||||
user.blocked=用户已封禁,请联系管理员
|
user.blocked=用户已封禁,请联系管理员
|
||||||
role.blocked=角色已封禁,请联系管理员
|
role.blocked=角色已封禁,请联系管理员
|
||||||
login.blocked=很遗憾,访问IP已被列入系统黑名单
|
|
||||||
user.logout.success=退出成功
|
user.logout.success=退出成功
|
||||||
|
|
||||||
length.not.valid=长度必须在{min}到{max}个字符之间
|
length.not.valid=长度必须在{min}到{max}个字符之间
|
||||||
|
|
@ -19,7 +18,6 @@ user.password.not.valid=* 5-50个字符
|
||||||
user.email.not.valid=邮箱格式错误
|
user.email.not.valid=邮箱格式错误
|
||||||
user.mobile.phone.number.not.valid=手机号格式错误
|
user.mobile.phone.number.not.valid=手机号格式错误
|
||||||
user.login.success=登录成功
|
user.login.success=登录成功
|
||||||
user.register.success=注册成功
|
|
||||||
user.notfound=请重新登录
|
user.notfound=请重新登录
|
||||||
user.forcelogout=管理员强制退出,请重新登录
|
user.forcelogout=管理员强制退出,请重新登录
|
||||||
user.unknown.error=未知错误,请重新登录
|
user.unknown.error=未知错误,请重新登录
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<!-- 日志存放路径 -->
|
|
||||||
<property name="log.path" value="/home/ruoyi/logs" />
|
<property name="log.path" value="/home/ruoyi/logs" />
|
||||||
<!-- 日志输出格式 -->
|
|
||||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||||
|
|
||||||
<!-- 控制台输出 -->
|
<!-- 控制台输出 -->
|
||||||
|
|
@ -15,9 +14,8 @@
|
||||||
<!-- 系统日志输出 -->
|
<!-- 系统日志输出 -->
|
||||||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<file>${log.path}/sys-info.log</file>
|
<file>${log.path}/sys-info.log</file>
|
||||||
<!-- 循环政策:基于时间创建日志文件 -->
|
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
<!-- 日志文件名格式 -->
|
<!-- 按天回滚 daily -->
|
||||||
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
<!-- 日志最大的历史 60天 -->
|
<!-- 日志最大的历史 60天 -->
|
||||||
<maxHistory>60</maxHistory>
|
<maxHistory>60</maxHistory>
|
||||||
|
|
@ -26,20 +24,15 @@
|
||||||
<pattern>${log.pattern}</pattern>
|
<pattern>${log.pattern}</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
<!-- 过滤的级别 -->
|
|
||||||
<level>INFO</level>
|
<level>INFO</level>
|
||||||
<!-- 匹配时的操作:接收(记录) -->
|
|
||||||
<onMatch>ACCEPT</onMatch>
|
<onMatch>ACCEPT</onMatch>
|
||||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
|
||||||
<onMismatch>DENY</onMismatch>
|
<onMismatch>DENY</onMismatch>
|
||||||
</filter>
|
</filter>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<file>${log.path}/sys-error.log</file>
|
<file>${log.path}/sys-error.log</file>
|
||||||
<!-- 循环政策:基于时间创建日志文件 -->
|
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
<!-- 日志文件名格式 -->
|
|
||||||
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
<!-- 日志最大的历史 60天 -->
|
<!-- 日志最大的历史 60天 -->
|
||||||
<maxHistory>60</maxHistory>
|
<maxHistory>60</maxHistory>
|
||||||
|
|
@ -48,11 +41,8 @@
|
||||||
<pattern>${log.pattern}</pattern>
|
<pattern>${log.pattern}</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
<!-- 过滤的级别 -->
|
|
||||||
<level>ERROR</level>
|
<level>ERROR</level>
|
||||||
<!-- 匹配时的操作:接收(记录) -->
|
|
||||||
<onMatch>ACCEPT</onMatch>
|
<onMatch>ACCEPT</onMatch>
|
||||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
|
||||||
<onMismatch>DENY</onMismatch>
|
<onMismatch>DENY</onMismatch>
|
||||||
</filter>
|
</filter>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
@ -71,10 +61,13 @@
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- 系统模块日志级别控制 -->
|
<!-- 显示形成的sql、使用的参数、结果集 -->
|
||||||
|
<!--
|
||||||
|
<logger name="java.sql" level="debug" />
|
||||||
|
<logger name="org.springframework.jdbc" level="debug" />
|
||||||
|
-->
|
||||||
|
|
||||||
<logger name="com.ruoyi" level="info" />
|
<logger name="com.ruoyi" level="info" />
|
||||||
<!-- Spring日志级别控制 -->
|
|
||||||
<logger name="org.springframework" level="warn" />
|
|
||||||
|
|
||||||
<root level="info">
|
<root level="info">
|
||||||
<appender-ref ref="console" />
|
<appender-ref ref="console" />
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!DOCTYPE configuration
|
|
||||||
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
|
|
||||||
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
|
||||||
<configuration>
|
|
||||||
<!-- 全局参数 -->
|
|
||||||
<settings>
|
|
||||||
<!-- 使全局的映射器启用或禁用缓存 -->
|
|
||||||
<setting name="cacheEnabled" value="true" />
|
|
||||||
<!-- 允许JDBC 支持自动生成主键 -->
|
|
||||||
<setting name="useGeneratedKeys" value="true" />
|
|
||||||
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
|
|
||||||
<setting name="defaultExecutorType" value="SIMPLE" />
|
|
||||||
<!-- 指定 MyBatis 所用日志的具体实现 -->
|
|
||||||
<setting name="logImpl" value="SLF4J" />
|
|
||||||
<!-- 使用驼峰命名法转换字段 -->
|
|
||||||
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
|
|
||||||
</settings>
|
|
||||||
|
|
||||||
</configuration>
|
|
||||||
|
|
@ -1,688 +0,0 @@
|
||||||
/*!
|
|
||||||
* bootstrap-fileinput v5.5.2
|
|
||||||
* http://plugins.krajee.com/file-input
|
|
||||||
*
|
|
||||||
* Krajee default styling for bootstrap-fileinput.
|
|
||||||
*
|
|
||||||
* Author: Kartik Visweswaran
|
|
||||||
* Copyright: 2014 - 2022, Kartik Visweswaran, Krajee.com
|
|
||||||
*
|
|
||||||
* Licensed under the BSD-3-Clause
|
|
||||||
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
|
|
||||||
*/
|
|
||||||
|
|
||||||
.file-loading input[type=file],
|
|
||||||
input[type=file].file-loading {
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-no-browse {
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
bottom: 20%;
|
|
||||||
width: 1px;
|
|
||||||
height: 1px;
|
|
||||||
font-size: 0;
|
|
||||||
opacity: 0;
|
|
||||||
border: none;
|
|
||||||
background: none;
|
|
||||||
outline: none;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kv-hidden,
|
|
||||||
.file-caption-icon,
|
|
||||||
.file-zoom-dialog .modal-header:before,
|
|
||||||
.file-zoom-dialog .modal-header:after,
|
|
||||||
.file-input-new .file-preview,
|
|
||||||
.file-input-new .close,
|
|
||||||
.file-input-new .glyphicon-file,
|
|
||||||
.file-input-new .fileinput-remove-button,
|
|
||||||
.file-input-new .fileinput-upload-button,
|
|
||||||
.file-input-new .no-browse .input-group-btn,
|
|
||||||
.file-input-ajax-new .fileinput-remove-button,
|
|
||||||
.file-input-ajax-new .fileinput-upload-button,
|
|
||||||
.file-input-ajax-new .no-browse .input-group-btn,
|
|
||||||
.hide-content .kv-file-content,
|
|
||||||
.is-locked .fileinput-upload-button,
|
|
||||||
.is-locked .fileinput-remove-button {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-caption .input-group {
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-file input[type=file],
|
|
||||||
.file-caption-icon,
|
|
||||||
.file-preview .fileinput-remove,
|
|
||||||
.krajee-default .file-thumb-progress,
|
|
||||||
.file-zoom-dialog .btn-navigate,
|
|
||||||
.file-zoom-dialog .floating-buttons {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-caption-icon .kv-caption-icon {
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-input,
|
|
||||||
.file-loading:before,
|
|
||||||
.btn-file,
|
|
||||||
.file-caption,
|
|
||||||
.file-preview,
|
|
||||||
.krajee-default.file-preview-frame,
|
|
||||||
.krajee-default .file-thumbnail-footer,
|
|
||||||
.file-zoom-dialog .modal-dialog {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-error-message pre,
|
|
||||||
.file-error-message ul,
|
|
||||||
.krajee-default .file-actions,
|
|
||||||
.krajee-default .file-other-error {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-error-message pre,
|
|
||||||
.file-error-message ul {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default .file-drag-handle,
|
|
||||||
.krajee-default .file-upload-indicator {
|
|
||||||
float: left;
|
|
||||||
margin-top: 10px;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-thumb-progress .progress,
|
|
||||||
.file-thumb-progress .progress-bar {
|
|
||||||
font-family: Verdana, Helvetica, sans-serif;
|
|
||||||
font-size: 0.7rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default .file-thumb-progress .progress,
|
|
||||||
.kv-upload-progress .progress {
|
|
||||||
background-color: #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default .file-caption-info,
|
|
||||||
.krajee-default .file-size-info {
|
|
||||||
display: block;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
width: 160px;
|
|
||||||
height: 15px;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-content > .file-object.type-video,
|
|
||||||
.file-zoom-content > .file-object.type-flash,
|
|
||||||
.file-zoom-content > .file-object.type-image {
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-content > .file-object.type-video,
|
|
||||||
.file-zoom-content > .file-object.type-flash {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-content > .file-object.type-pdf,
|
|
||||||
.file-zoom-content > .file-object.type-html,
|
|
||||||
.file-zoom-content > .file-object.type-text,
|
|
||||||
.file-zoom-content > .file-object.type-default {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-loading:before {
|
|
||||||
content: " Loading...";
|
|
||||||
display: inline-block;
|
|
||||||
padding-left: 20px;
|
|
||||||
line-height: 16px;
|
|
||||||
font-size: 13px;
|
|
||||||
font-variant: small-caps;
|
|
||||||
color: #999;
|
|
||||||
background: transparent url(loading.gif) top left no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-object {
|
|
||||||
margin: 0 0 -5px 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-file {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-file input[type=file] {
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
min-width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
text-align: right;
|
|
||||||
opacity: 0;
|
|
||||||
background: none repeat scroll 0 0 transparent;
|
|
||||||
cursor: inherit;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-file ::-ms-browse {
|
|
||||||
font-size: 10000px;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-caption.icon-visible .file-caption-icon {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-caption.icon-visible .file-caption-name {
|
|
||||||
padding-left: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-caption.icon-visible > .input-group-lg .file-caption-name {
|
|
||||||
padding-left: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-caption.icon-visible > .input-group-sm .file-caption-name {
|
|
||||||
padding-left: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-caption-name:not(.file-caption-disabled) {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-caption-name.file-processing {
|
|
||||||
font-style: italic;
|
|
||||||
border-color: #bbb;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-caption-icon {
|
|
||||||
padding: 7px 5px;
|
|
||||||
left: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group-lg .file-caption-icon {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group-sm .file-caption-icon {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
padding: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-error-message {
|
|
||||||
color: #a94442;
|
|
||||||
background-color: #f2dede;
|
|
||||||
margin: 5px;
|
|
||||||
border: 1px solid #ebccd1;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-error-message pre {
|
|
||||||
margin: 5px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-caption-disabled {
|
|
||||||
background-color: #eee;
|
|
||||||
cursor: not-allowed;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-preview {
|
|
||||||
border-radius: 5px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
padding: 8px;
|
|
||||||
width: 100%;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-preview .btn-xs {
|
|
||||||
padding: 1px 5px;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.5;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-preview .fileinput-remove {
|
|
||||||
top: 1px;
|
|
||||||
right: 1px;
|
|
||||||
line-height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-preview .clickable {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-preview-image {
|
|
||||||
font: 40px Impact, Charcoal, sans-serif;
|
|
||||||
color: #008000;
|
|
||||||
width: auto;
|
|
||||||
height: auto;
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default.file-preview-frame {
|
|
||||||
margin: 8px;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
||||||
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
|
|
||||||
padding: 6px;
|
|
||||||
float: left;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default.file-preview-frame .kv-file-content {
|
|
||||||
width: 213px;
|
|
||||||
height: 160px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered {
|
|
||||||
width: 400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default.file-preview-frame[data-template="audio"] .kv-file-content {
|
|
||||||
width: 240px;
|
|
||||||
height: 55px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default.file-preview-frame .file-thumbnail-footer {
|
|
||||||
height: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default.file-preview-frame:not(.file-preview-error):hover {
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.3);
|
|
||||||
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default .file-preview-text {
|
|
||||||
color: #428bca;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
outline: none;
|
|
||||||
resize: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default .file-preview-html {
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default .file-other-icon {
|
|
||||||
font-size: 6em;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default .file-footer-buttons {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default .file-footer-caption {
|
|
||||||
display: block;
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 4px;
|
|
||||||
font-size: 11px;
|
|
||||||
color: #999;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-upload-stats {
|
|
||||||
font-size: 10px;
|
|
||||||
text-align: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kv-upload-progress .file-upload-stats {
|
|
||||||
font-size: 12px;
|
|
||||||
margin: -10px 0 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default .file-preview-error {
|
|
||||||
opacity: 0.65;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default .file-thumb-progress {
|
|
||||||
top: 37px;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default.kvsortable-ghost {
|
|
||||||
background: #e1edf7;
|
|
||||||
border: 2px solid #a1abff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default .file-preview-other:hover {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.krajee-default .file-preview-frame:not(.file-preview-error) .file-footer-caption:hover {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kv-upload-progress .progress {
|
|
||||||
height: 20px;
|
|
||||||
margin: 10px 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kv-upload-progress .progress-bar {
|
|
||||||
height: 20px;
|
|
||||||
font-family: Verdana, Helvetica, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*noinspection CssOverwrittenProperties*/
|
|
||||||
|
|
||||||
.file-zoom-dialog .file-other-icon {
|
|
||||||
font-size: 22em;
|
|
||||||
font-size: 50vmin;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .modal-dialog {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .modal-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .btn-navigate {
|
|
||||||
margin: 0 0.1rem;
|
|
||||||
padding: 0;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
width: 2.4rem;
|
|
||||||
height: 2.4rem;
|
|
||||||
top: 50%;
|
|
||||||
border-radius: 50%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-navigate * {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .floating-buttons {
|
|
||||||
top: 5px;
|
|
||||||
right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .btn-kv-prev {
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .btn-kv-next {
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .kv-zoom-header {
|
|
||||||
padding: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .kv-zoom-body {
|
|
||||||
padding: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .kv-zoom-description {
|
|
||||||
position: absolute;
|
|
||||||
opacity: 0.8;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
background-color: #1a1a1a;
|
|
||||||
padding: 1rem;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
color: #fff;
|
|
||||||
left: 15%;
|
|
||||||
right: 15%;
|
|
||||||
bottom: 15%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .kv-desc-hide {
|
|
||||||
float: right;
|
|
||||||
color: #fff;
|
|
||||||
padding: 0 0.1rem;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .kv-desc-hide:hover {
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .kv-desc-hide:focus {
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-input-new .no-browse .form-control {
|
|
||||||
border-top-right-radius: 4px;
|
|
||||||
border-bottom-right-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-input-ajax-new .no-browse .form-control {
|
|
||||||
border-top-right-radius: 4px;
|
|
||||||
border-bottom-right-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-caption {
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-thumb-loading {
|
|
||||||
background: transparent url(loading.gif) no-repeat scroll center center content-box !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-drop-zone {
|
|
||||||
border: 1px dashed #aaa;
|
|
||||||
min-height: 260px;
|
|
||||||
border-radius: 4px;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: 12px 15px 12px 12px;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-drop-zone.clickable:hover {
|
|
||||||
border: 2px dashed #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-drop-zone.clickable:focus {
|
|
||||||
border: 2px solid #5acde2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-drop-zone .file-preview-thumbnails {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-drop-zone-title {
|
|
||||||
color: #aaa;
|
|
||||||
font-size: 1.6em;
|
|
||||||
text-align: center;
|
|
||||||
padding: 85px 10px;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-highlighted {
|
|
||||||
border: 2px dashed #999 !important;
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-uploading {
|
|
||||||
background: url(loading-sm.gif) no-repeat center bottom 10px;
|
|
||||||
opacity: 0.65;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-fullscreen .modal-dialog {
|
|
||||||
min-width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-fullscreen .modal-content {
|
|
||||||
border-radius: 0;
|
|
||||||
box-shadow: none;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-fullscreen .kv-zoom-body {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.floating-buttons {
|
|
||||||
z-index: 3000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.floating-buttons .btn-kv {
|
|
||||||
margin-left: 3px;
|
|
||||||
z-index: 3000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kv-zoom-actions {
|
|
||||||
min-width: 140px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kv-zoom-actions .btn-kv {
|
|
||||||
margin-left: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-content {
|
|
||||||
text-align: center;
|
|
||||||
white-space: nowrap;
|
|
||||||
min-height: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-content:hover {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-content .file-preview-image {
|
|
||||||
max-height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-content .file-preview-video {
|
|
||||||
max-height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-content > .file-object.type-image {
|
|
||||||
height: auto;
|
|
||||||
min-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-content > .file-object.type-audio {
|
|
||||||
width: auto;
|
|
||||||
height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 576px) {
|
|
||||||
.file-zoom-dialog .modal-dialog {
|
|
||||||
max-width: 500px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 992px) {
|
|
||||||
.file-zoom-dialog .modal-lg {
|
|
||||||
max-width: 800px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
|
||||||
.file-preview-thumbnails {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-zoom-dialog .modal-header {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 350px) {
|
|
||||||
.krajee-default.file-preview-frame:not([data-template="audio"]) .kv-file-content {
|
|
||||||
width: 160px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 420px) {
|
|
||||||
.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-loading[dir=rtl]:before {
|
|
||||||
background: transparent url(loading.gif) top right no-repeat;
|
|
||||||
padding-left: 0;
|
|
||||||
padding-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clickable .file-drop-zone-title {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-sortable .file-drag-handle:hover {
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-sortable .file-drag-handle {
|
|
||||||
cursor: grab;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-grabbing,
|
|
||||||
.file-grabbing * {
|
|
||||||
cursor: not-allowed !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-grabbing .file-preview-thumbnails * {
|
|
||||||
cursor: grabbing !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-preview-frame.sortable-chosen {
|
|
||||||
background-color: #d9edf7;
|
|
||||||
border-color: #17a2b8;
|
|
||||||
box-shadow: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-preview .kv-zoom-cache {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-preview-other-frame, .file-preview-object, .kv-file-content, .kv-zoom-body {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-kv-rotate,
|
|
||||||
.kv-file-rotate {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rotatable:not(.hide-rotate) .btn-kv-rotate,
|
|
||||||
.rotatable:not(.hide-rotate) .kv-file-rotate {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rotatable .file-zoom-detail,
|
|
||||||
.rotatable .kv-file-content,
|
|
||||||
.rotatable .kv-file-content > :first-child {
|
|
||||||
transform-origin: center center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rotate-animate {
|
|
||||||
transition: transform 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kv-overflow-hidden {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 847 B |
|
|
@ -1,459 +0,0 @@
|
||||||
/*!
|
|
||||||
* Bootstrap-select v1.13.18 (https://developer.snapappointments.com/bootstrap-select)
|
|
||||||
*
|
|
||||||
* Copyright 2012-2020 SnapAppointments, LLC
|
|
||||||
* Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE)
|
|
||||||
*/
|
|
||||||
|
|
||||||
@-webkit-keyframes bs-notify-fadeOut {
|
|
||||||
0% {
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@-o-keyframes bs-notify-fadeOut {
|
|
||||||
0% {
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes bs-notify-fadeOut {
|
|
||||||
0% {
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
select.bs-select-hidden,
|
|
||||||
.bootstrap-select > select.bs-select-hidden,
|
|
||||||
select.selectpicker {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
.bootstrap-select {
|
|
||||||
width: 220px \0;
|
|
||||||
/*IE9 and below*/
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.bootstrap-select > .dropdown-toggle {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
text-align: right;
|
|
||||||
white-space: nowrap;
|
|
||||||
display: -webkit-inline-box;
|
|
||||||
display: -webkit-inline-flex;
|
|
||||||
display: -ms-inline-flexbox;
|
|
||||||
display: inline-flex;
|
|
||||||
-webkit-box-align: center;
|
|
||||||
-webkit-align-items: center;
|
|
||||||
-ms-flex-align: center;
|
|
||||||
align-items: center;
|
|
||||||
-webkit-box-pack: justify;
|
|
||||||
-webkit-justify-content: space-between;
|
|
||||||
-ms-flex-pack: justify;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
.bootstrap-select > .dropdown-toggle:after {
|
|
||||||
margin-top: -1px;
|
|
||||||
}
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder:hover,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder:focus,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder:active {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:hover,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:hover,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:hover,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:hover,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:hover,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:hover,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:focus,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:focus,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:focus,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:focus,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:focus,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:focus,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:active,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:active,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:active,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:active,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:active,
|
|
||||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:active {
|
|
||||||
color: rgba(255, 255, 255, 0.5);
|
|
||||||
}
|
|
||||||
.bootstrap-select > select {
|
|
||||||
position: absolute !important;
|
|
||||||
bottom: 0;
|
|
||||||
left: 50%;
|
|
||||||
display: block !important;
|
|
||||||
width: 0.5px !important;
|
|
||||||
height: 100% !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
opacity: 0 !important;
|
|
||||||
border: none;
|
|
||||||
z-index: 0 !important;
|
|
||||||
}
|
|
||||||
.bootstrap-select > select.mobile-device {
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: block !important;
|
|
||||||
width: 100% !important;
|
|
||||||
z-index: 2 !important;
|
|
||||||
}
|
|
||||||
.has-error .bootstrap-select .dropdown-toggle,
|
|
||||||
.error .bootstrap-select .dropdown-toggle,
|
|
||||||
.bootstrap-select.is-invalid .dropdown-toggle,
|
|
||||||
.was-validated .bootstrap-select select:invalid + .dropdown-toggle {
|
|
||||||
border-color: #b94a48;
|
|
||||||
}
|
|
||||||
.bootstrap-select.is-valid .dropdown-toggle,
|
|
||||||
.was-validated .bootstrap-select select:valid + .dropdown-toggle {
|
|
||||||
border-color: #28a745;
|
|
||||||
}
|
|
||||||
.bootstrap-select.fit-width {
|
|
||||||
width: auto !important;
|
|
||||||
}
|
|
||||||
.bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) {
|
|
||||||
width: 220px;
|
|
||||||
}
|
|
||||||
.bootstrap-select > select.mobile-device:focus + .dropdown-toggle,
|
|
||||||
.bootstrap-select .dropdown-toggle:focus {
|
|
||||||
outline: thin dotted #333333 !important;
|
|
||||||
outline: 5px auto -webkit-focus-ring-color !important;
|
|
||||||
outline-offset: -2px;
|
|
||||||
}
|
|
||||||
.bootstrap-select.form-control {
|
|
||||||
margin-bottom: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: none;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
:not(.input-group) > .bootstrap-select.form-control:not([class*="col-"]) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.bootstrap-select.form-control.input-group-btn {
|
|
||||||
float: none;
|
|
||||||
z-index: auto;
|
|
||||||
}
|
|
||||||
.form-inline .bootstrap-select,
|
|
||||||
.form-inline .bootstrap-select.form-control:not([class*="col-"]) {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
.bootstrap-select:not(.input-group-btn),
|
|
||||||
.bootstrap-select[class*="col-"] {
|
|
||||||
float: none;
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
.bootstrap-select.dropdown-menu-right,
|
|
||||||
.bootstrap-select[class*="col-"].dropdown-menu-right,
|
|
||||||
.row .bootstrap-select[class*="col-"].dropdown-menu-right {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
.form-inline .bootstrap-select,
|
|
||||||
.form-horizontal .bootstrap-select,
|
|
||||||
.form-group .bootstrap-select {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
.form-group-lg .bootstrap-select.form-control,
|
|
||||||
.form-group-sm .bootstrap-select.form-control {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.form-group-lg .bootstrap-select.form-control .dropdown-toggle,
|
|
||||||
.form-group-sm .bootstrap-select.form-control .dropdown-toggle {
|
|
||||||
height: 100%;
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
border-radius: inherit;
|
|
||||||
}
|
|
||||||
.bootstrap-select.form-control-sm .dropdown-toggle,
|
|
||||||
.bootstrap-select.form-control-lg .dropdown-toggle {
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
border-radius: inherit;
|
|
||||||
}
|
|
||||||
.bootstrap-select.form-control-sm .dropdown-toggle {
|
|
||||||
padding: 0.25rem 0.5rem;
|
|
||||||
}
|
|
||||||
.bootstrap-select.form-control-lg .dropdown-toggle {
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
}
|
|
||||||
.form-inline .bootstrap-select .form-control {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.bootstrap-select.disabled,
|
|
||||||
.bootstrap-select > .disabled {
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
.bootstrap-select.disabled:focus,
|
|
||||||
.bootstrap-select > .disabled:focus {
|
|
||||||
outline: none !important;
|
|
||||||
}
|
|
||||||
.bootstrap-select.bs-container {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 0 !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
.bootstrap-select.bs-container .dropdown-menu {
|
|
||||||
z-index: 1060;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-toggle .filter-option {
|
|
||||||
position: static;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
float: left;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
text-align: left;
|
|
||||||
overflow: hidden;
|
|
||||||
-webkit-box-flex: 0;
|
|
||||||
-webkit-flex: 0 1 auto;
|
|
||||||
-ms-flex: 0 1 auto;
|
|
||||||
flex: 0 1 auto;
|
|
||||||
}
|
|
||||||
.bs3.bootstrap-select .dropdown-toggle .filter-option {
|
|
||||||
padding-right: inherit;
|
|
||||||
}
|
|
||||||
.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option {
|
|
||||||
position: absolute;
|
|
||||||
padding-top: inherit;
|
|
||||||
padding-bottom: inherit;
|
|
||||||
padding-left: inherit;
|
|
||||||
float: none;
|
|
||||||
}
|
|
||||||
.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option .filter-option-inner {
|
|
||||||
padding-right: inherit;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-toggle .filter-option-inner-inner {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-toggle .filter-expand {
|
|
||||||
width: 0 !important;
|
|
||||||
float: left;
|
|
||||||
opacity: 0 !important;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-toggle .caret {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
right: 12px;
|
|
||||||
margin-top: -2px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.input-group .bootstrap-select.form-control .dropdown-toggle {
|
|
||||||
border-radius: inherit;
|
|
||||||
}
|
|
||||||
.bootstrap-select[class*="col-"] .dropdown-toggle {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu {
|
|
||||||
min-width: 100%;
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu > .inner:focus {
|
|
||||||
outline: none !important;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu.inner {
|
|
||||||
position: static;
|
|
||||||
float: none;
|
|
||||||
border: 0;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
-webkit-box-shadow: none;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu li {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu li.active small {
|
|
||||||
color: rgba(255, 255, 255, 0.5) !important;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu li.disabled a {
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu li a {
|
|
||||||
cursor: pointer;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu li a.opt {
|
|
||||||
position: relative;
|
|
||||||
padding-left: 2.25em;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu li a span.check-mark {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu li a span.text {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu li small {
|
|
||||||
padding-left: 0.5em;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu .notify {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 5px;
|
|
||||||
width: 96%;
|
|
||||||
margin: 0 2%;
|
|
||||||
min-height: 26px;
|
|
||||||
padding: 3px 5px;
|
|
||||||
background: #f5f5f5;
|
|
||||||
border: 1px solid #e3e3e3;
|
|
||||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
|
|
||||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
|
|
||||||
pointer-events: none;
|
|
||||||
opacity: 0.9;
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.bootstrap-select .dropdown-menu .notify.fadeOut {
|
|
||||||
-webkit-animation: 300ms linear 750ms forwards bs-notify-fadeOut;
|
|
||||||
-o-animation: 300ms linear 750ms forwards bs-notify-fadeOut;
|
|
||||||
animation: 300ms linear 750ms forwards bs-notify-fadeOut;
|
|
||||||
}
|
|
||||||
.bootstrap-select .no-results {
|
|
||||||
padding: 3px;
|
|
||||||
background: #f5f5f5;
|
|
||||||
margin: 0 5px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.bootstrap-select.fit-width .dropdown-toggle .filter-option {
|
|
||||||
position: static;
|
|
||||||
display: inline;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner,
|
|
||||||
.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner-inner {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
.bootstrap-select.fit-width .dropdown-toggle .bs-caret:before {
|
|
||||||
content: '\00a0';
|
|
||||||
}
|
|
||||||
.bootstrap-select.fit-width .dropdown-toggle .caret {
|
|
||||||
position: static;
|
|
||||||
top: auto;
|
|
||||||
margin-top: -1px;
|
|
||||||
}
|
|
||||||
.bootstrap-select.show-tick .dropdown-menu .selected span.check-mark {
|
|
||||||
position: absolute;
|
|
||||||
display: inline-block;
|
|
||||||
right: 15px;
|
|
||||||
top: 5px;
|
|
||||||
}
|
|
||||||
.bootstrap-select.show-tick .dropdown-menu li a span.text {
|
|
||||||
margin-right: 34px;
|
|
||||||
}
|
|
||||||
.bootstrap-select .bs-ok-default:after {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
width: 0.5em;
|
|
||||||
height: 1em;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 0 0.26em 0.26em 0;
|
|
||||||
-webkit-transform-style: preserve-3d;
|
|
||||||
transform-style: preserve-3d;
|
|
||||||
-webkit-transform: rotate(45deg);
|
|
||||||
-ms-transform: rotate(45deg);
|
|
||||||
-o-transform: rotate(45deg);
|
|
||||||
transform: rotate(45deg);
|
|
||||||
}
|
|
||||||
.bootstrap-select.show-menu-arrow.open > .dropdown-toggle,
|
|
||||||
.bootstrap-select.show-menu-arrow.show > .dropdown-toggle {
|
|
||||||
z-index: 1061;
|
|
||||||
}
|
|
||||||
.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:before {
|
|
||||||
content: '';
|
|
||||||
border-left: 7px solid transparent;
|
|
||||||
border-right: 7px solid transparent;
|
|
||||||
border-bottom: 7px solid rgba(204, 204, 204, 0.2);
|
|
||||||
position: absolute;
|
|
||||||
bottom: -4px;
|
|
||||||
left: 9px;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:after {
|
|
||||||
content: '';
|
|
||||||
border-left: 6px solid transparent;
|
|
||||||
border-right: 6px solid transparent;
|
|
||||||
border-bottom: 6px solid white;
|
|
||||||
position: absolute;
|
|
||||||
bottom: -4px;
|
|
||||||
left: 10px;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:before {
|
|
||||||
bottom: auto;
|
|
||||||
top: -4px;
|
|
||||||
border-top: 7px solid rgba(204, 204, 204, 0.2);
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:after {
|
|
||||||
bottom: auto;
|
|
||||||
top: -4px;
|
|
||||||
border-top: 6px solid white;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:before {
|
|
||||||
right: 12px;
|
|
||||||
left: auto;
|
|
||||||
}
|
|
||||||
.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:after {
|
|
||||||
right: 13px;
|
|
||||||
left: auto;
|
|
||||||
}
|
|
||||||
.bootstrap-select.show-menu-arrow.open > .dropdown-toggle .filter-option:before,
|
|
||||||
.bootstrap-select.show-menu-arrow.show > .dropdown-toggle .filter-option:before,
|
|
||||||
.bootstrap-select.show-menu-arrow.open > .dropdown-toggle .filter-option:after,
|
|
||||||
.bootstrap-select.show-menu-arrow.show > .dropdown-toggle .filter-option:after {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.bs-searchbox,
|
|
||||||
.bs-actionsbox,
|
|
||||||
.bs-donebutton {
|
|
||||||
padding: 4px 8px;
|
|
||||||
}
|
|
||||||
.bs-actionsbox {
|
|
||||||
width: 100%;
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.bs-actionsbox .btn-group button {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
.bs-donebutton {
|
|
||||||
float: left;
|
|
||||||
width: 100%;
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.bs-donebutton .btn-group button {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.bs-searchbox + .bs-actionsbox {
|
|
||||||
padding: 0 8px 4px;
|
|
||||||
}
|
|
||||||
.bs-searchbox .form-control {
|
|
||||||
margin-bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
float: none;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,95 +0,0 @@
|
||||||
/**
|
|
||||||
* @author: Alec Fenichel
|
|
||||||
* @webSite: https://fenichelar.com
|
|
||||||
* @update: zhixin wen <wenzhixin2010@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
var Utils = $.fn.bootstrapTable.utils
|
|
||||||
|
|
||||||
$.extend($.fn.bootstrapTable.defaults, {
|
|
||||||
autoRefresh: false,
|
|
||||||
showAutoRefresh: true,
|
|
||||||
autoRefreshInterval: 60,
|
|
||||||
autoRefreshSilent: true,
|
|
||||||
autoRefreshStatus: true,
|
|
||||||
autoRefreshFunction: null
|
|
||||||
})
|
|
||||||
|
|
||||||
$.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'
|
|
||||||
})
|
|
||||||
|
|
||||||
$.extend($.fn.bootstrapTable.locales, {
|
|
||||||
formatAutoRefresh () {
|
|
||||||
return 'Auto Refresh'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
|
|
||||||
|
|
||||||
$.BootstrapTable = class extends $.BootstrapTable {
|
|
||||||
init (...args) {
|
|
||||||
super.init(...args)
|
|
||||||
|
|
||||||
if (this.options.autoRefresh && this.options.autoRefreshStatus) {
|
|
||||||
this.setupRefreshInterval()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initToolbar (...args) {
|
|
||||||
if (this.options.autoRefresh) {
|
|
||||||
this.buttons = Object.assign(this.buttons, {
|
|
||||||
autoRefresh: {
|
|
||||||
html: `
|
|
||||||
<button class="auto-refresh ${this.constants.buttonsClass}
|
|
||||||
${this.options.autoRefreshStatus ? ` ${this.constants.classes.buttonActive}` : ''}"
|
|
||||||
type="button" name="autoRefresh" title="${this.options.formatAutoRefresh()}">
|
|
||||||
${this.options.showButtonIcons ? Utils.sprintf(this.constants.html.icon, this.options.iconsPrefix, this.options.icons.autoRefresh) : ''}
|
|
||||||
${this.options.showButtonText ? this.options.formatAutoRefresh() : ''}
|
|
||||||
</button>
|
|
||||||
`,
|
|
||||||
event: this.toggleAutoRefresh
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
super.initToolbar(...args)
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleAutoRefresh () {
|
|
||||||
if (this.options.autoRefresh) {
|
|
||||||
if (this.options.autoRefreshStatus) {
|
|
||||||
clearInterval(this.options.autoRefreshFunction)
|
|
||||||
this.$toolbar.find('>.columns .auto-refresh')
|
|
||||||
.removeClass(this.constants.classes.buttonActive)
|
|
||||||
} else {
|
|
||||||
this.setupRefreshInterval()
|
|
||||||
this.$toolbar.find('>.columns .auto-refresh')
|
|
||||||
.addClass(this.constants.classes.buttonActive)
|
|
||||||
}
|
|
||||||
this.options.autoRefreshStatus = !this.options.autoRefreshStatus
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
destroy () {
|
|
||||||
if (this.options.autoRefresh && this.options.autoRefreshStatus) {
|
|
||||||
clearInterval(this.options.autoRefreshFunction)
|
|
||||||
}
|
|
||||||
|
|
||||||
super.destroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
setupRefreshInterval () {
|
|
||||||
this.options.autoRefreshFunction = setInterval(() => {
|
|
||||||
if (!this.options.autoRefresh || !this.options.autoRefreshStatus) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.refresh({ silent: this.options.autoRefreshSilent })
|
|
||||||
}, this.options.autoRefreshInterval * 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
.fixed-table-header-columns,
|
||||||
|
.fixed-table-body-columns {
|
||||||
|
position: absolute;
|
||||||
|
background-color: #fff;
|
||||||
|
display: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-header-columns .table,
|
||||||
|
.fixed-table-body-columns .table {
|
||||||
|
border-right: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-header-columns .table.table-no-bordered,
|
||||||
|
.fixed-table-body-columns .table.table-no-bordered {
|
||||||
|
border-right: 1px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-body-columns table {
|
||||||
|
position: absolute;
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bootstrap-table .table-hover > tbody > tr.hover > td {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,606 +0,0 @@
|
||||||
/**
|
|
||||||
* @author: Dennis Hernández
|
|
||||||
* @update zhixin wen <wenzhixin2010@gmail.com>
|
|
||||||
*/
|
|
||||||
var Utils = $.fn.bootstrapTable.utils
|
|
||||||
var UtilsCookie = {
|
|
||||||
cookieIds: {
|
|
||||||
sortOrder: 'bs.table.sortOrder',
|
|
||||||
sortName: 'bs.table.sortName',
|
|
||||||
sortPriority: 'bs.table.sortPriority',
|
|
||||||
pageNumber: 'bs.table.pageNumber',
|
|
||||||
pageList: 'bs.table.pageList',
|
|
||||||
hiddenColumns: 'bs.table.hiddenColumns',
|
|
||||||
cardView: 'bs.table.cardView',
|
|
||||||
customView: 'bs.table.customView',
|
|
||||||
searchText: 'bs.table.searchText',
|
|
||||||
reorderColumns: 'bs.table.reorderColumns',
|
|
||||||
filterControl: 'bs.table.filterControl',
|
|
||||||
filterBy: 'bs.table.filterBy'
|
|
||||||
},
|
|
||||||
getCurrentHeader (that) {
|
|
||||||
return that.options.height ? that.$tableHeader : that.$header
|
|
||||||
},
|
|
||||||
getCurrentSearchControls (that) {
|
|
||||||
return that.options.height ? 'table select, table input' : 'select, input'
|
|
||||||
},
|
|
||||||
isCookieSupportedByBrowser () {
|
|
||||||
return navigator.cookieEnabled
|
|
||||||
},
|
|
||||||
isCookieEnabled (that, cookieName) {
|
|
||||||
return that.options.cookiesEnabled.includes(cookieName)
|
|
||||||
},
|
|
||||||
setCookie (that, cookieName, cookieValue) {
|
|
||||||
if (
|
|
||||||
!that.options.cookie ||
|
|
||||||
!UtilsCookie.isCookieEnabled(that, cookieName)
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return that._storage.setItem(`${that.options.cookieIdTable}.${cookieName}`, cookieValue)
|
|
||||||
},
|
|
||||||
getCookie (that, cookieName) {
|
|
||||||
if (
|
|
||||||
!cookieName ||
|
|
||||||
!UtilsCookie.isCookieEnabled(that, cookieName)
|
|
||||||
) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return that._storage.getItem(`${that.options.cookieIdTable}.${cookieName}`)
|
|
||||||
},
|
|
||||||
deleteCookie (that, cookieName) {
|
|
||||||
return that._storage.removeItem(`${that.options.cookieIdTable}.${cookieName}`)
|
|
||||||
},
|
|
||||||
calculateExpiration (cookieExpire) {
|
|
||||||
const time = cookieExpire.replace(/[0-9]*/, '') // s,mi,h,d,m,y
|
|
||||||
|
|
||||||
cookieExpire = cookieExpire.replace(/[A-Za-z]{1,2}/, '') // number
|
|
||||||
|
|
||||||
switch (time.toLowerCase()) {
|
|
||||||
case 's':
|
|
||||||
cookieExpire = +cookieExpire
|
|
||||||
break
|
|
||||||
case 'mi':
|
|
||||||
cookieExpire *= 60
|
|
||||||
break
|
|
||||||
case 'h':
|
|
||||||
cookieExpire = cookieExpire * 60 * 60
|
|
||||||
break
|
|
||||||
case 'd':
|
|
||||||
cookieExpire = cookieExpire * 24 * 60 * 60
|
|
||||||
break
|
|
||||||
case 'm':
|
|
||||||
cookieExpire = cookieExpire * 30 * 24 * 60 * 60
|
|
||||||
break
|
|
||||||
case 'y':
|
|
||||||
cookieExpire = cookieExpire * 365 * 24 * 60 * 60
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
cookieExpire = undefined
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if (!cookieExpire) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
const d = new Date()
|
|
||||||
|
|
||||||
d.setTime(d.getTime() + cookieExpire * 1000)
|
|
||||||
return d.toGMTString()
|
|
||||||
},
|
|
||||||
initCookieFilters (that) {
|
|
||||||
setTimeout(() => {
|
|
||||||
const parsedCookieFilters = JSON.parse(
|
|
||||||
UtilsCookie.getCookie(that, UtilsCookie.cookieIds.filterControl))
|
|
||||||
|
|
||||||
if (!that._filterControlValuesLoaded && parsedCookieFilters) {
|
|
||||||
const cachedFilters = {}
|
|
||||||
const header = UtilsCookie.getCurrentHeader(that)
|
|
||||||
const searchControls = UtilsCookie.getCurrentSearchControls(that)
|
|
||||||
|
|
||||||
const applyCookieFilters = (element, filteredCookies) => {
|
|
||||||
filteredCookies.forEach(cookie => {
|
|
||||||
const value = element.value.toString()
|
|
||||||
const text = cookie.text
|
|
||||||
|
|
||||||
if (
|
|
||||||
text === '' ||
|
|
||||||
element.type === 'radio' &&
|
|
||||||
value !== text
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
element.tagName === 'INPUT' &&
|
|
||||||
element.type === 'radio' &&
|
|
||||||
value === text
|
|
||||||
) {
|
|
||||||
element.checked = true
|
|
||||||
cachedFilters[cookie.field] = text
|
|
||||||
} else if (element.tagName === 'INPUT') {
|
|
||||||
element.value = text
|
|
||||||
cachedFilters[cookie.field] = text
|
|
||||||
} else if (
|
|
||||||
element.tagName === 'SELECT' &&
|
|
||||||
that.options.filterControlContainer
|
|
||||||
) {
|
|
||||||
element.value = text
|
|
||||||
cachedFilters[cookie.field] = text
|
|
||||||
} else if (text !== '' && element.tagName === 'SELECT') {
|
|
||||||
cachedFilters[cookie.field] = text
|
|
||||||
for (const currentElement of element) {
|
|
||||||
if (currentElement.value === text) {
|
|
||||||
currentElement.selected = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const option = document.createElement('option')
|
|
||||||
|
|
||||||
option.value = text
|
|
||||||
option.text = text
|
|
||||||
element.add(option, element[1])
|
|
||||||
element.selectedIndex = 1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let filterContainer = header
|
|
||||||
|
|
||||||
if (that.options.filterControlContainer) {
|
|
||||||
filterContainer = $(`${that.options.filterControlContainer}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
filterContainer.find(searchControls).each(function () {
|
|
||||||
const field = $(this).closest('[data-field]').data('field')
|
|
||||||
const filteredCookies = parsedCookieFilters.filter(cookie => cookie.field === field)
|
|
||||||
|
|
||||||
applyCookieFilters(this, filteredCookies)
|
|
||||||
})
|
|
||||||
|
|
||||||
that.initColumnSearch(cachedFilters)
|
|
||||||
that._filterControlValuesLoaded = true
|
|
||||||
that.initServer()
|
|
||||||
}
|
|
||||||
}, 250)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.defaults, {
|
|
||||||
cookie: false,
|
|
||||||
cookieExpire: '2h',
|
|
||||||
cookiePath: null,
|
|
||||||
cookieDomain: null,
|
|
||||||
cookieSecure: null,
|
|
||||||
cookieSameSite: 'Lax',
|
|
||||||
cookieIdTable: '',
|
|
||||||
cookiesEnabled: [
|
|
||||||
'bs.table.sortOrder', 'bs.table.sortName', 'bs.table.sortPriority',
|
|
||||||
'bs.table.pageNumber', 'bs.table.pageList',
|
|
||||||
'bs.table.hiddenColumns', 'bs.table.searchText',
|
|
||||||
'bs.table.filterControl', 'bs.table.filterBy',
|
|
||||||
'bs.table.reorderColumns', 'bs.table.cardView', 'bs.table.customView'
|
|
||||||
],
|
|
||||||
cookieStorage: 'cookieStorage', // localStorage, sessionStorage, customStorage
|
|
||||||
cookieCustomStorageGet: null,
|
|
||||||
cookieCustomStorageSet: null,
|
|
||||||
cookieCustomStorageDelete: null,
|
|
||||||
// internal variable
|
|
||||||
_filterControls: [],
|
|
||||||
_filterControlValuesLoaded: false,
|
|
||||||
_storage: {
|
|
||||||
setItem: undefined,
|
|
||||||
getItem: undefined,
|
|
||||||
removeItem: undefined
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
$.fn.bootstrapTable.methods.push('getCookies')
|
|
||||||
$.fn.bootstrapTable.methods.push('deleteCookie')
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.utils, {
|
|
||||||
setCookie: UtilsCookie.setCookie,
|
|
||||||
getCookie: UtilsCookie.getCookie
|
|
||||||
})
|
|
||||||
|
|
||||||
$.BootstrapTable = class extends $.BootstrapTable {
|
|
||||||
init () {
|
|
||||||
if (this.options.cookie) {
|
|
||||||
if (
|
|
||||||
this.options.cookieStorage === 'cookieStorage' &&
|
|
||||||
!UtilsCookie.isCookieSupportedByBrowser()
|
|
||||||
) {
|
|
||||||
throw new Error('Cookies are not enabled in this browser.')
|
|
||||||
}
|
|
||||||
|
|
||||||
this.configureStorage()
|
|
||||||
|
|
||||||
// FilterBy logic
|
|
||||||
const filterByCookieValue = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.filterBy)
|
|
||||||
|
|
||||||
if (typeof filterByCookieValue === 'boolean' && !filterByCookieValue) {
|
|
||||||
throw new Error('The cookie value of filterBy must be a json!')
|
|
||||||
}
|
|
||||||
|
|
||||||
let filterByCookie = {}
|
|
||||||
|
|
||||||
try {
|
|
||||||
filterByCookie = JSON.parse(filterByCookieValue)
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error('Could not parse the json of the filterBy cookie!')
|
|
||||||
}
|
|
||||||
this.filterColumns = filterByCookie ? filterByCookie : {}
|
|
||||||
|
|
||||||
// FilterControl logic
|
|
||||||
this._filterControls = []
|
|
||||||
this._filterControlValuesLoaded = false
|
|
||||||
|
|
||||||
this.options.cookiesEnabled = typeof this.options.cookiesEnabled === 'string' ?
|
|
||||||
this.options.cookiesEnabled.replace('[', '').replace(']', '')
|
|
||||||
.replace(/'/g, '').replace(/ /g, '').split(',') :
|
|
||||||
this.options.cookiesEnabled
|
|
||||||
|
|
||||||
if (this.options.filterControl) {
|
|
||||||
const that = this
|
|
||||||
|
|
||||||
this.$el.on('column-search.bs.table', (e, field, text) => {
|
|
||||||
let isNewField = true
|
|
||||||
|
|
||||||
for (let i = 0; i < that._filterControls.length; i++) {
|
|
||||||
if (that._filterControls[i].field === field) {
|
|
||||||
that._filterControls[i].text = text
|
|
||||||
isNewField = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isNewField) {
|
|
||||||
that._filterControls.push({
|
|
||||||
field,
|
|
||||||
text
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
UtilsCookie.setCookie(that, UtilsCookie.cookieIds.filterControl, JSON.stringify(that._filterControls))
|
|
||||||
}).on('created-controls.bs.table', UtilsCookie.initCookieFilters(that))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
initServer (...args) {
|
|
||||||
if (
|
|
||||||
this.options.cookie &&
|
|
||||||
this.options.filterControl &&
|
|
||||||
!this._filterControlValuesLoaded
|
|
||||||
) {
|
|
||||||
const cookie = JSON.parse(UtilsCookie.getCookie(this, UtilsCookie.cookieIds.filterControl))
|
|
||||||
|
|
||||||
if (cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.initServer(...args)
|
|
||||||
}
|
|
||||||
|
|
||||||
initTable (...args) {
|
|
||||||
super.initTable(...args)
|
|
||||||
this.initCookie()
|
|
||||||
}
|
|
||||||
|
|
||||||
onSort (...args) {
|
|
||||||
super.onSort(...args)
|
|
||||||
|
|
||||||
if (!this.options.cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options.sortName === undefined || this.options.sortOrder === undefined) {
|
|
||||||
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortName)
|
|
||||||
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortOrder)
|
|
||||||
} else {
|
|
||||||
this.options.sortPriority = null
|
|
||||||
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortPriority)
|
|
||||||
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortOrder, this.options.sortOrder)
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortName, this.options.sortName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMultipleSort (...args) {
|
|
||||||
super.onMultipleSort(...args)
|
|
||||||
|
|
||||||
if (!this.options.cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options.sortPriority === undefined) {
|
|
||||||
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortPriority)
|
|
||||||
} else {
|
|
||||||
this.options.sortName = undefined
|
|
||||||
this.options.sortOrder = undefined
|
|
||||||
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortName)
|
|
||||||
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortOrder)
|
|
||||||
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortPriority, JSON.stringify(this.options.sortPriority))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onPageNumber (...args) {
|
|
||||||
super.onPageNumber(...args)
|
|
||||||
if (!this.options.cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
onPageListChange (...args) {
|
|
||||||
super.onPageListChange(...args)
|
|
||||||
if (!this.options.cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageList,
|
|
||||||
this.options.pageSize === this.options.formatAllRows() ? 'all' : this.options.pageSize)
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
onPagePre (...args) {
|
|
||||||
super.onPagePre(...args)
|
|
||||||
if (!this.options.cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
onPageNext (...args) {
|
|
||||||
super.onPageNext(...args)
|
|
||||||
if (!this.options.cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleColumn (...args) {
|
|
||||||
super._toggleColumn(...args)
|
|
||||||
if (!this.options.cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.hiddenColumns, JSON.stringify(this.getHiddenColumns().map(column => column.field)))
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleAllColumns (...args) {
|
|
||||||
super._toggleAllColumns(...args)
|
|
||||||
if (!this.options.cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.hiddenColumns, JSON.stringify(this.getHiddenColumns().map(column => column.field)))
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleView () {
|
|
||||||
super.toggleView()
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.cardView, this.options.cardView)
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleCustomView () {
|
|
||||||
super.toggleCustomView()
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.customView, this.customViewDefaultView)
|
|
||||||
}
|
|
||||||
|
|
||||||
selectPage (page) {
|
|
||||||
super.selectPage(page)
|
|
||||||
if (!this.options.cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, page)
|
|
||||||
}
|
|
||||||
|
|
||||||
onSearch (event) {
|
|
||||||
super.onSearch(event, arguments.length > 1 ? arguments[1] : true)
|
|
||||||
if (!this.options.cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.options.search) {
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.searchText, this.searchText)
|
|
||||||
}
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
initHeader (...args) {
|
|
||||||
if (this.options.reorderableColumns && this.options.cookie) {
|
|
||||||
this.columnsSortOrder = JSON.parse(UtilsCookie.getCookie(this, UtilsCookie.cookieIds.reorderColumns))
|
|
||||||
}
|
|
||||||
super.initHeader(...args)
|
|
||||||
}
|
|
||||||
|
|
||||||
persistReorderColumnsState (that) {
|
|
||||||
UtilsCookie.setCookie(that, UtilsCookie.cookieIds.reorderColumns, JSON.stringify(that.columnsSortOrder))
|
|
||||||
}
|
|
||||||
|
|
||||||
filterBy (...args) {
|
|
||||||
super.filterBy(...args)
|
|
||||||
if (!this.options.cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.filterBy, JSON.stringify(this.filterColumns))
|
|
||||||
}
|
|
||||||
|
|
||||||
initCookie () {
|
|
||||||
if (!this.options.cookie) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options.cookieIdTable === '' || this.options.cookieExpire === '') {
|
|
||||||
console.error('Configuration error. Please review the cookieIdTable and the cookieExpire property. If the properties are correct, then this browser does not support cookies.')
|
|
||||||
this.options.cookie = false // Make sure that the cookie extension is disabled
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const sortOrderCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.sortOrder)
|
|
||||||
const sortOrderNameCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.sortName)
|
|
||||||
let sortPriorityCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.sortPriority)
|
|
||||||
const pageNumberCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.pageNumber)
|
|
||||||
const pageListCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.pageList)
|
|
||||||
const searchTextCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.searchText)
|
|
||||||
const cardViewCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.cardView)
|
|
||||||
const customViewCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.customView)
|
|
||||||
const hiddenColumnsCookieValue = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.hiddenColumns)
|
|
||||||
|
|
||||||
let hiddenColumnsCookie = {}
|
|
||||||
|
|
||||||
try {
|
|
||||||
hiddenColumnsCookie = JSON.parse(hiddenColumnsCookieValue)
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error('Could not parse the json of the hidden columns cookie!', hiddenColumnsCookieValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
sortPriorityCookie = JSON.parse(sortPriorityCookie)
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error('Could not parse the json of the sortPriority cookie!', sortPriorityCookie)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sortPriorityCookie) {
|
|
||||||
// sortOrder
|
|
||||||
this.options.sortOrder = sortOrderCookie ? sortOrderCookie : this.options.sortOrder
|
|
||||||
// sortName
|
|
||||||
this.options.sortName = sortOrderNameCookie ? sortOrderNameCookie : this.options.sortName
|
|
||||||
} else {
|
|
||||||
this.options.sortOrder = undefined
|
|
||||||
this.options.sortName = undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
// sortPriority
|
|
||||||
this.options.sortPriority = sortPriorityCookie ? sortPriorityCookie : this.options.sortPriority
|
|
||||||
|
|
||||||
if (this.options.sortOrder || this.options.sortName) {
|
|
||||||
// sortPriority
|
|
||||||
this.options.sortPriority = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// pageNumber
|
|
||||||
this.options.pageNumber = pageNumberCookie ? +pageNumberCookie : this.options.pageNumber
|
|
||||||
// pageSize
|
|
||||||
this.options.pageSize = pageListCookie ? pageListCookie === 'all' ?
|
|
||||||
this.options.formatAllRows() : +pageListCookie : this.options.pageSize
|
|
||||||
// searchText
|
|
||||||
if (UtilsCookie.isCookieEnabled(this, UtilsCookie.cookieIds.searchText) && this.options.searchText === '') {
|
|
||||||
this.options.searchText = searchTextCookie ? searchTextCookie : ''
|
|
||||||
}
|
|
||||||
// cardView
|
|
||||||
if (cardViewCookie !== null) {
|
|
||||||
this.options.cardView = cardViewCookie === 'true' ? cardViewCookie : false
|
|
||||||
}
|
|
||||||
this.customViewDefaultView = customViewCookie === 'true'
|
|
||||||
|
|
||||||
if (hiddenColumnsCookie) {
|
|
||||||
for (const column of this.columns) {
|
|
||||||
if (!column.switchable) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
column.visible = this.isSelectionColumn(column) ||
|
|
||||||
!hiddenColumnsCookie.includes(column.field)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getCookies () {
|
|
||||||
const bootstrapTable = this
|
|
||||||
const cookies = {}
|
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(UtilsCookie.cookieIds)) {
|
|
||||||
cookies[key] = UtilsCookie.getCookie(bootstrapTable, value)
|
|
||||||
if (key === 'columns' || key === 'hiddenColumns' || key === 'sortPriority') {
|
|
||||||
cookies[key] = JSON.parse(cookies[key])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cookies
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteCookie (cookieName) {
|
|
||||||
if (!cookieName) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds[cookieName])
|
|
||||||
}
|
|
||||||
|
|
||||||
configureStorage () {
|
|
||||||
const that = this
|
|
||||||
|
|
||||||
this._storage = {}
|
|
||||||
switch (this.options.cookieStorage) {
|
|
||||||
case 'cookieStorage':
|
|
||||||
this._storage.setItem = function (cookieName, cookieValue) {
|
|
||||||
document.cookie = [
|
|
||||||
cookieName, '=', encodeURIComponent(cookieValue),
|
|
||||||
`; expires=${UtilsCookie.calculateExpiration(that.options.cookieExpire)}`,
|
|
||||||
that.options.cookiePath ? `; path=${that.options.cookiePath}` : '',
|
|
||||||
that.options.cookieDomain ? `; domain=${that.options.cookieDomain}` : '',
|
|
||||||
that.options.cookieSecure ? '; secure' : '',
|
|
||||||
`;SameSite=${that.options.cookieSameSite}`
|
|
||||||
].join('')
|
|
||||||
}
|
|
||||||
this._storage.getItem = function (cookieName) {
|
|
||||||
const value = `; ${document.cookie}`
|
|
||||||
const parts = value.split(`; ${cookieName}=`)
|
|
||||||
|
|
||||||
return parts.length === 2 ? decodeURIComponent(parts.pop().split(';').shift()) : null
|
|
||||||
}
|
|
||||||
this._storage.removeItem = function (cookieName) {
|
|
||||||
document.cookie = [
|
|
||||||
encodeURIComponent(cookieName), '=',
|
|
||||||
'; expires=Thu, 01 Jan 1970 00:00:00 GMT',
|
|
||||||
that.options.cookiePath ? `; path=${that.options.cookiePath}` : '',
|
|
||||||
that.options.cookieDomain ? `; domain=${that.options.cookieDomain}` : '',
|
|
||||||
`;SameSite=${that.options.cookieSameSite}`
|
|
||||||
].join('')
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'localStorage':
|
|
||||||
this._storage.setItem = function (cookieName, cookieValue) {
|
|
||||||
localStorage.setItem(cookieName, cookieValue)
|
|
||||||
}
|
|
||||||
this._storage.getItem = function (cookieName) {
|
|
||||||
return localStorage.getItem(cookieName)
|
|
||||||
}
|
|
||||||
this._storage.removeItem = function (cookieName) {
|
|
||||||
localStorage.removeItem(cookieName)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'sessionStorage':
|
|
||||||
this._storage.setItem = function (cookieName, cookieValue) {
|
|
||||||
sessionStorage.setItem(cookieName, cookieValue)
|
|
||||||
}
|
|
||||||
this._storage.getItem = function (cookieName) {
|
|
||||||
return sessionStorage.getItem(cookieName)
|
|
||||||
}
|
|
||||||
this._storage.removeItem = function (cookieName) {
|
|
||||||
sessionStorage.removeItem(cookieName)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'customStorage':
|
|
||||||
if (
|
|
||||||
!this.options.cookieCustomStorageSet ||
|
|
||||||
!this.options.cookieCustomStorageGet ||
|
|
||||||
!this.options.cookieCustomStorageDelete
|
|
||||||
) {
|
|
||||||
throw new Error('The following options must be set while using the customStorage: cookieCustomStorageSet, cookieCustomStorageGet and cookieCustomStorageDelete')
|
|
||||||
}
|
|
||||||
|
|
||||||
this._storage.setItem = function (cookieName, cookieValue) {
|
|
||||||
Utils.calculateObjectValue(that.options, that.options.cookieCustomStorageSet, [cookieName, cookieValue], '')
|
|
||||||
}
|
|
||||||
this._storage.getItem = function (cookieName) {
|
|
||||||
return Utils.calculateObjectValue(that.options, that.options.cookieCustomStorageGet, [cookieName], '')
|
|
||||||
}
|
|
||||||
this._storage.removeItem = function (cookieName) {
|
|
||||||
Utils.calculateObjectValue(that.options, that.options.cookieCustomStorageDelete, [cookieName], '')
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
throw new Error('Storage method not supported.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,135 +0,0 @@
|
||||||
/**
|
|
||||||
* @author: Dustin Utecht
|
|
||||||
* @github: https://github.com/UtechtDustin
|
|
||||||
*/
|
|
||||||
|
|
||||||
var Utils = $.fn.bootstrapTable.utils
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.defaults, {
|
|
||||||
customView: false,
|
|
||||||
showCustomView: false,
|
|
||||||
customViewDefaultView: false
|
|
||||||
})
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.defaults.icons, {
|
|
||||||
customViewOn: {
|
|
||||||
bootstrap3: 'glyphicon glyphicon-list',
|
|
||||||
bootstrap5: 'bi-list',
|
|
||||||
bootstrap4: 'fa fa-list',
|
|
||||||
semantic: 'fa fa-list',
|
|
||||||
foundation: 'fa fa-list',
|
|
||||||
bulma: 'fa fa-list',
|
|
||||||
materialize: 'list'
|
|
||||||
}[$.fn.bootstrapTable.theme] || 'fa-list',
|
|
||||||
customViewOff: {
|
|
||||||
bootstrap3: 'glyphicon glyphicon-eye-open',
|
|
||||||
bootstrap5: 'bi-grid',
|
|
||||||
bootstrap4: 'fa fa-th',
|
|
||||||
semantic: 'fa fa-th',
|
|
||||||
foundation: 'fa fa-th',
|
|
||||||
bulma: 'fa fa-th',
|
|
||||||
materialize: 'grid_on'
|
|
||||||
}[$.fn.bootstrapTable.theme] || 'fa-th'
|
|
||||||
})
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.defaults, {
|
|
||||||
onCustomViewPostBody () {
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
onCustomViewPreBody () {
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
onToggleCustomView () {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.locales, {
|
|
||||||
formatToggleCustomViewOn () {
|
|
||||||
return 'Show custom view'
|
|
||||||
},
|
|
||||||
formatToggleCustomViewOff () {
|
|
||||||
return 'Hide custom view'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
Object.assign($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
|
|
||||||
|
|
||||||
$.fn.bootstrapTable.methods.push('toggleCustomView')
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.events, {
|
|
||||||
'custom-view-post-body.bs.table': 'onCustomViewPostBody',
|
|
||||||
'custom-view-pre-body.bs.table': 'onCustomViewPreBody',
|
|
||||||
'toggle-custom-view.bs.table': 'onToggleCustomView'
|
|
||||||
})
|
|
||||||
|
|
||||||
$.BootstrapTable = class extends $.BootstrapTable {
|
|
||||||
|
|
||||||
init () {
|
|
||||||
this.customViewDefaultView = this.options.customViewDefaultView
|
|
||||||
|
|
||||||
super.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
initToolbar (...args) {
|
|
||||||
if (this.options.customView && this.options.showCustomView) {
|
|
||||||
this.buttons = Object.assign(this.buttons, {
|
|
||||||
customView: {
|
|
||||||
text: this.options.customViewDefaultView ? this.options.formatToggleCustomViewOff() : this.options.formatToggleCustomViewOn(),
|
|
||||||
icon: this.options.customViewDefaultView ? this.options.icons.customViewOn : this.options.icons.customViewOff,
|
|
||||||
event: this.toggleCustomView,
|
|
||||||
attributes: {
|
|
||||||
'aria-label': this.options.customViewDefaultView ? this.options.formatToggleCustomViewOff() : this.options.formatToggleCustomViewOn(),
|
|
||||||
title: this.options.customViewDefaultView ? this.options.formatToggleCustomViewOff() : this.options.formatToggleCustomViewOn()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
super.initToolbar(...args)
|
|
||||||
}
|
|
||||||
|
|
||||||
initBody () {
|
|
||||||
super.initBody()
|
|
||||||
|
|
||||||
if (!this.options.customView) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const $table = this.$el
|
|
||||||
const $customViewContainer = this.$container.find('.fixed-table-custom-view')
|
|
||||||
|
|
||||||
$table.hide()
|
|
||||||
$customViewContainer.hide()
|
|
||||||
if (!this.options.customView || !this.customViewDefaultView) {
|
|
||||||
$table.show()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = this.getData().slice(this.pageFrom - 1, this.pageTo)
|
|
||||||
const value = Utils.calculateObjectValue(this, this.options.customView, [data], '')
|
|
||||||
|
|
||||||
this.trigger('custom-view-pre-body', data, value)
|
|
||||||
if ($customViewContainer.length === 1) {
|
|
||||||
$customViewContainer.show().html(value)
|
|
||||||
} else {
|
|
||||||
this.$tableBody.after(`<div class="fixed-table-custom-view">${value}</div>`)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.trigger('custom-view-post-body', data, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleCustomView () {
|
|
||||||
this.customViewDefaultView = !this.customViewDefaultView
|
|
||||||
|
|
||||||
const icon = this.options.showButtonIcons ? this.customViewDefaultView ? this.options.icons.customViewOn : this.options.icons.customViewOff : ''
|
|
||||||
const text = this.options.showButtonText ? this.customViewDefaultView ? this.options.formatToggleCustomViewOff() : this.options.formatToggleCustomViewOn() : ''
|
|
||||||
|
|
||||||
this.$toolbar.find('button[name="customView"]')
|
|
||||||
.html(`${Utils.sprintf(this.constants.html.icon, this.options.iconsPrefix, icon)} ${text}`)
|
|
||||||
.attr('aria-label', text)
|
|
||||||
.attr('title', text)
|
|
||||||
|
|
||||||
this.initBody()
|
|
||||||
this.trigger('toggle-custom-view', this.customViewDefaultView)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,674 +0,0 @@
|
||||||
/*! X-editable - v1.5.3
|
|
||||||
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
|
|
||||||
* http://github.com/vitalets/x-editable
|
|
||||||
* Copyright (c) 2019 Vitaliy Potapov; Licensed MIT */
|
|
||||||
.editableform {
|
|
||||||
margin-bottom: 0; /* overwrites bootstrap margin */
|
|
||||||
}
|
|
||||||
|
|
||||||
.editableform .control-group {
|
|
||||||
margin-bottom: 0; /* overwrites bootstrap margin */
|
|
||||||
white-space: nowrap; /* prevent wrapping buttons on new line */
|
|
||||||
line-height: 20px; /* overwriting bootstrap line-height. See #133 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
BS3 fix: stop css from breaking when the form is inside a popup and inside a form with the class .form-horizontal
|
|
||||||
See: https://github.com/vitalets/x-editable/issues/682
|
|
||||||
*/
|
|
||||||
.form-horizontal .editable-popup .editableform .form-group {
|
|
||||||
margin-left:0;
|
|
||||||
margin-right:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
BS3 width:1005 for inputs breaks editable form in popup
|
|
||||||
See: https://github.com/vitalets/x-editable/issues/393
|
|
||||||
*/
|
|
||||||
.editableform .form-control {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-buttons {
|
|
||||||
display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
|
|
||||||
vertical-align: top;
|
|
||||||
margin-left: 7px;
|
|
||||||
/* inline-block emulation for IE7*/
|
|
||||||
zoom: 1;
|
|
||||||
*display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-buttons.editable-buttons-bottom {
|
|
||||||
display: block;
|
|
||||||
margin-top: 7px;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-input {
|
|
||||||
vertical-align: top;
|
|
||||||
display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
|
|
||||||
width: auto; /* bootstrap-responsive has width: 100% that breakes layout */
|
|
||||||
white-space: normal; /* reset white-space decalred in parent*/
|
|
||||||
/* display-inline emulation for IE7*/
|
|
||||||
zoom: 1;
|
|
||||||
*display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-buttons .editable-cancel {
|
|
||||||
margin-left: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*for jquery-ui buttons need set height to look more pretty*/
|
|
||||||
.editable-buttons button.ui-button-icon-only {
|
|
||||||
height: 24px;
|
|
||||||
width: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editableform-loading {
|
|
||||||
background: url('loading.gif') center center no-repeat;
|
|
||||||
height: 25px;
|
|
||||||
width: auto;
|
|
||||||
min-width: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-inline .editableform-loading {
|
|
||||||
background-position: left 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-error-block {
|
|
||||||
max-width: 300px;
|
|
||||||
margin: 5px 0 0 0;
|
|
||||||
width: auto;
|
|
||||||
white-space: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*add padding for jquery ui*/
|
|
||||||
.editable-error-block.ui-state-error {
|
|
||||||
padding: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-error {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- For specific types ---- */
|
|
||||||
|
|
||||||
.editableform .editable-date {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* move datepicker icon to center of add-on button. See https://github.com/vitalets/x-editable/issues/183 */
|
|
||||||
.editable-inline .add-on .icon-th {
|
|
||||||
margin-top: 3px;
|
|
||||||
margin-left: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* checklist vertical alignment */
|
|
||||||
.editable-checklist label input[type="checkbox"],
|
|
||||||
.editable-checklist label span {
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-checklist label {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set exact width of textarea to fit buttons toolbar */
|
|
||||||
.editable-wysihtml5 {
|
|
||||||
width: 566px;
|
|
||||||
height: 250px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear button shown as link in date inputs */
|
|
||||||
.editable-clear {
|
|
||||||
clear: both;
|
|
||||||
font-size: 0.9em;
|
|
||||||
text-decoration: none;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* IOS-style clear button for text inputs */
|
|
||||||
.editable-clear-x {
|
|
||||||
background: url('clear.png') center center no-repeat;
|
|
||||||
display: block;
|
|
||||||
width: 13px;
|
|
||||||
height: 13px;
|
|
||||||
position: absolute;
|
|
||||||
opacity: 0.6;
|
|
||||||
z-index: 100;
|
|
||||||
|
|
||||||
top: 50%;
|
|
||||||
right: 6px;
|
|
||||||
margin-top: -6px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-clear-x:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-pre-wrapped {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-container.editable-popup {
|
|
||||||
max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-container.popover {
|
|
||||||
width: auto; /* without this rule popover does not stretch */
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-container.editable-inline {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
width: auto;
|
|
||||||
/* inline-block emulation for IE7*/
|
|
||||||
zoom: 1;
|
|
||||||
*display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-container.ui-widget {
|
|
||||||
font-size: inherit; /* jqueryui widget font 1.1em too big, overwrite it */
|
|
||||||
z-index: 9990; /* should be less than select2 dropdown z-index to close dropdown first when click */
|
|
||||||
}
|
|
||||||
.editable-click,
|
|
||||||
a.editable-click,
|
|
||||||
a.editable-click:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
border-bottom: dashed 1px #0088cc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-click.editable-disabled,
|
|
||||||
a.editable-click.editable-disabled,
|
|
||||||
a.editable-click.editable-disabled:hover {
|
|
||||||
color: #585858;
|
|
||||||
cursor: default;
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-empty, .editable-empty:hover, .editable-empty:focus{
|
|
||||||
font-style: italic;
|
|
||||||
color: #DD1144;
|
|
||||||
/* border-bottom: none; */
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-unsaved {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-unsaved:after {
|
|
||||||
/* content: '*'*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable-bg-transition {
|
|
||||||
-webkit-transition: background-color 1400ms ease-out;
|
|
||||||
-moz-transition: background-color 1400ms ease-out;
|
|
||||||
-o-transition: background-color 1400ms ease-out;
|
|
||||||
-ms-transition: background-color 1400ms ease-out;
|
|
||||||
transition: background-color 1400ms ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*see https://github.com/vitalets/x-editable/issues/139 */
|
|
||||||
.form-horizontal .editable
|
|
||||||
{
|
|
||||||
padding-top: 5px;
|
|
||||||
display:inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Datepicker for Bootstrap
|
|
||||||
*
|
|
||||||
* Copyright 2012 Stefan Petre
|
|
||||||
* Improvements by Andrew Rowls
|
|
||||||
* Licensed under the Apache License v2.0
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
.datepicker {
|
|
||||||
padding: 4px;
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
direction: ltr;
|
|
||||||
/*.dow {
|
|
||||||
border-top: 1px solid #ddd !important;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
|
||||||
.datepicker-inline {
|
|
||||||
width: 220px;
|
|
||||||
}
|
|
||||||
.datepicker.datepicker-rtl {
|
|
||||||
direction: rtl;
|
|
||||||
}
|
|
||||||
.datepicker.datepicker-rtl table tr td span {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
.datepicker-dropdown {
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
.datepicker-dropdown:before {
|
|
||||||
content: '';
|
|
||||||
display: inline-block;
|
|
||||||
border-left: 7px solid transparent;
|
|
||||||
border-right: 7px solid transparent;
|
|
||||||
border-bottom: 7px solid #ccc;
|
|
||||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
|
||||||
position: absolute;
|
|
||||||
top: -7px;
|
|
||||||
left: 6px;
|
|
||||||
}
|
|
||||||
.datepicker-dropdown:after {
|
|
||||||
content: '';
|
|
||||||
display: inline-block;
|
|
||||||
border-left: 6px solid transparent;
|
|
||||||
border-right: 6px solid transparent;
|
|
||||||
border-bottom: 6px solid #ffffff;
|
|
||||||
position: absolute;
|
|
||||||
top: -6px;
|
|
||||||
left: 7px;
|
|
||||||
}
|
|
||||||
.datepicker > div {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.datepicker.days div.datepicker-days {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.datepicker.months div.datepicker-months {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.datepicker.years div.datepicker-years {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.datepicker table {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.datepicker td,
|
|
||||||
.datepicker th {
|
|
||||||
text-align: center;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
.table-striped .datepicker table tr td,
|
|
||||||
.table-striped .datepicker table tr th {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.day:hover {
|
|
||||||
background: #eeeeee;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.old,
|
|
||||||
.datepicker table tr td.new {
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.disabled,
|
|
||||||
.datepicker table tr td.disabled:hover {
|
|
||||||
background: none;
|
|
||||||
color: #999999;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.today,
|
|
||||||
.datepicker table tr td.today:hover,
|
|
||||||
.datepicker table tr td.today.disabled,
|
|
||||||
.datepicker table tr td.today.disabled:hover {
|
|
||||||
background-color: #fde19a;
|
|
||||||
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
|
|
||||||
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
|
|
||||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
|
|
||||||
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
|
|
||||||
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
|
|
||||||
background-image: linear-gradient(top, #fdd49a, #fdf59a);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
|
|
||||||
border-color: #fdf59a #fdf59a #fbed50;
|
|
||||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.today:hover,
|
|
||||||
.datepicker table tr td.today:hover:hover,
|
|
||||||
.datepicker table tr td.today.disabled:hover,
|
|
||||||
.datepicker table tr td.today.disabled:hover:hover,
|
|
||||||
.datepicker table tr td.today:active,
|
|
||||||
.datepicker table tr td.today:hover:active,
|
|
||||||
.datepicker table tr td.today.disabled:active,
|
|
||||||
.datepicker table tr td.today.disabled:hover:active,
|
|
||||||
.datepicker table tr td.today.active,
|
|
||||||
.datepicker table tr td.today:hover.active,
|
|
||||||
.datepicker table tr td.today.disabled.active,
|
|
||||||
.datepicker table tr td.today.disabled:hover.active,
|
|
||||||
.datepicker table tr td.today.disabled,
|
|
||||||
.datepicker table tr td.today:hover.disabled,
|
|
||||||
.datepicker table tr td.today.disabled.disabled,
|
|
||||||
.datepicker table tr td.today.disabled:hover.disabled,
|
|
||||||
.datepicker table tr td.today[disabled],
|
|
||||||
.datepicker table tr td.today:hover[disabled],
|
|
||||||
.datepicker table tr td.today.disabled[disabled],
|
|
||||||
.datepicker table tr td.today.disabled:hover[disabled] {
|
|
||||||
background-color: #fdf59a;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.today:active,
|
|
||||||
.datepicker table tr td.today:hover:active,
|
|
||||||
.datepicker table tr td.today.disabled:active,
|
|
||||||
.datepicker table tr td.today.disabled:hover:active,
|
|
||||||
.datepicker table tr td.today.active,
|
|
||||||
.datepicker table tr td.today:hover.active,
|
|
||||||
.datepicker table tr td.today.disabled.active,
|
|
||||||
.datepicker table tr td.today.disabled:hover.active {
|
|
||||||
background-color: #fbf069 \9;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.today:hover:hover {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.today.active:hover {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.range,
|
|
||||||
.datepicker table tr td.range:hover,
|
|
||||||
.datepicker table tr td.range.disabled,
|
|
||||||
.datepicker table tr td.range.disabled:hover {
|
|
||||||
background: #eeeeee;
|
|
||||||
-webkit-border-radius: 0;
|
|
||||||
-moz-border-radius: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.range.today,
|
|
||||||
.datepicker table tr td.range.today:hover,
|
|
||||||
.datepicker table tr td.range.today.disabled,
|
|
||||||
.datepicker table tr td.range.today.disabled:hover {
|
|
||||||
background-color: #f3d17a;
|
|
||||||
background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a);
|
|
||||||
background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);
|
|
||||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
|
|
||||||
background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);
|
|
||||||
background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);
|
|
||||||
background-image: linear-gradient(top, #f3c17a, #f3e97a);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
|
|
||||||
border-color: #f3e97a #f3e97a #edde34;
|
|
||||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
-webkit-border-radius: 0;
|
|
||||||
-moz-border-radius: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.range.today:hover,
|
|
||||||
.datepicker table tr td.range.today:hover:hover,
|
|
||||||
.datepicker table tr td.range.today.disabled:hover,
|
|
||||||
.datepicker table tr td.range.today.disabled:hover:hover,
|
|
||||||
.datepicker table tr td.range.today:active,
|
|
||||||
.datepicker table tr td.range.today:hover:active,
|
|
||||||
.datepicker table tr td.range.today.disabled:active,
|
|
||||||
.datepicker table tr td.range.today.disabled:hover:active,
|
|
||||||
.datepicker table tr td.range.today.active,
|
|
||||||
.datepicker table tr td.range.today:hover.active,
|
|
||||||
.datepicker table tr td.range.today.disabled.active,
|
|
||||||
.datepicker table tr td.range.today.disabled:hover.active,
|
|
||||||
.datepicker table tr td.range.today.disabled,
|
|
||||||
.datepicker table tr td.range.today:hover.disabled,
|
|
||||||
.datepicker table tr td.range.today.disabled.disabled,
|
|
||||||
.datepicker table tr td.range.today.disabled:hover.disabled,
|
|
||||||
.datepicker table tr td.range.today[disabled],
|
|
||||||
.datepicker table tr td.range.today:hover[disabled],
|
|
||||||
.datepicker table tr td.range.today.disabled[disabled],
|
|
||||||
.datepicker table tr td.range.today.disabled:hover[disabled] {
|
|
||||||
background-color: #f3e97a;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.range.today:active,
|
|
||||||
.datepicker table tr td.range.today:hover:active,
|
|
||||||
.datepicker table tr td.range.today.disabled:active,
|
|
||||||
.datepicker table tr td.range.today.disabled:hover:active,
|
|
||||||
.datepicker table tr td.range.today.active,
|
|
||||||
.datepicker table tr td.range.today:hover.active,
|
|
||||||
.datepicker table tr td.range.today.disabled.active,
|
|
||||||
.datepicker table tr td.range.today.disabled:hover.active {
|
|
||||||
background-color: #efe24b \9;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.selected,
|
|
||||||
.datepicker table tr td.selected:hover,
|
|
||||||
.datepicker table tr td.selected.disabled,
|
|
||||||
.datepicker table tr td.selected.disabled:hover {
|
|
||||||
background-color: #9e9e9e;
|
|
||||||
background-image: -moz-linear-gradient(top, #b3b3b3, #808080);
|
|
||||||
background-image: -ms-linear-gradient(top, #b3b3b3, #808080);
|
|
||||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
|
|
||||||
background-image: -webkit-linear-gradient(top, #b3b3b3, #808080);
|
|
||||||
background-image: -o-linear-gradient(top, #b3b3b3, #808080);
|
|
||||||
background-image: linear-gradient(top, #b3b3b3, #808080);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
|
|
||||||
border-color: #808080 #808080 #595959;
|
|
||||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
.datepicker table tr td.selected:hover,
|
|
||||||
.datepicker table tr td.selected:hover:hover,
|
|
||||||
.datepicker table tr td.selected.disabled:hover,
|
|
||||||
.datepicker table tr td.selected.disabled:hover:hover,
|
|
||||||
.datepicker table tr td.selected:active,
|
|
||||||
.datepicker table tr td.selected:hover:active,
|
|
||||||
.datepicker table tr td.selected.disabled:active,
|
|
||||||
.datepicker table tr td.selected.disabled:hover:active,
|
|
||||||
.datepicker table tr td.selected.active,
|
|
||||||
.datepicker table tr td.selected:hover.active,
|
|
||||||
.datepicker table tr td.selected.disabled.active,
|
|
||||||
.datepicker table tr td.selected.disabled:hover.active,
|
|
||||||
.datepicker table tr td.selected.disabled,
|
|
||||||
.datepicker table tr td.selected:hover.disabled,
|
|
||||||
.datepicker table tr td.selected.disabled.disabled,
|
|
||||||
.datepicker table tr td.selected.disabled:hover.disabled,
|
|
||||||
.datepicker table tr td.selected[disabled],
|
|
||||||
.datepicker table tr td.selected:hover[disabled],
|
|
||||||
.datepicker table tr td.selected.disabled[disabled],
|
|
||||||
.datepicker table tr td.selected.disabled:hover[disabled] {
|
|
||||||
background-color: #808080;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.selected:active,
|
|
||||||
.datepicker table tr td.selected:hover:active,
|
|
||||||
.datepicker table tr td.selected.disabled:active,
|
|
||||||
.datepicker table tr td.selected.disabled:hover:active,
|
|
||||||
.datepicker table tr td.selected.active,
|
|
||||||
.datepicker table tr td.selected:hover.active,
|
|
||||||
.datepicker table tr td.selected.disabled.active,
|
|
||||||
.datepicker table tr td.selected.disabled:hover.active {
|
|
||||||
background-color: #666666 \9;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.active,
|
|
||||||
.datepicker table tr td.active:hover,
|
|
||||||
.datepicker table tr td.active.disabled,
|
|
||||||
.datepicker table tr td.active.disabled:hover {
|
|
||||||
background-color: #006dcc;
|
|
||||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
|
||||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-image: linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
|
||||||
border-color: #0044cc #0044cc #002a80;
|
|
||||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
.datepicker table tr td.active:hover,
|
|
||||||
.datepicker table tr td.active:hover:hover,
|
|
||||||
.datepicker table tr td.active.disabled:hover,
|
|
||||||
.datepicker table tr td.active.disabled:hover:hover,
|
|
||||||
.datepicker table tr td.active:active,
|
|
||||||
.datepicker table tr td.active:hover:active,
|
|
||||||
.datepicker table tr td.active.disabled:active,
|
|
||||||
.datepicker table tr td.active.disabled:hover:active,
|
|
||||||
.datepicker table tr td.active.active,
|
|
||||||
.datepicker table tr td.active:hover.active,
|
|
||||||
.datepicker table tr td.active.disabled.active,
|
|
||||||
.datepicker table tr td.active.disabled:hover.active,
|
|
||||||
.datepicker table tr td.active.disabled,
|
|
||||||
.datepicker table tr td.active:hover.disabled,
|
|
||||||
.datepicker table tr td.active.disabled.disabled,
|
|
||||||
.datepicker table tr td.active.disabled:hover.disabled,
|
|
||||||
.datepicker table tr td.active[disabled],
|
|
||||||
.datepicker table tr td.active:hover[disabled],
|
|
||||||
.datepicker table tr td.active.disabled[disabled],
|
|
||||||
.datepicker table tr td.active.disabled:hover[disabled] {
|
|
||||||
background-color: #0044cc;
|
|
||||||
}
|
|
||||||
.datepicker table tr td.active:active,
|
|
||||||
.datepicker table tr td.active:hover:active,
|
|
||||||
.datepicker table tr td.active.disabled:active,
|
|
||||||
.datepicker table tr td.active.disabled:hover:active,
|
|
||||||
.datepicker table tr td.active.active,
|
|
||||||
.datepicker table tr td.active:hover.active,
|
|
||||||
.datepicker table tr td.active.disabled.active,
|
|
||||||
.datepicker table tr td.active.disabled:hover.active {
|
|
||||||
background-color: #003399 \9;
|
|
||||||
}
|
|
||||||
.datepicker table tr td span {
|
|
||||||
display: block;
|
|
||||||
width: 23%;
|
|
||||||
height: 54px;
|
|
||||||
line-height: 54px;
|
|
||||||
float: left;
|
|
||||||
margin: 1%;
|
|
||||||
cursor: pointer;
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
.datepicker table tr td span:hover {
|
|
||||||
background: #eeeeee;
|
|
||||||
}
|
|
||||||
.datepicker table tr td span.disabled,
|
|
||||||
.datepicker table tr td span.disabled:hover {
|
|
||||||
background: none;
|
|
||||||
color: #999999;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
.datepicker table tr td span.active,
|
|
||||||
.datepicker table tr td span.active:hover,
|
|
||||||
.datepicker table tr td span.active.disabled,
|
|
||||||
.datepicker table tr td span.active.disabled:hover {
|
|
||||||
background-color: #006dcc;
|
|
||||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
|
||||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-image: linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
|
||||||
border-color: #0044cc #0044cc #002a80;
|
|
||||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
.datepicker table tr td span.active:hover,
|
|
||||||
.datepicker table tr td span.active:hover:hover,
|
|
||||||
.datepicker table tr td span.active.disabled:hover,
|
|
||||||
.datepicker table tr td span.active.disabled:hover:hover,
|
|
||||||
.datepicker table tr td span.active:active,
|
|
||||||
.datepicker table tr td span.active:hover:active,
|
|
||||||
.datepicker table tr td span.active.disabled:active,
|
|
||||||
.datepicker table tr td span.active.disabled:hover:active,
|
|
||||||
.datepicker table tr td span.active.active,
|
|
||||||
.datepicker table tr td span.active:hover.active,
|
|
||||||
.datepicker table tr td span.active.disabled.active,
|
|
||||||
.datepicker table tr td span.active.disabled:hover.active,
|
|
||||||
.datepicker table tr td span.active.disabled,
|
|
||||||
.datepicker table tr td span.active:hover.disabled,
|
|
||||||
.datepicker table tr td span.active.disabled.disabled,
|
|
||||||
.datepicker table tr td span.active.disabled:hover.disabled,
|
|
||||||
.datepicker table tr td span.active[disabled],
|
|
||||||
.datepicker table tr td span.active:hover[disabled],
|
|
||||||
.datepicker table tr td span.active.disabled[disabled],
|
|
||||||
.datepicker table tr td span.active.disabled:hover[disabled] {
|
|
||||||
background-color: #0044cc;
|
|
||||||
}
|
|
||||||
.datepicker table tr td span.active:active,
|
|
||||||
.datepicker table tr td span.active:hover:active,
|
|
||||||
.datepicker table tr td span.active.disabled:active,
|
|
||||||
.datepicker table tr td span.active.disabled:hover:active,
|
|
||||||
.datepicker table tr td span.active.active,
|
|
||||||
.datepicker table tr td span.active:hover.active,
|
|
||||||
.datepicker table tr td span.active.disabled.active,
|
|
||||||
.datepicker table tr td span.active.disabled:hover.active {
|
|
||||||
background-color: #003399 \9;
|
|
||||||
}
|
|
||||||
.datepicker table tr td span.old,
|
|
||||||
.datepicker table tr td span.new {
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
.datepicker th.datepicker-switch {
|
|
||||||
width: 145px;
|
|
||||||
}
|
|
||||||
.datepicker thead tr:first-child th,
|
|
||||||
.datepicker tfoot tr th {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.datepicker thead tr:first-child th:hover,
|
|
||||||
.datepicker tfoot tr th:hover {
|
|
||||||
background: #eeeeee;
|
|
||||||
}
|
|
||||||
.datepicker .cw {
|
|
||||||
font-size: 10px;
|
|
||||||
width: 12px;
|
|
||||||
padding: 0 2px 0 5px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.datepicker thead tr:first-child th.cw {
|
|
||||||
cursor: default;
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
.input-append.date .add-on i,
|
|
||||||
.input-prepend.date .add-on i {
|
|
||||||
display: block;
|
|
||||||
cursor: pointer;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
.input-daterange input {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.input-daterange input:first-child {
|
|
||||||
-webkit-border-radius: 3px 0 0 3px;
|
|
||||||
-moz-border-radius: 3px 0 0 3px;
|
|
||||||
border-radius: 3px 0 0 3px;
|
|
||||||
}
|
|
||||||
.input-daterange input:last-child {
|
|
||||||
-webkit-border-radius: 0 3px 3px 0;
|
|
||||||
-moz-border-radius: 0 3px 3px 0;
|
|
||||||
border-radius: 0 3px 3px 0;
|
|
||||||
}
|
|
||||||
.input-daterange .add-on {
|
|
||||||
display: inline-block;
|
|
||||||
width: auto;
|
|
||||||
min-width: 16px;
|
|
||||||
height: 18px;
|
|
||||||
padding: 4px 5px;
|
|
||||||
font-weight: normal;
|
|
||||||
line-height: 18px;
|
|
||||||
text-align: center;
|
|
||||||
text-shadow: 0 1px 0 #ffffff;
|
|
||||||
vertical-align: middle;
|
|
||||||
background-color: #eeeeee;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
margin-left: -5px;
|
|
||||||
margin-right: -5px;
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,189 +1,146 @@
|
||||||
/* eslint-disable no-unused-vars */
|
/**
|
||||||
/**
|
* @author zhixin wen <wenzhixin2010@gmail.com>
|
||||||
* @author zhixin wen <wenzhixin2010@gmail.com>
|
* extensions: https://github.com/vitalets/x-editable
|
||||||
* extensions: https://github.com/vitalets/x-editable
|
*/
|
||||||
*/
|
|
||||||
|
(function($) {
|
||||||
var Utils = $.fn.bootstrapTable.utils
|
|
||||||
|
'use strict';
|
||||||
$.extend($.fn.bootstrapTable.defaults, {
|
|
||||||
editable: true,
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
onEditableInit () {
|
editable: true,
|
||||||
return false
|
onEditableInit: function() {
|
||||||
},
|
return false;
|
||||||
onEditableSave (field, row, rowIndex, oldValue, $el) {
|
},
|
||||||
return false
|
onEditableSave: function(field, row, oldValue, $el) {
|
||||||
},
|
return false;
|
||||||
onEditableShown (field, row, $el, editable) {
|
},
|
||||||
return false
|
onEditableShown: function(field, row, $el, editable) {
|
||||||
},
|
return false;
|
||||||
onEditableHidden (field, row, $el, reason) {
|
},
|
||||||
return false
|
onEditableHidden: function(field, row, $el, reason) {
|
||||||
}
|
return false;
|
||||||
})
|
}
|
||||||
|
});
|
||||||
$.extend($.fn.bootstrapTable.columnDefaults, {
|
|
||||||
alwaysUseFormatter: false
|
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
||||||
})
|
'editable-init.bs.table': 'onEditableInit',
|
||||||
|
'editable-save.bs.table': 'onEditableSave',
|
||||||
$.extend($.fn.bootstrapTable.events, {
|
'editable-shown.bs.table': 'onEditableShown',
|
||||||
'editable-init.bs.table': 'onEditableInit',
|
'editable-hidden.bs.table': 'onEditableHidden'
|
||||||
'editable-save.bs.table': 'onEditableSave',
|
});
|
||||||
'editable-shown.bs.table': 'onEditableShown',
|
|
||||||
'editable-hidden.bs.table': 'onEditableHidden'
|
var BootstrapTable = $.fn.bootstrapTable.Constructor,
|
||||||
})
|
_initTable = BootstrapTable.prototype.initTable,
|
||||||
|
_initBody = BootstrapTable.prototype.initBody;
|
||||||
$.BootstrapTable = class extends $.BootstrapTable {
|
|
||||||
initTable () {
|
BootstrapTable.prototype.initTable = function() {
|
||||||
super.initTable()
|
var that = this;
|
||||||
|
_initTable.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
if (!this.options.editable) {
|
|
||||||
return
|
if (!this.options.editable) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
this.editedCells = []
|
|
||||||
$.each(this.columns, (i, column) => {
|
$.each(this.columns, function(i, column) {
|
||||||
if (!column.editable) {
|
if (!column.editable) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const editableOptions = {}
|
var editableOptions = {},
|
||||||
const editableDataMarkup = []
|
editableDataMarkup = [],
|
||||||
const editableDataPrefix = 'editable-'
|
editableDataPrefix = 'editable-';
|
||||||
const processDataOptions = (key, value) => {
|
|
||||||
// Replace camel case with dashes.
|
var processDataOptions = function(key, value) {
|
||||||
const dashKey = key.replace(/([A-Z])/g, $1 => `-${$1.toLowerCase()}`)
|
// Replace camel case with dashes.
|
||||||
|
var dashKey = key.replace(/([A-Z])/g, function($1) {
|
||||||
if (dashKey.indexOf(editableDataPrefix) === 0) {
|
return "-" + $1.toLowerCase();
|
||||||
editableOptions[dashKey.replace(editableDataPrefix, 'data-')] = value
|
});
|
||||||
}
|
if (dashKey.slice(0, editableDataPrefix.length) == editableDataPrefix) {
|
||||||
}
|
var dataKey = dashKey.replace(editableDataPrefix, 'data-');
|
||||||
|
editableOptions[dataKey] = value;
|
||||||
$.each(this.options, processDataOptions)
|
}
|
||||||
|
};
|
||||||
column.formatter = column.formatter || (value => value)
|
|
||||||
column._formatter = column._formatter ? column._formatter : column.formatter
|
$.each(that.options, processDataOptions);
|
||||||
column.formatter = (value, row, index, field) => {
|
|
||||||
let result = Utils.calculateObjectValue(column, column._formatter, [value, row, index], value)
|
column.formatter = column.formatter || function(value, row, index) {
|
||||||
|
return value;
|
||||||
result = typeof result === 'undefined' || result === null ? this.options.undefinedText : result
|
};
|
||||||
if (this.options.uniqueId !== undefined && !column.alwaysUseFormatter) {
|
column._formatter = column._formatter ? column._formatter : column.formatter;
|
||||||
const uniqueId = Utils.getItemField(row, this.options.uniqueId, false)
|
column.formatter = function(value, row, index) {
|
||||||
|
var result = column._formatter ? column._formatter(value, row, index) : value;
|
||||||
if ($.inArray(column.field + uniqueId, this.editedCells) !== -1) {
|
|
||||||
result = value
|
$.each(column, processDataOptions);
|
||||||
}
|
|
||||||
}
|
$.each(editableOptions, function(key, value) {
|
||||||
|
editableDataMarkup.push(' ' + key + '="' + value + '"');
|
||||||
$.each(column, processDataOptions)
|
});
|
||||||
|
|
||||||
$.each(editableOptions, (key, value) => {
|
var _dont_edit_formatter = false;
|
||||||
editableDataMarkup.push(` ${key}="${value}"`)
|
if (column.editable.hasOwnProperty('noeditFormatter')) {
|
||||||
})
|
_dont_edit_formatter = column.editable.noeditFormatter(value, row, index);
|
||||||
|
}
|
||||||
let noEditFormatter = false
|
|
||||||
const editableOpts = Utils.calculateObjectValue(column,
|
if (_dont_edit_formatter === false) {
|
||||||
column.editable, [index, row], {})
|
return ['<a href="javascript:void(0)"',
|
||||||
|
' data-name="' + column.field + '"',
|
||||||
if (editableOpts.hasOwnProperty('noEditFormatter')) {
|
' data-pk="' + row[that.options.idField] + '"',
|
||||||
noEditFormatter = editableOpts.noEditFormatter(value, row, index, field)
|
' data-value="' + result + '"',
|
||||||
}
|
editableDataMarkup.join(''),
|
||||||
|
'>' + '</a>'
|
||||||
if (noEditFormatter === false) {
|
].join('');
|
||||||
return `<a href="javascript:void(0)"
|
} else {
|
||||||
data-name="${column.field}"
|
return _dont_edit_formatter;
|
||||||
data-pk="${row[this.options.idField]}"
|
}
|
||||||
data-value="${result}"
|
|
||||||
${editableDataMarkup.join('')}></a>`
|
};
|
||||||
}
|
});
|
||||||
return noEditFormatter
|
};
|
||||||
}
|
|
||||||
})
|
BootstrapTable.prototype.initBody = function() {
|
||||||
}
|
var that = this;
|
||||||
|
_initBody.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
initBody (fixedScroll) {
|
|
||||||
super.initBody(fixedScroll)
|
if (!this.options.editable) {
|
||||||
|
return;
|
||||||
if (!this.options.editable) {
|
}
|
||||||
return
|
|
||||||
}
|
$.each(this.columns, function(i, column) {
|
||||||
|
if (!column.editable) {
|
||||||
$.each(this.columns, (i, column) => {
|
return;
|
||||||
if (!column.editable) {
|
}
|
||||||
return
|
|
||||||
}
|
that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable)
|
||||||
|
.off('save').on('save', function(e, params) {
|
||||||
const data = this.getData({ escape: true })
|
var data = that.getData(),
|
||||||
const $field = this.$body.find(`a[data-name="${column.field}"]`)
|
index = $(this).parents('tr[data-index]').data('index'),
|
||||||
|
row = data[index],
|
||||||
$field.each((i, element) => {
|
oldValue = row[column.field];
|
||||||
const $element = $(element)
|
|
||||||
const $tr = $element.closest('tr')
|
$(this).data('value', params.submitValue);
|
||||||
const index = $tr.data('index')
|
row[column.field] = params.submitValue;
|
||||||
const row = data[index]
|
that.trigger('editable-save', column.field, row, oldValue, $(this));
|
||||||
|
that.resetFooter();
|
||||||
const editableOpts = Utils.calculateObjectValue(column,
|
});
|
||||||
column.editable, [index, row, $element], {})
|
that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable)
|
||||||
|
.off('shown').on('shown', function(e, editable) {
|
||||||
$element.editable(editableOpts)
|
var data = that.getData(),
|
||||||
})
|
index = $(this).parents('tr[data-index]').data('index'),
|
||||||
|
row = data[index];
|
||||||
$field.off('save').on('save', ({ currentTarget }, { submitValue }) => {
|
|
||||||
const $this = $(currentTarget)
|
that.trigger('editable-shown', column.field, row, $(this), editable);
|
||||||
const data = this.getData()
|
});
|
||||||
const rowIndex = $this.parents('tr[data-index]').data('index')
|
that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable)
|
||||||
const row = data[rowIndex]
|
.off('hidden').on('hidden', function(e, reason) {
|
||||||
const oldValue = row[column.field]
|
var data = that.getData(),
|
||||||
|
index = $(this).parents('tr[data-index]').data('index'),
|
||||||
if (this.options.uniqueId !== undefined && !column.alwaysUseFormatter) {
|
row = data[index];
|
||||||
const uniqueId = Utils.getItemField(row, this.options.uniqueId, false)
|
|
||||||
|
that.trigger('editable-hidden', column.field, row, $(this), reason);
|
||||||
if ($.inArray(column.field + uniqueId, this.editedCells) === -1) {
|
});
|
||||||
this.editedCells.push(column.field + uniqueId)
|
});
|
||||||
}
|
this.trigger('editable-init');
|
||||||
}
|
};
|
||||||
|
|
||||||
submitValue = Utils.escapeHTML(submitValue)
|
})(jQuery);
|
||||||
$this.data('value', submitValue)
|
|
||||||
row[column.field] = submitValue
|
|
||||||
this.trigger('editable-save', column.field, row, rowIndex, oldValue, $this)
|
|
||||||
this.initBody()
|
|
||||||
})
|
|
||||||
|
|
||||||
$field.off('shown').on('shown', ({ currentTarget }, editable) => {
|
|
||||||
const $this = $(currentTarget)
|
|
||||||
const data = this.getData()
|
|
||||||
const rowIndex = $this.parents('tr[data-index]').data('index')
|
|
||||||
const row = data[rowIndex]
|
|
||||||
|
|
||||||
this.trigger('editable-shown', column.field, row, $this, editable)
|
|
||||||
})
|
|
||||||
|
|
||||||
$field.off('hidden').on('hidden', ({ currentTarget }, reason) => {
|
|
||||||
const $this = $(currentTarget)
|
|
||||||
const data = this.getData()
|
|
||||||
const rowIndex = $this.parents('tr[data-index]').data('index')
|
|
||||||
const row = data[rowIndex]
|
|
||||||
|
|
||||||
this.trigger('editable-hidden', column.field, row, $this, reason)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
this.trigger('editable-init')
|
|
||||||
}
|
|
||||||
|
|
||||||
getData (params) {
|
|
||||||
const data = super.getData(params)
|
|
||||||
|
|
||||||
if (params && params.escape) {
|
|
||||||
for (const row of data) {
|
|
||||||
for (const [key, value] of Object.entries(row)) {
|
|
||||||
if (typeof(value) !== "number") {
|
|
||||||
row[key] = Utils.unescapeHTML(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
* bootstrap-table - v1.11.0 - 2016-07-02
|
||||||
|
* https://github.com/wenzhixin/bootstrap-table
|
||||||
|
* Copyright (c) 2016 zhixin wen
|
||||||
|
* Licensed MIT License
|
||||||
|
*/
|
||||||
|
!function(a){"use strict";a.extend(a.fn.bootstrapTable.defaults,{editable:!0,onEditableInit:function(){return!1},onEditableSave:function(){return!1},onEditableShown:function(){return!1},onEditableHidden:function(){return!1}}),a.extend(a.fn.bootstrapTable.Constructor.EVENTS,{"editable-init.bs.table":"onEditableInit","editable-save.bs.table":"onEditableSave","editable-shown.bs.table":"onEditableShown","editable-hidden.bs.table":"onEditableHidden"});var b=a.fn.bootstrapTable.Constructor,c=b.prototype.initTable,d=b.prototype.initBody;b.prototype.initTable=function(){var b=this;c.apply(this,Array.prototype.slice.apply(arguments)),this.options.editable&&a.each(this.columns,function(c,d){if(d.editable){var e={},f=[],g="editable-",h=function(a,b){var c=a.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()});if(c.slice(0,g.length)==g){var d=c.replace(g,"data-");e[d]=b}};a.each(b.options,h),d.formatter=d.formatter||function(a){return a},d._formatter=d._formatter?d._formatter:d.formatter,d.formatter=function(c,g,i){var j=d._formatter?d._formatter(c,g,i):c;a.each(d,h),a.each(e,function(a,b){f.push(" "+a+'="'+b+'"')});var k=!1;return d.editable.hasOwnProperty("noeditFormatter")&&(k=d.editable.noeditFormatter(c,g,i)),k===!1?['<a href="javascript:void(0)"',' data-name="'+d.field+'"',' data-pk="'+g[b.options.idField]+'"',' data-value="'+j+'"',f.join(""),"></a>"].join(""):k}}})},b.prototype.initBody=function(){var b=this;d.apply(this,Array.prototype.slice.apply(arguments)),this.options.editable&&(a.each(this.columns,function(c,d){d.editable&&(b.$body.find('a[data-name="'+d.field+'"]').editable(d.editable).off("save").on("save",function(c,e){var f=b.getData(),g=a(this).parents("tr[data-index]").data("index"),h=f[g],i=h[d.field];a(this).data("value",e.submitValue),h[d.field]=e.submitValue,b.trigger("editable-save",d.field,h,i,a(this)),b.resetFooter()}),b.$body.find('a[data-name="'+d.field+'"]').editable(d.editable).off("shown").on("shown",function(c,e){var f=b.getData(),g=a(this).parents("tr[data-index]").data("index"),h=f[g];b.trigger("editable-shown",d.field,h,a(this),e)}),b.$body.find('a[data-name="'+d.field+'"]').editable(d.editable).off("hidden").on("hidden",function(c,e){var f=b.getData(),g=a(this).parents("tr[data-index]").data("index"),h=f[g];b.trigger("editable-hidden",d.field,h,a(this),e)}))}),this.trigger("editable-init"))}}(jQuery);
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 244 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
|
|
@ -1,335 +1,119 @@
|
||||||
/**
|
/**
|
||||||
* @author zhixin wen <wenzhixin2010@gmail.com>
|
* @author zhixin wen <wenzhixin2010@gmail.com>
|
||||||
* extensions: https://github.com/hhurz/tableExport.jquery.plugin
|
* extensions: https://github.com/kayalshri/tableExport.jquery.plugin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Utils = $.fn.bootstrapTable.utils
|
(function ($) {
|
||||||
|
'use strict';
|
||||||
const TYPE_NAME = {
|
var sprintf = $.fn.bootstrapTable.utils.sprintf;
|
||||||
json: 'JSON',
|
|
||||||
xml: 'XML',
|
var TYPE_NAME = {
|
||||||
png: 'PNG',
|
csv: 'CSV',
|
||||||
csv: 'CSV',
|
txt: 'TXT',
|
||||||
txt: 'TXT',
|
doc: 'Word',
|
||||||
sql: 'SQL',
|
excel: 'Excel'
|
||||||
doc: 'MS-Word',
|
};
|
||||||
excel: 'MS-Excel',
|
|
||||||
xlsx: 'MS-Excel (OpenXML)',
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
powerpoint: 'MS-Powerpoint',
|
showExport: false,
|
||||||
pdf: 'PDF'
|
exportDataType: 'all', // basic, all, selected
|
||||||
}
|
exportTypes: ['csv', 'txt', 'doc', 'excel'],
|
||||||
|
exportOptions: {
|
||||||
Object.assign($.fn.bootstrapTable.defaults, {
|
ignoreColumn: [0] //忽略列索引
|
||||||
showExport: false,
|
}
|
||||||
exportDataType: 'basic', // basic, all, selected
|
});
|
||||||
exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'],
|
|
||||||
exportOptions: {},
|
$.extend($.fn.bootstrapTable.defaults.icons, {
|
||||||
exportFooter: false
|
export: 'glyphicon glyphicon-save'
|
||||||
})
|
});
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.columnDefaults, {
|
$.extend($.fn.bootstrapTable.locales, {
|
||||||
forceExport: false,
|
formatExport: function () {
|
||||||
forceHide: false
|
return 'Export data';
|
||||||
})
|
}
|
||||||
|
});
|
||||||
Object.assign($.fn.bootstrapTable.defaults.icons, {
|
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
|
||||||
export: {
|
|
||||||
bootstrap3: 'glyphicon-export icon-share',
|
var BootstrapTable = $.fn.bootstrapTable.Constructor,
|
||||||
bootstrap5: 'bi-download',
|
_initToolbar = BootstrapTable.prototype.initToolbar;
|
||||||
materialize: 'file_download',
|
|
||||||
'bootstrap-table': 'icon-download'
|
BootstrapTable.prototype.initToolbar = function () {
|
||||||
}[$.fn.bootstrapTable.theme] || 'fa-download'
|
this.showToolbar = this.options.showExport;
|
||||||
})
|
|
||||||
|
_initToolbar.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
Object.assign($.fn.bootstrapTable.locales, {
|
|
||||||
formatExport () {
|
if (this.options.showExport) {
|
||||||
return 'Export data'
|
var that = this,
|
||||||
}
|
$btnGroup = this.$toolbar.find('>.btn-group'),
|
||||||
})
|
$export = $btnGroup.find('div.export');
|
||||||
Object.assign($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
|
|
||||||
|
if (!$export.length) {
|
||||||
$.fn.bootstrapTable.methods.push('exportTable')
|
$export = $([
|
||||||
|
'<div class="export btn-group">',
|
||||||
Object.assign($.fn.bootstrapTable.defaults, {
|
'<button class="btn' +
|
||||||
// eslint-disable-next-line no-unused-vars
|
sprintf(' btn-%s', this.options.buttonsClass) +
|
||||||
onExportSaved (exportedRows) {
|
sprintf(' btn-%s', this.options.iconSize) +
|
||||||
return false
|
' dropdown-toggle" ' +
|
||||||
},
|
'title="' + this.options.formatExport() + '" ' +
|
||||||
onExportStarted () {
|
'data-toggle="dropdown" type="button">',
|
||||||
return false
|
sprintf('<i class="%s %s"></i> ', this.options.iconsPrefix, this.options.icons.export),
|
||||||
}
|
'<span class="caret"></span>',
|
||||||
})
|
'</button>',
|
||||||
|
'<ul class="dropdown-menu" role="menu">',
|
||||||
Object.assign($.fn.bootstrapTable.events, {
|
'</ul>',
|
||||||
'export-saved.bs.table': 'onExportSaved',
|
'</div>'].join('')).appendTo($btnGroup);
|
||||||
'export-started.bs.table': 'onExportStarted'
|
|
||||||
})
|
var $menu = $export.find('.dropdown-menu'),
|
||||||
|
exportTypes = this.options.exportTypes;
|
||||||
$.BootstrapTable = class extends $.BootstrapTable {
|
|
||||||
initToolbar (...args) {
|
if (typeof this.options.exportTypes === 'string') {
|
||||||
const o = this.options
|
var types = this.options.exportTypes.slice(1, -1).replace(/ /g, '').split(',');
|
||||||
let exportTypes = o.exportTypes
|
|
||||||
|
exportTypes = [];
|
||||||
this.showToolbar = this.showToolbar || o.showExport
|
$.each(types, function (i, value) {
|
||||||
|
exportTypes.push(value.slice(1, -1));
|
||||||
if (this.options.showExport) {
|
});
|
||||||
|
}
|
||||||
if (typeof exportTypes === 'string') {
|
$.each(exportTypes, function (i, type) {
|
||||||
const types = exportTypes.slice(1, -1).replace(/ /g, '').split(',')
|
if (TYPE_NAME.hasOwnProperty(type)) {
|
||||||
|
$menu.append(['<li data-type="' + type + '">',
|
||||||
exportTypes = types.map(t => t.slice(1, -1))
|
'<a href="javascript:void(0)">',
|
||||||
}
|
TYPE_NAME[type],
|
||||||
|
'</a>',
|
||||||
if (typeof o.exportOptions === 'string') {
|
'</li>'].join(''));
|
||||||
o.exportOptions = Utils.calculateObjectValue(null, o.exportOptions)
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
this.$export = this.$toolbar.find('>.columns div.export')
|
$menu.find('li').click(function () {
|
||||||
if (this.$export.length) {
|
var type = $(this).data('type'),
|
||||||
this.updateExportButton()
|
doExport = function () {
|
||||||
return
|
that.$el.tableExport($.extend({}, that.options.exportOptions, {
|
||||||
}
|
type: type,
|
||||||
|
escape: false
|
||||||
this.buttons = Object.assign(this.buttons, {
|
}));
|
||||||
export: {
|
};
|
||||||
html:
|
|
||||||
() => {
|
if (that.options.exportDataType === 'all' && that.options.pagination) {
|
||||||
if (exportTypes.length === 1) {
|
that.$el.one(that.options.sidePagination === 'server' ? 'post-body.bs.table' : 'page-change.bs.table', function () {
|
||||||
return `
|
doExport();
|
||||||
<div class="export ${this.constants.classes.buttonsDropdown}"
|
that.togglePagination();
|
||||||
data-type="${exportTypes[0]}">
|
});
|
||||||
<button class="${this.constants.buttonsClass}"
|
that.togglePagination();
|
||||||
aria-label="${o.formatExport()}"
|
} else if (that.options.exportDataType === 'selected') {
|
||||||
type="button"
|
//修改sidePagination属性为server无法导出选中数据
|
||||||
title="${o.formatExport()}">
|
var trs = that.$body.children();
|
||||||
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
|
for (var i = 0; i < trs.length; i++) {
|
||||||
${o.showButtonText ? o.formatExport() : ''}
|
var $this = $(trs[i]);
|
||||||
</button>
|
if(!$this.find(sprintf('[name="%s"]',that.options.selectItemName)).prop('checked')){
|
||||||
</div>
|
$this['hide']();
|
||||||
`
|
}}
|
||||||
}
|
doExport();
|
||||||
|
that.getRowsHidden(true);
|
||||||
const html = []
|
} else {
|
||||||
|
doExport();
|
||||||
html.push(`
|
}
|
||||||
<div class="export ${this.constants.classes.buttonsDropdown}">
|
});
|
||||||
<button class="${this.constants.buttonsClass} dropdown-toggle"
|
}
|
||||||
aria-label="${o.formatExport()}"
|
}
|
||||||
${this.constants.dataToggle}="dropdown"
|
};
|
||||||
type="button"
|
})(jQuery);
|
||||||
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('')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
super.initToolbar(...args)
|
|
||||||
this.$export = this.$toolbar.find('>.columns div.export')
|
|
||||||
|
|
||||||
if (!this.options.showExport) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateExportButton()
|
|
||||||
let $exportButtons = this.$export.find('[data-type]')
|
|
||||||
|
|
||||||
if (exportTypes.length === 1) {
|
|
||||||
$exportButtons = this.$export
|
|
||||||
}
|
|
||||||
|
|
||||||
$exportButtons.click(e => {
|
|
||||||
e.preventDefault()
|
|
||||||
this.trigger('export-started')
|
|
||||||
this.exportTable({
|
|
||||||
type: $(e.currentTarget).data('type')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
this.handleToolbar()
|
|
||||||
}
|
|
||||||
|
|
||||||
handleToolbar () {
|
|
||||||
if (!this.$export) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (super.handleToolbar) {
|
|
||||||
super.handleToolbar()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exportTable (options) {
|
|
||||||
const o = this.options
|
|
||||||
const stateField = this.header.stateField
|
|
||||||
const isCardView = o.cardView
|
|
||||||
|
|
||||||
const doExport = callback => {
|
|
||||||
if (stateField) {
|
|
||||||
this.hideColumn(stateField)
|
|
||||||
}
|
|
||||||
if (isCardView) {
|
|
||||||
this.toggleView()
|
|
||||||
}
|
|
||||||
|
|
||||||
this.columns.forEach(row => {
|
|
||||||
if (row.forceHide) {
|
|
||||||
this.hideColumn(row.field)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const data = this.getData()
|
|
||||||
|
|
||||||
if (o.detailView && o.detailViewIcon) {
|
|
||||||
const detailViewIndex = o.detailViewAlign === 'left' ? 0 : this.getVisibleFields().length + Utils.getDetailViewIndexOffset(this.options)
|
|
||||||
|
|
||||||
o.exportOptions.ignoreColumn = [detailViewIndex].concat(o.exportOptions.ignoreColumn || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o.exportFooter && o.height) {
|
|
||||||
const $footerRow = this.$tableFooter.find('tr').first()
|
|
||||||
const footerData = {}
|
|
||||||
const footerHtml = []
|
|
||||||
|
|
||||||
$.each($footerRow.children(), (index, footerCell) => {
|
|
||||||
const footerCellHtml = $(footerCell).children('.th-inner').first().html()
|
|
||||||
|
|
||||||
footerData[this.columns[index].field] = footerCellHtml === ' ' ? null : footerCellHtml
|
|
||||||
|
|
||||||
// grab footer cell text into cell index-based array
|
|
||||||
footerHtml.push(footerCellHtml)
|
|
||||||
})
|
|
||||||
|
|
||||||
this.$body.append(this.$body.children().last()[0].outerHTML)
|
|
||||||
const $lastTableRow = this.$body.children().last()
|
|
||||||
|
|
||||||
$.each($lastTableRow.children(), (index, lastTableRowCell) => {
|
|
||||||
$(lastTableRowCell).html(footerHtml[index])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const hiddenColumns = this.getHiddenColumns()
|
|
||||||
|
|
||||||
hiddenColumns.forEach(row => {
|
|
||||||
if (row.forceExport) {
|
|
||||||
this.showColumn(row.field)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (typeof o.exportOptions.fileName === 'function') {
|
|
||||||
options.fileName = o.exportOptions.fileName()
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$el.tableExport(Utils.extend({
|
|
||||||
onAfterSaveToFile: () => {
|
|
||||||
if (o.exportFooter) {
|
|
||||||
this.load(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stateField) {
|
|
||||||
this.showColumn(stateField)
|
|
||||||
}
|
|
||||||
if (isCardView) {
|
|
||||||
this.toggleView()
|
|
||||||
}
|
|
||||||
|
|
||||||
hiddenColumns.forEach(row => {
|
|
||||||
if (row.forceExport) {
|
|
||||||
this.hideColumn(row.field)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
this.columns.forEach(row => {
|
|
||||||
if (row.forceHide) {
|
|
||||||
this.showColumn(row.field)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (callback) callback()
|
|
||||||
}
|
|
||||||
}, o.exportOptions, options))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o.exportDataType === 'all' && o.pagination) {
|
|
||||||
const eventName = o.sidePagination === 'server' ?
|
|
||||||
'post-body.bs.table' : 'page-change.bs.table'
|
|
||||||
const virtualScroll = this.options.virtualScroll
|
|
||||||
|
|
||||||
this.$el.one(eventName, () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
const data = this.getData()
|
|
||||||
|
|
||||||
doExport(() => {
|
|
||||||
this.options.virtualScroll = virtualScroll
|
|
||||||
this.togglePagination()
|
|
||||||
})
|
|
||||||
this.trigger('export-saved', data)
|
|
||||||
}, 0)
|
|
||||||
})
|
|
||||||
this.options.virtualScroll = false
|
|
||||||
this.togglePagination()
|
|
||||||
} else if (o.exportDataType === 'selected') {
|
|
||||||
let data = this.getData()
|
|
||||||
let selectedData = this.getSelections()
|
|
||||||
const pagination = o.pagination
|
|
||||||
|
|
||||||
if (!selectedData.length) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o.sidePagination === 'server') {
|
|
||||||
data = {
|
|
||||||
total: o.totalRows,
|
|
||||||
[this.options.dataField]: data
|
|
||||||
}
|
|
||||||
selectedData = {
|
|
||||||
total: selectedData.length,
|
|
||||||
[this.options.dataField]: selectedData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.load(selectedData)
|
|
||||||
if (pagination) {
|
|
||||||
this.togglePagination()
|
|
||||||
}
|
|
||||||
doExport(() => {
|
|
||||||
if (pagination) {
|
|
||||||
this.togglePagination()
|
|
||||||
}
|
|
||||||
this.load(data)
|
|
||||||
})
|
|
||||||
this.trigger('export-saved', selectedData)
|
|
||||||
} else {
|
|
||||||
doExport()
|
|
||||||
this.trigger('export-saved', this.getData(true))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSelected () {
|
|
||||||
super.updateSelected()
|
|
||||||
this.updateExportButton()
|
|
||||||
}
|
|
||||||
|
|
||||||
updateExportButton () {
|
|
||||||
if (this.options.exportDataType === 'selected') {
|
|
||||||
this.$export.find('> button')
|
|
||||||
.prop('disabled', !this.getSelections().length)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
tableExport.jquery.plugin
|
|
||||||
Version 1.10.24
|
|
||||||
Copyright (c) 2015-2021 hhurz, https://github.com/hhurz/tableExport.jquery.plugin
|
|
||||||
Based on https://github.com/kayalshri/tableExport.jquery.plugin
|
|
||||||
Licensed under the MIT License
|
|
||||||
*/
|
|
||||||
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(d,k,y){d instanceof String&&(d=String(d));for(var C=d.length,v=0;v<C;v++){var R=d[v];if(k.call(y,R,v,d))return{i:v,v:R}}return{i:-1,v:void 0}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(d,k,y){d!=Array.prototype&&d!=Object.prototype&&(d[k]=y.value)};
|
|
||||||
$jscomp.getGlobal=function(d){return"undefined"!=typeof window&&window===d?d:"undefined"!=typeof global&&null!=global?global:d};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(d,k,y,C){if(k){y=$jscomp.global;d=d.split(".");for(C=0;C<d.length-1;C++){var v=d[C];v in y||(y[v]={});y=y[v]}d=d[d.length-1];C=y[d];k=k(C);k!=C&&null!=k&&$jscomp.defineProperty(y,d,{configurable:!0,writable:!0,value:k})}};
|
|
||||||
$jscomp.polyfill("Array.prototype.find",function(d){return d?d:function(d,y){return $jscomp.findInternal(this,d,y).v}},"es6","es3");
|
|
||||||
(function(d){d.fn.tableExport=function(k){function y(b){var c=[];v(b,"thead").each(function(){c.push.apply(c,v(d(this),a.theadSelector).toArray())});return c}function C(b){var c=[];v(b,"tbody").each(function(){c.push.apply(c,v(d(this),a.tbodySelector).toArray())});a.tfootSelector.length&&v(b,"tfoot").each(function(){c.push.apply(c,v(d(this),a.tfootSelector).toArray())});return c}function v(b,a){var c=b[0].tagName,q=b.parents(c).length;return b.find(a).filter(function(){return q===d(this).closest(c).parents(c).length})}
|
|
||||||
function R(b){var a=[],e=0,q=0,f=0;d(b).find("thead").first().find("th").each(function(b,c){b=void 0!==d(c).attr("data-field");"undefined"!==typeof c.parentNode.rowIndex&&q!==c.parentNode.rowIndex&&(q=c.parentNode.rowIndex,e=f=0);var h=J(c);for(e+=h?h:1;f<e;)a[f]=b?d(c).attr("data-field"):f.toString(),f++});return a}function I(b){var a="undefined"!==typeof b[0].rowIndex,e=!1===a&&"undefined"!==typeof b[0].cellIndex,q=e||a?Ja(b):b.is(":visible"),f=b.attr("data-tableexport-display");e&&"none"!==f&&
|
|
||||||
"always"!==f&&(b=d(b[0].parentNode),a="undefined"!==typeof b[0].rowIndex,f=b.attr("data-tableexport-display"));a&&"none"!==f&&"always"!==f&&(f=b.closest("table").attr("data-tableexport-display"));return"none"!==f&&(!0===q||"always"===f)}function Ja(b){var a=[];V&&(a=K.filter(function(){var a=!1;this.nodeType===b[0].nodeType&&("undefined"!==typeof this.rowIndex&&this.rowIndex===b[0].rowIndex?a=!0:"undefined"!==typeof this.cellIndex&&this.cellIndex===b[0].cellIndex&&"undefined"!==typeof this.parentNode.rowIndex&&
|
|
||||||
"undefined"!==typeof b[0].parentNode.rowIndex&&this.parentNode.rowIndex===b[0].parentNode.rowIndex&&(a=!0));return a}));return!1===V||0===a.length}function ta(b,c,e){var q=!1;I(b)?0<a.ignoreColumn.length&&(-1!==d.inArray(e,a.ignoreColumn)||-1!==d.inArray(e-c,a.ignoreColumn)||S.length>e&&"undefined"!==typeof S[e]&&-1!==d.inArray(S[e],a.ignoreColumn))&&(q=!0):q=!0;return q}function E(b,c,e,q,f){if("function"===typeof f){var h=!1;"function"===typeof a.onIgnoreRow&&(h=a.onIgnoreRow(d(b),e));if(!1===h&&
|
|
||||||
(0===a.ignoreRow.length||-1===d.inArray(e,a.ignoreRow)&&-1===d.inArray(e-q,a.ignoreRow))&&I(d(b))){b=v(d(b),c);var n=b.length,l=0,u=0;b.each(function(){var b=d(this),a=J(this),c=T(this),h;d.each(G,function(){if(e>this.s.r&&e<=this.e.r&&l>=this.s.c&&l<=this.e.c)for(h=0;h<=this.e.c-this.s.c;++h)n++,u++,f(null,e,l++)});if(c||a)a=a||1,G.push({s:{r:e,c:l},e:{r:e+(c||1)-1,c:l+a-1}});!1===ta(b,n,u++)&&f(this,e,l++);if(1<a)for(h=0;h<a-1;++h)u++,f(null,e,l++)});d.each(G,function(){if(e>=this.s.r&&e<=this.e.r&&
|
|
||||||
l>=this.s.c&&l<=this.e.c)for(ea=0;ea<=this.e.c-this.s.c;++ea)f(null,e,l++)})}}}function ua(b,a,e,d){if("undefined"!==typeof d.images&&(e=d.images[e],"undefined"!==typeof e)){a=a.getBoundingClientRect();var c=b.width/b.height,h=a.width/a.height,q=b.width,l=b.height,u=19.049976/25.4,g=0;h<=c?(l=Math.min(b.height,a.height),q=a.width*l/a.height):h>c&&(q=Math.min(b.width,a.width),l=a.height*q/a.width);q*=u;l*=u;l<b.height&&(g=(b.height-l)/2);try{d.doc.addImage(e.src,b.textPos.x,b.y+g,q,l)}catch(Pa){}b.textPos.x+=
|
|
||||||
q}}function va(b,c){if("string"===a.outputMode)return b.output();if("base64"===a.outputMode)return L(b.output());if("window"===a.outputMode)window.URL=window.URL||window.webkitURL,window.open(window.URL.createObjectURL(b.output("blob")));else try{var e=b.output("blob");saveAs(e,a.fileName+".pdf")}catch(q){ka(a.fileName+".pdf","data:application/pdf"+(c?"":";base64")+",",c?b.output("blob"):b.output())}}function wa(b,a,e){var c=0;"undefined"!==typeof e&&(c=e.colspan);if(0<=c){for(var f=b.width,d=b.textPos.x,
|
|
||||||
n=a.table.columns.indexOf(a.column),l=1;l<c;l++)f+=a.table.columns[n+l].width;1<c&&("right"===b.styles.halign?d=b.textPos.x+f-b.width:"center"===b.styles.halign&&(d=b.textPos.x+(f-b.width)/2));b.width=f;b.textPos.x=d;"undefined"!==typeof e&&1<e.rowspan&&(b.height*=e.rowspan);if("middle"===b.styles.valign||"bottom"===b.styles.valign)e=("string"===typeof b.text?b.text.split(/\r\n|\r|\n/g):b.text).length||1,2<e&&(b.textPos.y-=(2-1.15)/2*a.row.styles.fontSize*(e-2)/3);return!0}return!1}function xa(b,
|
|
||||||
a,e){"undefined"!==typeof b&&null!==b&&(b.hasAttribute("data-tableexport-canvas")?(a=(new Date).getTime(),d(b).attr("data-tableexport-canvas",a),e.images[a]={url:'[data-tableexport-canvas="'+a+'"]',src:null}):"undefined"!==a&&null!=a&&a.each(function(){if(d(this).is("img")){var a=ya(this.src);e.images[a]={url:this.src,src:this.src}}xa(b,d(this).children(),e)}))}function Ka(b,a){function c(b){if(b.url)if(b.src){var c=new Image;q=++f;c.crossOrigin="Anonymous";c.onerror=c.onload=function(){if(c.complete&&
|
|
||||||
(0===c.src.indexOf("data:image/")&&(c.width=b.width||c.width||0,c.height=b.height||c.height||0),c.width+c.height)){var e=document.createElement("canvas"),d=e.getContext("2d");e.width=c.width;e.height=c.height;d.drawImage(c,0,0);b.src=e.toDataURL("image/png")}--f||a(q)};c.src=b.url}else{var e=d(b.url);e.length&&(q=++f,html2canvas(e[0]).then(function(c){b.src=c.toDataURL("image/png");--f||a(q)}))}}var q=0,f=0;if("undefined"!==typeof b.images)for(var h in b.images)b.images.hasOwnProperty(h)&&c(b.images[h]);
|
|
||||||
(b=f)||(a(q),b=void 0);return b}function za(b,c,e){c.each(function(){if(d(this).is("div")){var c=fa(M(this,"background-color"),[255,255,255]),f=fa(M(this,"border-top-color"),[0,0,0]),h=ha(this,"border-top-width",a.jspdf.unit),n=this.getBoundingClientRect(),l=this.offsetLeft*e.wScaleFactor,u=this.offsetTop*e.hScaleFactor,g=n.width*e.wScaleFactor;n=n.height*e.hScaleFactor;e.doc.setDrawColor.apply(void 0,f);e.doc.setFillColor.apply(void 0,c);e.doc.setLineWidth(h);e.doc.rect(b.x+l,b.y+u,g,n,h?"FD":"F")}else d(this).is("img")&&
|
|
||||||
(c=ya(this.src),ua(b,this,c,e));za(b,d(this).children(),e)})}function Aa(b,c,e){if("function"===typeof e.onAutotableText)e.onAutotableText(e.doc,b,c);else{var q=b.textPos.x,f=b.textPos.y,h={halign:b.styles.halign,valign:b.styles.valign};if(c.length){for(c=c[0];c.previousSibling;)c=c.previousSibling;for(var n=!1,l=!1;c;){var u=c.innerText||c.textContent||"",g=u.length&&" "===u[0]?" ":"",k=1<u.length&&" "===u[u.length-1]?" ":"";!0!==a.preserve.leadingWS&&(u=g+la(u));!0!==a.preserve.trailingWS&&(u=ma(u)+
|
|
||||||
k);d(c).is("br")&&(q=b.textPos.x,f+=e.doc.internal.getFontSize());d(c).is("b")?n=!0:d(c).is("i")&&(l=!0);(n||l)&&e.doc.setFontType(n&&l?"bolditalic":n?"bold":"italic");if(g=e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize()){"linebreak"===b.styles.overflow&&q>b.textPos.x&&q+g>b.textPos.x+b.width&&(0<=".,!%*;:=-".indexOf(u.charAt(0))&&(k=u.charAt(0),g=e.doc.getStringUnitWidth(k)*e.doc.internal.getFontSize(),q+g<=b.textPos.x+b.width&&(e.doc.autoTableText(k,q,f,h),u=u.substring(1,u.length)),g=
|
|
||||||
e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize()),q=b.textPos.x,f+=e.doc.internal.getFontSize());if("visible"!==b.styles.overflow)for(;u.length&&q+g>b.textPos.x+b.width;)u=u.substring(0,u.length-1),g=e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize();e.doc.autoTableText(u,q,f,h);q+=g}if(n||l)d(c).is("b")?n=!1:d(c).is("i")&&(l=!1),e.doc.setFontType(n||l?n?"bold":"italic":"normal");c=c.nextSibling}b.textPos.x=q;b.textPos.y=f}else e.doc.autoTableText(b.text,b.textPos.x,b.textPos.y,h)}}
|
|
||||||
function W(b,a,e){return null==b?"":b.toString().replace(new RegExp(null==a?"":a.toString().replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1"),"g"),e)}function la(b){return null==b?"":b.toString().replace(/^\s+/,"")}function ma(b){return null==b?"":b.toString().replace(/\s+$/,"")}function La(b){if(0===a.date.html.length)return!1;a.date.pattern.lastIndex=0;var c=a.date.pattern.exec(b);if(null==c)return!1;b=+c[a.date.match_y];if(0>b||8099<b)return!1;var e=1*c[a.date.match_m];c=1*c[a.date.match_d];if(!isFinite(c))return!1;
|
|
||||||
var d=new Date(b,e-1,c,0,0,0);return d.getFullYear()===b&&d.getMonth()===e-1&&d.getDate()===c?new Date(Date.UTC(b,e-1,c,0,0,0)):!1}function na(b){b=b||"0";""!==a.numbers.html.thousandsSeparator&&(b=W(b,a.numbers.html.thousandsSeparator,""));"."!==a.numbers.html.decimalMark&&(b=W(b,a.numbers.html.decimalMark,"."));return"number"===typeof b||!1!==jQuery.isNumeric(b)?b:!1}function Ma(b){-1<b.indexOf("%")?(b=na(b.replace(/%/g,"")),!1!==b&&(b/=100)):b=!1;return b}function D(b,c,e,q){var f="",h="text";
|
|
||||||
if(null!==b){var n=d(b);n.removeData("teUserDefText");if(n[0].hasAttribute("data-tableexport-canvas"))var l="";else if(n[0].hasAttribute("data-tableexport-value"))l=(l=n.attr("data-tableexport-value"))?l+"":"",n.data("teUserDefText",1);else if(l=n.html(),"function"===typeof a.onCellHtmlData)l=a.onCellHtmlData(n,c,e,l),n.data("teUserDefText",1);else if(""!==l){b=d.parseHTML(l);var g=0,k=0;l="";d.each(b,function(){if(d(this).is("input"))l+=n.find("input").eq(g++).val();else if(d(this).is("select"))l+=
|
|
||||||
n.find("select option:selected").eq(k++).text();else if(d(this).is("br"))l+="<br>";else{if("undefined"===typeof d(this).html())l+=d(this).text();else if(void 0===jQuery().bootstrapTable||!1===d(this).hasClass("fht-cell")&&!1===d(this).hasClass("filterControl")&&0===n.parents(".detail-view").length)l+=d(this).html();if(d(this).is("a")){var b=n.find("a").attr("href")||"";f="function"===typeof a.onCellHtmlHyperlink?f+a.onCellHtmlHyperlink(n,c,e,b,l):"href"===a.htmlHyperlink?f+b:f+l;l=""}}})}if(l&&""!==
|
|
||||||
l&&!0===a.htmlContent)f=d.trim(l);else if(l&&""!==l)if(""!==n.attr("data-tableexport-cellformat")){var m=l.replace(/\n/g,"\u2028").replace(/(<\s*br([^>]*)>)/gi,"\u2060"),p=d("<div/>").html(m).contents();b=!1;m="";d.each(p.text().split("\u2028"),function(b,c){0<b&&(m+=" ");!0!==a.preserve.leadingWS&&(c=la(c));m+=!0!==a.preserve.trailingWS?ma(c):c});d.each(m.split("\u2060"),function(b,c){0<b&&(f+="\n");!0!==a.preserve.leadingWS&&(c=la(c));!0!==a.preserve.trailingWS&&(c=ma(c));f+=c.replace(/\u00AD/g,
|
|
||||||
"")});f=f.replace(/\u00A0/g," ");if("json"===a.type||"excel"===a.type&&"xmlss"===a.mso.fileFormat||!1===a.numbers.output)b=na(f),!1!==b&&(h="number",f=Number(b));else if(a.numbers.html.decimalMark!==a.numbers.output.decimalMark||a.numbers.html.thousandsSeparator!==a.numbers.output.thousandsSeparator)if(b=na(f),!1!==b){p=(""+b.substr(0>b?1:0)).split(".");1===p.length&&(p[1]="");var t=3<p[0].length?p[0].length%3:0;h="number";f=(0>b?"-":"")+(a.numbers.output.thousandsSeparator?(t?p[0].substr(0,t)+a.numbers.output.thousandsSeparator:
|
|
||||||
"")+p[0].substr(t).replace(/(\d{3})(?=\d)/g,"$1"+a.numbers.output.thousandsSeparator):p[0])+(p[1].length?a.numbers.output.decimalMark+p[1]:"")}}else f=l;!0===a.escape&&(f=escape(f));"function"===typeof a.onCellData&&(f=a.onCellData(n,c,e,f,h),n.data("teUserDefText",1))}void 0!==q&&(q.type=h);return f}function Ba(b){return 0<b.length&&!0===a.preventInjection&&0<="=+-@".indexOf(b.charAt(0))?"'"+b:b}function Na(b,a,e){return a+"-"+e.toLowerCase()}function fa(b,a){(b=/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(b))&&
|
|
||||||
(a=[parseInt(b[1]),parseInt(b[2]),parseInt(b[3])]);return a}function Ca(b){var a=M(b,"text-align"),e=M(b,"font-weight"),d=M(b,"font-style"),f="";"start"===a&&(a="rtl"===M(b,"direction")?"right":"left");700<=e&&(f="bold");"italic"===d&&(f+=d);""===f&&(f="normal");a={style:{align:a,bcolor:fa(M(b,"background-color"),[255,255,255]),color:fa(M(b,"color"),[0,0,0]),fstyle:f},colspan:J(b),rowspan:T(b)};null!==b&&(b=b.getBoundingClientRect(),a.rect={width:b.width,height:b.height});return a}function J(b){var a=
|
|
||||||
d(b).attr("data-tableexport-colspan");"undefined"===typeof a&&d(b).is("[colspan]")&&(a=d(b).attr("colspan"));return parseInt(a)||0}function T(b){var a=d(b).attr("data-tableexport-rowspan");"undefined"===typeof a&&d(b).is("[rowspan]")&&(a=d(b).attr("rowspan"));return parseInt(a)||0}function M(a,c){try{return window.getComputedStyle?(c=c.replace(/([a-z])([A-Z])/,Na),window.getComputedStyle(a,null).getPropertyValue(c)):a.currentStyle?a.currentStyle[c]:a.style[c]}catch(e){}return""}function ha(a,c,e){c=
|
|
||||||
M(a,c).match(/\d+/);if(null!==c){c=c[0];a=a.parentElement;var b=document.createElement("div");b.style.overflow="hidden";b.style.visibility="hidden";a.appendChild(b);b.style.width=100+e;e=100/b.offsetWidth;a.removeChild(b);return c*e}return 0}function Oa(a){for(var b=new ArrayBuffer(a.length),e=new Uint8Array(b),d=0;d!==a.length;++d)e[d]=a.charCodeAt(d)&255;return b}function oa(a){var b=a.c,e="";for(++b;b;b=Math.floor((b-1)/26))e=String.fromCharCode((b-1)%26+65)+e;return e+(""+(a.r+1))}function pa(a,
|
|
||||||
c){if("undefined"===typeof c||"number"===typeof c)return pa(a.s,a.e);"string"!==typeof a&&(a=oa(a));"string"!==typeof c&&(c=oa(c));return a===c?a:a+":"+c}function Da(a,c){var b=Number(a);if(isFinite(b))return b;var d=1;""!==c.thousandsSeparator&&(a=a.replace(new RegExp("([\\d])"+c.thousandsSeparator+"([\\d])","g"),"$1$2"));"."!==c.decimalMark&&(a=a.replace(new RegExp("([\\d])"+c.decimalMark+"([\\d])","g"),"$1.$2"));a=a.replace(/[$]/g,"").replace(/[%]/g,function(){d*=100;return""});if(isFinite(b=Number(a)))return b/
|
|
||||||
d;a=a.replace(/[(](.*)[)]/,function(a,b){d=-d;return b});return isFinite(b=Number(a))?b/d:b}function ya(a){var b=0,d;if(0===a.length)return b;var q=0;for(d=a.length;q<d;q++){var f=a.charCodeAt(q);b=(b<<5)-b+f;b|=0}return b}function N(b,c,d,q,f,h){var e=!0;"function"===typeof a.onBeforeSaveToFile&&(e=a.onBeforeSaveToFile(b,c,d,q,f),"boolean"!==typeof e&&(e=!0));if(e)try{if(Ea=new Blob([b],{type:d+";charset="+q}),saveAs(Ea,c,!1===h),"function"===typeof a.onAfterSaveToFile)a.onAfterSaveToFile(b,c)}catch(l){ka(c,
|
|
||||||
"data:"+d+(q.length?";charset="+q:"")+(f.length?";"+f:"")+",",h?"\ufeff"+b:b)}}function ka(b,c,d){var e=window.navigator.userAgent;if(!1!==b&&window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(new Blob([d]),b);else if(!1!==b&&(0<e.indexOf("MSIE ")||e.match(/Trident.*rv\:11\./))){if(c=document.createElement("iframe")){document.body.appendChild(c);c.setAttribute("style","display:none");c.contentDocument.open("txt/plain","replace");c.contentDocument.write(d);c.contentDocument.close();
|
|
||||||
c.contentWindow.focus();switch(b.substr(b.lastIndexOf(".")+1)){case "doc":case "json":case "png":case "pdf":case "xls":case "xlsx":b+=".txt"}c.contentDocument.execCommand("SaveAs",!0,b);document.body.removeChild(c)}}else{var f=document.createElement("a");if(f){var h=null;f.style.display="none";!1!==b?f.download=b:f.target="_blank";"object"===typeof d?(window.URL=window.URL||window.webkitURL,e=[],e.push(d),h=window.URL.createObjectURL(new Blob(e,{type:c})),f.href=h):0<=c.toLowerCase().indexOf("base64,")?
|
|
||||||
f.href=c+L(d):f.href=c+encodeURIComponent(d);document.body.appendChild(f);if(document.createEvent)null===ia&&(ia=document.createEvent("MouseEvents")),ia.initEvent("click",!0,!1),f.dispatchEvent(ia);else if(document.createEventObject)f.fireEvent("onclick");else if("function"===typeof f.onclick)f.onclick();setTimeout(function(){h&&window.URL.revokeObjectURL(h);document.body.removeChild(f);if("function"===typeof a.onAfterSaveToFile)a.onAfterSaveToFile(d,b)},100)}}}function L(a){var b,d="",q=0;if("string"===
|
|
||||||
typeof a){a=a.replace(/\x0d\x0a/g,"\n");var f="";for(b=0;b<a.length;b++){var h=a.charCodeAt(b);128>h?f+=String.fromCharCode(h):(127<h&&2048>h?f+=String.fromCharCode(h>>6|192):(f+=String.fromCharCode(h>>12|224),f+=String.fromCharCode(h>>6&63|128)),f+=String.fromCharCode(h&63|128))}a=f}for(;q<a.length;){var n=a.charCodeAt(q++);f=a.charCodeAt(q++);b=a.charCodeAt(q++);h=n>>2;n=(n&3)<<4|f>>4;var l=(f&15)<<2|b>>6;var g=b&63;isNaN(f)?l=g=64:isNaN(b)&&(g=64);d=d+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(h)+
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(n)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(l)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(g)}return d}var a={csvEnclosure:'"',csvSeparator:",",csvUseBOM:!0,date:{html:"dd/mm/yyyy"},displayTableName:!1,escape:!1,exportHiddenCells:!1,fileName:"tableExport",htmlContent:!1,htmlHyperlink:"content",ignoreColumn:[],ignoreRow:[],jsonScope:"all",jspdf:{orientation:"p",
|
|
||||||
unit:"pt",format:"a4",margins:{left:20,right:10,top:10,bottom:10},onDocCreated:null,autotable:{styles:{cellPadding:2,rowHeight:12,fontSize:8,fillColor:255,textColor:50,fontStyle:"normal",overflow:"ellipsize",halign:"inherit",valign:"middle"},headerStyles:{fillColor:[52,73,94],textColor:255,fontStyle:"bold",halign:"inherit",valign:"middle"},alternateRowStyles:{fillColor:245},tableExport:{doc:null,onAfterAutotable:null,onBeforeAutotable:null,onAutotableText:null,onTable:null,outputImages:!0}}},mso:{fileFormat:"xlshtml",
|
|
||||||
onMsoNumberFormat:null,pageFormat:"a4",pageOrientation:"portrait",rtl:!1,styles:[],worksheetName:"",xslx:{formatId:{date:14,numbers:2}}},numbers:{html:{decimalMark:".",thousandsSeparator:","},output:{decimalMark:".",thousandsSeparator:","}},onAfterSaveToFile:null,onBeforeSaveToFile:null,onCellData:null,onCellHtmlData:null,onCellHtmlHyperlink:null,onIgnoreRow:null,onTableExportBegin:null,onTableExportEnd:null,outputMode:"file",pdfmake:{enabled:!1,docDefinition:{pageSize:"A4",pageOrientation:"portrait",
|
|
||||||
styles:{header:{background:"#34495E",color:"#FFFFFF",bold:!0,alignment:"center",fillColor:"#34495E"},alternateRow:{fillColor:"#f5f5f5"}},defaultStyle:{color:"#000000",fontSize:8,font:"Roboto"}},fonts:{}},preserve:{leadingWS:!1,trailingWS:!1},preventInjection:!0,sql:{tableEnclosure:"`",columnEnclosure:"`"},tbodySelector:"tr",tfootSelector:"tr",theadSelector:"tr",tableName:"Table",type:"csv"},O={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,
|
|
||||||
595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,
|
|
||||||
161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]},B=this,ia=null,r=[],w=[],p=0,t="",S=[],G=[],Ea,K=[],V=!1;d.extend(!0,a,k);"xlsx"===a.type&&(a.mso.fileFormat=a.type,a.type="excel");"undefined"!==typeof a.excelFileFormat&&"undefined"===a.mso.fileFormat&&(a.mso.fileFormat=a.excelFileFormat);"undefined"!==typeof a.excelPageFormat&&"undefined"===a.mso.pageFormat&&
|
|
||||||
(a.mso.pageFormat=a.excelPageFormat);"undefined"!==typeof a.excelPageOrientation&&"undefined"===a.mso.pageOrientation&&(a.mso.pageOrientation=a.excelPageOrientation);"undefined"!==typeof a.excelRTL&&"undefined"===a.mso.rtl&&(a.mso.rtl=a.excelRTL);"undefined"!==typeof a.excelstyles&&"undefined"===a.mso.styles&&(a.mso.styles=a.excelstyles);"undefined"!==typeof a.onMsoNumberFormat&&"undefined"===a.mso.onMsoNumberFormat&&(a.mso.onMsoNumberFormat=a.onMsoNumberFormat);"undefined"!==typeof a.worksheetName&&
|
|
||||||
"undefined"===a.mso.worksheetName&&(a.mso.worksheetName=a.worksheetName);a.mso.pageOrientation="l"===a.mso.pageOrientation.substr(0,1)?"landscape":"portrait";a.date.html=a.date.html||"";if(a.date.html.length){k=[];k.dd="(3[01]|[12][0-9]|0?[1-9])";k.mm="(1[012]|0?[1-9])";k.yyyy="((?:1[6-9]|2[0-2])\\d{2})";k.yy="(\\d{2})";var z=a.date.html.match(/[^a-zA-Z0-9]/)[0];z=a.date.html.toLowerCase().split(z);a.date.regex="^\\s*";a.date.regex+=k[z[0]];a.date.regex+="(.)";a.date.regex+=k[z[1]];a.date.regex+=
|
|
||||||
"\\2";a.date.regex+=k[z[2]];a.date.regex+="\\s*$";a.date.pattern=new RegExp(a.date.regex,"g");k=z.indexOf("dd")+1;a.date.match_d=k+(1<k?1:0);k=z.indexOf("mm")+1;a.date.match_m=k+(1<k?1:0);k=(0<=z.indexOf("yyyy")?z.indexOf("yyyy"):z.indexOf("yy"))+1;a.date.match_y=k+(1<k?1:0)}S=R(B);if("function"===typeof a.onTableExportBegin)a.onTableExportBegin();if("csv"===a.type||"tsv"===a.type||"txt"===a.type){var P="",Z=0;G=[];p=0;var qa=function(b,c,e){b.each(function(){t="";E(this,c,p,e+b.length,function(b,
|
|
||||||
c,d){var e=t,f="";if(null!==b)if(b=D(b,c,d),c=null===b||""===b?"":b.toString(),"tsv"===a.type)b instanceof Date&&b.toLocaleString(),f=W(c,"\t"," ");else if(b instanceof Date)f=a.csvEnclosure+b.toLocaleString()+a.csvEnclosure;else if(f=Ba(c),f=W(f,a.csvEnclosure,a.csvEnclosure+a.csvEnclosure),0<=f.indexOf(a.csvSeparator)||/[\r\n ]/g.test(f))f=a.csvEnclosure+f+a.csvEnclosure;t=e+(f+("tsv"===a.type?"\t":a.csvSeparator))});t=d.trim(t).substring(0,t.length-1);0<t.length&&(0<P.length&&(P+="\n"),P+=t);p++});
|
|
||||||
return b.length};Z+=qa(d(B).find("thead").first().find(a.theadSelector),"th,td",Z);v(d(B),"tbody").each(function(){Z+=qa(v(d(this),a.tbodySelector),"td,th",Z)});a.tfootSelector.length&&qa(d(B).find("tfoot").first().find(a.tfootSelector),"td,th",Z);P+="\n";if("string"===a.outputMode)return P;if("base64"===a.outputMode)return L(P);if("window"===a.outputMode){ka(!1,"data:text/"+("csv"===a.type?"csv":"plain")+";charset=utf-8,",P);return}N(P,a.fileName+"."+a.type,"text/"+("csv"===a.type?"csv":"plain"),
|
|
||||||
"utf-8","","csv"===a.type&&a.csvUseBOM)}else if("sql"===a.type){p=0;G=[];var A="INSERT INTO "+a.sql.tableEnclosure+a.tableName+a.sql.tableEnclosure+" (";r=y(d(B));d(r).each(function(){E(this,"th,td",p,r.length,function(b,c,d){b=D(b,c,d)||"";-1<b.indexOf(a.sql.columnEnclosure)&&(b=W(b.toString(),a.sql.columnEnclosure,a.sql.columnEnclosure+a.sql.columnEnclosure));A+=a.sql.columnEnclosure+b+a.sql.columnEnclosure+","});p++;A=d.trim(A).substring(0,A.length-1)});A+=") VALUES ";w=C(d(B));d(w).each(function(){t=
|
|
||||||
"";E(this,"td,th",p,r.length+w.length,function(a,c,d){a=D(a,c,d)||"";-1<a.indexOf("'")&&(a=W(a.toString(),"'","''"));t+="'"+a+"',"});3<t.length&&(A+="("+t,A=d.trim(A).substring(0,A.length-1),A+="),");p++});A=d.trim(A).substring(0,A.length-1);A+=";";if("string"===a.outputMode)return A;if("base64"===a.outputMode)return L(A);N(A,a.fileName+".sql","application/sql","utf-8","",!1)}else if("json"===a.type){var X=[];G=[];r=y(d(B));d(r).each(function(){var a=[];E(this,"th,td",p,r.length,function(b,d,g){a.push(D(b,
|
|
||||||
d,g))});X.push(a)});var ra=[];w=C(d(B));d(w).each(function(){var a={},c=0;E(this,"td,th",p,r.length+w.length,function(b,d,f){X.length?a[X[X.length-1][c]]=D(b,d,f):a[c]=D(b,d,f);c++});!1===d.isEmptyObject(a)&&ra.push(a);p++});k="head"===a.jsonScope?JSON.stringify(X):"data"===a.jsonScope?JSON.stringify(ra):JSON.stringify({header:X,data:ra});if("string"===a.outputMode)return k;if("base64"===a.outputMode)return L(k);N(k,a.fileName+".json","application/json","utf-8","base64",!1)}else if("xml"===a.type){p=
|
|
||||||
0;G=[];var Q='<?xml version="1.0" encoding="utf-8"?>';Q+="<tabledata><fields>";r=y(d(B));d(r).each(function(){E(this,"th,td",p,r.length,function(a,d,e){Q+="<field>"+D(a,d,e)+"</field>"});p++});Q+="</fields><data>";var Fa=1;w=C(d(B));d(w).each(function(){var a=1;t="";E(this,"td,th",p,r.length+w.length,function(b,d,g){t+="<column-"+a+">"+D(b,d,g)+"</column-"+a+">";a++});0<t.length&&"<column-1></column-1>"!==t&&(Q+='<row id="'+Fa+'">'+t+"</row>",Fa++);p++});Q+="</data></tabledata>";if("string"===a.outputMode)return Q;
|
|
||||||
if("base64"===a.outputMode)return L(Q);N(Q,a.fileName+".xml","application/xml","utf-8","base64",!1)}else if("excel"===a.type&&"xmlss"===a.mso.fileFormat){var sa=[],F=[];d(B).filter(function(){return I(d(this))}).each(function(){function b(a,b,c){var f=[];d(a).each(function(){var b=0,e=0;t="";E(this,"td,th",p,c+a.length,function(a,c,h){if(null!==a){var l="";c=D(a,c,h);h="String";if(!1!==jQuery.isNumeric(c))h="Number";else{var n=Ma(c);!1!==n&&(c=n,h="Number",l+=' ss:StyleID="pct1"')}"Number"!==h&&(c=
|
|
||||||
c.replace(/\n/g,"<br>"));n=J(a);a=T(a);d.each(f,function(){if(p>=this.s.r&&p<=this.e.r&&e>=this.s.c&&e<=this.e.c)for(var a=0;a<=this.e.c-this.s.c;++a)e++,b++});if(a||n)a=a||1,n=n||1,f.push({s:{r:p,c:e},e:{r:p+a-1,c:e+n-1}});1<n&&(l+=' ss:MergeAcross="'+(n-1)+'"',e+=n-1);1<a&&(l+=' ss:MergeDown="'+(a-1)+'" ss:StyleID="rsp1"');0<b&&(l+=' ss:Index="'+(e+1)+'"',b=0);t+="<Cell"+l+'><Data ss:Type="'+h+'">'+d("<div />").text(c).html()+"</Data></Cell>\r";e++}});0<t.length&&(H+='<Row ss:AutoFitHeight="0">\r'+
|
|
||||||
t+"</Row>\r");p++});return a.length}var c=d(this),e="";"string"===typeof a.mso.worksheetName&&a.mso.worksheetName.length?e=a.mso.worksheetName+" "+(F.length+1):"undefined"!==typeof a.mso.worksheetName[F.length]&&(e=a.mso.worksheetName[F.length]);e.length||(e=c.find("caption").text()||"");e.length||(e="Table "+(F.length+1));e=d.trim(e.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31));F.push(d("<div />").text(e).html());!1===a.exportHiddenCells&&(K=c.find("tr, th, td").filter(":hidden"),V=0<K.length);
|
|
||||||
p=0;S=R(this);H="<Table>\r";e=b(y(c),"th,td",0);b(C(c),"td,th",e);H+="</Table>\r";sa.push(H)});k={};z={};for(var m,aa,Y=0,ea=F.length;Y<ea;Y++)m=F[Y],aa=k[m],aa=k[m]=null==aa?1:aa+1,2===aa&&(F[z[m]]=F[z[m]].substring(0,29)+"-1"),1<k[m]?F[Y]=F[Y].substring(0,29)+"-"+k[m]:z[m]=Y;k='<?xml version="1.0" encoding="UTF-8"?>\r<?mso-application progid="Excel.Sheet"?>\r<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"\r xmlns:o="urn:schemas-microsoft-com:office:office"\r xmlns:x="urn:schemas-microsoft-com:office:excel"\r xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"\r xmlns:html="http://www.w3.org/TR/REC-html40">\r<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">\r <Created>'+
|
|
||||||
(new Date).toISOString()+'</Created>\r</DocumentProperties>\r<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">\r <AllowPNG/>\r</OfficeDocumentSettings>\r<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">\r <WindowHeight>9000</WindowHeight>\r <WindowWidth>13860</WindowWidth>\r <WindowTopX>0</WindowTopX>\r <WindowTopY>0</WindowTopY>\r <ProtectStructure>False</ProtectStructure>\r <ProtectWindows>False</ProtectWindows>\r</ExcelWorkbook>\r<Styles>\r <Style ss:ID="Default" ss:Name="Normal">\r <Alignment ss:Vertical="Bottom"/>\r <Borders/>\r <Font/>\r <Interior/>\r <NumberFormat/>\r <Protection/>\r </Style>\r <Style ss:ID="rsp1">\r <Alignment ss:Vertical="Center"/>\r </Style>\r <Style ss:ID="pct1">\r <NumberFormat ss:Format="Percent"/>\r </Style>\r</Styles>\r';
|
|
||||||
for(z=0;z<sa.length;z++)k+='<Worksheet ss:Name="'+F[z]+'" ss:RightToLeft="'+(a.mso.rtl?"1":"0")+'">\r'+sa[z],k=a.mso.rtl?k+'<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">\r<DisplayRightToLeft/>\r</WorksheetOptions>\r':k+'<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"/>\r',k+="</Worksheet>\r";k+="</Workbook>\r";if("string"===a.outputMode)return k;if("base64"===a.outputMode)return L(k);N(k,a.fileName+".xml","application/xml","utf-8","base64",!1)}else if("excel"===
|
|
||||||
a.type&&"xlsx"===a.mso.fileFormat){var ba=[],Ga=XLSX.utils.book_new();d(B).filter(function(){return I(d(this))}).each(function(){for(var b=d(this),c={},e=this.getElementsByTagName("tr"),g={s:{r:0,c:0},e:{r:0,c:0}},f=[],h,n=[],l=0,u=0,k,m,p,t,r,w=XLSX.SSF.get_table();l<e.length&&1E7>u;++l)if(k=e[l],m=!1,"function"===typeof a.onIgnoreRow&&(m=a.onIgnoreRow(d(k),l)),!0!==m&&(0===a.ignoreRow.length||-1===d.inArray(l,a.ignoreRow)&&-1===d.inArray(l-e.length,a.ignoreRow))&&!1!==I(d(k))){var y=k.children,
|
|
||||||
B=0;for(k=0;k<y.length;++k)r=y[k],t=+J(r)||1,B+=t;var z=0;for(k=m=0;k<y.length;++k)if(r=y[k],t=+J(r)||1,h=k+z,!ta(d(r),B,h+(h<m?m-h:0))){z+=t-1;for(h=0;h<f.length;++h){var v=f[h];v.s.c==m&&v.s.r<=u&&u<=v.e.r&&(m=v.e.c+1,h=-1)}(0<(p=+T(r))||1<t)&&f.push({s:{r:u,c:m},e:{r:u+(p||1)-1,c:m+t-1}});var C={type:""};h=D(r,l,k+z,C);v={t:"s",v:h};var A="";if(""!==(d(r).attr("data-tableexport-cellformat")||"")){var x=parseInt(d(r).attr("data-tableexport-xlsxformatid")||0);0===x&&"function"===typeof a.mso.xslx.formatId.numbers&&
|
|
||||||
(x=a.mso.xslx.formatId.numbers(d(r),l,k+z));0===x&&"function"===typeof a.mso.xslx.formatId.date&&(x=a.mso.xslx.formatId.date(d(r),l,k+z));if(49===x||"@"===x)A="s";else if("number"===C.type||0<x&&14>x||36<x&&41>x||48===x)A="n";else if("date"===C.type||13<x&&37>x||44<x&&48>x||56===x)A="d"}else A="s";if(null!=h)if(0===h.length)v.t="z";else if(0!==h.trim().length)if("s"===A)d(r).find("a").length&&(h="href"!==a.htmlHyperlink?h:"",v={f:'=HYPERLINK("'+d(r).find("a").attr("href")+(h.length?'","'+h:"")+'")'});
|
|
||||||
else if("function"===C.type)v={f:h};else if("TRUE"===h)v={t:"b",v:!0};else if("FALSE"===h)v={t:"b",v:!1};else if("n"===A||isFinite(Da(h,a.numbers.output))){if(r=Da(h,a.numbers.output),0===x&&"function"!==typeof a.mso.xslx.formatId.numbers&&(x=a.mso.xslx.formatId.numbers),isFinite(r)||isFinite(h))v={t:"n",v:isFinite(r)?r:h,z:"string"===typeof x?x:x in w?w[x]:"0.00"}}else if(!1!==(r=La(h))||"d"===A)0===x&&"function"!==typeof a.mso.xslx.formatId.date&&(x=a.mso.xslx.formatId.date),v={t:"d",v:!1!==r?r:
|
|
||||||
h,z:"string"===typeof x?x:x in w?w[x]:"m/d/yy"};c[oa({c:m,r:u})]=v;g.e.c<m&&(g.e.c=m);m+=t}++u}f.length&&(c["!merges"]=f);n.length&&(c["!rows"]=n);g.e.r=u-1;c["!ref"]=pa(g);1E7<=u&&(c["!fullref"]=pa((g.e.r=e.length-l+u-1,g)));e="";"string"===typeof a.mso.worksheetName&&a.mso.worksheetName.length?e=a.mso.worksheetName+" "+(ba.length+1):"undefined"!==typeof a.mso.worksheetName[ba.length]&&(e=a.mso.worksheetName[ba.length]);e.length||(e=b.find("caption").text()||"");e.length||(e="Table "+(ba.length+
|
|
||||||
1));e=d.trim(e.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31));ba.push(e);XLSX.utils.book_append_sheet(Ga,c,e)});k=XLSX.write(Ga,{type:"binary",bookType:a.mso.fileFormat,bookSST:!1});N(Oa(k),a.fileName+"."+a.mso.fileFormat,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","UTF-8","",!1)}else if("excel"===a.type||"xls"===a.type||"word"===a.type||"doc"===a.type){k="excel"===a.type||"xls"===a.type?"excel":"word";z="excel"===k?"xls":"doc";m='xmlns:x="urn:schemas-microsoft-com:office:'+
|
|
||||||
k+'"';var H="",ca="";d(B).filter(function(){return I(d(this))}).each(function(){var b=d(this);""===ca&&(ca=a.mso.worksheetName||b.find("caption").text()||"Table",ca=d.trim(ca.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31)));!1===a.exportHiddenCells&&(K=b.find("tr, th, td").filter(":hidden"),V=0<K.length);p=0;G=[];S=R(this);H+="<table><thead>";r=y(b);d(r).each(function(){var b=d(this);t="";E(this,"th,td",p,r.length,function(d,c,f){if(null!==d){var e="";t+="<th";if(a.mso.styles.length){var n=document.defaultView.getComputedStyle(d,
|
|
||||||
null),l=document.defaultView.getComputedStyle(b[0],null),g;for(g in a.mso.styles){var k=n[a.mso.styles[g]];""===k&&(k=l[a.mso.styles[g]]);""!==k&&"0px none rgb(0, 0, 0)"!==k&&"rgba(0, 0, 0, 0)"!==k&&(e+=""===e?'style="':";",e+=a.mso.styles[g]+":"+k)}}""!==e&&(t+=" "+e+'"');e=J(d);0<e&&(t+=' colspan="'+e+'"');e=T(d);0<e&&(t+=' rowspan="'+e+'"');t+=">"+D(d,c,f)+"</th>"}});0<t.length&&(H+="<tr>"+t+"</tr>");p++});H+="</thead><tbody>";w=C(b);d(w).each(function(){var b=d(this);t="";E(this,"td,th",p,r.length+
|
|
||||||
w.length,function(c,g,f){if(null!==c){var e=D(c,g,f),n="",l=d(c).attr("data-tableexport-msonumberformat");"undefined"===typeof l&&"function"===typeof a.mso.onMsoNumberFormat&&(l=a.mso.onMsoNumberFormat(c,g,f));"undefined"!==typeof l&&""!==l&&(n="style=\"mso-number-format:'"+l+"'");if(a.mso.styles.length){g=document.defaultView.getComputedStyle(c,null);f=document.defaultView.getComputedStyle(b[0],null);for(var k in a.mso.styles)l=g[a.mso.styles[k]],""===l&&(l=f[a.mso.styles[k]]),""!==l&&"0px none rgb(0, 0, 0)"!==
|
|
||||||
l&&"rgba(0, 0, 0, 0)"!==l&&(n+=""===n?'style="':";",n+=a.mso.styles[k]+":"+l)}t+="<td";""!==n&&(t+=" "+n+'"');n=J(c);0<n&&(t+=' colspan="'+n+'"');c=T(c);0<c&&(t+=' rowspan="'+c+'"');"string"===typeof e&&""!==e&&(e=Ba(e),e=e.replace(/\n/g,"<br>"));t+=">"+e+"</td>"}});0<t.length&&(H+="<tr>"+t+"</tr>");p++});a.displayTableName&&(H+="<tr><td></td></tr><tr><td></td></tr><tr><td>"+D(d("<p>"+a.tableName+"</p>"))+"</td></tr>");H+="</tbody></table>"});m='<html xmlns:o="urn:schemas-microsoft-com:office:office" '+
|
|
||||||
m+' xmlns="http://www.w3.org/TR/REC-html40">'+('<meta http-equiv="content-type" content="application/vnd.ms-'+k+'; charset=UTF-8">')+"<head>";"excel"===k&&(m+="\x3c!--[if gte mso 9]>",m+="<xml>",m+="<x:ExcelWorkbook>",m+="<x:ExcelWorksheets>",m+="<x:ExcelWorksheet>",m+="<x:Name>",m+=ca,m+="</x:Name>",m+="<x:WorksheetOptions>",m+="<x:DisplayGridlines/>",a.mso.rtl&&(m+="<x:DisplayRightToLeft/>"),m+="</x:WorksheetOptions>",m+="</x:ExcelWorksheet>",m+="</x:ExcelWorksheets>",m+="</x:ExcelWorkbook>",m+=
|
|
||||||
"</xml>",m+="<![endif]--\x3e");m+="<style>";m+="@page { size:"+a.mso.pageOrientation+"; mso-page-orientation:"+a.mso.pageOrientation+"; }";m+="@page Section1 {size:"+O[a.mso.pageFormat][0]+"pt "+O[a.mso.pageFormat][1]+"pt";m+="; margin:1.0in 1.25in 1.0in 1.25in;mso-header-margin:.5in;mso-footer-margin:.5in;mso-paper-source:0;}";m+="div.Section1 {page:Section1;}";m+="@page Section2 {size:"+O[a.mso.pageFormat][1]+"pt "+O[a.mso.pageFormat][0]+"pt";m+=";mso-page-orientation:"+a.mso.pageOrientation+";margin:1.25in 1.0in 1.25in 1.0in;mso-header-margin:.5in;mso-footer-margin:.5in;mso-paper-source:0;}";
|
|
||||||
m+="div.Section2 {page:Section2;}";m+="br {mso-data-placement:same-cell;}";m+="</style>";m+="</head>";m+="<body>";m+='<div class="Section'+("landscape"===a.mso.pageOrientation?"2":"1")+'">';m+=H;m+="</div>";m+="</body>";m+="</html>";if("string"===a.outputMode)return m;if("base64"===a.outputMode)return L(m);N(m,a.fileName+"."+z,"application/vnd.ms-"+k,"","base64",!1)}else if("png"===a.type)html2canvas(d(B)[0]).then(function(b){b=b.toDataURL();for(var c=atob(b.substring(22)),d=new ArrayBuffer(c.length),
|
|
||||||
g=new Uint8Array(d),f=0;f<c.length;f++)g[f]=c.charCodeAt(f);if("string"===a.outputMode)return c;if("base64"===a.outputMode)return L(b);"window"===a.outputMode?window.open(b):N(d,a.fileName+".png","image/png","","",!1)});else if("pdf"===a.type)if(!0===a.pdfmake.enabled){var U={content:[]};d.extend(!0,U,a.pdfmake.docDefinition);G=[];d(B).filter(function(){return I(d(this))}).each(function(){var b=d(this),c=[],e=[];p=0;var g=function(a,b,c){var f=0;d(a).each(function(){var a=[];E(this,b,p,c,function(c,
|
|
||||||
d,f){if("undefined"!==typeof c&&null!==c){var e=J(c),h=T(c);c={text:D(c,d,f)||" "};if(1<e||1<h)c.colSpan=e||1,c.rowSpan=h||1}else c={text:" "};0<=b.indexOf("th")&&(c.style="header");a.push(c)});for(var d=a.length;d<c;d++)a.push("");a.length&&e.push(a);f<a.length&&(f=a.length);p++});return f};r=y(b);for(var f=g(r,"th,td",r.length),h=c.length;h<f;h++)c.push("*");w=C(b);f=g(w,"td",r.length+w.length);for(h=c.length;h<f;h++)c.push("*");U.content.push({table:{headerRows:r.length?r.length:null,widths:c,
|
|
||||||
body:e},layout:{layout:"noBorders",hLineStyle:function(a,b){return 0},vLineWidth:function(a,b){return 0},hLineColor:function(b,c){return b<c.table.headerRows?a.pdfmake.docDefinition.styles.header.background:a.pdfmake.docDefinition.styles.alternateRow.fillColor},vLineColor:function(b,c){return b<c.table.headerRows?a.pdfmake.docDefinition.styles.header.background:a.pdfmake.docDefinition.styles.alternateRow.fillColor},fillColor:function(b,c,d){return 0===b%2?a.pdfmake.docDefinition.styles.alternateRow.fillColor:
|
|
||||||
null}},pageBreak:U.content.length?"before":void 0})});"undefined"!==typeof pdfMake&&"undefined"!==typeof pdfMake.createPdf&&(pdfMake.fonts={Roboto:{normal:"Roboto-Regular.ttf",bold:"Roboto-Medium.ttf",italics:"Roboto-Italic.ttf",bolditalics:"Roboto-MediumItalic.ttf"}},pdfMake.vfs.hasOwnProperty("Mirza-Regular.ttf")?(U.defaultStyle.font="Mirza",d.extend(!0,pdfMake.fonts,{Mirza:{normal:"Mirza-Regular.ttf",bold:"Mirza-Bold.ttf",italics:"Mirza-Medium.ttf",bolditalics:"Mirza-SemiBold.ttf"}})):pdfMake.vfs.hasOwnProperty("gbsn00lp.ttf")?
|
|
||||||
(U.defaultStyle.font="gbsn00lp",d.extend(!0,pdfMake.fonts,{gbsn00lp:{normal:"gbsn00lp.ttf",bold:"gbsn00lp.ttf",italics:"gbsn00lp.ttf",bolditalics:"gbsn00lp.ttf"}})):pdfMake.vfs.hasOwnProperty("ZCOOLXiaoWei-Regular.ttf")&&(U.defaultStyle.font="ZCOOLXiaoWei",d.extend(!0,pdfMake.fonts,{ZCOOLXiaoWei:{normal:"ZCOOLXiaoWei-Regular.ttf",bold:"ZCOOLXiaoWei-Regular.ttf",italics:"ZCOOLXiaoWei-Regular.ttf",bolditalics:"ZCOOLXiaoWei-Regular.ttf"}})),d.extend(!0,pdfMake.fonts,a.pdfmake.fonts),pdfMake.createPdf(U).getBuffer(function(b){N(b,
|
|
||||||
a.fileName+".pdf","application/pdf","","",!1)}))}else if(!1===a.jspdf.autotable){k={dim:{w:ha(d(B).first().get(0),"width","mm"),h:ha(d(B).first().get(0),"height","mm")},pagesplit:!1};var Ha=new jsPDF(a.jspdf.orientation,a.jspdf.unit,a.jspdf.format);Ha.addHTML(d(B).first(),a.jspdf.margins.left,a.jspdf.margins.top,k,function(){va(Ha,!1)})}else{var g=a.jspdf.autotable.tableExport;if("string"===typeof a.jspdf.format&&"bestfit"===a.jspdf.format.toLowerCase()){var ja="",da="",Ia=0;d(B).each(function(){if(I(d(this))){var a=
|
|
||||||
ha(d(this).get(0),"width","pt");if(a>Ia){a>O.a0[0]&&(ja="a0",da="l");for(var c in O)O.hasOwnProperty(c)&&O[c][1]>a&&(ja=c,da="l",O[c][0]>a&&(da="p"));Ia=a}}});a.jspdf.format=""===ja?"a4":ja;a.jspdf.orientation=""===da?"w":da}if(null==g.doc&&(g.doc=new jsPDF(a.jspdf.orientation,a.jspdf.unit,a.jspdf.format),g.wScaleFactor=1,g.hScaleFactor=1,"function"===typeof a.jspdf.onDocCreated))a.jspdf.onDocCreated(g.doc);!0===g.outputImages&&(g.images={});"undefined"!==typeof g.images&&(d(B).filter(function(){return I(d(this))}).each(function(){var b=
|
|
||||||
0;G=[];!1===a.exportHiddenCells&&(K=d(this).find("tr, th, td").filter(":hidden"),V=0<K.length);r=y(d(this));w=C(d(this));d(w).each(function(){E(this,"td,th",r.length+b,r.length+w.length,function(a){xa(a,d(a).children(),g)});b++})}),r=[],w=[]);Ka(g,function(){d(B).filter(function(){return I(d(this))}).each(function(){var b;p=0;G=[];!1===a.exportHiddenCells&&(K=d(this).find("tr, th, td").filter(":hidden"),V=0<K.length);S=R(this);g.columns=[];g.rows=[];g.teCells={};if("function"===typeof g.onTable&&
|
|
||||||
!1===g.onTable(d(this),a))return!0;a.jspdf.autotable.tableExport=null;var c=d.extend(!0,{},a.jspdf.autotable);a.jspdf.autotable.tableExport=g;c.margin={};d.extend(!0,c.margin,a.jspdf.margins);c.tableExport=g;"function"!==typeof c.beforePageContent&&(c.beforePageContent=function(a){if(1===a.pageCount){var b=a.table.rows.concat(a.table.headerRow);d.each(b,function(){0<this.height&&(this.height+=(2-1.15)/2*this.styles.fontSize,a.table.height+=(2-1.15)/2*this.styles.fontSize)})}});"function"!==typeof c.createdHeaderCell&&
|
|
||||||
(c.createdHeaderCell=function(a,b){a.styles=d.extend({},b.row.styles);if("undefined"!==typeof g.columns[b.column.dataKey]){var e=g.columns[b.column.dataKey];if("undefined"!==typeof e.rect){a.contentWidth=e.rect.width;if("undefined"===typeof g.heightRatio||0===g.heightRatio){var f=b.row.raw[b.column.dataKey].rowspan?b.row.raw[b.column.dataKey].rect.height/b.row.raw[b.column.dataKey].rowspan:b.row.raw[b.column.dataKey].rect.height;g.heightRatio=a.styles.rowHeight/f}f=b.row.raw[b.column.dataKey].rect.height*
|
|
||||||
g.heightRatio;f>a.styles.rowHeight&&(a.styles.rowHeight=f)}a.styles.halign="inherit"===c.headerStyles.halign?"center":c.headerStyles.halign;a.styles.valign=c.headerStyles.valign;"undefined"!==typeof e.style&&!0!==e.style.hidden&&("inherit"===c.headerStyles.halign&&(a.styles.halign=e.style.align),"inherit"===c.styles.fillColor&&(a.styles.fillColor=e.style.bcolor),"inherit"===c.styles.textColor&&(a.styles.textColor=e.style.color),"inherit"===c.styles.fontStyle&&(a.styles.fontStyle=e.style.fstyle))}});
|
|
||||||
"function"!==typeof c.createdCell&&(c.createdCell=function(a,b){b=g.teCells[b.row.index+":"+b.column.dataKey];a.styles.halign="inherit"===c.styles.halign?"center":c.styles.halign;a.styles.valign=c.styles.valign;"undefined"!==typeof b&&"undefined"!==typeof b.style&&!0!==b.style.hidden&&("inherit"===c.styles.halign&&(a.styles.halign=b.style.align),"inherit"===c.styles.fillColor&&(a.styles.fillColor=b.style.bcolor),"inherit"===c.styles.textColor&&(a.styles.textColor=b.style.color),"inherit"===c.styles.fontStyle&&
|
|
||||||
(a.styles.fontStyle=b.style.fstyle))});"function"!==typeof c.drawHeaderCell&&(c.drawHeaderCell=function(a,b){var c=g.columns[b.column.dataKey];return(!0!==c.style.hasOwnProperty("hidden")||!0!==c.style.hidden)&&0<=c.rowIndex?wa(a,b,c):!1});"function"!==typeof c.drawCell&&(c.drawCell=function(a,b){var c=g.teCells[b.row.index+":"+b.column.dataKey];if(!0!==("undefined"!==typeof c&&c.isCanvas))wa(a,b,c)&&(g.doc.rect(a.x,a.y,a.width,a.height,a.styles.fillStyle),"undefined"===typeof c||"undefined"!==typeof c.hasUserDefText&&
|
|
||||||
!0===c.hasUserDefText||"undefined"===typeof c.elements||!c.elements.length?Aa(a,{},g):(b=a.height/c.rect.height,b>g.hScaleFactor&&(g.hScaleFactor=b),g.wScaleFactor=a.width/c.rect.width,b=a.textPos.y,za(a,c.elements,g),a.textPos.y=b,Aa(a,c.elements,g)));else{c=c.elements[0];var e=d(c).attr("data-tableexport-canvas"),f=c.getBoundingClientRect();a.width=f.width*g.wScaleFactor;a.height=f.height*g.hScaleFactor;b.row.height=a.height;ua(a,c,e,g)}return!1});g.headerrows=[];r=y(d(this));d(r).each(function(){b=
|
|
||||||
0;g.headerrows[p]=[];E(this,"th,td",p,r.length,function(a,c,d){var e=Ca(a);e.title=D(a,c,d);e.key=b++;e.rowIndex=p;g.headerrows[p].push(e)});p++});if(0<p)for(var e=p-1;0<=e;)d.each(g.headerrows[e],function(){var a=this;0<e&&null===this.rect&&(a=g.headerrows[e-1][this.key]);null!==a&&0<=a.rowIndex&&(!0!==a.style.hasOwnProperty("hidden")||!0!==a.style.hidden)&&g.columns.push(a)}),e=0<g.columns.length?-1:e-1;var k=0;w=[];w=C(d(this));d(w).each(function(){var a=[];b=0;E(this,"td,th",p,r.length+w.length,
|
|
||||||
function(c,e,f){if("undefined"===typeof g.columns[b]){var h={title:"",key:b,style:{hidden:!0}};g.columns.push(h)}a.push(D(c,e,f));"undefined"!==typeof c&&null!==c?(h=Ca(c),h.isCanvas=c.hasAttribute("data-tableexport-canvas"),h.elements=h.isCanvas?d(c):d(c).children(),"undefined"!==typeof d(c).data("teUserDefText")&&(h.hasUserDefText=!0)):(h=d.extend(!0,{},g.teCells[k+":"+(b-1)]),h.colspan=-1);g.teCells[k+":"+b++]=h});a.length&&(g.rows.push(a),k++);p++});if("function"===typeof g.onBeforeAutotable)g.onBeforeAutotable(d(this),
|
|
||||||
g.columns,g.rows,c);g.doc.autoTable(g.columns,g.rows,c);if("function"===typeof g.onAfterAutotable)g.onAfterAutotable(d(this),c);a.jspdf.autotable.startY=g.doc.autoTableEndPosY()+c.margin.top});va(g.doc,"undefined"!==typeof g.images&&!1===jQuery.isEmptyObject(g.images));"undefined"!==typeof g.headerrows&&(g.headerrows.length=0);"undefined"!==typeof g.columns&&(g.columns.length=0);"undefined"!==typeof g.rows&&(g.rows.length=0);delete g.doc;g.doc=null})}if("function"===typeof a.onTableExportEnd)a.onTableExportEnd();
|
|
||||||
return this}})(jQuery);
|
|
||||||
|
|
@ -1,123 +1,92 @@
|
||||||
/**
|
/**
|
||||||
* @author: Dennis Hernández
|
* 基于bootstrap-table-mobile修改
|
||||||
* @update zhixin wen <wenzhixin2010@gmail.com>
|
* 修正部分iPhone手机不显示卡片视图
|
||||||
*/
|
* Copyright (c) 2019 ruoyi
|
||||||
|
*/
|
||||||
const debounce = (func, wait) => {
|
!function ($) {
|
||||||
let timeout = 0
|
|
||||||
|
'use strict';
|
||||||
return (...args) => {
|
|
||||||
const later = () => {
|
var resetView = function (that) {
|
||||||
timeout = 0
|
if (that.options.height || that.options.showFooter) {
|
||||||
func(...args)
|
setTimeout(that.resetView(), 1);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
clearTimeout(timeout)
|
|
||||||
timeout = setTimeout(later, wait)
|
// 判断是否 iphone
|
||||||
}
|
var isIPhone = function () {
|
||||||
}
|
var browserName = navigator.userAgent.toLowerCase();
|
||||||
|
return /(iPhone|iPad|iPod|iOS)/i.test(browserName);
|
||||||
Object.assign($.fn.bootstrapTable.defaults, {
|
};
|
||||||
mobileResponsive: false,
|
|
||||||
minWidth: 562,
|
var changeView = function (that, width, height) {
|
||||||
minHeight: undefined,
|
if (that.options.minHeight) {
|
||||||
heightThreshold: 100, // just slightly larger than mobile chrome's auto-hiding toolbar
|
if (checkValuesLessEqual(width, that.options.minWidth) && checkValuesLessEqual(height, that.options.minHeight)) {
|
||||||
checkOnInit: true,
|
conditionCardView(that);
|
||||||
columnsHidden: []
|
} else if (checkValuesGreater(width, that.options.minWidth) && checkValuesGreater(height, that.options.minHeight)) {
|
||||||
})
|
conditionFullView(that);
|
||||||
|
}
|
||||||
$.BootstrapTable = class extends $.BootstrapTable {
|
} else {
|
||||||
init (...args) {
|
if (checkValuesLessEqual(width, that.options.minWidth) || isIPhone()) {
|
||||||
super.init(...args)
|
conditionCardView(that);
|
||||||
|
} else if (checkValuesGreater(width, that.options.minWidth)) {
|
||||||
if (!this.options.mobileResponsive || !this.options.minWidth) {
|
conditionFullView(that);
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.minWidth < 100 && this.options.resizable) {
|
resetView(that);
|
||||||
console.warn('The minWidth when the resizable extension is active should be greater or equal than 100')
|
};
|
||||||
this.options.minWidth = 100
|
|
||||||
}
|
var checkValuesLessEqual = function (currentValue, targetValue) {
|
||||||
|
return currentValue <= targetValue;
|
||||||
let old = {
|
};
|
||||||
width: $(window).width(),
|
|
||||||
height: $(window).height()
|
var checkValuesGreater = function (currentValue, targetValue) {
|
||||||
}
|
return currentValue > targetValue;
|
||||||
|
};
|
||||||
$(window).on('resize orientationchange', debounce(() => {
|
|
||||||
// reset view if height has only changed by at least the threshold.
|
var conditionCardView = function (that) {
|
||||||
const width = $(window).width()
|
changeTableView(that, false);
|
||||||
const height = $(window).height()
|
};
|
||||||
const $activeElement = $(document.activeElement)
|
|
||||||
|
var conditionFullView = function (that) {
|
||||||
if ($activeElement.length && ['INPUT', 'SELECT', 'TEXTAREA'].includes($activeElement.prop('nodeName'))) {
|
changeTableView(that, true);
|
||||||
return
|
};
|
||||||
}
|
|
||||||
|
var changeTableView = function (that, cardViewState) {
|
||||||
if (
|
that.options.cardView = cardViewState;
|
||||||
Math.abs(old.height - height) > this.options.heightThreshold ||
|
that.toggleView();
|
||||||
old.width !== width
|
};
|
||||||
) {
|
|
||||||
this.changeView(width, height)
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
old = {
|
mobileResponsive: false,
|
||||||
width,
|
minWidth: 562,
|
||||||
height
|
minHeight: undefined,
|
||||||
}
|
checkOnInit: true,
|
||||||
}
|
toggled: false
|
||||||
}, 200))
|
});
|
||||||
|
|
||||||
if (this.options.checkOnInit) {
|
var BootstrapTable = $.fn.bootstrapTable.Constructor,
|
||||||
const width = $(window).width()
|
_init = BootstrapTable.prototype.init;
|
||||||
const height = $(window).height()
|
|
||||||
|
BootstrapTable.prototype.init = function () {
|
||||||
this.changeView(width, height)
|
_init.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
old = {
|
|
||||||
width,
|
if (!this.options.mobileResponsive) {
|
||||||
height
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
if (!this.options.minWidth) {
|
||||||
|
return;
|
||||||
conditionCardView () {
|
}
|
||||||
this.changeTableView(false)
|
|
||||||
this.showHideColumns(false)
|
var that = this;
|
||||||
}
|
$(window).resize(function () {
|
||||||
|
changeView(that, $(this).width(), $(this).height())
|
||||||
conditionFullView () {
|
});
|
||||||
this.changeTableView(true)
|
|
||||||
this.showHideColumns(true)
|
if (this.options.checkOnInit) {
|
||||||
}
|
changeView(this, $(window).width(), $(window).height());
|
||||||
|
}
|
||||||
changeTableView (cardViewState) {
|
};
|
||||||
this.options.cardView = cardViewState
|
}(jQuery);
|
||||||
this.toggleView()
|
|
||||||
}
|
|
||||||
|
|
||||||
showHideColumns (checked) {
|
|
||||||
if (this.options.columnsHidden.length > 0) {
|
|
||||||
this.columns.forEach(column => {
|
|
||||||
if (this.options.columnsHidden.includes(column.field)) {
|
|
||||||
if (column.visible !== checked) {
|
|
||||||
this._toggleColumn(this.fieldsColumnsIndex[column.field], checked, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
changeView (width, height) {
|
|
||||||
if (this.options.minHeight) {
|
|
||||||
if (width <= this.options.minWidth && height <= this.options.minHeight) {
|
|
||||||
this.conditionCardView()
|
|
||||||
} else if (width > this.options.minWidth && height > this.options.minHeight) {
|
|
||||||
this.conditionFullView()
|
|
||||||
}
|
|
||||||
} else if (width <= this.options.minWidth) {
|
|
||||||
this.conditionCardView()
|
|
||||||
} else if (width > this.options.minWidth) {
|
|
||||||
this.conditionFullView()
|
|
||||||
}
|
|
||||||
|
|
||||||
this.resetView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,312 +0,0 @@
|
||||||
/**
|
|
||||||
* @update zhixin wen <wenzhixin2010@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
var Utils = $.fn.bootstrapTable.utils
|
|
||||||
|
|
||||||
function printPageBuilderDefault (table, styles) {
|
|
||||||
return `
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
${styles}
|
|
||||||
<style type="text/css" media="print">
|
|
||||||
@page {
|
|
||||||
size: auto;
|
|
||||||
margin: 25px 0 25px 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style type="text/css" media="all">
|
|
||||||
table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
table, th, td {
|
|
||||||
border: 1px solid grey;
|
|
||||||
}
|
|
||||||
th, td {
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
font-weight: bold;
|
|
||||||
margin-left:20px;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
width: 94%;
|
|
||||||
margin-left: 3%;
|
|
||||||
margin-right: 3%;
|
|
||||||
}
|
|
||||||
div.bs-table-print {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<title>Print Table</title>
|
|
||||||
<body>
|
|
||||||
<p>Printed on: ${new Date} </p>
|
|
||||||
<div class="bs-table-print">${table}</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.locales, {
|
|
||||||
formatPrint () {
|
|
||||||
return 'Print'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
Object.assign($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.defaults, {
|
|
||||||
showPrint: false,
|
|
||||||
printAsFilteredAndSortedOnUI: true,
|
|
||||||
printSortColumn: undefined,
|
|
||||||
printSortOrder: 'asc',
|
|
||||||
printStyles: [],
|
|
||||||
printPageBuilder (table, styles) {
|
|
||||||
return printPageBuilderDefault(table, styles)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.columnDefaults, {
|
|
||||||
printFilter: undefined,
|
|
||||||
printIgnore: false,
|
|
||||||
printFormatter: undefined
|
|
||||||
})
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.defaults.icons, {
|
|
||||||
print: {
|
|
||||||
bootstrap3: 'glyphicon-print icon-share',
|
|
||||||
bootstrap5: 'bi-printer',
|
|
||||||
'bootstrap-table': 'icon-printer'
|
|
||||||
}[$.fn.bootstrapTable.theme] || 'fa-print'
|
|
||||||
})
|
|
||||||
|
|
||||||
$.BootstrapTable = class extends $.BootstrapTable {
|
|
||||||
init (...args) {
|
|
||||||
super.init(...args)
|
|
||||||
|
|
||||||
if (!this.options.showPrint) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.mergedCells = []
|
|
||||||
}
|
|
||||||
|
|
||||||
initToolbar (...args) {
|
|
||||||
this.showToolbar = this.showToolbar || this.options.showPrint
|
|
||||||
|
|
||||||
if (this.options.showPrint) {
|
|
||||||
this.buttons = Object.assign(this.buttons, {
|
|
||||||
print: {
|
|
||||||
text: this.options.formatPrint(),
|
|
||||||
icon: this.options.icons.print,
|
|
||||||
event: () => {
|
|
||||||
this.doPrint(this.options.printAsFilteredAndSortedOnUI ? this.getData() : this.options.data.slice(0))
|
|
||||||
},
|
|
||||||
attributes: {
|
|
||||||
'aria-label': this.options.formatPrint(),
|
|
||||||
title: this.options.formatPrint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
super.initToolbar(...args)
|
|
||||||
}
|
|
||||||
|
|
||||||
mergeCells (options) {
|
|
||||||
super.mergeCells(options)
|
|
||||||
|
|
||||||
if (!this.options.showPrint) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let col = this.getVisibleFields().indexOf(options.field)
|
|
||||||
|
|
||||||
if (Utils.hasDetailViewIcon(this.options)) {
|
|
||||||
col += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
this.mergedCells.push({
|
|
||||||
row: options.index,
|
|
||||||
col,
|
|
||||||
rowspan: options.rowspan || 1,
|
|
||||||
colspan: options.colspan || 1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
doPrint (data) {
|
|
||||||
const canPrint = column => {
|
|
||||||
return !column.printIgnore && column.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatValue = (row, i, column) => {
|
|
||||||
const value_ = Utils.getItemField(row, column.field, this.options.escape, column.escape)
|
|
||||||
const value = Utils.calculateObjectValue(column,
|
|
||||||
column.printFormatter || column.formatter,
|
|
||||||
[value_, row, i], value_)
|
|
||||||
|
|
||||||
return typeof value === 'undefined' || value === null ?
|
|
||||||
this.options.undefinedText : value
|
|
||||||
}
|
|
||||||
|
|
||||||
const buildTable = (data, columnsArray) => {
|
|
||||||
const dir = this.$el.attr('dir') || 'ltr'
|
|
||||||
const html = [`<table dir="${dir}"><thead>`]
|
|
||||||
|
|
||||||
for (const columns of columnsArray) {
|
|
||||||
html.push('<tr>')
|
|
||||||
for (let h = 0; h < columns.length; h++) {
|
|
||||||
if (canPrint(columns[h])) {
|
|
||||||
html.push(
|
|
||||||
`<th
|
|
||||||
${Utils.sprintf(' rowspan="%s"', columns[h].rowspan)}
|
|
||||||
${Utils.sprintf(' colspan="%s"', columns[h].colspan)}
|
|
||||||
>${columns[h].title}</th>`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
html.push('</tr>')
|
|
||||||
}
|
|
||||||
|
|
||||||
html.push('</thead><tbody>')
|
|
||||||
|
|
||||||
const notRender = []
|
|
||||||
|
|
||||||
if (this.mergedCells) {
|
|
||||||
for (let mc = 0; mc < this.mergedCells.length; mc++) {
|
|
||||||
const currentMergedCell = this.mergedCells[mc]
|
|
||||||
|
|
||||||
for (let rs = 0; rs < currentMergedCell.rowspan; rs++) {
|
|
||||||
const row = currentMergedCell.row + rs
|
|
||||||
|
|
||||||
for (let cs = 0; cs < currentMergedCell.colspan; cs++) {
|
|
||||||
const col = currentMergedCell.col + cs
|
|
||||||
|
|
||||||
notRender.push(`${row},${col}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
html.push('<tr>')
|
|
||||||
|
|
||||||
const columns = columnsArray.flat(1)
|
|
||||||
|
|
||||||
columns.sort((c1, c2) => {
|
|
||||||
return c1.colspanIndex - c2.colspanIndex
|
|
||||||
})
|
|
||||||
|
|
||||||
for (let j = 0; j < columns.length; j++) {
|
|
||||||
if (columns[j].colspanGroup > 0) continue
|
|
||||||
|
|
||||||
let rowspan = 0
|
|
||||||
let colspan = 0
|
|
||||||
|
|
||||||
if (this.mergedCells) {
|
|
||||||
for (let mc = 0; mc < this.mergedCells.length; mc++) {
|
|
||||||
const currentMergedCell = this.mergedCells[mc]
|
|
||||||
|
|
||||||
if (currentMergedCell.col === j && currentMergedCell.row === i) {
|
|
||||||
rowspan = currentMergedCell.rowspan
|
|
||||||
colspan = currentMergedCell.colspan
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
canPrint(columns[j]) &&
|
|
||||||
(
|
|
||||||
!notRender.includes(`${i},${j}`) ||
|
|
||||||
rowspan > 0 && colspan > 0
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
if (rowspan > 0 && colspan > 0) {
|
|
||||||
html.push(`<td ${Utils.sprintf(' rowspan="%s"', rowspan)} ${Utils.sprintf(' colspan="%s"', colspan)}>`, formatValue(data[i], i, columns[j]), '</td>')
|
|
||||||
} else {
|
|
||||||
html.push('<td>', formatValue(data[i], i, columns[j]), '</td>')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
html.push('</tr>')
|
|
||||||
}
|
|
||||||
|
|
||||||
html.push('</tbody>')
|
|
||||||
if (this.options.showFooter) {
|
|
||||||
html.push('<footer><tr>')
|
|
||||||
|
|
||||||
for (const columns of columnsArray) {
|
|
||||||
for (let h = 0; h < columns.length; h++) {
|
|
||||||
if (canPrint(columns)) {
|
|
||||||
const footerData = Utils.trToData(columns, this.$el.find('>tfoot>tr'))
|
|
||||||
const footerValue = Utils.calculateObjectValue(columns[h], columns[h].footerFormatter, [data], footerData[0] && footerData[0][columns[h].field] || '')
|
|
||||||
|
|
||||||
html.push(`<th>${footerValue}</th>`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
html.push('</tr></footer>')
|
|
||||||
}
|
|
||||||
html.push('</table>')
|
|
||||||
return html.join('')
|
|
||||||
}
|
|
||||||
|
|
||||||
const sortRows = (data, colName, sortOrder) => {
|
|
||||||
if (!colName) {
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
let reverse = sortOrder !== 'asc'
|
|
||||||
|
|
||||||
reverse = -(+reverse || -1)
|
|
||||||
return data.sort((a, b) => reverse * a[colName].localeCompare(b[colName]))
|
|
||||||
}
|
|
||||||
|
|
||||||
const filterRow = (row, filters) => {
|
|
||||||
for (let index = 0; index < filters.length; ++index) {
|
|
||||||
if (row[filters[index].colName] !== filters[index].value) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
const filterRows = (data, filters) => data.filter(row => filterRow(row, filters))
|
|
||||||
const getColumnFilters = columns => !columns || !columns[0] ? [] : columns[0].filter(col => col.printFilter).map(col => ({
|
|
||||||
colName: col.field,
|
|
||||||
value: col.printFilter
|
|
||||||
}))
|
|
||||||
|
|
||||||
data = filterRows(data, getColumnFilters(this.options.columns))
|
|
||||||
data = sortRows(data, this.options.printSortColumn, this.options.printSortOrder)
|
|
||||||
const table = buildTable(data, this.options.columns)
|
|
||||||
const newWin = window.open('')
|
|
||||||
const printStyles = typeof this.options.printStyles === 'string' ?
|
|
||||||
this.options.printStyles.replace(/\[|\]| /g, '').toLowerCase().split(',') :
|
|
||||||
this.options.printStyles
|
|
||||||
const styles = printStyles.map(it =>
|
|
||||||
`<link rel="stylesheet" href="${it}" />`).join('')
|
|
||||||
|
|
||||||
const calculatedPrintPage = Utils.calculateObjectValue(this, this.options.printPageBuilder,
|
|
||||||
[table, styles], printPageBuilderDefault(table, styles))
|
|
||||||
const startPrint = () => {
|
|
||||||
newWin.focus()
|
|
||||||
newWin.print()
|
|
||||||
newWin.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
newWin.document.write(calculatedPrintPage)
|
|
||||||
newWin.document.close()
|
|
||||||
|
|
||||||
if (printStyles.length) {
|
|
||||||
const links = document.getElementsByTagName('link')
|
|
||||||
const lastLink = links[links.length - 1]
|
|
||||||
|
|
||||||
lastLink.onload = startPrint
|
|
||||||
} else {
|
|
||||||
startPrint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,212 +0,0 @@
|
||||||
/**
|
|
||||||
* @author: Dennis Hernández
|
|
||||||
* @update: https://github.com/wenzhixin
|
|
||||||
* @version: v1.2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
$.akottr.dragtable.prototype._restoreState = function (persistObj) {
|
|
||||||
let i = 0
|
|
||||||
|
|
||||||
for (const [field, value] of Object.entries(persistObj)) {
|
|
||||||
const $th = this.originalTable.el.find(`th[data-field="${field}"]`)
|
|
||||||
|
|
||||||
if (!$th.length) {
|
|
||||||
i++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
this.originalTable.startIndex = $th.prevAll().length + 1
|
|
||||||
this.originalTable.endIndex = parseInt(value, 10) + 1 - i
|
|
||||||
this._bubbleCols()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// From MDN site, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
|
|
||||||
const filterFn = () => {
|
|
||||||
if (!Array.prototype.filter) {
|
|
||||||
Array.prototype.filter = function (fun/* , thisArg*/) {
|
|
||||||
if (this === undefined || this === null) {
|
|
||||||
throw new TypeError()
|
|
||||||
}
|
|
||||||
|
|
||||||
const t = Object(this)
|
|
||||||
const len = t.length >>> 0
|
|
||||||
|
|
||||||
if (typeof fun !== 'function') {
|
|
||||||
throw new TypeError()
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = []
|
|
||||||
const thisArg = arguments.length >= 2 ? arguments[1] : undefined
|
|
||||||
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
if (i in t) {
|
|
||||||
const val = t[i]
|
|
||||||
|
|
||||||
// NOTE: Technically this should Object.defineProperty at
|
|
||||||
// the next index, as push can be affected by
|
|
||||||
// properties on Object.prototype and Array.prototype.
|
|
||||||
// But this method's new, and collisions should be
|
|
||||||
// rare, so use the more-compatible alternative.
|
|
||||||
if (fun.call(thisArg, val, i, t)) {
|
|
||||||
res.push(val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.defaults, {
|
|
||||||
reorderableColumns: false,
|
|
||||||
maxMovingRows: 10,
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
onReorderColumn (headerFields) {
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
dragaccept: null
|
|
||||||
})
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.events, {
|
|
||||||
'reorder-column.bs.table': 'onReorderColumn'
|
|
||||||
})
|
|
||||||
|
|
||||||
$.fn.bootstrapTable.methods.push('orderColumns')
|
|
||||||
|
|
||||||
$.BootstrapTable = class extends $.BootstrapTable {
|
|
||||||
initHeader (...args) {
|
|
||||||
super.initHeader(...args)
|
|
||||||
|
|
||||||
if (!this.options.reorderableColumns) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.makeColumnsReorderable()
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleColumn (...args) {
|
|
||||||
super._toggleColumn(...args)
|
|
||||||
|
|
||||||
if (!this.options.reorderableColumns) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.makeColumnsReorderable()
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleView (...args) {
|
|
||||||
super.toggleView(...args)
|
|
||||||
|
|
||||||
if (!this.options.reorderableColumns) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options.cardView) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.makeColumnsReorderable()
|
|
||||||
}
|
|
||||||
|
|
||||||
resetView (...args) {
|
|
||||||
super.resetView(...args)
|
|
||||||
|
|
||||||
if (!this.options.reorderableColumns) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.makeColumnsReorderable()
|
|
||||||
}
|
|
||||||
|
|
||||||
makeColumnsReorderable (order = null) {
|
|
||||||
try {
|
|
||||||
$(this.$el).dragtable('destroy')
|
|
||||||
} catch (e) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
$(this.$el).dragtable({
|
|
||||||
maxMovingRows: this.options.maxMovingRows,
|
|
||||||
dragaccept: this.options.dragaccept,
|
|
||||||
clickDelay: 200,
|
|
||||||
dragHandle: '.th-inner',
|
|
||||||
restoreState: order ? order : this.columnsSortOrder,
|
|
||||||
beforeStop: table => {
|
|
||||||
const sortOrder = {}
|
|
||||||
|
|
||||||
table.el.find('th').each((i, el) => {
|
|
||||||
sortOrder[$(el).data('field')] = i
|
|
||||||
})
|
|
||||||
|
|
||||||
this.columnsSortOrder = sortOrder
|
|
||||||
if (this.options.cookie) {
|
|
||||||
this.persistReorderColumnsState(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
const ths = []
|
|
||||||
const formatters = []
|
|
||||||
const columns = []
|
|
||||||
let columnsHidden = []
|
|
||||||
let columnIndex = -1
|
|
||||||
const optionsColumns = []
|
|
||||||
|
|
||||||
this.$header.find('th:not(.detail)').each((i, el) => {
|
|
||||||
ths.push($(el).data('field'))
|
|
||||||
formatters.push($(el).data('formatter'))
|
|
||||||
})
|
|
||||||
|
|
||||||
// Exist columns not shown
|
|
||||||
if (ths.length < this.columns.length) {
|
|
||||||
columnsHidden = this.columns.filter(column => !column.visible)
|
|
||||||
for (let i = 0; i < columnsHidden.length; i++) {
|
|
||||||
ths.push(columnsHidden[i].field)
|
|
||||||
formatters.push(columnsHidden[i].formatter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < ths.length; i++) {
|
|
||||||
columnIndex = this.fieldsColumnsIndex[ths[i]]
|
|
||||||
if (columnIndex !== -1) {
|
|
||||||
this.fieldsColumnsIndex[ths[i]] = i
|
|
||||||
this.columns[columnIndex].fieldIndex = i
|
|
||||||
columns.push(this.columns[columnIndex])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.columns = columns
|
|
||||||
|
|
||||||
filterFn() // Support <IE9
|
|
||||||
$.each(this.columns, (i, column) => {
|
|
||||||
let found = false
|
|
||||||
const field = column.field
|
|
||||||
|
|
||||||
this.options.columns[0].filter(item => {
|
|
||||||
if (!found && item['field'] === field) {
|
|
||||||
optionsColumns.push(item)
|
|
||||||
found = true
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
this.options.columns[0] = optionsColumns
|
|
||||||
|
|
||||||
this.header.fields = ths
|
|
||||||
this.header.formatters = formatters
|
|
||||||
this.initHeader()
|
|
||||||
this.initToolbar()
|
|
||||||
this.initSearchText()
|
|
||||||
this.initBody()
|
|
||||||
this.resetView()
|
|
||||||
this.trigger('reorder-column', ths)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
orderColumns (order) {
|
|
||||||
this.columnsSortOrder = order
|
|
||||||
this.makeColumnsReorderable()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,145 +0,0 @@
|
||||||
/**
|
|
||||||
* @author: Dennis Hernández
|
|
||||||
* @update zhixin wen <wenzhixin2010@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
const rowAttr = (row, index) => ({
|
|
||||||
id: `customId_${index}`
|
|
||||||
})
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.defaults, {
|
|
||||||
reorderableRows: false,
|
|
||||||
onDragStyle: null,
|
|
||||||
onDropStyle: null,
|
|
||||||
onDragClass: 'reorder-rows-on-drag-class',
|
|
||||||
dragHandle: '>tbody>tr>td:not(.bs-checkbox)',
|
|
||||||
useRowAttrFunc: false,
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
onReorderRowsDrag (row) {
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
onReorderRowsDrop (row) {
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
onReorderRow (newData) {
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
onDragStop () {},
|
|
||||||
onAllowDrop () {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.events, {
|
|
||||||
'reorder-row.bs.table': 'onReorderRow'
|
|
||||||
})
|
|
||||||
|
|
||||||
$.BootstrapTable = class extends $.BootstrapTable {
|
|
||||||
init (...args) {
|
|
||||||
if (!this.options.reorderableRows) {
|
|
||||||
super.init(...args)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options.useRowAttrFunc) {
|
|
||||||
this.options.rowAttributes = rowAttr
|
|
||||||
}
|
|
||||||
|
|
||||||
const onPostBody = this.options.onPostBody
|
|
||||||
|
|
||||||
this.options.onPostBody = () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.makeRowsReorderable()
|
|
||||||
onPostBody.call(this.options, this.options.data)
|
|
||||||
}, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
super.init(...args)
|
|
||||||
}
|
|
||||||
|
|
||||||
makeRowsReorderable () {
|
|
||||||
this.$el.tableDnD({
|
|
||||||
onDragStyle: this.options.onDragStyle,
|
|
||||||
onDropStyle: this.options.onDropStyle,
|
|
||||||
onDragClass: this.options.onDragClass,
|
|
||||||
onAllowDrop: (hoveredRow, draggedRow) => this.onAllowDrop(hoveredRow, draggedRow),
|
|
||||||
onDragStop: (table, draggedRow) => this.onDragStop(table, draggedRow),
|
|
||||||
onDragStart: (table, droppedRow) => this.onDropStart(table, droppedRow),
|
|
||||||
onDrop: (table, droppedRow) => this.onDrop(table, droppedRow),
|
|
||||||
dragHandle: this.options.dragHandle
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onDropStart (table, draggingTd) {
|
|
||||||
this.$draggingTd = $(draggingTd).css('cursor', 'move')
|
|
||||||
this.draggingIndex = $(this.$draggingTd.parent()).data('index')
|
|
||||||
// Call the user defined function
|
|
||||||
this.options.onReorderRowsDrag(this.data[this.draggingIndex])
|
|
||||||
}
|
|
||||||
|
|
||||||
onDragStop (table, draggedRow) {
|
|
||||||
const rowIndexDraggedRow = $(draggedRow).data('index')
|
|
||||||
const draggedRowItem = this.data[rowIndexDraggedRow]
|
|
||||||
|
|
||||||
this.options.onDragStop(table, draggedRowItem, draggedRow)
|
|
||||||
}
|
|
||||||
|
|
||||||
onAllowDrop (hoveredRow, draggedRow) {
|
|
||||||
const rowIndexDraggedRow = $(draggedRow).data('index')
|
|
||||||
const rowIndexHoveredRow = $(hoveredRow).data('index')
|
|
||||||
const draggedRowItem = this.data[rowIndexDraggedRow]
|
|
||||||
const hoveredRowItem = this.data[rowIndexHoveredRow]
|
|
||||||
|
|
||||||
return this.options.onAllowDrop(hoveredRowItem, draggedRowItem, hoveredRow, draggedRow)
|
|
||||||
}
|
|
||||||
|
|
||||||
onDrop (table) {
|
|
||||||
this.$draggingTd.css('cursor', '')
|
|
||||||
const pageNum = this.options.pageNumber
|
|
||||||
const pageSize = this.options.pageSize
|
|
||||||
const newData = []
|
|
||||||
|
|
||||||
for (let i = 0; i < table.tBodies[0].rows.length; i++) {
|
|
||||||
const $tr = $(table.tBodies[0].rows[i])
|
|
||||||
|
|
||||||
newData.push(this.data[$tr.data('index')])
|
|
||||||
$tr.data('index', i)
|
|
||||||
}
|
|
||||||
|
|
||||||
const draggingRow = this.data[this.draggingIndex]
|
|
||||||
const droppedIndex = newData.indexOf(this.data[this.draggingIndex])
|
|
||||||
const droppedRow = this.data[droppedIndex]
|
|
||||||
const index = (pageNum - 1) * pageSize + this.options.data.indexOf(this.data[droppedIndex])
|
|
||||||
|
|
||||||
this.options.data.splice(this.options.data.indexOf(draggingRow), 1)
|
|
||||||
this.options.data.splice(index, 0, draggingRow)
|
|
||||||
|
|
||||||
this.initSearch()
|
|
||||||
|
|
||||||
if (this.options.sidePagination === 'server') {
|
|
||||||
this.data = [...this.options.data]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the user defined function
|
|
||||||
this.options.onReorderRowsDrop(droppedRow)
|
|
||||||
|
|
||||||
// Call the event reorder-row
|
|
||||||
this.trigger('reorder-row', newData, draggingRow, droppedRow)
|
|
||||||
}
|
|
||||||
|
|
||||||
initSearch () {
|
|
||||||
this.ignoreInitSort = true
|
|
||||||
super.initSearch()
|
|
||||||
}
|
|
||||||
|
|
||||||
initSort () {
|
|
||||||
if (this.ignoreInitSort) {
|
|
||||||
this.ignoreInitSort = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
super.initSort()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,603 +0,0 @@
|
||||||
/**
|
|
||||||
* TableDnD plug-in for JQuery, allows you to drag and drop table rows
|
|
||||||
* You can set up various options to control how the system will work
|
|
||||||
* Copyright (c) Denis Howlett <denish@isocra.com>
|
|
||||||
* License: MIT.
|
|
||||||
* See https://github.com/isocra/TableDnD
|
|
||||||
*/
|
|
||||||
!function ($, window, document, undefined) {
|
|
||||||
|
|
||||||
var startEvent = 'touchstart mousedown',
|
|
||||||
moveEvent = 'touchmove mousemove',
|
|
||||||
endEvent = 'touchend mouseup';
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
function parseStyle(css) {
|
|
||||||
var objMap = {},
|
|
||||||
parts = css.match(/([^;:]+)/g) || [];
|
|
||||||
while (parts.length)
|
|
||||||
objMap[parts.shift()] = parts.shift().trim();
|
|
||||||
|
|
||||||
return objMap;
|
|
||||||
}
|
|
||||||
$('table').each(function () {
|
|
||||||
if ($(this).data('table') === 'dnd') {
|
|
||||||
|
|
||||||
$(this).tableDnD({
|
|
||||||
onDragStyle: $(this).data('ondragstyle') && parseStyle($(this).data('ondragstyle')) || null,
|
|
||||||
onDropStyle: $(this).data('ondropstyle') && parseStyle($(this).data('ondropstyle')) || null,
|
|
||||||
onDragClass: $(this).data('ondragclass') === undefined && "tDnD_whileDrag" || $(this).data('ondragclass'),
|
|
||||||
onDrop: $(this).data('ondrop') && new Function('table', 'row', $(this).data('ondrop')), // 'return eval("'+$(this).data('ondrop')+'");') || null,
|
|
||||||
onDragStart: $(this).data('ondragstart') && new Function('table', 'row' ,$(this).data('ondragstart')), // 'return eval("'+$(this).data('ondragstart')+'");') || null,
|
|
||||||
onDragStop: $(this).data('ondragstop') && new Function('table', 'row' ,$(this).data('ondragstop')),
|
|
||||||
scrollAmount: $(this).data('scrollamount') || 5,
|
|
||||||
sensitivity: $(this).data('sensitivity') || 10,
|
|
||||||
hierarchyLevel: $(this).data('hierarchylevel') || 0,
|
|
||||||
indentArtifact: $(this).data('indentartifact') || '<div class="indent"> </div>',
|
|
||||||
autoWidthAdjust: $(this).data('autowidthadjust') || true,
|
|
||||||
autoCleanRelations: $(this).data('autocleanrelations') || true,
|
|
||||||
jsonPretifySeparator: $(this).data('jsonpretifyseparator') || '\t',
|
|
||||||
serializeRegexp: $(this).data('serializeregexp') && new RegExp($(this).data('serializeregexp')) || /[^\-]*$/,
|
|
||||||
serializeParamName: $(this).data('serializeparamname') || false,
|
|
||||||
dragHandle: $(this).data('draghandle') || null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
jQuery.tableDnD = {
|
|
||||||
/** Keep hold of the current table being dragged */
|
|
||||||
currentTable: null,
|
|
||||||
/** Keep hold of the current drag object if any */
|
|
||||||
dragObject: null,
|
|
||||||
/** The current mouse offset */
|
|
||||||
mouseOffset: null,
|
|
||||||
/** Remember the old value of X and Y so that we don't do too much processing */
|
|
||||||
oldX: 0,
|
|
||||||
oldY: 0,
|
|
||||||
|
|
||||||
/** Actually build the structure */
|
|
||||||
build: function(options) {
|
|
||||||
// Set up the defaults if any
|
|
||||||
|
|
||||||
this.each(function() {
|
|
||||||
// This is bound to each matching table, set up the defaults and override with user options
|
|
||||||
this.tableDnDConfig = $.extend({
|
|
||||||
onDragStyle: null,
|
|
||||||
onDropStyle: null,
|
|
||||||
// Add in the default class for whileDragging
|
|
||||||
onDragClass: "tDnD_whileDrag",
|
|
||||||
onDrop: null,
|
|
||||||
onDragStart: null,
|
|
||||||
onDragStop: null,
|
|
||||||
scrollAmount: 5,
|
|
||||||
/** Sensitivity setting will throttle the trigger rate for movement detection */
|
|
||||||
sensitivity: 10,
|
|
||||||
/** Hierarchy level to support parent child. 0 switches this functionality off */
|
|
||||||
hierarchyLevel: 0,
|
|
||||||
/** The html artifact to prepend the first cell with as indentation */
|
|
||||||
indentArtifact: '<div class="indent"> </div>',
|
|
||||||
/** Automatically adjust width of first cell */
|
|
||||||
autoWidthAdjust: true,
|
|
||||||
/** Automatic clean-up to ensure relationship integrity */
|
|
||||||
autoCleanRelations: true,
|
|
||||||
/** Specify a number (4) as number of spaces or any indent string for JSON.stringify */
|
|
||||||
jsonPretifySeparator: '\t',
|
|
||||||
/** The regular expression to use to trim row IDs */
|
|
||||||
serializeRegexp: /[^\-]*$/,
|
|
||||||
/** If you want to specify another parameter name instead of the table ID */
|
|
||||||
serializeParamName: false,
|
|
||||||
/** If you give the name of a class here, then only Cells with this class will be draggable */
|
|
||||||
dragHandle: null
|
|
||||||
}, options || {});
|
|
||||||
|
|
||||||
// Now make the rows draggable
|
|
||||||
$.tableDnD.makeDraggable(this);
|
|
||||||
// Prepare hierarchy support
|
|
||||||
this.tableDnDConfig.hierarchyLevel
|
|
||||||
&& $.tableDnD.makeIndented(this);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Don't break the chain
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
makeIndented: function (table) {
|
|
||||||
var config = table.tableDnDConfig,
|
|
||||||
rows = table.rows,
|
|
||||||
firstCell = $(rows).first().find('td:first')[0],
|
|
||||||
indentLevel = 0,
|
|
||||||
cellWidth = 0,
|
|
||||||
longestCell,
|
|
||||||
tableStyle;
|
|
||||||
|
|
||||||
if ($(table).hasClass('indtd'))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
tableStyle = $(table).addClass('indtd').attr('style');
|
|
||||||
$(table).css({whiteSpace: "nowrap"});
|
|
||||||
|
|
||||||
for (var w = 0; w < rows.length; w++) {
|
|
||||||
if (cellWidth < $(rows[w]).find('td:first').text().length) {
|
|
||||||
cellWidth = $(rows[w]).find('td:first').text().length;
|
|
||||||
longestCell = w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$(firstCell).css({width: 'auto'});
|
|
||||||
for (w = 0; w < config.hierarchyLevel; w++)
|
|
||||||
$(rows[longestCell]).find('td:first').prepend(config.indentArtifact);
|
|
||||||
firstCell && $(firstCell).css({width: firstCell.offsetWidth});
|
|
||||||
tableStyle && $(table).css(tableStyle);
|
|
||||||
|
|
||||||
for (w = 0; w < config.hierarchyLevel; w++)
|
|
||||||
$(rows[longestCell]).find('td:first').children(':first').remove();
|
|
||||||
|
|
||||||
config.hierarchyLevel
|
|
||||||
&& $(rows).each(function () {
|
|
||||||
indentLevel = $(this).data('level') || 0;
|
|
||||||
indentLevel <= config.hierarchyLevel
|
|
||||||
&& $(this).data('level', indentLevel)
|
|
||||||
|| $(this).data('level', 0);
|
|
||||||
for (var i = 0; i < $(this).data('level'); i++)
|
|
||||||
$(this).find('td:first').prepend(config.indentArtifact);
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
/** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */
|
|
||||||
makeDraggable: function(table) {
|
|
||||||
var config = table.tableDnDConfig;
|
|
||||||
|
|
||||||
config.dragHandle
|
|
||||||
// We only need to add the event to the specified cells
|
|
||||||
&& $(config.dragHandle, table).each(function() {
|
|
||||||
if (! $(this).hasClass("nodrag")) {
|
|
||||||
// The cell is bound to "this"
|
|
||||||
$(this).bind(startEvent, function(e) {
|
|
||||||
if (e.target.tagName === "TD" && event.target.className !== "nodrag") {
|
|
||||||
$.tableDnD.initialiseDrag($(this).parents('tr')[0], table, this, e, config);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// For backwards compatibility, we add the event to the whole row
|
|
||||||
// get all the rows as a wrapped set
|
|
||||||
|| $(table.rows).each(function() {
|
|
||||||
// Iterate through each row, the row is bound to "this"
|
|
||||||
if (! $(this).hasClass("nodrag")) {
|
|
||||||
$(this).bind(startEvent, function(e) {
|
|
||||||
if (e.target.tagName === "TD" && event.target.className !== "nodrag") {
|
|
||||||
$.tableDnD.initialiseDrag(this, table, this, e, config);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}).css("cursor", "move"); // Store the tableDnD object
|
|
||||||
} else {
|
|
||||||
$(this).css("cursor", ""); // Remove the cursor if we don't have the nodrag class
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
currentOrder: function() {
|
|
||||||
var rows = this.currentTable.rows;
|
|
||||||
return $.map(rows, function (val) {
|
|
||||||
return ($(val).data('level') + val.id).replace(/\s/g, '');
|
|
||||||
}).join('');
|
|
||||||
},
|
|
||||||
initialiseDrag: function(dragObject, table, target, e, config) {
|
|
||||||
this.dragObject = dragObject;
|
|
||||||
this.currentTable = table;
|
|
||||||
this.mouseOffset = this.getMouseOffset(target, e);
|
|
||||||
this.originalOrder = this.currentOrder();
|
|
||||||
|
|
||||||
// Now we need to capture the mouse up and mouse move event
|
|
||||||
// We can use bind so that we don't interfere with other event handlers
|
|
||||||
$(document)
|
|
||||||
.bind(moveEvent, this.mousemove)
|
|
||||||
.bind(endEvent, this.mouseup);
|
|
||||||
|
|
||||||
// Call the onDragStart method if there is one
|
|
||||||
config.onDragStart
|
|
||||||
&& config.onDragStart(table, target);
|
|
||||||
},
|
|
||||||
updateTables: function() {
|
|
||||||
this.each(function() {
|
|
||||||
// this is now bound to each matching table
|
|
||||||
if (this.tableDnDConfig)
|
|
||||||
$.tableDnD.makeDraggable(this);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** Get the mouse coordinates from the event (allowing for browser differences) */
|
|
||||||
mouseCoords: function(e) {
|
|
||||||
if (e.originalEvent.changedTouches)
|
|
||||||
return {
|
|
||||||
x: e.originalEvent.changedTouches[0].clientX,
|
|
||||||
y: e.originalEvent.changedTouches[0].clientY
|
|
||||||
};
|
|
||||||
|
|
||||||
if(e.pageX || e.pageY)
|
|
||||||
return {
|
|
||||||
x: e.pageX,
|
|
||||||
y: e.pageY
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
x: e.clientX + document.body.scrollLeft - document.body.clientLeft,
|
|
||||||
y: e.clientY + document.body.scrollTop - document.body.clientTop
|
|
||||||
};
|
|
||||||
},
|
|
||||||
/** Given a target element and a mouse eent, get the mouse offset from that element.
|
|
||||||
To do this we need the element's position and the mouse position */
|
|
||||||
getMouseOffset: function(target, e) {
|
|
||||||
var mousePos,
|
|
||||||
docPos;
|
|
||||||
|
|
||||||
e = e || window.event;
|
|
||||||
|
|
||||||
docPos = this.getPosition(target);
|
|
||||||
mousePos = this.mouseCoords(e);
|
|
||||||
|
|
||||||
return {
|
|
||||||
x: mousePos.x - docPos.x,
|
|
||||||
y: mousePos.y - docPos.y
|
|
||||||
};
|
|
||||||
},
|
|
||||||
/** Get the position of an element by going up the DOM tree and adding up all the offsets */
|
|
||||||
getPosition: function(element) {
|
|
||||||
var left = 0,
|
|
||||||
top = 0;
|
|
||||||
|
|
||||||
// Safari fix -- thanks to Luis Chato for this!
|
|
||||||
// Safari 2 doesn't correctly grab the offsetTop of a table row
|
|
||||||
// this is detailed here:
|
|
||||||
// http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/
|
|
||||||
// the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild.
|
|
||||||
// note that firefox will return a text node as a first child, so designing a more thorough
|
|
||||||
// solution may need to take that into account, for now this seems to work in firefox, safari, ie
|
|
||||||
if (element.offsetHeight === 0)
|
|
||||||
element = element.firstChild; // a table cell
|
|
||||||
|
|
||||||
while (element.offsetParent) {
|
|
||||||
left += element.offsetLeft;
|
|
||||||
top += element.offsetTop;
|
|
||||||
element = element.offsetParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
left += element.offsetLeft;
|
|
||||||
top += element.offsetTop;
|
|
||||||
|
|
||||||
return {
|
|
||||||
x: left,
|
|
||||||
y: top
|
|
||||||
};
|
|
||||||
},
|
|
||||||
autoScroll: function (mousePos) {
|
|
||||||
var config = this.currentTable.tableDnDConfig,
|
|
||||||
yOffset = window.pageYOffset,
|
|
||||||
windowHeight = window.innerHeight
|
|
||||||
? window.innerHeight
|
|
||||||
: document.documentElement.clientHeight
|
|
||||||
? document.documentElement.clientHeight
|
|
||||||
: document.body.clientHeight;
|
|
||||||
|
|
||||||
// Windows version
|
|
||||||
// yOffset=document.body.scrollTop;
|
|
||||||
if (document.all)
|
|
||||||
if (typeof document.compatMode !== 'undefined'
|
|
||||||
&& document.compatMode !== 'BackCompat')
|
|
||||||
yOffset = document.documentElement.scrollTop;
|
|
||||||
else if (typeof document.body !== 'undefined')
|
|
||||||
yOffset = document.body.scrollTop;
|
|
||||||
|
|
||||||
mousePos.y - yOffset < config.scrollAmount
|
|
||||||
&& window.scrollBy(0, - config.scrollAmount)
|
|
||||||
|| windowHeight - (mousePos.y - yOffset) < config.scrollAmount
|
|
||||||
&& window.scrollBy(0, config.scrollAmount);
|
|
||||||
|
|
||||||
},
|
|
||||||
moveVerticle: function (moving, currentRow) {
|
|
||||||
|
|
||||||
if (0 !== moving.vertical
|
|
||||||
// If we're over a row then move the dragged row to there so that the user sees the
|
|
||||||
// effect dynamically
|
|
||||||
&& currentRow
|
|
||||||
&& this.dragObject !== currentRow
|
|
||||||
&& this.dragObject.parentNode === currentRow.parentNode)
|
|
||||||
0 > moving.vertical
|
|
||||||
&& this.dragObject.parentNode.insertBefore(this.dragObject, currentRow.nextSibling)
|
|
||||||
|| 0 < moving.vertical
|
|
||||||
&& this.dragObject.parentNode.insertBefore(this.dragObject, currentRow);
|
|
||||||
|
|
||||||
},
|
|
||||||
moveHorizontal: function (moving, currentRow) {
|
|
||||||
var config = this.currentTable.tableDnDConfig,
|
|
||||||
currentLevel;
|
|
||||||
|
|
||||||
if (!config.hierarchyLevel
|
|
||||||
|| 0 === moving.horizontal
|
|
||||||
// We only care if moving left or right on the current row
|
|
||||||
|| !currentRow
|
|
||||||
|| this.dragObject !== currentRow)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
currentLevel = $(currentRow).data('level');
|
|
||||||
|
|
||||||
0 < moving.horizontal
|
|
||||||
&& currentLevel > 0
|
|
||||||
&& $(currentRow).find('td:first').children(':first').remove()
|
|
||||||
&& $(currentRow).data('level', --currentLevel);
|
|
||||||
|
|
||||||
0 > moving.horizontal
|
|
||||||
&& currentLevel < config.hierarchyLevel
|
|
||||||
&& $(currentRow).prev().data('level') >= currentLevel
|
|
||||||
&& $(currentRow).children(':first').prepend(config.indentArtifact)
|
|
||||||
&& $(currentRow).data('level', ++currentLevel);
|
|
||||||
|
|
||||||
},
|
|
||||||
mousemove: function(e) {
|
|
||||||
var dragObj = $($.tableDnD.dragObject),
|
|
||||||
config = $.tableDnD.currentTable.tableDnDConfig,
|
|
||||||
currentRow,
|
|
||||||
mousePos,
|
|
||||||
moving,
|
|
||||||
x,
|
|
||||||
y;
|
|
||||||
|
|
||||||
e && e.preventDefault();
|
|
||||||
|
|
||||||
if (!$.tableDnD.dragObject)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// prevent touch device screen scrolling
|
|
||||||
e.type === 'touchmove'
|
|
||||||
&& event.preventDefault(); // TODO verify this is event and not really e
|
|
||||||
|
|
||||||
// update the style to show we're dragging
|
|
||||||
config.onDragClass
|
|
||||||
&& dragObj.addClass(config.onDragClass)
|
|
||||||
|| dragObj.css(config.onDragStyle);
|
|
||||||
|
|
||||||
mousePos = $.tableDnD.mouseCoords(e);
|
|
||||||
x = mousePos.x - $.tableDnD.mouseOffset.x;
|
|
||||||
y = mousePos.y - $.tableDnD.mouseOffset.y;
|
|
||||||
|
|
||||||
// auto scroll the window
|
|
||||||
$.tableDnD.autoScroll(mousePos);
|
|
||||||
|
|
||||||
currentRow = $.tableDnD.findDropTargetRow(dragObj, y);
|
|
||||||
moving = $.tableDnD.findDragDirection(x, y);
|
|
||||||
|
|
||||||
$.tableDnD.moveVerticle(moving, currentRow);
|
|
||||||
$.tableDnD.moveHorizontal(moving, currentRow);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
findDragDirection: function (x,y) {
|
|
||||||
var sensitivity = this.currentTable.tableDnDConfig.sensitivity,
|
|
||||||
oldX = this.oldX,
|
|
||||||
oldY = this.oldY,
|
|
||||||
xMin = oldX - sensitivity,
|
|
||||||
xMax = oldX + sensitivity,
|
|
||||||
yMin = oldY - sensitivity,
|
|
||||||
yMax = oldY + sensitivity,
|
|
||||||
moving = {
|
|
||||||
horizontal: x >= xMin && x <= xMax ? 0 : x > oldX ? -1 : 1,
|
|
||||||
vertical : y >= yMin && y <= yMax ? 0 : y > oldY ? -1 : 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// update the old value
|
|
||||||
if (moving.horizontal !== 0)
|
|
||||||
this.oldX = x;
|
|
||||||
if (moving.vertical !== 0)
|
|
||||||
this.oldY = y;
|
|
||||||
|
|
||||||
return moving;
|
|
||||||
},
|
|
||||||
/** We're only worried about the y position really, because we can only move rows up and down */
|
|
||||||
findDropTargetRow: function(draggedRow, y) {
|
|
||||||
var rowHeight = 0,
|
|
||||||
rows = this.currentTable.rows,
|
|
||||||
config = this.currentTable.tableDnDConfig,
|
|
||||||
rowY = 0,
|
|
||||||
row = null;
|
|
||||||
|
|
||||||
for (var i = 0; i < rows.length; i++) {
|
|
||||||
row = rows[i];
|
|
||||||
rowY = this.getPosition(row).y;
|
|
||||||
rowHeight = parseInt(row.offsetHeight) / 2;
|
|
||||||
if (row.offsetHeight === 0) {
|
|
||||||
rowY = this.getPosition(row.firstChild).y;
|
|
||||||
rowHeight = parseInt(row.firstChild.offsetHeight) / 2;
|
|
||||||
}
|
|
||||||
// Because we always have to insert before, we need to offset the height a bit
|
|
||||||
if (y > (rowY - rowHeight) && y < (rowY + rowHeight))
|
|
||||||
// that's the row we're over
|
|
||||||
// If it's the same as the current row, ignore it
|
|
||||||
if (draggedRow.is(row)
|
|
||||||
|| (config.onAllowDrop
|
|
||||||
&& !config.onAllowDrop(draggedRow, row))
|
|
||||||
// If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic)
|
|
||||||
|| $(row).hasClass("nodrop"))
|
|
||||||
return null;
|
|
||||||
else
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
processMouseup: function() {
|
|
||||||
if (!this.currentTable || !this.dragObject)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var config = this.currentTable.tableDnDConfig,
|
|
||||||
droppedRow = this.dragObject,
|
|
||||||
parentLevel = 0,
|
|
||||||
myLevel = 0;
|
|
||||||
|
|
||||||
// Unbind the event handlers
|
|
||||||
$(document)
|
|
||||||
.unbind(moveEvent, this.mousemove)
|
|
||||||
.unbind(endEvent, this.mouseup);
|
|
||||||
|
|
||||||
config.hierarchyLevel
|
|
||||||
&& config.autoCleanRelations
|
|
||||||
&& $(this.currentTable.rows).first().find('td:first').children().each(function () {
|
|
||||||
myLevel = $(this).parents('tr:first').data('level');
|
|
||||||
myLevel
|
|
||||||
&& $(this).parents('tr:first').data('level', --myLevel)
|
|
||||||
&& $(this).remove();
|
|
||||||
})
|
|
||||||
&& config.hierarchyLevel > 1
|
|
||||||
&& $(this.currentTable.rows).each(function () {
|
|
||||||
myLevel = $(this).data('level');
|
|
||||||
if (myLevel > 1) {
|
|
||||||
parentLevel = $(this).prev().data('level');
|
|
||||||
while (myLevel > parentLevel + 1) {
|
|
||||||
$(this).find('td:first').children(':first').remove();
|
|
||||||
$(this).data('level', --myLevel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// If we have a dragObject, then we need to release it,
|
|
||||||
// The row will already have been moved to the right place so we just reset stuff
|
|
||||||
config.onDragClass
|
|
||||||
&& $(droppedRow).removeClass(config.onDragClass)
|
|
||||||
|| $(droppedRow).css(config.onDropStyle);
|
|
||||||
|
|
||||||
this.dragObject = null;
|
|
||||||
// Call the onDrop method if there is one
|
|
||||||
config.onDrop
|
|
||||||
&& this.originalOrder !== this.currentOrder()
|
|
||||||
&& $(droppedRow).hide().fadeIn('fast')
|
|
||||||
&& config.onDrop(this.currentTable, droppedRow);
|
|
||||||
|
|
||||||
// Call the onDragStop method if there is one
|
|
||||||
config.onDragStop
|
|
||||||
&& config.onDragStop(this.currentTable, droppedRow);
|
|
||||||
|
|
||||||
this.currentTable = null; // let go of the table too
|
|
||||||
},
|
|
||||||
mouseup: function(e) {
|
|
||||||
e && e.preventDefault();
|
|
||||||
$.tableDnD.processMouseup();
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
jsonize: function(pretify) {
|
|
||||||
var table = this.currentTable;
|
|
||||||
if (pretify)
|
|
||||||
return JSON.stringify(
|
|
||||||
this.tableData(table),
|
|
||||||
null,
|
|
||||||
table.tableDnDConfig.jsonPretifySeparator
|
|
||||||
);
|
|
||||||
return JSON.stringify(this.tableData(table));
|
|
||||||
},
|
|
||||||
serialize: function() {
|
|
||||||
return $.param(this.tableData(this.currentTable));
|
|
||||||
},
|
|
||||||
serializeTable: function(table) {
|
|
||||||
var result = "";
|
|
||||||
var paramName = table.tableDnDConfig.serializeParamName || table.id;
|
|
||||||
var rows = table.rows;
|
|
||||||
for (var i=0; i<rows.length; i++) {
|
|
||||||
if (result.length > 0) result += "&";
|
|
||||||
var rowId = rows[i].id;
|
|
||||||
if (rowId && table.tableDnDConfig && table.tableDnDConfig.serializeRegexp) {
|
|
||||||
rowId = rowId.match(table.tableDnDConfig.serializeRegexp)[0];
|
|
||||||
result += paramName + '[]=' + rowId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
serializeTables: function() {
|
|
||||||
var result = [];
|
|
||||||
$('table').each(function() {
|
|
||||||
this.id && result.push($.param($.tableDnD.tableData(this)));
|
|
||||||
});
|
|
||||||
return result.join('&');
|
|
||||||
},
|
|
||||||
tableData: function (table) {
|
|
||||||
var config = table.tableDnDConfig,
|
|
||||||
previousIDs = [],
|
|
||||||
currentLevel = 0,
|
|
||||||
indentLevel = 0,
|
|
||||||
rowID = null,
|
|
||||||
data = {},
|
|
||||||
getSerializeRegexp,
|
|
||||||
paramName,
|
|
||||||
currentID,
|
|
||||||
rows;
|
|
||||||
|
|
||||||
if (!table)
|
|
||||||
table = this.currentTable;
|
|
||||||
if (!table || !table.rows || !table.rows.length)
|
|
||||||
return {error: { code: 500, message: "Not a valid table."}};
|
|
||||||
if (!table.id && !config.serializeParamName)
|
|
||||||
return {error: { code: 500, message: "No serializable unique id provided."}};
|
|
||||||
|
|
||||||
rows = config.autoCleanRelations
|
|
||||||
&& table.rows
|
|
||||||
|| $.makeArray(table.rows);
|
|
||||||
paramName = config.serializeParamName || table.id;
|
|
||||||
currentID = paramName;
|
|
||||||
|
|
||||||
getSerializeRegexp = function (rowId) {
|
|
||||||
if (rowId && config && config.serializeRegexp)
|
|
||||||
return rowId.match(config.serializeRegexp)[0];
|
|
||||||
return rowId;
|
|
||||||
};
|
|
||||||
|
|
||||||
data[currentID] = [];
|
|
||||||
!config.autoCleanRelations
|
|
||||||
&& $(rows[0]).data('level')
|
|
||||||
&& rows.unshift({id: 'undefined'});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (var i=0; i < rows.length; i++) {
|
|
||||||
if (config.hierarchyLevel) {
|
|
||||||
indentLevel = $(rows[i]).data('level') || 0;
|
|
||||||
if (indentLevel === 0) {
|
|
||||||
currentID = paramName;
|
|
||||||
previousIDs = [];
|
|
||||||
}
|
|
||||||
else if (indentLevel > currentLevel) {
|
|
||||||
previousIDs.push([currentID, currentLevel]);
|
|
||||||
currentID = getSerializeRegexp(rows[i-1].id);
|
|
||||||
}
|
|
||||||
else if (indentLevel < currentLevel) {
|
|
||||||
for (var h = 0; h < previousIDs.length; h++) {
|
|
||||||
if (previousIDs[h][1] === indentLevel)
|
|
||||||
currentID = previousIDs[h][0];
|
|
||||||
if (previousIDs[h][1] >= currentLevel)
|
|
||||||
previousIDs[h][1] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentLevel = indentLevel;
|
|
||||||
|
|
||||||
if (!$.isArray(data[currentID]))
|
|
||||||
data[currentID] = [];
|
|
||||||
rowID = getSerializeRegexp(rows[i].id);
|
|
||||||
rowID && data[currentID].push(rowID);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rowID = getSerializeRegexp(rows[i].id);
|
|
||||||
rowID && data[currentID].push(rowID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
jQuery.fn.extend(
|
|
||||||
{
|
|
||||||
tableDnD : $.tableDnD.build,
|
|
||||||
tableDnDUpdate : $.tableDnD.updateTables,
|
|
||||||
tableDnDSerialize : $.proxy($.tableDnD.serialize, $.tableDnD),
|
|
||||||
tableDnDSerializeAll : $.tableDnD.serializeTables,
|
|
||||||
tableDnDData : $.proxy($.tableDnD.tableData, $.tableDnD)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
}(jQuery, window, window.document);
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
/**
|
|
||||||
* @author: Dennis Hernández
|
|
||||||
* @version: v2.0.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
const isInit = that => that.$el.data('resizableColumns') !== undefined
|
|
||||||
|
|
||||||
const initResizable = that => {
|
|
||||||
if (
|
|
||||||
that.options.resizable &&
|
|
||||||
!that.options.cardView &&
|
|
||||||
!isInit(that) &&
|
|
||||||
that.$el.is(':visible')
|
|
||||||
) {
|
|
||||||
that.$el.resizableColumns({
|
|
||||||
store: window.store
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const destroy = that => {
|
|
||||||
if (isInit(that)) {
|
|
||||||
that.$el.data('resizableColumns').destroy()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const reInitResizable = that => {
|
|
||||||
destroy(that)
|
|
||||||
initResizable(that)
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign($.fn.bootstrapTable.defaults, {
|
|
||||||
resizable: false
|
|
||||||
})
|
|
||||||
|
|
||||||
$.BootstrapTable = class extends $.BootstrapTable {
|
|
||||||
|
|
||||||
initBody (...args) {
|
|
||||||
super.initBody(...args)
|
|
||||||
|
|
||||||
this.$el.off('column-switch.bs.table page-change.bs.table')
|
|
||||||
.on('column-switch.bs.table page-change.bs.table', () => {
|
|
||||||
reInitResizable(this)
|
|
||||||
})
|
|
||||||
|
|
||||||
reInitResizable(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleView (...args) {
|
|
||||||
super.toggleView(...args)
|
|
||||||
|
|
||||||
if (this.options.resizable && this.options.cardView) {
|
|
||||||
// Destroy the plugin
|
|
||||||
destroy(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resetView (...args) {
|
|
||||||
super.resetView(...args)
|
|
||||||
|
|
||||||
if (this.options.resizable) {
|
|
||||||
// because in fitHeader function, we use setTimeout(func, 100);
|
|
||||||
setTimeout(() => {
|
|
||||||
initResizable(this)
|
|
||||||
}, 100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,211 @@
|
||||||
|
/**
|
||||||
|
* @author: aperez <aperez@datadec.es>
|
||||||
|
* @version: v2.0.0
|
||||||
|
*
|
||||||
|
* @update Dennis Hernández <http://djhvscf.github.io/Blog>
|
||||||
|
*/
|
||||||
|
|
||||||
|
!function($) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var firstLoad = false;
|
||||||
|
|
||||||
|
var sprintf = $.fn.bootstrapTable.utils.sprintf;
|
||||||
|
|
||||||
|
var showAvdSearch = function(pColumns, searchTitle, searchText, that) {
|
||||||
|
if (!$("#avdSearchModal" + "_" + that.options.idTable).hasClass("modal")) {
|
||||||
|
var vModal = sprintf("<div id=\"avdSearchModal%s\" class=\"modal fade\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"mySmallModalLabel\" aria-hidden=\"true\">", "_" + that.options.idTable);
|
||||||
|
vModal += "<div class=\"modal-dialog modal-xs\">";
|
||||||
|
vModal += " <div class=\"modal-content\">";
|
||||||
|
vModal += " <div class=\"modal-header\">";
|
||||||
|
vModal += " <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\" >×</button>";
|
||||||
|
vModal += sprintf(" <h4 class=\"modal-title\">%s</h4>", searchTitle);
|
||||||
|
vModal += " </div>";
|
||||||
|
vModal += " <div class=\"modal-body modal-body-custom\">";
|
||||||
|
vModal += sprintf(" <div class=\"container-fluid\" id=\"avdSearchModalContent%s\" style=\"padding-right: 0px;padding-left: 0px;\" >", "_" + that.options.idTable);
|
||||||
|
vModal += " </div>";
|
||||||
|
vModal += " </div>";
|
||||||
|
vModal += " </div>";
|
||||||
|
vModal += " </div>";
|
||||||
|
vModal += "</div>";
|
||||||
|
|
||||||
|
$("body").append($(vModal));
|
||||||
|
|
||||||
|
var vFormAvd = createFormAvd(pColumns, searchText, that),
|
||||||
|
timeoutId = 0;;
|
||||||
|
|
||||||
|
$('#avdSearchModalContent' + "_" + that.options.idTable).append(vFormAvd.join(''));
|
||||||
|
|
||||||
|
$('#' + that.options.idForm).off('keyup blur', 'input').on('keyup blur', 'input', function (event) {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
timeoutId = setTimeout(function () {
|
||||||
|
that.onColumnAdvancedSearch(event);
|
||||||
|
}, that.options.searchTimeOut);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#btnCloseAvd" + "_" + that.options.idTable).click(function() {
|
||||||
|
$("#avdSearchModal" + "_" + that.options.idTable).modal('hide');
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#avdSearchModal" + "_" + that.options.idTable).modal();
|
||||||
|
} else {
|
||||||
|
$("#avdSearchModal" + "_" + that.options.idTable).modal();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var createFormAvd = function(pColumns, searchText, that) {
|
||||||
|
var htmlForm = [];
|
||||||
|
htmlForm.push(sprintf('<form class="form-horizontal" id="%s" action="%s" >', that.options.idForm, that.options.actionForm));
|
||||||
|
for (var i in pColumns) {
|
||||||
|
var vObjCol = pColumns[i];
|
||||||
|
if (!vObjCol.checkbox && vObjCol.visible && vObjCol.searchable) {
|
||||||
|
htmlForm.push('<div class="form-group">');
|
||||||
|
htmlForm.push(sprintf('<label class="col-sm-4 control-label">%s</label>', vObjCol.title));
|
||||||
|
htmlForm.push('<div class="col-sm-6">');
|
||||||
|
htmlForm.push(sprintf('<input type="text" class="form-control input-md" name="%s" placeholder="%s" id="%s">', vObjCol.field, vObjCol.title, vObjCol.field));
|
||||||
|
htmlForm.push('</div>');
|
||||||
|
htmlForm.push('</div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
htmlForm.push('<div class="form-group">');
|
||||||
|
htmlForm.push('<div class="col-sm-offset-9 col-sm-3">');
|
||||||
|
htmlForm.push(sprintf('<button type="button" id="btnCloseAvd%s" class="btn btn-default" >%s</button>', "_" + that.options.idTable, searchText));
|
||||||
|
htmlForm.push('</div>');
|
||||||
|
htmlForm.push('</div>');
|
||||||
|
htmlForm.push('</form>');
|
||||||
|
|
||||||
|
return htmlForm;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
advancedSearch: false,
|
||||||
|
idForm: 'advancedSearch',
|
||||||
|
actionForm: '',
|
||||||
|
idTable: undefined,
|
||||||
|
onColumnAdvancedSearch: function (field, text) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults.icons, {
|
||||||
|
advancedSearchIcon: 'glyphicon-chevron-down'
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
||||||
|
'column-advanced-search.bs.table': 'onColumnAdvancedSearch'
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.locales, {
|
||||||
|
formatAdvancedSearch: function() {
|
||||||
|
return 'Advanced search';
|
||||||
|
},
|
||||||
|
formatAdvancedCloseButton: function() {
|
||||||
|
return "Close";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
|
||||||
|
|
||||||
|
var BootstrapTable = $.fn.bootstrapTable.Constructor,
|
||||||
|
_initToolbar = BootstrapTable.prototype.initToolbar,
|
||||||
|
_load = BootstrapTable.prototype.load,
|
||||||
|
_initSearch = BootstrapTable.prototype.initSearch;
|
||||||
|
|
||||||
|
BootstrapTable.prototype.initToolbar = function() {
|
||||||
|
_initToolbar.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
|
|
||||||
|
if (!this.options.search) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.options.advancedSearch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.options.idTable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var that = this,
|
||||||
|
html = [];
|
||||||
|
|
||||||
|
html.push(sprintf('<div class="columns columns-%s btn-group pull-%s" role="group">', this.options.buttonsAlign, this.options.buttonsAlign));
|
||||||
|
html.push(sprintf('<button class="btn btn-default%s' + '" type="button" name="advancedSearch" title="%s">', that.options.iconSize === undefined ? '' : ' btn-' + that.options.iconSize, that.options.formatAdvancedSearch()));
|
||||||
|
html.push(sprintf('<i class="%s %s"></i>', that.options.iconsPrefix, that.options.icons.advancedSearchIcon))
|
||||||
|
html.push('</button></div>');
|
||||||
|
|
||||||
|
that.$toolbar.prepend(html.join(''));
|
||||||
|
|
||||||
|
that.$toolbar.find('button[name="advancedSearch"]')
|
||||||
|
.off('click').on('click', function() {
|
||||||
|
showAvdSearch(that.columns, that.options.formatAdvancedSearch(), that.options.formatAdvancedCloseButton(), that);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
BootstrapTable.prototype.load = function(data) {
|
||||||
|
_load.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
|
|
||||||
|
if (!this.options.advancedSearch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof this.options.idTable === 'undefined') {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (!firstLoad) {
|
||||||
|
var height = parseInt($(".bootstrap-table").height());
|
||||||
|
height += 10;
|
||||||
|
$("#" + this.options.idTable).bootstrapTable("resetView", {height: height});
|
||||||
|
firstLoad = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BootstrapTable.prototype.initSearch = function () {
|
||||||
|
_initSearch.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
|
|
||||||
|
if (!this.options.advancedSearch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var that = this;
|
||||||
|
var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial;
|
||||||
|
|
||||||
|
this.data = fp ? $.grep(this.data, function (item, i) {
|
||||||
|
for (var key in fp) {
|
||||||
|
var fval = fp[key].toLowerCase();
|
||||||
|
var value = item[key];
|
||||||
|
value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header,
|
||||||
|
that.header.formatters[$.inArray(key, that.header.fields)],
|
||||||
|
[value, item, i], value);
|
||||||
|
|
||||||
|
if (!($.inArray(key, that.header.fields) !== -1 &&
|
||||||
|
(typeof value === 'string' || typeof value === 'number') &&
|
||||||
|
(value + '').toLowerCase().indexOf(fval) !== -1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}) : this.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
BootstrapTable.prototype.onColumnAdvancedSearch = function (event) {
|
||||||
|
var text = $.trim($(event.currentTarget).val());
|
||||||
|
var $field = $(event.currentTarget)[0].id;
|
||||||
|
|
||||||
|
if ($.isEmptyObject(this.filterColumnsPartial)) {
|
||||||
|
this.filterColumnsPartial = {};
|
||||||
|
}
|
||||||
|
if (text) {
|
||||||
|
this.filterColumnsPartial[$field] = text;
|
||||||
|
} else {
|
||||||
|
delete this.filterColumnsPartial[$field];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.options.pageNumber = 1;
|
||||||
|
this.onSearch(event);
|
||||||
|
this.updatePagination();
|
||||||
|
this.trigger('column-advanced-search', $field, text);
|
||||||
|
};
|
||||||
|
}(jQuery);
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
* bootstrap-table - v1.11.0 - 2016-07-02
|
||||||
|
* https://github.com/wenzhixin/bootstrap-table
|
||||||
|
* Copyright (c) 2016 zhixin wen
|
||||||
|
* Licensed MIT License
|
||||||
|
*/
|
||||||
|
!function(a){"use strict";var b=!1,c=a.fn.bootstrapTable.utils.sprintf,d=function(b,d,f,g){if(a("#avdSearchModal_"+g.options.idTable).hasClass("modal"))a("#avdSearchModal_"+g.options.idTable).modal();else{var h=c('<div id="avdSearchModal%s" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">',"_"+g.options.idTable);h+='<div class="modal-dialog modal-xs">',h+=' <div class="modal-content">',h+=' <div class="modal-header">',h+=' <button type="button" class="close" data-dismiss="modal" aria-hidden="true" >×</button>',h+=c(' <h4 class="modal-title">%s</h4>',d),h+=" </div>",h+=' <div class="modal-body modal-body-custom">',h+=c(' <div class="container-fluid" id="avdSearchModalContent%s" style="padding-right: 0px;padding-left: 0px;" >',"_"+g.options.idTable),h+=" </div>",h+=" </div>",h+=" </div>",h+=" </div>",h+="</div>",a("body").append(a(h));var i=e(b,f,g),j=0;a("#avdSearchModalContent_"+g.options.idTable).append(i.join("")),a("#"+g.options.idForm).off("keyup blur","input").on("keyup blur","input",function(a){clearTimeout(j),j=setTimeout(function(){g.onColumnAdvancedSearch(a)},g.options.searchTimeOut)}),a("#btnCloseAvd_"+g.options.idTable).click(function(){a("#avdSearchModal_"+g.options.idTable).modal("hide")}),a("#avdSearchModal_"+g.options.idTable).modal()}},e=function(a,b,d){var e=[];e.push(c('<form class="form-horizontal" id="%s" action="%s" >',d.options.idForm,d.options.actionForm));for(var f in a){var g=a[f];!g.checkbox&&g.visible&&g.searchable&&(e.push('<div class="form-group">'),e.push(c('<label class="col-sm-4 control-label">%s</label>',g.title)),e.push('<div class="col-sm-6">'),e.push(c('<input type="text" class="form-control input-md" name="%s" placeholder="%s" id="%s">',g.field,g.title,g.field)),e.push("</div>"),e.push("</div>"))}return e.push('<div class="form-group">'),e.push('<div class="col-sm-offset-9 col-sm-3">'),e.push(c('<button type="button" id="btnCloseAvd%s" class="btn btn-default" >%s</button>',"_"+d.options.idTable,b)),e.push("</div>"),e.push("</div>"),e.push("</form>"),e};a.extend(a.fn.bootstrapTable.defaults,{advancedSearch:!1,idForm:"advancedSearch",actionForm:"",idTable:void 0,onColumnAdvancedSearch:function(){return!1}}),a.extend(a.fn.bootstrapTable.defaults.icons,{advancedSearchIcon:"glyphicon-chevron-down"}),a.extend(a.fn.bootstrapTable.Constructor.EVENTS,{"column-advanced-search.bs.table":"onColumnAdvancedSearch"}),a.extend(a.fn.bootstrapTable.locales,{formatAdvancedSearch:function(){return"Advanced search"},formatAdvancedCloseButton:function(){return"Close"}}),a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales);var f=a.fn.bootstrapTable.Constructor,g=f.prototype.initToolbar,h=f.prototype.load,i=f.prototype.initSearch;f.prototype.initToolbar=function(){if(g.apply(this,Array.prototype.slice.apply(arguments)),this.options.search&&this.options.advancedSearch&&this.options.idTable){var a=this,b=[];b.push(c('<div class="columns columns-%s btn-group pull-%s" role="group">',this.options.buttonsAlign,this.options.buttonsAlign)),b.push(c('<button class="btn btn-default%s" type="button" name="advancedSearch" title="%s">',void 0===a.options.iconSize?"":" btn-"+a.options.iconSize,a.options.formatAdvancedSearch())),b.push(c('<i class="%s %s"></i>',a.options.iconsPrefix,a.options.icons.advancedSearchIcon)),b.push("</button></div>"),a.$toolbar.prepend(b.join("")),a.$toolbar.find('button[name="advancedSearch"]').off("click").on("click",function(){d(a.columns,a.options.formatAdvancedSearch(),a.options.formatAdvancedCloseButton(),a)})}},f.prototype.load=function(){if(h.apply(this,Array.prototype.slice.apply(arguments)),this.options.advancedSearch&&"undefined"!=typeof this.options.idTable&&!b){var c=parseInt(a(".bootstrap-table").height());c+=10,a("#"+this.options.idTable).bootstrapTable("resetView",{height:c}),b=!0}},f.prototype.initSearch=function(){if(i.apply(this,Array.prototype.slice.apply(arguments)),this.options.advancedSearch){var b=this,c=a.isEmptyObject(this.filterColumnsPartial)?null:this.filterColumnsPartial;this.data=c?a.grep(this.data,function(d,e){for(var f in c){var g=c[f].toLowerCase(),h=d[f];if(h=a.fn.bootstrapTable.utils.calculateObjectValue(b.header,b.header.formatters[a.inArray(f,b.header.fields)],[h,d,e],h),-1===a.inArray(f,b.header.fields)||"string"!=typeof h&&"number"!=typeof h||-1===(h+"").toLowerCase().indexOf(g))return!1}return!0}):this.data}},f.prototype.onColumnAdvancedSearch=function(b){var c=a.trim(a(b.currentTarget).val()),d=a(b.currentTarget)[0].id;a.isEmptyObject(this.filterColumnsPartial)&&(this.filterColumnsPartial={}),c?this.filterColumnsPartial[d]=c:delete this.filterColumnsPartial[d],this.options.pageNumber=1,this.onSearch(b),this.updatePagination(),this.trigger("column-advanced-search",d,c)}}(jQuery);
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,109 +1,42 @@
|
||||||
/**
|
(function ($) {
|
||||||
* Bootstrap Table Chinese translation
|
'use strict';
|
||||||
* Author: Zhixin Wen<wenzhixin2010@gmail.com>
|
|
||||||
*/
|
$.fn.bootstrapTable.locales['zh-CN'] = {
|
||||||
$.fn.bootstrapTable.locales['zh-CN'] = {
|
formatLoadingMessage: function () {
|
||||||
formatShowSearch: function formatShowSearch() {
|
return '正在努力地加载数据中,请稍候……';
|
||||||
return '隐藏/显示搜索';
|
},
|
||||||
},
|
formatRecordsPerPage: function (pageNumber) {
|
||||||
formatPageGo: function formatPageGo() {
|
return pageNumber + ' 条记录每页';
|
||||||
return '跳转';
|
},
|
||||||
},
|
formatShowingRows: function (pageFrom, pageTo, totalRows) {
|
||||||
formatCopyRows: function formatCopyRows() {
|
return '第 ' + pageFrom + ' 到 ' + pageTo + ' 条,共 ' + totalRows + ' 条记录。';
|
||||||
return '复制行';
|
},
|
||||||
},
|
formatSearch: function () {
|
||||||
formatPrint: function formatPrint() {
|
return '搜索';
|
||||||
return '打印';
|
},
|
||||||
},
|
formatNoMatches: function () {
|
||||||
formatLoadingMessage: function formatLoadingMessage() {
|
return '没有找到匹配的记录';
|
||||||
return '正在努力地加载数据中,请稍候';
|
},
|
||||||
},
|
formatPaginationSwitch: function () {
|
||||||
formatRecordsPerPage: function formatRecordsPerPage(pageNumber) {
|
return '隐藏/显示分页';
|
||||||
return "每页显示 ".concat(pageNumber, " 条记录");
|
},
|
||||||
},
|
formatRefresh: function () {
|
||||||
formatShowingRows: function formatShowingRows(pageFrom, pageTo, totalRows, totalNotFiltered) {
|
return '刷新';
|
||||||
if (totalNotFiltered !== undefined && totalNotFiltered > 0 && totalNotFiltered > totalRows) {
|
},
|
||||||
return "显示第 ".concat(pageFrom, " 到第 ").concat(pageTo, " 条记录,总共 ").concat(totalRows, " 条记录(从 ").concat(totalNotFiltered, " 总记录中过滤)");
|
formatToggle: function () {
|
||||||
}
|
return '切换';
|
||||||
return "显示第 ".concat(pageFrom, " 到第 ").concat(pageTo, " 条记录,总共 ").concat(totalRows, " 条记录");
|
},
|
||||||
},
|
formatColumns: function () {
|
||||||
formatSRPaginationPreText: function formatSRPaginationPreText() {
|
return '列';
|
||||||
return '上一页';
|
},
|
||||||
},
|
formatExport: function () {
|
||||||
formatSRPaginationPageText: function formatSRPaginationPageText(page) {
|
return '导出数据';
|
||||||
return "第".concat(page, "页");
|
},
|
||||||
},
|
formatClearFilters: function () {
|
||||||
formatSRPaginationNextText: function formatSRPaginationNextText() {
|
return '清空过滤';
|
||||||
return '下一页';
|
}
|
||||||
},
|
};
|
||||||
formatDetailPagination: function formatDetailPagination(totalRows) {
|
|
||||||
return "总共 ".concat(totalRows, " 条记录");
|
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']);
|
||||||
},
|
|
||||||
formatClearSearch: function formatClearSearch() {
|
})(jQuery);
|
||||||
return '清空过滤';
|
|
||||||
},
|
|
||||||
formatSearch: function formatSearch() {
|
|
||||||
return '搜索';
|
|
||||||
},
|
|
||||||
formatNoMatches: function formatNoMatches() {
|
|
||||||
return '没有找到匹配的记录';
|
|
||||||
},
|
|
||||||
formatPaginationSwitch: function formatPaginationSwitch() {
|
|
||||||
return '隐藏/显示分页';
|
|
||||||
},
|
|
||||||
formatPaginationSwitchDown: function formatPaginationSwitchDown() {
|
|
||||||
return '显示分页';
|
|
||||||
},
|
|
||||||
formatPaginationSwitchUp: function formatPaginationSwitchUp() {
|
|
||||||
return '隐藏分页';
|
|
||||||
},
|
|
||||||
formatRefresh: function formatRefresh() {
|
|
||||||
return '刷新';
|
|
||||||
},
|
|
||||||
formatToggle: function formatToggle() {
|
|
||||||
return '切换';
|
|
||||||
},
|
|
||||||
formatToggleOn: function formatToggleOn() {
|
|
||||||
return '显示卡片视图';
|
|
||||||
},
|
|
||||||
formatToggleOff: function formatToggleOff() {
|
|
||||||
return '隐藏卡片视图';
|
|
||||||
},
|
|
||||||
formatColumns: function formatColumns() {
|
|
||||||
return '列';
|
|
||||||
},
|
|
||||||
formatColumnsToggleAll: function formatColumnsToggleAll() {
|
|
||||||
return '切换所有';
|
|
||||||
},
|
|
||||||
formatFullscreen: function formatFullscreen() {
|
|
||||||
return '全屏';
|
|
||||||
},
|
|
||||||
formatAllRows: function formatAllRows() {
|
|
||||||
return '所有';
|
|
||||||
},
|
|
||||||
formatAutoRefresh: function formatAutoRefresh() {
|
|
||||||
return '自动刷新';
|
|
||||||
},
|
|
||||||
formatExport: function formatExport() {
|
|
||||||
return '导出数据';
|
|
||||||
},
|
|
||||||
formatJumpTo: function formatJumpTo() {
|
|
||||||
return '跳转';
|
|
||||||
},
|
|
||||||
formatAdvancedSearch: function formatAdvancedSearch() {
|
|
||||||
return '高级搜索';
|
|
||||||
},
|
|
||||||
formatAdvancedCloseButton: function formatAdvancedCloseButton() {
|
|
||||||
return '关闭';
|
|
||||||
},
|
|
||||||
formatFilterControlSwitch: function formatFilterControlSwitch() {
|
|
||||||
return '隐藏/显示过滤控制';
|
|
||||||
},
|
|
||||||
formatFilterControlSwitchHide: function formatFilterControlSwitchHide() {
|
|
||||||
return '隐藏过滤控制';
|
|
||||||
},
|
|
||||||
formatFilterControlSwitchShow: function formatFilterControlSwitchShow() {
|
|
||||||
return '显示过滤控制';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']);
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
$.fn.bootstrapTable.locales["zh-CN"]={formatShowSearch:function formatShowSearch(){return"隐藏/显示搜索"},formatPageGo:function formatPageGo(){return"跳转"},formatCopyRows:function formatCopyRows(){return"复制行"},formatPrint:function formatPrint(){return"打印"},formatLoadingMessage:function formatLoadingMessage(){return"正在努力地加载数据中,请稍候"},formatRecordsPerPage:function formatRecordsPerPage(pageNumber){return"每页显示 ".concat(pageNumber," 条记录")},formatShowingRows:function formatShowingRows(pageFrom,pageTo,totalRows,totalNotFiltered){if(totalNotFiltered!==undefined&&totalNotFiltered>0&&totalNotFiltered>totalRows){return"显示第 ".concat(pageFrom," 到第 ").concat(pageTo," 条记录,总共 ").concat(totalRows," 条记录(从 ").concat(totalNotFiltered," 总记录中过滤)")}return"显示第 ".concat(pageFrom," 到第 ").concat(pageTo," 条记录,总共 ").concat(totalRows," 条记录")},formatSRPaginationPreText:function formatSRPaginationPreText(){return"上一页"},formatSRPaginationPageText:function formatSRPaginationPageText(page){return"第".concat(page,"页")},formatSRPaginationNextText:function formatSRPaginationNextText(){return"下一页"},formatDetailPagination:function formatDetailPagination(totalRows){return"总共 ".concat(totalRows," 条记录")},formatClearSearch:function formatClearSearch(){return"清空过滤"},formatSearch:function formatSearch(){return"搜索"},formatNoMatches:function formatNoMatches(){return"没有找到匹配的记录"},formatPaginationSwitch:function formatPaginationSwitch(){return"隐藏/显示分页"},formatPaginationSwitchDown:function formatPaginationSwitchDown(){return"显示分页"},formatPaginationSwitchUp:function formatPaginationSwitchUp(){return"隐藏分页"},formatRefresh:function formatRefresh(){return"刷新"},formatToggle:function formatToggle(){return"切换"},formatToggleOn:function formatToggleOn(){return"显示卡片视图"},formatToggleOff:function formatToggleOff(){return"隐藏卡片视图"},formatColumns:function formatColumns(){return"列"},formatColumnsToggleAll:function formatColumnsToggleAll(){return"切换所有"},formatFullscreen:function formatFullscreen(){return"全屏"},formatAllRows:function formatAllRows(){return"所有"},formatAutoRefresh:function formatAutoRefresh(){return"自动刷新"},formatExport:function formatExport(){return"导出数据"},formatJumpTo:function formatJumpTo(){return"跳转"},formatAdvancedSearch:function formatAdvancedSearch(){return"高级搜索"},formatAdvancedCloseButton:function formatAdvancedCloseButton(){return"关闭"},formatFilterControlSwitch:function formatFilterControlSwitch(){return"隐藏/显示过滤控制"},formatFilterControlSwitchHide:function formatFilterControlSwitchHide(){return"隐藏过滤控制"},formatFilterControlSwitchShow:function formatFilterControlSwitchShow(){return"显示过滤控制"}};$.extend($.fn.bootstrapTable.defaults,$.fn.bootstrapTable.locales["zh-CN"]);
|
(function($){$.fn.bootstrapTable.locales["zh-CN"]={formatLoadingMessage:function(){return"正在努力地加载数据中,请稍候……"},formatRecordsPerPage:function(pageNumber){return pageNumber+" 条记录每页"},formatShowingRows:function(pageFrom,pageTo,totalRows){return"第 "+pageFrom+" 到 "+pageTo+" 条,共 "+totalRows+" 条记录。"},formatSearch:function(){return"搜索"},formatNoMatches:function(){return"没有找到匹配的记录"},formatPaginationSwitch:function(){return"隐藏/显示分页"},formatRefresh:function(){return"刷新"},formatToggle:function(){return"切换"},formatColumns:function(){return"列"},formatExport:function(){return"导出数据"},formatClearFilters:function(){return"清空过滤"}};$.extend($.fn.bootstrapTable.defaults,$.fn.bootstrapTable.locales["zh-CN"])})(jQuery);
|
||||||
14
ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-treetable/bootstrap-treetable.css
vendored
Normal file
14
ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-treetable/bootstrap-treetable.css
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
.bootstrap-tree-table .treetable-indent {width:16px; height: 16px; display: inline-block; position: relative;}
|
||||||
|
.bootstrap-tree-table .treetable-expander {width:16px; height: 16px; display: inline-block; position: relative; cursor: pointer;}
|
||||||
|
.bootstrap-tree-table .treetable-selected{background: #f5f5f5 !important;}
|
||||||
|
.bootstrap-tree-table .treetable-table{border:0 !important;margin-bottom:0}
|
||||||
|
.bootstrap-tree-table .treetable-table tbody {display:block;height:auto;}
|
||||||
|
.bootstrap-tree-table .treetable-table thead, .treetable-table tbody tr {display:table;width:100%;table-layout:fixed;}
|
||||||
|
.bootstrap-tree-table .treetable-thead th{line-height:24px;border: 0 !important;border-radius: 4px;border-left:0px solid #e7eaec !important;border-bottom:1px solid #ccc!important;text-align: left;}
|
||||||
|
.bootstrap-tree-table .treetable-thead tr :first-child{border-left:0 !important}
|
||||||
|
.bootstrap-tree-table .treetable-tbody td{border: 0 !important;border-left:0px solid #e7eaec !important;border-bottom:1px solid #e7eaec!important;white-space: nowrap; text-overflow: ellipsis;}
|
||||||
|
.bootstrap-tree-table .treetable-tbody tr :first-child{border-left:0 !important}
|
||||||
|
.bootstrap-tree-table .treetable-bars .tool-left, .bootstrap-tree-table .treetable-bars .tool-right{margin-top: 10px; margin-bottom: 10px;}
|
||||||
|
.bootstrap-tree-table .treetable-bars .tool-left{float: left;}
|
||||||
|
.bootstrap-tree-table .treetable-bars .tool-right{float: right;}
|
||||||
|
.bootstrap-tree-table .treetable-bars .columns li label{display: block;padding: 3px 20px;clear: both;font-weight: 400;line-height: 1.428571429;max-width: 100%;margin-bottom: 5px;cursor:pointer;}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,127 @@
|
||||||
|
@charset "utf-8";
|
||||||
|
.container {
|
||||||
|
margin: 10px auto 0 auto;
|
||||||
|
position: relative;
|
||||||
|
font-family: 微软雅黑;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.container p {
|
||||||
|
line-height: 12px;
|
||||||
|
line-height: 0px;
|
||||||
|
height: 0px;
|
||||||
|
margin: 10px;
|
||||||
|
color: #bbb
|
||||||
|
}
|
||||||
|
.action {
|
||||||
|
width: 400px;
|
||||||
|
height: 30px;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
.cropped {
|
||||||
|
position: absolute;
|
||||||
|
left: 500px;
|
||||||
|
top: 0;
|
||||||
|
width: 200px;
|
||||||
|
border: 1px #ddd solid;
|
||||||
|
height: 440px;
|
||||||
|
padding: 4px;
|
||||||
|
box-shadow: 0px 0px 12px #ddd;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.imageBox {
|
||||||
|
position: relative;
|
||||||
|
height: 400px;
|
||||||
|
width: 400px;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
background: #fff;
|
||||||
|
overflow: hidden;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
cursor: move;
|
||||||
|
box-shadow: 4px 4px 12px #B0B0B0;
|
||||||
|
}
|
||||||
|
.imageBox .thumbBox {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
margin-top: -100px;
|
||||||
|
margin-left: -100px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid rgb(102, 102, 102);
|
||||||
|
box-shadow: 0 0 0 1000px rgba(0, 0, 0, 0.5);
|
||||||
|
background: none repeat scroll 0% 0% transparent;
|
||||||
|
}
|
||||||
|
.imageBox .spinner {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 400px;
|
||||||
|
background: rgba(0,0,0,0.7);
|
||||||
|
}
|
||||||
|
.Btnsty_peyton{ float: right;
|
||||||
|
width: 46px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
height: 37px;
|
||||||
|
line-height: 37px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #FFFFFF;
|
||||||
|
margin:0px 2px;
|
||||||
|
background-color: #f38e81;
|
||||||
|
border-radius: 3px;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0px 0px 5px #B0B0B0;
|
||||||
|
border: 0px #fff solid;}
|
||||||
|
/*选择文件上传*/
|
||||||
|
.new-contentarea {
|
||||||
|
width: 165px;
|
||||||
|
overflow:hidden;
|
||||||
|
margin: 0 auto;
|
||||||
|
position:relative;float:left;
|
||||||
|
}
|
||||||
|
.new-contentarea label {
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
.new-contentarea input[type=file] {
|
||||||
|
width:188px;
|
||||||
|
height:60px;
|
||||||
|
background:#333;
|
||||||
|
margin: 0 auto;
|
||||||
|
position:absolute;
|
||||||
|
right:50%;
|
||||||
|
margin-right:-94px;
|
||||||
|
top:0;
|
||||||
|
right/*\**/:0px\9;
|
||||||
|
margin-right/*\**/:0px\9;
|
||||||
|
width/*\**/:10px\9;
|
||||||
|
opacity:0;
|
||||||
|
filter:alpha(opacity=0);
|
||||||
|
z-index:2;
|
||||||
|
}
|
||||||
|
a.upload-img{
|
||||||
|
width:165px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
height:37px;
|
||||||
|
line-height: 37px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #FFFFFF;
|
||||||
|
background-color: #f38e81;
|
||||||
|
border-radius: 3px;
|
||||||
|
text-decoration:none;
|
||||||
|
cursor:pointer;
|
||||||
|
border: 0px #fff solid;
|
||||||
|
box-shadow: 0px 0px 5px #B0B0B0;
|
||||||
|
}
|
||||||
|
a.upload-img:hover{
|
||||||
|
background-color: #ec7e70;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tc{text-align:center;}
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
"use strict";
|
||||||
|
(function (factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define(['jquery'], factory);
|
||||||
|
} else {
|
||||||
|
factory(jQuery);
|
||||||
|
}
|
||||||
|
}(function ($) {
|
||||||
|
var cropbox = function(options, el){
|
||||||
|
var el = el || $(options.imageBox),
|
||||||
|
obj =
|
||||||
|
{
|
||||||
|
state : {},
|
||||||
|
ratio : 1,
|
||||||
|
options : options,
|
||||||
|
imageBox : el,
|
||||||
|
thumbBox : el.find(options.thumbBox),
|
||||||
|
spinner : el.find(options.spinner),
|
||||||
|
image : new Image(),
|
||||||
|
getDataURL: function ()
|
||||||
|
{
|
||||||
|
var width = this.thumbBox.width(),
|
||||||
|
height = this.thumbBox.height(),
|
||||||
|
canvas = document.createElement("canvas"),
|
||||||
|
dim = el.css('background-position').split(' '),
|
||||||
|
size = el.css('background-size').split(' '),
|
||||||
|
dx = parseInt(dim[0]) - el.width()/2 + width/2,
|
||||||
|
dy = parseInt(dim[1]) - el.height()/2 + height/2,
|
||||||
|
dw = parseInt(size[0]),
|
||||||
|
dh = parseInt(size[1]),
|
||||||
|
sh = parseInt(this.image.height),
|
||||||
|
sw = parseInt(this.image.width);
|
||||||
|
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
var context = canvas.getContext("2d");
|
||||||
|
context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh);
|
||||||
|
var imageData = canvas.toDataURL('image/png');
|
||||||
|
return imageData;
|
||||||
|
},
|
||||||
|
getBlob: function()
|
||||||
|
{
|
||||||
|
var imageData = this.getDataURL();
|
||||||
|
var b64 = imageData.replace('data:image/png;base64,','');
|
||||||
|
var binary = atob(b64);
|
||||||
|
var array = [];
|
||||||
|
for (var i = 0; i < binary.length; i++) {
|
||||||
|
array.push(binary.charCodeAt(i));
|
||||||
|
}
|
||||||
|
return new Blob([new Uint8Array(array)], {type: 'image/png'});
|
||||||
|
},
|
||||||
|
zoomIn: function ()
|
||||||
|
{
|
||||||
|
this.ratio*=1.1;
|
||||||
|
setBackground();
|
||||||
|
},
|
||||||
|
zoomOut: function ()
|
||||||
|
{
|
||||||
|
this.ratio*=0.9;
|
||||||
|
setBackground();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setBackground = function()
|
||||||
|
{
|
||||||
|
var w = parseInt(obj.image.width)*obj.ratio;
|
||||||
|
var h = parseInt(obj.image.height)*obj.ratio;
|
||||||
|
|
||||||
|
var pw = (el.width() - w) / 2;
|
||||||
|
var ph = (el.height() - h) / 2;
|
||||||
|
|
||||||
|
el.css({
|
||||||
|
'background-image': 'url(' + obj.image.src + ')',
|
||||||
|
'background-size': w +'px ' + h + 'px',
|
||||||
|
'background-position': pw + 'px ' + ph + 'px',
|
||||||
|
'background-repeat': 'no-repeat'});
|
||||||
|
},
|
||||||
|
imgMouseDown = function(e)
|
||||||
|
{
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
|
||||||
|
obj.state.dragable = true;
|
||||||
|
obj.state.mouseX = e.clientX;
|
||||||
|
obj.state.mouseY = e.clientY;
|
||||||
|
},
|
||||||
|
imgMouseMove = function(e)
|
||||||
|
{
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
|
||||||
|
if (obj.state.dragable)
|
||||||
|
{
|
||||||
|
var x = e.clientX - obj.state.mouseX;
|
||||||
|
var y = e.clientY - obj.state.mouseY;
|
||||||
|
|
||||||
|
var bg = el.css('background-position').split(' ');
|
||||||
|
|
||||||
|
var bgX = x + parseInt(bg[0]);
|
||||||
|
var bgY = y + parseInt(bg[1]);
|
||||||
|
|
||||||
|
el.css('background-position', bgX +'px ' + bgY + 'px');
|
||||||
|
|
||||||
|
obj.state.mouseX = e.clientX;
|
||||||
|
obj.state.mouseY = e.clientY;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
imgMouseUp = function(e)
|
||||||
|
{
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
obj.state.dragable = false;
|
||||||
|
},
|
||||||
|
zoomImage = function(e)
|
||||||
|
{
|
||||||
|
e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0 ? obj.ratio*=1.1 : obj.ratio*=0.9;
|
||||||
|
setBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.spinner.show();
|
||||||
|
obj.image.onload = function() {
|
||||||
|
obj.spinner.hide();
|
||||||
|
setBackground();
|
||||||
|
|
||||||
|
el.bind('mousedown', imgMouseDown);
|
||||||
|
el.bind('mousemove', imgMouseMove);
|
||||||
|
$(window).bind('mouseup', imgMouseUp);
|
||||||
|
el.bind('mousewheel DOMMouseScroll', zoomImage);
|
||||||
|
};
|
||||||
|
obj.image.crossOrigin = 'Anonymous';
|
||||||
|
obj.image.src = options.imgSrc;
|
||||||
|
el.on('remove', function(){$(window).unbind('mouseup', imgMouseUp)});
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
jQuery.fn.cropbox = function(options){
|
||||||
|
return new cropbox(options, this);
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
@ -1,304 +0,0 @@
|
||||||
/*!
|
|
||||||
* Cropper.js v1.5.12
|
|
||||||
* https://fengyuanchen.github.io/cropperjs
|
|
||||||
*
|
|
||||||
* Copyright 2015-present Chen Fengyuan
|
|
||||||
* Released under the MIT license
|
|
||||||
*
|
|
||||||
* Date: 2021-06-12T08:00:11.623Z
|
|
||||||
*/
|
|
||||||
|
|
||||||
.cropper-container {
|
|
||||||
direction: ltr;
|
|
||||||
font-size: 0;
|
|
||||||
line-height: 0;
|
|
||||||
position: relative;
|
|
||||||
-ms-touch-action: none;
|
|
||||||
touch-action: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-container img {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
image-orientation: 0deg;
|
|
||||||
max-height: none !important;
|
|
||||||
max-width: none !important;
|
|
||||||
min-height: 0 !important;
|
|
||||||
min-width: 0 !important;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-wrap-box,
|
|
||||||
.cropper-canvas,
|
|
||||||
.cropper-drag-box,
|
|
||||||
.cropper-crop-box,
|
|
||||||
.cropper-modal {
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-wrap-box,
|
|
||||||
.cropper-canvas {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-drag-box {
|
|
||||||
background-color: #fff;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-modal {
|
|
||||||
background-color: #000;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-view-box {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
outline: 1px solid #39f;
|
|
||||||
outline-color: rgba(51, 153, 255, 0.75);
|
|
||||||
overflow: hidden;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-dashed {
|
|
||||||
border: 0 dashed #eee;
|
|
||||||
display: block;
|
|
||||||
opacity: 0.5;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-dashed.dashed-h {
|
|
||||||
border-bottom-width: 1px;
|
|
||||||
border-top-width: 1px;
|
|
||||||
height: calc(100% / 3);
|
|
||||||
left: 0;
|
|
||||||
top: calc(100% / 3);
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-dashed.dashed-v {
|
|
||||||
border-left-width: 1px;
|
|
||||||
border-right-width: 1px;
|
|
||||||
height: 100%;
|
|
||||||
left: calc(100% / 3);
|
|
||||||
top: 0;
|
|
||||||
width: calc(100% / 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-center {
|
|
||||||
display: block;
|
|
||||||
height: 0;
|
|
||||||
left: 50%;
|
|
||||||
opacity: 0.75;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-center::before,
|
|
||||||
.cropper-center::after {
|
|
||||||
background-color: #eee;
|
|
||||||
content: ' ';
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-center::before {
|
|
||||||
height: 1px;
|
|
||||||
left: -3px;
|
|
||||||
top: 0;
|
|
||||||
width: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-center::after {
|
|
||||||
height: 7px;
|
|
||||||
left: 0;
|
|
||||||
top: -3px;
|
|
||||||
width: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-face,
|
|
||||||
.cropper-line,
|
|
||||||
.cropper-point {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
opacity: 0.1;
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-face {
|
|
||||||
background-color: #fff;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-line {
|
|
||||||
background-color: #39f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-line.line-e {
|
|
||||||
cursor: ew-resize;
|
|
||||||
right: -3px;
|
|
||||||
top: 0;
|
|
||||||
width: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-line.line-n {
|
|
||||||
cursor: ns-resize;
|
|
||||||
height: 5px;
|
|
||||||
left: 0;
|
|
||||||
top: -3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-line.line-w {
|
|
||||||
cursor: ew-resize;
|
|
||||||
left: -3px;
|
|
||||||
top: 0;
|
|
||||||
width: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-line.line-s {
|
|
||||||
bottom: -3px;
|
|
||||||
cursor: ns-resize;
|
|
||||||
height: 5px;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-point {
|
|
||||||
background-color: #39f;
|
|
||||||
height: 5px;
|
|
||||||
opacity: 0.75;
|
|
||||||
width: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-point.point-e {
|
|
||||||
cursor: ew-resize;
|
|
||||||
margin-top: -3px;
|
|
||||||
right: -3px;
|
|
||||||
top: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-point.point-n {
|
|
||||||
cursor: ns-resize;
|
|
||||||
left: 50%;
|
|
||||||
margin-left: -3px;
|
|
||||||
top: -3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-point.point-w {
|
|
||||||
cursor: ew-resize;
|
|
||||||
left: -3px;
|
|
||||||
margin-top: -3px;
|
|
||||||
top: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-point.point-s {
|
|
||||||
bottom: -3px;
|
|
||||||
cursor: s-resize;
|
|
||||||
left: 50%;
|
|
||||||
margin-left: -3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-point.point-ne {
|
|
||||||
cursor: nesw-resize;
|
|
||||||
right: -3px;
|
|
||||||
top: -3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-point.point-nw {
|
|
||||||
cursor: nwse-resize;
|
|
||||||
left: -3px;
|
|
||||||
top: -3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-point.point-sw {
|
|
||||||
bottom: -3px;
|
|
||||||
cursor: nesw-resize;
|
|
||||||
left: -3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-point.point-se {
|
|
||||||
bottom: -3px;
|
|
||||||
cursor: nwse-resize;
|
|
||||||
height: 20px;
|
|
||||||
opacity: 1;
|
|
||||||
right: -3px;
|
|
||||||
width: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.cropper-point.point-se {
|
|
||||||
height: 15px;
|
|
||||||
width: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 992px) {
|
|
||||||
.cropper-point.point-se {
|
|
||||||
height: 10px;
|
|
||||||
width: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
.cropper-point.point-se {
|
|
||||||
height: 5px;
|
|
||||||
opacity: 0.75;
|
|
||||||
width: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-point.point-se::before {
|
|
||||||
background-color: #39f;
|
|
||||||
bottom: -50%;
|
|
||||||
content: ' ';
|
|
||||||
display: block;
|
|
||||||
height: 200%;
|
|
||||||
opacity: 0;
|
|
||||||
position: absolute;
|
|
||||||
right: -50%;
|
|
||||||
width: 200%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-invisible {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-bg {
|
|
||||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-hide {
|
|
||||||
display: block;
|
|
||||||
height: 0;
|
|
||||||
position: absolute;
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-hidden {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-move {
|
|
||||||
cursor: move;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-crop {
|
|
||||||
cursor: crosshair;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cropper-disabled .cropper-drag-box,
|
|
||||||
.cropper-disabled .cropper-face,
|
|
||||||
.cropper-disabled .cropper-line,
|
|
||||||
.cropper-disabled .cropper-point {
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,9 +0,0 @@
|
||||||
/*!
|
|
||||||
* Cropper.js v1.5.12
|
|
||||||
* https://fengyuanchen.github.io/cropperjs
|
|
||||||
*
|
|
||||||
* Copyright 2015-present Chen Fengyuan
|
|
||||||
* Released under the MIT license
|
|
||||||
*
|
|
||||||
* Date: 2021-06-12T08:00:11.623Z
|
|
||||||
*/.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{image-orientation:0deg;display:block;height:100%;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-canvas,.cropper-wrap-box{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:rgba(51,153,255,.75);overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:after,.cropper-center:before{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,406 +0,0 @@
|
||||||
/*!
|
|
||||||
* jQuery cxSelect
|
|
||||||
* @name jquery.cxselect.js
|
|
||||||
* @version 1.4.2
|
|
||||||
* @date 2017-09-26
|
|
||||||
* @author ciaoca
|
|
||||||
* @email ciaoca@gmail.com
|
|
||||||
* @site https://github.com/ciaoca/cxSelect
|
|
||||||
* @license Released under the MIT license
|
|
||||||
*/
|
|
||||||
(function(factory) {
|
|
||||||
if (typeof define === 'function' && define.amd) {
|
|
||||||
define(['jquery'], factory);
|
|
||||||
} else {
|
|
||||||
factory(window.jQuery || window.Zepto || window.$);
|
|
||||||
};
|
|
||||||
}(function($) {
|
|
||||||
var cxSelect = function() {
|
|
||||||
var self = this;
|
|
||||||
var dom, settings, callback;
|
|
||||||
|
|
||||||
// 分配参数
|
|
||||||
for (var i = 0, l = arguments.length; i < l; i++) {
|
|
||||||
if (cxSelect.isJquery(arguments[i]) || cxSelect.isZepto(arguments[i])) {
|
|
||||||
dom = arguments[i];
|
|
||||||
} else if (cxSelect.isElement(arguments[i])) {
|
|
||||||
dom = $(arguments[i]);
|
|
||||||
} else if (typeof arguments[i] === 'function') {
|
|
||||||
callback = arguments[i];
|
|
||||||
} else if (typeof arguments[i] === 'object') {
|
|
||||||
settings = arguments[i];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var api = new cxSelect.init(dom, settings);
|
|
||||||
|
|
||||||
if (typeof callback === 'function') {
|
|
||||||
callback(api);
|
|
||||||
};
|
|
||||||
|
|
||||||
return api;
|
|
||||||
};
|
|
||||||
|
|
||||||
cxSelect.isElement = function(o){
|
|
||||||
if (o && (typeof HTMLElement === 'function' || typeof HTMLElement === 'object') && o instanceof HTMLElement) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return (o && o.nodeType && o.nodeType === 1) ? true : false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
cxSelect.isJquery = function(o){
|
|
||||||
return (o && o.length && (typeof jQuery === 'function' || typeof jQuery === 'object') && o instanceof jQuery) ? true : false;
|
|
||||||
};
|
|
||||||
|
|
||||||
cxSelect.isZepto = function(o){
|
|
||||||
return (o && o.length && (typeof Zepto === 'function' || typeof Zepto === 'object') && Zepto.zepto.isZ(o)) ? true : false;
|
|
||||||
};
|
|
||||||
|
|
||||||
cxSelect.getIndex = function(n, required) {
|
|
||||||
return required ? n : n - 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
cxSelect.getData = function(data, space) {
|
|
||||||
if (typeof space === 'string' && space.length) {
|
|
||||||
space = space.split('.');
|
|
||||||
for (var i = 0, l = space.length; i < l; i++) {
|
|
||||||
data = data[space[i]];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
cxSelect.init = function(dom, settings) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
if (!cxSelect.isJquery(dom) && !cxSelect.isZepto(dom)) {return};
|
|
||||||
|
|
||||||
var theSelect = {
|
|
||||||
dom: {
|
|
||||||
box: dom
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.attach = cxSelect.attach.bind(theSelect);
|
|
||||||
self.detach = cxSelect.detach.bind(theSelect);
|
|
||||||
self.setOptions = cxSelect.setOptions.bind(theSelect);
|
|
||||||
self.clear = cxSelect.clear.bind(theSelect);
|
|
||||||
|
|
||||||
theSelect.changeEvent = function() {
|
|
||||||
cxSelect.selectChange.call(theSelect, this.className);
|
|
||||||
};
|
|
||||||
|
|
||||||
theSelect.settings = $.extend({}, $.cxSelect.defaults, settings, {
|
|
||||||
url: theSelect.dom.box.data('url'),
|
|
||||||
emptyStyle: theSelect.dom.box.data('emptyStyle'),
|
|
||||||
required: theSelect.dom.box.data('required'),
|
|
||||||
firstTitle: theSelect.dom.box.data('firstTitle'),
|
|
||||||
firstValue: theSelect.dom.box.data('firstValue'),
|
|
||||||
jsonSpace: theSelect.dom.box.data('jsonSpace'),
|
|
||||||
jsonName: theSelect.dom.box.data('jsonName'),
|
|
||||||
jsonValue: theSelect.dom.box.data('jsonValue'),
|
|
||||||
jsonSub: theSelect.dom.box.data('jsonSub')
|
|
||||||
});
|
|
||||||
|
|
||||||
var _dataSelects = theSelect.dom.box.data('selects');
|
|
||||||
|
|
||||||
if (typeof _dataSelects === 'string' && _dataSelects.length) {
|
|
||||||
theSelect.settings.selects = _dataSelects.split(',');
|
|
||||||
};
|
|
||||||
|
|
||||||
self.setOptions();
|
|
||||||
self.attach();
|
|
||||||
|
|
||||||
// 使用独立接口获取数据
|
|
||||||
if (!theSelect.settings.url && !theSelect.settings.data) {
|
|
||||||
cxSelect.start.apply(theSelect);
|
|
||||||
|
|
||||||
// 设置自定义数据
|
|
||||||
} else if ($.isArray(theSelect.settings.data)) {
|
|
||||||
cxSelect.start.call(theSelect, theSelect.settings.data);
|
|
||||||
|
|
||||||
// 设置 URL,通过 Ajax 获取数据
|
|
||||||
} else if (typeof theSelect.settings.url === 'string' && theSelect.settings.url.length) {
|
|
||||||
$.getJSON(theSelect.settings.url, function(json) {
|
|
||||||
cxSelect.start.call(theSelect, json);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// 设置参数
|
|
||||||
cxSelect.setOptions = function(opts) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
if (opts) {
|
|
||||||
$.extend(self.settings, opts);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 初次或重设选择器组
|
|
||||||
if (!$.isArray(self.selectArray) || !self.selectArray.length || (opts && opts.selects)) {
|
|
||||||
self.selectArray = [];
|
|
||||||
|
|
||||||
if ($.isArray(self.settings.selects) && self.settings.selects.length) {
|
|
||||||
var _tempSelect;
|
|
||||||
|
|
||||||
for (var i = 0, l = self.settings.selects.length; i < l; i++) {
|
|
||||||
_tempSelect = self.dom.box.find('select.' + self.settings.selects[i]);
|
|
||||||
|
|
||||||
if (!_tempSelect || !_tempSelect.length) {break};
|
|
||||||
|
|
||||||
self.selectArray.push(_tempSelect);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
if (opts) {
|
|
||||||
if (!$.isArray(opts.data) && typeof opts.url === 'string' && opts.url.length) {
|
|
||||||
$.getJSON(self.settings.url, function(json) {
|
|
||||||
cxSelect.start.call(self, json);
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
cxSelect.start.call(self, opts.data);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// 绑定
|
|
||||||
cxSelect.attach = function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
if (!self.attachStatus) {
|
|
||||||
self.dom.box.on('change', 'select', self.changeEvent);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (typeof self.attachStatus === 'boolean') {
|
|
||||||
cxSelect.start.call(self);
|
|
||||||
};
|
|
||||||
|
|
||||||
self.attachStatus = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 移除绑定
|
|
||||||
cxSelect.detach = function() {
|
|
||||||
var self = this;
|
|
||||||
self.dom.box.off('change', 'select', self.changeEvent);
|
|
||||||
self.attachStatus = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 清空选项
|
|
||||||
cxSelect.clear = function(index) {
|
|
||||||
var self = this;
|
|
||||||
var _style = {
|
|
||||||
display: '',
|
|
||||||
visibility: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
index = isNaN(index) ? 0 : index;
|
|
||||||
|
|
||||||
// 清空后面的 select
|
|
||||||
for (var i = index, l = self.selectArray.length; i < l; i++) {
|
|
||||||
self.selectArray[i].empty().prop('disabled', true);
|
|
||||||
|
|
||||||
if (self.settings.emptyStyle === 'none') {
|
|
||||||
_style.display = 'none';
|
|
||||||
} else if (self.settings.emptyStyle === 'hidden') {
|
|
||||||
_style.visibility = 'hidden';
|
|
||||||
};
|
|
||||||
|
|
||||||
self.selectArray[i].css(_style);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
cxSelect.start = function(data) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
if ($.isArray(data)) {
|
|
||||||
self.settings.data = cxSelect.getData(data, self.settings.jsonSpace);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!self.selectArray.length) {return};
|
|
||||||
|
|
||||||
// 保存默认值
|
|
||||||
for (var i = 0, l = self.selectArray.length; i < l; i++) {
|
|
||||||
if (typeof self.selectArray[i].attr('data-value') !== 'string' && self.selectArray[i][0].options.length) {
|
|
||||||
self.selectArray[i].attr('data-value', self.selectArray[i].val());
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
if (self.settings.data || (typeof self.selectArray[0].data('url') === 'string' && self.selectArray[0].data('url').length)) {
|
|
||||||
cxSelect.getOptionData.call(self, 0);
|
|
||||||
} else if (self.selectArray[0][0].options.length && typeof self.selectArray[0].attr('data-value') === 'string' && self.selectArray[0].attr('data-value').length) {
|
|
||||||
self.selectArray[0].val(self.selectArray[0].attr('data-value'));
|
|
||||||
cxSelect.getOptionData.call(self, 1);
|
|
||||||
} else {
|
|
||||||
self.selectArray[0].prop('disabled', false).css({
|
|
||||||
'display': '',
|
|
||||||
'visibility': ''
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取选项数据
|
|
||||||
cxSelect.getOptionData = function(index) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
if (typeof index !== 'number' || isNaN(index) || index < 0 || index >= self.selectArray.length) {return};
|
|
||||||
|
|
||||||
var _indexPrev = index - 1;
|
|
||||||
var _select = self.selectArray[index];
|
|
||||||
var _selectData;
|
|
||||||
var _valueIndex;
|
|
||||||
var _dataUrl = _select.data('url');
|
|
||||||
var _jsonSpace = typeof _select.data('jsonSpace') === 'undefined' ? self.settings.jsonSpace : _select.data('jsonSpace');
|
|
||||||
var _query = {};
|
|
||||||
var _queryName;
|
|
||||||
var _selectName;
|
|
||||||
var _selectValue;
|
|
||||||
|
|
||||||
cxSelect.clear.call(self, index);
|
|
||||||
|
|
||||||
// 使用独立接口
|
|
||||||
if (typeof _dataUrl === 'string' && _dataUrl.length) {
|
|
||||||
if (index > 0) {
|
|
||||||
for (var i = 0, j = 1; i < index; i++, j++) {
|
|
||||||
_queryName = self.selectArray[j].data('queryName');
|
|
||||||
_selectName = self.selectArray[i].attr('name');
|
|
||||||
_selectValue = self.selectArray[i].val();
|
|
||||||
|
|
||||||
if (typeof _queryName === 'string' && _queryName.length) {
|
|
||||||
_query[_queryName] = _selectValue;
|
|
||||||
} else if (typeof _selectName === 'string' && _selectName.length) {
|
|
||||||
_query[_selectName] = _selectValue;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
$.getJSON(_dataUrl, _query, function(json) {
|
|
||||||
_selectData = cxSelect.getData(json, _jsonSpace);
|
|
||||||
|
|
||||||
cxSelect.buildOption.call(self, index, _selectData);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 使用整合数据
|
|
||||||
} else if (self.settings.data && typeof self.settings.data === 'object') {
|
|
||||||
_selectData = self.settings.data;
|
|
||||||
|
|
||||||
for (var i = 0; i < index; i++) {
|
|
||||||
_valueIndex = cxSelect.getIndex(self.selectArray[i][0].selectedIndex, typeof self.selectArray[i].data('required') === 'boolean' ? self.selectArray[i].data('required') : self.settings.required);
|
|
||||||
|
|
||||||
if (typeof _selectData[_valueIndex] === 'object' && $.isArray(_selectData[_valueIndex][self.settings.jsonSub]) && _selectData[_valueIndex][self.settings.jsonSub].length) {
|
|
||||||
_selectData = _selectData[_valueIndex][self.settings.jsonSub];
|
|
||||||
} else {
|
|
||||||
_selectData = null;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
cxSelect.buildOption.call(self, index, _selectData);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// 构建选项列表
|
|
||||||
cxSelect.buildOption = function(index, data) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
var _select = self.selectArray[index];
|
|
||||||
var _required = typeof _select.data('required') === 'boolean' ? _select.data('required') : self.settings.required;
|
|
||||||
var _firstTitle = typeof _select.data('firstTitle') === 'undefined' ? self.settings.firstTitle : _select.data('firstTitle');
|
|
||||||
var _firstValue = typeof _select.data('firstValue') === 'undefined' ? self.settings.firstValue : _select.data('firstValue');
|
|
||||||
var _jsonName = typeof _select.data('jsonName') === 'undefined' ? self.settings.jsonName : _select.data('jsonName');
|
|
||||||
var _jsonValue = typeof _select.data('jsonValue') === 'undefined' ? self.settings.jsonValue : _select.data('jsonValue');
|
|
||||||
|
|
||||||
if (!$.isArray(data)) {return};
|
|
||||||
|
|
||||||
var _html = !_required ? '<option value="' + String(_firstValue) + '">' + String(_firstTitle) + '</option>' : '';
|
|
||||||
|
|
||||||
// 区分标题、值的数据
|
|
||||||
if (typeof _jsonName === 'string' && _jsonName.length) {
|
|
||||||
// 无值字段时使用标题作为值
|
|
||||||
if (typeof _jsonValue !== 'string' || !_jsonValue.length) {
|
|
||||||
_jsonValue = _jsonName;
|
|
||||||
};
|
|
||||||
|
|
||||||
for (var i = 0, l = data.length; i < l; i++) {
|
|
||||||
_html += '<option value="' + String(data[i][_jsonValue]) + '">' + String(data[i][_jsonName]) + '</option>';
|
|
||||||
};
|
|
||||||
|
|
||||||
// 数组即为值的数据
|
|
||||||
} else {
|
|
||||||
for (var i = 0, l = data.length; i < l; i++) {
|
|
||||||
_html += '<option value="' + String(data[i]) + '">' + String(data[i]) + '</option>';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
_select.html(_html).prop('disabled', false).css({
|
|
||||||
'display': '',
|
|
||||||
'visibility': ''
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初次加载设置默认值
|
|
||||||
if (typeof _select.attr('data-value') === 'string') {
|
|
||||||
_select.val(String(_select.attr('data-value'))).removeAttr('data-value');
|
|
||||||
|
|
||||||
if (_select[0].selectedIndex < 0) {
|
|
||||||
_select[0].options[0].selected = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
if (_required || _select[0].selectedIndex > 0) {
|
|
||||||
_select.trigger('change');
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// 改变选择时的处理
|
|
||||||
cxSelect.selectChange = function(name) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
if (typeof name !== 'string' || !name.length) {return};
|
|
||||||
|
|
||||||
var index;
|
|
||||||
|
|
||||||
name = name.replace(/\s+/g, ',');
|
|
||||||
name = ',' + name + ',';
|
|
||||||
|
|
||||||
// 获取当前 select 位置
|
|
||||||
for (var i = 0, l = self.selectArray.length; i < l; i++) {
|
|
||||||
if (name.indexOf(',' + self.settings.selects[i] + ',') > -1) {
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
if (typeof index === 'number' && index > -1) {
|
|
||||||
index += 1;
|
|
||||||
cxSelect.getOptionData.call(self, index);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
$.cxSelect = function() {
|
|
||||||
return cxSelect.apply(this, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 默认值
|
|
||||||
$.cxSelect.defaults = {
|
|
||||||
selects: [], // 下拉选框组
|
|
||||||
url: null, // 列表数据文件路径(URL)或数组数据
|
|
||||||
data: null, // 自定义数据
|
|
||||||
emptyStyle: null, // 无数据状态显示方式
|
|
||||||
required: false, // 是否为必选
|
|
||||||
firstTitle: '请选择', // 第一个选项的标题
|
|
||||||
firstValue: '', // 第一个选项的值
|
|
||||||
jsonSpace: '', // 数据命名空间
|
|
||||||
jsonName: 'n', // 数据标题字段名称
|
|
||||||
jsonValue: '', // 数据值字段名称
|
|
||||||
jsonSub: 's' // 子集数据字段名称
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.cxSelect = function(settings, callback) {
|
|
||||||
this.each(function(i) {
|
|
||||||
$.cxSelect(this, settings, callback);
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,86 +0,0 @@
|
||||||
/*
|
|
||||||
* Bootstrap Duallistbox - v3.0.9
|
|
||||||
* A responsive dual listbox widget optimized for Twitter Bootstrap. It works on all modern browsers and on touch devices.
|
|
||||||
* https://www.virtuosoft.eu/code/bootstrap-duallistbox/
|
|
||||||
*
|
|
||||||
* Made by István Ujj-Mészáros
|
|
||||||
* Under Apache License v2.0 License
|
|
||||||
*/
|
|
||||||
.bootstrap-duallistbox-container .buttons {
|
|
||||||
width: 100%;
|
|
||||||
margin-bottom: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container label {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container .info {
|
|
||||||
display: inline-block;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
font-size: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container .clear1,
|
|
||||||
.bootstrap-duallistbox-container .clear2 {
|
|
||||||
display: none;
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container .box1.filtered .clear1,
|
|
||||||
.bootstrap-duallistbox-container .box2.filtered .clear2 {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container .move,
|
|
||||||
.bootstrap-duallistbox-container .remove {
|
|
||||||
width: 60%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container .btn-group .btn {
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
border-bottom-right-radius: 0;
|
|
||||||
}
|
|
||||||
.bootstrap-duallistbox-container select {
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-top-right-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container .moveall,
|
|
||||||
.bootstrap-duallistbox-container .removeall {
|
|
||||||
width: 40%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container.bs2compatible .btn-group > .btn + .btn {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container select {
|
|
||||||
width: 100%;
|
|
||||||
height: 300px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container .filter {
|
|
||||||
display: inline-block;
|
|
||||||
width: 100%;
|
|
||||||
height: 31px;
|
|
||||||
margin: 0 0 5px 0;
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container .filter.placeholder {
|
|
||||||
color: #aaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container.moveonselect .move,
|
|
||||||
.bootstrap-duallistbox-container.moveonselect .remove {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-duallistbox-container.moveonselect .moveall,
|
|
||||||
.bootstrap-duallistbox-container.moveonselect .removeall {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
@ -1,844 +0,0 @@
|
||||||
/*
|
|
||||||
* Bootstrap Duallistbox - v3.0.9
|
|
||||||
* A responsive dual listbox widget optimized for Twitter Bootstrap. It works on all modern browsers and on touch devices.
|
|
||||||
* https://www.virtuosoft.eu/code/bootstrap-duallistbox/
|
|
||||||
*
|
|
||||||
* Made by István Ujj-Mészáros
|
|
||||||
* Under Apache License v2.0 License
|
|
||||||
*/
|
|
||||||
;(function ($, window, document, undefined) {
|
|
||||||
// Create the defaults once
|
|
||||||
var pluginName = 'bootstrapDualListbox',
|
|
||||||
defaults = {
|
|
||||||
bootstrap2Compatible: false,
|
|
||||||
filterTextClear: 'show all',
|
|
||||||
filterPlaceHolder: 'Filter',
|
|
||||||
moveSelectedLabel: 'Move selected',
|
|
||||||
moveAllLabel: 'Move all',
|
|
||||||
removeSelectedLabel: 'Remove selected',
|
|
||||||
removeAllLabel: 'Remove all',
|
|
||||||
moveOnSelect: true, // true/false (forced true on androids, see the comment later)
|
|
||||||
moveOnDoubleClick: true, // true/false (forced false on androids, cause moveOnSelect is forced to true)
|
|
||||||
preserveSelectionOnMove: false, // 'all' / 'moved' / false
|
|
||||||
selectedListLabel: false, // 'string', false
|
|
||||||
nonSelectedListLabel: false, // 'string', false
|
|
||||||
helperSelectNamePostfix: '_helper', // 'string_of_postfix' / false
|
|
||||||
selectorMinimalHeight: 100,
|
|
||||||
showFilterInputs: true, // whether to show filter inputs
|
|
||||||
nonSelectedFilter: '', // string, filter the non selected options
|
|
||||||
selectedFilter: '', // string, filter the selected options
|
|
||||||
infoText: 'Showing all {0}', // text when all options are visible / false for no info text
|
|
||||||
infoTextFiltered: '<span class="label label-warning">Filtered</span> {0} from {1}', // when not all of the options are visible due to the filter
|
|
||||||
infoTextEmpty: 'Empty list', // when there are no options present in the list
|
|
||||||
filterOnValues: false, // filter by selector's values, boolean
|
|
||||||
sortByInputOrder: false,
|
|
||||||
eventMoveOverride: false, // boolean, allows user to unbind default event behaviour and run their own instead
|
|
||||||
eventMoveAllOverride: false, // boolean, allows user to unbind default event behaviour and run their own instead
|
|
||||||
eventRemoveOverride: false, // boolean, allows user to unbind default event behaviour and run their own instead
|
|
||||||
eventRemoveAllOverride: false // boolean, allows user to unbind default event behaviour and run their own instead
|
|
||||||
},
|
|
||||||
// Selections are invisible on android if the containing select is styled with CSS
|
|
||||||
// http://code.google.com/p/android/issues/detail?id=16922
|
|
||||||
isBuggyAndroid = /android/i.test(navigator.userAgent.toLowerCase());
|
|
||||||
|
|
||||||
// The actual plugin constructor
|
|
||||||
function BootstrapDualListbox(element, options) {
|
|
||||||
this.element = $(element);
|
|
||||||
// jQuery has an extend method which merges the contents of two or
|
|
||||||
// more objects, storing the result in the first object. The first object
|
|
||||||
// is generally empty as we don't want to alter the default options for
|
|
||||||
// future instances of the plugin
|
|
||||||
this.settings = $.extend({}, defaults, options);
|
|
||||||
this._defaults = defaults;
|
|
||||||
this._name = pluginName;
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
function triggerChangeEvent(dualListbox) {
|
|
||||||
dualListbox.element.trigger('change');
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateSelectionStates(dualListbox) {
|
|
||||||
dualListbox.element.find('option').each(function(index, item) {
|
|
||||||
var $item = $(item);
|
|
||||||
if (typeof($item.data('original-index')) === 'undefined') {
|
|
||||||
$item.data('original-index', dualListbox.elementCount++);
|
|
||||||
}
|
|
||||||
if (typeof($item.data('_selected')) === 'undefined') {
|
|
||||||
$item.data('_selected', false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeSelectionState(dualListbox, original_index, selected) {
|
|
||||||
dualListbox.element.find('option').each(function(index, item) {
|
|
||||||
var $item = $(item);
|
|
||||||
if ($item.data('original-index') === original_index) {
|
|
||||||
$item.prop('selected', selected);
|
|
||||||
if(selected){
|
|
||||||
$item.attr('data-sortindex', dualListbox.sortIndex);
|
|
||||||
dualListbox.sortIndex++;
|
|
||||||
} else {
|
|
||||||
$item.removeAttr('data-sortindex');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatString(s, args) {
|
|
||||||
return s.replace(/\{(\d+)\}/g, function(match, number) {
|
|
||||||
return typeof args[number] !== 'undefined' ? args[number] : match;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshInfo(dualListbox) {
|
|
||||||
if (!dualListbox.settings.infoText) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var visible1 = dualListbox.elements.select1.find('option').length,
|
|
||||||
visible2 = dualListbox.elements.select2.find('option').length,
|
|
||||||
all1 = dualListbox.element.find('option').length - dualListbox.selectedElements,
|
|
||||||
all2 = dualListbox.selectedElements,
|
|
||||||
content = '';
|
|
||||||
|
|
||||||
if (all1 === 0) {
|
|
||||||
content = dualListbox.settings.infoTextEmpty;
|
|
||||||
} else if (visible1 === all1) {
|
|
||||||
content = formatString(dualListbox.settings.infoText, [visible1, all1]);
|
|
||||||
} else {
|
|
||||||
content = formatString(dualListbox.settings.infoTextFiltered, [visible1, all1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
dualListbox.elements.info1.html(content);
|
|
||||||
dualListbox.elements.box1.toggleClass('filtered', !(visible1 === all1 || all1 === 0));
|
|
||||||
|
|
||||||
if (all2 === 0) {
|
|
||||||
content = dualListbox.settings.infoTextEmpty;
|
|
||||||
} else if (visible2 === all2) {
|
|
||||||
content = formatString(dualListbox.settings.infoText, [visible2, all2]);
|
|
||||||
} else {
|
|
||||||
content = formatString(dualListbox.settings.infoTextFiltered, [visible2, all2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
dualListbox.elements.info2.html(content);
|
|
||||||
dualListbox.elements.box2.toggleClass('filtered', !(visible2 === all2 || all2 === 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshSelects(dualListbox) {
|
|
||||||
dualListbox.selectedElements = 0;
|
|
||||||
|
|
||||||
dualListbox.elements.select1.empty();
|
|
||||||
dualListbox.elements.select2.empty();
|
|
||||||
|
|
||||||
dualListbox.element.find('option').each(function(index, item) {
|
|
||||||
var $item = $(item);
|
|
||||||
if ($item.prop('selected')) {
|
|
||||||
dualListbox.selectedElements++;
|
|
||||||
dualListbox.elements.select2.append($item.clone(true).prop('selected', $item.data('_selected')));
|
|
||||||
} else {
|
|
||||||
dualListbox.elements.select1.append($item.clone(true).prop('selected', $item.data('_selected')));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (dualListbox.settings.showFilterInputs) {
|
|
||||||
filter(dualListbox, 1);
|
|
||||||
filter(dualListbox, 2);
|
|
||||||
}
|
|
||||||
refreshInfo(dualListbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
function filter(dualListbox, selectIndex) {
|
|
||||||
if (!dualListbox.settings.showFilterInputs) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
saveSelections(dualListbox, selectIndex);
|
|
||||||
|
|
||||||
dualListbox.elements['select'+selectIndex].empty().scrollTop(0);
|
|
||||||
var regex = new RegExp($.trim(dualListbox.elements['filterInput'+selectIndex].val()), 'gi'),
|
|
||||||
allOptions = dualListbox.element.find('option'),
|
|
||||||
options = dualListbox.element;
|
|
||||||
|
|
||||||
if (selectIndex === 1) {
|
|
||||||
options = allOptions.not(':selected');
|
|
||||||
} else {
|
|
||||||
options = options.find('option:selected');
|
|
||||||
}
|
|
||||||
|
|
||||||
options.each(function(index, item) {
|
|
||||||
var $item = $(item),
|
|
||||||
isFiltered = true;
|
|
||||||
if (item.text.match(regex) || (dualListbox.settings.filterOnValues && $item.attr('value').match(regex) ) ) {
|
|
||||||
isFiltered = false;
|
|
||||||
dualListbox.elements['select'+selectIndex].append($item.clone(true).prop('selected', $item.data('_selected')));
|
|
||||||
}
|
|
||||||
allOptions.eq($item.data('original-index')).data('filtered'+selectIndex, isFiltered);
|
|
||||||
});
|
|
||||||
|
|
||||||
refreshInfo(dualListbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveSelections(dualListbox, selectIndex) {
|
|
||||||
var options = dualListbox.element.find('option');
|
|
||||||
dualListbox.elements['select'+selectIndex].find('option').each(function(index, item) {
|
|
||||||
var $item = $(item);
|
|
||||||
options.eq($item.data('original-index')).data('_selected', $item.prop('selected'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function sortOptionsByInputOrder(select){
|
|
||||||
var selectopt = select.children('option');
|
|
||||||
|
|
||||||
selectopt.sort(function(a,b){
|
|
||||||
var an = parseInt(a.getAttribute('data-sortindex')),
|
|
||||||
bn = parseInt(b.getAttribute('data-sortindex'));
|
|
||||||
|
|
||||||
if(an > bn) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if(an < bn) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
selectopt.detach().appendTo(select);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sortOptions(select, dualListbox) {
|
|
||||||
select.find('option').sort(function(a, b) {
|
|
||||||
return ($(a).data('original-index') > $(b).data('original-index')) ? 1 : -1;
|
|
||||||
}).appendTo(select);
|
|
||||||
|
|
||||||
// workaround for chromium bug: https://bugs.chromium.org/p/chromium/issues/detail?id=1072475
|
|
||||||
refreshSelects(dualListbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearSelections(dualListbox) {
|
|
||||||
dualListbox.elements.select1.find('option').each(function() {
|
|
||||||
dualListbox.element.find('option').data('_selected', false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function move(dualListbox) {
|
|
||||||
if (dualListbox.settings.preserveSelectionOnMove === 'all' && !dualListbox.settings.moveOnSelect) {
|
|
||||||
saveSelections(dualListbox, 1);
|
|
||||||
saveSelections(dualListbox, 2);
|
|
||||||
} else if (dualListbox.settings.preserveSelectionOnMove === 'moved' && !dualListbox.settings.moveOnSelect) {
|
|
||||||
saveSelections(dualListbox, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
dualListbox.elements.select1.find('option:selected').each(function(index, item) {
|
|
||||||
var $item = $(item);
|
|
||||||
if (!$item.data('filtered1')) {
|
|
||||||
changeSelectionState(dualListbox, $item.data('original-index'), true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
refreshSelects(dualListbox);
|
|
||||||
triggerChangeEvent(dualListbox);
|
|
||||||
if(dualListbox.settings.sortByInputOrder){
|
|
||||||
sortOptionsByInputOrder(dualListbox.elements.select2);
|
|
||||||
} else {
|
|
||||||
sortOptions(dualListbox.elements.select2, dualListbox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function remove(dualListbox) {
|
|
||||||
if (dualListbox.settings.preserveSelectionOnMove === 'all' && !dualListbox.settings.moveOnSelect) {
|
|
||||||
saveSelections(dualListbox, 1);
|
|
||||||
saveSelections(dualListbox, 2);
|
|
||||||
} else if (dualListbox.settings.preserveSelectionOnMove === 'moved' && !dualListbox.settings.moveOnSelect) {
|
|
||||||
saveSelections(dualListbox, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
dualListbox.elements.select2.find('option:selected').each(function(index, item) {
|
|
||||||
var $item = $(item);
|
|
||||||
if (!$item.data('filtered2')) {
|
|
||||||
changeSelectionState(dualListbox, $item.data('original-index'), false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
refreshSelects(dualListbox);
|
|
||||||
triggerChangeEvent(dualListbox);
|
|
||||||
sortOptions(dualListbox.elements.select1, dualListbox);
|
|
||||||
if(dualListbox.settings.sortByInputOrder){
|
|
||||||
sortOptionsByInputOrder(dualListbox.elements.select2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveAll(dualListbox) {
|
|
||||||
if (dualListbox.settings.preserveSelectionOnMove === 'all' && !dualListbox.settings.moveOnSelect) {
|
|
||||||
saveSelections(dualListbox, 1);
|
|
||||||
saveSelections(dualListbox, 2);
|
|
||||||
} else if (dualListbox.settings.preserveSelectionOnMove === 'moved' && !dualListbox.settings.moveOnSelect) {
|
|
||||||
saveSelections(dualListbox, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
dualListbox.element.find('option').each(function(index, item) {
|
|
||||||
var $item = $(item);
|
|
||||||
if (!$item.data('filtered1')) {
|
|
||||||
$item.prop('selected', true);
|
|
||||||
$item.attr('data-sortindex', dualListbox.sortIndex);
|
|
||||||
dualListbox.sortIndex++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
refreshSelects(dualListbox);
|
|
||||||
triggerChangeEvent(dualListbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeAll(dualListbox) {
|
|
||||||
if (dualListbox.settings.preserveSelectionOnMove === 'all' && !dualListbox.settings.moveOnSelect) {
|
|
||||||
saveSelections(dualListbox, 1);
|
|
||||||
saveSelections(dualListbox, 2);
|
|
||||||
} else if (dualListbox.settings.preserveSelectionOnMove === 'moved' && !dualListbox.settings.moveOnSelect) {
|
|
||||||
saveSelections(dualListbox, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
dualListbox.element.find('option').each(function(index, item) {
|
|
||||||
var $item = $(item);
|
|
||||||
if (!$item.data('filtered2')) {
|
|
||||||
$item.prop('selected', false);
|
|
||||||
$item.removeAttr('data-sortindex');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
refreshSelects(dualListbox);
|
|
||||||
triggerChangeEvent(dualListbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
function bindEvents(dualListbox) {
|
|
||||||
dualListbox.elements.form.submit(function(e) {
|
|
||||||
if (dualListbox.elements.filterInput1.is(':focus')) {
|
|
||||||
e.preventDefault();
|
|
||||||
dualListbox.elements.filterInput1.focusout();
|
|
||||||
} else if (dualListbox.elements.filterInput2.is(':focus')) {
|
|
||||||
e.preventDefault();
|
|
||||||
dualListbox.elements.filterInput2.focusout();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
dualListbox.element.on('bootstrapDualListbox.refresh', function(e, mustClearSelections){
|
|
||||||
dualListbox.refresh(mustClearSelections);
|
|
||||||
});
|
|
||||||
|
|
||||||
dualListbox.elements.filterClear1.on('click', function() {
|
|
||||||
dualListbox.setNonSelectedFilter('', true);
|
|
||||||
});
|
|
||||||
|
|
||||||
dualListbox.elements.filterClear2.on('click', function() {
|
|
||||||
dualListbox.setSelectedFilter('', true);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (dualListbox.settings.eventMoveOverride === false) {
|
|
||||||
dualListbox.elements.moveButton.on('click', function() {
|
|
||||||
move(dualListbox);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dualListbox.settings.eventMoveAllOverride === false) {
|
|
||||||
dualListbox.elements.moveAllButton.on('click', function() {
|
|
||||||
moveAll(dualListbox);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dualListbox.settings.eventRemoveOverride === false) {
|
|
||||||
dualListbox.elements.removeButton.on('click', function() {
|
|
||||||
remove(dualListbox);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dualListbox.settings.eventRemoveAllOverride === false) {
|
|
||||||
dualListbox.elements.removeAllButton.on('click', function() {
|
|
||||||
removeAll(dualListbox);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dualListbox.elements.filterInput1.on('change keyup', function() {
|
|
||||||
filter(dualListbox, 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
dualListbox.elements.filterInput2.on('change keyup', function() {
|
|
||||||
filter(dualListbox, 2);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
BootstrapDualListbox.prototype = {
|
|
||||||
init: function () {
|
|
||||||
// Add the custom HTML template
|
|
||||||
this.container = $('' +
|
|
||||||
'<div class="bootstrap-duallistbox-container">' +
|
|
||||||
' <div class="box1">' +
|
|
||||||
' <label></label>' +
|
|
||||||
' <span class="info-container">' +
|
|
||||||
' <span class="info"></span>' +
|
|
||||||
' <button type="button" class="btn clear1 pull-right"></button>' +
|
|
||||||
' </span>' +
|
|
||||||
' <input class="filter" type="text">' +
|
|
||||||
' <div class="btn-group buttons">' +
|
|
||||||
' <button type="button" class="btn moveall">' +
|
|
||||||
' <i></i>' +
|
|
||||||
' <i></i>' +
|
|
||||||
' </button>' +
|
|
||||||
' <button type="button" class="btn move">' +
|
|
||||||
' <i></i>' +
|
|
||||||
' </button>' +
|
|
||||||
' </div>' +
|
|
||||||
' <select multiple="multiple"></select>' +
|
|
||||||
' </div>' +
|
|
||||||
' <div class="box2">' +
|
|
||||||
' <label></label>' +
|
|
||||||
' <span class="info-container">' +
|
|
||||||
' <span class="info"></span>' +
|
|
||||||
' <button type="button" class="btn clear2 pull-right"></button>' +
|
|
||||||
' </span>' +
|
|
||||||
' <input class="filter" type="text">' +
|
|
||||||
' <div class="btn-group buttons">' +
|
|
||||||
' <button type="button" class="btn remove">' +
|
|
||||||
' <i></i>' +
|
|
||||||
' </button>' +
|
|
||||||
' <button type="button" class="btn removeall">' +
|
|
||||||
' <i></i>' +
|
|
||||||
' <i></i>' +
|
|
||||||
' </button>' +
|
|
||||||
' </div>' +
|
|
||||||
' <select multiple="multiple"></select>' +
|
|
||||||
' </div>' +
|
|
||||||
'</div>')
|
|
||||||
.insertBefore(this.element);
|
|
||||||
|
|
||||||
// Cache the inner elements
|
|
||||||
this.elements = {
|
|
||||||
originalSelect: this.element,
|
|
||||||
box1: $('.box1', this.container),
|
|
||||||
box2: $('.box2', this.container),
|
|
||||||
filterInput1: $('.box1 .filter', this.container),
|
|
||||||
filterInput2: $('.box2 .filter', this.container),
|
|
||||||
filterClear1: $('.box1 .clear1', this.container),
|
|
||||||
filterClear2: $('.box2 .clear2', this.container),
|
|
||||||
label1: $('.box1 > label', this.container),
|
|
||||||
label2: $('.box2 > label', this.container),
|
|
||||||
info1: $('.box1 .info', this.container),
|
|
||||||
info2: $('.box2 .info', this.container),
|
|
||||||
select1: $('.box1 select', this.container),
|
|
||||||
select2: $('.box2 select', this.container),
|
|
||||||
moveButton: $('.box1 .move', this.container),
|
|
||||||
removeButton: $('.box2 .remove', this.container),
|
|
||||||
moveAllButton: $('.box1 .moveall', this.container),
|
|
||||||
removeAllButton: $('.box2 .removeall', this.container),
|
|
||||||
form: $($('.box1 .filter', this.container)[0].form)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set select IDs
|
|
||||||
this.originalSelectName = this.element.attr('name') || '';
|
|
||||||
var select1Id = 'bootstrap-duallistbox-nonselected-list_' + this.originalSelectName,
|
|
||||||
select2Id = 'bootstrap-duallistbox-selected-list_' + this.originalSelectName;
|
|
||||||
this.elements.select1.attr('id', select1Id);
|
|
||||||
this.elements.select2.attr('id', select2Id);
|
|
||||||
this.elements.label1.attr('for', select1Id);
|
|
||||||
this.elements.label2.attr('for', select2Id);
|
|
||||||
|
|
||||||
// Apply all settings
|
|
||||||
this.selectedElements = 0;
|
|
||||||
this.sortIndex = 0;
|
|
||||||
this.elementCount = 0;
|
|
||||||
this.setBootstrap2Compatible(this.settings.bootstrap2Compatible);
|
|
||||||
this.setFilterTextClear(this.settings.filterTextClear);
|
|
||||||
this.setFilterPlaceHolder(this.settings.filterPlaceHolder);
|
|
||||||
this.setMoveSelectedLabel(this.settings.moveSelectedLabel);
|
|
||||||
this.setMoveAllLabel(this.settings.moveAllLabel);
|
|
||||||
this.setRemoveSelectedLabel(this.settings.removeSelectedLabel);
|
|
||||||
this.setRemoveAllLabel(this.settings.removeAllLabel);
|
|
||||||
this.setMoveOnSelect(this.settings.moveOnSelect);
|
|
||||||
this.setMoveOnDoubleClick(this.settings.moveOnDoubleClick);
|
|
||||||
this.setPreserveSelectionOnMove(this.settings.preserveSelectionOnMove);
|
|
||||||
this.setSelectedListLabel(this.settings.selectedListLabel);
|
|
||||||
this.setNonSelectedListLabel(this.settings.nonSelectedListLabel);
|
|
||||||
this.setHelperSelectNamePostfix(this.settings.helperSelectNamePostfix);
|
|
||||||
this.setSelectOrMinimalHeight(this.settings.selectorMinimalHeight);
|
|
||||||
|
|
||||||
updateSelectionStates(this);
|
|
||||||
|
|
||||||
this.setShowFilterInputs(this.settings.showFilterInputs);
|
|
||||||
this.setNonSelectedFilter(this.settings.nonSelectedFilter);
|
|
||||||
this.setSelectedFilter(this.settings.selectedFilter);
|
|
||||||
this.setInfoText(this.settings.infoText);
|
|
||||||
this.setInfoTextFiltered(this.settings.infoTextFiltered);
|
|
||||||
this.setInfoTextEmpty(this.settings.infoTextEmpty);
|
|
||||||
this.setFilterOnValues(this.settings.filterOnValues);
|
|
||||||
this.setSortByInputOrder(this.settings.sortByInputOrder);
|
|
||||||
this.setEventMoveOverride(this.settings.eventMoveOverride);
|
|
||||||
this.setEventMoveAllOverride(this.settings.eventMoveAllOverride);
|
|
||||||
this.setEventRemoveOverride(this.settings.eventRemoveOverride);
|
|
||||||
this.setEventRemoveAllOverride(this.settings.eventRemoveAllOverride);
|
|
||||||
|
|
||||||
// Hide the original select
|
|
||||||
this.element.hide();
|
|
||||||
|
|
||||||
bindEvents(this);
|
|
||||||
refreshSelects(this);
|
|
||||||
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setBootstrap2Compatible: function(value, refresh) {
|
|
||||||
this.settings.bootstrap2Compatible = value;
|
|
||||||
if (value) {
|
|
||||||
this.container.removeClass('row').addClass('row-fluid bs2compatible');
|
|
||||||
this.container.find('.box1, .box2').removeClass('col-md-6').addClass('span6');
|
|
||||||
this.container.find('.clear1, .clear2').removeClass('btn-default btn-xs').addClass('btn-mini');
|
|
||||||
this.container.find('input, select').removeClass('form-control');
|
|
||||||
this.container.find('.btn').removeClass('btn-default');
|
|
||||||
this.container.find('.moveall > i, .move > i').removeClass('glyphicon glyphicon-arrow-right').addClass('icon-arrow-right');
|
|
||||||
this.container.find('.removeall > i, .remove > i').removeClass('glyphicon glyphicon-arrow-left').addClass('icon-arrow-left');
|
|
||||||
} else {
|
|
||||||
this.container.removeClass('row-fluid bs2compatible').addClass('row');
|
|
||||||
this.container.find('.box1, .box2').removeClass('span6').addClass('col-md-6');
|
|
||||||
this.container.find('.clear1, .clear2').removeClass('btn-mini').addClass('btn-default btn-xs');
|
|
||||||
this.container.find('input, select').addClass('form-control');
|
|
||||||
this.container.find('.btn').addClass('btn-default');
|
|
||||||
this.container.find('.moveall > i, .move > i').removeClass('icon-arrow-right').addClass('glyphicon glyphicon-arrow-right');
|
|
||||||
this.container.find('.removeall > i, .remove > i').removeClass('icon-arrow-left').addClass('glyphicon glyphicon-arrow-left');
|
|
||||||
}
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setFilterTextClear: function(value, refresh) {
|
|
||||||
this.settings.filterTextClear = value;
|
|
||||||
this.elements.filterClear1.html(value);
|
|
||||||
this.elements.filterClear2.html(value);
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setFilterPlaceHolder: function(value, refresh) {
|
|
||||||
this.settings.filterPlaceHolder = value;
|
|
||||||
this.elements.filterInput1.attr('placeholder', value);
|
|
||||||
this.elements.filterInput2.attr('placeholder', value);
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setMoveSelectedLabel: function(value, refresh) {
|
|
||||||
this.settings.moveSelectedLabel = value;
|
|
||||||
this.elements.moveButton.attr('title', value);
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setMoveAllLabel: function(value, refresh) {
|
|
||||||
this.settings.moveAllLabel = value;
|
|
||||||
this.elements.moveAllButton.attr('title', value);
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setRemoveSelectedLabel: function(value, refresh) {
|
|
||||||
this.settings.removeSelectedLabel = value;
|
|
||||||
this.elements.removeButton.attr('title', value);
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setRemoveAllLabel: function(value, refresh) {
|
|
||||||
this.settings.removeAllLabel = value;
|
|
||||||
this.elements.removeAllButton.attr('title', value);
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setMoveOnSelect: function(value, refresh) {
|
|
||||||
if (isBuggyAndroid) {
|
|
||||||
value = true;
|
|
||||||
}
|
|
||||||
this.settings.moveOnSelect = value;
|
|
||||||
if (this.settings.moveOnSelect) {
|
|
||||||
this.container.addClass('moveonselect');
|
|
||||||
var self = this;
|
|
||||||
this.elements.select1.on('change', function() {
|
|
||||||
move(self);
|
|
||||||
});
|
|
||||||
this.elements.select2.on('change', function() {
|
|
||||||
remove(self);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.container.removeClass('moveonselect');
|
|
||||||
this.elements.select1.off('change');
|
|
||||||
this.elements.select2.off('change');
|
|
||||||
}
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setMoveOnDoubleClick: function(value, refresh) {
|
|
||||||
if (isBuggyAndroid) {
|
|
||||||
value = false;
|
|
||||||
}
|
|
||||||
this.settings.moveOnDoubleClick = value;
|
|
||||||
if (this.settings.moveOnDoubleClick) {
|
|
||||||
this.container.addClass('moveondoubleclick');
|
|
||||||
var self = this;
|
|
||||||
this.elements.select1.on('dblclick', function() {
|
|
||||||
move(self);
|
|
||||||
});
|
|
||||||
this.elements.select2.on('dblclick', function() {
|
|
||||||
remove(self);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.container.removeClass('moveondoubleclick');
|
|
||||||
this.elements.select1.off('dblclick');
|
|
||||||
this.elements.select2.off('dblclick');
|
|
||||||
}
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setPreserveSelectionOnMove: function(value, refresh) {
|
|
||||||
// We are forcing to move on select and disabling preserveSelectionOnMove on Android
|
|
||||||
if (isBuggyAndroid) {
|
|
||||||
value = false;
|
|
||||||
}
|
|
||||||
this.settings.preserveSelectionOnMove = value;
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setSelectedListLabel: function(value, refresh) {
|
|
||||||
this.settings.selectedListLabel = value;
|
|
||||||
if (value) {
|
|
||||||
this.elements.label2.show().html(value);
|
|
||||||
} else {
|
|
||||||
this.elements.label2.hide().html(value);
|
|
||||||
}
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setNonSelectedListLabel: function(value, refresh) {
|
|
||||||
this.settings.nonSelectedListLabel = value;
|
|
||||||
if (value) {
|
|
||||||
this.elements.label1.show().html(value);
|
|
||||||
} else {
|
|
||||||
this.elements.label1.hide().html(value);
|
|
||||||
}
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setHelperSelectNamePostfix: function(value, refresh) {
|
|
||||||
this.settings.helperSelectNamePostfix = value;
|
|
||||||
if (value) {
|
|
||||||
this.elements.select1.attr('name', this.originalSelectName + value + '1');
|
|
||||||
this.elements.select2.attr('name', this.originalSelectName + value + '2');
|
|
||||||
} else {
|
|
||||||
this.elements.select1.removeAttr('name');
|
|
||||||
this.elements.select2.removeAttr('name');
|
|
||||||
}
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setSelectOrMinimalHeight: function(value, refresh) {
|
|
||||||
this.settings.selectorMinimalHeight = value;
|
|
||||||
var height = this.element.height();
|
|
||||||
if (this.element.height() < value) {
|
|
||||||
height = value;
|
|
||||||
}
|
|
||||||
this.elements.select1.height(height);
|
|
||||||
this.elements.select2.height(height);
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setShowFilterInputs: function(value, refresh) {
|
|
||||||
if (!value) {
|
|
||||||
this.setNonSelectedFilter('');
|
|
||||||
this.setSelectedFilter('');
|
|
||||||
refreshSelects(this);
|
|
||||||
this.elements.filterInput1.hide();
|
|
||||||
this.elements.filterInput2.hide();
|
|
||||||
} else {
|
|
||||||
this.elements.filterInput1.show();
|
|
||||||
this.elements.filterInput2.show();
|
|
||||||
}
|
|
||||||
this.settings.showFilterInputs = value;
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setNonSelectedFilter: function(value, refresh) {
|
|
||||||
if (this.settings.showFilterInputs) {
|
|
||||||
this.settings.nonSelectedFilter = value;
|
|
||||||
this.elements.filterInput1.val(value);
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setSelectedFilter: function(value, refresh) {
|
|
||||||
if (this.settings.showFilterInputs) {
|
|
||||||
this.settings.selectedFilter = value;
|
|
||||||
this.elements.filterInput2.val(value);
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setInfoText: function(value, refresh) {
|
|
||||||
this.settings.infoText = value;
|
|
||||||
if (value) {
|
|
||||||
this.elements.info1.show();
|
|
||||||
this.elements.info2.show();
|
|
||||||
} else {
|
|
||||||
this.elements.info1.hide();
|
|
||||||
this.elements.info2.hide();
|
|
||||||
}
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setInfoTextFiltered: function(value, refresh) {
|
|
||||||
this.settings.infoTextFiltered = value;
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setInfoTextEmpty: function(value, refresh) {
|
|
||||||
this.settings.infoTextEmpty = value;
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setFilterOnValues: function(value, refresh) {
|
|
||||||
this.settings.filterOnValues = value;
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setSortByInputOrder: function(value, refresh){
|
|
||||||
this.settings.sortByInputOrder = value;
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setEventMoveOverride: function(value, refresh) {
|
|
||||||
this.settings.eventMoveOverride = value;
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setEventMoveAllOverride: function(value, refresh) {
|
|
||||||
this.settings.eventMoveAllOverride = value;
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setEventRemoveOverride: function(value, refresh) {
|
|
||||||
this.settings.eventRemoveOverride = value;
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
setEventRemoveAllOverride: function(value, refresh) {
|
|
||||||
this.settings.eventRemoveAllOverride = value;
|
|
||||||
if (refresh) {
|
|
||||||
refreshSelects(this);
|
|
||||||
}
|
|
||||||
return this.element;
|
|
||||||
},
|
|
||||||
getContainer: function() {
|
|
||||||
return this.container;
|
|
||||||
},
|
|
||||||
refresh: function(mustClearSelections) {
|
|
||||||
updateSelectionStates(this);
|
|
||||||
|
|
||||||
if (!mustClearSelections) {
|
|
||||||
saveSelections(this, 1);
|
|
||||||
saveSelections(this, 2);
|
|
||||||
} else {
|
|
||||||
clearSelections(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshSelects(this);
|
|
||||||
},
|
|
||||||
destroy: function() {
|
|
||||||
this.container.remove();
|
|
||||||
this.element.show();
|
|
||||||
$.data(this, 'plugin_' + pluginName, null);
|
|
||||||
return this.element;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// A really lightweight plugin wrapper around the constructor,
|
|
||||||
// preventing against multiple instantiations
|
|
||||||
$.fn[ pluginName ] = function (options) {
|
|
||||||
var args = arguments;
|
|
||||||
|
|
||||||
// Is the first parameter an object (options), or was omitted, instantiate a new instance of the plugin.
|
|
||||||
if (options === undefined || typeof options === 'object') {
|
|
||||||
return this.each(function () {
|
|
||||||
// If this is not a select
|
|
||||||
if (!$(this).is('select')) {
|
|
||||||
$(this).find('select').each(function(index, item) {
|
|
||||||
// For each nested select, instantiate the Dual List Box
|
|
||||||
$(item).bootstrapDualListbox(options);
|
|
||||||
});
|
|
||||||
} else if (!$.data(this, 'plugin_' + pluginName)) {
|
|
||||||
// Only allow the plugin to be instantiated once so we check that the element has no plugin instantiation yet
|
|
||||||
|
|
||||||
// if it has no instance, create a new one, pass options to our plugin constructor,
|
|
||||||
// and store the plugin instance in the elements jQuery data object.
|
|
||||||
$.data(this, 'plugin_' + pluginName, new BootstrapDualListbox(this, options));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// If the first parameter is a string and it doesn't start with an underscore or "contains" the `init`-function,
|
|
||||||
// treat this as a call to a public method.
|
|
||||||
} else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
|
|
||||||
|
|
||||||
// Cache the method call to make it possible to return a value
|
|
||||||
var returns;
|
|
||||||
|
|
||||||
this.each(function () {
|
|
||||||
var instance = $.data(this, 'plugin_' + pluginName);
|
|
||||||
// Tests that there's already a plugin-instance and checks that the requested public method exists
|
|
||||||
if (instance instanceof BootstrapDualListbox && typeof instance[options] === 'function') {
|
|
||||||
// Call the method of our plugin instance, and pass it the supplied arguments.
|
|
||||||
returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// If the earlier cached method gives a value back return the value,
|
|
||||||
// otherwise return this to preserve chainability.
|
|
||||||
return returns !== undefined ? returns : this;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
})(jQuery, window, document);
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
/*
|
|
||||||
* Bootstrap Duallistbox - v3.0.9
|
|
||||||
* A responsive dual listbox widget optimized for Twitter Bootstrap. It works on all modern browsers and on touch devices.
|
|
||||||
* https://www.virtuosoft.eu/code/bootstrap-duallistbox/
|
|
||||||
*
|
|
||||||
* Made by István Ujj-Mészáros
|
|
||||||
* Under Apache License v2.0 License
|
|
||||||
*/
|
|
||||||
.bootstrap-duallistbox-container .buttons{width:100%;margin-bottom:-1px}.bootstrap-duallistbox-container label{display:block}.bootstrap-duallistbox-container .info{display:inline-block;margin-bottom:5px;font-size:11px}.bootstrap-duallistbox-container .clear1,.bootstrap-duallistbox-container .clear2{display:none;font-size:10px}.bootstrap-duallistbox-container .box1.filtered .clear1,.bootstrap-duallistbox-container .box2.filtered .clear2{display:inline-block}.bootstrap-duallistbox-container .move,.bootstrap-duallistbox-container .remove{width:60%}.bootstrap-duallistbox-container .btn-group .btn{border-bottom-left-radius:0;border-bottom-right-radius:0}.bootstrap-duallistbox-container select{border-top-left-radius:0;border-top-right-radius:0}.bootstrap-duallistbox-container .moveall,.bootstrap-duallistbox-container .removeall{width:40%}.bootstrap-duallistbox-container.bs2compatible .btn-group>.btn+.btn{margin-left:0}.bootstrap-duallistbox-container select{width:100%;height:300px;padding:0}.bootstrap-duallistbox-container .filter{display:inline-block;width:100%;height:31px;margin:0 0 5px 0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-duallistbox-container .filter.placeholder{color:#aaa}.bootstrap-duallistbox-container.moveonselect .move,.bootstrap-duallistbox-container.moveonselect .remove{display:none}.bootstrap-duallistbox-container.moveonselect .moveall,.bootstrap-duallistbox-container.moveonselect .removeall{width:100%}
|
|
||||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue