Merge remote-tracking branch 'upstream/master'

This commit is contained in:
tangliu 2021-05-27 15:46:50 +08:00
commit 99d952244f
88 changed files with 1259 additions and 2574 deletions

View File

@ -88,4 +88,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群](https://img.shields.io/badge/143151071-blue.svg)](https://jq.qq.com/?_wv=1027&k=4NsjKbtU)
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-1389287-blue.svg)](https://jq.qq.com/?_wv=1027&k=5HBAaYN) [![加入QQ群](https://img.shields.io/badge/已满-1679294-blue.svg)](https://jq.qq.com/?_wv=1027&k=5cHeRVW) [![加入QQ群](https://img.shields.io/badge/已满-1529866-blue.svg)](https://jq.qq.com/?_wv=1027&k=53R0L5Z) [![加入QQ群](https://img.shields.io/badge/已满-1772718-blue.svg)](https://jq.qq.com/?_wv=1027&k=5g75dCU) [![加入QQ群](https://img.shields.io/badge/已满-1366522-blue.svg)](https://jq.qq.com/?_wv=1027&k=58cPoHA) [![加入QQ群](https://img.shields.io/badge/已满-1382251-blue.svg)](https://jq.qq.com/?_wv=1027&k=5Ofd4Pb) [![加入QQ群](https://img.shields.io/badge/已满-1145125-blue.svg)](https://jq.qq.com/?_wv=1027&k=5yugASz) [![加入QQ群](https://img.shields.io/badge/已满-86752435-blue.svg)](https://jq.qq.com/?_wv=1027&k=5Rf3d2P) [![加入QQ群](https://img.shields.io/badge/已满-134072510-blue.svg)](https://jq.qq.com/?_wv=1027&k=5ZIjaeP) [![加入QQ群](https://img.shields.io/badge/已满-210336300-blue.svg)](https://jq.qq.com/?_wv=1027&k=5CJw1jY) [![加入QQ群](https://img.shields.io/badge/已满-339522636-blue.svg)](https://jq.qq.com/?_wv=1027&k=5omzbKc) [![加入QQ群](https://img.shields.io/badge/已满-130035985-blue.svg)](https://jq.qq.com/?_wv=1027&k=qPIKBb7s) [![加入QQ群](https://img.shields.io/badge/已满-143151071-blue.svg)](https://jq.qq.com/?_wv=1027&k=4NsjKbtU) [![加入QQ群](https://img.shields.io/badge/已满-158781320-blue.svg)](https://jq.qq.com/?_wv=1027&k=VD2pkz2G) [![加入QQ群](https://img.shields.io/badge/201531282-blue.svg)](https://jq.qq.com/?_wv=1027&k=HlshFwkJ)

16
pom.xml
View File

@ -5,26 +5,27 @@
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>4.6.0</version>
<version>4.6.1</version>
<name>ruoyi</name>
<url>http://www.ruoyi.vip</url>
<description>若依管理系统</description>
<properties>
<ruoyi.version>4.6.0</ruoyi.version>
<ruoyi.version>4.6.1</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.7.1</shiro.version>
<thymeleaf.extras.shiro.version>2.0.0</thymeleaf.extras.shiro.version>
<druid.version>1.2.4</druid.version>
<druid.version>1.2.6</druid.version>
<bitwalker.version>1.21</bitwalker.version>
<kaptcha.version>2.3.2</kaptcha.version>
<swagger.version>2.9.2</swagger.version>
<mybatis-spring-boot.version>2.1.4</mybatis-spring-boot.version>
<pagehelper.boot.version>1.3.0</pagehelper.boot.version>
<fastjson.version>1.2.75</fastjson.version>
<fastjson.version>1.2.76</fastjson.version>
<oshi.version>5.6.0</oshi.version>
<jna.version>5.7.0</jna.version>
<commons.io.version>2.5</commons.io.version>
@ -95,6 +96,13 @@
<version>${bitwalker.version}</version>
</dependency>
<!-- SpringBoot集成mybatis框架 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot.version}</version>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.6.0</version>
<version>4.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
@ -107,6 +107,38 @@
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
<!-- YUI Compressor (CSS/JS压缩)
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.5.1</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<encoding>UTF-8</encoding>
<jswarn>false</jswarn>
<nosuffix>true</nosuffix>
<linebreakpos>50000</linebreakpos>
<sourceDirectory>src/main/resources/static</sourceDirectory>
<force>true</force>
<includes>
<include>**/*.js</include>
<include>**/*.css</include>
</includes>
<excludes>
<exclude>**/*.min.js</exclude>
<exclude>**/*.min.css</exclude>
<exclude>**/fileinput.js</exclude>
<exclude>**/bootstrap-treetable.js</exclude>
</excludes>
</configuration>
</plugin> -->
</plugins>
<finalName>${project.artifactId}</finalName>
</build>

View File

@ -12,13 +12,17 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
/**
* 表格相关
@ -107,6 +111,44 @@ public class DemoTableController extends BaseController
return prefix + "/export";
}
/**
* 表格导出选择列
*/
@GetMapping("/exportSelected")
public String exportSelected()
{
return prefix + "/exportSelected";
}
/**
* 导出数据
*/
@PostMapping("/exportData")
@ResponseBody
public AjaxResult exportSelected(UserTableModel userModel, String userIds)
{
List<UserTableModel> userList = new ArrayList<UserTableModel>(Arrays.asList(new UserTableModel[users.size()]));
Collections.copy(userList, users);
// 条件过滤
if (StringUtils.isNotEmpty(userIds))
{
userList.clear();
for (Long userId : Convert.toLongArray(userIds))
{
for (UserTableModel user : users)
{
if (user.getUserId() == userId)
{
userList.add(user);
}
}
}
}
ExcelUtil<UserTableModel> util = new ExcelUtil<UserTableModel>(UserTableModel.class);
return util.exportExcel(userList, "用户数据");
}
/**
* 翻页记住选择
*/
@ -217,12 +259,21 @@ public class DemoTableController extends BaseController
}
/**
* 表格拖拽操作
* 表格拖拽操作
*/
@GetMapping("/reorder")
public String reorder()
@GetMapping("/reorderRows")
public String reorderRows()
{
return prefix + "/reorder";
return prefix + "/reorderRows";
}
/**
* 表格列拖拽操作
*/
@GetMapping("/reorderColumns")
public String reorderColumns()
{
return prefix + "/reorderColumns";
}
/**
@ -399,21 +450,26 @@ class UserTableModel
private int userId;
/** 用户编号 */
@Excel(name = "用户编号", cellType = ColumnType.NUMERIC)
private String userCode;
/** 用户姓名 */
@Excel(name = "用户姓名")
private String userName;
/** 用户性别 */
private String userSex;
/** 用户手机 */
@Excel(name = "用户手机")
private String userPhone;
/** 用户邮箱 */
@Excel(name = "用户邮箱")
private String userEmail;
/** 用户余额 */
@Excel(name = "用户余额", cellType = ColumnType.NUMERIC)
private double userBalance;
/** 用户状态0正常 1停用 */

View File

@ -21,6 +21,6 @@ public class DruidController extends BaseController
@GetMapping()
public String index()
{
return redirect(prefix + "/index");
return redirect(prefix + "/index.html");
}
}

View File

@ -61,6 +61,7 @@ public class SysOperlogController extends BaseController
return util.exportExcel(list, "操作日志");
}
@Log(title = "操作日志", businessType = BusinessType.DELETE)
@RequiresPermissions("monitor:operlog:remove")
@PostMapping("/remove")
@ResponseBody

View File

@ -129,19 +129,20 @@ public class SysConfigController extends BaseController
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(configService.deleteConfigByIds(ids));
configService.deleteConfigByIds(ids);
return success();
}
/**
* 清空缓存
* 刷新参数缓存
*/
@RequiresPermissions("system:config:remove")
@Log(title = "参数管理", businessType = BusinessType.CLEAN)
@GetMapping("/clearCache")
@GetMapping("/refreshCache")
@ResponseBody
public AjaxResult clearCache()
public AjaxResult refreshCache()
{
configService.clearCache();
configService.resetConfigCache();
return success();
}

View File

@ -59,6 +59,10 @@ public class SysDeptController extends BaseController
@GetMapping("/add/{parentId}")
public String add(@PathVariable("parentId") Long parentId, ModelMap mmap)
{
if (!ShiroUtils.getSysUser().isAdmin())
{
parentId = ShiroUtils.getSysUser().getDeptId();
}
mmap.put("dept", deptService.selectDeptById(parentId));
return prefix + "/add";
}

View File

@ -115,6 +115,7 @@ public class SysDictDataController extends BaseController
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(dictDataService.deleteDictDataByIds(ids));
dictDataService.deleteDictDataByIds(ids);
return success();
}
}

View File

@ -125,19 +125,20 @@ public class SysDictTypeController extends BaseController
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(dictTypeService.deleteDictTypeByIds(ids));
dictTypeService.deleteDictTypeByIds(ids);
return success();
}
/**
* 清空缓存
* 刷新字典缓存
*/
@RequiresPermissions("system:dict:remove")
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
@GetMapping("/clearCache")
@GetMapping("/refreshCache")
@ResponseBody
public AjaxResult clearCache()
public AjaxResult refreshCache()
{
dictTypeService.clearCache();
dictTypeService.resetDictCache();
return success();
}

View File

