83 Commits
Author SHA1 Message Date
RuoYi 3faa23b7c0 若依 v4.6.0 2021-01-01 10:07:25 +08:00
RuoYi 9c643e7c08 添加新群号 2020-12-29 10:05:25 +08:00
RuoYi e6fd0c3661 初始列默认字段类型 2020-12-28 16:05:39 +08:00
若依andGitee d95dbf235e !253 代码生成: 数据库文本类型生成表单文本域
Merge pull request !253 from dawn9117/N/A
2020-12-28 15:26:36 +08:00
dawn9117andGitee 583b8b79b0 代码生成: 数据库文本类型生成表单文本域 2020-12-28 10:13:27 +08:00
RuoYi 243b993751 Excel注解支持Image图片导出 2020-12-27 10:03:10 +08:00
RuoYi 73ee7bc485 代码生成日期控件区分范围 2020-12-25 09:34:25 +08:00
RuoYi a1ec9a6508 防止错误页返回主页出现嵌套问题 2020-12-24 17:40:03 +08:00
RuoYi de6fa42721 新增示例(标签 & 提示) 2020-12-24 16:50:39 +08:00
RuoYi 9d81ccb528 添加单据打印示例 2020-12-24 12:14:57 +08:00
RuoYi 9abeb6ac41 弹出层openOptions移动端自适应 2020-12-24 12:14:37 +08:00
若依andGitee 5e6226a39c !252 update pom.xml.
Merge pull request !252 from Hacker/N/A
2020-12-23 18:21:25 +08:00
HackerandGitee 0098b5cc2a update pom.xml. 2020-12-22 17:58:30 +08:00
若依andGitee bc0a1c8fe0 !251 公共方法(addFull添加信息 全屏)在无参数时没有替换url中参数字符为空的问题
Merge pull request !251 from 小光/master
2020-12-22 17:05:40 +08:00
小光andGitee 681fddc387 公共方法(addFull添加信息 全屏)在无参数时没有替换url中参数字符为空的问题 2020-12-22 17:02:50 +08:00
若依andGitee d6a2d09f95 !249 修复主子表editColumn table dataIndex循环bug
Merge pull request !249 from dawn9117/N/A
2020-12-22 14:50:05 +08:00
RuoYi 926f5881ac 使用widthUnit定义选项单位 2020-12-22 14:13:49 +08:00
若依andGitee 0499cd8d97 !237 浏览文件解决bootstrap-treetable,表头跟表格宽度不同步的问题
Merge pull request !237 from Vmo/master
2020-12-22 13:34:36 +08:00
dawn9117andGitee 223f5d6532 修复主子表editColumn table dataIndex循环bug 2020-12-22 11:10:13 +08:00
RuoYi 3e37ba5f1f 新增表格参数(自定义打印页面模板printPageBuilder) 2020-12-21 12:32:25 +08:00
RuoYi 697a989ab3 新增表格参数(自定义打印页面模板printPageBuilder) 2020-12-21 12:24:09 +08:00
若依andGitee e5f914277e !246 1、修复请求返回值未使用常量web_status.SUCCESS的问题。
Merge pull request !246 from kagome2014/N/A
2020-12-21 10:29:34 +08:00
kagome2014andGitee 0c8a6935f2 1、修复请求返回值未使用常量web_status.SUCCESS的问题。 2020-12-21 10:23:02 +08:00
RuoYi bda12d5016 升级SpringBoot到最新版本2.2.12 提升启动速度 2020-12-16 10:05:01 +08:00
RuoYi 78eed9cd56 菜单新增是否刷新页面 2020-12-14 17:36:54 +08:00
RuoYi 9c92d8f87d 新增选项卡是否刷新属性 2020-12-14 15:08:10 +08:00
RuoYi f0e4e1a1a6 修改表格初始参数sortName默认值为undefined 2020-12-12 11:40:43 +08:00
RuoYi 5ac8aea155 获取属性的get方法空值验证 2020-12-12 11:40:31 +08:00
idevmo 2cf1b00b33 解决bootstrap-treetable,表头跟表格宽度不同步的问题 2020-12-11 14:52:34 +08:00
RuoYi 10ac990d36 修复生成主子表外键名错误 2020-12-11 10:30:34 +08:00
若依andGitee ed91f217d2 !235 修复online sessionId大小写bug;修复代码生成: 生成主子表代码, 子表新增数据报错
Merge pull request !235 from dawn9117/N/A
2020-12-11 10:02:29 +08:00
dawn9117andGitee edfaa1210a 修复online sessionId大小写bug;
修复代码生成: 生成主子表代码, 子表新增数据报错
2020-12-09 15:35:11 +08:00
RuoYi ded17a552d 删除用户和角色解绑关联 2020-12-09 10:14:10 +08:00
RuoYi fb480530c8 新增锁定屏幕功能 2020-12-08 15:35:24 +08:00
RuoYi 832b1f4e14 回显数据字典防止空值 2020-12-08 15:34:05 +08:00
若依andGitee 9116b722a4 !233 浏览文件密码强度字符范围提示
Merge pull request !233 from Byron.Liu/develop
2020-12-07 14:02:49 +08:00
RuoYi 3f114ccc15 防止匿名访问进行过滤 2020-12-07 13:52:51 +08:00
Byron.Liu f884fc927f 密码强度字符范围提示 2020-12-07 11:33:06 +08:00
RuoYi 438fcc0928 新增密码字符范围提示 2020-12-04 10:48:43 +08:00
RuoYi 35a49e9462 主子表操作添加通用addColumn方法 2020-12-04 10:48:32 +08:00
RuoYi 59ad2b1d5e 升级bitwalker到最新版本1.21 2020-12-04 10:48:18 +08:00
RuoYi 69160bf0da 升级poi到最新版本4.1.2 2020-12-03 12:40:13 +08:00
RuoYi 9e994023a8 Excel支持注解align对齐方式 2020-12-03 12:38:22 +08:00
RuoYi d14ce06afd 升级bootstrap-fileinput到最新版本5.1.3 2020-12-02 15:32:38 +08:00
RuoYi 7776b82c18 表格树加载完成触发tooltip方法 2020-12-02 14:59:26 +08:00
RuoYi 1e761c7e66 升级SpringBoot到最新版本2.1.18 2020-11-30 09:58:21 +08:00
RuoYi c6962a1f8d 修正转换字符串的目标字符集属性 2020-11-30 09:58:10 +08:00
RuoYi 17ab56cf53 新增表格参数(是否显示行间隔色striped) 2020-11-29 17:02:06 +08:00
RuoYi fa69ae7b49 升级bootstrapTable相关组件到最新版本v1.18.0 2020-11-29 16:31:53 +08:00
RuoYi ad3d75c9f2 升级bootstrapTable到最新版本v1.18.0 2020-11-29 16:31:26 +08:00
RuoYi cdccfcbf9b 代码生成删除多余的数字float类型 2020-11-28 11:52:40 +08:00
RuoYi 9d30a4652c Excel支持导入Boolean型数据 2020-11-28 11:51:41 +08:00
若依andGitee c0d66fffcd !230 update ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java.
Merge pull request !230 from fatfish517/N/A
2020-11-28 11:27:10 +08:00
若依andGitee c7262e4c3e !229 update ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java.
Merge pull request !229 from fatfish517/N/A
2020-11-28 11:27:07 +08:00
若依andGitee 07826c687a !232 修复用户详细页面用户编号格式错位
Merge pull request !232 from 嘿白熊/master
2020-11-28 11:20:28 +08:00
X.B-H f3aa0bc673 详细信息展示格式修复 2020-11-27 13:36:45 +08:00
RuoYi 07694e8f40 新增表格参数(渲染完成后执行的事件onPostBody) 2020-11-26 10:22:24 +08:00
RuoYi 08430b192f 防止未初始参数脚本导致的异常 2020-11-25 18:35:17 +08:00
若依andGitee 9aa405c203 !231 修复封装类转基础数据空指针异常
Merge pull request !231 from RamaYuYang/master
2020-11-25 18:26:20 +08:00
yuyang bc96bbc9ac 修复Integer为null转基础类型空指针 2020-11-25 13:25:39 +08:00
RuoYi e6500ee26a 升级oshi到最新版本v5.3.6 2020-11-24 16:01:47 +08:00
fatfish517andGitee a8b569a24d update ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java. 2020-11-24 10:48:34 +08:00
fatfish517andGitee ed0deeb230 update ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java. 2020-11-24 10:45:19 +08:00
RuoYi 30850c1fdf 新增缓存监控功能 2020-11-23 10:18:58 +08:00
RuoYi 784cc3a10f session配置永不过期,不删除在线会话信息 2020-11-23 10:06:00 +08:00
RuoYi 34445af291 树表溢出元素内容隐藏 2020-11-20 11:40:39 +08:00
RuoYi 680ad3a5e0 若依 v4.5.1 2020-11-18 09:36:21 +08:00
RuoYi a825075dd5 全局配置保持和其他应用命名相同 2020-11-17 10:34:04 +08:00
RuoYi 18f6366f2e 阻止任意文件下载漏洞 2020-11-17 09:33:36 +08:00
RuoYi 6ca8c712e3 升级shiro到最新版1.7.0 阻止权限绕过漏洞 2020-11-16 15:10:51 +08:00
RuoYi cefb14e521 新增表格行触发事件(onCheck、onUncheck、onCheckAll、onUncheckAll) 2020-11-12 10:30:15 +08:00
RuoYi c27ea9d3f4 修复多页签关闭非当前选项出现空白问题 2020-11-11 12:17:16 +08:00
RuoYi 80bf31dcbc 升级druid到最新版本v1.2.2 2020-11-05 14:01:19 +08:00
RuoYi 79ab6b558a 2020年双十一云服务器优惠,错过又要等一年 2020-11-04 16:54:55 +08:00
RuoYi 1c83adc507 去除多余的代码 2020-11-04 16:54:36 +08:00
RuoYi 4b265bb193 代码生成预览支持高亮显示 2020-11-04 12:02:51 +08:00
RuoYi 057a390bff mapperLocations配置支持分隔符 2020-11-02 17:05:08 +08:00
若依andGitee f32dd2bd07 !224 MyBatisConfig mapperLocations 不能识别 , 分隔
Merge pull request !224 from GodOfBug/master
2020-11-02 17:01:43 +08:00
GodOfBug 06cde445b5 修复mapperLocations问题 2020-11-02 16:21:35 +08:00
RuoYi 7a6a109a8c 权限调整 2020-10-22 19:58:32 +08:00
Ricky a955d38ef1 个人中心头像和上传头像增加默认图片 2020-10-22 18:07:59 +08:00
RuoYi 685e090f2f 权限调整 2020-10-22 17:13:10 +08:00
Ricky 207126847e 个人中心头像和上传头像增加默认图片 2020-10-22 09:40:31 +08:00
151 changed files with 5245 additions and 7532 deletions
+3 -2
View File
@@ -8,7 +8,8 @@
* 前后端分离版本,请移步[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 框架。
* 阿里云优惠券[点我进入](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)  
* 阿里云折扣场[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场[点我进入](http://txy.ruoyi.vip)  
* 阿里云优惠券:[点我领取](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)  
## 内置功能
@@ -86,4 +87,4 @@
## 若依交流群
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群: [![加入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)
+10 -10
View File
@@ -5,31 +5,31 @@
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>4.5.0</version>
<version>4.6.0</version>
<name>ruoyi</name>
<url>http://www.ruoyi.vip</url>
<description>若依管理系统</description>
<properties>
<ruoyi.version>4.5.0</ruoyi.version>
<ruoyi.version>4.6.0</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.6.0</shiro.version>
<shiro.version>1.7.0</shiro.version>
<thymeleaf.extras.shiro.version>2.0.0</thymeleaf.extras.shiro.version>
<druid.version>1.2.1</druid.version>
<bitwalker.version>1.19</bitwalker.version>
<druid.version>1.2.2</druid.version>
<bitwalker.version>1.21</bitwalker.version>
<kaptcha.version>2.3.2</kaptcha.version>
<swagger.version>2.9.2</swagger.version>
<pagehelper.boot.version>1.3.0</pagehelper.boot.version>
<fastjson.version>1.2.74</fastjson.version>
<oshi.version>5.2.5</oshi.version>
<jna.version>5.5.0</jna.version>
<oshi.version>5.3.6</oshi.version>
<jna.version>5.6.0</jna.version>
<commons.io.version>2.5</commons.io.version>
<commons.fileupload.version>1.3.3</commons.fileupload.version>
<poi.version>3.17</poi.version>
<poi.version>4.1.2</poi.version>
<velocity.version>1.7</velocity.version>
</properties>
@@ -41,7 +41,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.17.RELEASE</version>
<version>2.2.12.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -67,7 +67,7 @@
<version>${shiro.version}</version>
</dependency>
<!-- Shiro使用Srping框架 -->
<!-- Shiro使用Spring框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.5.0</version>
<version>4.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
@@ -11,7 +11,7 @@ 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.multipart.MultipartFile;
import com.ruoyi.common.config.Global;
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;
@@ -43,16 +43,15 @@ public class CommonController
{
try
{
if (!FileUtils.isValidFilename(fileName))
if (!FileUtils.checkAllowDownload(fileName))
{
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
}
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
String filePath = Global.getDownloadPath() + fileName;
String filePath = RuoYiConfig.getDownloadPath() + fileName;
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, realFileName);
FileUtils.writeBytes(filePath, response.getOutputStream());
if (delete)
{
@@ -75,7 +74,7 @@ public class CommonController
try
{
// 上传文件路径
String filePath = Global.getUploadPath();
String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
@@ -97,16 +96,25 @@ public class CommonController
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
throws Exception
{
// 本地资源路径
String localPath = Global.getProfile();
// 数据库资源地址
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
// 下载名称
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, downloadName);
FileUtils.writeBytes(downloadPath, response.getOutputStream());
try
{
if (!FileUtils.checkAllowDownload(resource))
{
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
}
// 本地资源路径
String localPath = RuoYiConfig.getProfile();
// 数据库资源地址
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
// 下载名称
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, downloadName);
FileUtils.writeBytes(downloadPath, response.getOutputStream());
}
catch (Exception e)
{
log.error("下载文件失败", e);
}
}
}
@@ -89,6 +89,24 @@ public class DemoFormController
return prefix + "/sortable";
}
/**
* 单据打印
*/
@GetMapping("/invoice")
public String invoice()
{
return prefix + "/invoice";
}
/**
* 标签 & 提示
*/
@GetMapping("/labels_tips")
public String labels_tips()
{
return prefix + "/labels_tips";
}
/**
* 选项卡 & 面板
*/
@@ -227,41 +245,42 @@ public class DemoFormController
@GetMapping("/localrefresh")
public String localRefresh(ModelMap mmap)
{
JSONArray list = new JSONArray();
JSONObject item = new JSONObject();
item.put("name", "这条任务数据是由ModelMap传递到页面的,点击添加按钮后会将这条数据替换为新数据");
item.put("type", "默认");
item.put("date", "2020.06.10");
list.add(item);
mmap.put("tasks",list);
mmap.put("min",2);
mmap.put("max",10);
JSONArray list = new JSONArray();
JSONObject item = new JSONObject();
item.put("name", "这条任务数据是由ModelMap传递到页面的,点击添加按钮后会将这条数据替换为新数据");
item.put("type", "默认");
item.put("date", "2020.06.10");
list.add(item);
mmap.put("tasks", list);
mmap.put("min", 2);
mmap.put("max", 10);
return prefix + "/localrefresh";
}
/**
* 局部刷新-添加任务
* @param fragment 页面中的模板名称
* @param taskName 任务名称
*
* @param fragment 页面中的模板名称
* @param taskName 任务名称
*/
@PostMapping("/localrefresh/task")
public String localRefreshTask(String fragment,String taskName,ModelMap mmap)
public String localRefreshTask(String fragment, String taskName, ModelMap mmap)
{
JSONArray list = new JSONArray();
JSONObject item = new JSONObject();
item.put("name", StringUtils.defaultIfBlank(taskName, "通过电话销售过程中了解各盛市的设备仪器使用、采购情况及相关重要追踪人"));
item.put("type", "新增");
item.put("date", "2018.06.10");
list.add(item);
item = new JSONObject();
item.put("name", "提高自己电话营销技巧,灵活专业地与客户进行电话交流");
item.put("type", "新增");
item.put("date", "2018.06.12");
list.add(item);
mmap.put("tasks",list);
JSONArray list = new JSONArray();
JSONObject item = new JSONObject();
item.put("name", StringUtils.defaultIfBlank(taskName, "通过电话销售过程中了解各盛市的设备仪器使用、采购情况及相关重要追踪人"));
item.put("type", "新增");
item.put("date", "2018.06.10");
list.add(item);
item = new JSONObject();
item.put("name", "提高自己电话营销技巧,灵活专业地与客户进行电话交流");
item.put("type", "新增");
item.put("date", "2018.06.12");
list.add(item);
mmap.put("tasks", list);
return prefix + "/localrefresh::" + fragment;
}
/**
* 模拟数据
*/
@@ -0,0 +1,82 @@
package com.ruoyi.web.controller.monitor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.framework.web.service.CacheService;
/**
* 缓存监控
*
* @author ruoyi
*/
@Controller
@RequestMapping("/monitor/cache")
public class CacheController extends BaseController
{
private String prefix = "monitor/cache";
@Autowired
private CacheService cacheService;
@GetMapping()
public String cache(ModelMap mmap)
{
mmap.put("cacheNames", cacheService.getCacheNames());
return prefix + "/cache";
}
@PostMapping("/getNames")
public String getCacheNames(String fragment, ModelMap mmap)
{
mmap.put("cacheNames", cacheService.getCacheNames());
return prefix + "/cache::" + fragment;
}
@PostMapping("/getKeys")
public String getCacheKeys(String fragment, String cacheName, ModelMap mmap)
{
mmap.put("cacheName", cacheName);
mmap.put("cacheKyes", cacheService.getCacheKeys(cacheName));
return prefix + "/cache::" + fragment;
}
@PostMapping("/getValue")
public String getCacheValue(String fragment, String cacheName, String cacheKey, ModelMap mmap)
{
mmap.put("cacheName", cacheName);
mmap.put("cacheKey", cacheKey);
mmap.put("cacheValue", cacheService.getCacheValue(cacheName, cacheKey));
return prefix + "/cache::" + fragment;
}
@PostMapping("/clearCacheName")
@ResponseBody
public AjaxResult clearCacheName(String cacheName, ModelMap mmap)
{
cacheService.clearCacheName(cacheName);
return AjaxResult.success();
}
@PostMapping("/clearCacheKey")
@ResponseBody
public AjaxResult clearCacheKey(String cacheName, String cacheKey, ModelMap mmap)
{
cacheService.clearCacheKey(cacheName, cacheKey);
return AjaxResult.success();
}
@GetMapping("/clearAll")
@ResponseBody
public AjaxResult clearAll(ModelMap mmap)
{
cacheService.clearAll();
return AjaxResult.success();
}
}
@@ -16,9 +16,9 @@ import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.OnlineStatus;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.framework.shiro.session.OnlineSession;
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysUserOnline;
import com.ruoyi.system.service.ISysUserOnlineService;
@@ -17,8 +17,8 @@ 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.ShiroUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.service.ISysConfigService;
@@ -16,11 +16,11 @@ 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.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysDept;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.service.ISysDeptService;
/**
@@ -14,11 +14,11 @@ import org.springframework.web.bind.annotation.ResponseBody;
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.ShiroUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysDictData;
import com.ruoyi.system.service.ISysDictDataService;
/**
@@ -16,11 +16,11 @@ 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;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysDictType;
import com.ruoyi.system.service.ISysDictTypeService;
/**
@@ -9,16 +9,21 @@ 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 com.ruoyi.common.config.Global;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.ShiroConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.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.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysMenu;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysMenuService;
@@ -36,6 +41,9 @@ public class SysIndexController extends BaseController
@Autowired
private ISysConfigService configService;
@Autowired
private SysPasswordService passwordService;
// 系统首页
@GetMapping("/index")
public String index(ModelMap mmap)
@@ -49,8 +57,8 @@ public class SysIndexController extends BaseController
mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme"));
mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName"));
mmap.put("ignoreFooter", configService.selectConfigByKey("sys.index.ignoreFooter"));
mmap.put("copyrightYear", Global.getCopyrightYear());
mmap.put("demoEnabled", Global.isDemoEnabled());
mmap.put("copyrightYear", RuoYiConfig.getCopyrightYear());
mmap.put("demoEnabled", RuoYiConfig.isDemoEnabled());
mmap.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
mmap.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
@@ -73,6 +81,33 @@ public class SysIndexController extends BaseController
return webIndex;
}
// 锁定屏幕
@GetMapping("/lockscreen")
public String lockscreen(ModelMap mmap)
{
mmap.put("user", ShiroUtils.getSysUser());
ServletUtils.getSession().setAttribute(ShiroConstants.LOCK_SCREEN, true);
return "lock";
}
// 解锁屏幕
@PostMapping("/unlockscreen")
@ResponseBody
public AjaxResult unlockscreen(String password)
{
SysUser user = ShiroUtils.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()
@@ -91,22 +126,22 @@ public class SysIndexController extends BaseController
@GetMapping("/system/main")
public String main(ModelMap mmap)
{
mmap.put("version", Global.getVersion());
mmap.put("version", RuoYiConfig.getVersion());
return "main";
}
// 检查初始密码是否提醒修改
public boolean initPasswordIsModify(Date pwdUpdateDate)
{
int initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
return initPasswordModify == 1 && pwdUpdateDate == null;
Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null;
}
// 检查密码是否过期
public boolean passwordIsExpiration(Date pwdUpdateDate)
{
int passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
if (passwordValidateDays > 0)
Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
if (passwordValidateDays != null && passwordValidateDays > 0)
{
if (StringUtils.isNull(pwdUpdateDate))
{
@@ -16,10 +16,11 @@ 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.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysMenu;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.service.ISysMenuService;
/**
@@ -70,7 +71,7 @@ public class SysMenuController extends BaseController
{
return AjaxResult.warn("菜单已分配,不允许删除");
}
ShiroUtils.clearCachedAuthorizationInfo();
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.deleteMenuById(menuId));
}
@@ -109,7 +110,7 @@ public class SysMenuController extends BaseController
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
menu.setCreateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.insertMenu(menu));
}
@@ -137,7 +138,7 @@ public class SysMenuController extends BaseController
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
menu.setUpdateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.updateMenu(menu));
}
@@ -15,7 +15,7 @@ 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.framework.util.ShiroUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.system.domain.SysNotice;
import com.ruoyi.system.service.ISysNoticeService;
@@ -17,8 +17,8 @@ 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.ShiroUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.service.ISysPostService;
@@ -12,15 +12,15 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.RuoYiConfig;
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.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysUserService;
/**
@@ -156,7 +156,7 @@ public class SysProfileController extends BaseController
{
if (!file.isEmpty())
{
String avatar = FileUploadUtils.upload(Global.getAvatarPath(), file);
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file);
currentUser.setAvatar(avatar);
if (userService.updateUserInfo(currentUser) > 0)
{
@@ -8,8 +8,8 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.framework.shiro.service.SysRegisterService;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysConfigService;
/**
@@ -15,12 +15,13 @@ 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.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
@@ -97,7 +98,7 @@ public class SysRoleController extends BaseController
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setCreateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(roleService.insertRole(role));
}
@@ -131,7 +132,7 @@ public class SysRoleController extends BaseController
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setUpdateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(roleService.updateRole(role));
}
@@ -170,14 +171,7 @@ public class SysRoleController extends BaseController
@ResponseBody
public AjaxResult remove(String ids)
{
try
{
return toAjax(roleService.deleteRoleByIds(ids));
}
catch (Exception e)
{
return error(e.getMessage());
}
return toAjax(roleService.deleteRoleByIds(ids));
}
/**
@@ -17,14 +17,14 @@ 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.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
@@ -240,14 +240,7 @@ public class SysUserController extends BaseController
@ResponseBody
public AjaxResult remove(String ids)
{
try
{
return toAjax(userService.deleteUserByIds(ids));
}
catch (Exception e)
{
return error(e.getMessage());
}
return toAjax(userService.deleteUserByIds(ids));
}
/**
@@ -3,7 +3,7 @@ package com.ruoyi.web.core.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.RuoYiConfig;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
@@ -61,9 +61,9 @@ public class SwaggerConfig
// 描述
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
// 作者信息
.contact(new Contact(Global.getName(), null, null))
.contact(new Contact(RuoYiConfig.getName(), null, null))
// 版本
.version("版本号:" + Global.getVersion())
.version("版本号:" + RuoYiConfig.getVersion())
.build();
}
}
@@ -3,9 +3,9 @@ ruoyi:
# 名称
name: RuoYi
# 版本
version: 4.5.0
version: 4.6.0
# 版权年份
copyrightYear: 2019
copyrightYear: 2021
# 实例演示开关
demoEnabled: true
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
@@ -42,6 +42,17 @@
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"
@@ -1,5 +1,5 @@
/*!
* bootstrap-fileinput v5.1.2
* bootstrap-fileinput v5.1.3
* http://plugins.krajee.com/file-input
*
* Krajee default styling for bootstrap-fileinput.
@@ -200,6 +200,10 @@
.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 {
@@ -241,19 +245,14 @@
}
.krajee-default .file-preview-text {
display: block;
color: #428bca;
border: 1px solid #ddd;
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
outline: none;
padding: 8px;
resize: none;
}
.krajee-default .file-preview-html {
border: 1px solid #ddd;
padding: 8px;
overflow: auto;
}
.krajee-default .file-other-icon {
@@ -316,7 +315,7 @@
}
.kv-upload-progress .progress-bar {
height: 11px;
height: 20px;
font-family: Verdana, Helvetica, sans-serif;
}
@@ -434,7 +433,7 @@
}
.file-uploading {
background: url(loading-sm.gif) no-repeat center bottom 10px;
background: url(../img/loading-sm.gif) no-repeat center bottom 10px;
opacity: 0.65;
}
@@ -557,4 +556,8 @@
background-color: #d9edf7;
border-color: #17a2b8;
box-shadow: none !important;
}
.file-preview .kv-zoom-cache {
display: none;
}
@@ -1,5 +1,5 @@
/*!
* bootstrap-fileinput v5.1.2
* bootstrap-fileinput v5.1.3
* http://plugins.krajee.com/file-input
*
* Author: Kartik Visweswaran
@@ -111,7 +111,7 @@
if (!relativePath) {
return null;
}
return (file.size + '_' + relativePath.replace(/\s/img, '_'));
return (file.size + '_' + encodeURIComponent(relativePath).replace(/%/g, '_'));
},
getFrameSelector: function (id, selector) {
selector = selector || '';
@@ -471,18 +471,8 @@
uniqId: function () {
return (new Date().getTime() + Math.floor(Math.random() * Math.pow(10, 15))).toString(36);
},
parseEventCallback: function (str) {
return Function('\'use strict\'; return (function() { ' + str + ' });')(); // jshint ignore:line
},
cspBuffer: {
CSP_ATTRIB: 'data-csp-01928735', // a randomly named temporary attribute to store the CSP elem id
domEventsList: [
'mousedown', 'mouseup', 'click', 'dblclick', 'mousemove', 'mouseover', 'mousewheel', 'mouseout',
'contextmenu', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'keydown', 'keypress', 'keyup',
'focus', 'blur', 'change', 'submit', 'scroll', 'resize', 'hashchange', 'load', 'unload',
'cut', 'copy', 'paste'
],
domElementEvents: {},
domElementsStyles: {},
stash: function (htmlString) {
var self = this, outerDom = $.parseHTML('<div>' + htmlString + '</div>'), $el = $(outerDom);
@@ -503,20 +493,6 @@
}
});
$el.filter('*').removeAttr('style'); // make sure all style attr are removed
$.each(self.domEventsList, function (key, eventName) { // handle onXXX events set as inline markup
var id, fn, event = 'on' + eventName, $inlineEvent = $el.find('[' + event + ']');
if ($inlineEvent.length) {
fn = $h.parseEventCallback($inlineEvent.attr(event));
if ($inlineEvent.attr(self.CSP_ATTRIB)) {
id = $inlineEvent.attr(self.CSP_ATTRIB);
} else {
id = $h.uniqId();
self.domElementEvents[id] = [];
}
self.domElementEvents[id].push({name: eventName + '.csp', handler: fn}); // special csp namespace
$inlineEvent.removeAttr(event).attr(self.CSP_ATTRIB, id);
}
});
var values = Object.values ? Object.values(outerDom) : Object.keys(outerDom).map(function (itm) {
return outerDom[itm];
});
@@ -527,22 +503,13 @@
apply: function (domElement) {
var self = this, $el = $(domElement);
$el.find('[' + self.CSP_ATTRIB + ']').each(function (key, elem) {
var $elem = $(elem), id = $elem.attr(self.CSP_ATTRIB), styles = self.domElementsStyles[id],
events = self.domElementEvents[id];
var $elem = $(elem), id = $elem.attr(self.CSP_ATTRIB), styles = self.domElementsStyles[id];
if (styles) {
$elem.css(styles);
}
if (events) {
$.each(events, function (key, event) {
if (event && event.name) {
$elem.off(event.name).on(event.name, event.handler);
}
});
}
$elem.removeAttr(self.CSP_ATTRIB);
});
self.domElementsStyles = {};
self.domElementEvents = {};
}
},
setHtml: function ($elem, htmlString) {
@@ -1651,7 +1618,10 @@
tModalMain, tModal, tProgress, tSize, tFooter, tActions, tActionDelete, tActionUpload, tActionDownload,
tActionZoom, tActionDrag, tIndicator, tTagBef, tTagBef1, tTagBef2, tTagAft, tGeneric, tHtml, tImage,
tText, tOffice, tGdocs, tVideo, tAudio, tFlash, tObject, tPdf, tOther, tStyle, tZoomCache, vDefaultDim,
tStats;
tStats, tModalLabel, renderObject = function (type, mime) {
return '<object class="kv-preview-data file-preview-' + type + '" title="{caption}" ' +
'data="{data}" type="' + mime + '"' + tStyle + '>\n' + $h.DEFAULT_PREVIEW + '\n</object>\n';
};
tMain1 = '{preview}\n' +
'<div class="kv-upload-progress kv-hidden"></div><div class="clearfix"></div>\n' +
'<div class="input-group {class}">\n' +
@@ -1680,7 +1650,7 @@
// noinspection HtmlUnknownAttribute
tCaption = '<div class="file-caption form-control {class}" tabindex="500">\n' +
' <span class="file-caption-icon"></span>\n' +
' <input class="file-caption-name" onkeydown="return false;" onpaste="return false;">\n' +
' <input class="file-caption-name">\n' +
'</div>';
//noinspection HtmlUnknownAttribute
tBtnDefault = '<button type="{type}" tabindex="500" title="{title}" class="{css}" ' +
@@ -1689,12 +1659,13 @@
tBtnLink = '<a href="{href}" tabindex="500" title="{title}" class="{css}" {status}>{icon} {label}</a>';
//noinspection HtmlUnknownAttribute
tBtnBrowse = '<div tabindex="500" class="{css}" {status}>{icon} {label}</div>';
tModalLabel = $h.MODAL_ID + 'Label';
tModalMain = '<div id="' + $h.MODAL_ID + '" class="file-zoom-dialog modal fade" ' +
'tabindex="-1" aria-labelledby="' + $h.MODAL_ID + 'Label"></div>';
'tabindex="-1" aria-labelledby="' + tModalLabel + '"></div>';
tModal = '<div class="modal-dialog modal-lg{rtl}" role="document">\n' +
' <div class="modal-content">\n' +
' <div class="modal-header">\n' +
' <h5 class="modal-title">{heading}</h5>\n' +
' <h5 class="modal-title" id="' + tModalLabel + '">{heading}</h5>\n' +
' <span class="kv-zoom-title"></span>\n' +
' <div class="kv-zoom-actions">{toggleheader}{fullscreen}{borderless}{close}</div>\n' +
' </div>\n' +
@@ -1747,11 +1718,11 @@
tTagAft = '</div>{footer}\n{zoomCache}</div>\n';
tGeneric = '{content}\n';
tStyle = ' {style}';
tHtml = '<div class="kv-preview-data file-preview-html" title="{caption}"' + tStyle + '>{data}</div>\n';
tImage = '<img src="{data}" class="file-preview-image kv-preview-data" title="{title}" ' +
'alt="{alt}"' + tStyle + '>\n';
tText = '<textarea class="kv-preview-data file-preview-text" title="{caption}" readonly' + tStyle + '>' +
'{data}</textarea>\n';
tHtml = renderObject('html', 'text/html');
tText = renderObject('text', 'text/plain;charset=UTF-8');
tPdf = renderObject('pdf', 'application/pdf');
tImage = '<img src="{data}" class="file-preview-image kv-preview-data" title="{title}" alt="{alt}"' +
tStyle + '>\n';
tOffice = '<iframe class="kv-preview-data file-preview-office" ' +
'src="https://view.officeapps.live.com/op/embed.aspx?src={data}"' + tStyle + '></iframe>';
tGdocs = '<iframe class="kv-preview-data file-preview-gdocs" ' +
@@ -1761,12 +1732,11 @@
tAudio = '<!--suppress ALL --><audio class="kv-preview-data file-preview-audio" controls' + tStyle + '>\n<source src="{data}" ' +
'type="{type}">\n' + $h.DEFAULT_PREVIEW + '\n</audio>\n';
tFlash = '<embed class="kv-preview-data file-preview-flash" src="{data}" type="application/x-shockwave-flash"' + tStyle + '>\n';
tPdf = '<embed class="kv-preview-data file-preview-pdf" src="{data}" type="application/pdf"' + tStyle + '>\n';
tObject = '<object class="kv-preview-data file-preview-object file-object {typeCss}" ' +
'data="{data}" type="{type}"' + tStyle + '>\n' + '<param name="movie" value="{caption}" />\n' +
$h.OBJECT_PARAMS + ' ' + $h.DEFAULT_PREVIEW + '\n</object>\n';
tOther = '<div class="kv-preview-data file-preview-other-frame"' + tStyle + '>\n' + $h.DEFAULT_PREVIEW + '\n</div>\n';
tZoomCache = '<div class="kv-zoom-cache" style="display:none">{zoomContent}</div>';
tZoomCache = '<div class="kv-zoom-cache">{zoomContent}</div>';
vDefaultDim = {width: '100%', height: '100%', 'min-height': '480px'};
if (self._isPdfRendered()) {
tPdf = self.pdfRendererTemplate.replace('{renderer}', self._encodeURI(self.pdfRendererUrl));
@@ -1879,7 +1849,7 @@
},
text: function (vType, vName) {
return $h.compare(vType, 'text.*') || $h.compare(vName, /\.(xml|javascript)$/i) ||
$h.compare(vName, /\.(txt|md|csv|nfo|ini|json|php|js|css)$/i);
$h.compare(vName, /\.(txt|md|nfo|ini|json|php|js|css)$/i);
},
video: function (vType, vName) {
return $h.compare(vType, 'video.*') && ($h.compare(vType, /(ogg|mp4|mp?g|mov|webm|3gp)$/i) ||
@@ -1956,7 +1926,7 @@
$.each(self.previewContentTemplates, function (key, value) {
if ($h.isEmpty(self.previewTemplates[key])) {
tagBef = tags.tagBefore2;
if (key === 'generic' || key === 'image' || key === 'html' || key === 'text') {
if (key === 'generic' || key === 'image') {
tagBef = tags.tagBefore1;
}
if (self._isPdfRendered() && key === 'pdf') {
@@ -2473,7 +2443,7 @@
}
},
_listen: function () {
var self = this, $el = self.$element, $form = self.$form, $cont = self.$container, fullScreenEvents;
var self = this, $el = self.$element, $form = self.$form, $cont = self.$container, fullScreenEv, $cap, fn;
self._handler($el, 'click', function (e) {
if ($el.hasClass('file-no-browse')) {
if ($el.data('zoneClicked')) {
@@ -2487,9 +2457,15 @@
if (self.showBrowse) {
self._handler(self.$btnFile, 'click', $.proxy(self._browse, self));
}
$cap = $cont.find('.file-caption-name');
fn = function () {
return false;
};
self._handler($cont.find('.fileinput-remove:not([disabled])'), 'click', $.proxy(self.clear, self));
self._handler($cont.find('.fileinput-cancel'), 'click', $.proxy(self.cancel, self));
self._handler($cont.find('.fileinput-pause'), 'click', $.proxy(self.pause, self));
self._handler($cap, 'keydown', fn);
self._handler($cap, 'paste', fn);
self._initDragDrop();
self._handler($form, 'reset', $.proxy(self.clear, self));
if (!self.isAjaxUpload) {
@@ -2499,8 +2475,8 @@
self._handler($(window), 'resize', function () {
self._listenFullScreen(screen.width === window.innerWidth && screen.height === window.innerHeight);
});
fullScreenEvents = 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange';
self._handler($(document), fullScreenEvents, function () {
fullScreenEv = 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange';
self._handler($(document), fullScreenEv, function () {
self._listenFullScreen($h.checkFullScreen());
});
self._autoFitContent();
@@ -2563,15 +2539,15 @@
e.preventDefault();
},
_zoneDragEnter: function (e) {
var self = this, dataTransfer = e.originalEvent.dataTransfer,
hasFiles = $.inArray('Files', dataTransfer.types) > -1;
var self = this, dt = e.originalEvent.dataTransfer, hasFiles = $.inArray('Files', dt.types) > -1;
self._zoneDragDropInit(e);
if (self.isDisabled || !hasFiles) {
e.originalEvent.dataTransfer.effectAllowed = 'none';
e.originalEvent.dataTransfer.dropEffect = 'none';
dt.effectAllowed = 'none';
dt.dropEffect = 'none';
return;
}
if (self._raise('fileDragEnter', {'sourceEvent': e, 'files': dataTransfer.types.Files})) {
dt.dropEffect = 'copy';
if (self._raise('fileDragEnter', {'sourceEvent': e, 'files': dt.types.Files})) {
$h.addCss(self.$dropZone, 'file-highlighted');
}
},
@@ -2588,8 +2564,8 @@
},
_zoneDrop: function (e) {
/** @namespace e.originalEvent.dataTransfer */
var self = this, i, $el = self.$element, dataTransfer = e.originalEvent.dataTransfer,
files = dataTransfer.files, items = dataTransfer.items, folders = $h.getDragDropFolders(items),
var self = this, i, $el = self.$element, dt = e.originalEvent.dataTransfer,
files = dt.files, items = dt.items, folders = $h.getDragDropFolders(items),
processFiles = function () {
if (!self.isAjaxUpload) {
self.changeTriggered = true;
@@ -3639,10 +3615,18 @@
self._showFileError(errMsg, params);
}, self.processDelay);
};
formdata.append(self.uploadFileAttr, fileObj.file, fileName);
self._setFileData(formdata, fileObj.file, fileName, id);
self._setUploadData(formdata, {fileId: id});
self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, formdata, id, i);
},
_setFileData: function (formdata, file, fileName, fileId) {
var self = this, preProcess = self.preProcessUpload;
if (preProcess && typeof preProcess === 'function') {
formdata.append(self.uploadFileAttr, preProcess(fileId, file));
} else {
formdata.append(self.uploadFileAttr, file, fileName);
}
},
_uploadBatch: function () {
var self = this, fm = self.fileManager, total = fm.total(), params = {}, fnBefore, fnSuccess, fnError,
fnComplete, hasPostData = total > 0 || !$.isEmptyObject(self.uploadExtraData), errMsg,
@@ -3766,7 +3750,7 @@
var ctr = 0;
$.each(self.fileManager.stack, function (key, data) {
if (!$h.isEmpty(data.file)) {
formdata.append(self.uploadFileAttr, data.file, (data.nameFmt || ('untitled_' + ctr)));
self._setFileData(formdata, data.file, (data.nameFmt || ('untitled_' + ctr)), key);
}
ctr++;
});
@@ -4082,9 +4066,6 @@
css = css.replace(' ' + $h.SORT_CSS, '');
}
tmplt = self._parseFilePreviewIcon(tmplt, fname);
if (c === 'text') {
d = $h.htmlEncode(d);
}
if (cat === 'object' && !ftype) {
$.each(self.defaults.fileTypeSettings, function (key, func) {
if (key === 'object' || key === 'other') {
@@ -4161,12 +4142,9 @@
}
var self = this, fname = $h.getFileName(file), ftype = fileInfo.type, caption = fileInfo.name,
cat = self._parseFileType(ftype, fname), content, $preview = self.$preview, fsize = file.size || 0,
iData = (cat === 'text' || cat === 'html' || cat === 'image') ? theFile.target.result : data,
iData = cat === 'image' ? theFile.target.result : data,
fileId = self.fileManager.getId(file), previewId = self._getThumbId(fileId);
/** @namespace window.DOMPurify */
if (cat === 'html' && self.purifyHtml && window.DOMPurify) {
iData = window.DOMPurify.sanitize(iData);
}
content = self._generatePreviewTemplate(cat, iData, fname, ftype, previewId, fileId, false, fsize);
self._clearDefaultPreview();
self._addToPreview($preview, content);
@@ -5217,12 +5195,12 @@
return;
}
self.lock(true);
var file = files[i], previewId = previewInitId + '-' + self._getFileId(file), fSizeKB, j, msg,
var file = files[i], id = self._getFileId(file), previewId = previewInitId + '-' + id, fSizeKB, j, msg,
fnText = settings.text, fnImage = settings.image, fnHtml = settings.html, typ, chk, typ1, typ2,
caption = self._getFileName(file, ''), fileSize = (file && file.size || 0) / 1000,
fileExtExpr = '', previewData = $h.createObjectURL(file), fileCount = 0,
strTypes = '', fileId, canLoad, fileReaderAborted = false,
func, knownTypes = 0, isText, isHtml, isImage, txtFlag, processFileLoaded = function () {
func, knownTypes = 0, isImage, txtFlag, processFileLoaded = function () {
var msg = msgProgress.setTokens({
'index': i + 1,
'files': numFiles,
@@ -5234,7 +5212,7 @@
self._updateFileDetails(numFiles);
readFile(i + 1);
}, self.processDelay);
if (self._raise('fileloaded', [file, previewId, i, reader]) && self.isAjaxUpload) {
if (self._raise('fileloaded', [file, previewId, id, i, reader]) && self.isAjaxUpload) {
fm.add(file);
}
};
@@ -5336,12 +5314,10 @@
self._updateFileDetails(numFiles);
}
readFile(i + 1);
self._raise('fileloaded', [file, previewId, i]);
self._raise('fileloaded', [file, previewId, id, i]);
}, 10);
return;
}
isText = fnText(file.type, caption);
isHtml = fnHtml(file.type, caption);
isImage = fnImage(file.type, caption);
$status.html(msgLoading.replace('{index}', i + 1).replace('{files}', numFiles));
$container.addClass('file-thumb-loading');
@@ -5349,7 +5325,7 @@
self._errorHandler(evt, caption);
};
reader.onload = function (theFile) {
var hex, fileInfo, uint, byte, bytes = [], contents, mime, readTextImage = function (textFlag) {
var hex, fileInfo, uint, byte, bytes = [], contents, mime, readImage = function () {
var newReader = new FileReader();
newReader.onerror = function (theFileNew) {
self._errorHandler(theFileNew, caption);
@@ -5368,11 +5344,7 @@
self._initFileActions();
processFileLoaded();
};
if (textFlag) {
newReader.readAsText(file, self.textEncoding);
} else {
newReader.readAsDataURL(file);
}
newReader.readAsDataURL(file);
};
fileInfo = {'name': caption, 'type': file.type};
$.each(settings, function (k, f) {
@@ -5393,12 +5365,9 @@
mime = $h.isSvg(contents) ? 'image/svg+xml' : $h.getMimeType(hex, contents, file.type);
}
fileInfo = {'name': caption, 'type': mime};
isText = fnText(mime, '');
isHtml = fnHtml(mime, '');
isImage = fnImage(mime, '');
txtFlag = isText || isHtml;
if (txtFlag || isImage) {
readTextImage(txtFlag);
if (isImage) {
readImage(txtFlag);
return;
}
}
@@ -5431,14 +5400,10 @@
}, self.processDelay);
}
};
if (isText || isHtml) {
reader.readAsText(file, self.textEncoding);
if (isImage) {
reader.readAsDataURL(file);
} else {
if (isImage) {
reader.readAsDataURL(file);
} else {
reader.readAsArrayBuffer(file);
}
reader.readAsArrayBuffer(file);
}
};
@@ -5831,7 +5796,6 @@
frameClass: 'krajee-default',
mainClass: 'file-caption-main',
mainTemplate: null,
purifyHtml: true,
fileSizeGetter: null,
initialCaption: '',
initialPreview: [],
@@ -5939,7 +5903,7 @@
resizeQuality: 0.92,
resizeDefaultImageType: 'image/jpeg',
resizeIfSizeMoreThan: 0, // in KB
minFileSize: 0,
minFileSize: -1,
maxFileSize: 0,
maxFilePreviewSize: 25600, // 25 MB
minFileCount: 0,
@@ -5949,11 +5913,11 @@
msgValidationErrorClass: 'text-danger',
msgValidationErrorIcon: '<i class="glyphicon glyphicon-exclamation-sign"></i> ',
msgErrorClass: 'file-error-message',
progressThumbClass: 'progress-bar progress-bar-striped active',
progressClass: 'progress-bar bg-success progress-bar-success progress-bar-striped active',
progressInfoClass: 'progress-bar bg-info progress-bar-info progress-bar-striped active',
progressThumbClass: 'progress-bar progress-bar-striped active progress-bar-animated',
progressClass: 'progress-bar bg-success progress-bar-success progress-bar-striped active progress-bar-animated',
progressInfoClass: 'progress-bar bg-info progress-bar-info progress-bar-striped active progress-bar-animated',
progressCompleteClass: 'progress-bar bg-success progress-bar-success',
progressPauseClass: 'progress-bar bg-primary progress-bar-primary progress-bar-striped active',
progressPauseClass: 'progress-bar bg-primary progress-bar-primary progress-bar-striped active progress-bar-animated',
progressErrorClass: 'progress-bar bg-danger progress-bar-danger',
progressUploadThreshold: 99,
previewFileType: 'image',
@@ -5970,6 +5934,7 @@
fileActionSettings: {},
otherActionButtons: '',
textEncoding: 'UTF-8',
preProcessUpload: null,
ajaxSettings: {},
ajaxDeleteSettings: {},
showAjaxErrorDetails: true,
@@ -6071,7 +6036,7 @@
close: 'Close detailed preview'
}
};
$.fn.fileinputLocales.zh = {
fileSingle: '文件',
filePlural: '个文件',
@@ -6088,13 +6053,14 @@
msgNoFilesSelected: '未选择文件',
msgPaused: 'Paused',
msgCancelled: '取消',
msgPlaceholder: '选择 {files}...',
msgPlaceholder: '选择 {files} ...',
msgZoomModalHeading: '详细预览',
msgFileRequired: '必须选择一个文件上传.',
msgSizeTooSmall: '文件 "{name}" (<b>{size} KB</b>) 必须大于限定大小 <b>{minSize} KB</b>.',
msgSizeTooLarge: '文件 "{name}" (<b>{size} KB</b>) 超过了允许大小 <b>{maxSize} KB</b>.',
msgFilesTooLess: '你必须选择最少 <b>{n}</b> {files} 来上传. ',
msgFilesTooMany: '选择的上传文件个数 <b>({n})</b> 超出最大文件的限制个数 <b>{m}</b>.',
msgTotalFilesTooMany: 'You can upload a maximum of <b>{m}</b> files (<b>{n}</b> files detected).',
msgFileNotFound: '文件 "{name}" 未找到!',
msgFileSecured: '安全限制,为了防止读取文件 "{name}".',
msgFileNotReadable: '文件 "{name}" 不可读.',
@@ -6114,10 +6080,10 @@
'object': 'object'
},
msgUploadAborted: '该文件上传被中止',
msgUploadThreshold: '处理中...',
msgUploadBegin: '正在初始化...',
msgUploadThreshold: '处理中 &hellip;',
msgUploadBegin: '正在初始化 &hellip;',
msgUploadEnd: '完成',
msgUploadResume: 'Resuming upload...',
msgUploadResume: 'Resuming upload &hellip;',
msgUploadEmpty: '无效的文件上传.',
msgUploadError: 'Upload Error',
msgDeleteError: 'Delete Error',
@@ -6158,7 +6124,7 @@
indicatorSuccessTitle: '上传',
indicatorErrorTitle: '上传错误',
indicatorPausedTitle: 'Upload Paused',
indicatorLoadingTitle: '上传 ...'
indicatorLoadingTitle: '上传 &hellip;'
},
previewZoomButtonTitles: {
prev: '预览上一个文件',
@@ -6169,7 +6135,7 @@
close: '关闭当前预览'
}
};
$.fn.fileinput.Constructor = FileInput;
/**
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,771 +1,109 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) :
typeof define === 'function' && define.amd ? define(['jquery'], factory) :
(global = global || self, factory(global.jQuery));
}(this, (function ($) { 'use strict';
$ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var check = function (it) {
return it && it.Math == Math && it;
};
// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
var global_1 =
// eslint-disable-next-line no-undef
check(typeof globalThis == 'object' && globalThis) ||
check(typeof window == 'object' && window) ||
check(typeof self == 'object' && self) ||
check(typeof commonjsGlobal == 'object' && commonjsGlobal) ||
// eslint-disable-next-line no-new-func
Function('return this')();
var fails = function (exec) {
try {
return !!exec();
} catch (error) {
return true;
}
};
// Thank's IE8 for his funny defineProperty
var descriptors = !fails(function () {
return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
});
var nativePropertyIsEnumerable = {}.propertyIsEnumerable;
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
// Nashorn ~ JDK8 bug
var NASHORN_BUG = getOwnPropertyDescriptor && !nativePropertyIsEnumerable.call({ 1: 2 }, 1);
// `Object.prototype.propertyIsEnumerable` method implementation
// https://tc39.github.io/ecma262/#sec-object.prototype.propertyisenumerable
var f = NASHORN_BUG ? function propertyIsEnumerable(V) {
var descriptor = getOwnPropertyDescriptor(this, V);
return !!descriptor && descriptor.enumerable;
} : nativePropertyIsEnumerable;
var objectPropertyIsEnumerable = {
f: f
};
var createPropertyDescriptor = function (bitmap, value) {
return {
enumerable: !(bitmap & 1),
configurable: !(bitmap & 2),
writable: !(bitmap & 4),
value: value
};
};
var toString = {}.toString;
var classofRaw = function (it) {
return toString.call(it).slice(8, -1);
};
var split = ''.split;
// fallback for non-array-like ES3 and non-enumerable old V8 strings
var indexedObject = fails(function () {
// throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
// eslint-disable-next-line no-prototype-builtins
return !Object('z').propertyIsEnumerable(0);
}) ? function (it) {
return classofRaw(it) == 'String' ? split.call(it, '') : Object(it);
} : Object;
// `RequireObjectCoercible` abstract operation
// https://tc39.github.io/ecma262/#sec-requireobjectcoercible
var requireObjectCoercible = function (it) {
if (it == undefined) throw TypeError("Can't call method on " + it);
return it;
};
// toObject with fallback for non-array-like ES3 strings
var toIndexedObject = function (it) {
return indexedObject(requireObjectCoercible(it));
};
var isObject = function (it) {
return typeof it === 'object' ? it !== null : typeof it === 'function';
};
// `ToPrimitive` abstract operation
// https://tc39.github.io/ecma262/#sec-toprimitive
// instead of the ES6 spec version, we didn't implement @@toPrimitive case
// and the second argument - flag - preferred type is a string
var toPrimitive = function (input, PREFERRED_STRING) {
if (!isObject(input)) return input;
var fn, val;
if (PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
if (typeof (fn = input.valueOf) == 'function' && !isObject(val = fn.call(input))) return val;
if (!PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
throw TypeError("Can't convert object to primitive value");
};
var hasOwnProperty = {}.hasOwnProperty;
var has = function (it, key) {
return hasOwnProperty.call(it, key);
};
var document = global_1.document;
// typeof document.createElement is 'object' in old IE
var EXISTS = isObject(document) && isObject(document.createElement);
var documentCreateElement = function (it) {
return EXISTS ? document.createElement(it) : {};
};
// Thank's IE8 for his funny defineProperty
var ie8DomDefine = !descriptors && !fails(function () {
return Object.defineProperty(documentCreateElement('div'), 'a', {
get: function () { return 7; }
}).a != 7;
});
var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
// `Object.getOwnPropertyDescriptor` method
// https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptor
var f$1 = descriptors ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
O = toIndexedObject(O);
P = toPrimitive(P, true);
if (ie8DomDefine) try {
return nativeGetOwnPropertyDescriptor(O, P);
} catch (error) { /* empty */ }
if (has(O, P)) return createPropertyDescriptor(!objectPropertyIsEnumerable.f.call(O, P), O[P]);
};
var objectGetOwnPropertyDescriptor = {
f: f$1
};
var anObject = function (it) {
if (!isObject(it)) {
throw TypeError(String(it) + ' is not an object');
} return it;
};
var nativeDefineProperty = Object.defineProperty;
// `Object.defineProperty` method
// https://tc39.github.io/ecma262/#sec-object.defineproperty
var f$2 = descriptors ? nativeDefineProperty : function defineProperty(O, P, Attributes) {
anObject(O);
P = toPrimitive(P, true);
anObject(Attributes);
if (ie8DomDefine) try {
return nativeDefineProperty(O, P, Attributes);
} catch (error) { /* empty */ }
if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
if ('value' in Attributes) O[P] = Attributes.value;
return O;
};
var objectDefineProperty = {
f: f$2
};
var createNonEnumerableProperty = descriptors ? function (object, key, value) {
return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value));
} : function (object, key, value) {
object[key] = value;
return object;
};
var setGlobal = function (key, value) {
try {
createNonEnumerableProperty(global_1, key, value);
} catch (error) {
global_1[key] = value;
} return value;
};
var SHARED = '__core-js_shared__';
var store = global_1[SHARED] || setGlobal(SHARED, {});
var sharedStore = store;
var functionToString = Function.toString;
// this helper broken in `3.4.1-3.4.4`, so we can't use `shared` helper
if (typeof sharedStore.inspectSource != 'function') {
sharedStore.inspectSource = function (it) {
return functionToString.call(it);
};
}
var inspectSource = sharedStore.inspectSource;
var WeakMap = global_1.WeakMap;
var nativeWeakMap = typeof WeakMap === 'function' && /native code/.test(inspectSource(WeakMap));
var shared = createCommonjsModule(function (module) {
(module.exports = function (key, value) {
return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
})('versions', []).push({
version: '3.6.0',
mode: 'global',
copyright: '© 2019 Denis Pushkarev (zloirock.ru)'
});
});
var id = 0;
var postfix = Math.random();
var uid = function (key) {
return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id + postfix).toString(36);
};
var keys = shared('keys');
var sharedKey = function (key) {
return keys[key] || (keys[key] = uid(key));
};
var hiddenKeys = {};
var WeakMap$1 = global_1.WeakMap;
var set, get, has$1;
var enforce = function (it) {
return has$1(it) ? get(it) : set(it, {});
};
var getterFor = function (TYPE) {
return function (it) {
var state;
if (!isObject(it) || (state = get(it)).type !== TYPE) {
throw TypeError('Incompatible receiver, ' + TYPE + ' required');
} return state;
};
};
if (nativeWeakMap) {
var store$1 = new WeakMap$1();
var wmget = store$1.get;
var wmhas = store$1.has;
var wmset = store$1.set;
set = function (it, metadata) {
wmset.call(store$1, it, metadata);
return metadata;
};
get = function (it) {
return wmget.call(store$1, it) || {};
};
has$1 = function (it) {
return wmhas.call(store$1, it);
};
} else {
var STATE = sharedKey('state');
hiddenKeys[STATE] = true;
set = function (it, metadata) {
createNonEnumerableProperty(it, STATE, metadata);
return metadata;
};
get = function (it) {
return has(it, STATE) ? it[STATE] : {};
};
has$1 = function (it) {
return has(it, STATE);
};
}
var internalState = {
set: set,
get: get,
has: has$1,
enforce: enforce,
getterFor: getterFor
};
var redefine = createCommonjsModule(function (module) {
var getInternalState = internalState.get;
var enforceInternalState = internalState.enforce;
var TEMPLATE = String(String).split('String');
(module.exports = function (O, key, value, options) {
var unsafe = options ? !!options.unsafe : false;
var simple = options ? !!options.enumerable : false;
var noTargetGet = options ? !!options.noTargetGet : false;
if (typeof value == 'function') {
if (typeof key == 'string' && !has(value, 'name')) createNonEnumerableProperty(value, 'name', key);
enforceInternalState(value).source = TEMPLATE.join(typeof key == 'string' ? key : '');
}
if (O === global_1) {
if (simple) O[key] = value;
else setGlobal(key, value);
return;
} else if (!unsafe) {
delete O[key];
} else if (!noTargetGet && O[key]) {
simple = true;
}
if (simple) O[key] = value;
else createNonEnumerableProperty(O, key, value);
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, 'toString', function toString() {
return typeof this == 'function' && getInternalState(this).source || inspectSource(this);
});
});
var path = global_1;
var aFunction = function (variable) {
return typeof variable == 'function' ? variable : undefined;
};
var getBuiltIn = function (namespace, method) {
return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global_1[namespace])
: path[namespace] && path[namespace][method] || global_1[namespace] && global_1[namespace][method];
};
var ceil = Math.ceil;
var floor = Math.floor;
// `ToInteger` abstract operation
// https://tc39.github.io/ecma262/#sec-tointeger
var toInteger = function (argument) {
return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);
};
var min = Math.min;
// `ToLength` abstract operation
// https://tc39.github.io/ecma262/#sec-tolength
var toLength = function (argument) {
return argument > 0 ? min(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
};
var max = Math.max;
var min$1 = Math.min;
// Helper for a popular repeating case of the spec:
// Let integer be ? ToInteger(index).
// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
var toAbsoluteIndex = function (index, length) {
var integer = toInteger(index);
return integer < 0 ? max(integer + length, 0) : min$1(integer, length);
};
// `Array.prototype.{ indexOf, includes }` methods implementation
var createMethod = function (IS_INCLUDES) {
return function ($this, el, fromIndex) {
var O = toIndexedObject($this);
var length = toLength(O.length);
var index = toAbsoluteIndex(fromIndex, length);
var value;
// Array#includes uses SameValueZero equality algorithm
// eslint-disable-next-line no-self-compare
if (IS_INCLUDES && el != el) while (length > index) {
value = O[index++];
// eslint-disable-next-line no-self-compare
if (value != value) return true;
// Array#indexOf ignores holes, Array#includes - not
} else for (;length > index; index++) {
if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
} return !IS_INCLUDES && -1;
};
};
var arrayIncludes = {
// `Array.prototype.includes` method
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
includes: createMethod(true),
// `Array.prototype.indexOf` method
// https://tc39.github.io/ecma262/#sec-array.prototype.indexof
indexOf: createMethod(false)
};
var indexOf = arrayIncludes.indexOf;
var objectKeysInternal = function (object, names) {
var O = toIndexedObject(object);
var i = 0;
var result = [];
var key;
for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
// Don't enum bug & hidden keys
while (names.length > i) if (has(O, key = names[i++])) {
~indexOf(result, key) || result.push(key);
}
return result;
};
// IE8- don't enum bug keys
var enumBugKeys = [
'constructor',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'toLocaleString',
'toString',
'valueOf'
];
var hiddenKeys$1 = enumBugKeys.concat('length', 'prototype');
// `Object.getOwnPropertyNames` method
// https://tc39.github.io/ecma262/#sec-object.getownpropertynames
var f$3 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
return objectKeysInternal(O, hiddenKeys$1);
};
var objectGetOwnPropertyNames = {
f: f$3
};
var f$4 = Object.getOwnPropertySymbols;
var objectGetOwnPropertySymbols = {
f: f$4
};
// all object keys, includes non-enumerable and symbols
var ownKeys = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
var keys = objectGetOwnPropertyNames.f(anObject(it));
var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
};
var copyConstructorProperties = function (target, source) {
var keys = ownKeys(source);
var defineProperty = objectDefineProperty.f;
var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (!has(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
}
};
var replacement = /#|\.prototype\./;
var isForced = function (feature, detection) {
var value = data[normalize(feature)];
return value == POLYFILL ? true
: value == NATIVE ? false
: typeof detection == 'function' ? fails(detection)
: !!detection;
};
var normalize = isForced.normalize = function (string) {
return String(string).replace(replacement, '.').toLowerCase();
};
var data = isForced.data = {};
var NATIVE = isForced.NATIVE = 'N';
var POLYFILL = isForced.POLYFILL = 'P';
var isForced_1 = isForced;
var getOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f;
/*
options.target - name of the target object
options.global - target is the global object
options.stat - export as static methods of target
options.proto - export as prototype methods of target
options.real - real prototype method for the `pure` version
options.forced - export even if the native feature is available
options.bind - bind methods to the target, required for the `pure` version
options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
options.unsafe - use the simple assignment of property instead of delete + defineProperty
options.sham - add a flag to not completely full polyfills
options.enumerable - export as enumerable property
options.noTargetGet - prevent calling a getter on target
*/
var _export = function (options, source) {
var TARGET = options.target;
var GLOBAL = options.global;
var STATIC = options.stat;
var FORCED, target, key, targetProperty, sourceProperty, descriptor;
if (GLOBAL) {
target = global_1;
} else if (STATIC) {
target = global_1[TARGET] || setGlobal(TARGET, {});
} else {
target = (global_1[TARGET] || {}).prototype;
}
if (target) for (key in source) {
sourceProperty = source[key];
if (options.noTargetGet) {
descriptor = getOwnPropertyDescriptor$1(target, key);
targetProperty = descriptor && descriptor.value;
} else targetProperty = target[key];
FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
// contained in target
if (!FORCED && targetProperty !== undefined) {
if (typeof sourceProperty === typeof targetProperty) continue;
copyConstructorProperties(sourceProperty, targetProperty);
}
// add a flag to not completely full polyfills
if (options.sham || (targetProperty && targetProperty.sham)) {
createNonEnumerableProperty(sourceProperty, 'sham', true);
}
// extend global
redefine(target, key, sourceProperty, options);
}
};
// `IsArray` abstract operation
// https://tc39.github.io/ecma262/#sec-isarray
var isArray = Array.isArray || function isArray(arg) {
return classofRaw(arg) == 'Array';
};
// `ToObject` abstract operation
// https://tc39.github.io/ecma262/#sec-toobject
var toObject = function (argument) {
return Object(requireObjectCoercible(argument));
};
var createProperty = function (object, key, value) {
var propertyKey = toPrimitive(key);
if (propertyKey in object) objectDefineProperty.f(object, propertyKey, createPropertyDescriptor(0, value));
else object[propertyKey] = value;
};
var nativeSymbol = !!Object.getOwnPropertySymbols && !fails(function () {
// Chrome 38 Symbol has incorrect toString conversion
// eslint-disable-next-line no-undef
return !String(Symbol());
});
var useSymbolAsUid = nativeSymbol
// eslint-disable-next-line no-undef
&& !Symbol.sham
// eslint-disable-next-line no-undef
&& typeof Symbol() == 'symbol';
var WellKnownSymbolsStore = shared('wks');
var Symbol$1 = global_1.Symbol;
var createWellKnownSymbol = useSymbolAsUid ? Symbol$1 : uid;
var wellKnownSymbol = function (name) {
if (!has(WellKnownSymbolsStore, name)) {
if (nativeSymbol && has(Symbol$1, name)) WellKnownSymbolsStore[name] = Symbol$1[name];
else WellKnownSymbolsStore[name] = createWellKnownSymbol('Symbol.' + name);
} return WellKnownSymbolsStore[name];
};
var SPECIES = wellKnownSymbol('species');
// `ArraySpeciesCreate` abstract operation
// https://tc39.github.io/ecma262/#sec-arrayspeciescreate
var arraySpeciesCreate = function (originalArray, length) {
var C;
if (isArray(originalArray)) {
C = originalArray.constructor;
// cross-realm fallback
if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
else if (isObject(C)) {
C = C[SPECIES];
if (C === null) C = undefined;
}
} return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
};
var userAgent = getBuiltIn('navigator', 'userAgent') || '';
var process = global_1.process;
var versions = process && process.versions;
var v8 = versions && versions.v8;
var match, version;
if (v8) {
match = v8.split('.');
version = match[0] + match[1];
} else if (userAgent) {
match = userAgent.match(/Edge\/(\d+)/);
if (!match || match[1] >= 74) {
match = userAgent.match(/Chrome\/(\d+)/);
if (match) version = match[1];
}
}
var v8Version = version && +version;
var SPECIES$1 = wellKnownSymbol('species');
var arrayMethodHasSpeciesSupport = function (METHOD_NAME) {
// We can't use this feature detection in V8 since it causes
// deoptimization and serious performance degradation
// https://github.com/zloirock/core-js/issues/677
return v8Version >= 51 || !fails(function () {
var array = [];
var constructor = array.constructor = {};
constructor[SPECIES$1] = function () {
return { foo: 1 };
};
return array[METHOD_NAME](Boolean).foo !== 1;
});
};
var IS_CONCAT_SPREADABLE = wellKnownSymbol('isConcatSpreadable');
var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;
var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded';
// We can't use this feature detection in V8 since it causes
// deoptimization and serious performance degradation
// https://github.com/zloirock/core-js/issues/679
var IS_CONCAT_SPREADABLE_SUPPORT = v8Version >= 51 || !fails(function () {
var array = [];
array[IS_CONCAT_SPREADABLE] = false;
return array.concat()[0] !== array;
});
var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat');
var isConcatSpreadable = function (O) {
if (!isObject(O)) return false;
var spreadable = O[IS_CONCAT_SPREADABLE];
return spreadable !== undefined ? !!spreadable : isArray(O);
};
var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;
// `Array.prototype.concat` method
// https://tc39.github.io/ecma262/#sec-array.prototype.concat
// with adding support of @@isConcatSpreadable and @@species
_export({ target: 'Array', proto: true, forced: FORCED }, {
concat: function concat(arg) { // eslint-disable-line no-unused-vars
var O = toObject(this);
var A = arraySpeciesCreate(O, 0);
var n = 0;
var i, k, length, len, E;
for (i = -1, length = arguments.length; i < length; i++) {
E = i === -1 ? O : arguments[i];
if (isConcatSpreadable(E)) {
len = toLength(E.length);
if (n + len > MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
} else {
if (n >= MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
createProperty(A, n++, E);
}
}
A.length = n;
return A;
}
});
/**
* Bootstrap Table Chinese translation
* Author: Zhixin Wen<wenzhixin2010@gmail.com>
*/
$.fn.bootstrapTable.locales['zh-CN'] = {
formatLoadingMessage: function formatLoadingMessage() {
return '正在努力地加载数据中,请稍候';
},
formatRecordsPerPage: function formatRecordsPerPage(pageNumber) {
return "\u6BCF\u9875\u663E\u793A ".concat(pageNumber, " \u6761\u8BB0\u5F55");
},
formatShowingRows: function formatShowingRows(pageFrom, pageTo, totalRows, totalNotFiltered) {
if (totalNotFiltered !== undefined && totalNotFiltered > 0 && totalNotFiltered > totalRows) {
return "\u663E\u793A\u7B2C ".concat(pageFrom, " \u5230\u7B2C ").concat(pageTo, " \u6761\u8BB0\u5F55\uFF0C\u603B\u5171 ").concat(totalRows, " \u6761\u8BB0\u5F55\uFF08\u4ECE ").concat(totalNotFiltered, " \u603B\u8BB0\u5F55\u4E2D\u8FC7\u6EE4\uFF09");
}
return "\u663E\u793A\u7B2C ".concat(pageFrom, " \u5230\u7B2C ").concat(pageTo, " \u6761\u8BB0\u5F55\uFF0C\u603B\u5171 ").concat(totalRows, " \u6761\u8BB0\u5F55");
},
formatSRPaginationPreText: function formatSRPaginationPreText() {
return '上一页';
},
formatSRPaginationPageText: function formatSRPaginationPageText(page) {
return "\u7B2C".concat(page, "\u9875");
},
formatSRPaginationNextText: function formatSRPaginationNextText() {
return '下一页';
},
formatDetailPagination: function formatDetailPagination(totalRows) {
return "\u603B\u5171 ".concat(totalRows, " \u6761\u8BB0\u5F55");
},
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']);
})));
/**
* 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']);
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,79 @@
/**
* GitHub Gist Theme
* Author : Anthony Attard - https://github.com/AnthonyAttard
* Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro
*/
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #d73a49;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #6f42c1;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
.hljs-number {
color: #005cc5;
}
.hljs-string {
color: #032f62;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -602,7 +602,7 @@ div.ztree-border {
list-style: none;
}
.time-input {
.select-time .time-input {
display: block;
width: 100%;
padding-left: 10px;
@@ -80,7 +80,10 @@ function syncMenuTab(dataId) {
$dataObj.parents("ul").addClass("in")
$dataObj.parents("li").addClass("active").siblings().removeClass("active").find('li').removeClass("active");
$dataObj.parents("ul").css('height', 'auto').height();
$dataObj.click();
$(".nav ul li, .nav li").removeClass("selected");
$dataObj.parent("li").addClass("selected");
setIframeUrl(dataId);
// 顶部菜单同步处理
var tabStr = $dataObj.parents(".tab-pane").attr("id");
if ($.common.isNotEmpty(tabStr)) {
@@ -104,6 +107,17 @@ function fixedSidebar() {
}, 100);
}
// 设置锚点
function setIframeUrl(href) {
if($.common.equals("history", mode)) {
storage.set('publicPath', href);
} else {
var nowUrl = window.location.href;
var newUrl = nowUrl.substring(0, nowUrl.indexOf("#"));
window.location.href = newUrl + "#" + href;
}
}
function SmoothlyMenu() {
if (isMobile && !$('body').hasClass('canvas-menu')) {
$('.navbar-static-side').fadeIn();
@@ -174,10 +188,7 @@ $(function() {
} else if (marginLeftVal > (visibleWidth - $(element).outerWidth(true) - $(element).prev().outerWidth(true))) {
scrollVal = marginLeftVal - $(element).prev().outerWidth(true);
}
$('.page-tabs-content').animate({
marginLeft: 0 - scrollVal + 'px'
},
"fast");
$('.page-tabs-content').animate({ marginLeft: 0 - scrollVal + 'px' }, "fast");
}
//查看左侧隐藏的选项卡
@@ -207,10 +218,7 @@ $(function() {
scrollVal = calSumWidth($(tabElement).prevAll());
}
}
$('.page-tabs-content').animate({
marginLeft: 0 - scrollVal + 'px'
},
"fast");
$('.page-tabs-content').animate({ marginLeft: 0 - scrollVal + 'px' }, "fast");
}
//查看右侧隐藏的选项卡
@@ -238,10 +246,7 @@ $(function() {
}
scrollVal = calSumWidth($(tabElement).prevAll());
if (scrollVal > 0) {
$('.page-tabs-content').animate({
marginLeft: 0 - scrollVal + 'px'
},
"fast");
$('.page-tabs-content').animate({ marginLeft: 0 - scrollVal + 'px' }, "fast");
}
}
}
@@ -258,6 +263,7 @@ $(function() {
var dataUrl = $(this).attr('href'),
dataIndex = $(this).data('index'),
menuName = $.trim($(this).text()),
isRefresh = $(this).data("refresh"),
flag = true;
var $dataObj = $('a[href$="' + decodeURI(dataUrl) + '"]');
@@ -287,6 +293,9 @@ $(function() {
}
});
}
if (isRefresh) {
refreshTab();
}
flag = false;
return false;
}
@@ -347,10 +356,7 @@ $(function() {
var marginLeftVal = parseInt($('.page-tabs-content').css('margin-left'));
if (marginLeftVal < 0) {
$('.page-tabs-content').animate({
marginLeft: (marginLeftVal + currentWidth) + 'px'
},
"fast");
$('.page-tabs-content').animate({ marginLeft: (marginLeftVal + currentWidth) + 'px' }, "fast");
}
// 移除当前选项卡
@@ -470,7 +476,7 @@ $(function() {
$('.RuoYi_iframe[data-id="' + $(this).data('id') + '"]').remove();
$(this).remove();
});
$('.page-tabs-content').css("margin-left", "0");
$('.page-tabs-content').animate({ marginLeft: '0px' }, "fast");
}
// 关闭全部选项卡
@@ -492,6 +498,11 @@ $(function() {
$('#fullScreen').on('click', function () {
$(document).toggleFullScreen();
});
// 锁定屏幕
$('#lockScreen').on('click', function () {
location.href = ctx + "lockscreen";
});
// 页签刷新按钮
$('.tabReload').on('click', refreshTab);
@@ -534,17 +545,6 @@ $(function() {
$('#ax_close_max').show();
}
// 设置锚点
function setIframeUrl(href) {
if($.common.equals("history", mode)) {
storage.set('publicPath', href);
} else {
var nowUrl = window.location.href;
var newUrl = nowUrl.substring(0, nowUrl.indexOf("#"));
window.location.href = newUrl + "#" + href;
}
}
$(window).keydown(function(event) {
if (event.keyCode == 27) {
$('#content-main').removeClass('max');
@@ -591,7 +591,7 @@ $(function() {
$('.RuoYi_iframe[data-id="' + $(this).data('id') + '"]').remove();
$(this).remove();
});
$('.page-tabs-content').css("margin-left", "0");
$('.page-tabs-content').animate({ marginLeft: '0px' }, "fast");
}
},
"close_right": {
@@ -264,7 +264,7 @@ var closeItem = function(dataId){
}
/** 创建选项卡 */
function createMenuItem(dataUrl, menuName) {
function createMenuItem(dataUrl, menuName, isRefresh) {
var panelUrl = window.frameElement.getAttribute('data-id');
dataIndex = $.common.random(1, 100),
flag = true;
@@ -285,6 +285,9 @@ function createMenuItem(dataUrl, menuName) {
}
});
}
if (isRefresh) {
refreshTab();
}
flag = false;
return false;
}
@@ -310,6 +313,15 @@ function createMenuItem(dataUrl, menuName) {
return false;
}
// 刷新iframe
function refreshTab() {
var topWindow = $(window.parent.document);
var currentId = $('.page-tabs-content', topWindow).find('.active').attr('data-id');
var target = $('.RuoYi_iframe[data-id="' + currentId + '"]', topWindow);
var url = target.attr('src');
target.attr('src', url).ready();
}
// 滚动到指定选项卡
function scrollToTab(element) {
var topWindow = $(window.parent.document);
@@ -410,7 +422,7 @@ var sub = {
editColumn: function() {
var count = $("#" + table.options.id).bootstrapTable('getData').length;
var params = new Array();
for (var dataIndex = 0; dataIndex <= count; dataIndex++) {
for (var dataIndex = 0; dataIndex < count; dataIndex++) {
var columns = $('#' + table.options.id + ' tr[data-index="' + dataIndex + '"] td');
var obj = new Object();
for (var i = 0; i < columns.length; i++) {
@@ -438,9 +450,38 @@ var sub = {
return;
}
$("#" + table.options.id).bootstrapTable('remove', { field: subColumn, values: ids });
},
addColumn: function(row, tableId) {
var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId;
table.set(currentId);
var count = $("#" + currentId).bootstrapTable('getData').length;
sub.editColumn();
$("#" + currentId).bootstrapTable('insertRow', {
index: count + 1,
row: row
});
}
};
// 动态加载css文件
function loadCss(file, headElem) {
var link = document.createElement('link');
link.href = file;
link.rel = 'stylesheet';
link.type = 'text/css';
if (headElem) headElem.appendChild(link);
else document.getElementsByTagName('head')[0].appendChild(link);
}
// 动态加载js文件
function loadJs(file, headElem) {
var script = document.createElement('script');
script.src = file;
script.type = 'text/javascript';
if (headElem) headElem.appendChild(script);
else document.getElementsByTagName('head')[0].appendChild(script);
}
/** 设置全局ajax处理 */
$.ajaxSetup({
complete: function(XMLHttpRequest, textStatus) {
@@ -41,7 +41,7 @@ var table = {
method: 'post',
height: undefined,
sidePagination: "server",
sortName: "",
sortName: undefined,
sortOrder: "asc",
pagination: true,
paginationLoop: false,
@@ -116,12 +116,17 @@ var table = {
mobileResponsive: options.mobileResponsive, // 是否支持移动端适配
cardView: options.cardView, // 是否启用显示卡片视图
detailView: options.detailView, // 是否启用显示细节视图
onCheck: options.onCheck, // 当选择此行时触发
onUncheck: options.onUncheck, // 当取消此行时触发
onCheckAll: options.onCheckAll, // 当全选行时触发
onUncheckAll: options.onUncheckAll, // 当取消全选行时触发
onClickRow: options.onClickRow, // 点击某行触发的事件
onDblClickRow: options.onDblClickRow, // 双击某行触发的事件
onClickCell: options.onClickCell, // 单击某格触发的事件
onDblClickCell: options.onDblClickCell, // 双击某格触发的事件
onEditableSave: options.onEditableSave, // 行内编辑保存的事件
onExpandRow: options.onExpandRow, // 点击详细视图的事件
onPostBody: options.onPostBody, // 渲染完成后执行的事件
maintainSelected: options.maintainSelected, // 前端翻页时保留所选行
rememberSelected: options.rememberSelected, // 启用翻页记住前面的选择
fixedColumns: options.fixedColumns, // 是否启用冻结列(左侧)
@@ -137,6 +142,7 @@ var table = {
responseHandler: $.table.responseHandler, // 在加载服务器发送来的数据之前处理函数
onLoadSuccess: $.table.onLoadSuccess, // 当所有数据被加载时触发处理函数
exportOptions: options.exportOptions, // 前端导出忽略列索引
printPageBuilder: options.printPageBuilder, // 自定义打印页面模板
detailFormatter: options.detailFormatter, // 在行下面展示其他数据列表
});
},
@@ -167,7 +173,7 @@ var table = {
if (typeof table.get(this.id).responseHandler == "function") {
table.get(this.id).responseHandler(res);
}
if (res.code == 0) {
if (res.code == web_status.SUCCESS) {
if ($.common.isNotEmpty(table.options.sidePagination) && table.options.sidePagination == 'client') {
return res.rows;
} else {
@@ -487,6 +493,9 @@ var table = {
},
// 回显数据字典
selectDictLabel: function(datas, value) {
if ($.common.isEmpty(datas) || $.common.isEmpty(value)) {
return '';
}
var actions = [];
$.each(datas, function(index, dict) {
if (dict.dictValue == ('' + value)) {
@@ -499,7 +508,7 @@ var table = {
},
// 回显数据字典(字符串数组)
selectDictLabels: function(datas, value, separator) {
if ($.common.isEmpty(value)) {
if ($.common.isEmpty(datas) || $.common.isEmpty(value)) {
return '';
}
var currentSeparator = $.common.isEmpty(separator) ? "," : separator;
@@ -579,7 +588,7 @@ var table = {
expandFirst: options.expandFirst, // 是否默认第一级展开--expandAll为false时生效
columns: options.columns, // 显示列信息(*
responseHandler: $.treeTable.responseHandler, // 在加载服务器发送来的数据之前处理函数
onLoadSuccess: $.table.onLoadSuccess // 当所有数据被加载时触发处理函数
onLoadSuccess: $.treeTable.onLoadSuccess // 当所有数据被加载时触发处理函数
});
},
// 条件查询
@@ -604,13 +613,20 @@ var table = {
if (typeof table.options.responseHandler == "function") {
table.options.responseHandler(res);
}
if (res.code != undefined && res.code != 0) {
if (res.code != undefined && res.code != web_status.SUCCESS) {
$.modal.alertWarning(res.msg);
return [];
} else {
return res;
}
},
// 当所有数据被加载时触发
onLoadSuccess: function(data) {
if (typeof table.options.onLoadSuccess == "function") {
table.options.onLoadSuccess(data);
}
$(".table [data-toggle='tooltip']").tooltip();
},
},
// 表单封装处理
form: {
@@ -752,7 +768,7 @@ var table = {
},
// 弹出层指定宽度
open: function (title, url, width, height, callback) {
//如果是移动端,就使用自适应大小弹窗
// 如果是移动端,就使用自适应大小弹窗
if ($.common.isMobile()) {
width = 'auto';
height = 'auto';
@@ -800,6 +816,11 @@ var table = {
var _width = $.common.isEmpty(options.width) ? "800" : options.width;
var _height = $.common.isEmpty(options.height) ? ($(window).height() - 50) : options.height;
var _btn = ['<i class="fa fa-check"></i> 确认', '<i class="fa fa-close"></i> 关闭'];
// 如果是移动端,就使用自适应大小弹窗
if ($.common.isMobile()) {
_width = 'auto';
_height = 'auto';
}
if ($.common.isEmpty(options.yes)) {
options.yes = function(index, layero) {
options.callBack(index, layero);
@@ -836,7 +857,7 @@ var table = {
},
// 弹出层全屏
openFull: function (title, url, width, height) {
//如果是移动端,就使用自适应大小弹窗
// 如果是移动端,就使用自适应大小弹窗
if ($.common.isMobile()) {
width = 'auto';
height = 'auto';
@@ -876,8 +897,8 @@ var table = {
layer.full(index);
},
// 选卡页方式打开
openTab: function (title, url) {
createMenuItem(url, title);
openTab: function (title, url, isRefresh) {
createMenuItem(url, title, isRefresh);
},
// 选卡页同一页签打开
parentTab: function (title, url) {
@@ -947,17 +968,10 @@ var table = {
detail: function(id, width, height) {
table.set();
var _url = $.operate.detailUrl(id);
var _width = $.common.isEmpty(width) ? "800" : width;
var _height = $.common.isEmpty(height) ? ($(window).height() - 50) : height;
//如果是移动端,就使用自适应大小弹窗
if ($.common.isMobile()) {
_width = 'auto';
_height = 'auto';
}
var options = {
title: table.options.modalName + "详细",
width: _width,
height: _height,
width: width,
height: height,
url: _url,
skin: 'layui-layer-gray',
btn: ['关闭'],
@@ -1030,8 +1044,7 @@ var table = {
// 添加信息 全屏
addFull: function(id) {
table.set();
var url = $.common.isEmpty(id) ? table.options.createUrl : table.options.createUrl.replace("{id}", id);
$.modal.openFull("添加" + table.options.modalName, url);
$.modal.openFull("添加" + table.options.modalName, $.operate.addUrl(id));
},
// 添加访问地址
addUrl: function(id) {
@@ -30,7 +30,7 @@ function login() {
"rememberMe": rememberMe
},
success: function(r) {
if (r.code == 0) {
if (r.code == web_status.SUCCESS) {
location.href = ctx + 'index';
} else {
$.modal.closeLoading();
@@ -27,7 +27,7 @@ function register() {
"validateCode": validateCode
},
success: function(r) {
if (r.code == 0) {
if (r.code == web_status.SUCCESS) {
layer.alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", {
icon: 1,
title: "系统提示"
@@ -0,0 +1,121 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<th:block th:include="include :: header('单据打印')" />
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox-content p-xl">
<div class="row">
<div class="col-sm-6">
<address>
<strong>北京百度在线网络技术有限公司</strong><br>
北京市海淀区上地十街10号<br>
<abbr title="Phone">总机:</abbr> (+86 10) 5992 8888
</address>
</div>
<div class="col-sm-6 text-right">
<h4>单据编号:</h4>
<h4 class="text-navy">H+-000567F7-00</h4>
<address>
<strong>阿里巴巴集团</strong><br>
中国杭州市华星路99号东部软件园创业大厦6层(310099)<br>
<abbr title="Phone">总机:</abbr> (86) 571-8502-2088
</address>
<p>
<span><strong>日期:</strong> 2014-11-11</span>
</p>
</div>
</div>
<div class="table-responsive m-t">
<table class="table invoice-table">
<thead>
<tr>
<th>清单</th>
<th>数量</th>
<th>单价</th>
<th>税率</th>
<th>总价</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div><strong>尚都比拉2013冬装新款女装 韩版修身呢子大衣 秋冬气质羊毛呢外套</strong>
</div>
</td>
<td>1</td>
<td>&yen;26.00</td>
<td>&yen;1.20</td>
<td>&yen;31,98</td>
</tr>
<tr>
<td>
<div><strong>11*11夏娜 新款斗篷毛呢外套 女秋冬呢子大衣 韩版大码宽松呢大衣</strong>
</div>
<small>双十一特价
</small>
</td>
<td>2</td>
<td>&yen;80.00</td>
<td>&yen;1.20</td>
<td>&yen;196.80</td>
</tr>
<tr>
<td>
<div><strong>2013秋装 新款女装韩版学生秋冬加厚加绒保暖开衫卫衣 百搭女外套</strong>
</div>
</td>
<td>3</td>
<td>&yen;420.00</td>
<td>&yen;1.20</td>
<td>&yen;1033.20</td>
</tr>
</tbody>
</table>
</div>
<!-- /table-responsive -->
<table class="table invoice-total">
<tbody>
<tr>
<td><strong>总价:</strong>
</td>
<td>&yen;1026.00</td>
</tr>
<tr>
<td><strong>税:</strong>
</td>
<td>&yen;235.98</td>
</tr>
<tr>
<td><strong>总计</strong>
</td>
<td>&yen;1261.98</td>
</tr>
</tbody>
</table>
<div class="text-right">
<button class="btn btn-primary" onclick="printPage()"><i class="fa fa-print"></i> 打印</button>
</div>
<div class="well m-t"><strong>注意:</strong> 请在30日内完成付款,否则订单会自动取消。
</div>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script type="text/javascript">
function printPage() {
window.print();
}
</script>
</body>
</html>
@@ -0,0 +1,237 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<th:block th:include="include :: header('标签 & 提示')" />
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content animated fadeIn">
<div class="row">
<div class="col-sm-6">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>徽章 (Badges)</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">选项1</a>
</li>
<li><a href="#">选项2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<p>
要添加徽章,只需要在元素上添加<code>.badge</code>即可,改变徽章的颜色可使用如下class,如<code>.badge-primary</code>
</p>
<p><span class="badge"></span>
</p>
<p><span class="badge badge-primary">badge-primary</span>
</p>
<p><span class="badge badge-info">badge-info</span>
</p>
<p><span class="badge badge-success">badge-success</span>
</p>
<p><span class="badge badge-warning">badge-warning</span>
</p>
<p><span class="badge badge-danger">badge-danger</span>
</p>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>标签 (Labels)</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">选项1</a>
</li>
<li><a href="#">选项2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<p>
要添加徽章,只需要在元素上添加class<code>.label</code>即可,如果需要修改颜色,添加如下class,如<code>.label-primary</code>
</p>
<p><span class="label"></span>
</p>
<p><span class="label label-primary">label-primary</span>
</p>
<p><span class="label label-info">label-info</span>
</p>
<p><span class="label label-success">label-success</span>
</p>
<p><span class="label label-warning">label-warning</span>
</p>
<p><span class="label label-danger">label-danger</span>
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>通知样式</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">选项1</a>
</li>
<li><a href="#">选项2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="alert alert-success">
RuoYi是一个很棒的后台UI框架 <a class="alert-link" href="#">了解更多</a>.
</div>
<div class="alert alert-info">
RuoYi是一个很棒的后台UI框架 <a class="alert-link" href="#">了解更多</a>.
</div>
<div class="alert alert-warning">
RuoYi是一个很棒的后台UI框架 <a class="alert-link" href="#">了解更多</a>.
</div>
<div class="alert alert-danger">
RuoYi是一个很棒的后台UI框架 <a class="alert-link" href="#">了解更多</a>.
</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>带关闭按钮的通知样式</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">选项1</a>
</li>
<li><a href="#">选项2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="alert alert-success alert-dismissable">
<button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
RuoYi是一个很棒的后台UI框架 <a class="alert-link" href="#">了解更多</a>.
</div>
<div class="alert alert-info alert-dismissable">
<button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
RuoYi是一个很棒的后台UI框架 <a class="alert-link" href="#">了解更多</a>.
</div>
<div class="alert alert-warning alert-dismissable">
<button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
RuoYi是一个很棒的后台UI框架 <a class="alert-link" href="#">了解更多</a>.
</div>
<div class="alert alert-danger alert-dismissable">
<button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
RuoYi是一个很棒的后台UI框架 <a class="alert-link" href="#">了解更多</a>.
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>工具提示</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">选项1</a>
</li>
<li><a href="#">选项2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="text-center">
<h4>工具提示示例 <small>深色背景</small></h4>
<div>
<button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="left" title="这里是提示内容">左侧提示</button>
<button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="top" title="这里是提示内容">顶部提示</button>
<button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" title="这里是提示内容">底部提示</button>
<button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="right" title="这里是提示内容">右侧提示</button>
</div>
<br>
<h4>工具提示 - 单击提示</h4>
<div class="text-center" >
<button type="button" class="btn btn-primary" data-toggle="popover" data-placement="auto left" data-content="气泡提示">
气泡提示左
</button>
<button type="button" class="btn btn-primary" data-toggle="popover" data-placement="auto top" data-content="气泡提示">
气泡提示顶部
</button>
<button type="button" class="btn btn-primary" data-toggle="popover" data-placement="auto bottom" data-content="气泡提示">
气泡提示底部
</button>
<button type="button" class="btn btn-primary" data-toggle="popover" data-placement="auto right" data-content="气泡提示">
气泡提示右
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script type="text/javascript">
$("[data-toggle='tooltip']").tooltip();
$("[data-toggle=popover]").popover();
</script>
</body>
</html>
@@ -17,7 +17,7 @@
<h2>若依后台管理系统</h2>
<p>ruoyi是一个完全响应式,基于Bootstrap3.3.6最新版本开发的扁平化主题,她采用了主流的左右两栏式布局,使用了Html5+CSS3等现代技术,她提供了诸多的强大的可以重新组合的UI组件,并集成了最新的jQuery版本(v2.1.1),当然,也集成了很多功能强大,用途广泛的就jQuery插件,她可以用于所有的Web应用程序,如<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p>
<p>
<b>当前版本:</b>v4.5.0
<b>当前版本:</b>v4.6.0
</p>
<p>
<span class="label label-warning">免费开源</span>
@@ -56,7 +56,7 @@
<h3>你好,若依 </h3>
<p>H+是一个完全响应式,基于Bootstrap3.3.6最新版本开发的扁平化主题,她采用了主流的左右两栏式布局,使用了Html5+CSS3等现代技术,她提供了诸多的强大的可以重新组合的UI组件,并集成了最新的jQuery版本(v2.1.1),当然,也集成了很多功能强大,用途广泛的就jQuery插件,她可以用于所有的Web应用程序,如<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p>
<p>
<b>当前版本:</b>v4.5.0
<b>当前版本:</b>v4.6.0
</p>
<p>
<span class="label label-warning">开源免费</span>
@@ -8,7 +8,9 @@
<form class="form-horizontal m" id="form-user-edit">
<div class="form-group">
<label class="col-sm-3 control-label">用户编号:</label>
<div class="form-control-static" th:text="${user.userCode}"></div>
<div class="col-sm-8">
<div class="form-control-static" th:text="${user.userCode}"></div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">用户姓名:</label>
@@ -45,7 +47,7 @@
<th:block th:include="include :: footer" />
<script type="text/javascript">
var prefix = ctx + "demo/operate";
$("#form-user-add").validate({
onkeyup: false,
rules:{
@@ -58,7 +60,7 @@
},
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-user-edit').serialize());
@@ -9,13 +9,13 @@
<div class="form-group">
<label class="col-sm-2 control-label">用户名称:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="userName"placeholder="请输入用户名称">
<input type="text" class="form-control" name="userName" placeholder="请输入用户名称">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">手机号码:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="phonenumber" maxlength="11"placeholder="请输入手机号码">
<input type="text" class="form-control" name="phonenumber" maxlength="11" placeholder="请输入手机号码">
</div>
</div>
<div class="form-group">
@@ -29,13 +29,13 @@
<div class="form-group">
<label class="col-sm-2 control-label">用户名称:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="userName"placeholder="请输入用户名称">
<input type="text" class="form-control" name="userName" placeholder="请输入用户名称">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">手机号码:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="phonenumber" maxlength="11"placeholder="请输入手机号码">
<input type="text" class="form-control" name="phonenumber" maxlength="11" placeholder="请输入手机号码">
</div>
</div>
<div class="form-group">
@@ -58,7 +58,7 @@
data: $('#form-demo-2').serialize(),
type: "post",
success: function(result) {
if (result.code == 0) {
if (result.code == web_status.SUCCESS) {
layer.msg("保存成功,正在刷新数据请稍后……", {
icon: 1,
time: 500,
@@ -24,6 +24,10 @@
showRefresh: false,
showToggle: false,
showColumns: false,
onCheck: onCheck,
onUncheck: onUncheck,
onCheckAll: onCheckAll,
onUncheckAll: onUncheckAll,
onClickRow: onClickRow,
onDblClickRow: onDblClickRow,
onClickCell: onClickCell,
@@ -95,6 +99,28 @@
alert("双击格name" + field + " value" + value);
}
function onCheck(row, $element){
alert("选中行userId" + row.userId + " userName" + row.userName);
}
function onUncheck(row, $element){
alert("取消行userId" + row.userId + " userName" + row.userName);
}
function onCheckAll(rowsAfter, rowsBefore){
var rows = $.map(rowsAfter, function(row) {
return $.common.getItemField(row, "userId");
});
alert("全选行:" + rows);
}
function onUncheckAll(rowsAfter, rowsBefore){
var rows = $.map(rowsBefore, function(row) {
return $.common.getItemField(row, "userId");
});
alert("取消行:" + rows);
}
function responseHandler(res){
alert("请求获取数据后处理回调函数");
}
@@ -31,8 +31,10 @@
showRefresh: false,
showToggle: false,
showColumns: false,
printPageBuilder: printPageBuilder,
columns: [{
checkbox: true
checkbox: true,
printIgnore: true
},
{
field : 'userId',
@@ -61,6 +63,7 @@
{
title: '操作',
align: 'center',
printIgnore: true,
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-danger btn-xs" href="javascript:;" onclick="remove(this)"><i class="fa fa-remove"></i>删除</a>');
@@ -78,6 +81,50 @@
$.modal.msgSuccess('已删除!');
});
}
// 自定义打印页面模板
function printPageBuilder(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>
<div class="bs-table-print">${table}</div>
</body>
</html>`
}
</script>
</body>
</html>
@@ -164,22 +164,15 @@
autoclose: true
});
function addColumn() {
var count = $("#" + table.options.id).bootstrapTable('getData').length;
sub.editColumn();
$("#" + table.options.id).bootstrapTable('insertRow', {
index: count,
row: {
index: $.table.serialNumber(count),
name: "",
weight: "",
price: "",
date: "",
type: "",
}
});
var row = {
name: "",
weight: "",
price: "",
date: "",
type: "",
}
sub.addColumn(row);
}
$("#bootstrap-table").on("post-body.bs.table", function (e, args) {
@@ -20,7 +20,7 @@
<script th:inline="javascript">
var ctx = [[@{/}]];
function index() {
window.parent.frames.location.href = ctx + "index";
window.top.location = ctx + "index";
}
</script>
</body>
@@ -21,7 +21,7 @@
<script th:inline="javascript">
var ctx = [[@{/}]];
function index() {
window.parent.frames.location.href = ctx + "index";
window.top.location = ctx + "index";
}
</script>
</body>
@@ -21,7 +21,7 @@
<script th:inline="javascript">
var ctx = [[@{/}]];
function index() {
window.parent.frames.location.href = ctx + "index";
window.top.location = ctx + "index";
}
</script>
</body>
@@ -10,21 +10,22 @@
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
<link th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<!-- bootstrap-table 表格插件样式 -->
<link th:href="@{/ajax/libs/bootstrap-table/bootstrap-table.min.css?v=20200727}" rel="stylesheet"/>
<link th:href="@{/ajax/libs/bootstrap-table/bootstrap-table.min.css?v=20201129}" rel="stylesheet"/>
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
<link th:href="@{/css/style.css?v=20200903}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.5.0}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.6.0}" rel="stylesheet"/>
</head>
<!-- 通用JS -->
<div th:fragment="footer">
<script th:inline="javascript"> var ctx = [[@{/}]]; var lockscreen = [[${session.lockscreen}]]; if(lockscreen){window.top.location=ctx+"lockscreen";} </script>
<a id="scroll-up" href="#" class="btn btn-sm display"><i class="fa fa-angle-double-up"></i></a>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>
<!-- bootstrap-table 表格插件 -->
<script th:src="@{/ajax/libs/bootstrap-table/bootstrap-table.min.js?v=20200727}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/locale/bootstrap-table-zh-CN.min.js?v=20200727}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/mobile/bootstrap-table-mobile.js?v=20200727}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/bootstrap-table.min.js?v=20201129}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/locale/bootstrap-table-zh-CN.min.js?v=20201129}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/mobile/bootstrap-table-mobile.min.js?v=20201129}"></script>
<!-- jquery-validate 表单验证插件 -->
<script th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script>
<script th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script>
@@ -36,9 +37,8 @@
<script th:src="@{/ajax/libs/iCheck/icheck.min.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ajax/libs/layui/layui.js}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.5.0}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.5.0}"></script>
<script th:inline="javascript"> var ctx = [[@{/}]]; </script>
<script th:src="@{/ruoyi/js/common.js?v=4.6.0}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.6.0}"></script>
</div>
<!-- ztree树插件 -->
@@ -110,10 +110,10 @@
<!-- fileinput文件上传插件 -->
<div th:fragment="bootstrap-fileinput-css">
<link th:href="@{/ajax/libs/bootstrap-fileinput/fileinput.min.css}" rel="stylesheet"/>
<link th:href="@{/ajax/libs/bootstrap-fileinput/fileinput.min.css?v=20201202}" rel="stylesheet"/>
</div>
<div th:fragment="bootstrap-fileinput-js">
<script th:src="@{/ajax/libs/bootstrap-fileinput/fileinput.min.js}"></script>
<script th:src="@{/ajax/libs/bootstrap-fileinput/fileinput.min.js?v=20201202}"></script>
</div>
<!-- duallistbox双列表框插件 -->
@@ -179,7 +179,7 @@
<!-- 表格列宽拖动插件 -->
<div th:fragment="bootstrap-table-resizable-js">
<script th:src="@{/ajax/libs/bootstrap-table/extensions/resizable/jquery.resizableColumns.min.js}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/resizable/bootstrap-table-resizable.min.js}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/resizable/bootstrap-table-resizable.min.js?v=20201129}"></script>
</div>
<!-- 表格行内编辑插件 -->
@@ -188,7 +188,7 @@
</div>
<div th:fragment="bootstrap-table-editable-js">
<script th:src="@{/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.min.js}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/editable/bootstrap-table-editable.min.js?v=20200727}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/editable/bootstrap-table-editable.min.js?v=20201129}"></script>
</div>
<!-- 表格导出插件 -->
@@ -199,12 +199,12 @@
<!-- 表格冻结列插件 -->
<div th:fragment="bootstrap-table-fixed-columns-js">
<script th:src="@{/ajax/libs/bootstrap-table/extensions/columns/bootstrap-table-fixed-columns.min.js?v=20200727}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/columns/bootstrap-table-fixed-columns.min.js?v=20201129}"></script>
</div>
<!-- 表格自动刷新插件 -->
<div th:fragment="bootstrap-table-auto-refresh-js">
<script th:src="@{/ajax/libs/bootstrap-table/extensions/auto-refresh/bootstrap-table-auto-refresh.min.js?v=20200729}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/auto-refresh/bootstrap-table-auto-refresh.min.js?v=20201129}"></script>
</div>
<!-- 表格打印插件 -->
@@ -14,7 +14,7 @@
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
<link th:href="@{/css/style.css}" rel="stylesheet"/>
<link th:href="@{/css/skins.css?v=20200902}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.5.0}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.6.0}" rel="stylesheet"/>
</head>
<body class="fixed-sidebar full-height-layout gray-bg" style="overflow: hidden">
<div id="wrapper">
@@ -49,7 +49,7 @@
<div class="tab-pane fade height-full" th:id="|menu_${menu.menuId}|">
<ul class="nav">
<li th:each="cmenu : ${menu.children}">
<a class="menu-content" th:if="${#lists.isEmpty(cmenu.children)}" th:href="@{${cmenu.url}}" th:classappend="${#strings.isEmpty(cmenu.target)} ? |menuItem| : ${cmenu.target}">
<a class="menu-content" th:if="${#lists.isEmpty(cmenu.children)}" th:href="@{${cmenu.url}}" th:classappend="${#strings.isEmpty(cmenu.target)} ? |menuItem| : ${cmenu.target}" th:data-refresh="${cmenu.isRefresh == '0'}">
<i th:class="${cmenu.icon} + ' fa-fw'"></i> <span class="nav-label">[[${cmenu.menuName}]]</span>
</a>
<a class="menu-content" th:if="${not #lists.isEmpty(cmenu.children)}" href="#">
@@ -59,7 +59,7 @@
</a>
<ul th:if="${not #lists.isEmpty(cmenu.children)}" class="nav nav-second-level collapse">
<li th:each="emenu : ${cmenu.children}">
<a th:if="${#lists.isEmpty(emenu.children)}" th:href="@{${emenu.url}}" th:class="${#strings.isEmpty(emenu.target)} ? |menuItem| : ${emenu.target}">
<a th:if="${#lists.isEmpty(emenu.children)}" th:href="@{${emenu.url}}" th:class="${#strings.isEmpty(emenu.target)} ? |menuItem| : ${emenu.target}" th:data-refresh="${emenu.isRefresh == '0'}">
<i th:class="${emenu.icon} + ' fa-fw'"></i>
[[${emenu.menuName}]]
</a>
@@ -69,7 +69,7 @@
<span class="fa arrow"></span>
</a>
<ul th:if="${not #lists.isEmpty(emenu.children)}" class="nav nav-third-level collapse">
<li th:each="fmenu : ${emenu.children}"><a th:if="${#lists.isEmpty(fmenu.children)}" th:class="${#strings.isEmpty(fmenu.target)} ? |menuItem| : ${fmenu.target}" th:href="@{${fmenu.url}}">[[${fmenu.menuName}]]</a></li>
<li th:each="fmenu : ${emenu.children}"><a th:if="${#lists.isEmpty(fmenu.children)}" th:class="${#strings.isEmpty(fmenu.target)} ? |menuItem| : ${fmenu.target}" th:href="@{${fmenu.url}}" th:data-refresh="${fmenu.isRefresh == '0'}">[[${fmenu.menuName}]]</a></li>
</ul>
</li>
</ul>
@@ -102,6 +102,8 @@
<li><a class="menuItem" th:href="@{/demo/form/cards}">卡片列表</a></li>
<li><a class="menuItem" th:href="@{/demo/form/jasny}">功能扩展</a></li>
<li><a class="menuItem" th:href="@{/demo/form/sortable}">拖动排序</a></li>
<li><a class="menuItem" th:href="@{/demo/form/invoice}">单据打印</a></li>
<li><a class="menuItem" th:href="@{/demo/form/labels_tips}">标签 & 提示</a></li>
<li><a class="menuItem" th:href="@{/demo/form/tabs_panels}">选项卡 & 面板</a></li>
<li><a class="menuItem" th:href="@{/demo/form/validate}">表单校验</a></li>
<li><a class="menuItem" th:href="@{/demo/form/wizard}">表单向导</a></li>
@@ -234,9 +236,10 @@
</div>
<!-- 右侧栏 -->
<ul class="nav navbar-top-links navbar-right welcome-message">
<li><a title="视频教程" href="http://doc.ruoyi.vip/ruoyi/document/spjc.html" target="_blank"><i class="fa fa-video-camera"></i> 视频教程</a></li>
<li><a title="开发文档" href="http://doc.ruoyi.vip" target="_blank"><i class="fa fa-question-circle"></i> 开发文档</a></li>
<li><a title="全屏显示" href="javascript:void(0)" id="fullScreen"><i class="fa fa-arrows-alt"></i> 全屏显示</a></li>
<li><a data-toggle="tooltip" data-trigger="hover" data-placement="bottom" title="开发文档" href="http://doc.ruoyi.vip/ruoyi" target="_blank"><i class="fa fa-question-circle"></i> 文档</a></li>
<li><a data-toggle="tooltip" data-trigger="hover" data-placement="bottom" title="锁定屏幕" href="#" id="lockScreen"><i class="fa fa-lock"></i> 锁屏</a></li>
<li><a data-toggle="tooltip" data-trigger="hover" data-placement="bottom" title="全屏显示" href="#" id="fullScreen"><i class="fa fa-arrows-alt"></i> 全屏</a></li>
<li class="dropdown user-menu">
<a href="javascript:void(0)" class="dropdown-toggle" data-hover="dropdown">
<img th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="this.src='img/profile.jpg'" class="user-image">
@@ -305,13 +308,16 @@
<script th:src="@{/js/jquery.contextMenu.min.js}"></script>
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.5.0}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.5.0}"></script>
<script th:src="@{/ruoyi/index.js?v=20200902}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.6.0}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.6.0}"></script>
<script th:src="@{/ruoyi/index.js?v=20201208}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
<script th:src="@{/js/resize-tabs.js}"></script>
<script th:inline="javascript">
var ctx = [[@{/}]];
window.history.forward(1);
var ctx = [[@{/}]];
var lockscreen = [[${session.lockscreen}]];
if(lockscreen){window.top.location=ctx+"lockscreen";}
// 皮肤缓存
var skin = storage.get("skin");
// history(表示去掉地址的#)否则地址以"#"形式展示
@@ -417,6 +423,8 @@ $(function() {
layer.close(index);
});
}
$("[data-toggle='tooltip']").tooltip();
});
</script>
</body>
@@ -14,7 +14,7 @@
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
<link th:href="@{/css/style.css}" rel="stylesheet"/>
<link th:href="@{/css/skins.css}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.5.0}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.6.0}" rel="stylesheet"/>
</head>
<body class="fixed-sidebar full-height-layout gray-bg" style="overflow: hidden">
<div id="wrapper">
@@ -50,21 +50,21 @@
<a class="menuItem" th:href="@{/system/main}"><i class="fa fa-home"></i> <span class="nav-label">首页</span> </a>
</li>
<li th:each="menu : ${menus}">
<a th:class="@{${!#strings.isEmpty(menu.url) && menu.url != '#'} ? ${menu.target}}" th:href="@{${#strings.isEmpty(menu.url)} ? |#| : ${menu.url}}">
<a th:class="@{${!#strings.isEmpty(menu.url) && menu.url != '#'} ? ${menu.target}}" th:href="@{${#strings.isEmpty(menu.url)} ? |#| : ${menu.url}}" th:data-refresh="${menu.isRefresh == '0'}">
<i class="fa fa-bar-chart-o" th:class="${menu.icon}"></i>
<span class="nav-label" th:text="${menu.menuName}">一级菜单</span>
<span th:class="${#strings.isEmpty(menu.url) || menu.url == '#'} ? |fa arrow|"></span>
</a>
<ul class="nav nav-second-level collapse">
<li th:each="cmenu : ${menu.children}">
<a th:if="${#lists.isEmpty(cmenu.children)}" th:class="${#strings.isEmpty(cmenu.target)} ? |menuItem| : ${cmenu.target}" th:utext="${cmenu.menuName}" th:href="@{${cmenu.url}}">二级菜单</a>
<a th:if="${#lists.isEmpty(cmenu.children)}" th:class="${#strings.isEmpty(cmenu.target)} ? |menuItem| : ${cmenu.target}" th:utext="${cmenu.menuName}" th:href="@{${cmenu.url}}" th:data-refresh="${cmenu.isRefresh == '0'}">二级菜单</a>
<a th:if="${not #lists.isEmpty(cmenu.children)}" href="#">[[${cmenu.menuName}]]<span class="fa arrow"></span></a>
<ul th:if="${not #lists.isEmpty(cmenu.children)}" class="nav nav-third-level">
<li th:each="emenu : ${cmenu.children}">
<a th:if="${#lists.isEmpty(emenu.children)}" th:class="${#strings.isEmpty(emenu.target)} ? |menuItem| : ${emenu.target}" th:text="${emenu.menuName}" th:href="@{${emenu.url}}">三级菜单</a>
<a th:if="${#lists.isEmpty(emenu.children)}" th:class="${#strings.isEmpty(emenu.target)} ? |menuItem| : ${emenu.target}" th:text="${emenu.menuName}" th:href="@{${emenu.url}}" th:data-refresh="${emenu.isRefresh == '0'}">三级菜单</a>
<a th:if="${not #lists.isEmpty(emenu.children)}" href="#">[[${emenu.menuName}]]<span class="fa arrow"></span></a>
<ul th:if="${not #lists.isEmpty(emenu.children)}" class="nav nav-four-level">
<li th:each="fmenu : ${emenu.children}"><a th:if="${#lists.isEmpty(fmenu.children)}" th:class="${#strings.isEmpty(fmenu.target)} ? |menuItem| : ${fmenu.target}" th:text="${fmenu.menuName}" th:href="@{${fmenu.url}}">四级菜单</a></li>
<li th:each="fmenu : ${emenu.children}"><a th:if="${#lists.isEmpty(fmenu.children)}" th:class="${#strings.isEmpty(fmenu.target)} ? |menuItem| : ${fmenu.target}" th:text="${fmenu.menuName}" th:href="@{${fmenu.url}}" th:data-refresh="${fmenu.isRefresh == '0'}">四级菜单</a></li>
</ul>
</li>
</ul>
@@ -84,6 +84,8 @@
<li><a class="menuItem" th:href="@{/demo/form/cards}">卡片列表</a></li>
<li><a class="menuItem" th:href="@{/demo/form/jasny}">功能扩展</a></li>
<li><a class="menuItem" th:href="@{/demo/form/sortable}">拖动排序</a></li>
<li><a class="menuItem" th:href="@{/demo/form/invoice}">单据打印</a></li>
<li><a class="menuItem" th:href="@{/demo/form/labels_tips}">标签 & 提示</a></li>
<li><a class="menuItem" th:href="@{/demo/form/tabs_panels}">选项卡 & 面板</a></li>
<li><a class="menuItem" th:href="@{/demo/form/validate}">表单校验</a></li>
<li><a class="menuItem" th:href="@{/demo/form/wizard}">表单向导</a></li>
@@ -185,9 +187,9 @@
</a>
</div>
<ul class="nav navbar-top-links navbar-right welcome-message">
<li><a title="视频教程" href="http://doc.ruoyi.vip/ruoyi/document/spjc.html" target="_blank"><i class="fa fa-video-camera"></i> 视频教程</a></li>
<li><a title="开发文档" href="http://doc.ruoyi.vip" target="_blank"><i class="fa fa-question-circle"></i> 开发文档</a></li>
<li><a title="全屏显示" href="javascript:void(0)" id="fullScreen"><i class="fa fa-arrows-alt"></i> 全屏显示</a></li>
<li><a data-toggle="tooltip" data-trigger="hover" data-placement="bottom" title="开发文档" href="http://doc.ruoyi.vip/ruoyi" target="_blank"><i class="fa fa-question-circle"></i> 文档</a></li>
<li><a data-toggle="tooltip" data-trigger="hover" data-placement="bottom" title="锁定屏幕" href="#" id="lockScreen"><i class="fa fa-lock"></i> 锁屏</a></li>
<li><a data-toggle="tooltip" data-trigger="hover" data-placement="bottom" title="全屏显示" href="#" id="fullScreen"><i class="fa fa-arrows-alt"></i> 全屏</a></li>
<li class="dropdown user-menu">
<a href="javascript:void(0)" class="dropdown-toggle" data-hover="dropdown">
<img th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="this.src='img/profile.jpg'" class="user-image">
@@ -256,12 +258,15 @@
<script th:src="@{/js/jquery.contextMenu.min.js}"></script>
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.5.0}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.5.0}"></script>
<script th:src="@{/ruoyi/index.js}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.6.0}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.6.0}"></script>
<script th:src="@{/ruoyi/index.js?v=20201208}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
<script th:inline="javascript">
var ctx = [[@{/}]];
window.history.forward(1);
var ctx = [[@{/}]];
var lockscreen = [[${session.lockscreen}]];
if(lockscreen){window.top.location=ctx+"lockscreen";}
// 皮肤缓存
var skin = storage.get("skin");
// history(表示去掉地址的#)否则地址以"#"形式展示
@@ -357,6 +362,7 @@ $(function() {
layer.close(index);
});
}
$("[data-toggle='tooltip']").tooltip();
});
</script>
</body>
@@ -0,0 +1,208 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--360浏览器优先以webkit内核解析-->
<title>锁定屏幕</title>
<link th:href="@{favicon.ico}" rel="shortcut icon"/>
<link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<style>.lockscreen{background:#d2d6de;height:auto;}.lockscreen .lockscreen-name{text-align:center;font-weight:600;margin-top:50px;margin-bottom:30px;}.lockscreen-wrapper{max-width:400px;margin:10% auto;z-index:800;position:relative;}.lockscreen .lockscreen-name{text-align:center;font-weight:600;margin-top:50px;margin-bottom:30px;}.lockscreen-item{border-radius:4px;padding:0;background:#fff;position:relative;margin:10px auto 30px auto;width:290px}.lockscreen-image{border-radius:50%;position:absolute;left:-10px;top:-25px;background:#fff;padding:5px;z-index:10}.lockscreen-image>img{border-radius:50%;width:70px;height:70px}.lockscreen-credentials{margin-left:70px}.lockscreen-credentials .form-control{border:0}.lockscreen-credentials .btn{background-color:#fff;border:0;padding:0 10px}.lockscreen-footer{margin-top:150px}.lockscreen-time{width:100%;color:#fff;font-size:60px;display:inline-block;text-align:center;font-family:'Open Sans',sans-serif;font-weight:300;}</style>
</head>
<body class="lockscreen">
<div class="lockscreen-wrapper">
<div class="lockscreen-time"></div>
<div class="lockscreen-name">[[ ${user.loginName} ]] / [[${#strings.defaultString(user.userName, '-')}]]</div>
<div class="lockscreen-item">
<div class="lockscreen-image">
<img th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="this.src='img/profile.jpg'" class="img-circle" alt="User Image">
</div>
<form class="lockscreen-credentials" method="post" action="#" onsubmit="return false;">
<div class="input-group">
<input type="password" name="password" autocomplete="off" class="form-control" placeholder="密码">
<div class="input-group-btn">
<button type="button" class="btn" onclick="unlock()"><i class="fa fa-arrow-right text-muted"></i></button>
</div>
</div>
</form>
</div>
<div class="help-block text-center" style="margin-top: 50px;">系统锁屏,请输入密码登陆!</div>
<div class="text-center">
<a th:href="@{logout}">退出重新登陆</a>
</div>
</div>
<script src="../static/js/jquery.min.js" th:src="@{/js/jquery.min.js}"></script>
<script src="../static/js/bootstrap.min.js" th:src="@{/js/bootstrap.min.js}"></script>
<script src="../static/js/three.min.js" th:src="@{/js/three.min.js}"></script>
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.6.0}"></script>
</body>
<script th:inline="javascript">
var ctx = [[@{/}]];
Date.prototype.format = function(fmt) {
var o = {
"M+" : this.getMonth()+1, //月份
"d+" : this.getDate(), //日
"h+" : this.getHours(), //小时
"m+" : this.getMinutes(), //分
"s+" : this.getSeconds(), //秒
"q+" : Math.floor((this.getMonth()+3)/3), //季度
"S" : this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
$(function() {
$('.lockscreen-time').text((new Date()).format('hh:mm:ss'));
setInterval(function() {
$('.lockscreen-time').text((new Date()).format('hh:mm:ss'));
}, 500);
init();
animate();
});
$(document).keydown(function(event) {
if (event.keyCode == 13) {
unlock();
}
});
function unlock() {
var username = $("input[name='username']").val();
var password = $("input[name='password']").val();
if ($.common.isEmpty(password)) {
$.modal.msg("请输入密码");
return;
}
var index = "";
var config = {
url: ctx + "unlockscreen",
type: "post",
dataType: "json",
data: { password: password },
beforeSend: function() {
index = layer.load(2, {shade: false});
},
success: function(result) {
if (result.code == web_status.SUCCESS) {
location.href = ctx + 'index';
} else {
$.modal.msg(result.msg);
$("input[name='password']").val("");
}
layer.close(index);
}
};
$.ajax(config);
};
var container;
var camera, scene, projector, renderer;
var PI2 = Math.PI * 2;
var programFill = function(context) {
context.beginPath();
context.arc(0, 0, 1, 0, PI2, true);
context.closePath();
context.fill();
};
var programStroke = function(context) {
context.lineWidth = 0.05;
context.beginPath();
context.arc(0, 0, 1, 0, PI2, true);
context.closePath();
context.stroke();
};
var mouse = { x: 0, y: 0 }, INTERSECTED;
function init() {
container = document.createElement('div');
container.id = 'bgc';
container.style.position = 'absolute';
container.style.zIndex = '0';
container.style.top = '0px';
$(".lockscreen-wrapper").before(container);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 300, 500);
scene = new THREE.Scene();
for (var i = 0; i < 100; i++) {
var particle = new THREE.Particle(new THREE.ParticleCanvasMaterial({ color: Math.random() * 0x808080 + 0x808080, program: programStroke }));
particle.position.x = Math.random() * 800 - 400;
particle.position.y = Math.random() * 800 - 400;
particle.position.z = Math.random() * 800 - 400;
particle.scale.x = particle.scale.y = Math.random() * 10 + 10;
scene.add(particle);
}
projector = new THREE.Projector();
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight - 10);
container.appendChild(renderer.domElement);
document.addEventListener('mousemove', onDocumentMouseMove, false);
window.addEventListener('resize', onWindowResize, false);
};
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight - 10);
};
function onDocumentMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
};
function animate() {
requestAnimationFrame(animate);
render();
};
var radius = 600;
var theta = 0;
function render() {
theta += 0.2;
camera.position.x = radius * Math.sin(theta * Math.PI / 360);
camera.position.y = radius * Math.sin(theta * Math.PI / 360);
camera.position.z = radius * Math.cos(theta * Math.PI / 360);
camera.lookAt(scene.position);
camera.updateMatrixWorld();
var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5);
projector.unprojectVector(vector, camera);
var ray = new THREE.Ray(camera.position, vector.subSelf(camera.position).normalize());
var intersects = ray.intersectObjects(scene.children);
if (intersects.length > 0) {
if (INTERSECTED != intersects[0].object) {
if (INTERSECTED) INTERSECTED.material.program = programStroke;
INTERSECTED = intersects[0].object;
INTERSECTED.material.program = programFill;
}
} else {
if (INTERSECTED) INTERSECTED.material.program = programStroke;
INTERSECTED = null;
}
renderer.render(scene, camera);
}
</script>
</html>
@@ -9,7 +9,7 @@
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link href="../static/css/style.css" th:href="@{/css/style.css}" rel="stylesheet"/>
<link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.5.0}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.6.0}" rel="stylesheet"/>
<!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 -->
@@ -65,7 +65,7 @@
</div>
<div class="signup-footer">
<div class="pull-left">
&copy; 2019 All Rights Reserved. RuoYi <br>
Copyright © 2018-2021 ruoyi.vip All Rights Reserved. <br>
</div>
</div>
</div>
@@ -78,7 +78,7 @@
<script src="../static/ajax/libs/validate/messages_zh.min.js" th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script>
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.5.0}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.6.0}"></script>
<script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script>
</body>
</html>
@@ -20,6 +20,7 @@
<br><a target="_blank" href="https://www.aliyun.com/minisite/goods?userCode=brki8iof">https://www.aliyun.com/minisite/goods?userCode=brki8iof</a><br>
领取腾讯云通用云产品2860优惠券
<br><a target="_blank" href="https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console">https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console</a><br>
阿里云服务器折扣区 <a target="_blank" href="http://aly.ruoyi.vip">☛☛点我进入☚☚</a> &nbsp;&nbsp;&nbsp; 腾讯云服务器秒杀区 <a target="_blank" href="http://txy.ruoyi.vip">☛☛点我进入☚☚</a><br>
<h4 class="text-danger">云产品通用红包,可叠加官网常规优惠使用。(仅限新用户)</h4>
</blockquote>
@@ -79,7 +80,7 @@
<div class="ibox-content">
<p><i class="fa fa-send-o"></i> 官网:<a href="http://www.ruoyi.vip" target="_blank">http://www.ruoyi.vip</a>
</p>
<p><i class="fa fa-qq"></i> QQ群:<s>满1389287</s> <s>满1679294</s> <s>满1529866</s> <s>满1772718</s> <s>满1366522</s> <s>满1382251</s> <s>满1145125</s> <s>满86752435</s> <s>满134072510</s> <s>满210336300</s> <s>满339522636</s> <a href="https://jq.qq.com/?_wv=1027&k=qPIKBb7s" target="_blank">130035985</a>
<p><i class="fa fa-qq"></i> QQ群:<s>满1389287</s> <s>满1679294</s> <s>满1529866</s> <s>满1772718</s> <s>满1366522</s> <s>满1382251</s> <s>满1145125</s> <s>满86752435</s> <s>满134072510</s> <s>满210336300</s> <s>满339522636</s> <s>满130035985</s> <a href="https://jq.qq.com/?_wv=1027&k=4NsjKbtU" target="_blank">143151071</a>
</p>
<p><i class="fa fa-weixin"></i> 微信:<a href="javascript:;">/ *若依</a>
</p>
@@ -96,13 +97,85 @@
<div class="ibox-content no-padding">
<div class="panel-body">
<div class="panel-group" id="version">
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v46">v4.6.0</a><code class="pull-right">2021.01.01</code>
</h5>
</div>
<div id="v46" class="panel-collapse collapse in">
<div class="panel-body">
<ol>
<li>新增缓存监控管理</li>
<li>新增锁定屏幕功能</li>
<li>菜单新增是否刷新页面</li>
<li>删除用户和角色解绑关联</li>
<li>新增密码强度字符范围提示</li>
<li>防止匿名访问进行过滤</li>
<li>升级SpringBoot到最新版本2.2.12</li>
<li>升级poi到最新版本4.1.2</li>
<li>升级bitwalker到最新版本1.21</li>
<li>升级bootstrap-fileinput到最新版本5.1.3</li>
<li>升级bootstrapTable到最新版本v1.18.0</li>
<li>升级bootstrapTable相关组件到最新版本v1.18.0</li>
<li>升级oshi到最新版本v5.3.6</li>
<li>新增示例(标签 & 提示)</li>
<li>添加单据打印示例</li>
<li>修改表格初始参数sortName默认值为undefined</li>
<li>新增表格参数(自定义打印页面模板printPageBuilder</li>
<li>新增表格参数(是否显示行间隔色striped)</li>
<li>新增表格参数(渲染完成后执行的事件onPostBody)</li>
<li>Excel注解支持Image图片导出</li>
<li>Excel支持注解align对齐方式</li>
<li>Excel支持导入Boolean型数据</li>
<li>主子表操作添加通用addColumn方法</li>
<li>代码生成日期控件区分范围</li>
<li>代码生成数据库文本类型生成表单文本域</li>
<li>修复生成主子表外键名错误</li>
<li>选项卡新增是否刷新属性</li>
<li>修复树表格表头跟表格宽度不同步的问题</li>
<li>表格树加载完成触发tooltip方法</li>
<li>使用widthUnit定义树表格选项单位</li>
<li>修复主子表editColumn序列问题</li>
<li>修复添加全屏在无参数时没有替换url参数问题</li>
<li>弹出层openOptions移动端自适应</li>
<li>防止错误页返回主页出现嵌套问题</li>
<li>设置回显数据字典验证防止空值</li>
<li>其他细节优化</li>
</ol>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v451">v4.5.1</a><code class="pull-right">2020.11.18</code>
</h5>
</div>
<div id="v451" class="panel-collapse collapse">
<div class="panel-body">
<ol>
<li>阻止任意文件下载漏洞</li>
<li>升级shiro到最新版1.7.0 阻止权限绕过漏洞</li>
<li>升级druid到最新版本v1.2.2</li>
<li>新增表格行触发事件(onCheck、onUncheck、onCheckAll、onUncheckAll</li>
<li>修复多页签关闭非当前选项出现空白问题</li>
<li>代码生成预览支持高亮显示</li>
<li>mapperLocations配置支持分隔符</li>
<li>权限信息调整</li>
<li>个人中心头像和上传头像增加默认图片</li>
<li>全局配置类保持和其他应用命名相同</li>
</ol>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v45">v4.5.0</a><code class="pull-right">2020.10.20</code>
</h5>
</div>
<div id="v45" class="panel-collapse collapse in">
<div id="v45" class="panel-collapse collapse">
<div class="panel-body">
<ol>
<li>新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单)</li>
@@ -0,0 +1,184 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('缓存监控')" />
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content">
<input type="hidden" id="cacheName">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>缓存列表</h5>
<div class="ibox-tools">
<a href="javascript:getCacheNames()"><i class="fa fa-refresh"></i></a>
</div>
</div>
<div class="ibox-content">
<table class="table table-hover no-margins">
<thead>
<tr>
<th></th>
<th>缓存名称</th>
<th>操作</th>
</tr>
</thead>
<tbody id="cacheNames">
<tr th:fragment="fragment-cache-names" th:each="cacheName, stat : ${cacheNames}">
<td>[[${stat.index + 1}]]</td>
<td style="word-wrap:break-word;word-break:break-all;" th:onclick="getCacheKeys([[${cacheName}]])">[[${cacheName}]]</td>
<td style="width: 50px"><a href="#" th:onclick="clearCacheName([[${cacheName}]])" title="清空"><i class="fa fa-trash-o text-danger"></i></a></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>键名列表</h5>
<div class="ibox-tools">
<a href="javascript:getCacheKeys('', true)"><i class="fa fa-refresh"></i></a>
</div>
</div>
<div class="ibox-content">
<table class="table table-hover no-margins">
<thead>
<tr>
<th></th>
<th>缓存键名</th>
<th>操作</th>
</tr>
</thead>
<tbody id="cacheKyes">
<tr th:fragment="fragment-cache-kyes" th:each="cacheKey, stat : ${cacheKyes}">
<td>[[${stat.index + 1}]]</td>
<td style="word-wrap:break-word;word-break:break-all;" th:onclick="getCacheValue([[${cacheName}]], [[${cacheKey}]])">[[${cacheKey}]]</td>
<td style="width: 50px"><a href="#" th:onclick="clearCacheKey([[${cacheName}]], [[${cacheKey}]])" title="清空"><i class="fa fa-trash-o text-danger"></i></a></td>
</tr>
</tbody>
</div>
</table>
</div>
</div>
</div>
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>缓存内容</h5>
<div class="ibox-tools">
<a href="javascript:clearAll()"><i class="fa fa-refresh"></i> 清理全部</a>
</div>
</div>
<div class="ibox-content">
<div class="row" id="cacheValue">
<div class="col-sm-12" th:fragment="fragment-cache-value">
<div class="form-group">
<label>缓存名称:</label>
<input type="text" class="form-control" th:value="${cacheName}">
</div>
<div class="form-group">
<label>缓存键名:</label>
<input type="text"class="form-control" th:value="${cacheKey}">
</div>
<div class="form-group">
<label>缓存内容:</label>
<textarea class="form-control" style="height: 100px">[[${cacheValue}]]</textarea>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "monitor/cache";
function getCacheNames() {
$.ajax({
type: "post",
url: prefix + "/getNames",
data: {
"fragment": 'fragment-cache-names'
},
success: function(data) {
$("#cacheNames").html(data);
$.modal.msgSuccess("刷新缓存列表成功");
}
});
}
function getCacheKeys(cacheName, isMsg) {
var _cacheName = $.common.isNotEmpty(cacheName) ? cacheName : $("#cacheName").val();
$.ajax({
type: "post",
url: prefix + "/getKeys",
data: {
"cacheName": _cacheName,
"fragment": 'fragment-cache-kyes'
},
success: function(data) {
$("#cacheKyes").html(data);
$("#cacheName").val(_cacheName);
if (isMsg) {
$.modal.msgSuccess("刷新键名列表成功");
}
}
});
}
function getCacheValue(cacheName, cacheKey) {
$.ajax({
type: "post",
url: prefix + "/getValue",
data: {
"cacheName": cacheName,
"cacheKey": cacheKey,
"fragment": 'fragment-cache-value'
},
success: function(data) {
$("#cacheValue").html(data);
}
});
}
function clearCacheName(cacheName){
$.post(prefix + "/clearCacheName", {cacheName: cacheName}, function(result) {
if (result.code == web_status.SUCCESS) {
$.modal.msgSuccess("清理缓存[" + cacheName + "]成功")
getCacheKeys(cacheName);
} else {
$.modal.msgError(result.msg);
}
});
}
function clearCacheKey(cacheName, cacheKey) {
$.post(prefix + "/clearCacheKey", {cacheName: cacheName, cacheKey: cacheKey}, function(result) {
if (result.code == web_status.SUCCESS) {
$.modal.msgSuccess("清理缓存[" + cacheKey + "]成功")
getCacheKeys(cacheName);
} else {
$.modal.msgError(result.msg);
}
});
}
function clearAll(){
$.get(prefix + "/clearAll", function(result) {
if (result.code == web_status.SUCCESS) {
$.modal.msgSuccess("清理缓存成功")
} else {
$.modal.msgError(result.msg);
}
});
}
</script>
</html>
@@ -9,7 +9,7 @@
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link href="../static/css/style.css" th:href="@{/css/style.css}" rel="stylesheet"/>
<link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.5.0}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.6.0}" rel="stylesheet"/>
<!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 -->
@@ -77,7 +77,7 @@
<script src="../static/ajax/libs/validate/messages_zh.min.js" th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script>
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.5.0}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.6.0}"></script>
<script src="../static/ruoyi/register.js" th:src="@{/ruoyi/register.js}"></script>
</body>
</html>
@@ -140,7 +140,7 @@
</ul>
</body>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.5.0}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.6.0}"></script>
<script type="text/javascript">
//皮肤样式列表
var skins = ["skin-blue", "skin-green", "skin-purple", "skin-red", "skin-yellow"];
@@ -71,12 +71,23 @@
</div>
<div class="form-group">
<label class="col-sm-3 control-label">菜单状态:</label>
<div class="col-sm-8">
<div class="col-sm-3">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_show_hide')}">
<input type="radio" th:id="${dict.dictCode}" name="visible" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
<label class="col-sm-2 control-label is-refresh" title="打开菜单选项卡是否刷新页面">是否刷新:<i class="fa fa-question-circle-o"></i></label>
<div class="col-sm-3 is-refresh">
<div class="radio-box">
<input type="radio" id="refresh-no" name="isRefresh" value="1" checked>
<label for="refresh-no"></label>
</div>
<div class="radio-box">
<input type="radio" id="refresh-yes" name="isRefresh" value="0">
<label for="refresh-yes"></label>
</div>
</div>
</div>
</form>
</div>
@@ -147,18 +158,21 @@
$("#icon").parents(".form-group").show();
$("#target").parents(".form-group").hide();
$("input[name='visible']").parents(".form-group").show();
$(".is-refresh").hide();
} else if (menuType == "C") {
$("#url").parents(".form-group").show();
$("#perms").parents(".form-group").show();
$("#icon").parents(".form-group").show();
$("#target").parents(".form-group").show();
$("input[name='visible']").parents(".form-group").show();
$(".is-refresh").show();
} else if (menuType == "F") {
$("#url").parents(".form-group").hide();
$("#perms").parents(".form-group").show();
$("#icon").parents(".form-group").hide();
$("#target").parents(".form-group").hide();
$("input[name='visible']").parents(".form-group").hide();
$(".is-refresh").hide();
}
});
});
@@ -72,12 +72,23 @@
</div>
<div class="form-group">
<label class="col-sm-3 control-label">菜单状态:</label>
<div class="col-sm-8">
<div class="col-sm-3">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_show_hide')}">
<input type="radio" th:id="${dict.dictCode}" name="visible" th:value="${dict.dictValue}" th:field="*{visible}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
<label class="col-sm-2 control-label is-refresh" title="打开菜单选项卡是否刷新页面">是否刷新:<i class="fa fa-question-circle-o"></i></label>
<div class="col-sm-3 is-refresh">
<div class="radio-box">
<input type="radio" id="refresh-no" name="isRefresh" value="1" th:field="*{isRefresh}">
<label for="refresh-no"></label>
</div>
<div class="radio-box">
<input type="radio" id="refresh-yes" name="isRefresh" value="0" th:field="*{isRefresh}">
<label for="refresh-yes"></label>
</div>
</div>
</div>
</form>
</div>
@@ -163,18 +174,21 @@
$("#icon").parents(".form-group").show();
$("#target").parents(".form-group").hide();
$("input[name='visible']").parents(".form-group").show();
$(".is-refresh").hide();
} else if (menuType == "C") {
$("#url").parents(".form-group").show();
$("#perms").parents(".form-group").show();
$("#icon").parents(".form-group").show();
$("#target").parents(".form-group").show();
$("input[name='visible']").parents(".form-group").show();
$(".is-refresh").show();
} else if (menuType == "F") {
$("#url").parents(".form-group").hide();
$("#perms").parents(".form-group").show();
$("#icon").parents(".form-group").hide();
$("#target").parents(".form-group").hide();
$("input[name='visible']").parents(".form-group").hide();
$(".is-refresh").hide();
}
}
@@ -72,7 +72,8 @@
{
title: '菜单名称',
field: 'menuName',
width: '20%',
width: '20',
widthUnit: '%',
formatter: function(value, row, index) {
if ($.common.isEmpty(row.icon)) {
return row.menuName;
@@ -84,13 +85,15 @@
{
field: 'orderNum',
title: '排序',
width: '10%',
width: '10',
widthUnit: '%',
align: "left"
},
{
field: 'url',
title: '请求地址',
width: '15%',
width: '15',
widthUnit: '%',
align: "left",
formatter: function(value, row, index) {
return $.table.tooltip(value);
@@ -99,7 +102,8 @@
{
title: '类型',
field: 'menuType',
width: '10%',
width: '10',
widthUnit: '%',
align: "left",
formatter: function(value, item, index) {
if (item.menuType == 'M') {
@@ -116,7 +120,8 @@
{
field: 'visible',
title: '可见',
width: '10%',
width: '10',
widthUnit: '%',
align: "left",
formatter: function(value, row, index) {
if (row.menuType == 'F') {
@@ -128,7 +133,8 @@
{
field: 'perms',
title: '权限标识',
width: '15%',
width: '15',
widthUnit: '%',
align: "left",
formatter: function(value, row, index) {
return $.table.tooltip(value);
@@ -136,7 +142,8 @@
},
{
title: '操作',
width: '20%',
width: '20',
widthUnit: '%',
align: "left",
formatter: function(value, row, index) {
var actions = [];
@@ -134,7 +134,7 @@
<div class="row container">
<div class="col-md-10">
<div class="imageBox">
<img id="avatar" th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" >
<img id="avatar" th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="'this.src=\'' + @{'/img/profile.jpg'} + '\''">
</div>
<div class="action">
<div class="new-contentarea tc">
@@ -16,7 +16,7 @@
</div>
<div class="ibox-content">
<div class="text-center">
<p class="user-info-head" onclick="avatar()"><img class="img-circle img-lg" th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}"></p>
<p class="user-info-head" onclick="avatar()"><img class="img-circle img-lg" th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="'this.src=\'' + @{'/img/profile.jpg'} + '\''"></p>
<p><a href="javascript:avatar()">修改头像</a></p>
</div>
<ul class="list-group list-group-striped">
@@ -115,6 +115,16 @@
<label class="col-sm-2 control-label">新密码:</label>
<div class="col-sm-10">
<input type="password" class="form-control" name="newPassword" id="newPassword" placeholder="请输入新密码">
<th:block th:with="chrtype=${@config.getKey('sys.account.chrtype')}">
<th:block th:if="${chrtype != '0'}">
<span class="help-block m-b-none">
<th:block th:if="${chrtype == '1'}"><i class="fa fa-info-circle" style="color: red;"></i> 密码只能为0-9数字 </th:block>
<th:block th:if="${chrtype == '2'}"><i class="fa fa-info-circle" style="color: red;"></i> 密码只能为a-z和A-Z字母</th:block>
<th:block th:if="${chrtype == '3'}"><i class="fa fa-info-circle" style="color: red;"></i> 密码必须包含(字母,数字)</th:block>
<th:block th:if="${chrtype == '4'}"><i class="fa fa-info-circle" style="color: red;"></i> 密码必须包含(字母,数字,特殊字符!@#$%^&*()-=_+</th:block>
</span>
</th:block>
</th:block>
</div>
</div>
<div class="form-group">
@@ -1,94 +1,104 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改用户密码')" />
<th:block th:include="include :: header('修改用户密码')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-user-resetPwd">
<input name="userId" type="hidden" th:value="${user.userId}" />
<div class="form-group">
<label class="col-sm-3 control-label">登录名称:</label>
<div class="col-sm-8">
<input class="form-control" type="text" readonly="true" name="loginName" th:value="${user.loginName}"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">旧密码:</label>
<div class="col-sm-8">
<input class="form-control" type="password" name="oldPassword" id="oldPassword">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">新密码:</label>
<div class="col-sm-8">
<input class="form-control" type="password" name="newPassword" id="newPassword">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">再次确认:</label>
<div class="col-sm-8">
<input class="form-control" type="password" name="confirmPassword" id="confirmPassword">
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 请再次输入您的密码</span>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-user-resetPwd">
<input name="userId" type="hidden" th:value="${user.userId}" />
<div class="form-group">
<label class="col-sm-3 control-label">登录名称:</label>
<div class="col-sm-8">
<input class="form-control" type="text" readonly="true" name="loginName" th:value="${user.loginName}"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">旧密码:</label>
<div class="col-sm-8">
<input class="form-control" type="password" name="oldPassword" id="oldPassword">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">新密码:</label>
<div class="col-sm-8">
<input class="form-control" type="password" name="newPassword" id="newPassword">
<th:block th:with="chrtype=${@config.getKey('sys.account.chrtype')}">
<th:block th:if="${chrtype != '0'}">
<span class="help-block m-b-none">
<th:block th:if="${chrtype == '1'}"><i class="fa fa-info-circle" style="color: red;"></i> 密码只能为0-9数字 </th:block>
<th:block th:if="${chrtype == '2'}"><i class="fa fa-info-circle" style="color: red;"></i> 密码只能为a-z和A-Z字母</th:block>
<th:block th:if="${chrtype == '3'}"><i class="fa fa-info-circle" style="color: red;"></i> 密码必须包含(字母,数字)</th:block>
<th:block th:if="${chrtype == '4'}"><i class="fa fa-info-circle" style="color: red;"></i> 密码必须包含(字母,数字,特殊字符!@#$%^&*()-=_+</th:block>
</span>
</th:block>
</th:block>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">再次确认:</label>
<div class="col-sm-8">
<input class="form-control" type="password" name="confirmPassword" id="confirmPassword">
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 请再次输入您的密码</span>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script>
$("#form-user-resetPwd").validate({
rules:{
oldPassword:{
required:true,
remote: {
url: ctx + "system/user/profile/checkPassword",
type: "get",
dataType: "json",
data: {
password: function() {
return $("input[name='oldPassword']").val();
}
}
}
},
newPassword: {
required: true,
minlength: 5,
maxlength: 20
},
confirmPassword: {
required: true,
equalTo: "#newPassword"
}
},
messages: {
oldPassword: {
required: "请输入原密码",
remote: "原密码错误"
},
newPassword: {
required: "请输入新密码",
minlength: "密码不能小于5个字符",
maxlength: "密码不能大于20个字符"
},
confirmPassword: {
required: "请再次输入新密码",
equalTo: "两次密码输入不一致"
}
<script>
$("#form-user-resetPwd").validate({
rules:{
oldPassword:{
required:true,
remote: {
url: ctx + "system/user/profile/checkPassword",
type: "get",
dataType: "json",
data: {
password: function() {
return $("input[name='oldPassword']").val();
}
}
}
},
newPassword: {
required: true,
minlength: 5,
maxlength: 20
},
confirmPassword: {
required: true,
equalTo: "#newPassword"
}
},
messages: {
oldPassword: {
required: "请输入原密码",
remote: "原密码错误"
},
newPassword: {
required: "请输入新密码",
minlength: "密码不能小于5个字符",
maxlength: "密码不能大于20个字符"
},
confirmPassword: {
required: "请再次输入新密码",
equalTo: "两次密码输入不一致"
}
},
focusCleanup: true
});
function submitHandler() {
var chrtype = [[${#strings.defaultString(@config.getKey('sys.account.chrtype'), 0)}]];
var password = $("#newPassword").val();
if ($.validate.form() && checkpwd(chrtype, password)) {
$.operate.save(ctx + "system/user/profile/resetPwd", $('#form-user-resetPwd').serialize());
}
}
</script>
},
focusCleanup: true
});
function submitHandler() {
var chrtype = [[${#strings.defaultString(@config.getKey('sys.account.chrtype'), 0)}]];
var password = $("#newPassword").val();
if ($.validate.form() && checkpwd(chrtype, password)) {
$.operate.save(ctx + "system/user/profile/resetPwd", $('#form-user-resetPwd').serialize());
}
}
</script>
</body>
</html>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.5.0</version>
<version>4.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -105,6 +105,27 @@ public @interface Excel
*/
public boolean isStatistics() default false;
/**
* 导出字段对齐方式0默认1靠左2居中3靠右
*/
Align align() default Align.AUTO;
public enum Align
{
AUTO(0), LEFT(1), CENTER(2), RIGHT(3);
private final int value;
Align(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
/**
* 字段类型0导出导入1仅导出2仅导入
*/
@@ -128,7 +149,7 @@ public @interface Excel
public enum ColumnType
{
NUMERIC(0), STRING(1);
NUMERIC(0), STRING(1), IMAGE(2);
private final int value;
ColumnType(int value)
@@ -10,7 +10,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@ConfigurationProperties(prefix = "ruoyi")
public class Global
public class RuoYiConfig
{
/** 项目名称 */
private static String name;
@@ -37,7 +37,7 @@ public class Global
public void setName(String name)
{
Global.name = name;
RuoYiConfig.name = name;
}
public static String getVersion()
@@ -47,7 +47,7 @@ public class Global
public void setVersion(String version)
{
Global.version = version;
RuoYiConfig.version = version;
}
public static String getCopyrightYear()
@@ -57,7 +57,7 @@ public class Global
public void setCopyrightYear(String copyrightYear)
{
Global.copyrightYear = copyrightYear;
RuoYiConfig.copyrightYear = copyrightYear;
}
public static boolean isDemoEnabled()
@@ -67,7 +67,7 @@ public class Global
public void setDemoEnabled(boolean demoEnabled)
{
Global.demoEnabled = demoEnabled;
RuoYiConfig.demoEnabled = demoEnabled;
}
public static String getProfile()
@@ -77,7 +77,7 @@ public class Global
public void setProfile(String profile)
{
Global.profile = profile;
RuoYiConfig.profile = profile;
}
public static boolean isAddressEnabled()
@@ -87,7 +87,7 @@ public class Global
public void setAddressEnabled(boolean addressEnabled)
{
Global.addressEnabled = addressEnabled;
RuoYiConfig.addressEnabled = addressEnabled;
}
/**
@@ -66,6 +66,11 @@ public class Constants
* 排序的方向 "desc" 或者 "asc".
*/
public static final String IS_ASC = "isAsc";
/**
* 系统用户授权缓存
*/
public static final String SYS_AUTH_CACHE = "sys-authCache";
/**
* 参数管理 cache name
@@ -32,15 +32,17 @@ public class GenConstants
public static final String PARENT_MENU_NAME = "parentMenuName";
/** 数据库字符串类型 */
public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2", "tinytext", "text",
"mediumtext", "longtext" };
public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };
/** 数据库文本类型 */
public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };
/** 数据库时间类型 */
public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
/** 数据库数字类型 */
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
"bit", "bigint", "float", "float", "double", "decimal" };
"bit", "bigint", "float", "double", "decimal" };
/** 页面不需要编辑字段 */
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
@@ -13,10 +13,15 @@ public class ShiroConstants
public static final String CURRENT_USER = "currentUser";
/**
* 用户名
* 用户名字段
*/
public static final String CURRENT_USERNAME = "username";
/**
* 锁定屏幕字段
*/
public static final String LOCK_SCREEN = "lockscreen";
/**
* 消息key
*/
@@ -1,4 +1,4 @@
package com.ruoyi.system.domain;
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -1,4 +1,4 @@
package com.ruoyi.system.domain;
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -1,4 +1,4 @@
package com.ruoyi.system.domain;
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -1,4 +1,4 @@
package com.ruoyi.system.domain;
package com.ruoyi.common.core.domain.entity;
import java.util.List;
import java.util.ArrayList;
@@ -34,15 +34,18 @@ public class SysMenu extends BaseEntity
/** 菜单URL */
private String url;
/** 打开方式menuItem页签 menuBlank新窗口 */
/** 打开方式menuItem页签 menuBlank新窗口 */
private String target;
/** 类型:0目录,1菜单,2按钮 */
/** 类型M目录 C菜单 F按钮 */
private String menuType;
/** 菜单状态:0显示,1隐藏 */
/** 菜单状态0显示 1隐藏 */
private String visible;
/** 是否刷新(0刷新 1不刷新) */
private String isRefresh;
/** 权限字符串 */
private String perms;
@@ -147,6 +150,16 @@ public class SysMenu extends BaseEntity
this.visible = visible;
}
public String getIsRefresh()
{
return isRefresh;
}
public void setIsRefresh(String isRefresh)
{
this.isRefresh = isRefresh;
}
@Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
public String getPerms()
{
@@ -1,4 +1,4 @@
package com.ruoyi.system.domain;
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -1,4 +1,4 @@
package com.ruoyi.system.domain;
package com.ruoyi.common.core.domain.entity;
import java.util.Date;
import java.util.List;
@@ -66,7 +66,7 @@ public class CharsetKit
if (null == destCharset)
{
srcCharset = StandardCharsets.UTF_8;
destCharset = StandardCharsets.UTF_8;
}
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
@@ -3,7 +3,7 @@ package com.ruoyi.common.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.http.HttpUtils;
@@ -30,7 +30,7 @@ public class AddressUtils
{
return "内网IP";
}
if (Global.isAddressEnabled())
if (RuoYiConfig.isAddressEnabled())
{
try
{
@@ -4,6 +4,7 @@ import java.util.Iterator;
import java.util.Set;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.utils.spring.SpringUtils;
@@ -174,7 +175,7 @@ public class CacheUtils
* @param cacheName
* @return
*/
private static Cache<String, Object> getCache(String cacheName)
public static Cache<String, Object> getCache(String cacheName)
{
Cache<String, Object> cache = cacheManager.getCache(cacheName);
if (cache == null)
@@ -184,4 +185,13 @@ public class CacheUtils
return cache;
}
/**
* 获取所有缓存
*
* @return 缓存组
*/
public static String[] getCacheNames()
{
return ((EhCacheManager) cacheManager).getCacheManager().getCacheNames();
}
}
@@ -1,11 +1,9 @@
package com.ruoyi.system.utils;
package com.ruoyi.common.utils;
import java.util.List;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.CacheUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictData;
/**
* 字典工具类
@@ -1,4 +1,4 @@
package com.ruoyi.framework.util;
package com.ruoyi.common.utils;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -8,7 +8,6 @@ import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.json.JSON;
import com.ruoyi.common.utils.IpUtils;
/**
* 处理并记录日志文件
@@ -1,16 +1,13 @@
package com.ruoyi.framework.util;
package com.ruoyi.common.utils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.framework.shiro.realm.UserRealm;
import com.ruoyi.system.domain.SysUser;
/**
* shiro 工具类
@@ -56,13 +53,6 @@ public class ShiroUtils
subject.runAs(newPrincipalCollection);
}
public static void clearCachedAuthorizationInfo()
{
RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
UserRealm realm = (UserRealm) rsm.getRealms().iterator().next();
realm.clearCachedAuthorizationInfo();
}
public static Long getUserId()
{
return getSysUser().getUserId().longValue();
@@ -0,0 +1,76 @@
package com.ruoyi.common.utils.file;
import java.io.File;
import org.apache.commons.lang3.StringUtils;
/**
* 文件类型工具类
*
* @author ruoyi
*/
public class FileTypeUtils
{
/**
* 获取文件类型
* <p>
* 例如: ruoyi.txt, 返回: txt
*
* @param file 文件名
* @return 后缀不含".")
*/
public static String getFileType(File file)
{
if (null == file)
{
return StringUtils.EMPTY;
}
return getFileType(file.getName());
}
/**
* 获取文件类型
* <p>
* 例如: ruoyi.txt, 返回: txt
*
* @param fileName 文件名
* @return 后缀不含".")
*/
public static String getFileType(String fileName)
{
int separatorIndex = fileName.lastIndexOf(".");
if (separatorIndex < 0)
{
return "";
}
return fileName.substring(separatorIndex + 1).toLowerCase();
}
/**
* 获取文件类型
*
* @param photoByte 文件字节码
* @return 后缀不含".")
*/
public static String getFileExtendName(byte[] photoByte)
{
String strFileExtendName = "JPG";
if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
&& ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
{
strFileExtendName = "GIF";
}
else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
{
strFileExtendName = "JPG";
}
else if ((photoByte[0] == 66) && (photoByte[1] == 77))
{
strFileExtendName = "BMP";
}
else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
{
strFileExtendName = "PNG";
}
return strFileExtendName;
}
}
@@ -4,7 +4,7 @@ import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException;
import com.ruoyi.common.exception.file.FileSizeLimitExceededException;
@@ -33,7 +33,7 @@ public class FileUploadUtils
/**
* 默认上传的地址
*/
private static String defaultBaseDir = Global.getProfile();
private static String defaultBaseDir = RuoYiConfig.getProfile();
public static void setDefaultBaseDir(String defaultBaseDir)
{
@@ -143,7 +143,7 @@ public class FileUploadUtils
private static final String getPathFileName(String uploadDir, String fileName) throws IOException
{
int dirLastIndex = Global.getProfile().length() + 1;
int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
return pathFileName;
@@ -195,7 +195,6 @@ public class FileUploadUtils
throw new InvalidExtensionException(allowedExtension, extension, fileName);
}
}
}
/**
@@ -10,6 +10,8 @@ import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import com.ruoyi.common.utils.StringUtils;
/**
* 文件处理工具类
@@ -106,6 +108,30 @@ public class FileUtils extends org.apache.commons.io.FileUtils
return filename.matches(FILENAME_PATTERN);
}
/**
* 检查文件是否可下载
*
* @param resource 需要下载的文件
* @return true 正常 false 非法
*/
public static boolean checkAllowDownload(String resource)
{
// 禁止目录上跳级别
if (StringUtils.contains(resource, ".."))
{
return false;
}
// 检查允许下载的文件规则
if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
{
return true;
}
// 不在允许下载的文件规则
return false;
}
/**
* 下载文件名重新编码
*
@@ -113,8 +139,7 @@ public class FileUtils extends org.apache.commons.io.FileUtils
* @param fileName 文件名
* @return 编码后的文件名
*/
public static String setFileDownloadHeader(HttpServletRequest request, String fileName)
throws UnsupportedEncodingException
public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
{
final String agent = request.getHeader("USER-AGENT");
String filename = fileName;
@@ -0,0 +1,100 @@
package com.ruoyi.common.utils.file;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import org.apache.poi.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.StringUtils;
/**
* 图片处理工具类
*
* @author ruoyi
*/
public class ImageUtils
{
private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);
public static byte[] getImage(String imagePath)
{
InputStream is = getFile(imagePath);
try
{
return IOUtils.toByteArray(is);
}
catch (Exception e)
{
log.error("图片加载异常 {}", e);
return null;
}
finally
{
IOUtils.closeQuietly(is);
}
}
public static InputStream getFile(String imagePath)
{
try
{
byte[] result = readFile(imagePath);
result = Arrays.copyOf(result, result.length);
return new ByteArrayInputStream(result);
}
catch (Exception e)
{
log.error("获取图片异常 {}", e);
}
return null;
}
/**
* 读取文件为字节数据
*
* @param key 地址
* @return 字节数据
*/
public static byte[] readFile(String url)
{
InputStream in = null;
ByteArrayOutputStream baos = null;
try
{
if (url.startsWith("http"))
{
// 网络地址
URL urlObj = new URL(url);
URLConnection urlConnection = urlObj.openConnection();
urlConnection.setConnectTimeout(30 * 1000);
urlConnection.setReadTimeout(60 * 1000);
urlConnection.setDoInput(true);
in = urlConnection.getInputStream();
}
else
{
// 本机地址
String localPath = RuoYiConfig.getProfile();
String downloadPath = localPath + StringUtils.substringAfter(url, Constants.RESOURCE_PREFIX);
in = new FileInputStream(downloadPath);
}
return IOUtils.toByteArray(in);
}
catch (Exception e)
{
log.error("获取文件路径异常 {}", e);
return null;
}
finally
{
IOUtils.closeQuietly(baos);
}
}
}
@@ -6,7 +6,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
@@ -19,15 +18,16 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
@@ -39,6 +39,7 @@ import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,14 +47,16 @@ import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.annotation.Excels;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileTypeUtils;
import com.ruoyi.common.utils.file.ImageUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
/**
* Excel相关处理
@@ -104,16 +107,21 @@ public class ExcelUtil<T>
*/
private List<Object[]> fields;
/**
* 最大高度
*/
private short maxHeight;
/**
* 统计列表
*/
private Map<Integer, Double> statistics = new HashMap<Integer, Double>();
/**
* 数字格式
*/
private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
/**
* 实体对象
*/
@@ -211,7 +219,10 @@ public class ExcelUtil<T>
// 设置类的私有字段属性可访问.
field.setAccessible(true);
Integer column = cellMap.get(attr.name());
fieldsMap.put(column, field);
if (column != null)
{
fieldsMap.put(column, field);
}
}
}
for (int i = 1; i < rows; i++)
@@ -280,6 +291,10 @@ public class ExcelUtil<T>
val = DateUtil.getJavaDate((Double) val);
}
}
else if (Boolean.TYPE == fieldType || Boolean.class == fieldType)
{
val = Convert.toBool(val, false);
}
if (StringUtils.isNotNull(fieldType))
{
Excel attr = field.getAnnotation(Excel.class);
@@ -475,6 +490,21 @@ public class ExcelUtil<T>
style.setFont(totalFont);
styles.put("total", style);
style = wb.createCellStyle();
style.cloneStyleFrom(styles.get("data"));
style.setAlignment(HorizontalAlignment.LEFT);
styles.put("data1", style);
style = wb.createCellStyle();
style.cloneStyleFrom(styles.get("data"));
style.setAlignment(HorizontalAlignment.CENTER);
styles.put("data2", style);
style = wb.createCellStyle();
style.cloneStyleFrom(styles.get("data"));
style.setAlignment(HorizontalAlignment.RIGHT);
styles.put("data3", style);
return styles;
}
@@ -503,14 +533,53 @@ public class ExcelUtil<T>
{
if (ColumnType.STRING == attr.cellType())
{
cell.setCellType(CellType.STRING);
cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix());
}
else if (ColumnType.NUMERIC == attr.cellType())
{
cell.setCellType(CellType.NUMERIC);
cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value));
}
else if (ColumnType.IMAGE == attr.cellType())
{
ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1),
cell.getRow().getRowNum() + 1);
String imagePath = Convert.toStr(value);
if (StringUtils.isNotEmpty(imagePath))
{
byte[] data = ImageUtils.getImage(imagePath);
getDrawingPatriarch(cell.getSheet()).createPicture(anchor,
cell.getSheet().getWorkbook().addPicture(data, getImageType(data)));
}
}
}
/**
* 获取画布
*/
public static Drawing<?> getDrawingPatriarch(Sheet sheet)
{
if (sheet.getDrawingPatriarch() == null)
{
sheet.createDrawingPatriarch();
}
return sheet.getDrawingPatriarch();
}
/**
* 获取图片类型,设置图片插入类型
*/
public int getImageType(byte[] value)
{
String type = FileTypeUtils.getFileExtendName(value);
if ("JPG".equalsIgnoreCase(type))
{
return Workbook.PICTURE_TYPE_JPEG;
}
else if ("PNG".equalsIgnoreCase(type))
{
return Workbook.PICTURE_TYPE_PNG;
}
return Workbook.PICTURE_TYPE_JPEG;
}
/**
@@ -526,7 +595,6 @@ public class ExcelUtil<T>
{
// 设置列宽
sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
row.setHeight((short) (attr.height() * 20));
}
// 如果设置了提示信息则鼠标放上去提示.
if (StringUtils.isNotEmpty(attr.prompt()))
@@ -551,13 +619,14 @@ public class ExcelUtil<T>
try
{
// 设置行高
row.setHeight((short) (attr.height() * 20));
row.setHeight(maxHeight);
// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
if (attr.isExport())
{
// 创建cell
cell = row.createCell(column);
cell.setCellStyle(styles.get("data"));
int align = attr.align().value();
cell.setCellStyle(styles.get("data" + (align >= 1 && align <= 3 ? align : "")));
// 用于读取对象中的属性
Object value = getTargetValue(vo, field, attr);
@@ -660,40 +729,32 @@ public class ExcelUtil<T>
* @param converterExp 翻译注解
* @param separator 分隔符
* @return 解析后值
* @throws Exception
*/
public static String convertByExp(String propertyValue, String converterExp, String separator) throws Exception
public static String convertByExp(String propertyValue, String converterExp, String separator)
{
StringBuilder propertyString = new StringBuilder();
try
String[] convertSource = converterExp.split(",");
for (String item : convertSource)
{
String[] convertSource = converterExp.split(",");
for (String item : convertSource)
String[] itemArray = item.split("=");
if (StringUtils.containsAny(separator, propertyValue))
{
String[] itemArray = item.split("=");
if (StringUtils.containsAny(separator, propertyValue))
for (String value : propertyValue.split(separator))
{
for (String value : propertyValue.split(separator))
if (itemArray[0].equals(value))
{
if (itemArray[0].equals(value))
{
propertyString.append(itemArray[1] + separator);
break;
}
}
}
else
{
if (itemArray[0].equals(propertyValue))
{
return itemArray[1];
propertyString.append(itemArray[1] + separator);
break;
}
}
}
}
catch (Exception e)
{
throw e;
else
{
if (itemArray[0].equals(propertyValue))
{
return itemArray[1];
}
}
}
return StringUtils.stripEnd(propertyString.toString(), separator);
}
@@ -705,9 +766,8 @@ public class ExcelUtil<T>
* @param converterExp 翻译注解
* @param separator 分隔符
* @return 解析后值
* @throws Exception
*/
public static String reverseByExp(String propertyValue, String converterExp, String separator) throws Exception
public static String reverseByExp(String propertyValue, String converterExp, String separator)
{
StringBuilder propertyString = new StringBuilder();
String[] convertSource = converterExp.split(",");
@@ -735,7 +795,7 @@ public class ExcelUtil<T>
}
return StringUtils.stripEnd(propertyString.toString(), separator);
}
/**
* 解析字典值
*
@@ -744,12 +804,9 @@ public class ExcelUtil<T>
* @param separator 分隔符
* @return 字典标签
*/
public static String convertDictByExp(String dictValue, String dictType, String separator) throws Exception
public static String convertDictByExp(String dictValue, String dictType, String separator)
{
Object bean = SpringUtils.getBean("dictUtils");
String methodName = "getDictLabel";
Method method = bean.getClass().getDeclaredMethod(methodName, String.class, String.class, String.class);
return Convert.toStr(method.invoke(bean, dictType, dictValue, separator));
return DictUtils.getDictLabel(dictType, dictValue, separator);
}
/**
@@ -760,14 +817,11 @@ public class ExcelUtil<T>
* @param separator 分隔符
* @return 字典值
*/
public static String reverseDictByExp(String dictLabel, String dictType, String separator) throws Exception
public static String reverseDictByExp(String dictLabel, String dictType, String separator)
{
Object bean = SpringUtils.getBean("dictUtils");
String methodName = "getDictValue";
Method method = bean.getClass().getDeclaredMethod(methodName, String.class, String.class, String.class);
return Convert.toStr(method.invoke(bean, dictType, dictLabel, separator));
return DictUtils.getDictValue(dictType, dictLabel, separator);
}
/**
* 合计统计信息
*/
@@ -804,7 +858,7 @@ public class ExcelUtil<T>
cell = row.createCell(0);
cell.setCellStyle(styles.get("total"));
cell.setCellValue("合计");
for (Integer key : keys)
{
cell = row.createCell(key);
@@ -831,7 +885,7 @@ public class ExcelUtil<T>
*/
public String getAbsoluteFile(String filename)
{
String downloadPath = Global.getDownloadPath() + filename;
String downloadPath = RuoYiConfig.getDownloadPath() + filename;
File desc = new File(downloadPath);
if (!desc.getParentFile().exists())
{
@@ -881,7 +935,7 @@ public class ExcelUtil<T>
*/
private Object getValue(Object o, String name) throws Exception
{
if (StringUtils.isNotEmpty(name))
if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name))
{
Class<?> clazz = o.getClass();
Field field = clazz.getDeclaredField(name);
@@ -920,6 +974,21 @@ public class ExcelUtil<T>
}
}
this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList());
this.maxHeight = getRowHeight();
}
/**
* 根据注解获取最大行高
*/
public short getRowHeight()
{
double maxHeight = 0;
for (Object[] os : this.fields)
{
Excel excel = (Excel) os[1];
maxHeight = maxHeight > excel.height() ? maxHeight : excel.height();
}
return (short) (maxHeight * 20);
}
/**
@@ -981,10 +1050,10 @@ public class ExcelUtil<T>
Cell cell = row.getCell(column);
if (StringUtils.isNotNull(cell))
{
if (cell.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA)
if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA)
{
val = cell.getNumericCellValue();
if (HSSFDateUtil.isCellDateFormatted(cell))
if (DateUtil.isCellDateFormatted(cell))
{
val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换
}
@@ -1000,15 +1069,15 @@ public class ExcelUtil<T>
}
}
}
else if (cell.getCellTypeEnum() == CellType.STRING)
else if (cell.getCellType() == CellType.STRING)
{
val = cell.getStringCellValue();
}
else if (cell.getCellTypeEnum() == CellType.BOOLEAN)
else if (cell.getCellType() == CellType.BOOLEAN)
{
val = cell.getBooleanCellValue();
}
else if (cell.getCellTypeEnum() == CellType.ERROR)
else if (cell.getCellType() == CellType.ERROR)
{
val = cell.getErrorCellValue();
}
@@ -204,6 +204,10 @@ public class ReflectUtils
args[i] = DateUtil.getJavaDate((Double) args[i]);
}
}
else if (cs[i] == boolean.class || cs[i] == Boolean.class)
{
args[i] = Convert.toBool(args[i]);
}
}
}
return (E) method.invoke(obj, args);
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.5.0</version>
<version>4.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

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