Compare commits

...

No commits in common. "v4.7.6" and "master" have entirely different histories.

960 changed files with 44671 additions and 135870 deletions

2
.github/FUNDING.yml vendored
View File

@ -1 +1 @@
custom: http://doc.ruoyi.vip/ruoyi/other/donate.html
custom: http://doc.ruoyi.vip/ruoyi-vue/other/donate.html

93
.gitignore vendored
View File

@ -1,46 +1,47 @@
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### JRebel ###
rebel.xml
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
!*/build/*.java
!*/build/*.html
!*/build/*.xml
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### JRebel ###
rebel.xml
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
!*/build/*.java
!*/build/*.html
!*/build/*.xml

38
LICENSE
View File

@ -1,20 +1,20 @@
The MIT License (MIT)
Copyright (c) 2018 RuoYi
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
The MIT License (MIT)
Copyright (c) 2018 RuoYi
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

198
README.md
View File

@ -1,102 +1,96 @@
<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.6</h1>
<h4 align="center">基于SpringBoot开发的轻量级Java快速开发框架</h4>
<p align="center">
<a href="https://gitee.com/y_project/RuoYi/stargazers"><img src="https://gitee.com/y_project/RuoYi/badge/star.svg?theme=gvp"></a>
<a href="https://gitee.com/y_project/RuoYi"><img src="https://img.shields.io/badge/RuoYi-v4.7.6-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p>
## 平台简介
一直想做一款后台管理系统看了很多优秀的开源项目但是发现没有合适的。于是利用空闲休息时间开始自己写了一套后台系统。如此有了若依。她可以用于所有的Web应用程序如网站管理后台网站会员中心CMSCRMOA。所有前端后台代码封装过后十分精简易上手出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
性别男,若依是给女儿取的名字(寓意:你若不离不弃,我必生死相依)
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
* 前后端分离版本,请移步[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
* 感谢 [hplus](https://gitee.com/hplus_admin/hplus) 后台主题 UI 框架。
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
* 阿里云优惠券:[点我领取](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)&nbsp;&nbsp;
## 内置功能
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
3. 岗位管理:配置系统用户所属担任职务。
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
7. 参数管理:对系统动态配置常用参数。
8. 通知公告:系统通知公告信息发布维护。
9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
10. 登录日志:系统登录日志记录查询包含登录异常。
11. 在线用户:当前系统中活跃用户状态监控。
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
13. 代码生成前后端代码的生成java、html、xml、sql支持CRUD下载 。
14. 系统接口根据业务代码自动生成相关的api接口文档。
15. 服务监控监视当前系统CPU、内存、磁盘、堆栈等相关信息。
16. 缓存监控:对系统的缓存查询,删除、清空等操作。
17. 在线构建器拖动表单元素生成相应的HTML代码。
18. 连接池监视监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈。
## 在线体验
- admin/admin123
- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
演示地址http://ruoyi.vip
文档地址http://doc.ruoyi.vip
## 演示图
<table>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-42e518aa72a24d228427a1261cb3679f395.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-7f20dd0edba25e5187c5c4dd3ec7d3d9797.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-2dae3d87f6a8ca05057db059cd9a411d51d.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-ea4d98423471e55fba784694e45d12bd4bb.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-7f6c6e9f5873efca09bd2870ee8468b8fce.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-c708b65f2c382a03f69fe1efa8d341e6cff.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-9ab586c47dd5c7b92bca0d727962c90e3b8.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-ef954122a2080e02013112db21754b955c6.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-088edb4d531e122415a1e2342bccb1a9691.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-f886fe19bd820c0efae82f680223cac196c.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-c7a2eb71fa65d6e660294b4bccca613d638.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-e60137fb0787defe613bd83331dc4755a70.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-7c51c1b5758f0a0f92ed3c60469b7526f9f.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-15181aed45bb2461aa97b594cbf2f86ea5f.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-83326ad52ea63f67233d126226738054d98.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-3bd6d31e913b70df00107db51d64ef81df7.png"/></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>
</table>
## 若依交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-1389287-blue.svg)](https://jq.qq.com/?_wv=1027&k=5HBAaYN) [![加入QQ群](https://img.shields.io/badge/已满-1679294-blue.svg)](https://jq.qq.com/?_wv=1027&k=5cHeRVW) [![加入QQ群](https://img.shields.io/badge/已满-1529866-blue.svg)](https://jq.qq.com/?_wv=1027&k=53R0L5Z) [![加入QQ群](https://img.shields.io/badge/已满-1772718-blue.svg)](https://jq.qq.com/?_wv=1027&k=5g75dCU) [![加入QQ群](https://img.shields.io/badge/已满-1366522-blue.svg)](https://jq.qq.com/?_wv=1027&k=58cPoHA) [![加入QQ群](https://img.shields.io/badge/已满-1382251-blue.svg)](https://jq.qq.com/?_wv=1027&k=5Ofd4Pb) [![加入QQ群](https://img.shields.io/badge/已满-1145125-blue.svg)](https://jq.qq.com/?_wv=1027&k=5yugASz) [![加入QQ群](https://img.shields.io/badge/已满-86752435-blue.svg)](https://jq.qq.com/?_wv=1027&k=5Rf3d2P) [![加入QQ群](https://img.shields.io/badge/已满-134072510-blue.svg)](https://jq.qq.com/?_wv=1027&k=5ZIjaeP) [![加入QQ群](https://img.shields.io/badge/已满-210336300-blue.svg)](https://jq.qq.com/?_wv=1027&k=5CJw1jY) [![加入QQ群](https://img.shields.io/badge/已满-339522636-blue.svg)](https://jq.qq.com/?_wv=1027&k=5omzbKc) [![加入QQ群](https://img.shields.io/badge/已满-130035985-blue.svg)](https://jq.qq.com/?_wv=1027&k=qPIKBb7s) [![加入QQ群](https://img.shields.io/badge/已满-143151071-blue.svg)](https://jq.qq.com/?_wv=1027&k=4NsjKbtU) [![加入QQ群](https://img.shields.io/badge/已满-158781320-blue.svg)](https://jq.qq.com/?_wv=1027&k=VD2pkz2G) [![加入QQ群](https://img.shields.io/badge/已满-201531282-blue.svg)](https://jq.qq.com/?_wv=1027&k=HlshFwkJ) [![加入QQ群](https://img.shields.io/badge/已满-101526938-blue.svg)](https://jq.qq.com/?_wv=1027&k=0ARRrO9V) [![加入QQ群](https://img.shields.io/badge/已满-264355400-blue.svg)](https://jq.qq.com/?_wv=1027&k=up9k3ZXJ) [![加入QQ群](https://img.shields.io/badge/已满-298522656-blue.svg)](https://jq.qq.com/?_wv=1027&k=540WfdEr) [![加入QQ群](https://img.shields.io/badge/已满-139845794-blue.svg)](https://jq.qq.com/?_wv=1027&k=ss91fC4t) [![加入QQ群](https://img.shields.io/badge/185760789-blue.svg)](https://jq.qq.com/?_wv=1027&k=Cqd66IKe)
<p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.7</h1>
<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
<p align="center">
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.7-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p>
## 平台简介
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
* 前端采用Vue、Element UI。
* 后端采用Spring Boot、Spring Security、Redis & Jwt。
* 权限认证使用Jwt支持多终端认证系统。
* 支持加载动态权限菜单,多方式轻松权限控制。
* 高效率开发,使用代码生成器可以一键生成前后端代码。
* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。
* 提供了单应用版本[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast)Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
* 阿里云优惠券:[点我领取](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)&nbsp;&nbsp;
## 内置功能
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
3. 岗位管理:配置系统用户所属担任职务。
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
7. 参数管理:对系统动态配置常用参数。
8. 通知公告:系统通知公告信息发布维护。
9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
10. 登录日志:系统登录日志记录查询包含登录异常。
11. 在线用户:当前系统中活跃用户状态监控。
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
13. 代码生成前后端代码的生成java、html、xml、sql支持CRUD下载 。
14. 系统接口根据业务代码自动生成相关的api接口文档。
15. 服务监控监视当前系统CPU、内存、磁盘、堆栈等相关信息。
16. 缓存监控:对系统的缓存信息查询,命令统计等。
17. 在线构建器拖动表单元素生成相应的HTML代码。
18. 连接池监视监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈。
## 在线体验
- admin/admin123
- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
演示地址http://vue.ruoyi.vip
文档地址http://doc.ruoyi.vip
## 演示图
<table>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-8074972883b5ba0622e13246738ebba237a.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-9f88719cdfca9af2e58b352a20e23d43b12.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-39bf2584ec3a529b0d5a3b70d15c9b37646.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-936ec82d1f4872e1bc980927654b6007307.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-b2d62ceb95d2dd9b3fbe157bb70d26001e9.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-d67451d308b7a79ad6819723396f7c3d77a.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-8370a0d02977eebf6dbf854c8450293c937.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-49003ed83f60f633e7153609a53a2b644f7.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-d4fe726319ece268d4746602c39cffc0621.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
</tr>
</table>
## 若依前后端分离交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/已满-170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [![加入QQ群](https://img.shields.io/badge/已满-108482800-blue.svg)](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [![加入QQ群](https://img.shields.io/badge/已满-101046199-blue.svg)](https://jq.qq.com/?_wv=1027&k=SpyH2875) [![加入QQ群](https://img.shields.io/badge/已满-136919097-blue.svg)](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [![加入QQ群](https://img.shields.io/badge/已满-143961921-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [![加入QQ群](https://img.shields.io/badge/已满-174951577-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [![加入QQ群](https://img.shields.io/badge/已满-161281055-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [![加入QQ群](https://img.shields.io/badge/已满-138988063-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [![加入QQ群](https://img.shields.io/badge/151450850-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) 点击按钮入群。

View File

@ -1,12 +1,12 @@
@echo off
echo.
echo [信息] 清理工程target生成路径。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean
@echo off
echo.
echo [信息] 清理工程target生成路径。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean
pause

View File

@ -1,12 +1,12 @@
@echo off
echo.
echo [信息] 打包Web工程生成war/jar包文件。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean package -Dmaven.test.skip=true
@echo off
echo.
echo [信息] 打包Web工程生成war/jar包文件。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean package -Dmaven.test.skip=true
pause

View File

@ -1,14 +1,14 @@
@echo off
echo.
echo [信息] 使用Jar命令运行Web工程。
echo.
cd %~dp0
cd ../ruoyi-admin/target
set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -jar %JAVA_OPTS% ruoyi-admin.jar
cd bin
@echo off
echo.
echo [信息] 使用Jar命令运行Web工程。
echo.
cd %~dp0
cd ../ruoyi-admin/target
set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -jar %JAVA_OPTS% ruoyi-admin.jar
cd bin
pause

Binary file not shown.

80
package.json Normal file
View File

@ -0,0 +1,80 @@
{
"name": "front",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@vuepic/vue-datepicker": "^8.8.0",
"axios": "^1.7.2",
"core-js": "^3.8.3",
"echarts": "^5.5.0",
"element-plus": "^2.7.3",
"vue": "^3.2.13",
"vue-class-component": "^8.0.0-0",
"vue-router": "^4.0.3",
"vuex": "^4.0.0"
},
"devDependencies": {
"@types/jest": "^27.0.1",
"@types/vue": "^2.0.0",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-typescript": "~5.0.0",
"@vue/cli-plugin-unit-jest": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"@vue/eslint-config-typescript": "^9.1.0",
"@vue/test-utils": "^2.0.0-0",
"@vue/vue3-jest": "^27.0.0-alpha.1",
"babel-jest": "^27.0.6",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3",
"jest": "^27.0.5",
"ts-jest": "^27.0.4",
"typescript": "~4.5.5"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/typescript/recommended"
],
"parserOptions": {
"ecmaVersion": 2020
},
"rules": {},
"overrides": [
{
"files": [
"**/__tests__/*.{j,t}s?(x)",
"**/tests/unit/**/*.spec.{j,t}s?(x)"
],
"env": {
"jest": true
}
}
]
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
],
"jest": {
"preset": "@vue/cli-plugin-unit-jest/presets/typescript-and-babel"
}
}

488
pom.xml
View File

@ -1,252 +1,238 @@
<?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"
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>
<version>4.7.6</version>
<name>ruoyi</name>
<url>http://www.ruoyi.vip</url>
<description>若依管理系统</description>
<properties>
<ruoyi.version>4.7.6</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<shiro.version>1.10.1</shiro.version>
<thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
<druid.version>1.2.15</druid.version>
<bitwalker.version>1.21</bitwalker.version>
<kaptcha.version>2.3.3</kaptcha.version>
<swagger.version>3.0.0</swagger.version>
<pagehelper.boot.version>1.4.6</pagehelper.boot.version>
<fastjson.version>1.2.83</fastjson.version>
<oshi.version>6.4.0</oshi.version>
<commons.io.version>2.11.0</commons.io.version>
<commons.fileupload.version>1.4</commons.fileupload.version>
<poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version>
</properties>
<!-- 依赖声明 -->
<dependencyManagement>
<dependencies>
<!-- SpringBoot的依赖配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.14</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- 验证码 -->
<dependency>
<groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
<!-- Shiro核心框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- Shiro使用Spring框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- Shiro使用EhCache缓存框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- thymeleaf模板引擎和shiro框架的整合 -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>${thymeleaf.extras.shiro.version}</version>
</dependency>
<!-- 解析客户端操作系统、浏览器等 -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>${bitwalker.version}</version>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version>
</dependency>
<!-- 获取系统信息 -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>${oshi.version}</version>
</dependency>
<!-- Swagger3依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${swagger.version}</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- io常用工具类 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<!-- 文件上传工具类 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons.fileupload.version}</version>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!-- velocity代码生成使用模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-quartz</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-generator</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 核心模块-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 系统模块-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-system</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 通用工具-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>${ruoyi.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>ruoyi-admin</module>
<module>ruoyi-framework</module>
<module>ruoyi-system</module>
<module>ruoyi-quartz</module>
<module>ruoyi-generator</module>
<module>ruoyi-common</module>
</modules>
<packaging>pom</packaging>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<?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"
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>
<version>3.8.7</version>
<name>ruoyi</name>
<url>http://www.ruoyi.vip</url>
<description>若依管理系统</description>
<properties>
<ruoyi.version>3.8.7</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<spring-framework.version>5.3.33</spring-framework.version>
<spring-security.version>5.7.12</spring-security.version>
<druid.version>1.2.23</druid.version>
<bitwalker.version>1.21</bitwalker.version>
<swagger.version>3.0.0</swagger.version>
<kaptcha.version>2.3.3</kaptcha.version>
<pagehelper.boot.version>1.4.7</pagehelper.boot.version>
<fastjson.version>2.0.43</fastjson.version>
<oshi.version>6.6.1</oshi.version>
<commons.io.version>2.13.0</commons.io.version>
<poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version>
<jwt.version>0.9.1</jwt.version>
</properties>
<!-- 依赖声明 -->
<dependencyManagement>
<dependencies>
<!-- SpringFramework的依赖配置-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring-framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringSecurity的依赖配置-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-bom</artifactId>
<version>${spring-security.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringBoot的依赖配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.15</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- 解析客户端操作系统、浏览器等 -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>${bitwalker.version}</version>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version>
</dependency>
<!-- 获取系统信息 -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>${oshi.version}</version>
</dependency>
<!-- Swagger3依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${swagger.version}</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- io常用工具类 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!-- velocity代码生成使用模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- Token生成与解析-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!-- 验证码 -->
<dependency>
<groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-quartz</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-generator</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 核心模块-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 系统模块-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-system</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 通用工具-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>${ruoyi.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>ruoyi-admin</module>
<module>ruoyi-framework</module>
<module>ruoyi-system</module>
<module>ruoyi-quartz</module>
<module>ruoyi-generator</module>
<module>ruoyi-common</module>
</modules>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

View File

@ -1,134 +1,96 @@
<?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"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.7.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>ruoyi-admin</artifactId>
<description>
web服务入口
</description>
<dependencies>
<!-- SpringBoot集成thymeleaf模板 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency>
<!-- swagger3-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</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>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-quartz</artifactId>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-generator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置devtools不会生效 -->
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</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>**/bootstrap-table/**</exclude>
</excludes>
</configuration>
</plugin> -->
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
<?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"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.7</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>ruoyi-admin</artifactId>
<description>
web服务入口
</description>
<dependencies>
<!-- spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency>
<!-- swagger3-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</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>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-quartz</artifactId>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-generator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.15</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置devtools不会生效 -->
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>

View File

@ -27,4 +27,4 @@ public class RuoYiApplication
" | | \\ / \\ / \n" +
" ''-' `'-' `-..-' ");
}
}
}

View File

@ -0,0 +1,94 @@
package com.ruoyi.web.controller.common;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.google.code.kaptcha.Producer;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.sign.Base64;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.service.ISysConfigService;
/**
* 验证码操作处理
*
* @author ruoyi
*/
@RestController
public class CaptchaController
{
@Resource(name = "captchaProducer")
private Producer captchaProducer;
@Resource(name = "captchaProducerMath")
private Producer captchaProducerMath;
@Autowired
private RedisCache redisCache;
@Autowired
private ISysConfigService configService;
/**
* 生成验证码
*/
@GetMapping("/captchaImage")
public AjaxResult getCode(HttpServletResponse response) throws IOException
{
AjaxResult ajax = AjaxResult.success();
boolean captchaEnabled = configService.selectCaptchaEnabled();
ajax.put("captchaEnabled", captchaEnabled);
if (!captchaEnabled)
{
return ajax;
}
// 保存验证码信息
String uuid = IdUtils.simpleUUID();
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
String capStr = null, code = null;
BufferedImage image = null;
// 生成验证码
String captchaType = RuoYiConfig.getCaptchaType();
if ("math".equals(captchaType))
{
String capText = captchaProducerMath.createText();
capStr = capText.substring(0, capText.lastIndexOf("@"));
code = capText.substring(capText.lastIndexOf("@") + 1);
image = captchaProducerMath.createImage(capStr);
}
else if ("char".equals(captchaType))
{
capStr = code = captchaProducer.createText();
image = captchaProducer.createImage(capStr);
}
redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
// 转换流信息写出
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
try
{
ImageIO.write(image, "jpg", os);
}
catch (IOException e)
{
return AjaxResult.error(e.getMessage());
}
ajax.put("uuid", uuid);
ajax.put("img", Base64.encode(os.toByteArray()));
return ajax;
}
}

View File

@ -8,26 +8,25 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.ServerConfig;
/**
* 通用请求处理
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/common")
public class CommonController
{
@ -74,7 +73,6 @@ public class CommonController
* 通用上传请求单个
*/
@PostMapping("/upload")
@ResponseBody
public AjaxResult uploadFile(MultipartFile file) throws Exception
{
try
@ -101,7 +99,6 @@ public class CommonController
* 通用上传请求多个
*/
@PostMapping("/uploads")
@ResponseBody
public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
{
try

View File

@ -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

View File

@ -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";
}
}

View File

@ -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();
}
}

View File

@ -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";
}
}

View File