@ -13,12 +13,14 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.system.service.ISysUserService;
@ -135,6 +137,16 @@ public class SysProfileController extends BaseController
currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setSex(user.getSex());
if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(currentUser)))
{
return error("修改用户'" + currentUser.getLoginName() + "'失败,手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail())
&& UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(currentUser)))
{
return error("修改用户'" + currentUser.getLoginName() + "'失败,邮箱账号已存在");
}
if (userService.updateUserInfo(currentUser) > 0)
{
ShiroUtils.setSysUser(userService.selectUserById(currentUser.getUserId()));

View File

@ -43,7 +43,7 @@ spring:
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: admin
login-username: ruoyi
login-password: 123456
filter:
stat:

View File

@ -3,7 +3,7 @@ ruoyi:
# 名称
name: RuoYi
# 版本
version: 4.6.0
version: 4.6.1
# 版权年份
copyrightYear: 2021
# 实例演示开关
@ -108,8 +108,6 @@ shiro:
httpOnly: true
# 设置Cookie的过期时间天为单位
maxAge: 30
# 设置密钥务必保持唯一性生成方式直接拷贝到main运行即可KeyGenerator keygen = KeyGenerator.getInstance("AES"); SecretKey deskey = keygen.generateKey(); System.out.println(Base64.encodeToString(deskey.getEncoded()));
cipherKey: zSyK5Kp6PZAAjlT+eeNMlg==
session:
# Session超时时间-1代表永不过期默认30分钟
expireTime: 30

View File

@ -1,119 +0,0 @@
/**
* @author zhixin wen <wenzhixin2010@gmail.com>
* extensions: https://github.com/kayalshri/tableExport.jquery.plugin
*/
(function ($) {
'use strict';
var sprintf = $.fn.bootstrapTable.utils.sprintf;
var TYPE_NAME = {
csv: 'CSV',
txt: 'TXT',
doc: 'Word',
excel: 'Excel'
};
$.extend($.fn.bootstrapTable.defaults, {
showExport: false,
exportDataType: 'all', // basic, all, selected
exportTypes: ['csv', 'txt', 'doc', 'excel'],
exportOptions: {
ignoreColumn: [0] //忽略列索引
}
});
$.extend($.fn.bootstrapTable.defaults.icons, {
export: 'glyphicon glyphicon-save'
});
$.extend($.fn.bootstrapTable.locales, {
formatExport: function () {
return '导出';
}
});
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initToolbar = BootstrapTable.prototype.initToolbar;
BootstrapTable.prototype.initToolbar = function () {
this.showToolbar = this.options.showExport;
_initToolbar.apply(this, Array.prototype.slice.apply(arguments));
if (this.options.showExport) {
var that = this,
$btnGroup = this.$toolbar.find('>.btn-group'),
$export = $btnGroup.find('div.export');
if (!$export.length) {
$export = $([
'<div class="export btn-group">',
'<button class="btn' +
sprintf(' btn-%s', this.options.buttonsClass) +
sprintf(' btn-%s', this.options.iconSize) +
' dropdown-toggle" ' +
'title="' + this.options.formatExport() + '" ' +
'data-toggle="dropdown" type="button">',
sprintf('<i class="%s %s"></i> ', this.options.iconsPrefix, this.options.icons.export),
'<span class="caret"></span>',
'</button>',
'<ul class="dropdown-menu" role="menu">',
'</ul>',
'</div>'].join('')).appendTo($btnGroup);
var $menu = $export.find('.dropdown-menu'),
exportTypes = this.options.exportTypes;
if (typeof this.options.exportTypes === 'string') {
var types = this.options.exportTypes.slice(1, -1).replace(/ /g, '').split(',');
exportTypes = [];
$.each(types, function (i, value) {
exportTypes.push(value.slice(1, -1));
});
}
$.each(exportTypes, function (i, type) {
if (TYPE_NAME.hasOwnProperty(type)) {
$menu.append(['<li data-type="' + type + '">',
'<a href="javascript:void(0)">',
TYPE_NAME[type],
'</a>',
'</li>'].join(''));
}
});
$menu.find('li').click(function () {
var type = $(this).data('type'),
doExport = function () {
that.$el.tableExport($.extend({}, that.options.exportOptions, {
type: type,
escape: false
}));
};
if (that.options.exportDataType === 'all' && that.options.pagination) {
that.$el.one(that.options.sidePagination === 'server' ? 'post-body.bs.table' : 'page-change.bs.table', function () {
doExport();
that.togglePagination();
});
that.togglePagination();
} else if (that.options.exportDataType === 'selected') {
//修改sidePagination属性为server无法导出选中数据
var trs = that.$body.children();
for (var i = 0; i < trs.length; i++) {
var $this = $(trs[i]);
if(!$this.find(sprintf('[name="%s"]',that.options.selectItemName)).prop('checked')){
$this['hide']();
}}
doExport();
that.getRowsHidden(true);
} else {
doExport();
}
});
}
}
};
})(jQuery);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,92 @@
/*
tableExport.jquery.plugin
Version 1.10.24
Copyright (c) 2015-2021 hhurz, https://github.com/hhurz/tableExport.jquery.plugin
Based on https://github.com/kayalshri/tableExport.jquery.plugin
Licensed under the MIT License
*/
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(d,k,y){d instanceof String&&(d=String(d));for(var C=d.length,v=0;v<C;v++){var R=d[v];if(k.call(y,R,v,d))return{i:v,v:R}}return{i:-1,v:void 0}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(d,k,y){d!=Array.prototype&&d!=Object.prototype&&(d[k]=y.value)};
$jscomp.getGlobal=function(d){return"undefined"!=typeof window&&window===d?d:"undefined"!=typeof global&&null!=global?global:d};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(d,k,y,C){if(k){y=$jscomp.global;d=d.split(".");for(C=0;C<d.length-1;C++){var v=d[C];v in y||(y[v]={});y=y[v]}d=d[d.length-1];C=y[d];k=k(C);k!=C&&null!=k&&$jscomp.defineProperty(y,d,{configurable:!0,writable:!0,value:k})}};
$jscomp.polyfill("Array.prototype.find",function(d){return d?d:function(d,y){return $jscomp.findInternal(this,d,y).v}},"es6","es3");
(function(d){d.fn.tableExport=function(k){function y(b){var c=[];v(b,"thead").each(function(){c.push.apply(c,v(d(this),a.theadSelector).toArray())});return c}function C(b){var c=[];v(b,"tbody").each(function(){c.push.apply(c,v(d(this),a.tbodySelector).toArray())});a.tfootSelector.length&&v(b,"tfoot").each(function(){c.push.apply(c,v(d(this),a.tfootSelector).toArray())});return c}function v(b,a){var c=b[0].tagName,q=b.parents(c).length;return b.find(a).filter(function(){return q===d(this).closest(c).parents(c).length})}
function R(b){var a=[],e=0,q=0,f=0;d(b).find("thead").first().find("th").each(function(b,c){b=void 0!==d(c).attr("data-field");"undefined"!==typeof c.parentNode.rowIndex&&q!==c.parentNode.rowIndex&&(q=c.parentNode.rowIndex,e=f=0);var h=J(c);for(e+=h?h:1;f<e;)a[f]=b?d(c).attr("data-field"):f.toString(),f++});return a}function I(b){var a="undefined"!==typeof b[0].rowIndex,e=!1===a&&"undefined"!==typeof b[0].cellIndex,q=e||a?Ja(b):b.is(":visible"),f=b.attr("data-tableexport-display");e&&"none"!==f&&
"always"!==f&&(b=d(b[0].parentNode),a="undefined"!==typeof b[0].rowIndex,f=b.attr("data-tableexport-display"));a&&"none"!==f&&"always"!==f&&(f=b.closest("table").attr("data-tableexport-display"));return"none"!==f&&(!0===q||"always"===f)}function Ja(b){var a=[];V&&(a=K.filter(function(){var a=!1;this.nodeType===b[0].nodeType&&("undefined"!==typeof this.rowIndex&&this.rowIndex===b[0].rowIndex?a=!0:"undefined"!==typeof this.cellIndex&&this.cellIndex===b[0].cellIndex&&"undefined"!==typeof this.parentNode.rowIndex&&
"undefined"!==typeof b[0].parentNode.rowIndex&&this.parentNode.rowIndex===b[0].parentNode.rowIndex&&(a=!0));return a}));return!1===V||0===a.length}function ta(b,c,e){var q=!1;I(b)?0<a.ignoreColumn.length&&(-1!==d.inArray(e,a.ignoreColumn)||-1!==d.inArray(e-c,a.ignoreColumn)||S.length>e&&"undefined"!==typeof S[e]&&-1!==d.inArray(S[e],a.ignoreColumn))&&(q=!0):q=!0;return q}function E(b,c,e,q,f){if("function"===typeof f){var h=!1;"function"===typeof a.onIgnoreRow&&(h=a.onIgnoreRow(d(b),e));if(!1===h&&
(0===a.ignoreRow.length||-1===d.inArray(e,a.ignoreRow)&&-1===d.inArray(e-q,a.ignoreRow))&&I(d(b))){b=v(d(b),c);var n=b.length,l=0,u=0;b.each(function(){var b=d(this),a=J(this),c=T(this),h;d.each(G,function(){if(e>this.s.r&&e<=this.e.r&&l>=this.s.c&&l<=this.e.c)for(h=0;h<=this.e.c-this.s.c;++h)n++,u++,f(null,e,l++)});if(c||a)a=a||1,G.push({s:{r:e,c:l},e:{r:e+(c||1)-1,c:l+a-1}});!1===ta(b,n,u++)&&f(this,e,l++);if(1<a)for(h=0;h<a-1;++h)u++,f(null,e,l++)});d.each(G,function(){if(e>=this.s.r&&e<=this.e.r&&
l>=this.s.c&&l<=this.e.c)for(ea=0;ea<=this.e.c-this.s.c;++ea)f(null,e,l++)})}}}function ua(b,a,e,d){if("undefined"!==typeof d.images&&(e=d.images[e],"undefined"!==typeof e)){a=a.getBoundingClientRect();var c=b.width/b.height,h=a.width/a.height,q=b.width,l=b.height,u=19.049976/25.4,g=0;h<=c?(l=Math.min(b.height,a.height),q=a.width*l/a.height):h>c&&(q=Math.min(b.width,a.width),l=a.height*q/a.width);q*=u;l*=u;l<b.height&&(g=(b.height-l)/2);try{d.doc.addImage(e.src,b.textPos.x,b.y+g,q,l)}catch(Pa){}b.textPos.x+=
q}}function va(b,c){if("string"===a.outputMode)return b.output();if("base64"===a.outputMode)return L(b.output());if("window"===a.outputMode)window.URL=window.URL||window.webkitURL,window.open(window.URL.createObjectURL(b.output("blob")));else try{var e=b.output("blob");saveAs(e,a.fileName+".pdf")}catch(q){ka(a.fileName+".pdf","data:application/pdf"+(c?"":";base64")+",",c?b.output("blob"):b.output())}}function wa(b,a,e){var c=0;"undefined"!==typeof e&&(c=e.colspan);if(0<=c){for(var f=b.width,d=b.textPos.x,
n=a.table.columns.indexOf(a.column),l=1;l<c;l++)f+=a.table.columns[n+l].width;1<c&&("right"===b.styles.halign?d=b.textPos.x+f-b.width:"center"===b.styles.halign&&(d=b.textPos.x+(f-b.width)/2));b.width=f;b.textPos.x=d;"undefined"!==typeof e&&1<e.rowspan&&(b.height*=e.rowspan);if("middle"===b.styles.valign||"bottom"===b.styles.valign)e=("string"===typeof b.text?b.text.split(/\r\n|\r|\n/g):b.text).length||1,2<e&&(b.textPos.y-=(2-1.15)/2*a.row.styles.fontSize*(e-2)/3);return!0}return!1}function xa(b,
a,e){"undefined"!==typeof b&&null!==b&&(b.hasAttribute("data-tableexport-canvas")?(a=(new Date).getTime(),d(b).attr("data-tableexport-canvas",a),e.images[a]={url:'[data-tableexport-canvas="'+a+'"]',src:null}):"undefined"!==a&&null!=a&&a.each(function(){if(d(this).is("img")){var a=ya(this.src);e.images[a]={url:this.src,src:this.src}}xa(b,d(this).children(),e)}))}function Ka(b,a){function c(b){if(b.url)if(b.src){var c=new Image;q=++f;c.crossOrigin="Anonymous";c.onerror=c.onload=function(){if(c.complete&&
(0===c.src.indexOf("data:image/")&&(c.width=b.width||c.width||0,c.height=b.height||c.height||0),c.width+c.height)){var e=document.createElement("canvas"),d=e.getContext("2d");e.width=c.width;e.height=c.height;d.drawImage(c,0,0);b.src=e.toDataURL("image/png")}--f||a(q)};c.src=b.url}else{var e=d(b.url);e.length&&(q=++f,html2canvas(e[0]).then(function(c){b.src=c.toDataURL("image/png");--f||a(q)}))}}var q=0,f=0;if("undefined"!==typeof b.images)for(var h in b.images)b.images.hasOwnProperty(h)&&c(b.images[h]);
(b=f)||(a(q),b=void 0);return b}function za(b,c,e){c.each(function(){if(d(this).is("div")){var c=fa(M(this,"background-color"),[255,255,255]),f=fa(M(this,"border-top-color"),[0,0,0]),h=ha(this,"border-top-width",a.jspdf.unit),n=this.getBoundingClientRect(),l=this.offsetLeft*e.wScaleFactor,u=this.offsetTop*e.hScaleFactor,g=n.width*e.wScaleFactor;n=n.height*e.hScaleFactor;e.doc.setDrawColor.apply(void 0,f);e.doc.setFillColor.apply(void 0,c);e.doc.setLineWidth(h);e.doc.rect(b.x+l,b.y+u,g,n,h?"FD":"F")}else d(this).is("img")&&
(c=ya(this.src),ua(b,this,c,e));za(b,d(this).children(),e)})}function Aa(b,c,e){if("function"===typeof e.onAutotableText)e.onAutotableText(e.doc,b,c);else{var q=b.textPos.x,f=b.textPos.y,h={halign:b.styles.halign,valign:b.styles.valign};if(c.length){for(c=c[0];c.previousSibling;)c=c.previousSibling;for(var n=!1,l=!1;c;){var u=c.innerText||c.textContent||"",g=u.length&&" "===u[0]?" ":"",k=1<u.length&&" "===u[u.length-1]?" ":"";!0!==a.preserve.leadingWS&&(u=g+la(u));!0!==a.preserve.trailingWS&&(u=ma(u)+
k);d(c).is("br")&&(q=b.textPos.x,f+=e.doc.internal.getFontSize());d(c).is("b")?n=!0:d(c).is("i")&&(l=!0);(n||l)&&e.doc.setFontType(n&&l?"bolditalic":n?"bold":"italic");if(g=e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize()){"linebreak"===b.styles.overflow&&q>b.textPos.x&&q+g>b.textPos.x+b.width&&(0<=".,!%*;:=-".indexOf(u.charAt(0))&&(k=u.charAt(0),g=e.doc.getStringUnitWidth(k)*e.doc.internal.getFontSize(),q+g<=b.textPos.x+b.width&&(e.doc.autoTableText(k,q,f,h),u=u.substring(1,u.length)),g=
e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize()),q=b.textPos.x,f+=e.doc.internal.getFontSize());if("visible"!==b.styles.overflow)for(;u.length&&q+g>b.textPos.x+b.width;)u=u.substring(0,u.length-1),g=e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize();e.doc.autoTableText(u,q,f,h);q+=g}if(n||l)d(c).is("b")?n=!1:d(c).is("i")&&(l=!1),e.doc.setFontType(n||l?n?"bold":"italic":"normal");c=c.nextSibling}b.textPos.x=q;b.textPos.y=f}else e.doc.autoTableText(b.text,b.textPos.x,b.textPos.y,h)}}
function W(b,a,e){return null==b?"":b.toString().replace(new RegExp(null==a?"":a.toString().replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1"),"g"),e)}function la(b){return null==b?"":b.toString().replace(/^\s+/,"")}function ma(b){return null==b?"":b.toString().replace(/\s+$/,"")}function La(b){if(0===a.date.html.length)return!1;a.date.pattern.lastIndex=0;var c=a.date.pattern.exec(b);if(null==c)return!1;b=+c[a.date.match_y];if(0>b||8099<b)return!1;var e=1*c[a.date.match_m];c=1*c[a.date.match_d];if(!isFinite(c))return!1;
var d=new Date(b,e-1,c,0,0,0);return d.getFullYear()===b&&d.getMonth()===e-1&&d.getDate()===c?new Date(Date.UTC(b,e-1,c,0,0,0)):!1}function na(b){b=b||"0";""!==a.numbers.html.thousandsSeparator&&(b=W(b,a.numbers.html.thousandsSeparator,""));"."!==a.numbers.html.decimalMark&&(b=W(b,a.numbers.html.decimalMark,"."));return"number"===typeof b||!1!==jQuery.isNumeric(b)?b:!1}function Ma(b){-1<b.indexOf("%")?(b=na(b.replace(/%/g,"")),!1!==b&&(b/=100)):b=!1;return b}function D(b,c,e,q){var f="",h="text";
if(null!==b){var n=d(b);n.removeData("teUserDefText");if(n[0].hasAttribute("data-tableexport-canvas"))var l="";else if(n[0].hasAttribute("data-tableexport-value"))l=(l=n.attr("data-tableexport-value"))?l+"":"",n.data("teUserDefText",1);else if(l=n.html(),"function"===typeof a.onCellHtmlData)l=a.onCellHtmlData(n,c,e,l),n.data("teUserDefText",1);else if(""!==l){b=d.parseHTML(l);var g=0,k=0;l="";d.each(b,function(){if(d(this).is("input"))l+=n.find("input").eq(g++).val();else if(d(this).is("select"))l+=
n.find("select option:selected").eq(k++).text();else if(d(this).is("br"))l+="<br>";else{if("undefined"===typeof d(this).html())l+=d(this).text();else if(void 0===jQuery().bootstrapTable||!1===d(this).hasClass("fht-cell")&&!1===d(this).hasClass("filterControl")&&0===n.parents(".detail-view").length)l+=d(this).html();if(d(this).is("a")){var b=n.find("a").attr("href")||"";f="function"===typeof a.onCellHtmlHyperlink?f+a.onCellHtmlHyperlink(n,c,e,b,l):"href"===a.htmlHyperlink?f+b:f+l;l=""}}})}if(l&&""!==
l&&!0===a.htmlContent)f=d.trim(l);else if(l&&""!==l)if(""!==n.attr("data-tableexport-cellformat")){var m=l.replace(/\n/g,"\u2028").replace(/(<\s*br([^>]*)>)/gi,"\u2060"),p=d("<div/>").html(m).contents();b=!1;m="";d.each(p.text().split("\u2028"),function(b,c){0<b&&(m+=" ");!0!==a.preserve.leadingWS&&(c=la(c));m+=!0!==a.preserve.trailingWS?ma(c):c});d.each(m.split("\u2060"),function(b,c){0<b&&(f+="\n");!0!==a.preserve.leadingWS&&(c=la(c));!0!==a.preserve.trailingWS&&(c=ma(c));f+=c.replace(/\u00AD/g,
"")});f=f.replace(/\u00A0/g," ");if("json"===a.type||"excel"===a.type&&"xmlss"===a.mso.fileFormat||!1===a.numbers.output)b=na(f),!1!==b&&(h="number",f=Number(b));else if(a.numbers.html.decimalMark!==a.numbers.output.decimalMark||a.numbers.html.thousandsSeparator!==a.numbers.output.thousandsSeparator)if(b=na(f),!1!==b){p=(""+b.substr(0>b?1:0)).split(".");1===p.length&&(p[1]="");var t=3<p[0].length?p[0].length%3:0;h="number";f=(0>b?"-":"")+(a.numbers.output.thousandsSeparator?(t?p[0].substr(0,t)+a.numbers.output.thousandsSeparator:
"")+p[0].substr(t).replace(/(\d{3})(?=\d)/g,"$1"+a.numbers.output.thousandsSeparator):p[0])+(p[1].length?a.numbers.output.decimalMark+p[1]:"")}}else f=l;!0===a.escape&&(f=escape(f));"function"===typeof a.onCellData&&(f=a.onCellData(n,c,e,f,h),n.data("teUserDefText",1))}void 0!==q&&(q.type=h);return f}function Ba(b){return 0<b.length&&!0===a.preventInjection&&0<="=+-@".indexOf(b.charAt(0))?"'"+b:b}function Na(b,a,e){return a+"-"+e.toLowerCase()}function fa(b,a){(b=/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(b))&&
(a=[parseInt(b[1]),parseInt(b[2]),parseInt(b[3])]);return a}function Ca(b){var a=M(b,"text-align"),e=M(b,"font-weight"),d=M(b,"font-style"),f="";"start"===a&&(a="rtl"===M(b,"direction")?"right":"left");700<=e&&(f="bold");"italic"===d&&(f+=d);""===f&&(f="normal");a={style:{align:a,bcolor:fa(M(b,"background-color"),[255,255,255]),color:fa(M(b,"color"),[0,0,0]),fstyle:f},colspan:J(b),rowspan:T(b)};null!==b&&(b=b.getBoundingClientRect(),a.rect={width:b.width,height:b.height});return a}function J(b){var a=
d(b).attr("data-tableexport-colspan");"undefined"===typeof a&&d(b).is("[colspan]")&&(a=d(b).attr("colspan"));return parseInt(a)||0}function T(b){var a=d(b).attr("data-tableexport-rowspan");"undefined"===typeof a&&d(b).is("[rowspan]")&&(a=d(b).attr("rowspan"));return parseInt(a)||0}function M(a,c){try{return window.getComputedStyle?(c=c.replace(/([a-z])([A-Z])/,Na),window.getComputedStyle(a,null).getPropertyValue(c)):a.currentStyle?a.currentStyle[c]:a.style[c]}catch(e){}return""}function ha(a,c,e){c=
M(a,c).match(/\d+/);if(null!==c){c=c[0];a=a.parentElement;var b=document.createElement("div");b.style.overflow="hidden";b.style.visibility="hidden";a.appendChild(b);b.style.width=100+e;e=100/b.offsetWidth;a.removeChild(b);return c*e}return 0}function Oa(a){for(var b=new ArrayBuffer(a.length),e=new Uint8Array(b),d=0;d!==a.length;++d)e[d]=a.charCodeAt(d)&255;return b}function oa(a){var b=a.c,e="";for(++b;b;b=Math.floor((b-1)/26))e=String.fromCharCode((b-1)%26+65)+e;return e+(""+(a.r+1))}function pa(a,
c){if("undefined"===typeof c||"number"===typeof c)return pa(a.s,a.e);"string"!==typeof a&&(a=oa(a));"string"!==typeof c&&(c=oa(c));return a===c?a:a+":"+c}function Da(a,c){var b=Number(a);if(isFinite(b))return b;var d=1;""!==c.thousandsSeparator&&(a=a.replace(new RegExp("([\\d])"+c.thousandsSeparator+"([\\d])","g"),"$1$2"));"."!==c.decimalMark&&(a=a.replace(new RegExp("([\\d])"+c.decimalMark+"([\\d])","g"),"$1.$2"));a=a.replace(/[$]/g,"").replace(/[%]/g,function(){d*=100;return""});if(isFinite(b=Number(a)))return b/
d;a=a.replace(/[(](.*)[)]/,function(a,b){d=-d;return b});return isFinite(b=Number(a))?b/d:b}function ya(a){var b=0,d;if(0===a.length)return b;var q=0;for(d=a.length;q<d;q++){var f=a.charCodeAt(q);b=(b<<5)-b+f;b|=0}return b}function N(b,c,d,q,f,h){var e=!0;"function"===typeof a.onBeforeSaveToFile&&(e=a.onBeforeSaveToFile(b,c,d,q,f),"boolean"!==typeof e&&(e=!0));if(e)try{if(Ea=new Blob([b],{type:d+";charset="+q}),saveAs(Ea,c,!1===h),"function"===typeof a.onAfterSaveToFile)a.onAfterSaveToFile(b,c)}catch(l){ka(c,
"data:"+d+(q.length?";charset="+q:"")+(f.length?";"+f:"")+",",h?"\ufeff"+b:b)}}function ka(b,c,d){var e=window.navigator.userAgent;if(!1!==b&&window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(new Blob([d]),b);else if(!1!==b&&(0<e.indexOf("MSIE ")||e.match(/Trident.*rv\:11\./))){if(c=document.createElement("iframe")){document.body.appendChild(c);c.setAttribute("style","display:none");c.contentDocument.open("txt/plain","replace");c.contentDocument.write(d);c.contentDocument.close();
c.contentWindow.focus();switch(b.substr(b.lastIndexOf(".")+1)){case "doc":case "json":case "png":case "pdf":case "xls":case "xlsx":b+=".txt"}c.contentDocument.execCommand("SaveAs",!0,b);document.body.removeChild(c)}}else{var f=document.createElement("a");if(f){var h=null;f.style.display="none";!1!==b?f.download=b:f.target="_blank";"object"===typeof d?(window.URL=window.URL||window.webkitURL,e=[],e.push(d),h=window.URL.createObjectURL(new Blob(e,{type:c})),f.href=h):0<=c.toLowerCase().indexOf("base64,")?
f.href=c+L(d):f.href=c+encodeURIComponent(d);document.body.appendChild(f);if(document.createEvent)null===ia&&(ia=document.createEvent("MouseEvents")),ia.initEvent("click",!0,!1),f.dispatchEvent(ia);else if(document.createEventObject)f.fireEvent("onclick");else if("function"===typeof f.onclick)f.onclick();setTimeout(function(){h&&window.URL.revokeObjectURL(h);document.body.removeChild(f);if("function"===typeof a.onAfterSaveToFile)a.onAfterSaveToFile(d,b)},100)}}}function L(a){var b,d="",q=0;if("string"===
typeof a){a=a.replace(/\x0d\x0a/g,"\n");var f="";for(b=0;b<a.length;b++){var h=a.charCodeAt(b);128>h?f+=String.fromCharCode(h):(127<h&&2048>h?f+=String.fromCharCode(h>>6|192):(f+=String.fromCharCode(h>>12|224),f+=String.fromCharCode(h>>6&63|128)),f+=String.fromCharCode(h&63|128))}a=f}for(;q<a.length;){var n=a.charCodeAt(q++);f=a.charCodeAt(q++);b=a.charCodeAt(q++);h=n>>2;n=(n&3)<<4|f>>4;var l=(f&15)<<2|b>>6;var g=b&63;isNaN(f)?l=g=64:isNaN(b)&&(g=64);d=d+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(h)+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(n)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(l)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(g)}return d}var a={csvEnclosure:'"',csvSeparator:",",csvUseBOM:!0,date:{html:"dd/mm/yyyy"},displayTableName:!1,escape:!1,exportHiddenCells:!1,fileName:"tableExport",htmlContent:!1,htmlHyperlink:"content",ignoreColumn:[],ignoreRow:[],jsonScope:"all",jspdf:{orientation:"p",
unit:"pt",format:"a4",margins:{left:20,right:10,top:10,bottom:10},onDocCreated:null,autotable:{styles:{cellPadding:2,rowHeight:12,fontSize:8,fillColor:255,textColor:50,fontStyle:"normal",overflow:"ellipsize",halign:"inherit",valign:"middle"},headerStyles:{fillColor:[52,73,94],textColor:255,fontStyle:"bold",halign:"inherit",valign:"middle"},alternateRowStyles:{fillColor:245},tableExport:{doc:null,onAfterAutotable:null,onBeforeAutotable:null,onAutotableText:null,onTable:null,outputImages:!0}}},mso:{fileFormat:"xlshtml",
onMsoNumberFormat:null,pageFormat:"a4",pageOrientation:"portrait",rtl:!1,styles:[],worksheetName:"",xslx:{formatId:{date:14,numbers:2}}},numbers:{html:{decimalMark:".",thousandsSeparator:","},output:{decimalMark:".",thousandsSeparator:","}},onAfterSaveToFile:null,onBeforeSaveToFile:null,onCellData:null,onCellHtmlData:null,onCellHtmlHyperlink:null,onIgnoreRow:null,onTableExportBegin:null,onTableExportEnd:null,outputMode:"file",pdfmake:{enabled:!1,docDefinition:{pageSize:"A4",pageOrientation:"portrait",
styles:{header:{background:"#34495E",color:"#FFFFFF",bold:!0,alignment:"center",fillColor:"#34495E"},alternateRow:{fillColor:"#f5f5f5"}},defaultStyle:{color:"#000000",fontSize:8,font:"Roboto"}},fonts:{}},preserve:{leadingWS:!1,trailingWS:!1},preventInjection:!0,sql:{tableEnclosure:"`",columnEnclosure:"`"},tbodySelector:"tr",tfootSelector:"tr",theadSelector:"tr",tableName:"Table",type:"csv"},O={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,
595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,
161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]},B=this,ia=null,r=[],w=[],p=0,t="",S=[],G=[],Ea,K=[],V=!1;d.extend(!0,a,k);"xlsx"===a.type&&(a.mso.fileFormat=a.type,a.type="excel");"undefined"!==typeof a.excelFileFormat&&"undefined"===a.mso.fileFormat&&(a.mso.fileFormat=a.excelFileFormat);"undefined"!==typeof a.excelPageFormat&&"undefined"===a.mso.pageFormat&&
(a.mso.pageFormat=a.excelPageFormat);"undefined"!==typeof a.excelPageOrientation&&"undefined"===a.mso.pageOrientation&&(a.mso.pageOrientation=a.excelPageOrientation);"undefined"!==typeof a.excelRTL&&"undefined"===a.mso.rtl&&(a.mso.rtl=a.excelRTL);"undefined"!==typeof a.excelstyles&&"undefined"===a.mso.styles&&(a.mso.styles=a.excelstyles);"undefined"!==typeof a.onMsoNumberFormat&&"undefined"===a.mso.onMsoNumberFormat&&(a.mso.onMsoNumberFormat=a.onMsoNumberFormat);"undefined"!==typeof a.worksheetName&&
"undefined"===a.mso.worksheetName&&(a.mso.worksheetName=a.worksheetName);a.mso.pageOrientation="l"===a.mso.pageOrientation.substr(0,1)?"landscape":"portrait";a.date.html=a.date.html||"";if(a.date.html.length){k=[];k.dd="(3[01]|[12][0-9]|0?[1-9])";k.mm="(1[012]|0?[1-9])";k.yyyy="((?:1[6-9]|2[0-2])\\d{2})";k.yy="(\\d{2})";var z=a.date.html.match(/[^a-zA-Z0-9]/)[0];z=a.date.html.toLowerCase().split(z);a.date.regex="^\\s*";a.date.regex+=k[z[0]];a.date.regex+="(.)";a.date.regex+=k[z[1]];a.date.regex+=
"\\2";a.date.regex+=k[z[2]];a.date.regex+="\\s*$";a.date.pattern=new RegExp(a.date.regex,"g");k=z.indexOf("dd")+1;a.date.match_d=k+(1<k?1:0);k=z.indexOf("mm")+1;a.date.match_m=k+(1<k?1:0);k=(0<=z.indexOf("yyyy")?z.indexOf("yyyy"):z.indexOf("yy"))+1;a.date.match_y=k+(1<k?1:0)}S=R(B);if("function"===typeof a.onTableExportBegin)a.onTableExportBegin();if("csv"===a.type||"tsv"===a.type||"txt"===a.type){var P="",Z=0;G=[];p=0;var qa=function(b,c,e){b.each(function(){t="";E(this,c,p,e+b.length,function(b,
c,d){var e=t,f="";if(null!==b)if(b=D(b,c,d),c=null===b||""===b?"":b.toString(),"tsv"===a.type)b instanceof Date&&b.toLocaleString(),f=W(c,"\t"," ");else if(b instanceof Date)f=a.csvEnclosure+b.toLocaleString()+a.csvEnclosure;else if(f=Ba(c),f=W(f,a.csvEnclosure,a.csvEnclosure+a.csvEnclosure),0<=f.indexOf(a.csvSeparator)||/[\r\n ]/g.test(f))f=a.csvEnclosure+f+a.csvEnclosure;t=e+(f+("tsv"===a.type?"\t":a.csvSeparator))});t=d.trim(t).substring(0,t.length-1);0<t.length&&(0<P.length&&(P+="\n"),P+=t);p++});
return b.length};Z+=qa(d(B).find("thead").first().find(a.theadSelector),"th,td",Z);v(d(B),"tbody").each(function(){Z+=qa(v(d(this),a.tbodySelector),"td,th",Z)});a.tfootSelector.length&&qa(d(B).find("tfoot").first().find(a.tfootSelector),"td,th",Z);P+="\n";if("string"===a.outputMode)return P;if("base64"===a.outputMode)return L(P);if("window"===a.outputMode){ka(!1,"data:text/"+("csv"===a.type?"csv":"plain")+";charset=utf-8,",P);return}N(P,a.fileName+"."+a.type,"text/"+("csv"===a.type?"csv":"plain"),
"utf-8","","csv"===a.type&&a.csvUseBOM)}else if("sql"===a.type){p=0;G=[];var A="INSERT INTO "+a.sql.tableEnclosure+a.tableName+a.sql.tableEnclosure+" (";r=y(d(B));d(r).each(function(){E(this,"th,td",p,r.length,function(b,c,d){b=D(b,c,d)||"";-1<b.indexOf(a.sql.columnEnclosure)&&(b=W(b.toString(),a.sql.columnEnclosure,a.sql.columnEnclosure+a.sql.columnEnclosure));A+=a.sql.columnEnclosure+b+a.sql.columnEnclosure+","});p++;A=d.trim(A).substring(0,A.length-1)});A+=") VALUES ";w=C(d(B));d(w).each(function(){t=
"";E(this,"td,th",p,r.length+w.length,function(a,c,d){a=D(a,c,d)||"";-1<a.indexOf("'")&&(a=W(a.toString(),"'","''"));t+="'"+a+"',"});3<t.length&&(A+="("+t,A=d.trim(A).substring(0,A.length-1),A+="),");p++});A=d.trim(A).substring(0,A.length-1);A+=";";if("string"===a.outputMode)return A;if("base64"===a.outputMode)return L(A);N(A,a.fileName+".sql","application/sql","utf-8","",!1)}else if("json"===a.type){var X=[];G=[];r=y(d(B));d(r).each(function(){var a=[];E(this,"th,td",p,r.length,function(b,d,g){a.push(D(b,
d,g))});X.push(a)});var ra=[];w=C(d(B));d(w).each(function(){var a={},c=0;E(this,"td,th",p,r.length+w.length,function(b,d,f){X.length?a[X[X.length-1][c]]=D(b,d,f):a[c]=D(b,d,f);c++});!1===d.isEmptyObject(a)&&ra.push(a);p++});k="head"===a.jsonScope?JSON.stringify(X):"data"===a.jsonScope?JSON.stringify(ra):JSON.stringify({header:X,data:ra});if("string"===a.outputMode)return k;if("base64"===a.outputMode)return L(k);N(k,a.fileName+".json","application/json","utf-8","base64",!1)}else if("xml"===a.type){p=
0;G=[];var Q='<?xml version="1.0" encoding="utf-8"?>';Q+="<tabledata><fields>";r=y(d(B));d(r).each(function(){E(this,"th,td",p,r.length,function(a,d,e){Q+="<field>"+D(a,d,e)+"</field>"});p++});Q+="</fields><data>";var Fa=1;w=C(d(B));d(w).each(function(){var a=1;t="";E(this,"td,th",p,r.length+w.length,function(b,d,g){t+="<column-"+a+">"+D(b,d,g)+"</column-"+a+">";a++});0<t.length&&"<column-1></column-1>"!==t&&(Q+='<row id="'+Fa+'">'+t+"</row>",Fa++);p++});Q+="</data></tabledata>";if("string"===a.outputMode)return Q;
if("base64"===a.outputMode)return L(Q);N(Q,a.fileName+".xml","application/xml","utf-8","base64",!1)}else if("excel"===a.type&&"xmlss"===a.mso.fileFormat){var sa=[],F=[];d(B).filter(function(){return I(d(this))}).each(function(){function b(a,b,c){var f=[];d(a).each(function(){var b=0,e=0;t="";E(this,"td,th",p,c+a.length,function(a,c,h){if(null!==a){var l="";c=D(a,c,h);h="String";if(!1!==jQuery.isNumeric(c))h="Number";else{var n=Ma(c);!1!==n&&(c=n,h="Number",l+=' ss:StyleID="pct1"')}"Number"!==h&&(c=
c.replace(/\n/g,"<br>"));n=J(a);a=T(a);d.each(f,function(){if(p>=this.s.r&&p<=this.e.r&&e>=this.s.c&&e<=this.e.c)for(var a=0;a<=this.e.c-this.s.c;++a)e++,b++});if(a||n)a=a||1,n=n||1,f.push({s:{r:p,c:e},e:{r:p+a-1,c:e+n-1}});1<n&&(l+=' ss:MergeAcross="'+(n-1)+'"',e+=n-1);1<a&&(l+=' ss:MergeDown="'+(a-1)+'" ss:StyleID="rsp1"');0<b&&(l+=' ss:Index="'+(e+1)+'"',b=0);t+="<Cell"+l+'><Data ss:Type="'+h+'">'+d("<div />").text(c).html()+"</Data></Cell>\r";e++}});0<t.length&&(H+='<Row ss:AutoFitHeight="0">\r'+
t+"</Row>\r");p++});return a.length}var c=d(this),e="";"string"===typeof a.mso.worksheetName&&a.mso.worksheetName.length?e=a.mso.worksheetName+" "+(F.length+1):"undefined"!==typeof a.mso.worksheetName[F.length]&&(e=a.mso.worksheetName[F.length]);e.length||(e=c.find("caption").text()||"");e.length||(e="Table "+(F.length+1));e=d.trim(e.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31));F.push(d("<div />").text(e).html());!1===a.exportHiddenCells&&(K=c.find("tr, th, td").filter(":hidden"),V=0<K.length);
p=0;S=R(this);H="<Table>\r";e=b(y(c),"th,td",0);b(C(c),"td,th",e);H+="</Table>\r";sa.push(H)});k={};z={};for(var m,aa,Y=0,ea=F.length;Y<ea;Y++)m=F[Y],aa=k[m],aa=k[m]=null==aa?1:aa+1,2===aa&&(F[z[m]]=F[z[m]].substring(0,29)+"-1"),1<k[m]?F[Y]=F[Y].substring(0,29)+"-"+k[m]:z[m]=Y;k='<?xml version="1.0" encoding="UTF-8"?>\r<?mso-application progid="Excel.Sheet"?>\r<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"\r xmlns:o="urn:schemas-microsoft-com:office:office"\r xmlns:x="urn:schemas-microsoft-com:office:excel"\r xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"\r xmlns:html="http://www.w3.org/TR/REC-html40">\r<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">\r <Created>'+
(new Date).toISOString()+'</Created>\r</DocumentProperties>\r<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">\r <AllowPNG/>\r</OfficeDocumentSettings>\r<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">\r <WindowHeight>9000</WindowHeight>\r <WindowWidth>13860</WindowWidth>\r <WindowTopX>0</WindowTopX>\r <WindowTopY>0</WindowTopY>\r <ProtectStructure>False</ProtectStructure>\r <ProtectWindows>False</ProtectWindows>\r</ExcelWorkbook>\r<Styles>\r <Style ss:ID="Default" ss:Name="Normal">\r <Alignment ss:Vertical="Bottom"/>\r <Borders/>\r <Font/>\r <Interior/>\r <NumberFormat/>\r <Protection/>\r </Style>\r <Style ss:ID="rsp1">\r <Alignment ss:Vertical="Center"/>\r </Style>\r <Style ss:ID="pct1">\r <NumberFormat ss:Format="Percent"/>\r </Style>\r</Styles>\r';
for(z=0;z<sa.length;z++)k+='<Worksheet ss:Name="'+F[z]+'" ss:RightToLeft="'+(a.mso.rtl?"1":"0")+'">\r'+sa[z],k=a.mso.rtl?k+'<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">\r<DisplayRightToLeft/>\r</WorksheetOptions>\r':k+'<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"/>\r',k+="</Worksheet>\r";k+="</Workbook>\r";if("string"===a.outputMode)return k;if("base64"===a.outputMode)return L(k);N(k,a.fileName+".xml","application/xml","utf-8","base64",!1)}else if("excel"===
a.type&&"xlsx"===a.mso.fileFormat){var ba=[],Ga=XLSX.utils.book_new();d(B).filter(function(){return I(d(this))}).each(function(){for(var b=d(this),c={},e=this.getElementsByTagName("tr"),g={s:{r:0,c:0},e:{r:0,c:0}},f=[],h,n=[],l=0,u=0,k,m,p,t,r,w=XLSX.SSF.get_table();l<e.length&&1E7>u;++l)if(k=e[l],m=!1,"function"===typeof a.onIgnoreRow&&(m=a.onIgnoreRow(d(k),l)),!0!==m&&(0===a.ignoreRow.length||-1===d.inArray(l,a.ignoreRow)&&-1===d.inArray(l-e.length,a.ignoreRow))&&!1!==I(d(k))){var y=k.children,
B=0;for(k=0;k<y.length;++k)r=y[k],t=+J(r)||1,B+=t;var z=0;for(k=m=0;k<y.length;++k)if(r=y[k],t=+J(r)||1,h=k+z,!ta(d(r),B,h+(h<m?m-h:0))){z+=t-1;for(h=0;h<f.length;++h){var v=f[h];v.s.c==m&&v.s.r<=u&&u<=v.e.r&&(m=v.e.c+1,h=-1)}(0<(p=+T(r))||1<t)&&f.push({s:{r:u,c:m},e:{r:u+(p||1)-1,c:m+t-1}});var C={type:""};h=D(r,l,k+z,C);v={t:"s",v:h};var A="";if(""!==(d(r).attr("data-tableexport-cellformat")||"")){var x=parseInt(d(r).attr("data-tableexport-xlsxformatid")||0);0===x&&"function"===typeof a.mso.xslx.formatId.numbers&&
(x=a.mso.xslx.formatId.numbers(d(r),l,k+z));0===x&&"function"===typeof a.mso.xslx.formatId.date&&(x=a.mso.xslx.formatId.date(d(r),l,k+z));if(49===x||"@"===x)A="s";else if("number"===C.type||0<x&&14>x||36<x&&41>x||48===x)A="n";else if("date"===C.type||13<x&&37>x||44<x&&48>x||56===x)A="d"}else A="s";if(null!=h)if(0===h.length)v.t="z";else if(0!==h.trim().length)if("s"===A)d(r).find("a").length&&(h="href"!==a.htmlHyperlink?h:"",v={f:'=HYPERLINK("'+d(r).find("a").attr("href")+(h.length?'","'+h:"")+'")'});
else if("function"===C.type)v={f:h};else if("TRUE"===h)v={t:"b",v:!0};else if("FALSE"===h)v={t:"b",v:!1};else if("n"===A||isFinite(Da(h,a.numbers.output))){if(r=Da(h,a.numbers.output),0===x&&"function"!==typeof a.mso.xslx.formatId.numbers&&(x=a.mso.xslx.formatId.numbers),isFinite(r)||isFinite(h))v={t:"n",v:isFinite(r)?r:h,z:"string"===typeof x?x:x in w?w[x]:"0.00"}}else if(!1!==(r=La(h))||"d"===A)0===x&&"function"!==typeof a.mso.xslx.formatId.date&&(x=a.mso.xslx.formatId.date),v={t:"d",v:!1!==r?r:
h,z:"string"===typeof x?x:x in w?w[x]:"m/d/yy"};c[oa({c:m,r:u})]=v;g.e.c<m&&(g.e.c=m);m+=t}++u}f.length&&(c["!merges"]=f);n.length&&(c["!rows"]=n);g.e.r=u-1;c["!ref"]=pa(g);1E7<=u&&(c["!fullref"]=pa((g.e.r=e.length-l+u-1,g)));e="";"string"===typeof a.mso.worksheetName&&a.mso.worksheetName.length?e=a.mso.worksheetName+" "+(ba.length+1):"undefined"!==typeof a.mso.worksheetName[ba.length]&&(e=a.mso.worksheetName[ba.length]);e.length||(e=b.find("caption").text()||"");e.length||(e="Table "+(ba.length+
1));e=d.trim(e.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31));ba.push(e);XLSX.utils.book_append_sheet(Ga,c,e)});k=XLSX.write(Ga,{type:"binary",bookType:a.mso.fileFormat,bookSST:!1});N(Oa(k),a.fileName+"."+a.mso.fileFormat,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","UTF-8","",!1)}else if("excel"===a.type||"xls"===a.type||"word"===a.type||"doc"===a.type){k="excel"===a.type||"xls"===a.type?"excel":"word";z="excel"===k?"xls":"doc";m='xmlns:x="urn:schemas-microsoft-com:office:'+
k+'"';var H="",ca="";d(B).filter(function(){return I(d(this))}).each(function(){var b=d(this);""===ca&&(ca=a.mso.worksheetName||b.find("caption").text()||"Table",ca=d.trim(ca.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31)));!1===a.exportHiddenCells&&(K=b.find("tr, th, td").filter(":hidden"),V=0<K.length);p=0;G=[];S=R(this);H+="<table><thead>";r=y(b);d(r).each(function(){var b=d(this);t="";E(this,"th,td",p,r.length,function(d,c,f){if(null!==d){var e="";t+="<th";if(a.mso.styles.length){var n=document.defaultView.getComputedStyle(d,
null),l=document.defaultView.getComputedStyle(b[0],null),g;for(g in a.mso.styles){var k=n[a.mso.styles[g]];""===k&&(k=l[a.mso.styles[g]]);""!==k&&"0px none rgb(0, 0, 0)"!==k&&"rgba(0, 0, 0, 0)"!==k&&(e+=""===e?'style="':";",e+=a.mso.styles[g]+":"+k)}}""!==e&&(t+=" "+e+'"');e=J(d);0<e&&(t+=' colspan="'+e+'"');e=T(d);0<e&&(t+=' rowspan="'+e+'"');t+=">"+D(d,c,f)+"</th>"}});0<t.length&&(H+="<tr>"+t+"</tr>");p++});H+="</thead><tbody>";w=C(b);d(w).each(function(){var b=d(this);t="";E(this,"td,th",p,r.length+
w.length,function(c,g,f){if(null!==c){var e=D(c,g,f),n="",l=d(c).attr("data-tableexport-msonumberformat");"undefined"===typeof l&&"function"===typeof a.mso.onMsoNumberFormat&&(l=a.mso.onMsoNumberFormat(c,g,f));"undefined"!==typeof l&&""!==l&&(n="style=\"mso-number-format:'"+l+"'");if(a.mso.styles.length){g=document.defaultView.getComputedStyle(c,null);f=document.defaultView.getComputedStyle(b[0],null);for(var k in a.mso.styles)l=g[a.mso.styles[k]],""===l&&(l=f[a.mso.styles[k]]),""!==l&&"0px none rgb(0, 0, 0)"!==
l&&"rgba(0, 0, 0, 0)"!==l&&(n+=""===n?'style="':";",n+=a.mso.styles[k]+":"+l)}t+="<td";""!==n&&(t+=" "+n+'"');n=J(c);0<n&&(t+=' colspan="'+n+'"');c=T(c);0<c&&(t+=' rowspan="'+c+'"');"string"===typeof e&&""!==e&&(e=Ba(e),e=e.replace(/\n/g,"<br>"));t+=">"+e+"</td>"}});0<t.length&&(H+="<tr>"+t+"</tr>");p++});a.displayTableName&&(H+="<tr><td></td></tr><tr><td></td></tr><tr><td>"+D(d("<p>"+a.tableName+"</p>"))+"</td></tr>");H+="</tbody></table>"});m='<html xmlns:o="urn:schemas-microsoft-com:office:office" '+
m+' xmlns="http://www.w3.org/TR/REC-html40">'+('<meta http-equiv="content-type" content="application/vnd.ms-'+k+'; charset=UTF-8">')+"<head>";"excel"===k&&(m+="\x3c!--[if gte mso 9]>",m+="<xml>",m+="<x:ExcelWorkbook>",m+="<x:ExcelWorksheets>",m+="<x:ExcelWorksheet>",m+="<x:Name>",m+=ca,m+="</x:Name>",m+="<x:WorksheetOptions>",m+="<x:DisplayGridlines/>",a.mso.rtl&&(m+="<x:DisplayRightToLeft/>"),m+="</x:WorksheetOptions>",m+="</x:ExcelWorksheet>",m+="</x:ExcelWorksheets>",m+="</x:ExcelWorkbook>",m+=
"</xml>",m+="<![endif]--\x3e");m+="<style>";m+="@page { size:"+a.mso.pageOrientation+"; mso-page-orientation:"+a.mso.pageOrientation+"; }";m+="@page Section1 {size:"+O[a.mso.pageFormat][0]+"pt "+O[a.mso.pageFormat][1]+"pt";m+="; margin:1.0in 1.25in 1.0in 1.25in;mso-header-margin:.5in;mso-footer-margin:.5in;mso-paper-source:0;}";m+="div.Section1 {page:Section1;}";m+="@page Section2 {size:"+O[a.mso.pageFormat][1]+"pt "+O[a.mso.pageFormat][0]+"pt";m+=";mso-page-orientation:"+a.mso.pageOrientation+";margin:1.25in 1.0in 1.25in 1.0in;mso-header-margin:.5in;mso-footer-margin:.5in;mso-paper-source:0;}";
m+="div.Section2 {page:Section2;}";m+="br {mso-data-placement:same-cell;}";m+="</style>";m+="</head>";m+="<body>";m+='<div class="Section'+("landscape"===a.mso.pageOrientation?"2":"1")+'">';m+=H;m+="</div>";m+="</body>";m+="</html>";if("string"===a.outputMode)return m;if("base64"===a.outputMode)return L(m);N(m,a.fileName+"."+z,"application/vnd.ms-"+k,"","base64",!1)}else if("png"===a.type)html2canvas(d(B)[0]).then(function(b){b=b.toDataURL();for(var c=atob(b.substring(22)),d=new ArrayBuffer(c.length),
g=new Uint8Array(d),f=0;f<c.length;f++)g[f]=c.charCodeAt(f);if("string"===a.outputMode)return c;if("base64"===a.outputMode)return L(b);"window"===a.outputMode?window.open(b):N(d,a.fileName+".png","image/png","","",!1)});else if("pdf"===a.type)if(!0===a.pdfmake.enabled){var U={content:[]};d.extend(!0,U,a.pdfmake.docDefinition);G=[];d(B).filter(function(){return I(d(this))}).each(function(){var b=d(this),c=[],e=[];p=0;var g=function(a,b,c){var f=0;d(a).each(function(){var a=[];E(this,b,p,c,function(c,
d,f){if("undefined"!==typeof c&&null!==c){var e=J(c),h=T(c);c={text:D(c,d,f)||" "};if(1<e||1<h)c.colSpan=e||1,c.rowSpan=h||1}else c={text:" "};0<=b.indexOf("th")&&(c.style="header");a.push(c)});for(var d=a.length;d<c;d++)a.push("");a.length&&e.push(a);f<a.length&&(f=a.length);p++});return f};r=y(b);for(var f=g(r,"th,td",r.length),h=c.length;h<f;h++)c.push("*");w=C(b);f=g(w,"td",r.length+w.length);for(h=c.length;h<f;h++)c.push("*");U.content.push({table:{headerRows:r.length?r.length:null,widths:c,
body:e},layout:{layout:"noBorders",hLineStyle:function(a,b){return 0},vLineWidth:function(a,b){return 0},hLineColor:function(b,c){return b<c.table.headerRows?a.pdfmake.docDefinition.styles.header.background:a.pdfmake.docDefinition.styles.alternateRow.fillColor},vLineColor:function(b,c){return b<c.table.headerRows?a.pdfmake.docDefinition.styles.header.background:a.pdfmake.docDefinition.styles.alternateRow.fillColor},fillColor:function(b,c,d){return 0===b%2?a.pdfmake.docDefinition.styles.alternateRow.fillColor:
null}},pageBreak:U.content.length?"before":void 0})});"undefined"!==typeof pdfMake&&"undefined"!==typeof pdfMake.createPdf&&(pdfMake.fonts={Roboto:{normal:"Roboto-Regular.ttf",bold:"Roboto-Medium.ttf",italics:"Roboto-Italic.ttf",bolditalics:"Roboto-MediumItalic.ttf"}},pdfMake.vfs.hasOwnProperty("Mirza-Regular.ttf")?(U.defaultStyle.font="Mirza",d.extend(!0,pdfMake.fonts,{Mirza:{normal:"Mirza-Regular.ttf",bold:"Mirza-Bold.ttf",italics:"Mirza-Medium.ttf",bolditalics:"Mirza-SemiBold.ttf"}})):pdfMake.vfs.hasOwnProperty("gbsn00lp.ttf")?
(U.defaultStyle.font="gbsn00lp",d.extend(!0,pdfMake.fonts,{gbsn00lp:{normal:"gbsn00lp.ttf",bold:"gbsn00lp.ttf",italics:"gbsn00lp.ttf",bolditalics:"gbsn00lp.ttf"}})):pdfMake.vfs.hasOwnProperty("ZCOOLXiaoWei-Regular.ttf")&&(U.defaultStyle.font="ZCOOLXiaoWei",d.extend(!0,pdfMake.fonts,{ZCOOLXiaoWei:{normal:"ZCOOLXiaoWei-Regular.ttf",bold:"ZCOOLXiaoWei-Regular.ttf",italics:"ZCOOLXiaoWei-Regular.ttf",bolditalics:"ZCOOLXiaoWei-Regular.ttf"}})),d.extend(!0,pdfMake.fonts,a.pdfmake.fonts),pdfMake.createPdf(U).getBuffer(function(b){N(b,
a.fileName+".pdf","application/pdf","","",!1)}))}else if(!1===a.jspdf.autotable){k={dim:{w:ha(d(B).first().get(0),"width","mm"),h:ha(d(B).first().get(0),"height","mm")},pagesplit:!1};var Ha=new jsPDF(a.jspdf.orientation,a.jspdf.unit,a.jspdf.format);Ha.addHTML(d(B).first(),a.jspdf.margins.left,a.jspdf.margins.top,k,function(){va(Ha,!1)})}else{var g=a.jspdf.autotable.tableExport;if("string"===typeof a.jspdf.format&&"bestfit"===a.jspdf.format.toLowerCase()){var ja="",da="",Ia=0;d(B).each(function(){if(I(d(this))){var a=
ha(d(this).get(0),"width","pt");if(a>Ia){a>O.a0[0]&&(ja="a0",da="l");for(var c in O)O.hasOwnProperty(c)&&O[c][1]>a&&(ja=c,da="l",O[c][0]>a&&(da="p"));Ia=a}}});a.jspdf.format=""===ja?"a4":ja;a.jspdf.orientation=""===da?"w":da}if(null==g.doc&&(g.doc=new jsPDF(a.jspdf.orientation,a.jspdf.unit,a.jspdf.format),g.wScaleFactor=1,g.hScaleFactor=1,"function"===typeof a.jspdf.onDocCreated))a.jspdf.onDocCreated(g.doc);!0===g.outputImages&&(g.images={});"undefined"!==typeof g.images&&(d(B).filter(function(){return I(d(this))}).each(function(){var b=
0;G=[];!1===a.exportHiddenCells&&(K=d(this).find("tr, th, td").filter(":hidden"),V=0<K.length);r=y(d(this));w=C(d(this));d(w).each(function(){E(this,"td,th",r.length+b,r.length+w.length,function(a){xa(a,d(a).children(),g)});b++})}),r=[],w=[]);Ka(g,function(){d(B).filter(function(){return I(d(this))}).each(function(){var b;p=0;G=[];!1===a.exportHiddenCells&&(K=d(this).find("tr, th, td").filter(":hidden"),V=0<K.length);S=R(this);g.columns=[];g.rows=[];g.teCells={};if("function"===typeof g.onTable&&
!1===g.onTable(d(this),a))return!0;a.jspdf.autotable.tableExport=null;var c=d.extend(!0,{},a.jspdf.autotable);a.jspdf.autotable.tableExport=g;c.margin={};d.extend(!0,c.margin,a.jspdf.margins);c.tableExport=g;"function"!==typeof c.beforePageContent&&(c.beforePageContent=function(a){if(1===a.pageCount){var b=a.table.rows.concat(a.table.headerRow);d.each(b,function(){0<this.height&&(this.height+=(2-1.15)/2*this.styles.fontSize,a.table.height+=(2-1.15)/2*this.styles.fontSize)})}});"function"!==typeof c.createdHeaderCell&&
(c.createdHeaderCell=function(a,b){a.styles=d.extend({},b.row.styles);if("undefined"!==typeof g.columns[b.column.dataKey]){var e=g.columns[b.column.dataKey];if("undefined"!==typeof e.rect){a.contentWidth=e.rect.width;if("undefined"===typeof g.heightRatio||0===g.heightRatio){var f=b.row.raw[b.column.dataKey].rowspan?b.row.raw[b.column.dataKey].rect.height/b.row.raw[b.column.dataKey].rowspan:b.row.raw[b.column.dataKey].rect.height;g.heightRatio=a.styles.rowHeight/f}f=b.row.raw[b.column.dataKey].rect.height*
g.heightRatio;f>a.styles.rowHeight&&(a.styles.rowHeight=f)}a.styles.halign="inherit"===c.headerStyles.halign?"center":c.headerStyles.halign;a.styles.valign=c.headerStyles.valign;"undefined"!==typeof e.style&&!0!==e.style.hidden&&("inherit"===c.headerStyles.halign&&(a.styles.halign=e.style.align),"inherit"===c.styles.fillColor&&(a.styles.fillColor=e.style.bcolor),"inherit"===c.styles.textColor&&(a.styles.textColor=e.style.color),"inherit"===c.styles.fontStyle&&(a.styles.fontStyle=e.style.fstyle))}});
"function"!==typeof c.createdCell&&(c.createdCell=function(a,b){b=g.teCells[b.row.index+":"+b.column.dataKey];a.styles.halign="inherit"===c.styles.halign?"center":c.styles.halign;a.styles.valign=c.styles.valign;"undefined"!==typeof b&&"undefined"!==typeof b.style&&!0!==b.style.hidden&&("inherit"===c.styles.halign&&(a.styles.halign=b.style.align),"inherit"===c.styles.fillColor&&(a.styles.fillColor=b.style.bcolor),"inherit"===c.styles.textColor&&(a.styles.textColor=b.style.color),"inherit"===c.styles.fontStyle&&
(a.styles.fontStyle=b.style.fstyle))});"function"!==typeof c.drawHeaderCell&&(c.drawHeaderCell=function(a,b){var c=g.columns[b.column.dataKey];return(!0!==c.style.hasOwnProperty("hidden")||!0!==c.style.hidden)&&0<=c.rowIndex?wa(a,b,c):!1});"function"!==typeof c.drawCell&&(c.drawCell=function(a,b){var c=g.teCells[b.row.index+":"+b.column.dataKey];if(!0!==("undefined"!==typeof c&&c.isCanvas))wa(a,b,c)&&(g.doc.rect(a.x,a.y,a.width,a.height,a.styles.fillStyle),"undefined"===typeof c||"undefined"!==typeof c.hasUserDefText&&
!0===c.hasUserDefText||"undefined"===typeof c.elements||!c.elements.length?Aa(a,{},g):(b=a.height/c.rect.height,b>g.hScaleFactor&&(g.hScaleFactor=b),g.wScaleFactor=a.width/c.rect.width,b=a.textPos.y,za(a,c.elements,g),a.textPos.y=b,Aa(a,c.elements,g)));else{c=c.elements[0];var e=d(c).attr("data-tableexport-canvas"),f=c.getBoundingClientRect();a.width=f.width*g.wScaleFactor;a.height=f.height*g.hScaleFactor;b.row.height=a.height;ua(a,c,e,g)}return!1});g.headerrows=[];r=y(d(this));d(r).each(function(){b=
0;g.headerrows[p]=[];E(this,"th,td",p,r.length,function(a,c,d){var e=Ca(a);e.title=D(a,c,d);e.key=b++;e.rowIndex=p;g.headerrows[p].push(e)});p++});if(0<p)for(var e=p-1;0<=e;)d.each(g.headerrows[e],function(){var a=this;0<e&&null===this.rect&&(a=g.headerrows[e-1][this.key]);null!==a&&0<=a.rowIndex&&(!0!==a.style.hasOwnProperty("hidden")||!0!==a.style.hidden)&&g.columns.push(a)}),e=0<g.columns.length?-1:e-1;var k=0;w=[];w=C(d(this));d(w).each(function(){var a=[];b=0;E(this,"td,th",p,r.length+w.length,
function(c,e,f){if("undefined"===typeof g.columns[b]){var h={title:"",key:b,style:{hidden:!0}};g.columns.push(h)}a.push(D(c,e,f));"undefined"!==typeof c&&null!==c?(h=Ca(c),h.isCanvas=c.hasAttribute("data-tableexport-canvas"),h.elements=h.isCanvas?d(c):d(c).children(),"undefined"!==typeof d(c).data("teUserDefText")&&(h.hasUserDefText=!0)):(h=d.extend(!0,{},g.teCells[k+":"+(b-1)]),h.colspan=-1);g.teCells[k+":"+b++]=h});a.length&&(g.rows.push(a),k++);p++});if("function"===typeof g.onBeforeAutotable)g.onBeforeAutotable(d(this),
g.columns,g.rows,c);g.doc.autoTable(g.columns,g.rows,c);if("function"===typeof g.onAfterAutotable)g.onAfterAutotable(d(this),c);a.jspdf.autotable.startY=g.doc.autoTableEndPosY()+c.margin.top});va(g.doc,"undefined"!==typeof g.images&&!1===jQuery.isEmptyObject(g.images));"undefined"!==typeof g.headerrows&&(g.headerrows.length=0);"undefined"!==typeof g.columns&&(g.columns.length=0);"undefined"!==typeof g.rows&&(g.rows.length=0);delete g.doc;g.doc=null})}if("function"===typeof a.onTableExportEnd)a.onTableExportEnd();
return this}})(jQuery);

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

View File

@ -1025,7 +1025,7 @@ table.rc-table-resizing thead > th > a {
float:left;
}
/** 表格拖拽样式 **/
/** 表格拖拽样式 **/
.reorder_rows_onDragClass td {
color:yellow!important;
background-color:#999!important;
@ -1033,6 +1033,42 @@ table.rc-table-resizing thead > th > a {
box-shadow:0 12px 14px -12px #111 inset,0 -2px 2px -1px #333 inset
}
/** 表格列拖拽样式 **/
.dragtable-sortable {
list-style-type: none; margin: 0; padding: 0; -moz-user-select: none;
}
.dragtable-sortable li {
margin: 0; padding: 0; float: left; font-size: 1em; background: white;
}
.dragtable-sortable th, .dragtable-sortable td{
border-left: 0px;
}
.dragtable-sortable li:first-child th, .dragtable-sortable li:first-child td {
border-left: 1px solid #CCC;
}
.ui-sortable-helper {
opacity: 0.7;filter: alpha(opacity=70);
}
.ui-sortable-placeholder {
-moz-box-shadow: 4px 5px 4px #C6C6C6 inset;
-webkit-box-shadow: 4px 5px 4px #C6C6C6 inset;
box-shadow: 4px 5px 4px #C6C6C6 inset;
border-bottom: 1px solid #CCCCCC;
border-top: 1px solid #CCCCCC;
visibility: visible !important;
background: #EFEFEF !important;
visibility: visible !important;
}
.ui-sortable-placeholder * {
opacity: 0.0; visibility: hidden;
}
/** 表格选中样式 **/
.bootstrap-table .fixed-table-container .table tbody tr.selected td {
background-color: #E8F7FD;

View File

@ -501,6 +501,7 @@ $(function() {
// 锁定屏幕
$('#lockScreen').on('click', function () {
storage.set('lockPath', $('.page-tabs-content').find('.active').attr('data-id'));
location.href = ctx + "lockscreen";
});

View File

@ -418,11 +418,14 @@ var sub = {
for (var i = 0; i < columns.length; i++) {
var inputValue = $(columns[i]).find('input');
var selectValue = $(columns[i]).find('select');
var textareaValue = $(columns[i]).find('textarea');
var key = dataColumns[i].field;
if ($.common.isNotEmpty(inputValue.val())) {
obj[key] = inputValue.val();
} else if ($.common.isNotEmpty(selectValue.val())) {
obj[key] = selectValue.val();
} else if ($.common.isNotEmpty(textareaValue.val())) {
obj[key] = textareaValue.val();
} else {
obj[key] = "";
}

View File

@ -61,6 +61,8 @@ var table = {
showColumns: true,
showToggle: true,
showExport: false,
exportDataType: 'all',
exportTypes: ['csv', 'txt', 'doc', 'excel'],
clickToSelect: false,
singleSelect: false,
mobileResponsive: true,
@ -142,6 +144,8 @@ var table = {
responseHandler: $.table.responseHandler, // 在加载服务器发送来的数据之前处理函数
onLoadSuccess: $.table.onLoadSuccess, // 当所有数据被加载时触发处理函数
exportOptions: options.exportOptions, // 前端导出忽略列索引
exportDataType: options.exportDataType, // 导出方式默认all导出所有数据basic导出当前页的数据selected导出选中的数据
exportTypes: options.exportTypes, // 导出文件类型 json、xml、png、csv、txt、sql、doc、excel、xlsx、powerpoint、pdf
printPageBuilder: options.printPageBuilder, // 自定义打印页面模板
detailFormatter: options.detailFormatter, // 在行下面展示其他数据列表
});
@ -1007,6 +1011,11 @@ var table = {
};
$.modal.openOptions(options);
},
// 详细信息以tab页展现
detailTab: function(id) {
table.set();
$.modal.openTab("详细" + table.options.modalName, $.operate.detailUrl(id));
},
// 详细访问地址
detailUrl: function(id) {
var url = "/404.html";

View File

@ -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.6.0
<b>当前版本:</b>v4.6.1
</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.6.0
<b>当前版本:</b>v4.6.1
</p>
<p>
<span class="label label-warning">开源免费</span>

View File

@ -21,6 +21,13 @@
overflow-x: hidden;
overflow-y: auto;
}
/* 解决工具栏无法固定底部的问题如果页面没有animated类可以不写这部分代码 */
.animated {
animation-fill-mode: none;
-webkit-animation-fill-mode: none;
-moz-animation-fill-mode: none;
-o-animation-fill-mode: none;
}
</style>
</head>
<body class="gray-bg">

View File

@ -2,6 +2,10 @@
<html lang="zh">
<head>
<th:block th:include="include :: header('弹层组件')" />
<style>
/* 解决layer相册层弹出时导致页面自动滚动 */
html {height: auto;}
</style>
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content fadeInRight">
@ -103,6 +107,7 @@
<button type="button" class="btn btn-primary" id="button-open-8">tab层</button>
<button type="button" class="btn btn-primary" id="button-open-9">prompt层</button>
<button type="button" class="btn btn-primary" id="button-open-10">捕获页</button>
<button type="button" class="btn btn-primary" id="button-open-16">相册层</button>
</div>
</div>
</div>
@ -251,6 +256,33 @@
// 需要关闭窗口的url
$.modal.closeTab(prefix + "/form");
})
$("#button-open-16").click(function(){
var json = {
"title": "若依相册", //相册标题
"id": 123, //相册id
"start": 0, //初始显示的图片序号默认0
"data": [ //相册包含的图片,数组格式
{
"alt": "默认头像",
"pid": 1, //图片id
"src": "/img/profile.jpg", //原图地址
"thumb": "/img/profile.jpg" //缩略图地址
},
{
"alt": "打赏",
"pid": 2, //图片id
"src": "/img/pay.png", //原图地址
"thumb": "/img/pay.png" //缩略图地址
}
]
};
layer.photos({
photos: json,
closeBtn: 0, //右上角按钮可通过配置1和2来展示如果不显示则closeBtn: 0
anim: 5 //0-6的选择指定弹出图片动画类型默认随机请注意3.0之前的版本用shift参数
});
})
</script>
</body>
</html>

View File

@ -26,6 +26,7 @@
<div class="ibox-content" id="test">
<p>弹出复选框表格及单选框表格(点击提交后得到数据并回显到父窗体)。 </p>
<button type="button" class="btn btn-info" onclick="selectUsersToParent()">弹出表格(复选框)</button>
<button type="button" class="btn btn-warning" onclick="selectUsersToParentCallBack()">弹出表格(复选框)- 回调形式</button>
<p id="userids"> </p>
</div>
</div>
@ -48,6 +49,25 @@
$.modal.open("选择用户", prefix + "/parent");
}
function selectUsersToParentCallBack(){
var options = {
title: '选择用户',
url: prefix + "/parent",
callBack: doSubmit
};
$.modal.openOptions(options);
}
function doSubmit(index, layero){
var rows = layero.find("iframe")[0].contentWindow.getSelections();
if (rows.length == 0) {
$.modal.alertWarning("请至少选择一条记录");
return;
}
$('#userids').html(rows.join())
layer.close(index);
}
function selectUsers(){
alert(1);
}

View File

@ -72,7 +72,7 @@
$.table.init(options);
});
/* 添加用户-选择用户-提交 */
/* 添加用户-选择用户-提交(子页面调用父页面形式) */
function submitHandler(index, layero) {
var rows = $.table.selectFirstColumns();
if (rows.length == 0) {
@ -85,6 +85,11 @@
// 父页面的变量
parent.$('#userids').html(rows.join());
}
/* 添加用户-选择用户-提交(回调形式-父页面调用子页面) */
function getSelections() {
return $.table.selectFirstColumns();
}
</script>
</body>
</html>

View File

@ -25,9 +25,13 @@
showToggle: false,
showColumns: false,
showExport: true,
exportDataType: 'selected', // 导出选择数据
exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'], // 导出的文件类型
exportOptions: {
ignoreColumn: [0, 8] //忽略第一列和最后一列
fileName: '用户数据', // 文件名称设置
ignoreColumn: [0, 8] // 忽略第一列和最后一列
},
clickToSelect: true,
columns: [{
checkbox: true
},

View File

@ -0,0 +1,120 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('导出选择列')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="export-form">
<div class="select-list">
<ul>
<li>
用户姓名:<input type="text" name="userName" value=""/>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<i class="fa fa-info-circle" style="color: red;"></i> 勾选数据导出指定列,否则为全部
<a class="btn btn-warning" onclick="exportSelected()">
<i class="fa fa-download"></i> 导出
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<div th:include="include :: footer"></div>
<script th:inline="javascript">
var prefix = ctx + "demo/table";
var datas = [[${@dict.getType('sys_normal_disable')}]];
$(function() {
var options = {
url: prefix + "/list",
showSearch: false,
showRefresh: false,
showToggle: false,
showColumns: false,
clickToSelect: true,
rememberSelected: true,
columns: [{
field: 'state',
checkbox: true
},
{
field : 'userId',
title : '用户ID'
},
{
field : 'userCode',
title : '用户编号'
},
{
field : 'userName',
title : '用户姓名'
},
{
field : 'userPhone',
title : '用户手机'
},
{
field : 'userEmail',
title : '用户邮箱'
},
{
field : 'userBalance',
title : '用户余额'
},
{
field: 'status',
title: '用户状态',
align: 'center',
formatter: function(value, row, index) {
return $.table.selectDictLabel(datas, value);
}
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs" href="#"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs" href="#"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
// 导出数据
function exportSelected() {
var userIds = $.table.selectColumns("userId");
var dataParam = $("#export-form").serializeArray();
var tipMsg = "确定导出所有数据吗?";
if($.common.isNotEmpty(userIds)){
tipMsg = "确定导出勾选" + userIds.length + "条数据吗?";
dataParam.push({ "name": "userIds", "value": userIds });
}
$.modal.confirm(tipMsg, function() {
$.post(prefix + "/exportData", dataParam, function(result) {
if (result.code == web_status.SUCCESS) {
window.location.href = ctx + "common/download?fileName=" + encodeURI(result.msg) + "&delete=" + true;
} else {
$.modal.alertError(result.msg);
}
});
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,84 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('表格列拖拽操作')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="orderColumns()">
<i class="fa fa-refresh"></i> 恢复顺序
</a>
</div>
<div class="row">
<div class="col-sm-12 select-table table-bordered">
<p class="select-title">按住表格列拖拽</p>
<table id="bootstrap-table"
data-reorderable-columns="true"></table>
</div>
</div>
</div>
<div th:include="include :: footer"></div>
<script th:src="@{/js/jquery-ui-1.10.4.min.js}"></script>
<th:block th:include="include :: bootstrap-table-reorder-columns-js" />
<script th:inline="javascript">
var prefix = ctx + "demo/table";
var datas = [[${@dict.getType('sys_normal_disable')}]];
$(function() {
var options = {
url: prefix + "/list",
showSearch: false,
showRefresh: false,
showToggle: false,
showColumns: false,
columns: [{
field : 'userId',
title : '用户ID'
},
{
field : 'userCode',
title : '用户编号'
},
{
field : 'userName',
title : '用户姓名'
},
{
field : 'userPhone',
title : '用户手机'
},
{
field : 'userEmail',
title : '用户邮箱'
},
{
field : 'userBalance',
title : '用户余额'
},
{
field: 'status',
title: '用户状态',
align: 'center',
formatter: function(value, row, index) {
return $.table.selectDictLabel(datas, value);
}
}]
};
$.table.init(options);
});
function orderColumns() {
$('#bootstrap-table').bootstrapTable('orderColumns', {
userId: 0,
userCode: 1,
userName: 2,
userPhone: 3,
userEmail: 4,
userBalance: 5,
status: 6
})
}
</script>
</body>
</html>

View File

@ -1,13 +1,13 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('表格拖拽操作')" />
<th:block th:include="include :: header('表格拖拽操作')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 select-table table-striped">
<p class="select-title">按住表格拖拽</p>
<p class="select-title">按住表格拖拽</p>
<table id="bootstrap-table"
data-use-row-attr-func="true"
data-reorderable-rows="true"></table>
@ -15,7 +15,7 @@
</div>
</div>
<div th:include="include :: footer"></div>
<th:block th:include="include :: bootstrap-table-reorder-js" />
<th:block th:include="include :: bootstrap-table-reorder-row-js" />
<script th:inline="javascript">
var prefix = ctx + "demo/table";
var datas = [[${@dict.getType('sys_normal_disable')}]];

View File

@ -13,7 +13,7 @@
<link th:href="@{/ajax/libs/bootstrap-table/bootstrap-table.min.css?v=20210202}" 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.6.0}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.6.1}" rel="stylesheet"/>
</head>
<!-- 通用JS -->
@ -31,14 +31,14 @@
<script th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script>
<script th:src="@{/ajax/libs/validate/jquery.validate.extend.js}"></script>
<!-- jquery-validate 表单树插件 -->
<script th:src="@{/ajax/libs/bootstrap-treetable/bootstrap-treetable.js}"></script>
<script th:src="@{/ajax/libs/bootstrap-treetable/bootstrap-treetable.min.js?v=20210526}"></script>
<!-- 遮罩层 -->
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<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.6.0}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.6.0}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js?v=20210516}"></script>
<script th:src="@{/ajax/libs/layui/layui.js?v=20210516}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.6.1}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.6.1}"></script>
</div>
<!-- ztree树插件 -->
@ -157,7 +157,7 @@
<!-- ECharts百度统计图表插件 -->
<div th:fragment="echarts-js">
<script th:src="@{/ajax/libs/report/echarts/echarts-all.js}"></script>
<script th:src="@{/ajax/libs/report/echarts/echarts-all.min.js}"></script>
</div>
<!-- peity图表组合插件 -->
@ -170,10 +170,16 @@
<script th:src="@{/ajax/libs/report/sparkline/jquery.sparkline.min.js}"></script>
</div>
<!-- 表格拖拽插件 -->
<div th:fragment="bootstrap-table-reorder-js">
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder/bootstrap-table-reorder.js}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder/jquery.tablednd.js}"></script>
<!-- 表格行拖拽插件 -->
<div th:fragment="bootstrap-table-reorder-row-js">
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder-row/bootstrap-table-reorder.js}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder-row/jquery.tablednd.js}"></script>
</div>
<!-- 表格列拖拽插件 -->
<div th:fragment="bootstrap-table-reorder-columns-js">
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder-columns/jquery.dragtable.js}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder-columns/bootstrap-table-reorder.min.js?v=20210203}"></script>
</div>
<!-- 表格列宽拖动插件 -->
@ -193,8 +199,8 @@
<!-- 表格导出插件 -->
<div th:fragment="bootstrap-table-export-js">
<script th:src="@{/ajax/libs/bootstrap-table/extensions/export/bootstrap-table-export.js}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/export/tableExport.js}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/export/bootstrap-table-export.min.js?v=20210523}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/export/tableExport.min.js?v=20210523}"></script>
</div>
<!-- 表格冻结列插件 -->

View File

@ -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.6.0}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.6.1}" rel="stylesheet"/>
</head>
<body class="fixed-sidebar full-height-layout gray-bg" style="overflow: hidden">
<div id="wrapper">
@ -123,6 +123,7 @@
<li><a class="menuItem" th:href="@{/demo/table/footer}">数据汇总</a></li>
<li><a class="menuItem" th:href="@{/demo/table/groupHeader}">组合表头</a></li>
<li><a class="menuItem" th:href="@{/demo/table/export}">表格导出</a></li>
<li><a class="menuItem" th:href="@{/demo/table/exportSelected}">导出选择列</a></li>
<li><a class="menuItem" th:href="@{/demo/table/remember}">翻页记住选择</a></li>
<li><a class="menuItem" th:href="@{/demo/table/pageGo}">跳转至指定页</a></li>
<li><a class="menuItem" th:href="@{/demo/table/params}">自定义查询参数</a></li>
@ -136,7 +137,8 @@
<li><a class="menuItem" th:href="@{/demo/table/child}">表格父子视图</a></li>
<li><a class="menuItem" th:href="@{/demo/table/image}">表格图片预览</a></li>
<li><a class="menuItem" th:href="@{/demo/table/curd}">动态增删改查</a></li>
<li><a class="menuItem" th:href="@{/demo/table/reorder}">表格拖拽操作</a></li>
<li><a class="menuItem" th:href="@{/demo/table/reorderRows}">表格行拖拽操作</a></li>
<li><a class="menuItem" th:href="@{/demo/table/reorderColumns}">表格列拖拽操作</a></li>
<li><a class="menuItem" th:href="@{/demo/table/resizable}">表格列宽拖动</a></li>
<li><a class="menuItem" th:href="@{/demo/table/editable}">表格行内编辑</a></li>
<li><a class="menuItem" th:href="@{/demo/table/subdata}">主子表提交</a></li>
@ -216,7 +218,10 @@
<!-- 顶部菜单列表 -->
<th:block th:each="menu : ${menus}">
<li role="presentation" th:id="|tab_${menu.menuId}|">
<a data-toggle="tab" th:class="@{${!#strings.isEmpty(menu.target) && menu.target == 'menuBlank'} ? 'menuBlank'}" th:href="@{${!#strings.isEmpty(menu.target) && menu.target == 'menuBlank'} ? ${menu.url} : |#menu_${menu.menuId}|}">
<a th:if="${#lists.isEmpty(menu.children)}" data-toggle="tab" th:class="@{${!#strings.isEmpty(menu.target) && menu.target == 'menuBlank'} ? 'menuBlank' : 'menuItem noactive'}" th:href="${menu.url}">
<i th:class="${menu.icon}"></i> <span>[[${menu.menuName}]]</span>
</a>
<a th:if="${not #lists.isEmpty(menu.children)}" data-toggle="tab" th:class="@{${!#strings.isEmpty(menu.target) && menu.target == 'menuBlank'} ? 'menuBlank'}" th:href="@{${!#strings.isEmpty(menu.target) && menu.target == 'menuBlank'} ? ${menu.url} : |#menu_${menu.menuId}|}">
<i th:class="${menu.icon}"></i> <span>[[${menu.menuName}]]</span>
</a>
</li>
@ -309,8 +314,8 @@
<script th:src="@{/js/jquery.contextMenu.min.js}"></script>
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.6.0}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.6.0}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.6.1}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.6.1}"></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>
@ -379,6 +384,7 @@ function applyPath(url) {
}
$(function() {
var lockPath = storage.get('lockPath');
if($.common.equals("history", mode) && window.performance.navigation.type == 1) {
var url = storage.get('publicPath');
if ($.common.isNotEmpty(url)) {
@ -386,6 +392,9 @@ $(function() {
} else {
$(".navbar-toolbar li a").eq(0).click();
}
} else if($.common.isNotEmpty(lockPath)) {
applyPath(lockPath);
storage.remove('lockPath');
} else {
var hash = location.hash;
if ($.common.isNotEmpty(hash)) {

View File

@ -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.6.0}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.6.1}" rel="stylesheet"/>
</head>
<body class="fixed-sidebar full-height-layout gray-bg" style="overflow: hidden">
<div id="wrapper">
@ -104,6 +104,7 @@
<li><a class="menuItem" th:href="@{/demo/table/footer}">数据汇总</a></li>
<li><a class="menuItem" th:href="@{/demo/table/groupHeader}">组合表头</a></li>
<li><a class="menuItem" th:href="@{/demo/table/export}">表格导出</a></li>
<li><a class="menuItem" th:href="@{/demo/table/exportSelected}">导出选择列</a></li>
<li><a class="menuItem" th:href="@{/demo/table/remember}">翻页记住选择</a></li>
<li><a class="menuItem" th:href="@{/demo/table/pageGo}">跳转至指定页</a></li>
<li><a class="menuItem" th:href="@{/demo/table/params}">自定义查询参数</a></li>
@ -117,7 +118,8 @@
<li><a class="menuItem" th:href="@{/demo/table/child}">表格父子视图</a></li>
<li><a class="menuItem" th:href="@{/demo/table/image}">表格图片预览</a></li>
<li><a class="menuItem" th:href="@{/demo/table/curd}">动态增删改查</a></li>
<li><a class="menuItem" th:href="@{/demo/table/reorder}">表格拖拽操作</a></li>
<li><a class="menuItem" th:href="@{/demo/table/reorderRows}">表格行拖拽操作</a></li>
<li><a class="menuItem" th:href="@{/demo/table/reorderColumns}">表格列拖拽操作</a></li>
<li><a class="menuItem" th:href="@{/demo/table/resizable}">表格列宽拖动</a></li>
<li><a class="menuItem" th:href="@{/demo/table/editable}">表格行内编辑</a></li>
<li><a class="menuItem" th:href="@{/demo/table/subdata}">主子表提交</a></li>
@ -259,8 +261,8 @@
<script th:src="@{/js/jquery.contextMenu.min.js}"></script>
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.6.0}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.6.0}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.6.1}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.6.1}"></script>
<script th:src="@{/ruoyi/index.js?v=20201208}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
<script th:inline="javascript">
@ -321,11 +323,15 @@ function applyPath(url) {
}
$(function() {
var lockPath = storage.get('lockPath');
if($.common.equals("history", mode) && window.performance.navigation.type == 1) {
var url = storage.get('publicPath');
if ($.common.isNotEmpty(url)) {
applyPath(url);
}
} else if($.common.isNotEmpty(lockPath)) {
applyPath(lockPath);
storage.remove('lockPath');
} else {
var hash = location.hash;
if ($.common.isNotEmpty(hash)) {

View File

@ -38,7 +38,7 @@
<script src="../static/js/bootstrap.min.js" th:src="@{/js/bootstrap.min.js}"></script>
<script src="../static/js/three.min.js" th:src="@{/js/three.min.js}"></script>
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.6.0}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.6.1}"></script>
</body>
<script th:inline="javascript">
var ctx = [[@{/}]];

View File

@ -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.6.0}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.6.1}" rel="stylesheet"/>
<!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 -->
@ -52,7 +52,7 @@
</div>
<div class="col-xs-6">
<a href="javascript:void(0);" title="点击更换验证码">
<img th:src="@{captcha/captchaImage(type=${captchaType})}" class="imgcode" width="85%"/>
<img th:src="@{/captcha/captchaImage(type=${captchaType})}" class="imgcode" width="85%"/>
</a>
</div>
</div>
@ -70,6 +70,7 @@
</div>
</div>
<script th:inline="javascript"> var ctx = [[@{/}]]; var captchaType = [[${captchaType}]]; </script>
<!--[if lte IE 8]><script>window.location.href=ctx+'html/ie.html';</script><![endif]-->
<!-- 全局js -->
<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>
@ -78,7 +79,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.6.0}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.6.1}"></script>
<script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script>
</body>
</html>

