ed-frame-vue
Version:
easydata 基础组件
589 lines (531 loc) • 14.7 kB
JavaScript
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] : ''
}