|
|
let base = {
|
|
|
isNull(p){
|
|
|
return p == '' || p == undefined || p == null || p == 'undefined' || p == 'null';
|
|
|
},
|
|
|
isPhone(val) {
|
|
|
return /^[1][3,4,5,6,7,8,9][0-9]{9}$/.test(val)
|
|
|
},
|
|
|
isDecimal(val) {
|
|
|
return /(^[\-0-9][0-9]*(.[0-9]+)?)$/.test(val)
|
|
|
},
|
|
|
isNumber(val) {
|
|
|
return /(^[\-0-9][0-9]*([0-9]+)?)$/.test(val)
|
|
|
},
|
|
|
isMail(val) {
|
|
|
return /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(val)
|
|
|
},
|
|
|
isUrl(url) {
|
|
|
return this.checkUrl(url)
|
|
|
},
|
|
|
checkUrl(url) {
|
|
|
// url= 协议://(ftp的登录信息)[IP|域名](:端口号)(/或?请求参数)
|
|
|
var strRegex =
|
|
|
'^((https|http|ftp)://)?' + // (https或http或ftp):// 可有可无
|
|
|
"(([\\w_!~*'()\\.&=+$%-]+: )?[\\w_!~*'()\\.&=+$%-]+@)?" + // ftp的user@ 可有可无
|
|
|
'(([0-9]{1,3}\\.){3}[0-9]{1,3}' + // IP形式的URL- 3位数字.3位数字.3位数字.3位数字
|
|
|
'|' + // 允许IP和DOMAIN(域名)
|
|
|
'(localhost)|' + // 匹配localhost
|
|
|
"([\\w_!~*'()-]+\\.)*" + // 域名- 至少一个[英文或数字_!~*\'()-]加上.
|
|
|
'\\w+\\.' + // 一级域名 -英文或数字 加上.
|
|
|
'[a-zA-Z]{1,6})' + // 顶级域名- 1-6位英文
|
|
|
'(:[0-9]{1,5})?' + // 端口- :80 ,1-5位数字
|
|
|
'((/?)|' + // url无参数结尾 - 斜杆或这没有
|
|
|
"(/[\\w_!~*'()\\.;?:@&=+$,%#-]+)+/?)$" // 请求参数结尾- 英文或数字和[]内的各种字符
|
|
|
var re = new RegExp(strRegex, 'i') // i不区分大小写
|
|
|
// 将url做uri转码后再匹配,解除请求参数中的中文和空字符影响
|
|
|
if (re.test(encodeURI(url))) {
|
|
|
return true
|
|
|
}
|
|
|
return false
|
|
|
},
|
|
|
matchUrlIp(url, ip) { // url使用是否使用的当前ip
|
|
|
if (!url || !ip) {
|
|
|
return false
|
|
|
}
|
|
|
return url.indexOf(ip.replace('https://', '').replace('http://', '')) >= 0
|
|
|
},
|
|
|
getImgSrc(src, httpUrl) {
|
|
|
if (this.isUrl(src)) {
|
|
|
return src
|
|
|
}
|
|
|
if (httpUrl) {
|
|
|
return httpUrl + src
|
|
|
}
|
|
|
return src
|
|
|
},
|
|
|
previewImg(src, httpUrl) { // 图片预览,目前只支持单图片预览
|
|
|
if (src && !this.isUrl(src) && httpUrl) {
|
|
|
if (src.substr(0, 1) == '/' && httpUrl.substr(httpUrl.length - 1, 1) == '/') {
|
|
|
src = src.substr(1)
|
|
|
}
|
|
|
src = (httpUrl + src)
|
|
|
}
|
|
|
let id = 'vol-preview'
|
|
|
let $div = document.getElementById(id)
|
|
|
if (!$div) {
|
|
|
$div = document.createElement('div')
|
|
|
$div.setAttribute('id', 'vol-preview')
|
|
|
let $mask = document.createElement('div')
|
|
|
$mask.style.position = 'absolute'
|
|
|
$mask.style.width = '100%'
|
|
|
$mask.style.height = '100%'
|
|
|
$mask.style.background = 'black'
|
|
|
$mask.style.opacity = '0.6'
|
|
|
$div.appendChild($mask)
|
|
|
$div.style.position = 'fixed'
|
|
|
$div.style.width = '100%'
|
|
|
$div.style.height = '100%'
|
|
|
// $div.style.overflow = "scroll";
|
|
|
$div.style.top = 0
|
|
|
$div.style['z-index'] = 9999999
|
|
|
let $img = document.createElement('img')
|
|
|
$img.setAttribute('class', 'vol-preview-img')
|
|
|
$img.style.position = 'absolute'
|
|
|
$img.style.top = '50%'
|
|
|
$img.style.left = '50%'
|
|
|
$img.style['max-width'] = '90%'
|
|
|
$img.style['max-height'] = '90%'
|
|
|
$img.style.transform = 'translate(-50%,-50%)'
|
|
|
// $img.src = src;
|
|
|
$img.setAttribute('src', src)
|
|
|
$div.appendChild($img)
|
|
|
$div.addEventListener('click', function() {
|
|
|
this.style.display = 'none'
|
|
|
})
|
|
|
document.body.appendChild($div)
|
|
|
return
|
|
|
}
|
|
|
let $img1 = document.body.appendChild($div).querySelector('.vol-preview-img')
|
|
|
// img.src = src;
|
|
|
$img1.setAttribute('src', src)
|
|
|
$div.style.display = 'block'
|
|
|
},
|
|
|
// 下载文件 $element 标签, url完整url, fileName 文件名, header 以key/value传值
|
|
|
// backGroundUrl 后台url,如果后台url直接从后台下载,其他全部通过点击a标签下载
|
|
|
dowloadFile(url, fileName, header, backGroundUrl) {
|
|
|
if (!url) return alert('此文件没有url不能下载')
|
|
|
if (!this.isUrl(url)) {
|
|
|
url = backGroundUrl + url
|
|
|
}
|
|
|
window.open(url)
|
|
|
|
|
|
// let $element = document.getElementById('dowonloadfile-a');
|
|
|
// if (!$element) {
|
|
|
// $element = document.createElement('a');
|
|
|
// $element.setAttribute("id", "dowonloadfile-a");
|
|
|
// document.body.append($element);
|
|
|
// }
|
|
|
// //url为一个完整的地址,并且不是后台api的地址,直接点击a标签下载
|
|
|
// // if (this.isUrl(url) && !this.matchUrlIp(url, backGroundUrl)) {
|
|
|
// // $element.href = url;
|
|
|
// // $element.click();
|
|
|
// // return;
|
|
|
// // }
|
|
|
|
|
|
// if (!this.isUrl(url)) {
|
|
|
// if (!this.isUrl(backGroundUrl + url)) {
|
|
|
// console.log("文件路径不正确");
|
|
|
// alert('文件路径不正确')
|
|
|
// return;
|
|
|
// }
|
|
|
// url = backGroundUrl + url;
|
|
|
// }
|
|
|
// $element.href = url;
|
|
|
// $element.click();
|
|
|
|
|
|
// //通过后台api服务器下载
|
|
|
// if (!this.isUrl(url)) {
|
|
|
// if (!this.isUrl(backGroundUrl + url)) {
|
|
|
// alert('当前下载的文件url【' + url + '】不正确')
|
|
|
// return;
|
|
|
// }
|
|
|
// url = backGroundUrl + url;
|
|
|
// }
|
|
|
// let xmlResquest = new XMLHttpRequest();
|
|
|
// xmlResquest.open("GET", url, true);
|
|
|
// xmlResquest.setRequestHeader("Content-type", "application/json");
|
|
|
// if (header && typeof header == 'object') {
|
|
|
// for (const key in header) {
|
|
|
// xmlResquest.setRequestHeader(
|
|
|
// key,
|
|
|
// header[key]
|
|
|
// );
|
|
|
// }
|
|
|
// }
|
|
|
|
|
|
// xmlResquest.responseType = "blob";
|
|
|
// xmlResquest.onload = function (oEvent) {
|
|
|
// if (xmlResquest.status != 200) {
|
|
|
// return alert('没有下载到此文件的信息')
|
|
|
// }
|
|
|
// let content = xmlResquest.response;
|
|
|
// $element.download = fileName;
|
|
|
// let blob = new Blob([content]);
|
|
|
// $element.href = URL.createObjectURL(blob);
|
|
|
// $element.click();
|
|
|
// };
|
|
|
// xmlResquest.send();
|
|
|
},
|
|
|
downloadImg(data) {
|
|
|
if (!data.url || !data.callback || typeof data.callback !== 'function') {
|
|
|
return
|
|
|
}
|
|
|
// url, backGroundUrl, header, callback
|
|
|
if (this.isUrl(data.url) && !this.matchUrlIp(data.url, data.backGroundUrl)) {
|
|
|
return data.url
|
|
|
}
|
|
|
// 通过后台api服务器下载
|
|
|
if (!this.isUrl(data.url)) {
|
|
|
if (!this.isUrl(data.backGroundUrl + data.url)) {
|
|
|
return
|
|
|
}
|
|
|
data.url = data.backGroundUrl + data.url
|
|
|
}
|
|
|
var xmlResquest = new XMLHttpRequest()
|
|
|
xmlResquest.open('get', data.url, true)
|
|
|
xmlResquest.responseType = 'blob'
|
|
|
xmlResquest.setRequestHeader('Content-Type', 'application/json')
|
|
|
if (data.header && typeof data.header === 'object') {
|
|
|
for (const key in data.header) {
|
|
|
xmlResquest.setRequestHeader(
|
|
|
key,
|
|
|
data.header[key]
|
|
|
)
|
|
|
}
|
|
|
}
|
|
|
xmlResquest.onload = function() {
|
|
|
if (this.status == 200) {
|
|
|
var blob = this.response
|
|
|
callback(window.URL.createObjectURL(blob))
|
|
|
}
|
|
|
}
|
|
|
xmlResquest.send()
|
|
|
},
|
|
|
// 2020.06.01增加通用方法,将普通对象转换为tree结构
|
|
|
// data数据格式[
|
|
|
// { name: 'tree1', id: 1, parentId: 0 },
|
|
|
// { name: 'tree2', id: 2, parentId: 0 }]
|
|
|
|
|
|
// 1、id与parentId这两个字段必须有
|
|
|
// 2、树形tree需要注意Id与parentId循环依赖的问题
|
|
|
// 3、callback每次生成一新的节点的时回调的方法
|
|
|
|
|
|
convertTree(data, callback) {
|
|
|
var treeIds = []
|
|
|
var root_data = []
|
|
|
data.forEach(x => {
|
|
|
if (!x.children) {
|
|
|
x.children = []
|
|
|
}
|
|
|
if (!x.hidden && x.id !== undefined && x.id !== x.parentId && !data.some(s => {
|
|
|
return x.parentId == s.id
|
|
|
})) {
|
|
|
x.isRoot = true
|
|
|
callback && callback(x, data, true, treeIds)
|
|
|
root_data.push(x)
|
|
|
getTree(x.id, x, data, callback, treeIds)
|
|
|
}
|
|
|
})
|
|
|
var exceptionNodes = data.filter(f => {
|
|
|
return treeIds.indexOf(f.id) == -1 && !f.hidden
|
|
|
})
|
|
|
|
|
|
root_data.push(...exceptionNodes)
|
|
|
return root_data
|
|
|
},
|
|
|
getTreeAllParent(id, data) { // 获取某个节点的所有父节点信息2020.11.01
|
|
|
var nodes = []
|
|
|
if (!(data instanceof Array)) {
|
|
|
return nodes
|
|
|
}
|
|
|
|
|
|
var _child = data.find(x => {
|
|
|
return x.id === id
|
|
|
})
|
|
|
if (!_child) {
|
|
|
return []
|
|
|
}
|
|
|
nodes.push(_child)
|
|
|
var _parentIds = [_child.parentId]
|
|
|
for (let index = 0; index < _parentIds.length; index++) {
|
|
|
var _node = data.find(x => {
|
|
|
return x.id === _parentIds[index] && x.id !== x.parentId
|
|
|
})
|
|
|
if (!_node) {
|
|
|
return nodes
|
|
|
}
|
|
|
_parentIds.push(_node.parentId)
|
|
|
nodes.unshift(_node)
|
|
|
}
|
|
|
return nodes
|
|
|
},
|
|
|
//深拷贝数据
|
|
|
deepCopy(data) {
|
|
|
//string,number,bool,null,undefined,symbol
|
|
|
//object,array,date
|
|
|
if (data && typeof data === "object") {
|
|
|
//针对函数的拷贝
|
|
|
if (typeof data === "function") {
|
|
|
let tempFunc = data.bind(null);
|
|
|
tempFunc.prototype = this.deepCopy(data.prototype);
|
|
|
return tempFunc;
|
|
|
}
|
|
|
|
|
|
switch (Object.prototype.toString.call(data)) {
|
|
|
case "[object String]":
|
|
|
return data.toString();
|
|
|
case "[object Number]":
|
|
|
return Number(data.toString());
|
|
|
case "[object Boolean]":
|
|
|
return Boolean(data.toString());
|
|
|
case "[object Date]":
|
|
|
return new Date(data.getTime());
|
|
|
case "[object Array]":
|
|
|
let arr = [];
|
|
|
for (let i = 0; i < data.length; i++) {
|
|
|
arr[i] = this.deepCopy(data[i]);
|
|
|
}
|
|
|
return arr;
|
|
|
|
|
|
//js自带对象或用户自定义类实例
|
|
|
case "[object Object]":
|
|
|
let obj = {};
|
|
|
for (let key in data) {
|
|
|
//会遍历原型链上的属性方法,可以用hasOwnProperty来控制 (obj.hasOwnProperty(prop)
|
|
|
obj[key] = this.deepCopy(data[key]);
|
|
|
}
|
|
|
return obj;
|
|
|
}
|
|
|
} else {
|
|
|
//string,number,bool,null,undefined,symbol
|
|
|
return data;
|
|
|
}
|
|
|
},
|
|
|
// 按顺序把接口返回值 赋给 form
|
|
|
requestToForm(requestObj, form) {
|
|
|
// 获取a对象中属性的顺序和值
|
|
|
let aKeys = Object.keys(form);
|
|
|
let aValues = aKeys.map(key => form[key]);
|
|
|
|
|
|
// 遍历b对象,将属性等于a中属性值的对象深拷贝给a中的相应属性
|
|
|
for (let i = 0; i < aKeys.length; i++) {
|
|
|
let key = aKeys[i];
|
|
|
let value = aValues[i];
|
|
|
if (requestObj[key] === value) {
|
|
|
// 深拷贝对象
|
|
|
Object.assign(form, {
|
|
|
[key]: this.deepCopy(requestObj[key])
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
// 遍历b对象,将b中独有的属性按照a的顺序插入到a中
|
|
|
for (let key in requestObj) {
|
|
|
if (!form[key]) {
|
|
|
// 深拷贝属性值
|
|
|
Object.assign(form, {
|
|
|
[key]: this.deepCopy(requestObj[key])
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
return form
|
|
|
},
|
|
|
// 根据pid 重组树形结构
|
|
|
buildTree(flatData) {
|
|
|
// 创建一个映射表,用于存储每个 id 对应的数据项
|
|
|
const idMap = {};
|
|
|
flatData.forEach(item => {
|
|
|
idMap[item.id] = item;
|
|
|
});
|
|
|
// 创建根节点集合
|
|
|
const rootNodes = [];
|
|
|
|
|
|
flatData.forEach(item => {
|
|
|
// 如果没有父节点,则将该项添加到根节点集合中
|
|
|
if (parseInt(item.pid) === 0) {
|
|
|
rootNodes.push(item);
|
|
|
} else {
|
|
|
// 否则,将该项添加到父节点的 children 数组中
|
|
|
if(idMap[item.pid]){
|
|
|
const parent = idMap[item.pid];
|
|
|
// console.log("par",parent)
|
|
|
if (!parent.hasOwnProperty('children')) {
|
|
|
parent.children = [];
|
|
|
}
|
|
|
parent.children.push(item);
|
|
|
}else{
|
|
|
rootNodes.push(item);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
});
|
|
|
return rootNodes;
|
|
|
},
|
|
|
findNodesById(nodes, targetId) {
|
|
|
let result = [];
|
|
|
|
|
|
// 遍历每个节点
|
|
|
nodes.forEach(node => {
|
|
|
// 如果当前节点的ID匹配,添加到结果数组
|
|
|
if (node.id == targetId) {
|
|
|
result.push(node);
|
|
|
}
|
|
|
// 如果节点有子节点,递归查找
|
|
|
if (node.children && node.children.length > 0) {
|
|
|
const childNodes = this.findNodesById(node.children, targetId);
|
|
|
result = result.concat(childNodes);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
export default base
|
|
|
|
|
|
// 2020.06.01增加通用方法,将普通对象转换为tree结构
|
|
|
function getTree(id, node, data, callback, treeIds) {
|
|
|
if (treeIds.indexOf(id) == -1) {
|
|
|
treeIds.push(id)
|
|
|
}
|
|
|
data.forEach(x => {
|
|
|
if (!x.hidden && x.parentId == id) {
|
|
|
if (!node.children) node.children = []
|
|
|
callback && callback(x, node, false)
|
|
|
node.children.push(x)
|
|
|
getTree(x.id, x, data, callback, treeIds)
|
|
|
}
|
|
|
})
|
|
|
}
|