View File

@ -80,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> <s>满130035985</s> <a href="https://jq.qq.com/?_wv=1027&k=4NsjKbtU" target="_blank">143151071</a>
<p><i class="fa fa-qq"></i> QQ群<s>满1389287</s> <s>满1679294</s> <s>满1529866</s> <s>满1772718</s> <s>满1366522</s> <s>满1382251</s> <s>满1145125</s> <s>满86752435</s> <s>满134072510</s> <s>满210336300</s> <s>满339522636</s> <s>满130035985</s> <s>满143151071</s> <s>满158781320</s> <a href="https://jq.qq.com/?_wv=1027&k=HlshFwkJ" target="_blank">201531282</a>
</p>
<p><i class="fa fa-weixin"></i> 微信:<a href="javascript:;">/ *若依</a>
</p>
@ -97,13 +97,59 @@
<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="#v461">v4.6.1</a><code class="pull-right">2021.04.12</code>
</h5>
</div>
<div id="v461" class="panel-collapse collapse in">
<div class="panel-body">
<ol>
<li>新增IE浏览器版本过低提示页面</li>
<li>新增详细信息tab页签方式</li>
<li>新增解锁屏幕打开上次页签</li>
<li>数据监控默认账户密码防止越权访问</li>
<li>新增表格示例(导出选择列)</li>
<li>个人信息添加手机&邮箱重复验证</li>
<li>个人中心刷新后样式问题</li>
<li>操作日志返回参数添加非空验证</li>
<li>velocity剔除commons-collections版本防止3.2.1版本的反序列化漏洞</li>
<li>子表模板默认日期格式化</li>
<li>代码生成预览语言根据后缀名高亮显示</li>
<li>代码生成主子表相同字段导致数据问题</li>
<li>升级SpringBoot到最新版本2.2.13</li>
<li>升级shiro到最新版1.7.1 阻止身份认证绕过漏洞</li>
<li>升级bootstrapTable到最新版本v1.18.2</li>
<li>升级bootstrapTable相关组件到最新版本v1.18.2</li>
<li>升级fastjson到最新版1.2.75</li>
<li>升级druid到最新版本v1.2.4</li>
<li>升级oshi到最新版本v5.6.0</li>
<li>修改ip字段长度防止ipv6地址长度不够</li>
<li>搜索建议示例选择后隐藏列表</li>
<li>主子表示例增加初始化数据</li>
<li>优化Excel导入增加空行判断</li>
<li>修复横向菜单无法打开页签问题</li>
<li>修复导入数据为负浮点数时,导入结果会丢失精度问题</li>
<li>优化更多操作按钮左侧移入内容闪现消失情况</li>
<li>修复主子表提交中列隐藏后出现列偏移问题</li>
<li>单据打印网页时通过hidden-print隐藏元素</li>
<li>表格销毁清除记住选择数据</li>
<li>增加表格动态列示例</li>
<li>代码生成选择主子表关联元素必填</li>
<li>tree根据Id和Name选中指定节点增加空判断</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="#v46">v4.6.0</a><code class="pull-right">2021.01.01</code>
</h5>
</div>
<div id="v46" class="panel-collapse collapse in">
<div id="v46" class="panel-collapse collapse">
<div class="panel-body">
<ol>
<li>新增缓存监控管理</li>