@ -1,846 +0,0 @@
package com.ruoyi.web.controller.demo.controller;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
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.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
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.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
/**
* 表格相关
*
* @author ruoyi
*/
@Controller
@RequestMapping("/demo/table")
public class DemoTableController extends BaseController
{
private String prefix = "demo/table";
private final static List<UserTableModel> users = new ArrayList<UserTableModel>();
{
users.add(new UserTableModel(1, "1000001", "测试1", "0", "15888888888", "ry@qq.com", 150.0, "0"));
users.add(new UserTableModel(2, "1000002", "测试2", "1", "15666666666", "ry@qq.com", 180.0, "1"));
users.add(new UserTableModel(3, "1000003", "测试3", "0", "15666666666", "ry@qq.com", 110.0, "1"));
users.add(new UserTableModel(4, "1000004", "测试4", "1", "15666666666", "ry@qq.com", 220.0, "1"));
users.add(new UserTableModel(5, "1000005", "测试5", "0", "15666666666", "ry@qq.com", 140.0, "1"));
users.add(new UserTableModel(6, "1000006", "测试6", "1", "15666666666", "ry@qq.com", 330.0, "1"));
users.add(new UserTableModel(7, "1000007", "测试7", "0", "15666666666", "ry@qq.com", 160.0, "1"));
users.add(new UserTableModel(8, "1000008", "测试8", "1", "15666666666", "ry@qq.com", 170.0, "1"));
users.add(new UserTableModel(9, "1000009", "测试9", "0", "15666666666", "ry@qq.com", 180.0, "1"));
users.add(new UserTableModel(10, "1000010", "测试10", "0", "15666666666", "ry@qq.com", 210.0, "1"));
users.add(new UserTableModel(11, "1000011", "测试11", "1", "15666666666", "ry@qq.com", 110.0, "1"));
users.add(new UserTableModel(12, "1000012", "测试12", "0", "15666666666", "ry@qq.com", 120.0, "1"));
users.add(new UserTableModel(13, "1000013", "测试13", "1", "15666666666", "ry@qq.com", 380.0, "1"));
users.add(new UserTableModel(14, "1000014", "测试14", "0", "15666666666", "ry@qq.com", 280.0, "1"));
users.add(new UserTableModel(15, "1000015", "测试15", "0", "15666666666", "ry@qq.com", 570.0, "1"));
users.add(new UserTableModel(16, "1000016", "测试16", "1", "15666666666", "ry@qq.com", 260.0, "1"));
users.add(new UserTableModel(17, "1000017", "测试17", "1", "15666666666", "ry@qq.com", 210.0, "1"));
users.add(new UserTableModel(18, "1000018", "测试18", "1", "15666666666", "ry@qq.com", 340.0, "1"));
users.add(new UserTableModel(19, "1000019", "测试19", "1", "15666666666", "ry@qq.com", 160.0, "1"));
users.add(new UserTableModel(20, "1000020", "测试20", "1", "15666666666", "ry@qq.com", 220.0, "1"));
users.add(new UserTableModel(21, "1000021", "测试21", "1", "15666666666", "ry@qq.com", 120.0, "1"));
users.add(new UserTableModel(22, "1000022", "测试22", "1", "15666666666", "ry@qq.com", 130.0, "1"));
users.add(new UserTableModel(23, "1000023", "测试23", "1", "15666666666", "ry@qq.com", 490.0, "1"));
users.add(new UserTableModel(24, "1000024", "测试24", "1", "15666666666", "ry@qq.com", 570.0, "1"));
users.add(new UserTableModel(25, "1000025", "测试25", "1", "15666666666", "ry@qq.com", 250.0, "1"));
users.add(new UserTableModel(26, "1000026", "测试26", "1", "15666666666", "ry@qq.com", 250.0, "1"));
}
private final static List<AreaModel> areas = new ArrayList<AreaModel>();
{
areas.add(new AreaModel(1, 0, "广东省", "440000", "GDS", "GuangDongSheng", 1));
areas.add(new AreaModel(2, 0, "湖南省", "430000", "HNS", "HuNanSheng", 1));
areas.add(new AreaModel(3, 0, "河南省", "410000", "HNS", "HeNanSheng", 0));
areas.add(new AreaModel(4, 0, "湖北省", "420000", "HBS", "HuBeiSheng", 0));
areas.add(new AreaModel(5, 0, "辽宁省", "210000", "LNS", "LiaoNingSheng", 0));
areas.add(new AreaModel(6, 0, "山东省", "370000", "SDS", "ShanDongSheng", 0));
areas.add(new AreaModel(7, 0, "陕西省", "610000", "SXS", "ShanXiSheng", 0));
areas.add(new AreaModel(8, 0, "贵州省", "520000", "GZS", "GuiZhouSheng", 0));
areas.add(new AreaModel(9, 0, "上海市", "310000", "SHS", "ShangHaiShi", 0));
areas.add(new AreaModel(10, 0, "重庆市", "500000", "CQS", "ChongQingShi", 0));
areas.add(new AreaModel(11, 0, "若依省", "666666", "YYS", "RuoYiSheng", 0));
areas.add(new AreaModel(12, 0, "安徽省", "340000", "AHS", "AnHuiSheng", 0));
areas.add(new AreaModel(13, 0, "福建省", "350000", "FJS", "FuJianSheng", 0));
areas.add(new AreaModel(14, 0, "海南省", "460000", "HNS", "HaiNanSheng", 0));
areas.add(new AreaModel(15, 0, "江苏省", "320000", "JSS", "JiangSuSheng", 0));
areas.add(new AreaModel(16, 0, "青海省", "630000", "QHS", "QingHaiSheng", 0));
areas.add(new AreaModel(17, 0, "广西壮族自治区", "450000", "GXZZZZQ", "GuangXiZhuangZuZiZhiQu", 0));
areas.add(new AreaModel(18, 0, "宁夏回族自治区", "640000", "NXHZZZQ", "NingXiaHuiZuZiZhiQu", 0));
areas.add(new AreaModel(19, 0, "内蒙古自治区", "150000", "NMGZZQ", "NeiMengGuZiZhiQu", 0));
areas.add(new AreaModel(20, 0, "新疆维吾尔自治区", "650000", "XJWWEZZQ", "XinJiangWeiWuErZiZhiQu", 0));
areas.add(new AreaModel(21, 0, "江西省", "360000", "JXS", "JiangXiSheng", 0));
areas.add(new AreaModel(22, 0, "浙江省", "330000", "ZJS", "ZheJiangSheng", 0));
areas.add(new AreaModel(23, 0, "河北省", "130000", "HBS", "HeBeiSheng", 0));
areas.add(new AreaModel(24, 0, "天津市", "120000", "TJS", "TianJinShi", 0));
areas.add(new AreaModel(25, 0, "山西省", "140000", "SXS", "ShanXiSheng", 0));
areas.add(new AreaModel(26, 0, "台湾省", "710000", "TWS", "TaiWanSheng", 0));
areas.add(new AreaModel(27, 0, "甘肃省", "620000", "GSS", "GanSuSheng", 0));
areas.add(new AreaModel(28, 0, "四川省", "510000", "SCS", "SiChuanSheng", 0));
areas.add(new AreaModel(29, 0, "云南省", "530000", "YNS", "YunNanSheng", 0));
areas.add(new AreaModel(30, 0, "北京市", "110000", "BJS", "BeiJingShi", 0));
areas.add(new AreaModel(31, 0, "香港特别行政区", "810000", "XGTBXZQ", "XiangGangTeBieXingZhengQu", 0));
areas.add(new AreaModel(32, 0, "澳门特别行政区", "820000", "AMTBXZQ", "AoMenTeBieXingZhengQu", 0));
areas.add(new AreaModel(100, 1, "深圳市", "440300", "SZS", "ShenZhenShi", 1));
areas.add(new AreaModel(101, 1, "广州市", "440100", "GZS", "GuangZhouShi", 0));
areas.add(new AreaModel(102, 1, "东莞市", "441900", "DGS", "DongGuanShi", 0));
areas.add(new AreaModel(103, 2, "长沙市", "410005", "CSS", "ChangShaShi", 1));
areas.add(new AreaModel(104, 2, "岳阳市", "414000", "YYS", "YueYangShi", 0));
areas.add(new AreaModel(1000, 100, "龙岗区", "518172", "LGQ", "LongGangQu", 0));
areas.add(new AreaModel(1001, 100, "南山区", "518051", "NSQ", "NanShanQu", 0));
areas.add(new AreaModel(1002, 100, "宝安区", "518101", "BAQ", "BaoAnQu", 0));
areas.add(new AreaModel(1003, 100, "福田区", "518081", "FTQ", "FuTianQu", 0));
areas.add(new AreaModel(1004, 103, "天心区", "410004", "TXQ", "TianXinQu", 0));
areas.add(new AreaModel(1005, 103, "开福区", "410008", "KFQ", "KaiFuQu", 0));
areas.add(new AreaModel(1006, 103, "芙蓉区", "410011", "FRQ", "FuRongQu", 0));
areas.add(new AreaModel(1007, 103, "雨花区", "410011", "YHQ", "YuHuaQu", 0));
}
private final static List<UserTableColumn> columns = new ArrayList<UserTableColumn>();
{
columns.add(new UserTableColumn("用户ID", "userId"));
columns.add(new UserTableColumn("用户编号", "userCode"));
columns.add(new UserTableColumn("用户姓名", "userName"));
columns.add(new UserTableColumn("用户手机", "userPhone"));
columns.add(new UserTableColumn("用户邮箱", "userEmail"));
columns.add(new UserTableColumn("用户状态", "status"));
}
/**
* 搜索相关
*/
@GetMapping("/search")
public String search()
{
return prefix + "/search";
}
/**
* 数据汇总
*/
@GetMapping("/footer")
public String footer()
{
return prefix + "/footer";
}
/**
* 组合表头
*/
@GetMapping("/groupHeader")
public String groupHeader()
{
return prefix + "/groupHeader";
}
/**
* 表格导出
*/
@GetMapping("/export")
public String export()
{
return prefix + "/export";
}
/**
* 表格导出选择列
*/
@GetMapping("/exportSelected")
public String exportSelected()
{
return prefix + "/exportSelected";
}
/**
* 导出数据
*/
@PostMapping("/exportData")
@ResponseBody
public AjaxResult exportSelected(UserTableModel userModel, String userIds)
{
List<UserTableModel> userList = new ArrayList<UserTableModel>(Arrays.asList(new UserTableModel[users.size()]));
Collections.copy(userList, users);
// 条件过滤
if (StringUtils.isNotEmpty(userIds))
{
userList.clear();
for (Long userId : Convert.toLongArray(userIds))
{
for (UserTableModel user : users)
{
if (user.getUserId() == userId)
{
userList.add(user);
}
}
}
}
ExcelUtil<UserTableModel> util = new ExcelUtil<UserTableModel>(UserTableModel.class);
return util.exportExcel(userList, "用户数据");
}
/**
* 翻页记住选择
*/
@GetMapping("/remember")
public String remember()
{
return prefix + "/remember";
}
/**
* 跳转至指定页
*/
@GetMapping("/pageGo")
public String pageGo()
{
return prefix + "/pageGo";
}
/**
* 自定义查询参数
*/
@GetMapping("/params")
public String params()
{
return prefix + "/params";
}
/**
* 多表格
*/
@GetMapping("/multi")
public String multi()
{
return prefix + "/multi";
}
/**
* 点击按钮加载表格
*/
@GetMapping("/button")
public String button()
{
return prefix + "/button";
}
/**
* 直接加载表格数据
*/
@GetMapping("/data")
public String data(ModelMap mmap)
{
mmap.put("users", users);
return prefix + "/data";
}
/**
* 表格冻结列
*/
@GetMapping("/fixedColumns")
public String fixedColumns()
{
return prefix + "/fixedColumns";
}
/**
* 自定义触发事件
*/
@GetMapping("/event")
public String event()
{
return prefix + "/event";
}
/**
* 表格细节视图
*/
@GetMapping("/detail")
public String detail()
{
return prefix + "/detail";
}
/**
* 表格父子视图
*/
@GetMapping("/child")
public String child()
{
return prefix + "/child";
}
/**
* 表格图片预览
*/
@GetMapping("/image")
public String image()
{
return prefix + "/image";
}
/**
* 动态增删改查
*/
@GetMapping("/curd")
public String curd()
{
return prefix + "/curd";
}
/**
* 表格行拖拽操作
*/
@GetMapping("/reorderRows")
public String reorderRows()
{
return prefix + "/reorderRows";
}
/**
* 表格列拖拽操作
*/
@GetMapping("/reorderColumns")
public String reorderColumns()
{
return prefix + "/reorderColumns";
}
/**
* 表格列宽拖动
*/
@GetMapping("/resizable")
public String resizable()
{
return prefix + "/resizable";
}
/**
* 表格行内编辑操作
*/
@GetMapping("/editable")
public String editable()
{
return prefix + "/editable";
}
/**
* 主子表提交
*/
@GetMapping("/subdata")
public String subdata()
{
return prefix + "/subdata";
}
/**
* 表格自动刷新
*/
@GetMapping("/refresh")
public String refresh()
{
return prefix + "/refresh";
}
/**
* 表格打印配置
*/
@GetMapping("/print")
public String print()
{
return prefix + "/print";
}
/**
* 表格标题格式化
*/
@GetMapping("/headerStyle")
public String headerStyle()
{
return prefix + "/headerStyle";
}
/**
* 表格动态列
*/
@GetMapping("/dynamicColumns")
public String dynamicColumns()
{
return prefix + "/dynamicColumns";
}
/**
* 自定义视图分页
*/
@GetMapping("/customView")
public String customView()
{
return prefix + "/customView";
}
/**
* 异步加载表格树
*/
@GetMapping("/asynTree")
public String asynTree()
{
return prefix + "/asynTree";
}
/**
* 表格其他操作
*/
@GetMapping("/other")
public String other()
{
return prefix + "/other";
}
/**
* 动态获取列
*/
@PostMapping("/ajaxColumns")
@ResponseBody
public AjaxResult ajaxColumns(UserTableColumn userColumn)
{
List<UserTableColumn> columnList = new ArrayList<UserTableColumn>(Arrays.asList(new UserTableColumn[columns.size()]));
Collections.copy(columnList, columns);
if (userColumn != null && "userBalance".equals(userColumn.getField()))
{
columnList.add(new UserTableColumn("用户余额", "userBalance"));
}
return AjaxResult.success(columnList);
}
/**
* 查询数据
*/
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(UserTableModel userModel)
{
TableDataInfo rspData = new TableDataInfo();
List<UserTableModel> userList = new ArrayList<UserTableModel>(Arrays.asList(new UserTableModel[users.size()]));
Collections.copy(userList, users);
// 查询条件过滤
if (StringUtils.isNotEmpty(userModel.getUserName()))
{
userList.clear();
for (UserTableModel user : users)
{
if (user.getUserName().equals(userModel.getUserName()))
{
userList.add(user);
}
}
}
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;
}
/**
* 查询树表数据
*/
@PostMapping("/tree/list")
@ResponseBody
public TableDataInfo treeList(AreaModel areaModel)
{
TableDataInfo rspData = new TableDataInfo();
List<AreaModel> areaList = new ArrayList<AreaModel>(Arrays.asList(new AreaModel[areas.size()]));
// 默认查询条件 parentId 0
Collections.copy(areaList, areas);
areaList.clear();
if (StringUtils.isNotEmpty(areaModel.getAreaName()))
{
for (AreaModel area : areas)
{
if (area.getParentId() == 0 && area.getAreaName().equals(areaModel.getAreaName()))
{
areaList.add(area);
}
}
}
else
{
for (AreaModel area : areas)
{
if (area.getParentId() == 0)
{
areaList.add(area);
}
}
}
PageDomain pageDomain = TableSupport.buildPageRequest();
Integer pageNum = (pageDomain.getPageNum() - 1) * 10;
Integer pageSize = pageDomain.getPageNum() * 10;
if (pageSize > areaList.size())
{
pageSize = areaList.size();
}
rspData.setRows(areaList.subList(pageNum, pageSize));
rspData.setTotal(areaList.size());
return rspData;
}
/**
* 查询树表子节点数据
*/
@PostMapping("/tree/listChild")
@ResponseBody
public List<AreaModel> listChild(AreaModel areaModel)
{
List<AreaModel> areaList = new ArrayList<AreaModel>(Arrays.asList(new AreaModel[areas.size()]));
// 查询条件 parentId
Collections.copy(areaList, areas);
areaList.clear();
if (StringUtils.isNotEmpty(areaModel.getAreaName()))
{
for (AreaModel area : areas)
{
if (area.getParentId().intValue() == areaModel.getParentId().intValue() && area.getAreaName().equals(areaModel.getAreaName()))
{
areaList.add(area);
}
}
}
else
{
for (AreaModel area : areas)
{
if (area.getParentId().intValue() == areaModel.getParentId().intValue())
{
areaList.add(area);
}
}
}
return areaList;
}
}
class UserTableColumn
{
/** 表头 */
private String title;
/** 字段 */
private String field;
public UserTableColumn()
{
}
public UserTableColumn(String title, String field)
{
this.title = title;
this.field = field;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public String getField()
{
return field;
}
public void setField(String field)
{
this.field = field;
}
}
class UserTableModel
{
/** 用户ID */
private int userId;
/** 用户编号 */
@Excel(name = "用户编号", cellType = ColumnType.NUMERIC)
private String userCode;
/** 用户姓名 */
@Excel(name = "用户姓名")
private String userName;
/** 用户性别 */
private String userSex;
/** 用户手机 */
@Excel(name = "用户手机")
private String userPhone;
/** 用户邮箱 */
@Excel(name = "用户邮箱")
private String userEmail;
/** 用户余额 */
@Excel(name = "用户余额", cellType = ColumnType.NUMERIC)
private double userBalance;
/** 用户状态0正常 1停用 */
private String status;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
public UserTableModel()
{
}
public UserTableModel(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;
}
public Date getCreateTime()
{
return createTime;
}
public void setCreateTime(Date createTime)
{
this.createTime = createTime;
}
}
class AreaModel
{
/** 编号 */
private Long id;
/** 父编号 */
private Long parentId;
/** 区域名称 */
private String areaName;
/** 区域代码 */
private String areaCode;
/** 名称首字母 */
private String simplePy;
/** 名称全拼 */
private String pinYin;
/** 是否有子节点0无 1有 */
private Integer isTreeLeaf = 1;
public AreaModel()
{
}
public AreaModel(int id, int parentId, String areaName, String areaCode, String simplePy, String pinYin, Integer isTreeLeaf)
{
this.id = Long.valueOf(id);
this.parentId = Long.valueOf(parentId);
this.areaName = areaName;
this.areaCode = areaCode;
this.simplePy = simplePy;
this.pinYin = pinYin;
this.isTreeLeaf = isTreeLeaf;
}
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public Long getParentId()
{
return parentId;
}
public void setParentId(Long parentId)
{
this.parentId = parentId;
}
public String getAreaName()
{
return areaName;
}
public void setAreaName(String areaName)
{
this.areaName = areaName;
}
public String getAreaCode()
{
return areaCode;
}
public void setAreaCode(String areaCode)
{
this.areaCode = areaCode;
}
public String getSimplePy()
{
return simplePy;
}
public void setSimplePy(String simplePy)
{
this.simplePy = simplePy;
}
public String getPinYin()
{
return pinYin;
}
public void setPinYin(String pinYin)
{
this.pinYin = pinYin;
}
public Integer getIsTreeLeaf()
{
return isTreeLeaf;
}
public void setIsTreeLeaf(Integer isTreeLeaf)
{
this.isTreeLeaf = isTreeLeaf;
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -1,90 +1,121 @@
package com.ruoyi.web.controller.monitor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.core.controller.BaseController;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.framework.web.service.CacheService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysCache;
/**
* 缓存监控
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/monitor/cache")
public class CacheController extends BaseController
public class CacheController
{
private String prefix = "monitor/cache";
@Autowired
private CacheService cacheService;
private RedisTemplate<String, String> redisTemplate;
@RequiresPermissions("monitor:cache:view")
private final static List<SysCache> caches = new ArrayList<SysCache>();
{
caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息"));
caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息"));
caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典"));
caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码"));
caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交"));
caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理"));
caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数"));
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping()
public String cache(ModelMap mmap)
public AjaxResult getInfo() throws Exception
{
mmap.put("cacheNames", cacheService.getCacheNames());
return prefix + "/cache";
Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info());
Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize());
Map<String, Object> result = new HashMap<>(3);
result.put("info", info);
result.put("dbSize", dbSize);
List<Map<String, String>> pieList = new ArrayList<>();
commandStats.stringPropertyNames().forEach(key -> {
Map<String, String> data = new HashMap<>(2);
String property = commandStats.getProperty(key);
data.put("name", StringUtils.removeStart(key, "cmdstat_"));
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
pieList.add(data);
});
result.put("commandStats", pieList);
return AjaxResult.success(result);
}
@RequiresPermissions("monitor:cache:view")
@PostMapping("/getNames")
public String getCacheNames(String fragment, ModelMap mmap)
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getNames")
public AjaxResult cache()
{
mmap.put("cacheNames", cacheService.getCacheNames());
return prefix + "/cache::" + fragment;
return AjaxResult.success(caches);
}
@RequiresPermissions("monitor:cache:view")
@PostMapping("/getKeys")
public String getCacheKeys(String fragment, String cacheName, ModelMap mmap)
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getKeys/{cacheName}")
public AjaxResult getCacheKeys(@PathVariable String cacheName)
{
mmap.put("cacheName", cacheName);
mmap.put("cacheKeys", cacheService.getCacheKeys(cacheName));
return prefix + "/cache::" + fragment;
Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
return AjaxResult.success(new TreeSet<>(cacheKeys));
}
@RequiresPermissions("monitor:cache:view")
@PostMapping("/getValue")
public String getCacheValue(String fragment, String cacheName, String cacheKey, ModelMap mmap)
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getValue/{cacheName}/{cacheKey}")
public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey)
{
mmap.put("cacheName", cacheName);
mmap.put("cacheKey", cacheKey);
mmap.put("cacheValue", cacheService.getCacheValue(cacheName, cacheKey));
return prefix + "/cache::" + fragment;
String cacheValue = redisTemplate.opsForValue().get(cacheKey);
SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue);
return AjaxResult.success(sysCache);
}
@RequiresPermissions("monitor:cache:view")
@PostMapping("/clearCacheName")
@ResponseBody
public AjaxResult clearCacheName(String cacheName, ModelMap mmap)
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@DeleteMapping("/clearCacheName/{cacheName}")
public AjaxResult clearCacheName(@PathVariable String cacheName)
{
cacheService.clearCacheName(cacheName);
Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*");
redisTemplate.delete(cacheKeys);
return AjaxResult.success();
}
@RequiresPermissions("monitor:cache:view")
@PostMapping("/clearCacheKey")
@ResponseBody
public AjaxResult clearCacheKey(String cacheName, String cacheKey, ModelMap mmap)
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@DeleteMapping("/clearCacheKey/{cacheKey}")
public AjaxResult clearCacheKey(@PathVariable String cacheKey)
{
cacheService.clearCacheKey(cacheName, cacheKey);
redisTemplate.delete(cacheKey);
return AjaxResult.success();
}
@RequiresPermissions("monitor:cache:view")
@GetMapping("/clearAll")
@ResponseBody
public AjaxResult clearAll(ModelMap mmap)
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@DeleteMapping("/clearCacheAll")
public AjaxResult clearCacheAll()
{
cacheService.clearAll();
Collection<String> cacheKeys = redisTemplate.keys("*");
redisTemplate.delete(cacheKeys);
return AjaxResult.success();
}
}

View File

@ -1,26 +0,0 @@
package com.ruoyi.web.controller.monitor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.core.controller.BaseController;
/**
* druid 监控
*
* @author ruoyi
*/
@Controller
@RequestMapping("/monitor/data")
public class DruidController extends BaseController
{
private String prefix = "/druid";
@RequiresPermissions("monitor:data:view")
@GetMapping()
public String index()
{
return redirect(prefix + "/index.html");
}
}

View File

@ -1,11 +1,10 @@
package com.ruoyi.web.controller.monitor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.core.controller.BaseController;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.framework.web.domain.Server;
/**
@ -13,19 +12,16 @@ import com.ruoyi.framework.web.domain.Server;
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/monitor/server")
public class ServerController extends BaseController
public class ServerController
{
private String prefix = "monitor/server";
@RequiresPermissions("monitor:server:view")
@PreAuthorize("@ss.hasPermi('monitor:server:list')")
@GetMapping()
public String server(ModelMap mmap) throws Exception
public AjaxResult getInfo() throws Exception
{
Server server = new Server();
server.copyTo();
mmap.put("server", server);
return prefix + "/server";
return AjaxResult.success(server);
}
}

View File

@ -1,20 +1,22 @@
package com.ruoyi.web.controller.monitor;
import java.util.List;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
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.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.service.SysPasswordService;
import com.ruoyi.system.domain.SysLogininfor;
import com.ruoyi.system.service.ISysLogininforService;
@ -23,28 +25,18 @@ import com.ruoyi.system.service.ISysLogininforService;
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/monitor/logininfor")
public class SysLogininforController extends BaseController
{
private String prefix = "monitor/logininfor";
@Autowired
private ISysLogininforService logininforService;
@Autowired
private SysPasswordService passwordService;
@RequiresPermissions("monitor:logininfor:view")
@GetMapping()
public String logininfor()
{
return prefix + "/logininfor";
}
@RequiresPermissions("monitor:logininfor:list")
@PostMapping("/list")
@ResponseBody
@PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
@GetMapping("/list")
public TableDataInfo list(SysLogininfor logininfor)
{
startPage();
@ -53,42 +45,38 @@ public class SysLogininforController extends BaseController
}
@Log(title = "登录日志", businessType = BusinessType.EXPORT)
@RequiresPermissions("monitor:logininfor:export")
@PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysLogininfor logininfor)
public void export(HttpServletResponse response, SysLogininfor logininfor)
{
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
return util.exportExcel(list, "登录日志");
util.exportExcel(response, list, "登录日志");
}
@RequiresPermissions("monitor:logininfor:remove")
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
@Log(title = "登录日志", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
@DeleteMapping("/{infoIds}")
public AjaxResult remove(@PathVariable Long[] infoIds)
{
return toAjax(logininforService.deleteLogininforByIds(ids));
return toAjax(logininforService.deleteLogininforByIds(infoIds));
}
@RequiresPermissions("monitor:logininfor:remove")
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
@Log(title = "登录日志", businessType = BusinessType.CLEAN)
@PostMapping("/clean")
@ResponseBody
@DeleteMapping("/clean")
public AjaxResult clean()
{
logininforService.cleanLogininfor();
return success();
}
@RequiresPermissions("monitor:logininfor:unlock")
@PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')")
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
@PostMapping("/unlock")
@ResponseBody
public AjaxResult unlock(String loginName)
@GetMapping("/unlock/{userName}")
public AjaxResult unlock(@PathVariable("userName") String userName)
{
passwordService.clearLoginRecordCache(loginName);
passwordService.clearLoginRecordCache(userName);
return success();
}
}

View File

@ -1,15 +1,15 @@
package com.ruoyi.web.controller.monitor;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
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.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
@ -24,25 +24,15 @@ import com.ruoyi.system.service.ISysOperLogService;
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/monitor/operlog")
public class SysOperlogController extends BaseController
{
private String prefix = "monitor/operlog";
@Autowired
private ISysOperLogService operLogService;
@RequiresPermissions("monitor:operlog:view")
@GetMapping()
public String operlog()
{
return prefix + "/operlog";
}
@RequiresPermissions("monitor:operlog:list")
@PostMapping("/list")
@ResponseBody
@PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
@GetMapping("/list")
public TableDataInfo list(SysOperLog operLog)
{
startPage();
@ -51,37 +41,26 @@ public class SysOperlogController extends BaseController
}
@Log(title = "操作日志", businessType = BusinessType.EXPORT)
@RequiresPermissions("monitor:operlog:export")
@PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysOperLog operLog)
public void export(HttpServletResponse response, SysOperLog operLog)
{
List<SysOperLog> list = operLogService.selectOperLogList(operLog);
ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
return util.exportExcel(list, "操作日志");
util.exportExcel(response, list, "操作日志");
}
@Log(title = "操作日志", businessType = BusinessType.DELETE)
@RequiresPermissions("monitor:operlog:remove")
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
@DeleteMapping("/{operIds}")
public AjaxResult remove(@PathVariable Long[] operIds)
{
return toAjax(operLogService.deleteOperLogByIds(ids));
return toAjax(operLogService.deleteOperLogByIds(operIds));
}
@RequiresPermissions("monitor:operlog:detail")
@GetMapping("/detail/{operId}")
public String detail(@PathVariable("operId") Long operId, ModelMap mmap)
{
mmap.put("operLog", operLogService.selectOperLogById(operId));
return prefix + "/detail";
}
@Log(title = "操作日志", businessType = BusinessType.CLEAN)
@RequiresPermissions("monitor:operlog:remove")
@PostMapping("/clean")
@ResponseBody
@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
@DeleteMapping("/clean")
public AjaxResult clean()
{
operLogService.cleanOperLog();

View File

@ -1,24 +1,25 @@
package com.ruoyi.web.controller.monitor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
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.OnlineSessionDAO;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysUserOnline;
import com.ruoyi.system.service.ISysUserOnlineService;
@ -27,62 +28,56 @@ import com.ruoyi.system.service.ISysUserOnlineService;
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/monitor/online")
public class SysUserOnlineController extends BaseController
{
private String prefix = "monitor/online";
@Autowired
private ISysUserOnlineService userOnlineService;
@Autowired
private OnlineSessionDAO onlineSessionDAO;
private RedisCache redisCache;
@RequiresPermissions("monitor:online:view")
@GetMapping()
public String online()
@PreAuthorize("@ss.hasPermi('monitor:online:list')")
@GetMapping("/list")
public TableDataInfo list(String ipaddr, String userName)
{
return prefix + "/online";
}
@RequiresPermissions("monitor:online:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysUserOnline userOnline)
{
startPage();
List<SysUserOnline> list = userOnlineService.selectUserOnlineList(userOnline);
return getDataTable(list);
}
@RequiresPermissions(value = { "monitor:online:batchForceLogout", "monitor:online:forceLogout" }, logical = Logical.OR)
@Log(title = "在线用户", businessType = BusinessType.FORCE)
@PostMapping("/batchForceLogout")
@ResponseBody
public AjaxResult batchForceLogout(String ids)
{
for (String sessionId : Convert.toStrArray(ids))
Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
for (String key : keys)
{
SysUserOnline online = userOnlineService.selectOnlineById(sessionId);
if (online == null)
LoginUser user = redisCache.getCacheObject(key);
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
{
return error("用户已下线");
userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
}
OnlineSession onlineSession = (OnlineSession) onlineSessionDAO.readSession(online.getSessionId());
if (onlineSession == null)
else if (StringUtils.isNotEmpty(ipaddr))
{
return error("用户已下线");
userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
}
if (sessionId.equals(ShiroUtils.getSessionId()))
else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
{
return error("当前登录用户无法强退");
userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
}
else
{
userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
}
onlineSessionDAO.delete(onlineSession);
online.setStatus(OnlineStatus.off_line);
userOnlineService.saveOnline(online);
userOnlineService.removeUserCache(online.getLoginName(), sessionId);
}
Collections.reverse(userOnlineList);
userOnlineList.removeAll(Collections.singleton(null));
return getDataTable(userOnlineList);
}
/**
* 强退用户
*/
@PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')")
@Log(title = "在线用户", businessType = BusinessType.FORCE)
@DeleteMapping("/{tokenId}")
public AjaxResult forceLogout(@PathVariable String tokenId)
{
redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
return success();
}
}

View File

@ -1,92 +0,0 @@
package com.ruoyi.web.controller.system;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.ruoyi.common.core.controller.BaseController;
/**
* 图片验证码支持算术形式
*
* @author ruoyi
*/
@Controller
@RequestMapping("/captcha")
public class SysCaptchaController extends BaseController
{
@Resource(name = "captchaProducer")
private Producer captchaProducer;
@Resource(name = "captchaProducerMath")
private Producer captchaProducerMath;
/**
* 验证码生成
*/
@GetMapping(value = "/captchaImage")
public ModelAndView getKaptchaImage(HttpServletRequest request, HttpServletResponse response)
{
ServletOutputStream out = null;
try
{
HttpSession session = request.getSession();
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/jpeg");
String type = request.getParameter("type");
String capStr = null;
String code = null;
BufferedImage bi = null;
if ("math".equals(type))
{
String capText = captchaProducerMath.createText();
capStr = capText.substring(0, capText.lastIndexOf("@"));
code = capText.substring(capText.lastIndexOf("@") + 1);
bi = captchaProducerMath.createImage(capStr);
}
else if ("char".equals(type))
{
capStr = code = captchaProducer.createText();
bi = captchaProducer.createImage(capStr);
}
session.setAttribute(Constants.KAPTCHA_SESSION_KEY, code);
out = response.getOutputStream();
ImageIO.write(bi, "jpg", out);
out.flush();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (out != null)
{
out.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
return null;
}
}

View File

@ -1,18 +1,19 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
@ -26,28 +27,18 @@ import com.ruoyi.system.service.ISysConfigService;
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/system/config")
public class SysConfigController extends BaseController
{
private String prefix = "system/config";
@Autowired
private ISysConfigService configService;
@RequiresPermissions("system:config:view")
@GetMapping()
public String config()
{
return prefix + "/config";
}
/**
* 查询参数配置列表
* 获取参数配置列表
*/
@RequiresPermissions("system:config:list")
@PostMapping("/list")
@ResponseBody
@PreAuthorize("@ss.hasPermi('system:config:list')")
@GetMapping("/list")
public TableDataInfo list(SysConfig config)
{
startPage();
@ -56,103 +47,87 @@ public class SysConfigController extends BaseController
}
@Log(title = "参数管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:config:export")
@PreAuthorize("@ss.hasPermi('system:config:export')")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysConfig config)
public void export(HttpServletResponse response, SysConfig config)
{
List<SysConfig> list = configService.selectConfigList(config);
ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
return util.exportExcel(list, "参数数据");
util.exportExcel(response, list, "参数数据");
}
/**
* 根据参数编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:config:query')")
@GetMapping(value = "/{configId}")
public AjaxResult getInfo(@PathVariable Long configId)
{
return success(configService.selectConfigById(configId));
}
/**
* 根据参数键名查询参数值
*/
@GetMapping(value = "/configKey/{configKey}")
public AjaxResult getConfigKey(@PathVariable String configKey)
{
return success(configService.selectConfigByKey(configKey));
}
/**
* 新增参数配置
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存参数配置
*/
@RequiresPermissions("system:config:add")
@PreAuthorize("@ss.hasPermi('system:config:add')")
@Log(title = "参数管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysConfig config)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysConfig config)
{
if (UserConstants.CONFIG_KEY_NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
if (!configService.checkConfigKeyUnique(config))
{
return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
config.setCreateBy(getLoginName());
config.setCreateBy(getUsername());
return toAjax(configService.insertConfig(config));
}
/**
* 修改参数配置
*/
@RequiresPermissions("system:config:edit")
@GetMapping("/edit/{configId}")
public String edit(@PathVariable("configId") Long configId, ModelMap mmap)
{
mmap.put("config", configService.selectConfigById(configId));
return prefix + "/edit";
}
/**
* 修改保存参数配置
*/
@RequiresPermissions("system:config:edit")
@PreAuthorize("@ss.hasPermi('system:config:edit')")
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysConfig config)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysConfig config)
{
if (UserConstants.CONFIG_KEY_NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
if (!configService.checkConfigKeyUnique(config))
{
return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
config.setUpdateBy(getLoginName());
config.setUpdateBy(getUsername());
return toAjax(configService.updateConfig(config));
}
/**
* 删除参数配置
*/
@RequiresPermissions("system:config:remove")
@PreAuthorize("@ss.hasPermi('system:config:remove')")
@Log(title = "参数管理", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
@DeleteMapping("/{configIds}")
public AjaxResult remove(@PathVariable Long[] configIds)
{
configService.deleteConfigByIds(ids);
configService.deleteConfigByIds(configIds);
return success();
}
/**
* 刷新参数缓存
*/
@RequiresPermissions("system:config:remove")
@PreAuthorize("@ss.hasPermi('system:config:remove')")
@Log(title = "参数管理", businessType = BusinessType.CLEAN)
@GetMapping("/refreshCache")
@ResponseBody
@DeleteMapping("/refreshCache")
public AjaxResult refreshCache()
{
configService.resetConfigCache();
return success();
}
/**
* 校验参数键名
*/
@PostMapping("/checkConfigKeyUnique")
@ResponseBody
public String checkConfigKeyUnique(SysConfig config)
{
return configService.checkConfigKeyUnique(config);
}
}

View File

@ -1,21 +1,22 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
@ -26,91 +27,74 @@ import com.ruoyi.system.service.ISysDeptService;
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/system/dept")
public class SysDeptController extends BaseController
{
private String prefix = "system/dept";
@Autowired
private ISysDeptService deptService;
@RequiresPermissions("system:dept:view")
@GetMapping()
public String dept()
/**
* 获取部门列表
*/
@PreAuthorize("@ss.hasPermi('system:dept:list')")
@GetMapping("/list")
public AjaxResult list(SysDept dept)
{
return prefix + "/dept";
List<SysDept> depts = deptService.selectDeptList(dept);
return success(depts);
}
@RequiresPermissions("system:dept:list")
@PostMapping("/list")
@ResponseBody
public List<SysDept> list(SysDept dept)
/**
* 查询部门列表排除节点
*/
@PreAuthorize("@ss.hasPermi('system:dept:list')")
@GetMapping("/list/exclude/{deptId}")
public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId)
{
List<SysDept> deptList = deptService.selectDeptList(dept);
return deptList;
List<SysDept> depts = deptService.selectDeptList(new SysDept());
depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""));
return success(depts);
}
/**
* 根据部门编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:dept:query')")
@GetMapping(value = "/{deptId}")
public AjaxResult getInfo(@PathVariable Long deptId)
{
deptService.checkDeptDataScope(deptId);
return success(deptService.selectDeptById(deptId));
}
/**
* 新增部门
*/
@GetMapping("/add/{parentId}")
public String add(@PathVariable("parentId") Long parentId, ModelMap mmap)
{
if (!getSysUser().isAdmin())
{
parentId = getSysUser().getDeptId();
}
mmap.put("dept", deptService.selectDeptById(parentId));
return prefix + "/add";
}
/**
* 新增保存部门
*/
@PreAuthorize("@ss.hasPermi('system:dept:add')")
@Log(title = "部门管理", businessType = BusinessType.INSERT)
@RequiresPermissions("system:dept:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysDept dept)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysDept dept)
{
if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
if (!deptService.checkDeptNameUnique(dept))
{
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
dept.setCreateBy(getLoginName());
dept.setCreateBy(getUsername());
return toAjax(deptService.insertDept(dept));
}
/**
* 修改部门
*/
@RequiresPermissions("system:dept:edit")
@GetMapping("/edit/{deptId}")
public String edit(@PathVariable("deptId") Long deptId, ModelMap mmap)
{
deptService.checkDeptDataScope(deptId);
SysDept dept = deptService.selectDeptById(deptId);
if (StringUtils.isNotNull(dept) && 100L == deptId)
{
dept.setParentName("");
}
mmap.put("dept", dept);
return prefix + "/edit";
}
/**
* 修改保存部门
*/
@PreAuthorize("@ss.hasPermi('system:dept:edit')")
@Log(title = "部门管理", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:dept:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysDept dept)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysDept dept)
{
Long deptId = dept.getDeptId();
deptService.checkDeptDataScope(deptId);
if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
if (!deptService.checkDeptNameUnique(dept))
{
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
@ -120,68 +104,29 @@ public class SysDeptController extends BaseController
}
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
{
return AjaxResult.error("该部门包含未停用的子部门!");
return error("该部门包含未停用的子部门!");
}
dept.setUpdateBy(getLoginName());
dept.setUpdateBy(getUsername());
return toAjax(deptService.updateDept(dept));
}
/**
* 删除
* 删除部门
*/
@PreAuthorize("@ss.hasPermi('system:dept:remove')")
@Log(title = "部门管理", businessType = BusinessType.DELETE)
@RequiresPermissions("system:dept:remove")
@GetMapping("/remove/{deptId}")
@ResponseBody
public AjaxResult remove(@PathVariable("deptId") Long deptId)
@DeleteMapping("/{deptId}")
public AjaxResult remove(@PathVariable Long deptId)
{
if (deptService.selectDeptCount(deptId) > 0)
if (deptService.hasChildByDeptId(deptId))
{
return AjaxResult.warn("存在下级部门,不允许删除");
return warn("存在下级部门,不允许删除");
}
if (deptService.checkDeptExistUser(deptId))
{
return AjaxResult.warn("部门存在用户,不允许删除");
return warn("部门存在用户,不允许删除");
}
deptService.checkDeptDataScope(deptId);
return toAjax(deptService.deleteDeptById(deptId));
}
/**
* 校验部门名称
*/
@PostMapping("/checkDeptNameUnique")
@ResponseBody
public String checkDeptNameUnique(SysDept dept)
{
return deptService.checkDeptNameUnique(dept);
}
/**
* 选择部门树
*
* @param deptId 部门ID
* @param excludeId 排除ID
*/
@GetMapping(value = { "/selectDeptTree/{deptId}", "/selectDeptTree/{deptId}/{excludeId}" })
public String selectDeptTree(@PathVariable("deptId") Long deptId,
@PathVariable(value = "excludeId", required = false) Long excludeId, ModelMap mmap)
{
mmap.put("dept", deptService.selectDeptById(deptId));
mmap.put("excludeId", excludeId);
return prefix + "/tree";
}
/**
* 加载部门列表树排除下级
*/
@GetMapping("/treeData/{excludeId}")
@ResponseBody
public List<Ztree> treeDataExcludeChild(@PathVariable(value = "excludeId", required = false) Long excludeId)
{
SysDept dept = new SysDept();
dept.setExcludeId(excludeId);
List<Ztree> ztrees = deptService.selectDeptTreeExcludeChild(dept);
return ztrees;
}
}

View File

@ -1,49 +1,47 @@
package com.ruoyi.web.controller.system;
import java.util.ArrayList;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
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.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService;
/**
* 数据字典信息
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/system/dict/data")
public class SysDictDataController extends BaseController
{
private String prefix = "system/dict/data";
@Autowired
private ISysDictDataService dictDataService;
@RequiresPermissions("system:dict:view")
@GetMapping()
public String dictData()
{
return prefix + "/data";
}
@Autowired
private ISysDictTypeService dictTypeService;
@PostMapping("/list")
@RequiresPermissions("system:dict:list")
@ResponseBody
@PreAuthorize("@ss.hasPermi('system:dict:list')")
@GetMapping("/list")
public TableDataInfo list(SysDictData dictData)
{
startPage();
@ -52,70 +50,72 @@ public class SysDictDataController extends BaseController
}
@Log(title = "字典数据", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:dict:export")
@PreAuthorize("@ss.hasPermi('system:dict:export')")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysDictData dictData)
public void export(HttpServletResponse response, SysDictData dictData)
{
List<SysDictData> list = dictDataService.selectDictDataList(dictData);
ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class);
return util.exportExcel(list, "字典数据");
util.exportExcel(response, list, "字典数据");
}
/**
* 查询字典数据详细
*/
@PreAuthorize("@ss.hasPermi('system:dict:query')")
@GetMapping(value = "/{dictCode}")
public AjaxResult getInfo(@PathVariable Long dictCode)
{
return success(dictDataService.selectDictDataById(dictCode));
}
/**
* 根据字典类型查询字典数据信息
*/
@GetMapping(value = "/type/{dictType}")
public AjaxResult dictType(@PathVariable String dictType)
{
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
if (StringUtils.isNull(data))
{
data = new ArrayList<SysDictData>();
}
return success(data);
}
/**
* 新增字典类型
*/
@GetMapping("/add/{dictType}")
public String add(@PathVariable("dictType") String dictType, ModelMap mmap)
{
mmap.put("dictType", dictType);
return prefix + "/add";
}
/**
* 新增保存字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:add')")
@Log(title = "字典数据", businessType = BusinessType.INSERT)
@RequiresPermissions("system:dict:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysDictData dict)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysDictData dict)
{
dict.setCreateBy(getLoginName());
dict.setCreateBy(getUsername());
return toAjax(dictDataService.insertDictData(dict));
}
/**
* 修改字典类型
*/
@RequiresPermissions("system:dict:edit")
@GetMapping("/edit/{dictCode}")
public String edit(@PathVariable("dictCode") Long dictCode, ModelMap mmap)
{
mmap.put("dict", dictDataService.selectDictDataById(dictCode));
return prefix + "/edit";
}
/**
* 修改保存字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:edit')")
@Log(title = "字典数据", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:dict:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysDictData dict)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysDictData dict)
{
dict.setUpdateBy(getLoginName());
dict.setUpdateBy(getUsername());
return toAjax(dictDataService.updateDictData(dict));
}
@Log(title = "字典数据", businessType = BusinessType.DELETE)
@RequiresPermissions("system:dict:remove")
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
/**
* 删除字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictCodes}")
public AjaxResult remove(@PathVariable Long[] dictCodes)
{
dictDataService.deleteDictDataByIds(ids);
dictDataService.deleteDictDataByIds(dictCodes);
return success();
}
}

View File

@ -1,21 +1,21 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
@ -27,25 +27,15 @@ import com.ruoyi.system.service.ISysDictTypeService;
*
* @author ruoyi
*/
@Controller
@RequestMapping("/system/dict")
@RestController
@RequestMapping("/system/dict/type")
public class SysDictTypeController extends BaseController
{
private String prefix = "system/dict/type";
@Autowired
private ISysDictTypeService dictTypeService;
@RequiresPermissions("system:dict:view")
@GetMapping()
public String dictType()
{
return prefix + "/type";
}
@PostMapping("/list")
@RequiresPermissions("system:dict:list")
@ResponseBody
@PreAuthorize("@ss.hasPermi('system:dict:list')")
@GetMapping("/list")
public TableDataInfo list(SysDictType dictType)
{
startPage();
@ -54,88 +44,75 @@ public class SysDictTypeController extends BaseController
}
@Log(title = "字典类型", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:dict:export")
@PreAuthorize("@ss.hasPermi('system:dict:export')")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysDictType dictType)
public void export(HttpServletResponse response, SysDictType dictType)
{
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class);
return util.exportExcel(list, "字典类型");
util.exportExcel(response, list, "字典类型");
}
/**
* 查询字典类型详细
*/
@PreAuthorize("@ss.hasPermi('system:dict:query')")
@GetMapping(value = "/{dictId}")
public AjaxResult getInfo(@PathVariable Long dictId)
{
return success(dictTypeService.selectDictTypeById(dictId));
}
/**
* 新增字典类型
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:add')")
@Log(title = "字典类型", businessType = BusinessType.INSERT)
@RequiresPermissions("system:dict:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysDictType dict)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysDictType dict)
{
if (UserConstants.DICT_TYPE_NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
if (!dictTypeService.checkDictTypeUnique(dict))
{
return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setCreateBy(getLoginName());
dict.setCreateBy(getUsername());
return toAjax(dictTypeService.insertDictType(dict));
}
/**
* 修改字典类型
*/
@RequiresPermissions("system:dict:edit")
@GetMapping("/edit/{dictId}")
public String edit(@PathVariable("dictId") Long dictId, ModelMap mmap)
{
mmap.put("dict", dictTypeService.selectDictTypeById(dictId));
return prefix + "/edit";
}
/**
* 修改保存字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:edit')")
@Log(title = "字典类型", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:dict:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysDictType dict)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysDictType dict)
{
if (UserConstants.DICT_TYPE_NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
if (!dictTypeService.checkDictTypeUnique(dict))
{
return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setUpdateBy(getLoginName());
dict.setUpdateBy(getUsername());
return toAjax(dictTypeService.updateDictType(dict));
}
/**
* 删除字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@RequiresPermissions("system:dict:remove")
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
@DeleteMapping("/{dictIds}")
public AjaxResult remove(@PathVariable Long[] dictIds)
{
dictTypeService.deleteDictTypeByIds(ids);
dictTypeService.deleteDictTypeByIds(dictIds);
return success();
}
/**
* 刷新字典缓存
*/
@RequiresPermissions("system:dict:remove")
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
@GetMapping("/refreshCache")
@ResponseBody
@DeleteMapping("/refreshCache")
public AjaxResult refreshCache()
{
dictTypeService.resetDictCache();
@ -143,47 +120,12 @@ public class SysDictTypeController extends BaseController
}
/**
* 查询字典详细
* 获取字典选择框列表
*/
@RequiresPermissions("system:dict:list")
@GetMapping("/detail/{dictId}")
public String detail(@PathVariable("dictId") Long dictId, ModelMap mmap)
@GetMapping("/optionselect")
public AjaxResult optionselect()
{
mmap.put("dict", dictTypeService.selectDictTypeById(dictId));
mmap.put("dictList", dictTypeService.selectDictTypeAll());
return "system/dict/data/data";
}
/**
* 校验字典类型
*/
@PostMapping("/checkDictTypeUnique")
@ResponseBody
public String checkDictTypeUnique(SysDictType 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;
List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll();
return success(dictTypes);
}
}

View File

@ -1,178 +1,29 @@
package com.ruoyi.web.controller.system;
import java.util.Date;
import java.util.List;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
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.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.ShiroConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.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;
/**
* 首页 业务处理
*
* 首页
*
* @author ruoyi
*/
@Controller
public class SysIndexController extends BaseController
@RestController
public class SysIndexController
{
/** 系统基础配置 */
@Autowired
private ISysMenuService menuService;
private RuoYiConfig ruoyiConfig;
@Autowired
private ISysConfigService configService;
@Autowired
private SysPasswordService passwordService;
// 系统首页
@GetMapping("/index")
public String index(ModelMap mmap)
/**
* 访问首页提示语
*/
@RequestMapping("/")
public String index()
{
// 取身份信息
SysUser user = getSysUser();
// 根据用户id取出菜单
List<SysMenu> menus = menuService.selectMenusByUser(user);
mmap.put("menus", menus);
mmap.put("user", user);
mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme"));
mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName"));
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")
public String main(ModelMap mmap)
{
mmap.put("version", RuoYiConfig.getVersion());
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;
return StringUtils.format("欢迎使用{}后台管理框架当前版本v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion());
}
}

View File

@ -1,82 +1,86 @@
package com.ruoyi.web.controller.system;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.ResponseBody;
import com.ruoyi.common.core.controller.BaseController;
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
{
/**
* 是否开启记住我功能
*/
@Value("${shiro.rememberMe.enabled: false}")
private boolean rememberMe;
@Autowired
private ConfigService configService;
@GetMapping("/login")
public String login(HttpServletRequest request, HttpServletResponse response, ModelMap mmap)
{
// 如果是Ajax请求返回Json字符串
if (ServletUtils.isAjaxRequest(request))
{
return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
}
// 是否开启记住我
mmap.put("isRemembered", rememberMe);
// 是否开启用户注册
mmap.put("isAllowRegister", Convert.toBool(configService.getKey("sys.account.registerUser"), false));
return "login";
}
@PostMapping("/login")
@ResponseBody
public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
{
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
Subject subject = SecurityUtils.getSubject();
try
{
subject.login(token);
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";
}
}
package com.ruoyi.web.controller.system;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.system.service.ISysMenuService;
/**
* 登录验证
*
* @author ruoyi
*/
@RestController
public class SysLoginController
{
@Autowired
private SysLoginService loginService;
@Autowired
private ISysMenuService menuService;
@Autowired
private SysPermissionService permissionService;
/**
* 登录方法
*
* @param loginBody 登录信息
* @return 结果
*/
@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
loginBody.getUuid());
ajax.put(Constants.TOKEN, token);
return ajax;
}
/**
* 获取用户信息
*
* @return 用户信息
*/
@GetMapping("getInfo")
public AjaxResult getInfo()
{
SysUser user = SecurityUtils.getLoginUser().getUser();
// 角色集合
Set<String> roles = permissionService.getRolePermission(user);
// 权限集合
Set<String> permissions = permissionService.getMenuPermission(user);
AjaxResult ajax = AjaxResult.success();
ajax.put("user", user);
ajax.put("roles", roles);
ajax.put("permissions", permissions);
return ajax;
}
/**
* 获取路由信息
*
* @return 路由信息
*/
@GetMapping("getRouters")
public AjaxResult getRouters()
{
Long userId = SecurityUtils.getUserId();
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
return AjaxResult.success(menuService.buildMenus(menus));
}
}

View File

@ -1,26 +1,24 @@
package com.ruoyi.web.controller.system;
import java.util.List;
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.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysMenuService;
/**
@ -28,171 +26,117 @@ import com.ruoyi.system.service.ISysMenuService;
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/system/menu")
public class SysMenuController extends BaseController
{
private String prefix = "system/menu";
@Autowired
private ISysMenuService menuService;
@RequiresPermissions("system:menu:view")
@GetMapping()
public String menu()
/**
* 获取菜单列表
*/
@PreAuthorize("@ss.hasPermi('system:menu:list')")
@GetMapping("/list")
public AjaxResult list(SysMenu menu)
{
return prefix + "/menu";
}
@RequiresPermissions("system:menu:list")
@PostMapping("/list")
@ResponseBody
public List<SysMenu> list(SysMenu menu)
{
Long userId = ShiroUtils.getUserId();
List<SysMenu> menuList = menuService.selectMenuList(menu, userId);
return menuList;
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
return success(menus);
}
/**
* 删除菜单
* 根据菜单编号获取详细信息
*/
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
@RequiresPermissions("system:menu:remove")
@GetMapping("/remove/{menuId}")
@ResponseBody
public AjaxResult remove(@PathVariable("menuId") Long menuId)
@PreAuthorize("@ss.hasPermi('system:menu:query')")
@GetMapping(value = "/{menuId}")
public AjaxResult getInfo(@PathVariable Long menuId)
{
if (menuService.selectCountMenuByParentId(menuId) > 0)
{
return AjaxResult.warn("存在子菜单,不允许删除");
}
if (menuService.selectCountRoleMenuByMenuId(menuId) > 0)
{
return AjaxResult.warn("菜单已分配,不允许删除");
}
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.deleteMenuById(menuId));
return success(menuService.selectMenuById(menuId));
}
/**
* 新增
* 获取菜单下拉树列表
*/
@GetMapping("/add/{parentId}")
public String add(@PathVariable("parentId") Long parentId, ModelMap mmap)
@GetMapping("/treeselect")
public AjaxResult treeselect(SysMenu menu)
{
SysMenu menu = null;
if (0L != parentId)
{
menu = menuService.selectMenuById(parentId);
}
else
{
menu = new SysMenu();
menu.setMenuId(0L);
menu.setMenuName("主目录");
}
mmap.put("menu", menu);
return prefix + "/add";
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
return success(menuService.buildMenuTreeSelect(menus));
}
/**
* 新增保存菜单
* 加载对应角色菜单列表树
*/
@GetMapping(value = "/roleMenuTreeselect/{roleId}")
public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
{
List<SysMenu> menus = menuService.selectMenuList(getUserId());
AjaxResult ajax = AjaxResult.success();
ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
ajax.put("menus", menuService.buildMenuTreeSelect(menus));
return ajax;
}
/**
* 新增菜单
*/
@PreAuthorize("@ss.hasPermi('system:menu:add')")
@Log(title = "菜单管理", businessType = BusinessType.INSERT)
@RequiresPermissions("system:menu:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysMenu menu)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysMenu menu)
{
if (UserConstants.MENU_NAME_NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
if (!menuService.checkMenuNameUnique(menu))
{
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
menu.setCreateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
{
return error("新增菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
}
menu.setCreateBy(getUsername());
return toAjax(menuService.insertMenu(menu));
}
/**
* 修改菜单
*/
@RequiresPermissions("system:menu:edit")
@GetMapping("/edit/{menuId}")
public String edit(@PathVariable("menuId") Long menuId, ModelMap mmap)
{
mmap.put("menu", menuService.selectMenuById(menuId));
return prefix + "/edit";
}
/**
* 修改保存菜单
*/
@PreAuthorize("@ss.hasPermi('system:menu:edit')")
@Log(title = "菜单管理", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:menu:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysMenu menu)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysMenu menu)
{
if (UserConstants.MENU_NAME_NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
if (!menuService.checkMenuNameUnique(menu))
{
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
menu.setUpdateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
{
return error("修改菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
}
else if (menu.getMenuId().equals(menu.getParentId()))
{
return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
}
menu.setUpdateBy(getUsername());
return toAjax(menuService.updateMenu(menu));
}
/**
* 选择菜单图标
* 删除菜单
*/
@GetMapping("/icon")
public String icon()
@PreAuthorize("@ss.hasPermi('system:menu:remove')")
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{menuId}")
public AjaxResult remove(@PathVariable("menuId") Long menuId)
{
return prefix + "/icon";
}
/**
* 校验菜单名称
*/
@PostMapping("/checkMenuNameUnique")
@ResponseBody
public String checkMenuNameUnique(SysMenu menu)
{
return menuService.checkMenuNameUnique(menu);
}
/**
* 加载角色菜单列表树
*/
@GetMapping("/roleMenuTreeData")
@ResponseBody
public List<Ztree> roleMenuTreeData(SysRole role)
{
Long userId = ShiroUtils.getUserId();
List<Ztree> ztrees = menuService.roleMenuTreeData(role, userId);
return ztrees;
}
/**
* 加载所有菜单列表树
*/
@GetMapping("/menuTreeData")
@ResponseBody
public List<Ztree> menuTreeData()
{
Long userId = ShiroUtils.getUserId();
List<Ztree> ztrees = menuService.menuTreeData(userId);
return ztrees;
}
/**
* 选择菜单树
*/
@GetMapping("/selectMenuTree/{menuId}")
public String selectMenuTree(@PathVariable("menuId") Long menuId, ModelMap mmap)
{
mmap.put("menu", menuService.selectMenuById(menuId));
return prefix + "/tree";
if (menuService.hasChildByMenuId(menuId))
{
return warn("存在子菜单,不允许删除");
}
if (menuService.checkMenuExistRole(menuId))
{
return warn("菜单已分配,不允许删除");
}
return toAjax(menuService.deleteMenuById(menuId));
}
}

View File

@ -1,16 +1,17 @@
package com.ruoyi.web.controller.system;
import java.util.List;
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.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
@ -24,28 +25,18 @@ import com.ruoyi.system.service.ISysNoticeService;
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/system/notice")
public class SysNoticeController extends BaseController
{
private String prefix = "system/notice";
@Autowired
private ISysNoticeService noticeService;
@RequiresPermissions("system:notice:view")
@GetMapping()
public String notice()
{
return prefix + "/notice";
}
/**
* 查询公告列表
* 获取通知公告列表
*/
@RequiresPermissions("system:notice:list")
@PostMapping("/list")
@ResponseBody
@PreAuthorize("@ss.hasPermi('system:notice:list')")
@GetMapping("/list")
public TableDataInfo list(SysNotice notice)
{
startPage();
@ -54,60 +45,47 @@ public class SysNoticeController extends BaseController
}
/**
* 新增公告
* 根据通知公告编号获取详细信息
*/
@GetMapping("/add")
public String add()
@PreAuthorize("@ss.hasPermi('system:notice:query')")
@GetMapping(value = "/{noticeId}")
public AjaxResult getInfo(@PathVariable Long noticeId)
{
return prefix + "/add";
return success(noticeService.selectNoticeById(noticeId));
}
/**
* 新增保存公告
* 新增通知公告
*/
@RequiresPermissions("system:notice:add")
@PreAuthorize("@ss.hasPermi('system:notice:add')")
@Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysNotice notice)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysNotice notice)
{
notice.setCreateBy(getLoginName());
notice.setCreateBy(getUsername());
return toAjax(noticeService.insertNotice(notice));
}
/**
* 修改公告
* 修改通知公告
*/
@RequiresPermissions("system:notice:edit")
@GetMapping("/edit/{noticeId}")
public String edit(@PathVariable("noticeId") Long noticeId, ModelMap mmap)
{
mmap.put("notice", noticeService.selectNoticeById(noticeId));
return prefix + "/edit";
}
/**
* 修改保存公告
*/
@RequiresPermissions("system:notice:edit")
@PreAuthorize("@ss.hasPermi('system:notice:edit')")
@Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysNotice notice)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysNotice notice)
{
notice.setUpdateBy(getLoginName());
notice.setUpdateBy(getUsername());
return toAjax(noticeService.updateNotice(notice));
}
/**
* 删除公告
* 删除通知公告
*/
@RequiresPermissions("system:notice:remove")
@PreAuthorize("@ss.hasPermi('system:notice:remove')")
@Log(title = "通知公告", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
@DeleteMapping("/{noticeIds}")
public AjaxResult remove(@PathVariable Long[] noticeIds)
{
return toAjax(noticeService.deleteNoticeByIds(ids));
return toAjax(noticeService.deleteNoticeByIds(noticeIds));
}
}

View File

@ -1,18 +1,19 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
@ -26,138 +27,103 @@ import com.ruoyi.system.service.ISysPostService;
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/system/post")
public class SysPostController extends BaseController
{
private String prefix = "system/post";
@Autowired
private ISysPostService postService;
@RequiresPermissions("system:post:view")
@GetMapping()
public String operlog()
{
return prefix + "/post";
}
@RequiresPermissions("system:post:list")
@PostMapping("/list")
@ResponseBody
/**
* 获取岗位列表
*/
@PreAuthorize("@ss.hasPermi('system:post:list')")
@GetMapping("/list")
public TableDataInfo list(SysPost post)
{
startPage();
List<SysPost> list = postService.selectPostList(post);
return getDataTable(list);
}
@Log(title = "岗位管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:post:export")
@PreAuthorize("@ss.hasPermi('system:post:export')")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysPost post)
public void export(HttpServletResponse response, SysPost post)
{
List<SysPost> list = postService.selectPostList(post);
ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class);
return util.exportExcel(list, "岗位数据");
util.exportExcel(response, list, "岗位数据");
}
@RequiresPermissions("system:post:remove")
@Log(title = "岗位管理", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
/**
* 根据岗位编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:post:query')")
@GetMapping(value = "/{postId}")
public AjaxResult getInfo(@PathVariable Long postId)
{
try
{
return toAjax(postService.deletePostByIds(ids));
}
catch (Exception e)
{
return error(e.getMessage());
}
return success(postService.selectPostById(postId));
}
/**
* 新增岗位
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存岗位
*/
@RequiresPermissions("system:post:add")
@PreAuthorize("@ss.hasPermi('system:post:add')")
@Log(title = "岗位管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysPost post)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysPost post)
{
if (UserConstants.POST_NAME_NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
if (!postService.checkPostNameUnique(post))
{
return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
}
else if (UserConstants.POST_CODE_NOT_UNIQUE.equals(postService.checkPostCodeUnique(post)))
else if (!postService.checkPostCodeUnique(post))
{
return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
}
post.setCreateBy(getLoginName());
post.setCreateBy(getUsername());
return toAjax(postService.insertPost(post));
}
/**
* 修改岗位
*/
@RequiresPermissions("system:post:edit")
@GetMapping("/edit/{postId}")
public String edit(@PathVariable("postId") Long postId, ModelMap mmap)
{
mmap.put("post", postService.selectPostById(postId));
return prefix + "/edit";
}
/**
* 修改保存岗位
*/
@RequiresPermissions("system:post:edit")
@PreAuthorize("@ss.hasPermi('system:post:edit')")
@Log(title = "岗位管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysPost post)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysPost post)
{
if (UserConstants.POST_NAME_NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
if (!postService.checkPostNameUnique(post))
{
return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
}
else if (UserConstants.POST_CODE_NOT_UNIQUE.equals(postService.checkPostCodeUnique(post)))
else if (!postService.checkPostCodeUnique(post))
{
return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
}
post.setUpdateBy(getLoginName());
post.setUpdateBy(getUsername());
return toAjax(postService.updatePost(post));
}
/**
* 校验岗位名称
* 删除岗位
*/
@PostMapping("/checkPostNameUnique")
@ResponseBody
public String checkPostNameUnique(SysPost post)
@PreAuthorize("@ss.hasPermi('system:post:remove')")
@Log(title = "岗位管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{postIds}")
public AjaxResult remove(@PathVariable Long[] postIds)
{
return postService.checkPostNameUnique(post);
return toAjax(postService.deletePostByIds(postIds));
}
/**
* 校验岗位编码
* 获取岗位选择框列表
*/
@PostMapping("/checkPostCodeUnique")
@ResponseBody
public String checkPostCodeUnique(SysPost post)
@GetMapping("/optionselect")
public AjaxResult optionselect()
{
return postService.checkPostCodeUnique(post);
List<SysPost> posts = postService.selectPostAll();
return success(posts);
}
}

View File

@ -1,29 +1,26 @@
package com.ruoyi.web.controller.system;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
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.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
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.web.service.TokenService;
import com.ruoyi.system.service.ISysUserService;
/**
@ -31,154 +28,110 @@ import com.ruoyi.system.service.ISysUserService;
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController
{
private static final Logger log = LoggerFactory.getLogger(SysProfileController.class);
private String prefix = "system/user/profile";
@Autowired
private ISysUserService userService;
@Autowired
private SysPasswordService passwordService;
private TokenService tokenService;
/**
* 个人信息
*/
@GetMapping()
public String profile(ModelMap mmap)
@GetMapping
public AjaxResult profile()
{
SysUser user = getSysUser();
mmap.put("user", user);
mmap.put("roleGroup", userService.selectUserRoleGroup(user.getUserId()));
mmap.put("postGroup", userService.selectUserPostGroup(user.getUserId()));
return prefix + "/profile";
LoginUser loginUser = getLoginUser();
SysUser user = loginUser.getUser();
AjaxResult ajax = AjaxResult.success(user);
ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
return ajax;
}
@GetMapping("/checkPassword")
@ResponseBody
public boolean checkPassword(String password)
/**
* 修改用户
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult updateProfile(@RequestBody SysUser user)
{
SysUser user = getSysUser();
return passwordService.matches(user, password);
LoginUser loginUser = getLoginUser();
SysUser currentUser = loginUser.getUser();
currentUser.setNickName(user.getNickName());
currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setSex(user.getSex());
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
{
return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在");
}
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
{
return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在");
}
if (userService.updateUserProfile(currentUser) > 0)
{
// 更新缓存用户信息
tokenService.setLoginUser(loginUser);
return success();
}
return error("修改个人信息异常,请联系管理员");
}
@GetMapping("/resetPwd")
public String resetPwd(ModelMap mmap)
/**
* 重置密码
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping("/updatePwd")
public AjaxResult updatePwd(String oldPassword, String newPassword)
{
SysUser user = getSysUser();
mmap.put("user", userService.selectUserById(user.getUserId()));
return prefix + "/resetPwd";
}
@Log(title = "重置密码", businessType = BusinessType.UPDATE)
@PostMapping("/resetPwd")
@ResponseBody
public AjaxResult resetPwd(String oldPassword, String newPassword)
{
SysUser user = getSysUser();
if (!passwordService.matches(user, oldPassword))
LoginUser loginUser = getLoginUser();
String userName = loginUser.getUsername();
String password = loginUser.getPassword();
if (!SecurityUtils.matchesPassword(oldPassword, password))
{
return error("修改密码失败,旧密码错误");
}
if (passwordService.matches(user, newPassword))
if (SecurityUtils.matchesPassword(newPassword, password))
{
return error("新密码不能与旧密码相同");
}
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
user.setPwdUpdateDate(DateUtils.getNowDate());
if (userService.resetUserPwd(user) > 0)
newPassword = SecurityUtils.encryptPassword(newPassword);
if (userService.resetUserPwd(userName, newPassword) > 0)
{
setSysUser(userService.selectUserById(user.getUserId()));
// 更新缓存用户密码
loginUser.getUser().setPassword(newPassword);
tokenService.setLoginUser(loginUser);
return success();
}
return error("修改密码异常,请联系管理员");
}
/**
* 修改用户
* 头像上传
*/
@GetMapping("/edit")
public String edit(ModelMap mmap)
@Log(title = "用户头像", businessType = BusinessType.UPDATE)
@PostMapping("/avatar")
public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception
{
SysUser user = getSysUser();
mmap.put("user", userService.selectUserById(user.getUserId()));
return prefix + "/edit";
}
/**
* 修改头像
*/
@GetMapping("/avatar")
public String avatar(ModelMap mmap)
{
SysUser user = getSysUser();
mmap.put("user", userService.selectUserById(user.getUserId()));
return prefix + "/avatar";
}
/**
* 修改用户
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PostMapping("/update")
@ResponseBody
public AjaxResult update(SysUser user)
{
SysUser currentUser = getSysUser();
currentUser.setUserName(user.getUserName());
currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setSex(user.getSex());
if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(currentUser)))
if (!file.isEmpty())
{
return error("修改用户'" + currentUser.getLoginName() + "'失败,手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail())
&& UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(currentUser)))
{
return error("修改用户'" + currentUser.getLoginName() + "'失败,邮箱账号已存在");
}
if (userService.updateUserInfo(currentUser) > 0)
{
setSysUser(userService.selectUserById(currentUser.getUserId()));
return success();
}
return error();
}
/**
* 保存头像
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PostMapping("/updateAvatar")
@ResponseBody
public AjaxResult updateAvatar(@RequestParam("avatarfile") MultipartFile file)
{
SysUser currentUser = getSysUser();
try
{
if (!file.isEmpty())
LoginUser loginUser = getLoginUser();
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
if (userService.updateUserAvatar(loginUser.getUsername(), avatar))
{
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
currentUser.setAvatar(avatar);
if (userService.updateUserInfo(currentUser) > 0)
{
setSysUser(userService.selectUserById(currentUser.getUserId()));
return success();
}
AjaxResult ajax = AjaxResult.success();
ajax.put("imgUrl", avatar);
// 更新缓存用户头像
loginUser.getUser().setAvatar(avatar);
tokenService.setLoginUser(loginUser);
return ajax;
}
return error();
}
catch (Exception e)
{
log.error("修改头像失败!", e);
return error(e.getMessage());
}
return error("上传图片异常,请联系管理员");
}
}

View File

@ -1,15 +1,14 @@
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 org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
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.core.domain.model.RegisterBody;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.shiro.service.SysRegisterService;
import com.ruoyi.framework.web.service.SysRegisterService;
import com.ruoyi.system.service.ISysConfigService;
/**
@ -17,7 +16,7 @@ import com.ruoyi.system.service.ISysConfigService;
*
* @author ruoyi
*/
@Controller
@RestController
public class SysRegisterController extends BaseController
{
@Autowired
@ -26,15 +25,8 @@ public class SysRegisterController extends BaseController
@Autowired
private ISysConfigService configService;
@GetMapping("/register")
public String register()
{
return "register";
}
@PostMapping("/register")
@ResponseBody
public AjaxResult ajaxRegister(SysUser user)
public AjaxResult register(@RequestBody RegisterBody user)
{
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
{

View File

@ -1,27 +1,31 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysRoleService;
@ -32,31 +36,27 @@ import com.ruoyi.system.service.ISysUserService;
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/system/role")
public class SysRoleController extends BaseController
{
private String prefix = "system/role";
@Autowired
private ISysRoleService roleService;
@Autowired
private TokenService tokenService;
@Autowired
private SysPermissionService permissionService;
@Autowired
private ISysUserService userService;
@Autowired
private ISysDeptService deptService;
@RequiresPermissions("system:role:view")
@GetMapping()
public String role()
{
return prefix + "/role";
}
@RequiresPermissions("system:role:list")
@PostMapping("/list")
@ResponseBody
@PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/list")
public TableDataInfo list(SysRole role)
{
startPage();
@ -65,183 +65,135 @@ public class SysRoleController extends BaseController
}
@Log(title = "角色管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:role:export")
@PreAuthorize("@ss.hasPermi('system:role:export')")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysRole role)
public void export(HttpServletResponse response, SysRole role)
{
List<SysRole> list = roleService.selectRoleList(role);
ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
return util.exportExcel(list, "角色数据");
util.exportExcel(response, list, "角色数据");
}
/**
* 根据角色编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:role:query')")
@GetMapping(value = "/{roleId}")
public AjaxResult getInfo(@PathVariable Long roleId)
{
roleService.checkRoleDataScope(roleId);
return success(roleService.selectRoleById(roleId));
}
/**
* 新增角色
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存角色
*/
@RequiresPermissions("system:role:add")
@PreAuthorize("@ss.hasPermi('system:role:add')")
@Log(title = "角色管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysRole role)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysRole role)
{
if (UserConstants.ROLE_NAME_NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
if (!roleService.checkRoleNameUnique(role))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (UserConstants.ROLE_KEY_NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role)))
else if (!roleService.checkRoleKeyUnique(role))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setCreateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
role.setCreateBy(getUsername());
return toAjax(roleService.insertRole(role));
}
/**
* 修改角色
*/
@RequiresPermissions("system:role:edit")
@GetMapping("/edit/{roleId}")
public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap)
{
roleService.checkRoleDataScope(roleId);
mmap.put("role", roleService.selectRoleById(roleId));
return prefix + "/edit";
}
/**
* 修改保存角色
*/
@RequiresPermissions("system:role:edit")
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysRole role)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
if (UserConstants.ROLE_NAME_NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
if (!roleService.checkRoleNameUnique(role))
{
return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (UserConstants.ROLE_KEY_NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role)))
else if (!roleService.checkRoleKeyUnique(role))
{
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setUpdateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(roleService.updateRole(role));
}
/**
* 角色分配数据权限
*/
@GetMapping("/authDataScope/{roleId}")
public String authDataScope(@PathVariable("roleId") Long roleId, ModelMap mmap)
{
mmap.put("role", roleService.selectRoleById(roleId));
return prefix + "/dataScope";
}
/**
* 保存角色分配数据权限
*/
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PostMapping("/authDataScope")
@ResponseBody
public AjaxResult authDataScopeSave(SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
role.setUpdateBy(getLoginName());
if (roleService.authDataScope(role) > 0)
role.setUpdateBy(getUsername());
if (roleService.updateRole(role) > 0)
{
setSysUser(userService.selectUserById(getUserId()));
// 更新缓存用户权限
LoginUser loginUser = getLoginUser();
if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin())
{
loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser()));
loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
tokenService.setLoginUser(loginUser);
}
return success();
}
return error();
}
@RequiresPermissions("system:role:remove")
@Log(title = "角色管理", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(roleService.deleteRoleByIds(ids));
return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
}
/**
* 校验角色名称
*/
@PostMapping("/checkRoleNameUnique")
@ResponseBody
public String checkRoleNameUnique(SysRole role)
{
return roleService.checkRoleNameUnique(role);
}
/**
* 校验角色权限
*/
@PostMapping("/checkRoleKeyUnique")
@ResponseBody
public String checkRoleKeyUnique(SysRole role)
{
return roleService.checkRoleKeyUnique(role);
}
/**
* 选择菜单树
*/
@GetMapping("/selectMenuTree")
public String selectMenuTree()
{
return prefix + "/tree";
}
/**
* 角色状态修改
* 修改保存数据权限
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:role:edit")
@PostMapping("/changeStatus")
@ResponseBody
public AjaxResult changeStatus(SysRole role)
@PutMapping("/dataScope")
public AjaxResult dataScope(@RequestBody SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
return toAjax(roleService.changeStatus(role));
return toAjax(roleService.authDataScope(role));
}
/**
* 分配用户
* 状态修改
*/
@RequiresPermissions("system:role:edit")
@GetMapping("/authUser/{roleId}")
public String authUser(@PathVariable("roleId") Long roleId, ModelMap mmap)
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody SysRole role)
{
mmap.put("role", roleService.selectRoleById(roleId));
return prefix + "/authUser";
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
role.setUpdateBy(getUsername());
return toAjax(roleService.updateRoleStatus(role));
}
/**
* 删除角色
*/
@PreAuthorize("@ss.hasPermi('system:role:remove')")
@Log(title = "角色管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{roleIds}")
public AjaxResult remove(@PathVariable Long[] roleIds)
{
return toAjax(roleService.deleteRoleByIds(roleIds));
}
/**
* 获取角色选择框列表
*/
@PreAuthorize("@ss.hasPermi('system:role:query')")
@GetMapping("/optionselect")
public AjaxResult optionselect()
{
return success(roleService.selectRoleAll());
}
/**
* 查询已分配用户角色列表
*/
@RequiresPermissions("system:role:list")
@PostMapping("/authUser/allocatedList")
@ResponseBody
@PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/authUser/allocatedList")
public TableDataInfo allocatedList(SysUser user)
{
startPage();
@ -249,46 +201,11 @@ public class SysRoleController extends BaseController
return getDataTable(list);
}
/**
* 取消授权
*/
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PostMapping("/authUser/cancel")
@ResponseBody
public AjaxResult cancelAuthUser(SysUserRole userRole)
{
return toAjax(roleService.deleteAuthUser(userRole));
}
/**
* 批量取消授权
*/
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PostMapping("/authUser/cancelAll")
@ResponseBody
public AjaxResult cancelAuthUserAll(Long roleId, String userIds)
{
return toAjax(roleService.deleteAuthUsers(roleId, userIds));
}
/**
* 选择用户
*/
@GetMapping("/authUser/selectUser/{roleId}")
public String selectUser(@PathVariable("roleId") Long roleId, ModelMap mmap)
{
mmap.put("role", roleService.selectRoleById(roleId));
return prefix + "/selectUser";
}
/**
* 查询未分配用户角色列表
*/
@RequiresPermissions("system:role:list")
@PostMapping("/authUser/unallocatedList")
@ResponseBody
@PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/authUser/unallocatedList")
public TableDataInfo unallocatedList(SysUser user)
{
startPage();
@ -296,28 +213,50 @@ public class SysRoleController extends BaseController
return getDataTable(list);
}
/**
* 取消授权用户
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/cancel")
public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole)
{
return toAjax(roleService.deleteAuthUser(userRole));
}
/**
* 批量取消授权用户
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/cancelAll")
public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds)
{
return toAjax(roleService.deleteAuthUsers(roleId, userIds));
}
/**
* 批量选择用户授权
*/
@RequiresPermissions("system:role:edit")
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PostMapping("/authUser/selectAll")
@ResponseBody
public AjaxResult selectAuthUserAll(Long roleId, String userIds)
@PutMapping("/authUser/selectAll")
public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds)
{
roleService.checkRoleDataScope(roleId);
return toAjax(roleService.insertAuthUsers(roleId, userIds));
}
/**
* 加载角色部门数据权限列表树
* 获取对应角色部门树列表
*/
@RequiresPermissions("system:role:edit")
@GetMapping("/deptTreeData")
@ResponseBody
public List<Ztree> deptTreeData(SysRole role)
@PreAuthorize("@ss.hasPermi('system:role:query')")
@GetMapping(value = "/deptTree/{roleId}")
public AjaxResult deptTree(@PathVariable("roleId") Long roleId)
{
List<Ztree> ztrees = deptService.roleDeptTreeData(role);
return ztrees;
AjaxResult ajax = AjaxResult.success();
ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
return ajax;
}
}
}

View File

@ -2,34 +2,31 @@ package com.ruoyi.web.controller.system;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
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.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService;
@ -40,37 +37,27 @@ import com.ruoyi.system.service.ISysUserService;
*
* @author ruoyi
*/
@Controller
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController
{
private String prefix = "system/user";
@Autowired
private ISysUserService userService;
@Autowired
private ISysRoleService roleService;
@Autowired
private ISysDeptService deptService;
@Autowired
private ISysPostService postService;
@Autowired
private SysPasswordService passwordService;
@RequiresPermissions("system:user:view")
@GetMapping()
public String user()
{
return prefix + "/user";
}
@RequiresPermissions("system:user:list")
@PostMapping("/list")
@ResponseBody
/**
* 获取用户列表
*/
@PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/list")
public TableDataInfo list(SysUser user)
{
startPage();
@ -79,259 +66,191 @@ public class SysUserController extends BaseController
}
@Log(title = "用户管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:user:export")
@PreAuthorize("@ss.hasPermi('system:user:export')")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysUser user)
public void export(HttpServletResponse response, SysUser user)
{
List<SysUser> list = userService.selectUserList(user);
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
return util.exportExcel(list, "用户数据");
util.exportExcel(response, list, "用户数据");
}
@Log(title = "用户管理", businessType = BusinessType.IMPORT)
@RequiresPermissions("system:user:import")
@PreAuthorize("@ss.hasPermi('system:user:import')")
@PostMapping("/importData")
@ResponseBody
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
List<SysUser> userList = util.importExcel(file.getInputStream());
String message = userService.importUser(userList, updateSupport, getLoginName());
return AjaxResult.success(message);
String operName = getUsername();
String message = userService.importUser(userList, updateSupport, operName);
return success(message);
}
@RequiresPermissions("system:user:view")
@GetMapping("/importTemplate")
@ResponseBody
public AjaxResult importTemplate()
@PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response)
{
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
return util.importTemplateExcel("用户数据");
util.importTemplateExcel(response, "用户数据");
}
/**
* 根据用户编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:user:query')")
@GetMapping(value = { "/", "/{userId}" })
public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)
{
userService.checkUserDataScope(userId);
AjaxResult ajax = AjaxResult.success();
List<SysRole> roles = roleService.selectRoleAll();
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
ajax.put("posts", postService.selectPostAll());
if (StringUtils.isNotNull(userId))
{
SysUser sysUser = userService.selectUserById(userId);
ajax.put(AjaxResult.DATA_TAG, sysUser);
ajax.put("postIds", postService.selectPostListByUserId(userId));
ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
}
return ajax;
}
/**
* 新增用户
*/
@GetMapping("/add")
public String add(ModelMap mmap)
{
mmap.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
mmap.put("posts", postService.selectPostAll());
return prefix + "/add";
}
/**
* 新增保存用户
*/
@RequiresPermissions("system:user:add")
@PreAuthorize("@ss.hasPermi('system:user:add')")
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysUser user)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysUser user)
{
if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user)))
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user))
{
return error("新增用户'" + user.getLoginName() + "'失败,登录账号已存在");
return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
return error("新增用户'" + user.getLoginName() + "'失败,手机号码已存在");
return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail())
&& UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{
return error("新增用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
user.setCreateBy(getLoginName());
user.setCreateBy(getUsername());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
return toAjax(userService.insertUser(user));
}
/**
* 修改用户
*/
@RequiresPermissions("system:user:edit")
@GetMapping("/edit/{userId}")
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("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
mmap.put("posts", postService.selectPostsByUserId(userId));
return prefix + "/edit";
}
/**
* 修改保存用户
*/
@RequiresPermissions("system:user:edit")
@PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysUser user)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user)))
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user))
{
return error("修改用户'" + user.getLoginName() + "'失败,登录账号已存在");
return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
return error("修改用户'" + user.getLoginName() + "'失败,手机号码已存在");
return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail())
&& UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{
return error("修改用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setUpdateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
user.setUpdateBy(getUsername());
return toAjax(userService.updateUser(user));
}
@RequiresPermissions("system:user:resetPwd")
@GetMapping("/resetPwd/{userId}")
public String resetPwd(@PathVariable("userId") Long userId, ModelMap mmap)
/**
* 删除用户
*/
@PreAuthorize("@ss.hasPermi('system:user:remove')")
@Log(title = "用户管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{userIds}")
public AjaxResult remove(@PathVariable Long[] userIds)
{
mmap.put("user", userService.selectUserById(userId));
return prefix + "/resetPwd";
}
@RequiresPermissions("system:user:resetPwd")
@Log(title = "重置密码", businessType = BusinessType.UPDATE)
@PostMapping("/resetPwd")
@ResponseBody
public AjaxResult resetPwdSave(SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
if (userService.resetUserPwd(user) > 0)
if (ArrayUtils.contains(userIds, getUserId()))
{
if (ShiroUtils.getUserId().longValue() == user.getUserId().longValue())
{
setSysUser(userService.selectUserById(user.getUserId()));
}
return success();
return error("当前用户不能删除");
}
return error();
return toAjax(userService.deleteUserByIds(userIds));
}
/**
* 进入授权角色页
* 重置密码
*/
@GetMapping("/authRole/{userId}")
public String authRole(@PathVariable("userId") Long userId, ModelMap mmap)
@PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/resetPwd")
public AjaxResult resetPwd(@RequestBody SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
user.setUpdateBy(getUsername());
return toAjax(userService.resetPwd(user));
}
/**
* 状态修改
*/
@PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setUpdateBy(getUsername());
return toAjax(userService.updateUserStatus(user));
}
/**
* 根据用户编号获取授权角色
*/
@PreAuthorize("@ss.hasPermi('system:user:query')")
@GetMapping("/authRole/{userId}")
public AjaxResult authRole(@PathVariable("userId") Long userId)
{
AjaxResult ajax = AjaxResult.success();
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";
ajax.put("user", user);
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
return ajax;
}
/**
* 用户授权角色
*/
@RequiresPermissions("system:user:edit")
@PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.GRANT)
@PostMapping("/authRole/insertAuthRole")
@ResponseBody
@PutMapping("/authRole")
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")
@Log(title = "用户管理", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
if (ArrayUtils.contains(Convert.toLongArray(ids), getUserId()))
{
return error("当前用户不能删除");
}
return toAjax(userService.deleteUserByIds(ids));
}
/**
* 校验用户名
* 获取部门树列表
*/
@PostMapping("/checkLoginNameUnique")
@ResponseBody
public String checkLoginNameUnique(SysUser user)
@PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/deptTree")
public AjaxResult deptTree(SysDept dept)
{
return userService.checkLoginNameUnique(user);
return success(deptService.selectDeptTreeList(dept));
}
/**
* 校验手机号码
*/
@PostMapping("/checkPhoneUnique")
@ResponseBody
public String checkPhoneUnique(SysUser user)
{
return userService.checkPhoneUnique(user);
}
/**
* 校验email邮箱
*/
@PostMapping("/checkEmailUnique")
@ResponseBody
public String checkEmailUnique(SysUser user)
{
return userService.checkEmailUnique(user);
}
/**
* 用户状态修改
*/
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:user:edit")
@PostMapping("/changeStatus")
@ResponseBody
public AjaxResult changeStatus(SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
return toAjax(userService.changeStatus(user));
}
/**
* 加载部门列表树
*/
@RequiresPermissions("system:user:list")
@GetMapping("/deptTreeData")
@ResponseBody
public List<Ztree> deptTreeData()
{
List<Ztree> ztrees = deptService.selectDeptTree(new SysDept());
return ztrees;
}
/**
* 选择部门树
*
* @param deptId 部门ID
*/
@RequiresPermissions("system:user:list")
@GetMapping("/selectDeptTree/{deptId}")
public String selectDeptTree(@PathVariable("deptId") Long deptId, ModelMap mmap)
{
mmap.put("dept", deptService.selectDeptById(deptId));
return prefix + "/deptTree";
}
}
}

