import Vue from 'vue' // 下载,导出 Vue.prototype.$download = function (name, href) { var a = document.createElement('a') // 创建a标签 var e = document.createEvent('MouseEvents') // 创建鼠标事件对象 e.initEvent('click', false, false) // 初始化事件对象 a.href = href // 设置下载地址 a.download = name // 设置下载文件名 a.dispatchEvent(e) // 给指定的元素,执行事件click事件 } // 导出json文件 Vue.prototype.$downloadJson = function (data, name) { // 1 生成文件的 blob 对象 const blobData = new Blob([JSON.stringify(data)], { type: 'application/octet-stream' }) // 2 手动生成文件的 url const url = window.URL.createObjectURL(blobData) // 3 创建 a 标签,模拟点击事件 const link = document.createElement('a') link.href = url // 3.1 重命名下载文件名称 link.download = `${name}.json` document.body.appendChild(link) const evt = document.createEvent('MouseEvents') evt.initEvent('click', false, false) link.dispatchEvent(evt) document.body.removeChild(link) } const validConfig = [ { validKey: 'idcard', validRule: /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/, message: '请输入正确的身份证号码' }, { validKey: 'email', validRule: /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/, message: '请输入正确的邮箱' }, { validKey: 'phoneNumber', validRule: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码' } ] // 校验手机号 const checkTel = (rule, value, callback) => { const phoneReg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/ const rel = /^[0]\d{2,3}-[1-9]\d{7}$/ // if (!value) return callback(new Error("请输入联系电话")); setTimeout(() => { if (value && !(phoneReg.test(value) || rel.test(value))) { callback(new Error('请输入正确的联系电话')) } else callback() }, 500) } // 检验系统代码 const checkCode = (rule, value, callback) => { const rel = /^[0-9A-Z]+$/ if (!value) return callback(new Error('请输入代码')) setTimeout(() => { if (value && !rel.test(value)) { callback(new Error('只能为大写字母和数字')) } else callback() }, 500) } // 校验 idcard身份证号码 email邮箱 phoneNumber手机号码 // Vue.prototype.$validator = function(validName) { // const findValidConfig = _.find(validConfig, function(v) { // return v.validKey === validName // }) // return validMethods // function validMethods(rule, value, callback) { // if (value) { // findValidConfig.validRule.test(value) // ? callback() // : callback(findValidConfig.message) // } else { // callback() // } // } // } // 日期格式转换 "yyyy-MM-dd HH:mm:ss" Vue.prototype.$formdate = function (date) { if (!date) { return "" } var d = new Date(date); var YY = d.getFullYear() + '-'; var MM = (d.getMonth() + 1 < 10 ? '0' + (d.getMonth() + 1) : d.getMonth() + 1) + '-'; var DD = (d.getDate() < 10 ? '0' + (d.getDate()) : d.getDate()); var hh = (d.getHours() < 10 ? '0' + d.getHours() : d.getHours()) + ':'; var mm = (d.getMinutes() < 10 ? '0' + d.getMinutes() : d.getMinutes()) + ':'; var ss = (d.getSeconds() < 10 ? '0' + d.getSeconds() : d.getSeconds()); return YY + MM + DD + " " + hh + mm + ss } // 时间格式过滤 Vue.filter('timeFilter', function (timeStr) { if (timeStr) { return timeStr.substring(0, 10) } }) export function getType (o) { return Object.prototype.toString.call(o).slice(8, -1) } export function isKeyType (o, type) { return getType(o).toLowerCase() === type.toLowerCase() } // 深拷贝全局挂载 Vue.prototype.$deepCopy = function (sth) { // 深度复制数组 // if (Object.prototype.toString.call(obj) === "[object Array]") { // const object = []; // for (let i = 0; i < obj.length; i++) { // object.push(this.$deepCopy(obj[i])); // } // return object; // } // 深度复制对象 // if (Object.prototype.toString.call(obj) === "[object Object]") { // const object = {}; // for (let p in obj) { // object[p] = obj[p]; // } // return object; // } let copy if (sth === null || typeof sth !== 'object') return sth if (isKeyType(sth, 'date')) { copy = new Date() copy.setTime(sth.getTime()) return copy } if (isKeyType(sth, 'array')) { copy = [] for (let i = 0, len = sth.length; i < len; i++) { copy[i] = Vue.prototype.$deepCopy(sth[i]) } return copy } if (isKeyType(sth, 'object')) { copy = {} for (const attr in sth) { if (sth.hasOwnProperty(attr)) { copy[attr] = Vue.prototype.$deepCopy(sth[attr]) } } return copy } return null } // 递归处理树形数据children为空数组 Vue.prototype.$dealArrChildren = arr => { if (arr.length) { for (const i in arr) { if (arr[i].children && arr[i].children.length) { Vue.prototype.$dealArrChildren(arr[i].children) } else { arr[i].children = null } } } return arr } // 过滤对象中为空的属性 Vue.prototype.$filterNullObj = obj => { if (!(typeof obj === 'object')) { return } for (var key in obj) { if ( obj.hasOwnProperty(key) && (obj[key] === null || obj[key] === undefined || obj[key] === '') ) { delete obj[key] } } return obj } // 递归处理树形数据可选择项 Vue.prototype.$dealArrNotDisabled = arr => { if (arr.length) { for (const i in arr) { if (arr[i].disabled) { delete arr[i].disabled if (arr[i].children) { nodeDeal(arr[i].children) } // return false } if (arr[i].children) { Vue.prototype.$dealArrNotDisabled(arr[i].children) } } } function nodeDeal (arr) { arr.forEach(item => { delete item.disabled if (item.children) { nodeDeal(item.children) } }) } return arr } // 递归处理树形数据不可选择项 Vue.prototype.$dealArrDisabled = (arr, id) => { if (arr.length) { for (const i in arr) { if (arr[i].id === id) { arr[i]['disabled'] = true if (arr[i].children) { nodeDeal(arr[i].children) } // return false } if (arr[i].children) { Vue.prototype.$dealArrDisabled(arr[i].children, id) } } } function nodeDeal (arr) { arr.forEach(item => { item['disabled'] = true if (item.children) { nodeDeal(item.children) } }) } return arr } // 根据子节点id递归获取子节点路径id数组 Vue.prototype.$getNodeRoute = (val, id) => { let cid_list = [] val.forEach((item, index) => { if (item.id === id) { cid_list = [item.id] return false } else { if (item.children) { const newCid_list = [item.id] const list = nodefun(item.children, id, newCid_list) if (list) { cid_list = list } } } }) function nodefun (newVal, newId, newCid_list) { let flag = false newVal.forEach(j => { if (j.id === newId) { newCid_list.push(j.id) flag = true } else { if (j.children) { const cid_list = JSON.parse(JSON.stringify(newCid_list)) cid_list.push(j.id) const list = nodefun(j.children, newId, cid_list) if (list) { newCid_list = list flag = true } } } }) if (flag) { return newCid_list } } function result (cid_list) { const arr = cid_list.concat() arr.pop() return arr } return result(cid_list) } // 扁平化树形数组 Vue.prototype.$treeConvertToArr = tree => { let arrs = [] const result = [] arrs = arrs.concat(tree) while (arrs.length) { const first = arrs.shift() if (first.children) { // 如果有children arrs = arrs.concat(first.children) delete first['children'] } result.push(first) } return result } /** * 递归获取树形数组的所有父节点 * @param {*} list 树形数组 * @param {*} id 当前子节点判断条件parentId * @returns */ Vue.prototype.$findParent = (list, id) => { for (const i in list) { if (list[i].id === id) { return [list[i]] } if (list[i].children) { const node = Vue.prototype.$findParent(list[i].children, id) if (node !== undefined) { return node.concat(list[i]) } } } } /** * 递归获取树形数组当前点击节点的子节点 * @param {*} list 树形数组 * @param {*} nodeId 当前点击id * @returns */ Vue.prototype.$findChildren = (list, nodeId) => { let newArray = [] let flag = false function dealList (list, nodeId) { if (list.length !== 0) { list.forEach(item => { if (!flag) { if (item.id === nodeId) { flag = true newArray = item.children } else if (item.children !== null) { newArray = dealList(item.children, nodeId) } } }) } return newArray } return dealList(list, nodeId) } /** * 给子节点添加属性 * @param {*} list 树形数组 * @param {*} findIndex 操作符第几项 * @param {*} flag 属性状态 * @returns */ Vue.prototype.$setChildren = (arr, findIndex, flag) => { if (arr.length) { for (let i = 0; i < arr.length; i++) { if (arr[i].children && arr[i].children.length) { arr[i].checkArr[findIndex].value = flag Vue.prototype.$setChildren(arr[i].children, findIndex, flag) } else { arr[i].checkArr[findIndex].value = flag } } } return arr } /** * 根据情况联动checkout * @param {*} arr 数组 * @param {*} id 当前点击的id * @param {*} checkId 操作符类型 * @param {*} flag 选中状态 * @param {*} items 当前点击子节点同级节点 * @param {*} parentList 父级菜单 * @param {*} childList 子级菜单 */ Vue.prototype.$setChildArr = ( arr, id, checkId, flag, items, parentList, childList ) => { if (arr.length) { for (const i in arr) { if (arr[i].id === id) { const wholeArr = Vue.prototype.$deepCopy(items) const treeConvertArr = Vue.prototype.$treeConvertToArr(wholeArr) if (arr[i].children && arr[i].children.length !== 0) { // 勾选父级子级全部勾选 取消父级子级全部取消 // for (let j = 0; j < arr[i].children.length; j++) { // let findIndex = arr[i].children[j].checkArr.findIndex((item) => item.id === checkId); // arr[i].children[j].checkArr[findIndex].value = flag // } const findIndex = arr[i].checkArr.findIndex( item => item.id === checkId ) Vue.prototype.$setChildren(childList, findIndex, flag) } if (flag === true && parentList !== undefined) { // 子级若有一个选中,则父级选中 const isFlagCheck = treeConvertArr.some(val => { const checkIndex = val.checkArr.findIndex( item => item.id === checkId ) return val.checkArr[checkIndex].value === true }) if (isFlagCheck === true) { parentList.forEach(parent => { const checkIndex = parent.checkArr.findIndex( item => item.id === checkId ) parent.checkArr[checkIndex].value = true }) } } else if (flag === false && parentList !== undefined) { // 子级若都没选中,则父级不选中 const isFlagFalse = treeConvertArr.every(val => { const checkIndex = val.checkArr.findIndex( item => item.id === checkId ) return val.checkArr[checkIndex].value === false }) if (isFlagFalse === true) { parentList.forEach(parent => { const checkIndex = parent.checkArr.findIndex( item => item.id === checkId ) parent.checkArr[checkIndex].value = false }) } } } if (arr[i].children && arr[i].children.length !== 0) { Vue.prototype.$setChildArr( arr[i].children, id, checkId, flag, items, parentList, childList ) } } } } // 处理localStorage获取值转换boolean为string问题 json字符串转为json Vue.prototype.$getLocalStorage = (name, type) => { let data = localStorage.getItem(name) if (type === 'boolean') { if (data === 'false') { data = false } else { data = true } return data } if (type === 'object') { data = JSON.parse(data) return data } return data } export default { checkTel, checkCode }