UNPKG

ed-frame-vue

Version:

easydata 基础组件

589 lines (531 loc) 14.7 kB
import md5 from 'md5' import Vue from "vue"; const Event = new Vue(); // Event.$emit(事件名,数据); // 使用 $emit 来传递 // Event.$on(事件名,data => {}); // 使用 $on 来接收 /** * @name setBusEvent * @param event * @param value * @description 设置bus总线,记录数据 */ export function setBusEvent(event, value) { try { Event.$emit(event, value) } catch (e) { console.log(e) } } /** * @name getBusEvent * @returns {Promise<unknown>} * @description 获取bus数据 * @param key */ export function getBusEvent(key) { return new Promise((resolve, reject) => { try { console.log(key) Event.$on(key, data => { console.log(key, data) resolve(data) }) } catch (e) { console.log(e) reject(e) } }) } /** * 获取变量数据类型,包括ES6 新类型Symbol * @param n * @returns {string} */ export function getVarType(n) { const typeStr = Object.prototype.toString.call(n); let typeName = ''; switch (typeStr) { case '[object String]': typeName = 'string'; break; case '[object Number]': typeName = 'number'; break; case '[object Boolean]': typeName = 'boolean'; break; case '[object Undefined]': typeName = 'undefined'; break; case '[object Object]': typeName = 'object'; break; case '[object Array]': typeName = 'array'; break; case '[object Null]': typeName = 'null'; break; case '[object RegExp]': typeName = 'RegExp'; break; case '[object Symbol]': typeName = 'symbol'; break; case '[object JSON]': typeName = 'json'; break; case '[object Math]': typeName = 'math'; break; default: typeName = 'object'; } return typeName; } /** * 随机生成数字 * 示例:生成长度为 12 的随机数:randomNumber(12) * 示例:生成 3~23 之间的随机数:randomNumber(3, 23) * * @param1 最小值 | 长度 * @param2 最大值 * @return int 生成后的数字 */ export function randomNumber() { // 生成 最小值 到 最大值 区间的随机数 const random = (min, max) => { return Math.floor(Math.random() * (max - min + 1) + min) } if (arguments.length === 1) { let [length] = arguments // 生成指定长度的随机数字,首位一定不是 0 let nums = [...Array(length).keys()].map((i) => (i > 0 ? random(0, 9) : random(1, 9))) return parseInt(nums.join('')) } else if (arguments.length >= 2) { let [min, max] = arguments return random(min, max) } else { return Number.NaN } } /** * 随机生成字符串 * @param length 字符串的长度 * @param chats 可选字符串区间(只会生成传入的字符串中的字符) * @return string 生成的字符串 */ export function randomString(length, chats) { if (!length) length = 1 if (!chats) chats = '0123456789qwertyuioplkjhgfdsazxcvbnm' let str = '' for (let i = 0; i < length; i++) { let num = randomNumber(0, chats.length - 1) str += chats[num] } return str } /** * 随机生成uuid * @name randomUUID * @return string 生成的uuid */ export function randomUUID() { let chats = '0123456789abcdef' return randomString(32, chats) } export function getLength(object) { let count = 0; for (let i in object) count++; return count; } export function CompareObj(objA, objB, flag) { for (let key in objA) { if (!flag) //跳出整个循环 break; if (!objB.hasOwnProperty(key)) { flag = false; break; } if (getVarType(objA[key]) !== 'array') { //子级不是数组时,比较属性值 if (objB[key] != objA[key]) { flag = false; break; } } else { if (getVarType(objA[key]) !== 'array') { flag = false; break; } let oA = objA[key], oB = objB[key]; if (oA.length != oB.length) { flag = false; break; } for (let k in oA) { if (!flag) //这里跳出循环是为了不让递归继续 break; flag = CompareObj(oA[k], oB[k], flag); } } } return flag; } export function Compare(objA, objB) { if (getVarType(objA) !== 'object' || getVarType(objB) !== 'object') return false; //判断类型是否正确 if (getLength(objA) !== getLength(objB)) return false; //判断长度是否一致 return CompareObj(objA, objB, true); //默认为true } export function underlineToHumpJson(json) { if (json) { let result = {} Object.keys(json).forEach((key) => { result[underlineToHump(key)] = json[key] }) return result } return json } export function underlineToHump(s) { if (s.indexOf("_") > 0) { let a = s.split("_"); let result = a[0]; for (let i = 1; i < a.length; i++) { result = result + a[i].slice(0, 1).toUpperCase() + a[i].slice(1); } return result } else { return s } } export function humpToUnderline(str) { return str.replace(/([A-Z])/g, "_$1").toLowerCase() } /** * 加签 * @param params */ export function sign(params) { if (params) { let signArray = '' for (let param in params) { if (param === 'page' || param === 'createTime' || param === 'updateTime' || param === 'keyInfoObject' || param === 'dataInfoArray') { continue } let value = params[param] if (value != null) { value = JSON.stringify(value) value = value.replace(/{/g, "") value = value.replace(/}/g, "") value = value.replace("[", "") value = value.replace(/,/g, "") value = value.replace("]", "") value = value.replace(/,/g, "") value = value.replace(/['"]+/g, "") if (value != null && value !== '') { signArray += value } } } params.signature = md5(quick_sort(signArray).join("")) } return params } export function quick_sort(arr) { var arry1, arry2, mid; if (arr.length < 2) return arr; else if (arr.length === 2) if (arr[0] > arr[1]) return arr.reverse(); else return arr; else { arry1 = []; arry2 = []; mid = arr[0]; for (var i = 1; i < arr.length; i++) { if (arr[i] < mid) arry1.push(arr[i]); else arry2.push(arr[i]); } } return (quick_sort(arry1).concat(mid, quick_sort(arry2))); } /** * @param {*} url 文件下载地址 * @param {*} name 文件名称 */ export const downloadFile = async ({url, name}) => { let urlBlob = await urlToBlob(url) let link = document.createElement('a'); if (link.download !== undefined) { let uri = URL.createObjectURL(urlBlob); link.setAttribute('href', uri); link.setAttribute('download', name); link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } } // url 转bolb function urlToBlob(the_url) { return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest(); xhr.open('get', the_url, true); xhr.responseType = 'blob'; xhr.onload = (res) => { if (res.target.status === 200) { resolve(res.target.response); } else { reject(res) } }; xhr.send(); }) } /** * 初始化数据源控件 * @return {Object|Array} * @param record */ export function convertToViewModelOld(record) { if (record instanceof Array) { let newRecords = [] record.map((r) => newRecords.push(initViewModelRecord(r))) return newRecords } else { return initViewModelRecord(record) } } /** * 初始化数据源控件 * @return {Object|Array} * @param record 代转换对象 * @param deleteVirtualJson 是否删除虚拟列映射的前端json 包括:keyInfoObject、keyInfoView、dataInfoView * @param deleteVirtual 是否删除虚拟列属性,即只要viewModel对象需要的属性 */ export function convertToViewModel(record, deleteVirtual = false, deleteVirtualJson = false) { if (record instanceof Array) { let newRecords = [] record.map((r) => { newRecords.push(initViewModelRecord(r, deleteVirtual, deleteVirtualJson)) }) return newRecords } else { return initViewModelRecord(record, deleteVirtual, deleteVirtualJson) } } /** * @name initViewModelRecord * @param record * @return {*} */ function initViewModelRecord(record, deleteVirtual = false, deleteVirtualJson = false) { let newRecord = Object.assign({}, record) if(deleteVirtual) { let {id, dataSourceName, createTime, updateTime, keyInfo, dataInfo, deleted, tenantId, updater, creator, orgId, orgCode} = record newRecord = { id, dataSourceName, createTime, updateTime, keyInfo, dataInfo, deleted, tenantId, updater, creator, orgId, orgCode } } if(deleteVirtualJson) { delete newRecord.keyInfoObject delete newRecord.keyInfoView delete newRecord.dataInfoView } if (newRecord.keyInfo) { if (typeof newRecord.keyInfo == 'string') { newRecord.keyInfo = JSON.parse(newRecord.keyInfo) } newRecord.key = Object.assign(newRecord.keyInfo) newRecord.keyInfo = '' } if (newRecord.dataInfo) { if (typeof newRecord.dataInfo == 'string') { newRecord.dataInfo = JSON.parse(newRecord.dataInfo) } newRecord.data = Object.assign(newRecord.dataInfo) newRecord.dataInfo = '' } return newRecord } /** * 初始化数据源控件 * @return Control * @param record */ export function convertToModel(record) { let newRecord = Object.assign({}, record) if (newRecord.keyInfo) { if (typeof newRecord.keyInfo == 'string') { newRecord.keyInfo = JSON.parse(newRecord.keyInfo) } } if (newRecord.dataInfo) { if (typeof newRecord.dataInfo == 'string') { newRecord.dataInfo = JSON.parse(newRecord.dataInfo) } } return newRecord } /** * @name equal * @param a * @param b * @return {boolean} * @description ES6 Map、Set和Typed阵列支持的最快深度对等。 */ export function equal(a, b) { if (a === b) return true; if (a && b && typeof a == 'object' && typeof b == 'object') { if (a.constructor !== b.constructor) return false; let length, i, keys; if (Array.isArray(a)) { length = a.length; if (length != b.length) return false; for (i = length; i-- !== 0;) if (!equal(a[i], b[i])) return false; return true; } if ((a instanceof Map) && (b instanceof Map)) { if (a.size !== b.size) return false; for (i of a.entries()) if (!b.has(i[0])) return false; for (i of a.entries()) if (!equal(i[1], b.get(i[0]))) return false; return true; } if ((a instanceof Set) && (b instanceof Set)) { if (a.size !== b.size) return false; for (i of a.entries()) if (!b.has(i[0])) return false; return true; } if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { length = a.length; if (length !== b.length) return false; for (i = length; i-- !== 0;) if (a[i] !== b[i]) return false; return true; } if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); keys = Object.keys(a); length = keys.length; if (length !== Object.keys(b).length) return false; for (i = length; i-- !== 0;) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; for (i = length; i-- !== 0;) { let key = keys[i]; if (!equal(a[key], b[key])) return false; } return true; } // true if both NaN, false otherwise return a!==a && b!==b; } // 深度克隆 export function deepClone(obj) { // 对常见的“非”值,直接返回原来值 if ([null, undefined, NaN, false].includes(obj)) return obj if (typeof obj !== 'object' && typeof obj !== 'function') { // 原始类型直接返回 return obj } const o = getVarType(obj) === 'array' ? [] : {} for (const i in obj) { if (obj.hasOwnProperty(i)) { o[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i] } } return o } // JS对象深度合并 export function deepMerge(target = {}, source = {}) { target = deepClone(target) if (typeof target !== 'object' || typeof source !== 'object') return false for (const prop in source) { if (!source.hasOwnProperty(prop)) continue if (prop in target) { if (typeof target[prop] !== 'object') { target[prop] = source[prop] } else if (typeof source[prop] !== 'object') { target[prop] = source[prop] } else if (target[prop].concat && source[prop].concat) { target[prop] = target[prop].concat(source[prop]) } else { target[prop] = deepMerge(target[prop], source[prop]) } } else { target[prop] = source[prop] } } return target } /** * @name getVarType * @param jsonData * @param pathArr * @returns {*} * @description 获取json值, 可使用prototype */ export function getValueByKey(jsonData, pathArr){ if(pathArr.includes('.')){ let keyArr = pathArr.split('.') let value = jsonData for (const i in keyArr) { value = jsonData[keyArr[i]] } return value } else { return jsonData[pathArr] } } /** * 判断元素是否是 VNode对象 * @param _this * @param node * @return {boolean} */ export function isVNode(_this, node){ // 获取 vnode 实例 const vnode = _this.$createElement('span', '') // VNode 构造函数 const VNode = vnode.constructor; // 所以通过 obj instanceof VNode 即可判断 return node instanceof VNode } /** * 获取字段名 * getPath('key.name') ==> "name" * @param string * @return {*|string} */ export function getPath(string) { /** Used to match property names within property paths. */ const rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; /** Used to match backslashes in property paths. */ const reEscapeChar = /\\(\\)?/g; /** * Converts `string` to a property path array. * * @private * @param {string} string The string to convert. * @returns {Array} Returns the property path array. */ const result = []; if (string.charCodeAt(0) === 46 /* . */) { result.push(''); } string.replace(rePropName, function (match, number, quote, subString) { result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); }); return result.length !== 0 ? result[result.length - 1] : '' }