View File

@ -1,26 +0,0 @@
package com.ruoyi.web.controller.tool;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.core.controller.BaseController;
/**
* build 表单构建
*
* @author ruoyi
*/
@Controller
@RequestMapping("/tool/build")
public class BuildController extends BaseController
{
private String prefix = "tool/build";
@RequiresPermissions("tool:build:view")
@GetMapping()
public String build()
{
return prefix + "/build";
}
}

View File

@ -1,24 +0,0 @@
package com.ruoyi.web.controller.tool;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.core.controller.BaseController;
/**
* swagger 接口
*
* @author ruoyi
*/
@Controller
@RequestMapping("/tool/swagger")
public class SwaggerController extends BaseController
{
@RequiresPermissions("tool:swagger:view")
@GetMapping()
public String index()
{
return redirect("/swagger-ui/index.html");
}
}

View File

@ -1,16 +1,25 @@
package com.ruoyi.web.core.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.config.RuoYiConfig;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
/**
@ -21,10 +30,18 @@ import springfox.documentation.spring.web.plugins.Docket;
@Configuration
public class SwaggerConfig
{
/** 系统基础配置 */
@Autowired
private RuoYiConfig ruoyiConfig;
/** 是否开启swagger */
@Value("${swagger.enabled}")
private boolean enabled;
/** 设置请求的统一前缀 */
@Value("${swagger.pathMapping}")
private String pathMapping;
/**
* 创建API
*/
@ -41,10 +58,51 @@ public class SwaggerConfig
// 扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// 扫描指定包中的swagger注解
//.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
// .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
// 扫描所有 .apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
.build()
/* 设置安全模式swagger可以设置访问token */
.securitySchemes(securitySchemes())
.securityContexts(securityContexts())
.pathMapping(pathMapping);
}
/**
* 安全模式这里指定token通过Authorization头请求头传递
*/
private List<SecurityScheme> securitySchemes()
{
List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
return apiKeyList;
}
/**
* 安全上下文
*/
private List<SecurityContext> securityContexts()
{
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(
SecurityContext.builder()
.securityReferences(defaultAuth())
.operationSelector(o -> o.requestMappingPattern().matches("/.*"))
.build());
return securityContexts;
}
/**
* 默认的安全上引用
*/
private List<SecurityReference> defaultAuth()
{
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
/**
@ -59,9 +117,9 @@ public class SwaggerConfig
// 描述
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
// 作者信息
.contact(new Contact(RuoYiConfig.getName(), null, null))
.contact(new Contact(ruoyiConfig.getName(), null, null))
// 版本
.version("版本号:" + RuoYiConfig.getVersion())
.version("版本号:" + ruoyiConfig.getVersion())
.build();
}
}

View File

@ -0,0 +1 @@
restart.include.json=/com.alibaba.fastjson2.*.jar

View File

@ -6,7 +6,7 @@ spring:
druid:
# 主库数据源
master:
url: jdbc:mysql://localhost:3306/ry?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: password
# 从库数据源
@ -24,6 +24,10 @@ spring:
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒

View File

@ -3,20 +3,20 @@ ruoyi:
# 名称
name: RuoYi
# 版本
version: 4.7.6
version: 3.8.7
# 版权年份
copyrightYear: 2022
# 实例演示开关
demoEnabled: true
copyrightYear: 2024
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
profile: D:/ruoyi/uploadPath
# 获取ip地址开关
addressEnabled: false
# 验证码类型 math 数字计算 char 字符验证
captchaType: math
# 开发环境配置
server:
# 服务器的HTTP端口默认为80
port: 80
# 服务器的HTTP端口默认为8080
port: 8080
servlet:
# 应用的访问路径
context-path: /
@ -30,7 +30,7 @@ server:
max: 800
# Tomcat启动初始化的线程数默认值10
min-spare: 100
# 日志配置
logging:
level:
@ -40,103 +40,90 @@ logging:
# 用户配置
user:
password:
# 密码错误{maxRetryCount}次锁定10分钟
# 密码最大错误次数
maxRetryCount: 5
# 密码锁定时间默认10分钟
lockTime: 10
# Spring配置
spring:
# 模板引擎
thymeleaf:
mode: HTML
encoding: utf-8
# 禁用缓存
cache: false
# 资源信息
messages:
# 国际化资源文件路径
basename: static/i18n/messages
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
profiles:
basename: i18n/messages
profiles:
active: druid
# 文件上传
servlet:
multipart:
# 单个文件大小
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
multipart:
# 单个文件大小
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
# redis 配置
redis:
# 地址
host: localhost
# 端口默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password:
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# MyBatis
# token配置
token:
# 令牌自定义标识
header: Authorization
# 令牌密钥
secret: abcdefghijklmnopqrstuvwxyz
# 令牌有效期默认30分钟
expireTime: 30
# MyBatis配置
mybatis:
# 搜索指定包别名
typeAliasesPackage: com.ruoyi.**.domain
# 配置mapper的扫描找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
# 搜索指定包别名
typeAliasesPackage: com.ruoyi.**.domain
# 配置mapper的扫描找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件
pagehelper:
pagehelper:
helperDialect: mysql
supportMethodsArguments: true
params: count=countSql
# Shiro
shiro:
user:
# 登录地址
loginUrl: /login
# 权限认证失败地址
unauthorizedUrl: /unauth
# 首页地址
indexUrl: /index
# 验证码开关
captchaEnabled: true
# 验证码类型 math 数组计算 char 字符
captchaType: math
cookie:
# 设置Cookie的域名 默认空,即当前访问的域名
domain:
# 设置cookie的有效访问路径
path: /
# 设置HttpOnly属性
httpOnly: true
# 设置Cookie的过期时间天为单位
maxAge: 30
# 设置密钥务必保持唯一性生成方式直接拷贝到main运行即可Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) 默认启动生成随机秘钥随机秘钥会导致之前客户端RememberMe Cookie无效如设置固定秘钥RememberMe Cookie则有效
cipherKey:
session:
# Session超时时间-1代表永不过期默认30分钟
expireTime: 30
# 同步session到数据库的周期默认1分钟
dbSyncPeriod: 1
# 相隔多久检查一次session的有效性默认就是10分钟
validationInterval: 10
# 同一个用户最大会话数比如2的意思是同一个账号允许最多同时两个人登录默认-1不限制
maxSession: -1
# 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
kickoutAfter: false
rememberMe:
# 是否开启记住我
enabled: true
# 防止XSS攻击
xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
excludes: /system/notice/*
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
params: count=countSql
# Swagger配置
swagger:
# 是否开启swagger
enabled: true
# 请求前缀
pathMapping: /dev-api
# 防止XSS攻击
xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
excludes: /system/notice
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*

View File

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="ruoyi" updateCheck="false">
<!-- 磁盘缓存位置 -->
<diskStore path="java.io.tmpdir"/>
<!-- maxEntriesLocalHeap:堆内存中最大缓存对象数0没有限制 -->
<!-- maxElementsInMemory 在内存中缓存的element的最大数目。-->
<!-- eternal:elements是否永久有效如果为truetimeouts将被忽略element将永不过期 -->
<!-- timeToIdleSeconds:失效前的空闲秒数当eternal为false时这个属性才有效0为不限制 -->
<!-- timeToLiveSeconds:失效前的存活秒数创建时间到失效时间的间隔为存活时间当eternal为false时这个属性才有效0为不限制 -->
<!-- overflowToDisk 如果内存中数据超过内存限制,是否要缓存到磁盘上 -->
<!-- statistics是否收集统计信息。如果需要监控缓存使用情况应该打开这个选项。默认为关闭统计会影响性能。设置statistics="true"开启统计 -->
<!-- 默认缓存 -->
<defaultCache
maxEntriesLocalHeap="1000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="false">
</defaultCache>
<!-- 登录记录缓存 锁定10分钟 -->
<cache name="loginRecordCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="false">
</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>

View File

@ -1,13 +1,15 @@
#错误消息
not.null=* 必须填写
user.jcaptcha.error=验证码错误
user.jcaptcha.expire=验证码已失效
user.not.exists=用户不存在/密码错误
user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=密码输入错误{0}次
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定10分钟
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
user.password.delete=对不起,您的账号已被删除
user.blocked=用户已封禁,请联系管理员
role.blocked=角色已封禁,请联系管理员
login.blocked=很遗憾访问IP已被列入系统黑名单
user.logout.success=退出成功
length.not.valid=长度必须在{min}到{max}个字符之间

View File

@ -1,20 +1,20 @@
<?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>
<?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>

View File

@ -1,617 +0,0 @@
/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */
/*
The MIT License (MIT)
Copyright (c) 2007-2013 Einar Lielmanis and contributors.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Style HTML
---------------
Written by Nochum Sossonko, (nsossonko@hotmail.com)
Based on code initially developed by: Einar Lielmanis, <elfz@laacz.lv>
http://jsbeautifier.org/
Usage:
style_html(html_source);
style_html(html_source, options);
The options are:
indent_size (default 4) indentation size,
indent_char (default space) character to indent with,
max_char (default 250) - maximum amount of characters per line (0 = disable)
brace_style (default "collapse") - "collapse" | "expand" | "end-expand"
put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line.
unformatted (defaults to inline tags) - list of tags, that shouldn't be reformatted
indent_scripts (default normal) - "keep"|"separate"|"normal"
e.g.
style_html(html_source, {
'indent_size': 2,
'indent_char': ' ',
'max_char': 78,
'brace_style': 'expand',
'unformatted': ['a', 'sub', 'sup', 'b', 'i', 'u']
});
*/
(function() {
function style_html(html_source, options, js_beautify, css_beautify) {
//Wrapper function to invoke all the necessary constructors and deal with the output.
var multi_parser,
indent_size,
indent_character,
max_char,
brace_style,
unformatted;
options = options || {};
indent_size = options.indent_size || 4;
indent_character = options.indent_char || ' ';
brace_style = options.brace_style || 'collapse';
max_char = options.max_char === 0 ? Infinity : options.max_char || 250;
unformatted = options.unformatted || ['a', 'span', 'bdo', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'sub', 'sup', 'tt', 'i', 'b', 'big', 'small', 'u', 's', 'strike', 'font', 'ins', 'del', 'pre', 'address', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
function Parser() {
this.pos = 0; //Parser position
this.token = '';
this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT
this.tags = { //An object to hold tags, their position, and their parent-tags, initiated with default values
parent: 'parent1',
parentcount: 1,
parent1: ''
};
this.tag_type = '';
this.token_text = this.last_token = this.last_text = this.token_type = '';
this.Utils = { //Uilities made available to the various functions
whitespace: "\n\r\t ".split(''),
single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed,?php,?,?='.split(','), //all the single tags for HTML
extra_liners: 'head,body,/html'.split(','), //for tags that need a line of whitespace before them
in_array: function (what, arr) {
for (var i=0; i<arr.length; i++) {
if (what === arr[i]) {
return true;
}
}
return false;
}
};
this.get_content = function () { //function to capture regular content between tags
var input_char = '',
content = [],
space = false; //if a space is needed
while (this.input.charAt(this.pos) !== '<') {
if (this.pos >= this.input.length) {
return content.length?content.join(''):['', 'TK_EOF'];
}
input_char = this.input.charAt(this.pos);
this.pos++;
this.line_char_count++;
if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
if (content.length) {
space = true;
}
this.line_char_count--;
continue; //don't want to insert unnecessary space
}
else if (space) {
if (this.line_char_count >= this.max_char) { //insert a line when the max_char is reached
content.push('\n');
for (var i=0; i<this.indent_level; i++) {
content.push(this.indent_string);
}
this.line_char_count = 0;
}
else{
content.push(' ');
this.line_char_count++;
}
space = false;
}
content.push(input_char); //letter at-a-time (or string) inserted to an array
}
return content.length?content.join(''):'';
};
this.get_contents_to = function (name) { //get the full content of a script or style to pass to js_beautify
if (this.pos === this.input.length) {
return ['', 'TK_EOF'];
}
var input_char = '';
var content = '';
var reg_match = new RegExp('</' + name + '\\s*>', 'igm');
reg_match.lastIndex = this.pos;
var reg_array = reg_match.exec(this.input);
var end_script = reg_array?reg_array.index:this.input.length; //absolute end of script
if(this.pos < end_script) { //get everything in between the script tags
content = this.input.substring(this.pos, end_script);
this.pos = end_script;
}
return content;
};
this.record_tag = function (tag){ //function to record a tag and its parent in this.tags Object
if (this.tags[tag + 'count']) { //check for the existence of this tag type
this.tags[tag + 'count']++;
this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
}
else { //otherwise initialize this tag type
this.tags[tag + 'count'] = 1;
this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
}
this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent)
this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1')
};
this.retrieve_tag = function (tag) { //function to retrieve the opening tag to the corresponding closer
if (this.tags[tag + 'count']) { //if the openener is not in the Object we ignore it
var temp_parent = this.tags.parent; //check to see if it's a closable tag.
while (temp_parent) { //till we reach '' (the initial value);
if (tag + this.tags[tag + 'count'] === temp_parent) { //if this is it use it
break;
}
temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree
}
if (temp_parent) { //if we caught something
this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly
this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent
}
delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference...
delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself
if (this.tags[tag + 'count'] === 1) {
delete this.tags[tag + 'count'];
}
else {
this.tags[tag + 'count']--;
}
}
};
this.get_tag = function (peek) { //function to get a full tag and parse its type
var input_char = '',
content = [],
comment = '',
space = false,
tag_start, tag_end,
orig_pos = this.pos,
orig_line_char_count = this.line_char_count;
peek = peek !== undefined ? peek : false;
do {
if (this.pos >= this.input.length) {
if (peek) {
this.pos = orig_pos;
this.line_char_count = orig_line_char_count;
}
return content.length?content.join(''):['', 'TK_EOF'];
}
input_char = this.input.charAt(this.pos);
this.pos++;
this.line_char_count++;
if (this.Utils.in_array(input_char, this.Utils.whitespace)) { //don't want to insert unnecessary space
space = true;
this.line_char_count--;
continue;
}
if (input_char === "'" || input_char === '"') {
if (!content[1] || content[1] !== '!') { //if we're in a comment strings don't get treated specially
input_char += this.get_unformatted(input_char);
space = true;
}
}
if (input_char === '=') { //no space before =
space = false;
}
if (content.length && content[content.length-1] !== '=' && input_char !== '>' && space) {
//no space after = or before >
if (this.line_char_count >= this.max_char) {
this.print_newline(false, content);
this.line_char_count = 0;
}
else {
content.push(' ');
this.line_char_count++;
}
space = false;
}
if (input_char === '<') {
tag_start = this.pos - 1;
}
content.push(input_char); //inserts character at-a-time (or string)
} while (input_char !== '>');
var tag_complete = content.join('');
var tag_index;
if (tag_complete.indexOf(' ') !== -1) { //if there's whitespace, thats where the tag name ends
tag_index = tag_complete.indexOf(' ');
}
else { //otherwise go with the tag ending
tag_index = tag_complete.indexOf('>');
}
var tag_check = tag_complete.substring(1, tag_index).toLowerCase();
if (tag_complete.charAt(tag_complete.length-2) === '/' ||
this.Utils.in_array(tag_check, this.Utils.single_token)) { //if this tag name is a single tag type (either in the list or has a closing /)
if ( ! peek) {
this.tag_type = 'SINGLE';
}
}
else if (tag_check === 'script') { //for later script handling
if ( ! peek) {
this.record_tag(tag_check);
this.tag_type = 'SCRIPT';
}
}
else if (tag_check === 'style') { //for future style handling (for now it justs uses get_content)
if ( ! peek) {
this.record_tag(tag_check);
this.tag_type = 'STYLE';
}
}
else if (this.is_unformatted(tag_check, unformatted)) { // do not reformat the "unformatted" tags
comment = this.get_unformatted('</'+tag_check+'>', tag_complete); //...delegate to get_unformatted function
content.push(comment);
// Preserve collapsed whitespace either before or after this tag.
if (tag_start > 0 && this.Utils.in_array(this.input.charAt(tag_start - 1), this.Utils.whitespace)){
content.splice(0, 0, this.input.charAt(tag_start - 1));
}
tag_end = this.pos - 1;
if (this.Utils.in_array(this.input.charAt(tag_end + 1), this.Utils.whitespace)){
content.push(this.input.charAt(tag_end + 1));
}
this.tag_type = 'SINGLE';
}
else if (tag_check.charAt(0) === '!') { //peek for <!-- comment
if (tag_check.indexOf('[if') !== -1) { //peek for <!--[if conditional comment
if (tag_complete.indexOf('!IE') !== -1) { //this type needs a closing --> so...
comment = this.get_unformatted('-->', tag_complete); //...delegate to get_unformatted
content.push(comment);
}
if ( ! peek) {
this.tag_type = 'START';
}
}
else if (tag_check.indexOf('[endif') !== -1) {//peek for <!--[endif end conditional comment
this.tag_type = 'END';
this.unindent();
}
else if (tag_check.indexOf('[cdata[') !== -1) { //if it's a <[cdata[ comment...
comment = this.get_unformatted(']]>', tag_complete); //...delegate to get_unformatted function
content.push(comment);
if ( ! peek) {
this.tag_type = 'SINGLE'; //<![CDATA[ comments are treated like single tags
}
}
else {
comment = this.get_unformatted('-->', tag_complete);
content.push(comment);
this.tag_type = 'SINGLE';
}
}
else if ( ! peek) {
if (tag_check.charAt(0) === '/') { //this tag is a double tag so check for tag-ending
this.retrieve_tag(tag_check.substring(1)); //remove it and all ancestors
this.tag_type = 'END';
}
else { //otherwise it's a start-tag
this.record_tag(tag_check); //push it on the tag stack
this.tag_type = 'START';
}
if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) { //check if this double needs an extra line
this.print_newline(true, this.output);
}
}
if (peek) {
this.pos = orig_pos;
this.line_char_count = orig_line_char_count;
}
return content.join(''); //returns fully formatted tag
};
this.get_unformatted = function (delimiter, orig_tag) { //function to return unformatted content in its entirety
if (orig_tag && orig_tag.toLowerCase().indexOf(delimiter) !== -1) {
return '';
}
var input_char = '';
var content = '';
var space = true;
do {
if (this.pos >= this.input.length) {
return content;
}
input_char = this.input.charAt(this.pos);
this.pos++;
if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
if (!space) {
this.line_char_count--;
continue;
}
if (input_char === '\n' || input_char === '\r') {
content += '\n';
/* Don't change tab indention for unformatted blocks. If using code for html editing, this will greatly affect <pre> tags if they are specified in the 'unformatted array'
for (var i=0; i<this.indent_level; i++) {
content += this.indent_string;
}
space = false; //...and make sure other indentation is erased
*/
this.line_char_count = 0;
continue;
}
}
content += input_char;
this.line_char_count++;
space = true;
} while (content.toLowerCase().indexOf(delimiter) === -1);
return content;
};
this.get_token = function () { //initial handler for token-retrieval
var token;
if (this.last_token === 'TK_TAG_SCRIPT' || this.last_token === 'TK_TAG_STYLE') { //check if we need to format javascript
var type = this.last_token.substr(7);
token = this.get_contents_to(type);
if (typeof token !== 'string') {
return token;
}
return [token, 'TK_' + type];
}
if (this.current_mode === 'CONTENT') {
token = this.get_content();
if (typeof token !== 'string') {
return token;
}
else {
return [token, 'TK_CONTENT'];
}
}
if (this.current_mode === 'TAG') {
token = this.get_tag();
if (typeof token !== 'string') {
return token;
}
else {
var tag_name_type = 'TK_TAG_' + this.tag_type;
return [token, tag_name_type];
}
}
};
this.get_full_indent = function (level) {
level = this.indent_level + level || 0;
if (level < 1) {
return '';
}
return Array(level + 1).join(this.indent_string);
};
this.is_unformatted = function(tag_check, unformatted) {
//is this an HTML5 block-level link?
if (!this.Utils.in_array(tag_check, unformatted)){
return false;
}
if (tag_check.toLowerCase() !== 'a' || !this.Utils.in_array('a', unformatted)){
return true;
}
//at this point we have an tag; is its first child something we want to remain
//unformatted?
var next_tag = this.get_tag(true /* peek. */);
// tets next_tag to see if it is just html tag (no external content)
var tag = (next_tag || "").match(/^\s*<\s*\/?([a-z]*)\s*[^>]*>\s*$/);
// if next_tag comes back but is not an isolated tag, then
// let's treat the 'a' tag as having content
// and respect the unformatted option
if (!tag || this.Utils.in_array(tag, unformatted)){
return true;
} else {
return false;
}
};
this.printer = function (js_source, indent_character, indent_size, max_char, brace_style) { //handles input/output and some other printing functions
this.input = js_source || ''; //gets the input for the Parser
this.output = [];
this.indent_character = indent_character;
this.indent_string = '';
this.indent_size = indent_size;
this.brace_style = brace_style;
this.indent_level = 0;
this.max_char = max_char;
this.line_char_count = 0; //count to see if max_char was exceeded
for (var i=0; i<this.indent_size; i++) {
this.indent_string += this.indent_character;
}
this.print_newline = function (ignore, arr) {
this.line_char_count = 0;
if (!arr || !arr.length) {
return;
}
if (!ignore) { //we might want the extra line
while (this.Utils.in_array(arr[arr.length-1], this.Utils.whitespace)) {
arr.pop();
}
}
arr.push('\n');
for (var i=0; i<this.indent_level; i++) {
arr.push(this.indent_string);
}
};
this.print_token = function (text) {
this.output.push(text);
};
this.indent = function () {
this.indent_level++;
};
this.unindent = function () {
if (this.indent_level > 0) {
this.indent_level--;
}
};
};
return this;
}
/*_____________________--------------------_____________________*/
multi_parser = new Parser(); //wrapping functions Parser
multi_parser.printer(html_source, indent_character, indent_size, max_char, brace_style); //initialize starting values
while (true) {
var t = multi_parser.get_token();
multi_parser.token_text = t[0];
multi_parser.token_type = t[1];
if (multi_parser.token_type === 'TK_EOF') {
break;
}
switch (multi_parser.token_type) {
case 'TK_TAG_START':
multi_parser.print_newline(false, multi_parser.output);
multi_parser.print_token(multi_parser.token_text);
multi_parser.indent();
multi_parser.current_mode = 'CONTENT';
break;
case 'TK_TAG_STYLE':
case 'TK_TAG_SCRIPT':
multi_parser.print_newline(false, multi_parser.output);
multi_parser.print_token(multi_parser.token_text);
multi_parser.current_mode = 'CONTENT';
break;
case 'TK_TAG_END':
//Print new line only if the tag has no content and has child
if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '') {
var tag_name = multi_parser.token_text.match(/\w+/)[0];
var tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length -1].match(/<\s*(\w+)/);
if (tag_extracted_from_last_output === null || tag_extracted_from_last_output[1] !== tag_name) {
multi_parser.print_newline(true, multi_parser.output);
}
}
multi_parser.print_token(multi_parser.token_text);
multi_parser.current_mode = 'CONTENT';
break;
case 'TK_TAG_SINGLE':
// Don't add a newline before elements that should remain unformatted.
var tag_check = multi_parser.token_text.match(/^\s*<([a-z]+)/i);
if (!tag_check || !multi_parser.Utils.in_array(tag_check[1], unformatted)){
multi_parser.print_newline(false, multi_parser.output);
}
multi_parser.print_token(multi_parser.token_text);
multi_parser.current_mode = 'CONTENT';
break;
case 'TK_CONTENT':
if (multi_parser.token_text !== '') {
multi_parser.print_token(multi_parser.token_text);
}
multi_parser.current_mode = 'TAG';
break;
case 'TK_STYLE':
case 'TK_SCRIPT':
if (multi_parser.token_text !== '') {
multi_parser.output.push('\n');
var text = multi_parser.token_text,
_beautifier,
script_indent_level = 1;
if (multi_parser.token_type === 'TK_SCRIPT') {
_beautifier = typeof js_beautify === 'function' && js_beautify;
} else if (multi_parser.token_type === 'TK_STYLE') {
_beautifier = typeof css_beautify === 'function' && css_beautify;
}
if (options.indent_scripts === "keep") {
script_indent_level = 0;
} else if (options.indent_scripts === "separate") {
script_indent_level = -multi_parser.indent_level;
}
var indentation = multi_parser.get_full_indent(script_indent_level);
if (_beautifier) {
// call the Beautifier if avaliable
text = _beautifier(text.replace(/^\s*/, indentation), options);
} else {
// simply indent the string otherwise
var white = text.match(/^\s*/)[0];
var _level = white.match(/[^\n\r]*$/)[0].split(multi_parser.indent_string).length - 1;
var reindent = multi_parser.get_full_indent(script_indent_level -_level);
text = text.replace(/^\s*/, indentation)
.replace(/\r\n|\r|\n/g, '\n' + reindent)
.replace(/\s*$/, '');
}
if (text) {
multi_parser.print_token(text);
multi_parser.print_newline(true, multi_parser.output);
}
}
multi_parser.current_mode = 'TAG';
break;
}
multi_parser.last_token = multi_parser.token_type;
multi_parser.last_text = multi_parser.token_text;
}
return multi_parser.output.join('');
}
// If we're running a web page and don't have either of the above, add our one global
window.html_beautify = function(html_source, options) {
return style_html(html_source, options, window.js_beautify, window.css_beautify);
};
}());

