1、本组件支持列表的表头自定义配置,checkbox实现
2、本组件支持列表列排序,vuedraggable是拖拽插件,上图中字段管理里的拖拽效果 ,需要的话请自行npm install
3、本组件支持查询条件动态配置,穿梭框实现
查询配置
{{ tag.tagLabel }} :
{{ tag.tagValue }}
字段管理
勾选您要选择的字段
{{ item.label }}
查询
{{ row.type.label }}
{{ row[item.name] }}
{{ row[item.name].label }}
{{ row[item.name] }}
详情
{{ column.label }}
-
{{ item.label }}
{{ item.label }}
确定
import JSEncrypt from 'jsencrypt'
import { getPublicKey } from '@/api/publicKey'
const privateKey =
'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMFPa+v52FkSUXvcUnrGI/XzW3EpZRI0s9BCWJ3oNQmEYA5luWW5p8h0uadTIoTyYweFPdH4hveyxlwmS7oefvbIdiP+o+QIYW/R4Wjsb4Yl8MhR4PJqUE3RCy6IT9fM8ckG4kN9ECs6Ja8fQFc6/mSl5dJczzJO3k1rWMBhKJD/AgMBAAECgYEAucMakH9dWeryhrYoRHcXo4giPVJsH9ypVt4KzmOQY/7jV7KFQK3x//27UoHfUCak51sxFw9ek7UmTPM4HjikA9LkYeE7S381b4QRvFuf3L6IbMP3ywJnJ8pPr2l5SqQ00W+oKv+w/VmEsyUHr+k4Z+4ik+FheTkVWp566WbqFsECQQDjYaMcaKw3j2Zecl8T6eUe7fdaRMIzp/gcpPMfT/9rDzIQk+7ORvm1NI9AUmFv/FAlfpuAMrdL2n7p9uznWb7RAkEA2aP934kbXg5bdV0R313MrL+7WTK/qdcYxATUbMsMuWWQBoS5irrt80WCZbG48hpocJavLNjbtrjmUX3CuJBmzwJAOJg8uP10n/+ZQzjEYXh+BszEHDuw+pp8LuT/fnOy5zrJA0dO0RjpXijO3vuiNPVgHXT9z1LQPJkNrb5ACPVVgQJBALPeb4uV0bNrJDUb5RB4ghZnIxv18CcaqNIft7vuGCcFBAIPIRTBprR+RuVq+xHDt3sNXdsvom4h49+Hky1b0ksCQBBwUtVaqH6ztCtwUF1j2c/Zcrt5P/uN7IHAd44K0gIJc1+Csr3qPG+G2yoqRM8KVqLI8Z2ZYn9c+AvEE+L9OQY='
/**
* 最长加密长度
* @type {number}
*/
const MAX_ENCRYPT_BLOCK = 117
/**
* 最长解码长度
* @type {number}
*/
const MAX_DECRYPT_BLOCK = 128
/**
* @description RSA加密(支持长字符加密)
* @param data
* @returns {Promise<{param: PromiseLike}|*>}
*/
export async function encryptedData(data) {
let publicKey
const res = await getPublicKey()
publicKey = res.data.publicKey
if (res.data.mockServer) {
publicKey = ''
}
if (publicKey === '') {
return data
}
const encrypt = new JSEncrypt()
encrypt.setPublicKey(
`-----BEGIN PUBLIC KEY-----${publicKey}-----END PUBLIC KEY-----`
)
let bufTmp = ''
let hexTmp = ''
let result = ''
const buffer = Buffer.from(JSON.stringify(data))
let offSet = 0
const inputLen = buffer.length
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
bufTmp = buffer.slice(offSet, offSet + MAX_ENCRYPT_BLOCK)
} else {
bufTmp = buffer.slice(offSet, inputLen)
}
hexTmp = encrypt.encrypt(bufTmp.toString())
result += atob(hexTmp)
offSet += MAX_ENCRYPT_BLOCK
}
return btoa(result)
}
/**
* @description RSA解密(支持长字符解密)
* @param data
* @returns {PromiseLike}
*/
export function decryptedData(data) {
const decrypt = new JSEncrypt()
decrypt.setPrivateKey(
`-----BEGIN RSA PRIVATE KEY-----${privateKey}-----END RSA PRIVATE KEY-----`
)
let bufTmp = ''
let hexTmp = ''
let result = ''
const buffer = atob(data)
let offSet = 0
const inputLen = buffer.length
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
bufTmp = buffer.slice(offSet, offSet + MAX_DECRYPT_BLOCK)
} else {
bufTmp = buffer.slice(offSet, inputLen)
}
hexTmp = decrypt.decrypt(btoa(bufTmp))
result += hexTmp
offSet += MAX_DECRYPT_BLOCK
}
return JSON.parse(result)
}
/**
* @description 格式化时间
* @param time
* @param cFormat
* @returns {string|null}
*/
export function parseTime(time, cFormat) {
if (arguments.length === 0) {
return null
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
time = parseInt(time)
}
if (typeof time === 'number' && time.toString().length === 10) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay(),
}
return format.replace(/{([ymdhisa])+}/g, (result, key) => {
let value = formatObj[key]
if (key === 'a') {
return ['日', '一', '二', '三', '四', '五', '六'][value]
}
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
}
/**
* @description 格式化时间
* @param time
* @param option
* @returns {string}
*/
export function formatTime(time, option) {
if (('' + time).length === 10) {
time = parseInt(time) * 1000
} else {
time = +time
}
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
if (diff < 30) {
return '刚刚'
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
} else if (diff < 3600 * 24 * 2) {
return '1天前'
}
if (option) {
return parseTime(time, option)
} else {
return (
d.getMonth() +
1 +
'月' +
d.getDate() +
'日' +
d.getHours() +
'时' +
d.getMinutes() +
'分'
)
}
}
/**
* @description 将url请求参数转为json格式
* @param url
* @returns {{}|any}
*/
export function paramObj(url) {
const search = url.split('?')[1]
if (!search) {
return {}
}
return JSON.parse(
'{"' +
decodeURIComponent(search)
.replace(/"/g, '\\"')
.replace(/&/g, '","')
.replace(/=/g, '":"')
.replace(/\+/g, ' ') +
'"}'
)
}
/**
* @description 父子关系的数组转换成树形结构数据
* @param data
* @returns {*}
*/
export function translateDataToTree(data) {
const parent = data.filter(
(value) => value.parentId === 'undefined' || value.parentId === null
)
const children = data.filter(
(value) => value.parentId !== 'undefined' && value.parentId !== null
)
const translator = (parent, children) => {
parent.forEach((parent) => {
children.forEach((current, index) => {
if (current.parentId === parent.id) {
const temp = JSON.parse(JSON.stringify(children))
temp.splice(index, 1)
translator([current], temp)
typeof parent.children !== 'undefined' ?
parent.children.push(current) :
(parent.children = [current])
}
})
})
}
translator(parent, children)
return parent
}
/**
* @description 树形结构数据转换成父子关系的数组
* @param data
* @returns {[]}
*/
export function translateTreeToData(data) {
const result = []
data.forEach((item) => {
const loop = (data) => {
result.push({
id: data.id,
name: data.name,
parentId: data.parentId,
})
const child = data.children
if (child) {
for (let i = 0; i < child.length; i++) {
loop(child[i])
}
}
}
loop(item)
})
return result
}
/**
* @description 10位时间戳转换年月日时分秒
* @param time
* @returns {string}
*/
export function tenBitTimestamp(time) {
const date = new Date(time * 1000)
const y = date.getFullYear()
let m = date.getMonth() + 1
m = m < 10 ? '' + m : m
let d = date.getDate()
d = d < 10 ? '' + d : d
let h = date.getHours()
h = h < 10 ? '0' + h : h
let minute = date.getMinutes()
let second = date.getSeconds()
minute = minute < 10 ? '0' + minute : minute
second = second < 10 ? '0' + second : second
return y + '年' + m + '月' + d + '日 ' + h + ':' + minute + ':' + second //组合
}
/**
* @description 10位时间戳转换时分秒
* @param time
* @returns {string}
*/
export function tenBitTimestampHms(time) {
const date = new Date(time * 1000)
let h = date.getHours()
h = h < 10 ? '0' + h : h
let minute = date.getMinutes()
let second = date.getSeconds()
minute = minute < 10 ? '0' + minute : minute
second = second < 10 ? '0' + second : second
return h + ':' + minute + ':' + second //组合
}
/**
* @description 13位时间戳转换
* @param time
* @returns {string}
*/
export function thirteenBitTimestamp(time) {
const date = new Date(time / 1)
const y = date.getFullYear()
let m = date.getMonth() + 1
m = m < 10 ? '' + m : m
let d = date.getDate()
d = d < 10 ? '' + d : d
let h = date.getHours()
h = h < 10 ? '0' + h : h
let minute = date.getMinutes()
let second = date.getSeconds()
minute = minute < 10 ? '0' + minute : minute
second = second < 10 ? '0' + second : second
return y + '年' + m + '月' + d + '日 ' + h + ':' + minute + ':' + second //组合
}
/**
* @description 获取随机id
* @param length
* @returns {string}
*/
export function uuid(length = 32) {
const num = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
let str = ''
for (let i = 0; i < length; i++) {
str += num.charAt(Math.floor(Math.random() * num.length))
}
return str
}
/**
* @description m到n的随机数
* @param m
* @param n
* @returns {number}
*/
export function random(m, n) {
return Math.floor(Math.random() * (m - n) + n)
}
/**
* @description addEventListener
* @type {function(...[*]=)}
*/
export const on = (function () {
return function (element, event, handler, useCapture = false) {
if (element && event && handler) {
element.addEventListener(event, handler, useCapture)
}
}
})()
/**
* @description removeEventListener
* @type {function(...[*]=)}
*/
export const off = (function () {
return function (element, event, handler, useCapture = false) {
if (element && event) {
element.removeEventListener(event, handler, useCapture)
}
}
})()
/**
* @description 数组打乱
* @param array
* @returns {*}
*/
export function shuffle(array) {
let m = array.length,
t,
i
while (m) {
i = Math.floor(Math.random() * m--)
t = array[m]
array[m] = array[i]
array[i] = t
}
return array
}
/**
* @description ele表格序号
* @param number
* @returns {string}
*/
export function indexMethod(index) {
return index + 1;
}
/**
* @description 获取当前时间并打印
* @param null
* @returns {string}
*/
export function getCurrentTime() {
var _this = this
let yy = new Date().getFullYear()
let mm = new Date().getMonth() + 1
let dd = new Date().getDate()
let hh = new Date().getHours()
let mf =
new Date().getMinutes() < 10 ?
'0' + new Date().getMinutes() :
new Date().getMinutes()
let ss =
new Date().getSeconds() < 10 ?
'0' + new Date().getSeconds() :
new Date().getSeconds()
return (_this.gettime =
yy + '-' + mm + '-' + dd + ' ' + hh + ':' + mf + ':' + ss)
}
/**
* @description 数组里对象根据某个值(包含姓名、字母、数字)排序
* @param null
* @returns {array}
*/
export function compare(data) {
let chineseChars = [],
chars = [],
list = [];
data.forEach(item => {
// 判断是否为中文
if (/^[\u4e00-\u9fa5]*$/.test(item.nickname.charAt(0))) {
chineseChars.push(item); // 姓名首字符为中文的
} else {
chars.push(item); // 姓名首字符非中文的(字母,数字)
}
});
chars.sort((a, b) => a.nickname.charCodeAt(0) - b.nickname.charCodeAt(0));
chineseChars.sort((a, b) => a.nickname.localeCompare(b.nickname));
list = chars.concat(chineseChars); // list为最终想要的数组
return list
}
// 防止多次点击,重复请求
import Vue from 'vue'
const preventReClick = Vue.directive('preventReClick', {
inserted: function (el, binding) {
el.addEventListener('click', () => {
if (!el.disabled) {
el.disabled = true
setTimeout(() => {
el.disabled = false
}, binding.value || 3000)
}
})
}
});
export default{ preventReClick }
Math.easeInOutQuad = function(t, b, c, d) {
t /= d / 2
if (t < 1) {
return c / 2 * t * t + b
}
t--
return -c / 2 * (t * (t - 2) - 1) + b
}
// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
var requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
})()
/**
* Because it's so fucking difficult to detect the scrolling element, just move them all
* @param {number} amount
*/
function move(amount) {
document.documentElement.scrollTop = amount
document.body.parentNode.scrollTop = amount
document.body.scrollTop = amount
}
function position() {
return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
}
/**
* @param {number} to
* @param {number} duration
* @param {Function} callback
*/
export function scrollTo(to, duration, callback) {
const start = position()
const change = to - start
const increment = 20
let currentTime = 0
duration = (typeof (duration) === 'undefined') ? 500 : duration
var animateScroll = function() {
// increment the time
currentTime += increment
// find the value with the quadratic in-out easing function
var val = Math.easeInOutQuad(currentTime, start, change, duration)
// move the document.body
move(val)
// do the animation unless its over
if (currentTime < duration) {
requestAnimFrame(animateScroll)
} else {
if (callback && typeof (callback) === 'function') {
// the animation is done so lets callback
callback()
}
}
}
animateScroll()
}
/**
* @description 判读是否为外链
* @param path
* @returns {boolean}
*/
export function isExternal(path) {
return /^(https?:|mailto:|tel:|\/\/)/.test(path)
}
/**
* @description 校验密码是否小于6位
* @param value
* @returns {boolean}
*/
export function isPassword(value) {
return value.length >= 6
}
/**
* @description 判断是否为数字
* @param value
* @returns {boolean}
*/
export function isNumber(value) {
const reg = /^[0-9]*$/
return reg.test(value)
}
/**
* @description 判断是否是名称
* @param value
* @returns {boolean}
*/
export function isName(value) {
const reg = /^[\u4e00-\u9fa5]+$/
return reg.test(value)
}
/**
* @description 判断是否为IP
* @param ip
* @returns {boolean}
*/
export function isIP(ip) {
const reg =
/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
return reg.test(ip)
}
/**
* @description 判断是否是传统网站
* @param url
* @returns {boolean}
*/
export function isUrl(url) {
const reg =
/^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
return reg.test(url)
}
/**
* @description 判断是否是小写字母
* @param value
* @returns {boolean}
*/
export function isLowerCase(value) {
const reg = /^[a-z]+$/
return reg.test(value)
}
/**
* @description 判断是否是大写字母
* @param value
* @returns {boolean}
*/
export function isUpperCase(value) {
const reg = /^[A-Z]+$/
return reg.test(value)
}
/**
* @description 判断是否是大写字母开头
* @param value
* @returns {boolean}
*/
export function isAlphabets(value) {
const reg = /^[A-Za-z]+$/
return reg.test(value)
}
/**
* @description 判断是否是字符串
* @param value
* @returns {boolean}
*/
export function isString(value) {
return typeof value === 'string' || value instanceof String
}
/**
* @description 判断是否是数组
* @param arg
*/
export function isArray(arg) {
if (typeof Array.isArray === 'undefined') {
return Object.prototype.toString.call(arg) === '[object Array]'
}
return Array.isArray(arg)
}
/**
* @description 判断是否是端口号
* @param value
* @returns {boolean}
*/
export function isPort(value) {
const reg =
/^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/
return reg.test(value)
}
/**
* @description 判断是否是手机号
* @param value
* @returns {boolean}
*/
export function isPhone(value) {
const reg = /^1\d{10}$/
return reg.test(value)
}
/**
* @description 判断是否是身份证号(第二代)
* @param value
* @returns {boolean}
*/
export function isIdCard(value) {
const reg =
/^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
return reg.test(value)
}
/**
* @description 判断是否是邮箱
* @param value
* @returns {boolean}
*/
export function isEmail(value) {
const reg = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
return reg.test(value)
}
/**
* @description 判断是否中文
* @param value
* @returns {boolean}
*/
export function isChina(value) {
const reg = /^[\u4E00-\u9FA5]{0,30}$/
return reg.test(value)
}
/**
* @description 判断是否为空
* @param value
* @returns {boolean}
*/
export function isBlank(value) {
return (
value === null ||
false ||
value === '' ||
value.trim() === '' ||
value.toLocaleLowerCase().trim() === 'null'
)
}
/**
* @description 判断是否为固话
* @param value
* @returns {boolean}
*/
export function isTel(value) {
const reg =
/^(400|800)([0-9\\-]{7,10})|(([0-9]{4}|[0-9]{3})([- ])?)?([0-9]{7,8})(([- 转])*([0-9]{1,4}))?$/
return reg.test(value)
}
/**
* @description 判断是否为数字且最多两位小数
* @param value
* @returns {boolean}
*/
export function isNum(value) {
const reg = /^\d+(\.\d{1,2})?$/
return reg.test(value)
}
/**
* @description 判断是否为json
* @param value
* @returns {boolean}
*/
export function isJson(value) {
if (typeof value === 'string') {
const obj = JSON.parse(value)
return !!(typeof obj === 'object' && obj)
}
return false
}