View File

@ -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.6.0}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.6.1}" rel="stylesheet"/>
<!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 -->
@ -50,7 +50,7 @@
</div>
<div class="col-xs-6">
<a href="javascript:void(0);" title="点击更换验证码">
<img th:src="@{captcha/captchaImage(type=${captchaType})}" class="imgcode" width="85%"/>
<img th:src="@{/captcha/captchaImage(type=${captchaType})}" class="imgcode" width="85%"/>
</a>
</div>
</div>
@ -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.6.0}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.6.1}"></script>
<script src="../static/ruoyi/register.js" th:src="@{/ruoyi/register.js}"></script>
</body>
</html>

View File

@ -140,7 +140,7 @@
</ul>
</body>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.6.0}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.6.1}"></script>
<script type="text/javascript">
//皮肤样式列表
var skins = ["skin-blue", "skin-green", "skin-purple", "skin-red", "skin-yellow"];

View File

@ -50,8 +50,8 @@
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:config:export">
<i class="fa fa-download"></i> 导出
</a>
<a class="btn btn-danger" onclick="clearCache()" shiro:hasPermission="system:config:remove">
<i class="fa fa-refresh"></i> 清理缓存
<a class="btn btn-danger" onclick="refreshCache()" shiro:hasPermission="system:config:remove">
<i class="fa fa-refresh"></i> 刷新缓存
</a>
</div>
<div class="col-sm-12 select-table table-striped">
@ -135,9 +135,9 @@
$.table.init(options);
});
/** 清理参数缓存 */
function clearCache() {
$.operate.get(prefix + "/clearCache");
/** 刷新参数缓存 */
function refreshCache() {
$.operate.get(prefix + "/refreshCache");
}
</script>
</body>

View File

@ -50,8 +50,8 @@
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:dict:export">
<i class="fa fa-download"></i> 导出
</a>
<a class="btn btn-danger" onclick="clearCache()" shiro:hasPermission="system:dict:remove">
<i class="fa fa-refresh"></i> 清理缓存
<a class="btn btn-danger" onclick="refreshCache()" shiro:hasPermission="system:dict:remove">
<i class="fa fa-refresh"></i> 刷新缓存
</a>
</div>
@ -139,9 +139,9 @@
$.modal.openTab("字典数据", url);
}
/** 清理字典缓存 */
function clearCache() {
$.operate.get(prefix + "/clearCache");
/** 刷新字典缓存 */
function refreshCache() {
$.operate.get(prefix + "/refreshCache");
}
</script>
</body>

View File

@ -280,7 +280,7 @@
},
newPassword: {
required: "请输入新密码",
minlength: "密码不能小于5个字符",
minlength: "密码不能小于6个字符",
maxlength: "密码不能大于20个字符"
},
confirmPassword: {

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.6.0</version>
<version>4.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -108,7 +108,7 @@ public class Arith
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
BigDecimal one = BigDecimal.ONE;
return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
}
}