View File

@ -1,620 +0,0 @@
/*!
* jQuery blockUI plugin
* Version 2.70.0-2014.11.23
* Requires jQuery v1.7 or later
*
* Examples at: http://malsup.com/jquery/block/
* Copyright (c) 2007-2013 M. Alsup
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Thanks to Amir-Hossein Sobhi for some excellent contributions!
*/
;(function() {
/*jshint eqeqeq:false curly:false latedef:false */
"use strict";
function setup($) {
$.fn._fadeIn = $.fn.fadeIn;
var noOp = $.noop || function() {};
// this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
// confusing userAgent strings on Vista)
var msie = /MSIE/.test(navigator.userAgent);
var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
var mode = document.documentMode || 0;
var setExpr = $.isFunction( document.createElement('div').style.setExpression );
// global $ methods for blocking/unblocking the entire page
$.blockUI = function(opts) { install(window, opts); };
$.unblockUI = function(opts) { remove(window, opts); };
// convenience method for quick growl-like notifications (http://www.google.com/search?q=growl)
$.growlUI = function(title, message, timeout, onClose) {
var $m = $('<div class="growlUI"></div>');
if (title) $m.append('<h1>'+title+'</h1>');
if (message) $m.append('<h2>'+message+'</h2>');
if (timeout === undefined) timeout = 3000;
// Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
var callBlock = function(opts) {
opts = opts || {};
$.blockUI({
message: $m,
fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700,
fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
centerY: false,
showOverlay: false,
onUnblock: onClose,
css: $.blockUI.defaults.growlCSS
});
};
callBlock();
var nonmousedOpacity = $m.css('opacity');
$m.mouseover(function() {
callBlock({
fadeIn: 0,
timeout: 30000
});
var displayBlock = $('.blockMsg');
displayBlock.stop(); // cancel fadeout if it has started
displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
}).mouseout(function() {
$('.blockMsg').fadeOut(1000);
});
// End konapun additions
};
// plugin method for blocking element content
$.fn.block = function(opts) {
if ( this[0] === window ) {
$.blockUI( opts );
return this;
}
var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
this.each(function() {
var $el = $(this);
if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
return;
$el.unblock({ fadeOut: 0 });
});
return this.each(function() {
if ($.css(this,'position') == 'static') {
this.style.position = 'relative';
$(this).data('blockUI.static', true);
}
this.style.zoom = 1; // force 'hasLayout' in ie
install(this, opts);
});
};
// plugin method for unblocking element content
$.fn.unblock = function(opts) {
if ( this[0] === window ) {
$.unblockUI( opts );
return this;
}
return this.each(function() {
remove(this, opts);
});
};
$.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
// override these in your code to change the default behavior and style
$.blockUI.defaults = {
// message displayed when blocking (use null for no message)
message: '<div class="loaderbox"><div class="loading-activity"></div> 加载中......</div>',
title: null, // title string; only used when theme == true
draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded)
theme: false, // set to true to use with jQuery UI themes
// styles for the message when blocking; if you wish to disable
// these and use an external stylesheet then do this in your code:
// $.blockUI.defaults.css = {};
css: {
padding: 0,
margin: 0,
width: '30%',
top: '40%',
left: '35%',
textAlign: 'center',
color: '#000',
border: '0px',
backgroundColor:'transparent',
cursor: 'wait'
},
// minimal style set used when themes are used
themedCSS: {
width: '30%',
top: '40%',
left: '35%'
},
// styles for the overlay
overlayCSS: {
backgroundColor: '#000',
opacity: 0.6,
cursor: 'wait'
},
// style to replace wait cursor before unblocking to correct issue
// of lingering wait cursor
cursorReset: 'default',
// styles applied when using $.growlUI
growlCSS: {
width: '350px',
top: '10px',
left: '',
right: '10px',
border: 'none',
padding: '5px',
opacity: 0.6,
cursor: 'default',
color: '#fff',
backgroundColor: '#000',
'-webkit-border-radius':'10px',
'-moz-border-radius': '10px',
'border-radius': '10px'
},
// IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
// (hat tip to Jorge H. N. de Vasconcelos)
/*jshint scripturl:true */
iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
// force usage of iframe in non-IE browsers (handy for blocking applets)
forceIframe: false,
// z-index for the blocking overlay
baseZ: 1000,
// set these to true to have the message automatically centered
centerX: true, // <-- only effects element blocking (page block controlled via css above)
centerY: true,
// allow body element to be stetched in ie6; this makes blocking look better
// on "short" pages. disable if you wish to prevent changes to the body height
allowBodyStretch: true,
// enable if you want key and mouse events to be disabled for content that is blocked
bindEvents: true,
// be default blockUI will supress tab navigation from leaving blocking content
// (if bindEvents is true)
constrainTabKey: true,
// fadeIn time in millis; set to 0 to disable fadeIn on block
fadeIn: 200,
// fadeOut time in millis; set to 0 to disable fadeOut on unblock
fadeOut: 400,
// time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
timeout: 0,
// disable if you don't want to show the overlay
showOverlay: true,
// if true, focus will be placed in the first available input field when
// page blocking
focusInput: true,
// elements that can receive focus
focusableElements: ':input:enabled:visible',
// suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
// no longer needed in 2012
// applyPlatformOpacityRules: true,
// callback method invoked when fadeIn has completed and blocking message is visible
onBlock: null,
// callback method invoked when unblocking has completed; the callback is
// passed the element that has been unblocked (which is the window object for page
// blocks) and the options that were passed to the unblock call:
// onUnblock(element, options)
onUnblock: null,
// callback method invoked when the overlay area is clicked.
// setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
onOverlayClick: null,
// don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
quirksmodeOffsetHack: 4,
// class name of the message block
blockMsgClass: 'blockMsg',
// if it is already blocked, then ignore it (don't unblock and reblock)
ignoreIfBlocked: false
};
// private data and functions follow...
var pageBlock = null;
var pageBlockEls = [];
function install(el, opts) {
var css, themedCSS;
var full = (el == window);
var msg = (opts && opts.message !== undefined ? opts.message : undefined);
opts = $.extend({}, $.blockUI.defaults, opts || {});
if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
return;
opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
if (opts.onOverlayClick)
opts.overlayCSS.cursor = 'pointer';
themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
msg = msg === undefined ? opts.message : msg;
// remove the current block (if there is one)
if (full && pageBlock)
remove(window, {fadeOut:0});
// if an existing element is being used as the blocking content then we capture
// its current place in the DOM (and current display style) so we can restore
// it when we unblock
if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
var node = msg.jquery ? msg[0] : msg;
var data = {};
$(el).data('blockUI.history', data);
data.el = node;
data.parent = node.parentNode;
data.display = node.style.display;
data.position = node.style.position;
if (data.parent)
data.parent.removeChild(node);
}
$(el).data('blockUI.onUnblock', opts.onUnblock);
var z = opts.baseZ;
// blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
// layer1 is the iframe layer which is used to supress bleed through of underlying content
// layer2 is the overlay layer which has opacity and a wait cursor (by default)
// layer3 is the message content that is displayed while blocking
var lyr1, lyr2, lyr3, s;
if (msie || opts.forceIframe)
lyr1 = $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>');
else
lyr1 = $('<div class="blockUI" style="display:none"></div>');
if (opts.theme)
lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
else
lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
if (opts.theme && full) {
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
if ( opts.title ) {
s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
}
s += '<div class="ui-widget-content ui-dialog-content"></div>';
s += '</div>';
}
else if (opts.theme) {
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
if ( opts.title ) {
s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
}
s += '<div class="ui-widget-content ui-dialog-content"></div>';
s += '</div>';
}
else if (full) {
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
}
else {
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
}
lyr3 = $(s);
// if we have a message, style it
if (msg) {
if (opts.theme) {
lyr3.css(themedCSS);
lyr3.addClass('ui-widget-content');
}
else
lyr3.css(css);
}
// style the overlay
if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
lyr2.css(opts.overlayCSS);
lyr2.css('position', full ? 'fixed' : 'absolute');
// make iframe layer transparent in IE
if (msie || opts.forceIframe)
lyr1.css('opacity',0.0);
//$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
$.each(layers, function() {
this.appendTo($par);
});
if (opts.theme && opts.draggable && $.fn.draggable) {
lyr3.draggable({
handle: '.ui-dialog-titlebar',
cancel: 'li'
});
}
// ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
if (ie6 || expr) {
// give body 100% height
if (full && opts.allowBodyStretch && $.support.boxModel)
$('html,body').css('height','100%');
// fix ie6 issue when blocked element has a border width
if ((ie6 || !$.support.boxModel) && !full) {
var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
var fixT = t ? '(0 - '+t+')' : 0;
var fixL = l ? '(0 - '+l+')' : 0;
}
// simulate fixed position
$.each(layers, function(i,o) {
var s = o[0].style;
s.position = 'absolute';
if (i < 2) {
if (full)
s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
else
s.setExpression('height','this.parentNode.offsetHeight + "px"');
if (full)
s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
else
s.setExpression('width','this.parentNode.offsetWidth + "px"');
if (fixL) s.setExpression('left', fixL);
if (fixT) s.setExpression('top', fixT);
}
else if (opts.centerY) {
if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
s.marginTop = 0;
}
else if (!opts.centerY && full) {
var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
s.setExpression('top',expression);
}
});
}
// show the message
if (msg) {
if (opts.theme)
lyr3.find('.ui-widget-content').append(msg);
else
lyr3.append(msg);
if (msg.jquery || msg.nodeType)
$(msg).show();
}
if ((msie || opts.forceIframe) && opts.showOverlay)
lyr1.show(); // opacity is zero
if (opts.fadeIn) {
var cb = opts.onBlock ? opts.onBlock : noOp;
var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
var cb2 = msg ? cb : noOp;
if (opts.showOverlay)
lyr2._fadeIn(opts.fadeIn, cb1);
if (msg)
lyr3._fadeIn(opts.fadeIn, cb2);
}
else {
if (opts.showOverlay)
lyr2.show();
if (msg)
lyr3.show();
if (opts.onBlock)
opts.onBlock.bind(lyr3)();
}
// bind key and mouse events
bind(1, el, opts);
if (full) {
pageBlock = lyr3[0];
pageBlockEls = $(opts.focusableElements,pageBlock);
if (opts.focusInput)
setTimeout(focus, 20);
}
else
center(lyr3[0], opts.centerX, opts.centerY);
if (opts.timeout) {
// auto-unblock
var to = setTimeout(function() {
if (full)
$.unblockUI(opts);
else
$(el).unblock(opts);
}, opts.timeout);
$(el).data('blockUI.timeout', to);
}
}
// remove the block
function remove(el, opts) {
var count;
var full = (el == window);
var $el = $(el);
var data = $el.data('blockUI.history');
var to = $el.data('blockUI.timeout');
if (to) {
clearTimeout(to);
$el.removeData('blockUI.timeout');
}
opts = $.extend({}, $.blockUI.defaults, opts || {});
bind(0, el, opts); // unbind events
if (opts.onUnblock === null) {
opts.onUnblock = $el.data('blockUI.onUnblock');
$el.removeData('blockUI.onUnblock');
}
var els;
if (full) // crazy selector to handle odd field errors in ie6/7
els = $('body').children().filter('.blockUI').add('body > .blockUI');
else
els = $el.find('>.blockUI');
// fix cursor issue
if ( opts.cursorReset ) {
if ( els.length > 1 )
els[1].style.cursor = opts.cursorReset;
if ( els.length > 2 )
els[2].style.cursor = opts.cursorReset;
}
if (full)
pageBlock = pageBlockEls = null;
if (opts.fadeOut) {
count = els.length;
els.stop().fadeOut(opts.fadeOut, function() {
if ( --count === 0)
reset(els,data,opts,el);
});
}
else
reset(els, data, opts, el);
}
// move blocking element back into the DOM where it started
function reset(els,data,opts,el) {
var $el = $(el);
if ( $el.data('blockUI.isBlocked') )
return;
els.each(function(i,o) {
// remove via DOM calls so we don't lose event handlers
if (this.parentNode)
this.parentNode.removeChild(this);
});
if (data && data.el) {
data.el.style.display = data.display;
data.el.style.position = data.position;
data.el.style.cursor = 'default'; // #59
if (data.parent)
data.parent.appendChild(data.el);
$el.removeData('blockUI.history');
}
if ($el.data('blockUI.static')) {
$el.css('position', 'static'); // #22
}
if (typeof opts.onUnblock == 'function')
opts.onUnblock(el,opts);
// fix issue in Safari 6 where block artifacts remain until reflow
var body = $(document.body), w = body.width(), cssW = body[0].style.width;
body.width(w-1).width(w);
body[0].style.width = cssW;
}
// bind/unbind the handler
function bind(b, el, opts) {
var full = el == window, $el = $(el);
// don't bother unbinding if there is nothing to unbind
if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
return;
$el.data('blockUI.isBlocked', b);
// don't bind events when overlay is not in use or if bindEvents is false
if (!full || !opts.bindEvents || (b && !opts.showOverlay))
return;
// bind anchors and inputs for mouse and key events
var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
if (b)
$(document).bind(events, opts, handler);
else
$(document).unbind(events, handler);
// former impl...
// var $e = $('a,:input');
// b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
}
// event handler to suppress keyboard/mouse events when blocking
function handler(e) {
// allow tab navigation (conditionally)
if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
if (pageBlock && e.data.constrainTabKey) {
var els = pageBlockEls;
var fwd = !e.shiftKey && e.target === els[els.length-1];
var back = e.shiftKey && e.target === els[0];
if (fwd || back) {
setTimeout(function(){focus(back);},10);
return false;
}
}
}
var opts = e.data;
var target = $(e.target);
if (target.hasClass('blockOverlay') && opts.onOverlayClick)
opts.onOverlayClick(e);
// allow events within the message content
if (target.parents('div.' + opts.blockMsgClass).length > 0)
return true;
// allow events for content that is not being blocked
return target.parents().children().filter('div.blockUI').length === 0;
}
function focus(back) {
if (!pageBlockEls)
return;
var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
if (e)
e.focus();
}
function center(el, x, y) {
var p = el.parentNode, s = el.style;
var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
if (x) s.left = l > 0 ? (l+'px') : '0';
if (y) s.top = t > 0 ? (t+'px') : '0';
}
function sz(el, p) {
return parseInt($.css(el,p),10)||0;
}
}
/*global define:true */
if (typeof define === 'function' && define.amd && define.amd.jQuery) {
define(['jquery'], setup);
} else {
setup(jQuery);
}
})();

View File

@ -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 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

View File

@ -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 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

View File

@ -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)
}
}

View File

@ -1,405 +0,0 @@
/**
* @author zhixin wen <wenzhixin2010@gmail.com>
*/
var Utils = $.fn.bootstrapTable.utils
// Reasonable defaults
const PIXEL_STEP = 10
const LINE_HEIGHT = 40
const PAGE_HEIGHT = 800
function normalizeWheel (event) {
let sX = 0 // spinX
let sY = 0 // spinY
let pX = 0 // pixelX
let pY = 0 // pixelY
// Legacy
if ('detail' in event) { sY = event.detail }
if ('wheelDelta' in event) { sY = -event.wheelDelta / 120 }
if ('wheelDeltaY' in event) { sY = -event.wheelDeltaY / 120 }
if ('wheelDeltaX' in event) { sX = -event.wheelDeltaX / 120 }
// side scrolling on FF with DOMMouseScroll
if ('axis' in event && event.axis === event.HORIZONTAL_AXIS) {
sX = sY
sY = 0
}
pX = sX * PIXEL_STEP
pY = sY * PIXEL_STEP
if ('deltaY' in event) { pY = event.deltaY }
if ('deltaX' in event) { pX = event.deltaX }
if ((pX || pY) && event.deltaMode) {
if (event.deltaMode === 1) { // delta in LINE units
pX *= LINE_HEIGHT
pY *= LINE_HEIGHT
} else { // delta in PAGE units
pX *= PAGE_HEIGHT
pY *= PAGE_HEIGHT
}
}
// Fall-back if spin cannot be determined
if (pX && !sX) { sX = (pX < 1) ? -1 : 1 }
if (pY && !sY) { sY = (pY < 1) ? -1 : 1 }
return {
spinX: sX,
spinY: sY,
pixelX: pX,
pixelY: pY
}
}
$.extend($.fn.bootstrapTable.defaults, {
fixedColumns: false,
fixedNumber: 0,
fixedRightNumber: 0
})
$.BootstrapTable = class extends $.BootstrapTable {
fixedColumnsSupported () {
return this.options.fixedColumns &&
!this.options.detailView &&
!this.options.cardView
}
initContainer () {
super.initContainer()
if (!this.fixedColumnsSupported()) {
return
}
if (this.options.fixedNumber) {
this.$tableContainer.append('<div class="fixed-columns"></div>')
this.$fixedColumns = this.$tableContainer.find('.fixed-columns')
}
if (this.options.fixedRightNumber) {
this.$tableContainer.append('<div class="fixed-columns-right"></div>')
this.$fixedColumnsRight = this.$tableContainer.find('.fixed-columns-right')
}
}
initBody (...args) {
super.initBody(...args)
if (this.$fixedColumns && this.$fixedColumns.length) {
this.$fixedColumns.toggle(this.fixedColumnsSupported())
}
if (this.$fixedColumnsRight && this.$fixedColumnsRight.length) {
this.$fixedColumnsRight.toggle(this.fixedColumnsSupported())
}
if (!this.fixedColumnsSupported()) {
return
}
if (this.options.showHeader && this.options.height) {
return
}
this.initFixedColumnsBody()
this.initFixedColumnsEvents()
}
trigger (...args) {
super.trigger(...args)
if (!this.fixedColumnsSupported()) {
return
}
if (args[0] === 'post-header') {
this.initFixedColumnsHeader()
} else if (args[0] === 'scroll-body') {
if (this.needFixedColumns && this.options.fixedNumber) {
this.$fixedBody.scrollTop(this.$tableBody.scrollTop())
}
if (this.needFixedColumns && this.options.fixedRightNumber) {
this.$fixedBodyRight.scrollTop(this.$tableBody.scrollTop())
}
}
}
updateSelected () {
super.updateSelected()
if (!this.fixedColumnsSupported()) {
return
}
this.$tableBody.find('tr').each((i, el) => {
const $el = $(el)
const index = $el.data('index')
const classes = $el.attr('class')
const inputSelector = `[name="${this.options.selectItemName}"]`
const $input = $el.find(inputSelector)
if (typeof index === undefined) {
return
}
const updateFixedBody = ($fixedHeader, $fixedBody) => {
const $tr = $fixedBody.find(`tr[data-index="${index}"]`)
$tr.attr('class', classes)
if ($input.length) {
$tr.find(inputSelector).prop('checked', $input.prop('checked'))
}
if (this.$selectAll.length) {
$fixedHeader.add($fixedBody)
.find('[name="btSelectAll"]')
.prop('checked', this.$selectAll.prop('checked'))
}
}
if (this.$fixedBody && this.options.fixedNumber) {
updateFixedBody(this.$fixedHeader, this.$fixedBody)
}
if (this.$fixedBodyRight && this.options.fixedRightNumber) {
updateFixedBody(this.$fixedHeaderRight, this.$fixedBodyRight)
}
})
}
hideLoading () {
super.hideLoading()
if (this.needFixedColumns && this.options.fixedNumber) {
this.$fixedColumns.find('.fixed-table-loading').hide()
}
if (this.needFixedColumns && this.options.fixedRightNumber) {
this.$fixedColumnsRight.find('.fixed-table-loading').hide()
}
}
initFixedColumnsHeader () {
if (this.options.height) {
this.needFixedColumns = this.$tableHeader.outerWidth(true) < this.$tableHeader.find('table').outerWidth(true)
} else {
this.needFixedColumns = this.$tableBody.outerWidth(true) < this.$tableBody.find('table').outerWidth(true)
}
const initFixedHeader = ($fixedColumns, isRight) => {
$fixedColumns.find('.fixed-table-header').remove()
$fixedColumns.append(this.$tableHeader.clone(true))
$fixedColumns.css({
width: this.getFixedColumnsWidth(isRight)
})
return $fixedColumns.find('.fixed-table-header')
}
if (this.needFixedColumns && this.options.fixedNumber) {
this.$fixedHeader = initFixedHeader(this.$fixedColumns)
this.$fixedHeader.css('margin-right', '')
} else if (this.$fixedColumns) {
this.$fixedColumns.html('').css('width', '')
}
if (this.needFixedColumns && this.options.fixedRightNumber) {
this.$fixedHeaderRight = initFixedHeader(this.$fixedColumnsRight, true)
this.$fixedHeaderRight.scrollLeft(this.$fixedHeaderRight.find('table').width())
} else if (this.$fixedColumnsRight) {
this.$fixedColumnsRight.html('').css('width', '')
}
this.initFixedColumnsBody()
this.initFixedColumnsEvents()
}
initFixedColumnsBody () {
const initFixedBody = ($fixedColumns, $fixedHeader) => {
$fixedColumns.find('.fixed-table-body').remove()
$fixedColumns.append(this.$tableBody.clone(true))
$fixedColumns.find('.fixed-table-body table').removeAttr('id')
const $fixedBody = $fixedColumns.find('.fixed-table-body')
const tableBody = this.$tableBody.get(0)
const scrollHeight = tableBody.scrollWidth > tableBody.clientWidth ?
Utils.getScrollBarWidth() : 0
const height = this.$tableContainer.outerHeight(true) - scrollHeight - 1
$fixedColumns.css({
height
})
$fixedBody.css({
height: height - $fixedHeader.height()
})
return $fixedBody
}
if (this.needFixedColumns && this.options.fixedNumber) {
this.$fixedBody = initFixedBody(this.$fixedColumns, this.$fixedHeader)
}
if (this.needFixedColumns && this.options.fixedRightNumber) {
this.$fixedBodyRight = initFixedBody(this.$fixedColumnsRight, this.$fixedHeaderRight)
this.$fixedBodyRight.scrollLeft(this.$fixedBodyRight.find('table').width())
this.$fixedBodyRight.css('overflow-y', this.options.height ? 'auto' : 'hidden')
}
}
getFixedColumnsWidth (isRight) {
let visibleFields = this.getVisibleFields()
let width = 0
let fixedNumber = this.options.fixedNumber
let marginRight = 0
if (isRight) {
visibleFields = visibleFields.reverse()
fixedNumber = this.options.fixedRightNumber
marginRight = parseInt(this.$tableHeader.css('margin-right'), 10)
}
for (let i = 0; i < fixedNumber; i++) {
width += this.$header.find(`th[data-field="${visibleFields[i]}"]`).outerWidth(true)
}
return width + marginRight + 1
}
initFixedColumnsEvents () {
const toggleHover = (e, toggle) => {
const tr = `tr[data-index="${$(e.currentTarget).data('index')}"]`
let $trs = this.$tableBody.find(tr)
if (this.$fixedBody) {
$trs = $trs.add(this.$fixedBody.find(tr))
}
if (this.$fixedBodyRight) {
$trs = $trs.add(this.$fixedBodyRight.find(tr))
}
$trs.css('background-color', toggle ? $(e.currentTarget).css('background-color') : '')
}
this.$tableBody.find('tr').hover(e => {
toggleHover(e, true)
}, e => {
toggleHover(e, false)
})
const isFirefox = typeof navigator !== 'undefined' &&
navigator.userAgent.toLowerCase().indexOf('firefox') > -1
const mousewheel = isFirefox ? 'DOMMouseScroll' : 'mousewheel'
const updateScroll = (e, fixedBody) => {
const normalized = normalizeWheel(e)
const deltaY = Math.ceil(normalized.pixelY)
const top = this.$tableBody.scrollTop() + deltaY
if (
deltaY < 0 && top > 0 ||
deltaY > 0 && top < fixedBody.scrollHeight - fixedBody.clientHeight
) {
e.preventDefault()
}
this.$tableBody.scrollTop(top)
if (this.$fixedBody) {
this.$fixedBody.scrollTop(top)
}
if (this.$fixedBodyRight) {
this.$fixedBodyRight.scrollTop(top)
}
}
if (this.needFixedColumns && this.options.fixedNumber) {
this.$fixedBody.find('tr').hover(e => {
toggleHover(e, true)
}, e => {
toggleHover(e, false)
})
this.$fixedBody[0].addEventListener(mousewheel, e => {
updateScroll(e, this.$fixedBody[0])
})
}
if (this.needFixedColumns && this.options.fixedRightNumber) {
this.$fixedBodyRight.find('tr').hover(e => {
toggleHover(e, true)
}, e => {
toggleHover(e, false)
})
this.$fixedBodyRight.off('scroll').on('scroll', () => {
const top = this.$fixedBodyRight.scrollTop()
this.$tableBody.scrollTop(top)
if (this.$fixedBody) {
this.$fixedBody.scrollTop(top)
}
})
}
if (this.options.filterControl) {
$(this.$fixedColumns).off('keyup change').on('keyup change', e => {
const $target = $(e.target)
const value = $target.val()
const field = $target.parents('th').data('field')
const $coreTh = this.$header.find(`th[data-field="${field}"]`)
if ($target.is('input')) {
$coreTh.find('input').val(value)
} else if ($target.is('select')) {
const $select = $coreTh.find('select')
$select.find('option[selected]').removeAttr('selected')
$select.find(`option[value="${value}"]`).attr('selected', true)
}
this.triggerSearch()
})
}
}
renderStickyHeader () {
if (!this.options.stickyHeader) {
return
}
this.$stickyContainer = this.$container.find('.sticky-header-container')
super.renderStickyHeader()
if (this.needFixedColumns && this.options.fixedNumber) {
this.$fixedColumns.css('z-index', 101)
.find('.sticky-header-container')
.css('right', '')
.width(this.$fixedColumns.outerWidth())
}
if (this.needFixedColumns && this.options.fixedRightNumber) {
const $stickyHeaderContainerRight = this.$fixedColumnsRight.find('.sticky-header-container')
this.$fixedColumnsRight.css('z-index', 101)
$stickyHeaderContainerRight.css('left', '')
.scrollLeft($stickyHeaderContainerRight.find('.table').outerWidth())
.width(this.$fixedColumnsRight.outerWidth())
}
}
matchPositionX () {
if (!this.options.stickyHeader) {
return
}
this.$stickyContainer.eq(0).scrollLeft(this.$tableBody.scrollLeft())
}
}