View File

@ -150,6 +150,16 @@ public class DictUtils
return StringUtils.stripEnd(propertyString.toString(), separator);
}
/**
* 删除指定字典缓存
*
* @param key 字典键
*/
public static void removeDictCache(String key)
{
CacheUtils.remove(getCacheName(), getCacheKey(key));
}
/**
* 清空字典缓存
*/

View File

@ -22,7 +22,7 @@ public class ExceptionUtil
return str;
}
public static String getRootErrorMseeage(Exception e)
public static String getRootErrorMessage(Exception e)
{
Throwable root = ExceptionUtils.getRootCause(e);
root = (root == null ? e : root);

View File

@ -257,7 +257,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
}
/**
* 下划线转驼峰命名
* 驼峰转下划线命名
*/
public static String toUnderScoreCase(String str)
{

View File

@ -542,9 +542,12 @@ public class ExcelUtil<T>
cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix());
}
else if (ColumnType.NUMERIC == attr.cellType())
{
if (StringUtils.isNotNull(value))
{
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),

View File

@ -0,0 +1,36 @@
package com.ruoyi.common.utils.security;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.KeyGenerator;
/**
* 对称密钥密码算法工具类
*
* @author ruoyi
*/
public class CipherUtils
{
/**
* 生成随机秘钥
*
* @param keyBitSize 字节大小
* @param algorithmName 算法名称
* @return 创建密匙
*/
public static Key generateNewKey(int keyBitSize, String algorithmName)
{
KeyGenerator kg;
try
{
kg = KeyGenerator.getInstance(algorithmName);
}
catch (NoSuchAlgorithmException e)
{
String msg = "Unable to acquire " + algorithmName + " algorithm. This is required to function.";
throw new IllegalStateException(msg, e);
}
kg.init(keyBitSize);
return kg.generateKey();
}
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.6.0</version>
<version>4.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -63,6 +63,7 @@ public class DataScopeAspect
@Before("dataScopePointCut()")
public void doBefore(JoinPoint point) throws Throwable
{
clearDataScope(point);
handleDataScope(point);
}
@ -163,4 +164,17 @@ public class DataScopeAspect
}
return null;
}
/**
* 拼接权限sql前先清空params.dataScope参数防止注入
*/
private void clearDataScope(final JoinPoint joinPoint)
{
Object params = joinPoint.getArgs()[0];
if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
{
BaseEntity baseEntity = (BaseEntity) params;
baseEntity.getParams().put(DATA_SCOPE, "");
}
}
}