View File

@ -1,109 +0,0 @@
/**
* @author: Dustin Utecht
* @github: https://github.com/UtechtDustin
*/
var Utils = $.fn.bootstrapTable.utils
$.extend($.fn.bootstrapTable.defaults, {
customView: false,
showCustomView: false,
showCustomViewButton: false
})
$.extend($.fn.bootstrapTable.defaults.icons, {
customView: {
bootstrap3: 'glyphicon glyphicon-eye-open',
bootstrap5: 'bi-eye',
bootstrap4: 'fa fa-eye',
semantic: 'fa fa-eye',
foundation: 'fa fa-eye',
bulma: 'fa fa-eye',
materialize: 'remove_red_eye'
}[$.fn.bootstrapTable.theme] || 'fa-eye'
})
$.extend($.fn.bootstrapTable.defaults, {
onCustomViewPostBody () {
return false
},
onCustomViewPreBody () {
return false
}
})
$.extend($.fn.bootstrapTable.locales, {
formatToggleCustomView () {
return 'Toggle custom view'
}
})
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
$.fn.bootstrapTable.methods.push('toggleCustomView')
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
'custom-view-post-body.bs.table': 'onCustomViewPostBody',
'custom-view-pre-body.bs.table': 'onCustomViewPreBody'
})
$.BootstrapTable = class extends $.BootstrapTable {
init () {
this.showCustomView = this.options.showCustomView
super.init()
}
initToolbar (...args) {
if (this.options.customView && this.options.showCustomViewButton) {
this.buttons = Object.assign(this.buttons, {
customView: {
text: this.options.formatToggleCustomView(),
icon: this.options.icons.customView,
event: this.toggleCustomView,
attributes: {
'aria-label': this.options.formatToggleCustomView(),
title: this.options.formatToggleCustomView()
}
}
})
}
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.showCustomView) {
$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.showCustomView = !this.showCustomView
this.initBody()
}
}