View File

@ -1,7 +1,11 @@
package com.ruoyi.framework.aspectj;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
@ -12,6 +16,8 @@ import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.spring.PropertyPreFilters;
import com.ruoyi.common.annotation.Log;
@ -89,7 +95,10 @@ public class LogAspect
String ip = ShiroUtils.getIp();
operLog.setOperIp(ip);
// 返回参数
if (StringUtils.isNotNull(jsonResult))
{
operLog.setJsonResult(StringUtils.substring(JSON.marshal(jsonResult), 0, 2000));
}
operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
if (currentUser != null)
@ -114,7 +123,7 @@ public class LogAspect
// 设置请求方式
operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
// 处理设置注解上的参数
getControllerMethodDescription(controllerLog, operLog);
getControllerMethodDescription(joinPoint, controllerLog, operLog);
// 保存数据库
AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
}
@ -134,7 +143,7 @@ public class LogAspect
* @param operLog 操作日志
* @throws Exception
*/
public void getControllerMethodDescription(Log log, SysOperLog operLog) throws Exception
public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog) throws Exception
{
// 设置action动作
operLog.setBusinessType(log.businessType().ordinal());
@ -146,7 +155,7 @@ public class LogAspect
if (log.isSaveRequestData())
{
// 获取参数的信息传入到数据库中
setRequestValue(operLog);
setRequestValue(joinPoint, operLog);
}
}
@ -156,16 +165,23 @@ public class LogAspect
* @param operLog 操作日志
* @throws Exception 异常
*/
private void setRequestValue(SysOperLog operLog) throws Exception
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception
{
Map<String, String[]> map = ServletUtils.getRequest().getParameterMap();
if (StringUtils.isNotEmpty(map))
{
PropertyPreFilters.MySimplePropertyPreFilter excludefilter = new PropertyPreFilters().addFilter();
excludefilter.addExcludes(EXCLUDE_PROPERTIES);
String params = JSONObject.toJSONString(map, excludefilter);
String params = JSONObject.toJSONString(map, excludePropertyPreFilter());
operLog.setOperParam(StringUtils.substring(params, 0, 2000));
}
else
{
Object args = joinPoint.getArgs();
if (StringUtils.isNotNull(args))
{
String params = argsArrayToString(joinPoint.getArgs());
operLog.setOperParam(StringUtils.substring(params, 0, 2000));
}
}
}
/**
@ -183,4 +199,67 @@ public class LogAspect
}
return null;
}
/**
* 忽略敏感属性
*/
public PropertyPreFilters.MySimplePropertyPreFilter excludePropertyPreFilter()
{
return new PropertyPreFilters().addFilter().addExcludes(EXCLUDE_PROPERTIES);
}
/**
* 参数拼装
*/
private String argsArrayToString(Object[] paramsArray)
{
String params = "";
if (paramsArray != null && paramsArray.length > 0)
{
for (int i = 0; i < paramsArray.length; i++)
{
if (StringUtils.isNotNull(paramsArray[i]) && !isFilterObject(paramsArray[i]))
{
Object jsonObj = JSONObject.toJSONString(paramsArray[i], excludePropertyPreFilter());
params += jsonObj.toString() + " ";
}
}
}
return params.trim();
}
/**
* 判断是否需要过滤的对象
*
* @param o 对象信息
* @return 如果是需要过滤的对象则返回true否则返回false
*/
@SuppressWarnings("rawtypes")
public boolean isFilterObject(final Object o)
{
Class<?> clazz = o.getClass();
if (clazz.isArray())
{
return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
}
else if (Collection.class.isAssignableFrom(clazz))
{
Collection collection = (Collection) o;
for (Iterator iter = collection.iterator(); iter.hasNext();)
{
return iter.next() instanceof MultipartFile;
}
}
else if (Map.class.isAssignableFrom(clazz))
{
Map map = (Map) o;
for (Iterator iter = map.entrySet().iterator(); iter.hasNext();)
{
Map.Entry entry = (Map.Entry) iter.next();
return entry.getValue() instanceof MultipartFile;
}
}
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
|| o instanceof BindingResult;
}
}