View File

@ -1,663 +0,0 @@
/*! X-editable - v1.5.1
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2013 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 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;
}

View File

@ -1,187 +0,0 @@
/* eslint-disable no-unused-vars */
/**
* @author zhixin wen <wenzhixin2010@gmail.com>
* extensions: https://github.com/vitalets/x-editable
*/
var Utils = $.fn.bootstrapTable.utils
$.extend($.fn.bootstrapTable.defaults, {
editable: true,
onEditableInit () {
return false
},
onEditableSave (field, row, rowIndex, oldValue, $el) {
return false
},
onEditableShown (field, row, $el, editable) {
return false
},
onEditableHidden (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',
'editable-shown.bs.table': 'onEditableShown',
'editable-hidden.bs.table': 'onEditableHidden'
})
$.BootstrapTable = class extends $.BootstrapTable {
initTable () {
super.initTable()
if (!this.options.editable) {
return
}
this.editedCells = []
$.each(this.columns, (i, column) => {
if (!column.editable) {
return
}
const editableOptions = {}
const editableDataMarkup = []
const editableDataPrefix = 'editable-'
const processDataOptions = (key, value) => {
// Replace camel case with dashes.
const dashKey = key.replace(/([A-Z])/g, $1 => `-${$1.toLowerCase()}`)
if (dashKey.indexOf(editableDataPrefix) === 0) {
editableOptions[dashKey.replace(editableDataPrefix, 'data-')] = value
}
}
$.each(this.options, processDataOptions)
column.formatter = column.formatter || (value => value)
column._formatter = column._formatter ? column._formatter : column.formatter
column.formatter = (value, row, index) => {
let result = Utils.calculateObjectValue(column, column._formatter, [value, row, index], value)
result = typeof result === 'undefined' || result === null ? this.options.undefinedText : result
if (this.options.uniqueId !== undefined && !column.alwaysUseFormatter) {
const uniqueId = Utils.getItemField(row, this.options.uniqueId, false)
if ($.inArray(column.field + uniqueId, this.editedCells) !== -1) {
result = value
}
}
$.each(column, processDataOptions)
$.each(editableOptions, (key, value) => {
editableDataMarkup.push(` ${key}="${value}"`)
})
let noEditFormatter = false
const editableOpts = Utils.calculateObjectValue(column,
column.editable, [index, row], {})
if (editableOpts.hasOwnProperty('noEditFormatter')) {
noEditFormatter = editableOpts.noEditFormatter(value, row, index)
}
if (noEditFormatter === false) {
return `<a href="javascript:void(0)"
data-name="${column.field}"
data-pk="${row[this.options.idField]}"
data-value="${result}"
${editableDataMarkup.join('')}></a>`
}
return noEditFormatter
}
})
}
initBody (fixedScroll) {
super.initBody(fixedScroll)
if (!this.options.editable) {
return
}
$.each(this.columns, (i, column) => {
if (!column.editable) {
return
}
const data = this.getData({ escape: true })
const $field = this.$body.find(`a[data-name="${column.field}"]`)
$field.each((i, element) => {
const $element = $(element)
const $tr = $element.closest('tr')
const index = $tr.data('index')
const row = data[index]
const editableOpts = Utils.calculateObjectValue(column,
column.editable, [index, row, $element], {})
$element.editable(editableOpts)
})
$field.off('save').on('save', ({ currentTarget }, { submitValue }) => {
const $this = $(currentTarget)
const data = this.getData()
const rowIndex = $this.parents('tr[data-index]').data('index')
const row = data[rowIndex]
const oldValue = row[column.field]
if (this.options.uniqueId !== undefined && !column.alwaysUseFormatter) {
const uniqueId = Utils.getItemField(row, this.options.uniqueId, false)
if ($.inArray(column.field + uniqueId, this.editedCells) === -1) {
this.editedCells.push(column.field + uniqueId)
}
}
submitValue = Utils.escapeHTML(submitValue)
$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)) {
row[key] = Utils.unescapeHTML(value)
}
}
}
return data
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,337 +0,0 @@
/**
* @author zhixin wen <wenzhixin2010@gmail.com>
* extensions: https://github.com/hhurz/tableExport.jquery.plugin
*/
var Utils = $.fn.bootstrapTable.utils
const TYPE_NAME = {
json: 'JSON',
xml: 'XML',
png: 'PNG',
csv: 'CSV',
txt: 'TXT',
sql: 'SQL',
doc: 'MS-Word',
excel: 'MS-Excel',
xlsx: 'MS-Excel (OpenXML)',
powerpoint: 'MS-Powerpoint',
pdf: 'PDF'
}
$.extend($.fn.bootstrapTable.defaults, {
showExport: false,
exportDataType: 'basic', // basic, all, selected
exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'],
exportOptions: {
onCellHtmlData (cell, rowIndex, colIndex, htmlData) {
if (cell.is('th')) {
return cell.find('.th-inner').text()
}
return htmlData
}
},
exportFooter: false
})
$.extend($.fn.bootstrapTable.columnDefaults, {
forceExport: false,
forceHide: false
})
$.extend($.fn.bootstrapTable.defaults.icons, {
export: {
bootstrap3: 'glyphicon-export icon-share',
bootstrap5: 'bi-download',
materialize: 'file_download',
'bootstrap-table': 'icon-download'
}[$.fn.bootstrapTable.theme] || 'fa-download'
})
$.extend($.fn.bootstrapTable.locales, {
formatExport () {
return 'Export data'
}
})
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
$.fn.bootstrapTable.methods.push('exportTable')
$.extend($.fn.bootstrapTable.defaults, {
// eslint-disable-next-line no-unused-vars
onExportSaved (exportedRows) {
return false
}
})
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
'export-saved.bs.table': 'onExportSaved'
})
$.BootstrapTable = class extends $.BootstrapTable {
initToolbar (...args) {
const o = this.options
let exportTypes = o.exportTypes
this.showToolbar = this.showToolbar || o.showExport
if (this.options.showExport) {
if (typeof exportTypes === 'string') {
const types = exportTypes.slice(1, -1).replace(/ /g, '').split(',')
exportTypes = types.map(t => t.slice(1, -1))
}
this.$export = this.$toolbar.find('>.columns div.export')
if (this.$export.length) {
this.updateExportButton()
return
}
this.buttons = Object.assign(this.buttons, {
export: {
html:
(() => {
if (exportTypes.length === 1) {
return `
<div class="export ${this.constants.classes.buttonsDropdown}"
data-type="${exportTypes[0]}">
<button class="${this.constants.buttonsClass}"
aria-label="Export"
type="button"
title="${o.formatExport()}">
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
${o.showButtonText ? o.formatExport() : ''}
</button>
</div>
`
}
const html = []
html.push(`
<div class="export ${this.constants.classes.buttonsDropdown}">
<button class="${this.constants.buttonsClass} dropdown-toggle"
aria-label="Export"
${this.constants.dataToggle}="dropdown"
type="button"
title="${o.formatExport()}">
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
${o.showButtonText ? o.formatExport() : ''}
${this.constants.html.dropdownCaret}
</button>
${this.constants.html.toolbarDropdown[0]}
`)
for (const type of exportTypes) {
if (TYPE_NAME.hasOwnProperty(type)) {
const $item = $(Utils.sprintf(this.constants.html.pageDropdownItem, '', TYPE_NAME[type]))
$item.attr('data-type', type)
html.push($item.prop('outerHTML'))
}
}
html.push(this.constants.html.toolbarDropdown[1], '</div>')
return html.join('')
})
}
})
}
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.find('button')
}
$exportButtons.click(e => {
e.preventDefault()
const type = $(e.currentTarget).data('type')
const exportOptions = {
type,
escape: false
}
this.exportTable(exportOptions)
})
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) {
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 === '&nbsp;' ? 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($.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(() => {
doExport(() => {
this.options.virtualScroll = virtualScroll
this.togglePagination()
})
}, 0)
})
this.options.virtualScroll = false
this.togglePagination()
this.trigger('export-saved', this.getData())
} 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)
}
}
}