View File

@ -8,7 +8,6 @@ import java.util.Map;
import javax.servlet.Filter;
import org.apache.commons.io.IOUtils;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.config.ConfigurationException;
import org.apache.shiro.io.ResourceUtils;
import org.apache.shiro.mgt.SecurityManager;
@ -23,6 +22,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.security.CipherUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.shiro.realm.UserRealm;
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
@ -104,12 +104,6 @@ public class ShiroConfig
@Value("${shiro.cookie.maxAge}")
private int maxAge;
/**
* 设置cipherKey密钥
*/
@Value("${shiro.cookie.cipherKey}")
private String cipherKey;
/**
* 登录地址
*/
@ -271,6 +265,7 @@ public class ShiroConfig
// 对静态资源设置匿名访问
filterChainDefinitionMap.put("/favicon.ico**", "anon");
filterChainDefinitionMap.put("/ruoyi.png**", "anon");
filterChainDefinitionMap.put("/html/**", "anon");
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/docs/**", "anon");
filterChainDefinitionMap.put("/fonts/**", "anon");
@ -356,7 +351,7 @@ public class ShiroConfig
{
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
cookieRememberMeManager.setCipherKey(Base64.decode(cipherKey));
cookieRememberMeManager.setCipherKey(CipherUtils.generateNewKey(128, "AES").getEncoded());
return cookieRememberMeManager;
}

View File

@ -94,18 +94,8 @@ public class KickoutSessionFilter extends AccessControlFilter
// 如果队列里的sessionId数超出最大会话数开始踢人
while (deque.size() > maxSession)
{
Serializable kickoutSessionId = null;
// 是否踢出后来登录的默认是false即后者登录的用户踢出前者登录的用户
if (kickoutAfter)
{
// 踢出后者
kickoutSessionId = deque.removeFirst();
}
else
{
// 踢出前者
kickoutSessionId = deque.removeLast();
}
Serializable kickoutSessionId = kickoutAfter ? deque.removeFirst() : deque.removeLast();
// 踢出后再更新下缓存队列
cache.put(loginName, deque);
@ -126,7 +116,7 @@ public class KickoutSessionFilter extends AccessControlFilter
}
// 如果被踢出了(前者或后者)直接退出重定向到踢出后的地址
if ((Boolean) session.getAttribute("kickout") != null && (Boolean) session.getAttribute("kickout") == true)
if (session.getAttribute("kickout") != null && (Boolean) session.getAttribute("kickout") == true)
{
// 退出登录
subject.logout();

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.6.0</version>
<version>4.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -22,7 +22,7 @@ public class VelocityInitializer
// 加载classpath目录下的vm文件
p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
// 定义字符集
p.setProperty(Velocity.ENCODING_DEFAULT, Constants.UTF8);
p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8);
p.setProperty(Velocity.OUTPUT_ENCODING, Constants.UTF8);
// 初始化Velocity引擎指定配置Properties
Velocity.init(p);

View File

@ -257,7 +257,7 @@
</section>
<th:block th:include="include :: footer" />
<th:block th:include="include :: select2-js" />
<th:block th:include="include :: bootstrap-table-reorder-js" />
<th:block th:include="include :: bootstrap-table-reorder-row-js" />
<script th:src="@{/js/jquery.tmpl.js}"></script>
<th:block th:include="include :: jquery-cxselect-js" />
<script th:inline="javascript">

View File

@ -274,7 +274,7 @@
#end
#if($table.tree)
/*${functionName}-新增-选择父部门树*/
/*${functionName}-新增-选择父${functionName}树*/
function select${BusinessName}Tree() {
var options = {
title: '${functionName}选择',

View File

@ -284,7 +284,7 @@
#end
#if($table.tree)
/*${functionName}-新增-选择父部门树*/
/*${functionName}-编辑-选择父${functionName}树*/
function select${BusinessName}Tree() {
var options = {
title: '${functionName}选择',

View File

@ -84,7 +84,7 @@ public class ${ClassName}Controller extends BaseController
{
List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class);
return util.exportExcel(list, "${businessName}");
return util.exportExcel(list, "${functionName}数据");
}
#if($table.crud || $table.sub)

View File

@ -83,7 +83,7 @@ public interface ${ClassName}Mapper
/**
* 通过${functionName}ID删除${subTable.functionName}信息
*
* @param roleId 角色ID
* @param ${pkColumn.javaField} ${functionName}ID
* @return 结果
*/
public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField});

View File

@ -15,12 +15,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#if($table.sub)
<resultMap id="${ClassName}${subClassName}Result" type="${ClassName}" extends="${ClassName}Result">
<collection property="${subclassName}List" notNullColumn="${subTable.pkColumn.columnName}" javaType="java.util.List" resultMap="${subClassName}Result" />
<collection property="${subclassName}List" notNullColumn="sub_${subTable.pkColumn.columnName}" javaType="java.util.List" resultMap="${subClassName}Result" />
</resultMap>
<resultMap type="${subClassName}" id="${subClassName}Result">
#foreach ($column in $subTable.columns)
<result property="${column.javaField}" column="${column.columnName}" />
<result property="${column.javaField}" column="sub_${column.columnName}" />
#end
</resultMap>
#end
@ -75,7 +75,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where t.${pkColumn.columnName} = #{${pkColumn.javaField}}
#elseif($table.sub)
select#foreach($column in $columns) a.$column.columnName#if($velocityCount != $columns.size()),#end#end,
#foreach($column in $subTable.columns) b.$column.columnName#if($velocityCount != $subTable.columns.size()),#end#end
#foreach($column in $subTable.columns) b.$column.columnName as sub_$column.columnName#if($velocityCount != $subTable.columns.size()),#end#end
from ${tableName} a
left join ${subTableName} b on b.${subTableFkName} = a.${pkColumn.columnName}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.6.0</version>
<version>4.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.6.0</version>
<version>4.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -50,6 +50,14 @@ public interface SysConfigMapper
*/
public int updateConfig(SysConfig config);
/**
* 删除参数配置
*
* @param configId 参数主键
* @return 结果
*/
public int deleteConfigById(Long configId);
/**
* 批量删除参数配置
*

View File

@ -56,12 +56,22 @@ public interface ISysConfigService
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteConfigByIds(String ids);
public void deleteConfigByIds(String ids);
/**
* 清空缓存数据
* 加载参数缓存数据
*/
public void clearCache();
public void loadingConfigCache();
/**
* 清空参数缓存数据
*/
public void clearConfigCache();
/**
* 重置参数缓存数据
*/
public void resetConfigCache();
/**
* 校验参数键名是否唯一

View File

@ -41,7 +41,7 @@ public interface ISysDictDataService
* @param ids 需要删除的数据
* @return 结果
*/
public int deleteDictDataByIds(String ids);
public void deleteDictDataByIds(String ids);
/**
* 新增保存字典数据信息

View File

@ -58,12 +58,22 @@ public interface ISysDictTypeService
* @return 结果
* @throws Exception 异常
*/
public int deleteDictTypeByIds(String ids);
public void deleteDictTypeByIds(String ids);
/**
* 清空缓存数据
* 加载字典缓存数据
*/
public void clearCache();
public void loadingDictCache();
/**
* 清空字典缓存数据
*/
public void clearDictCache();
/**
* 重置字典缓存数据
*/
public void resetDictCache();
/**
* 新增保存字典类型信息

View File

@ -31,11 +31,7 @@ public class SysConfigServiceImpl implements ISysConfigService
@PostConstruct
public void init()
{
List<SysConfig> configsList = configMapper.selectConfigList(new SysConfig());
for (SysConfig config : configsList)
{
CacheUtils.put(getCacheName(), getCacheKey(config.getConfigKey()), config.getConfigValue());
}
loadingConfigCache();
}
/**
@ -130,7 +126,7 @@ public class SysConfigServiceImpl implements ISysConfigService
* @return 结果
*/
@Override
public int deleteConfigByIds(String ids)
public void deleteConfigByIds(String ids)
{
Long[] configIds = Convert.toLongArray(ids);
for (Long configId : configIds)
@ -140,25 +136,43 @@ public class SysConfigServiceImpl implements ISysConfigService
{
throw new BusinessException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey()));
}
configMapper.deleteConfigById(configId);
CacheUtils.remove(getCacheName(), getCacheKey(config.getConfigKey()));
}
int count = configMapper.deleteConfigByIds(Convert.toStrArray(ids));
if (count > 0)
{
CacheUtils.removeAll(getCacheName());
}
return count;
}
/**
* 清空缓存数据
* 加载参数缓存数据
*/
@Override
public void clearCache()
public void loadingConfigCache()
{
List<SysConfig> configsList = configMapper.selectConfigList(new SysConfig());
for (SysConfig config : configsList)
{
CacheUtils.put(getCacheName(), getCacheKey(config.getConfigKey()), config.getConfigValue());
}
}
/**
* 清空参数缓存数据
*/
@Override
public void clearConfigCache()
{
CacheUtils.removeAll(getCacheName());
}
/**
* 重置参数缓存数据
*/
@Override
public void resetConfigCache()
{
clearConfigCache();
loadingConfigCache();
}
/**
* 校验参数键名是否唯一
*

View File

@ -259,7 +259,7 @@ public class SysDeptServiceImpl implements ISysDeptService
List<SysDept> children = deptMapper.selectChildrenDeptById(deptId);
for (SysDept child : children)
{
child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
}
if (children.size() > 0)
{

View File

@ -64,14 +64,16 @@ public class SysDictDataServiceImpl implements ISysDictDataService
* @return 结果
*/
@Override
public int deleteDictDataByIds(String ids)
public void deleteDictDataByIds(String ids)
{
int row = dictDataMapper.deleteDictDataByIds(Convert.toStrArray(ids));
if (row > 0)
Long[] dictCodes = Convert.toLongArray(ids);
for (Long dictCode : dictCodes)
{
DictUtils.clearDictCache();
SysDictData data = selectDictDataById(dictCode);
dictDataMapper.deleteDictDataById(dictCode);
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(data.getDictType());
DictUtils.setDictCache(data.getDictType(), dictDatas);
}
return row;
}
/**
@ -81,12 +83,13 @@ public class SysDictDataServiceImpl implements ISysDictDataService
* @return 结果
*/
@Override
public int insertDictData(SysDictData dictData)
public int insertDictData(SysDictData data)
{
int row = dictDataMapper.insertDictData(dictData);
int row = dictDataMapper.insertDictData(data);
if (row > 0)
{
DictUtils.clearDictCache();
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(data.getDictType());
DictUtils.setDictCache(data.getDictType(), dictDatas);
}
return row;
}
@ -98,12 +101,13 @@ public class SysDictDataServiceImpl implements ISysDictDataService
* @return 结果
*/
@Override
public int updateDictData(SysDictData dictData)
public int updateDictData(SysDictData data)
{
int row = dictDataMapper.updateDictData(dictData);
int row = dictDataMapper.updateDictData(data);
if (row > 0)
{
DictUtils.clearDictCache();
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(data.getDictType());
DictUtils.setDictCache(data.getDictType(), dictDatas);
}
return row;
}