View File

@ -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);

View File

@ -1,124 +0,0 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
const debounce = (func, wait) => {
let timeout = 0
return (...args) => {
const later = () => {
timeout = 0
func(...args)
}
clearTimeout(timeout)
timeout = setTimeout(later, wait)
}
}
$.extend($.fn.bootstrapTable.defaults, {
mobileResponsive: false,
minWidth: 562,
minHeight: undefined,
heightThreshold: 100, // just slightly larger than mobile chrome's auto-hiding toolbar
checkOnInit: true,
columnsHidden: []
})
$.BootstrapTable = class extends $.BootstrapTable {
init (...args) {
super.init(...args)
if (!this.options.mobileResponsive || !this.options.minWidth) {
return
}
if (this.options.minWidth < 100 && this.options.resizable) {
console.warn('The minWidth when the resizable extension is active should be greater or equal than 100')
this.options.minWidth = 100
}
let old = {
width: $(window).width(),
height: $(window).height()
}
$(window).on('resize orientationchange', debounce(() => {
// reset view if height has only changed by at least the threshold.
const width = $(window).width()
const height = $(window).height()
const $activeElement = $(document.activeElement)
if ($activeElement.length && ['INPUT', 'SELECT', 'TEXTAREA'].includes($activeElement.prop('nodeName'))) {
return
}
if (
Math.abs(old.height - height) > this.options.heightThreshold ||
old.width !== width
) {
this.changeView(width, height)
old = {
width,
height
}
}
}, 200))
if (this.options.checkOnInit) {
const width = $(window).width()
const height = $(window).height()
this.changeView(width, height)
old = {
width,
height
}
}
}
conditionCardView () {
this.changeTableView(false)
this.showHideColumns(false)
}
conditionFullView () {
this.changeTableView(true)
this.showHideColumns(true)
}
changeTableView (cardViewState) {
this.options.cardView = cardViewState
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()
}
}

View File

@ -1,285 +0,0 @@
/**
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
var Utils = $.fn.bootstrapTable.utils
function printPageBuilderDefault (table) {
return `
<html>
<head>
<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>`
}
$.extend($.fn.bootstrapTable.locales, {
formatPrint () {
return 'Print'
}
})
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
$.extend($.fn.bootstrapTable.defaults, {
showPrint: false,
printAsFilteredAndSortedOnUI: true,
printSortColumn: undefined,
printSortOrder: 'asc',
printPageBuilder (table) {
return printPageBuilderDefault(table)
}
})
$.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {
printFilter: undefined,
printIgnore: false,
printFormatter: undefined
})
$.extend($.fn.bootstrapTable.defaults.icons, {
print: {
bootstrap3: 'glyphicon-print icon-share',
'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 formatValue = (row, i, column) => {
const value = Utils.calculateObjectValue(column,
column.printFormatter || column.formatter,
[$.common.getItemField(row, column.field), row, i], $.common.getItemField(row, column.field))
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 (!columns[h].printIgnore) {
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 dontRender = []
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
dontRender.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 (
!columns[j].printIgnore && columns[j].field &&
(
!dontRender.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 (!columns[h].printIgnore) {
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('')
newWin.document.write(this.options.printPageBuilder.call(this, table))
newWin.document.close()
newWin.focus()
newWin.print()
newWin.close()
}
}

View File

@ -1,213 +0,0 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @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
}
}
}
$.extend($.fn.bootstrapTable.defaults, {
reorderableColumns: false,
maxMovingRows: 10,
// eslint-disable-next-line no-unused-vars
onReorderColumn (headerFields) {
return false
},
dragaccept: null
})
$.extend($.fn.bootstrapTable.Constructor.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.makeRowsReorderable()
}
_toggleColumn (...args) {
super._toggleColumn(...args)
if (!this.options.reorderableColumns) {
return
}
this.makeRowsReorderable()
}
toggleView (...args) {
super.toggleView(...args)
if (!this.options.reorderableColumns) {
return
}
if (this.options.cardView) {
return
}
this.makeRowsReorderable()
}
resetView (...args) {
super.resetView(...args)
if (!this.options.reorderableColumns) {
return
}
this.makeRowsReorderable()
}
makeRowsReorderable (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.makeRowsReorderable()
}
}

View File

@ -1,118 +0,0 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
const rowAttr = (row, index) => ({
id: `customId_${index}`
})
$.extend($.fn.bootstrapTable.defaults, {
reorderableRows: false,
onDragStyle: null,
onDropStyle: null,
onDragClass: 'reorder_rows_onDragClass',
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
}
})
$.extend($.fn.bootstrapTable.Constructor.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,
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])
}
onDrop (table) {
this.$draggingTd.css('cursor', '')
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 = 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()
// 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()
}
}

View File

@ -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">&nbsp;</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">&nbsp;</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);

View File

@ -1,69 +0,0 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @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)
}
$.extend($.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)
}
}
}

View File

@ -1,109 +0,0 @@
/**
* Bootstrap Table Chinese translation
* Author: Zhixin Wen<wenzhixin2010@gmail.com>
*/
$.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']);

View File

@ -1 +0,0 @@
$.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"]);

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -1,418 +0,0 @@
/*!
* Datetimepicker 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
*
*/
.datetimepicker {
padding: 4px;
margin-top: 1px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
direction: ltr;
}
.datetimepicker-inline {
width: 220px;
}
.datetimepicker.datetimepicker-rtl {
direction: rtl;
}
.datetimepicker.datetimepicker-rtl table tr td span {
float: right;
}
.datetimepicker-dropdown, .datetimepicker-dropdown-left {
top: 0;
left: 0;
}
[class*=" datetimepicker-dropdown"]:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #cccccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
}
[class*=" datetimepicker-dropdown"]:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #ffffff;
position: absolute;
}
[class*=" datetimepicker-dropdown-top"]:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid #cccccc;
border-top-color: rgba(0, 0, 0, 0.2);
border-bottom: 0;
}
[class*=" datetimepicker-dropdown-top"]:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #ffffff;
border-bottom: 0;
}
.datetimepicker-dropdown-bottom-left:before {
top: -7px;
right: 6px;
}
.datetimepicker-dropdown-bottom-left:after {
top: -6px;
right: 7px;
}
.datetimepicker-dropdown-bottom-right:before {
top: -7px;
left: 6px;
}
.datetimepicker-dropdown-bottom-right:after {
top: -6px;
left: 7px;
}
.datetimepicker-dropdown-top-left:before {
bottom: -7px;
right: 6px;
}
.datetimepicker-dropdown-top-left:after {
bottom: -6px;
right: 7px;
}
.datetimepicker-dropdown-top-right:before {
bottom: -7px;
left: 6px;
}
.datetimepicker-dropdown-top-right:after {
bottom: -6px;
left: 7px;
}
.datetimepicker > div {
display: none;
}
.datetimepicker.minutes div.datetimepicker-minutes {
display: block;
}
.datetimepicker.hours div.datetimepicker-hours {
display: block;
}
.datetimepicker.days div.datetimepicker-days {
display: block;
}
.datetimepicker.months div.datetimepicker-months {
display: block;
}
.datetimepicker.years div.datetimepicker-years {
display: block;
}
.datetimepicker table {
margin: 0;
}
.datetimepicker td,
.datetimepicker th {
text-align: center;
width: 20px;
height: 20px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: none;
}
.table-striped .datetimepicker table tr td,
.table-striped .datetimepicker table tr th {
background-color: transparent;
}
.datetimepicker table tr td.minute:hover {
background: #eeeeee;
cursor: pointer;
}
.datetimepicker table tr td.hour:hover {
background: #eeeeee;
cursor: pointer;
}
.datetimepicker table tr td.day:hover {
background: #eeeeee;
cursor: pointer;
}
.datetimepicker table tr td.old,
.datetimepicker table tr td.new {
color: #999999;
}
.datetimepicker table tr td.disabled,
.datetimepicker table tr td.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datetimepicker table tr td.today,
.datetimepicker table tr td.today:hover,
.datetimepicker table tr td.today.disabled,
.datetimepicker 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(to bottom, #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);
}
.datetimepicker table tr td.today:hover,
.datetimepicker table tr td.today:hover:hover,
.datetimepicker table tr td.today.disabled:hover,
.datetimepicker table tr td.today.disabled:hover:hover,
.datetimepicker table tr td.today:active,
.datetimepicker table tr td.today:hover:active,
.datetimepicker table tr td.today.disabled:active,
.datetimepicker table tr td.today.disabled:hover:active,
.datetimepicker table tr td.today.active,
.datetimepicker table tr td.today:hover.active,
.datetimepicker table tr td.today.disabled.active,
.datetimepicker table tr td.today.disabled:hover.active,
.datetimepicker table tr td.today.disabled,
.datetimepicker table tr td.today:hover.disabled,
.datetimepicker table tr td.today.disabled.disabled,
.datetimepicker table tr td.today.disabled:hover.disabled,
.datetimepicker table tr td.today[disabled],
.datetimepicker table tr td.today:hover[disabled],
.datetimepicker table tr td.today.disabled[disabled],
.datetimepicker table tr td.today.disabled:hover[disabled] {
background-color: #fdf59a;
}
.datetimepicker table tr td.today:active,
.datetimepicker table tr td.today:hover:active,
.datetimepicker table tr td.today.disabled:active,
.datetimepicker table tr td.today.disabled:hover:active,
.datetimepicker table tr td.today.active,
.datetimepicker table tr td.today:hover.active,
.datetimepicker table tr td.today.disabled.active,
.datetimepicker table tr td.today.disabled:hover.active {
background-color: #fbf069;
}
.datetimepicker table tr td.active,
.datetimepicker table tr td.active:hover,
.datetimepicker table tr td.active.disabled,
.datetimepicker 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(to bottom, #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: #ffffff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datetimepicker table tr td.active:hover,
.datetimepicker table tr td.active:hover:hover,
.datetimepicker table tr td.active.disabled:hover,
.datetimepicker table tr td.active.disabled:hover:hover,
.datetimepicker table tr td.active:active,
.datetimepicker table tr td.active:hover:active,
.datetimepicker table tr td.active.disabled:active,
.datetimepicker table tr td.active.disabled:hover:active,
.datetimepicker table tr td.active.active,
.datetimepicker table tr td.active:hover.active,
.datetimepicker table tr td.active.disabled.active,
.datetimepicker table tr td.active.disabled:hover.active,
.datetimepicker table tr td.active.disabled,
.datetimepicker table tr td.active:hover.disabled,
.datetimepicker table tr td.active.disabled.disabled,
.datetimepicker table tr td.active.disabled:hover.disabled,
.datetimepicker table tr td.active[disabled],
.datetimepicker table tr td.active:hover[disabled],
.datetimepicker table tr td.active.disabled[disabled],
.datetimepicker table tr td.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datetimepicker table tr td.active:active,
.datetimepicker table tr td.active:hover:active,
.datetimepicker table tr td.active.disabled:active,
.datetimepicker table tr td.active.disabled:hover:active,
.datetimepicker table tr td.active.active,
.datetimepicker table tr td.active:hover.active,
.datetimepicker table tr td.active.disabled.active,
.datetimepicker table tr td.active.disabled:hover.active {
background-color: #003399;
}
.datetimepicker 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;
}
.datetimepicker .datetimepicker-hours span {
height: 26px;
line-height: 26px;
}
.datetimepicker .datetimepicker-hours table tr td span.hour_am,
.datetimepicker .datetimepicker-hours table tr td span.hour_pm {
width: 14.6%;
}
.datetimepicker .datetimepicker-hours fieldset legend,
.datetimepicker .datetimepicker-minutes fieldset legend {
margin-bottom: inherit;
line-height: 30px;
}
.datetimepicker .datetimepicker-minutes span {
height: 26px;
line-height: 26px;
}
.datetimepicker table tr td span:hover {
background: #eeeeee;
}
.datetimepicker table tr td span.disabled,
.datetimepicker table tr td span.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datetimepicker table tr td span.active,
.datetimepicker table tr td span.active:hover,
.datetimepicker table tr td span.active.disabled,
.datetimepicker 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(to bottom, #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: #ffffff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datetimepicker table tr td span.active:hover,
.datetimepicker table tr td span.active:hover:hover,
.datetimepicker table tr td span.active.disabled:hover,
.datetimepicker table tr td span.active.disabled:hover:hover,
.datetimepicker table tr td span.active:active,
.datetimepicker table tr td span.active:hover:active,
.datetimepicker table tr td span.active.disabled:active,
.datetimepicker table tr td span.active.disabled:hover:active,
.datetimepicker table tr td span.active.active,
.datetimepicker table tr td span.active:hover.active,
.datetimepicker table tr td span.active.disabled.active,
.datetimepicker table tr td span.active.disabled:hover.active,
.datetimepicker table tr td span.active.disabled,
.datetimepicker table tr td span.active:hover.disabled,
.datetimepicker table tr td span.active.disabled.disabled,
.datetimepicker table tr td span.active.disabled:hover.disabled,
.datetimepicker table tr td span.active[disabled],
.datetimepicker table tr td span.active:hover[disabled],
.datetimepicker table tr td span.active.disabled[disabled],
.datetimepicker table tr td span.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datetimepicker table tr td span.active:active,
.datetimepicker table tr td span.active:hover:active,
.datetimepicker table tr td span.active.disabled:active,
.datetimepicker table tr td span.active.disabled:hover:active,
.datetimepicker table tr td span.active.active,
.datetimepicker table tr td span.active:hover.active,
.datetimepicker table tr td span.active.disabled.active,
.datetimepicker table tr td span.active.disabled:hover.active {
background-color: #003399;
}
.datetimepicker table tr td span.old {
color: #999999;
}
.datetimepicker th.switch {
width: 145px;
}
.datetimepicker th span.glyphicon {
pointer-events: none;
}
.datetimepicker thead tr:first-child th,
.datetimepicker tfoot th {
cursor: pointer;
}
.datetimepicker thead tr:first-child th:hover,
.datetimepicker tfoot th:hover {
background: #eeeeee;
}
.input-append.date .add-on i,
.input-prepend.date .add-on i,
.input-group.date .input-group-addon span {
cursor: pointer;
width: 14px;
height: 14px;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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%;
}

View File

@ -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);

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