View File

@ -38,12 +38,7 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
@PostConstruct
public void init()
{
List<SysDictType> dictTypeList = dictTypeMapper.selectDictTypeAll();
for (SysDictType dictType : dictTypeList)
{
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dictType.getDictType());
DictUtils.setDictCache(dictType.getDictType(), dictDatas);
}
loadingDictCache();
}
/**
@ -123,7 +118,7 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
* @return 结果
*/
@Override
public int deleteDictTypeByIds(String ids)
public void deleteDictTypeByIds(String ids)
{
Long[] dictIds = Convert.toLongArray(ids);
for (Long dictId : dictIds)
@ -133,24 +128,41 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
{
throw new BusinessException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
}
dictTypeMapper.deleteDictTypeById(dictId);
DictUtils.removeDictCache(dictType.getDictType());
}
int count = dictTypeMapper.deleteDictTypeByIds(dictIds);
if (count > 0)
{
DictUtils.clearDictCache();
}
return count;
}
/**
* 清空缓存数据
* 加载字典缓存数据
*/
@Override
public void clearCache()
public void loadingDictCache()
{
List<SysDictType> dictTypeList = dictTypeMapper.selectDictTypeAll();
for (SysDictType dict : dictTypeList)
{
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType());
DictUtils.setDictCache(dict.getDictType(), dictDatas);
}
}
/**
* 清空字典缓存数据
*/
public void clearDictCache()
{
DictUtils.clearDictCache();
}
/**
* 重置字典缓存数据
*/
public void resetDictCache()
{
clearDictCache();
loadingDictCache();
}
/**
* 新增保存字典类型信息
*
@ -158,12 +170,12 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
* @return 结果
*/
@Override
public int insertDictType(SysDictType dictType)
public int insertDictType(SysDictType dict)
{
int row = dictTypeMapper.insertDictType(dictType);
int row = dictTypeMapper.insertDictType(dict);
if (row > 0)
{
DictUtils.clearDictCache();
DictUtils.setDictCache(dict.getDictType(), null);
}
return row;
}
@ -176,14 +188,15 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
*/
@Override
@Transactional
public int updateDictType(SysDictType dictType)
public int updateDictType(SysDictType dict)
{
SysDictType oldDict = dictTypeMapper.selectDictTypeById(dictType.getDictId());
dictDataMapper.updateDictDataType(oldDict.getDictType(), dictType.getDictType());
int row = dictTypeMapper.updateDictType(dictType);
SysDictType oldDict = dictTypeMapper.selectDictTypeById(dict.getDictId());
dictDataMapper.updateDictDataType(oldDict.getDictType(), dict.getDictType());
int row = dictTypeMapper.updateDictType(dict);
if (row > 0)
{
DictUtils.clearDictCache();
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType());
DictUtils.setDictCache(dict.getDictType(), dictDatas);
}
return row;
}

View File

@ -98,6 +98,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where config_id = #{configId}
</update>
<delete id="deleteConfigById" parameterType="Long">
delete from sys_config where config_id = #{configId}
</delete>
<delete id="deleteConfigByIds" parameterType="String">
delete from sys_config where config_id in
<foreach item="configId" collection="array" open="(" separator="," close=")">

View File

@ -152,7 +152,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
update_time = sysdate()
</set>
where dept_id in (${ancestors})
where find_in_set(#{deptId}, ancestors)
</update>
</mapper>

View File

@ -79,7 +79,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select>
<delete id="deleteRoleById" parameterType="Long">
delete from sys_role where role_id = #{roleId}
update sys_role set del_flag = '2' where role_id = #{roleId}
</delete>
<delete id="deleteRoleByIds" parameterType="Long">