mirror of
https://gitee.com/orangeform/orange-admin.git
synced 2026-01-18 19:16:37 +08:00
commit:升级到vue3,更新最近工作流技术栈,支持sa-token
This commit is contained in:
664
OrangeFormsOpen-VUE3/src/common/utils/index.ts
Normal file
664
OrangeFormsOpen-VUE3/src/common/utils/index.ts
Normal file
@@ -0,0 +1,664 @@
|
||||
import { JSEncrypt } from 'jsencrypt';
|
||||
import dayjs from 'dayjs';
|
||||
import { ANY_OBJECT } from '@/types/generic';
|
||||
|
||||
/**
|
||||
* 列表数据转换树形数据
|
||||
* @param {Array} data 要转换的列表
|
||||
* @param {String} id 主键字段字段名
|
||||
* @param {String} pid 父字段字段名
|
||||
* @returns {Array} 转换后的树数据
|
||||
*/
|
||||
export function treeDataTranslate<D>(data: Array<D>, id = 'id', pid = 'parentId'): D[] {
|
||||
const res: D[] = [];
|
||||
const temp: ANY_OBJECT = {};
|
||||
const dataList: ANY_OBJECT[] = data.map(item => {
|
||||
return { ...item } as ANY_OBJECT;
|
||||
});
|
||||
for (let i = 0; i < dataList.length; i++) {
|
||||
const d = dataList[i];
|
||||
if (d) {
|
||||
temp[d[id]] = dataList[i];
|
||||
}
|
||||
}
|
||||
for (let k = 0; k < dataList.length; k++) {
|
||||
const d = dataList[k];
|
||||
if (d) {
|
||||
if (temp[d[pid]] && d[id] !== d[pid]) {
|
||||
if (!temp[d[pid]]['children']) {
|
||||
temp[d[pid]]['children'] = [];
|
||||
}
|
||||
if (!temp[d[pid]]['_level']) {
|
||||
temp[d[pid]]['_level'] = 1;
|
||||
}
|
||||
d['_level'] = temp[d[pid]]._level + 1;
|
||||
d['_parent'] = d[pid];
|
||||
temp[d[pid]]['children'].push(d);
|
||||
} else {
|
||||
res.push(d as D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* 获取字符串字节长度(中文算2个字符)
|
||||
* @param {String} str 要获取长度的字符串
|
||||
*/
|
||||
export function getStringLength(str: string) {
|
||||
return str.replace(/[\u4e00-\u9fa5\uff00-\uffff]/g, '**').length;
|
||||
}
|
||||
/**
|
||||
* 获取uuid
|
||||
*/
|
||||
export function getUUID(): string {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
||||
const random: number = Math.random() * 16;
|
||||
return (c === 'x' ? random : (random & 0x3) | 0x8).toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
export function stringCase(str: string, type: number) {
|
||||
if (str == null || str === '') return str;
|
||||
if (type === 0) {
|
||||
// 首字母小写
|
||||
return str.slice(0, 1).toLowerCase() + str.slice(1);
|
||||
} else {
|
||||
// 首字母大写
|
||||
return str.slice(0, 1).toUpperCase() + str.slice(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 大小驼峰变换函数
|
||||
* @param name 要转换的字符串
|
||||
* @param type 转换的类型0:转换成小驼峰,1:转换成大驼峰
|
||||
*/
|
||||
export function nameTranslate(name: string, type: 0 | 1) {
|
||||
name = name.toLowerCase();
|
||||
let nameArray = name.split('_');
|
||||
nameArray.forEach((item, index) => {
|
||||
if (index === 0) {
|
||||
name = type === 1 ? item.slice(0, 1).toUpperCase() + item.slice(1) : item;
|
||||
} else {
|
||||
name = name + item.slice(0, 1).toUpperCase() + item.slice(1);
|
||||
}
|
||||
});
|
||||
|
||||
nameArray = name.split('-');
|
||||
nameArray.forEach((item, index) => {
|
||||
if (index === 0) {
|
||||
name = type === 1 ? item.slice(0, 1).toUpperCase() + item.slice(1) : item;
|
||||
} else {
|
||||
name = name + item.slice(0, 1).toUpperCase() + item.slice(1);
|
||||
}
|
||||
});
|
||||
return name;
|
||||
}
|
||||
/**
|
||||
* 通过id从树中获取指定的节点
|
||||
* @param {Object} node 根节点
|
||||
* @param {String|Nubmer} id 键值
|
||||
* @param {Array} list 保存查询路径
|
||||
* @param {String} idKey 主键字段名
|
||||
* @param {String} childKey 子节点字段名
|
||||
*/
|
||||
function findNode(
|
||||
node: ANY_OBJECT,
|
||||
id: string | number | undefined,
|
||||
list?: Array<ANY_OBJECT> | undefined,
|
||||
idKey = 'id',
|
||||
childKey = 'children',
|
||||
): ANY_OBJECT | undefined {
|
||||
if (Array.isArray(list)) list.push(node);
|
||||
if (node[idKey] === id) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (node[childKey] != null && Array.isArray(node[childKey])) {
|
||||
for (let i = 0; i < node[childKey].length; i++) {
|
||||
const tempNode: ANY_OBJECT | undefined = findNode(
|
||||
node[childKey][i],
|
||||
id,
|
||||
list,
|
||||
idKey,
|
||||
childKey,
|
||||
);
|
||||
if (tempNode) return tempNode;
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(list)) list.pop();
|
||||
}
|
||||
/**
|
||||
* 通过id返回从根节点到指定节点的路径
|
||||
* @param {Array} treeRoot 树根节点数组
|
||||
* @param {*} id 要查询的节点的id
|
||||
* @param {*} idKey 主键字段名
|
||||
* @param {*} childKey 子节点字段名
|
||||
*/
|
||||
export function findTreeNodeObjectPath(
|
||||
treeRoot: ANY_OBJECT,
|
||||
id: string | number | undefined,
|
||||
idKey = 'id',
|
||||
childKey = 'children',
|
||||
) {
|
||||
const tempList: ANY_OBJECT[] = [];
|
||||
for (let i = 0; i < treeRoot.length; i++) {
|
||||
if (findNode(treeRoot[i], id, tempList, idKey, childKey)) {
|
||||
return tempList;
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
export function findTreeNodePath<D>(
|
||||
treeRoot: Array<D>,
|
||||
id: string | number | undefined,
|
||||
idKey = 'id',
|
||||
childKey = 'children',
|
||||
): Array<string | number> {
|
||||
return (findTreeNodeObjectPath(treeRoot, id, idKey, childKey) || []).map(item => item[idKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id从树中查找节点
|
||||
* @param {Array} treeRoot 根节点数组
|
||||
* @param {*} id 要查找的节点的id
|
||||
* @param {*} idKey 主键字段名
|
||||
* @param {*} childKey 子节点字段名
|
||||
*/
|
||||
export function findTreeNode(
|
||||
treeRoot: ANY_OBJECT,
|
||||
id: string,
|
||||
idKey = 'id',
|
||||
childKey = 'children',
|
||||
) {
|
||||
for (let i = 0; i < treeRoot.length; i++) {
|
||||
const tempNode = findNode(treeRoot[i], id, undefined, idKey, childKey);
|
||||
if (tempNode) return tempNode;
|
||||
}
|
||||
}
|
||||
|
||||
export function traverseTree(
|
||||
root: ANY_OBJECT,
|
||||
callback: (node: ANY_OBJECT) => void,
|
||||
childKey = 'children',
|
||||
) {
|
||||
function traverseNode(node: ANY_OBJECT) {
|
||||
if (typeof callback === 'function') callback(node);
|
||||
if (Array.isArray(node[childKey])) {
|
||||
node[childKey].forEach((suNode: ANY_OBJECT) => {
|
||||
traverseNode(suNode);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (Array.isArray(root)) {
|
||||
root.forEach(node => {
|
||||
traverseNode(node);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 把Object转换成query字符串
|
||||
* @param {Object} params 要转换的Object
|
||||
*/
|
||||
export function objectToQueryString(params: ANY_OBJECT | null) {
|
||||
if (params == null) {
|
||||
return null;
|
||||
} else {
|
||||
return Object.keys(params)
|
||||
.map(key => {
|
||||
if (params[key] !== undefined) {
|
||||
return `${key}=${params[key]}`;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
})
|
||||
.filter(item => item != null)
|
||||
.join('&');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 从数组中查找某一项
|
||||
* @param {Array} list 要查找的数组
|
||||
* @param {String} id 要查找的节点id
|
||||
* @param {String} idKey 主键字段名(如果为null则直接比较)
|
||||
* @param {Boolean} removeItem 是否从数组中移除查找到的节点
|
||||
* @returns {Object} 找到返回节点,没找到返回undefined
|
||||
*/
|
||||
export function findItemFromList(
|
||||
list: ANY_OBJECT[],
|
||||
id: string | number | undefined | null,
|
||||
idKey: string | null = null,
|
||||
removeItem = false,
|
||||
) {
|
||||
if (Array.isArray(list) && list.length > 0 && id != null) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const item = list[i];
|
||||
if (
|
||||
((idKey == null || idKey === '') && item.toString() === id) ||
|
||||
(idKey != null && item[idKey] === id)
|
||||
) {
|
||||
if (removeItem) list.splice(i, 1);
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 将数据保存到sessionStorage
|
||||
* @param {*} key sessionStorage的键值
|
||||
* @param {*} value 要保存的数据
|
||||
*/
|
||||
export function setObjectToSessionStorage(key: string, value: ANY_OBJECT) {
|
||||
if (key == null || key === '') return false;
|
||||
if (value == null) {
|
||||
window.sessionStorage.removeItem(key);
|
||||
return true;
|
||||
} else {
|
||||
const jsonObj = {
|
||||
data: value,
|
||||
};
|
||||
window.sessionStorage.setItem(key, JSON.stringify(jsonObj));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 从sessionStorage里面获取数据
|
||||
* @param {String} key 键值
|
||||
* @param {*} defaultValue 默认值
|
||||
*/
|
||||
export function getObjectFromSessionStorage(key: string, defaultValue: ANY_OBJECT): ANY_OBJECT {
|
||||
let jsonObj = null;
|
||||
try {
|
||||
const val: string | null = sessionStorage.getItem(key);
|
||||
if (val == null) return defaultValue;
|
||||
jsonObj = JSON.parse(val);
|
||||
jsonObj = (jsonObj || {}).data;
|
||||
} catch (e) {
|
||||
jsonObj = defaultValue;
|
||||
}
|
||||
return jsonObj != null ? jsonObj : defaultValue;
|
||||
}
|
||||
/**
|
||||
* 判读字符串是否一个数字
|
||||
* @param {String} str 要判断的字符串
|
||||
*/
|
||||
export function isNumber(str: string) {
|
||||
const num = Number.parseFloat(str);
|
||||
if (Number.isNaN(num)) return false;
|
||||
return num.toString() === str;
|
||||
}
|
||||
/**
|
||||
* 生成随机数
|
||||
* @param {Integer} min 随机数最小值
|
||||
* @param {Integer} max 随机数最大值
|
||||
*/
|
||||
export function random(min: number, max: number) {
|
||||
const base = Math.random();
|
||||
return min + base * (max - min);
|
||||
}
|
||||
/**
|
||||
* 加密
|
||||
* @param {*} value 要加密的字符串
|
||||
*/
|
||||
const publicKey =
|
||||
'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpC4QMnbTrQOFriJJCCFFWhlruBJThAEBfRk7pRx1jsAhyNVL3CqJb0tRvpnbCnJhrRAEPdgFHXv5A0RrvFp+5Cw7QoFH6O9rKB8+0H7+aVQeKITMUHf/XMXioymw6Iq4QfWd8RhdtM1KM6eGTy8aU7SO2s69Mc1LXefg/x3yw6wIDAQAB';
|
||||
export function encrypt(value: string): string | null {
|
||||
if (value == null || value === '') return null;
|
||||
const encrypt = new JSEncrypt();
|
||||
encrypt.setPublicKey(publicKey);
|
||||
return encodeURIComponent(encrypt.encrypt(value));
|
||||
}
|
||||
|
||||
export function getToken() {
|
||||
return sessionStorage.getItem('token');
|
||||
}
|
||||
|
||||
export function setToken(token: string | null | undefined) {
|
||||
if (token == null || token === '') {
|
||||
sessionStorage.removeItem('token');
|
||||
} else {
|
||||
sessionStorage.setItem('token', token);
|
||||
}
|
||||
}
|
||||
|
||||
export function getAppId() {
|
||||
const appId = sessionStorage.getItem('appId');
|
||||
return appId != null ? appId : undefined;
|
||||
}
|
||||
|
||||
export function setAppId(appId: string | null | undefined) {
|
||||
if (appId == null || appId === '') {
|
||||
sessionStorage.removeItem('appId');
|
||||
} else {
|
||||
sessionStorage.setItem('appId', appId);
|
||||
}
|
||||
}
|
||||
|
||||
export function traversalTree(
|
||||
treeNode: ANY_OBJECT,
|
||||
callback: (treeNode: ANY_OBJECT) => void,
|
||||
childrenKey = 'children',
|
||||
) {
|
||||
if (
|
||||
treeNode != null &&
|
||||
Array.isArray(treeNode[childrenKey]) &&
|
||||
treeNode[childrenKey].length > 0
|
||||
) {
|
||||
treeNode[childrenKey].forEach((childNode: ANY_OBJECT) => {
|
||||
traversalTree(childNode, callback, childrenKey);
|
||||
});
|
||||
}
|
||||
return typeof callback === 'function' ? callback(treeNode) : undefined;
|
||||
}
|
||||
|
||||
export class TreeTableImpl {
|
||||
private options;
|
||||
private dataList;
|
||||
private dataMap;
|
||||
private checkedRows: Map<string, ANY_OBJECT> | undefined;
|
||||
|
||||
constructor(
|
||||
dataList: Array<ANY_OBJECT>,
|
||||
options: {
|
||||
idKey: string;
|
||||
nameKey: string;
|
||||
parentIdKey: string;
|
||||
isLefeCallback: (item: ANY_OBJECT) => boolean | undefined;
|
||||
checkStrictly: boolean;
|
||||
},
|
||||
) {
|
||||
this.options = {
|
||||
idKey: options ? options.idKey : 'id',
|
||||
nameKey: options ? options.nameKey : 'name',
|
||||
parentIdKey: options ? options.parentIdKey : 'parentId',
|
||||
isLefeCallback: options ? options.isLefeCallback : undefined,
|
||||
checkStrictly: options ? options.checkStrictly : false,
|
||||
};
|
||||
|
||||
this.dataList = Array.isArray(dataList) ? dataList : [];
|
||||
this.dataMap = new Map();
|
||||
this.dataList.forEach(item => {
|
||||
this.dataMap.set(item[this.options.idKey], item);
|
||||
});
|
||||
// 表格选中行
|
||||
this.checkedRows = undefined;
|
||||
this.onCheckedRowChange = this.onCheckedRowChange.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤表格数据
|
||||
* @param {string} filterString 过滤条件字符串
|
||||
* @param {boolean} onlyChecked 是否只显示选中节点
|
||||
* @returns {array} 过滤后的表格数据列表
|
||||
*/
|
||||
getFilterTableData(filterString: string | null, onlyChecked = false) {
|
||||
const { idKey, nameKey, parentIdKey, isLefeCallback } = this.options;
|
||||
const tempMap = new Map();
|
||||
const parentIdList: ANY_OBJECT[] = [];
|
||||
this.dataList.forEach(item => {
|
||||
if (
|
||||
(filterString == null ||
|
||||
filterString === '' ||
|
||||
item[nameKey].indexOf(filterString) !== -1) &&
|
||||
(!onlyChecked || (this.checkedRows != null && this.checkedRows.get(item[idKey])))
|
||||
) {
|
||||
if (!isLefeCallback || !isLefeCallback(item)) {
|
||||
parentIdList.push(item[idKey]);
|
||||
}
|
||||
// 将命中节点以及它的父节点都设置为命中
|
||||
let tempItem = item;
|
||||
do {
|
||||
tempMap.set(tempItem[idKey], tempItem);
|
||||
tempItem = this.dataMap.get(tempItem[parentIdKey]);
|
||||
} while (tempItem != null);
|
||||
}
|
||||
});
|
||||
|
||||
return this.dataList.map(item => {
|
||||
let disabled = true;
|
||||
|
||||
if (parentIdList.indexOf(item[parentIdKey]) !== -1 || tempMap.get(item[idKey]) != null) {
|
||||
if (
|
||||
parentIdList.indexOf(item[parentIdKey]) !== -1 &&
|
||||
(isLefeCallback == null || !isLefeCallback(item))
|
||||
) {
|
||||
parentIdList.push(item[idKey]);
|
||||
}
|
||||
disabled = false;
|
||||
}
|
||||
|
||||
return {
|
||||
...item,
|
||||
__disabled: disabled,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表格树数据,计算选中状态
|
||||
* @param {array} dataList 表格列表数据
|
||||
*/
|
||||
getTableTreeData(dataList: ANY_OBJECT[], checkedRows: Map<string, ANY_OBJECT>) {
|
||||
const { idKey, parentIdKey, checkStrictly } = this.options;
|
||||
let treeData: ANY_OBJECT[] = [];
|
||||
function calcPermCodeTreeAttribute(treeNode: ANY_OBJECT, checkedRows: Map<string, ANY_OBJECT>) {
|
||||
const checkedItem = checkedRows == null ? null : checkedRows.get(treeNode[idKey]);
|
||||
treeNode.__checked = checkedItem != null;
|
||||
// 是否所有子权限字都被选中
|
||||
let allChildChecked = true;
|
||||
// 是否任意子权限字被选中
|
||||
let hasChildChecked = false;
|
||||
// 如果存在子权限字
|
||||
if (Array.isArray(treeNode.children) && treeNode.children.length > 0) {
|
||||
treeNode.children.forEach((item: ANY_OBJECT) => {
|
||||
const isChecked = calcPermCodeTreeAttribute(item, checkedRows);
|
||||
hasChildChecked = hasChildChecked || isChecked;
|
||||
allChildChecked = allChildChecked && isChecked;
|
||||
});
|
||||
} else {
|
||||
allChildChecked = false;
|
||||
}
|
||||
treeNode.__indeterminate = !checkStrictly && hasChildChecked && !allChildChecked;
|
||||
treeNode.__checked = treeNode.__checked || (allChildChecked && !checkStrictly);
|
||||
return treeNode.__checked || treeNode.__indeterminate;
|
||||
}
|
||||
|
||||
if (Array.isArray(dataList)) {
|
||||
treeData = treeDataTranslate(
|
||||
dataList.map(item => {
|
||||
return { ...item };
|
||||
}),
|
||||
idKey,
|
||||
parentIdKey,
|
||||
);
|
||||
treeData.forEach(item => {
|
||||
calcPermCodeTreeAttribute(item, checkedRows);
|
||||
});
|
||||
}
|
||||
|
||||
return treeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 树表格行选中状态改变
|
||||
* @param {object} row 选中状态改变行数据
|
||||
*/
|
||||
onCheckedRowChange(row: ANY_OBJECT) {
|
||||
if (this.checkedRows == null) {
|
||||
this.checkedRows = new Map();
|
||||
} else {
|
||||
const temp = new Map();
|
||||
this.checkedRows.forEach((item, key) => {
|
||||
temp.set(key, item);
|
||||
});
|
||||
this.checkedRows = temp;
|
||||
}
|
||||
const { idKey } = this.options;
|
||||
if (!row.__checked || row.__indeterminate) {
|
||||
// 节点之前未被选中或者之前为半选状态,修改当前节点以及子节点为选中状态
|
||||
this.checkedRows.set(row[idKey], row);
|
||||
if (Array.isArray(row.children) && !this.options.checkStrictly) {
|
||||
row.children.forEach((childNode: ANY_OBJECT) => {
|
||||
traversalTree(childNode, node => {
|
||||
this.checkedRows?.set(node[idKey], node);
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// 节点之前为选中状态,修改节点以及子节点为未选中状态
|
||||
this.checkedRows.delete(row[idKey]);
|
||||
if (Array.isArray(row.children) && !this.options.checkStrictly) {
|
||||
row.children.forEach((childNode: ANY_OBJECT) => {
|
||||
traversalTree(childNode, node => {
|
||||
this.checkedRows?.delete(node[idKey]);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有选中的权限字节点
|
||||
* @param {array} treeData 树数据
|
||||
* @param {boolean} includeHalfChecked 是否包含半选节点,默认为false
|
||||
* @returns {array} 选中节点列表
|
||||
*/
|
||||
getCheckedRows(treeData: ANY_OBJECT, includeHalfChecked = false) {
|
||||
const checkedRows: ANY_OBJECT[] = [];
|
||||
|
||||
function traversalCallback(node: ANY_OBJECT) {
|
||||
if (node == null) return;
|
||||
if (node.__checked || (includeHalfChecked && node.__indeterminate)) {
|
||||
checkedRows.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(treeData) && treeData.length > 0) {
|
||||
treeData.forEach(permCode => {
|
||||
traversalTree(permCode, traversalCallback, 'children');
|
||||
});
|
||||
}
|
||||
|
||||
return checkedRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置选中节点
|
||||
* @param {array} checkedRows
|
||||
*/
|
||||
setCheckedRows(checkedRows: ANY_OBJECT[]) {
|
||||
this.checkedRows = new Map();
|
||||
if (Array.isArray(checkedRows)) {
|
||||
checkedRows.forEach(item => {
|
||||
const node = this.dataMap.get(item[this.options.idKey]);
|
||||
if (node != null) {
|
||||
this.checkedRows?.set(node[this.options.idKey], node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 根据id获取表格行
|
||||
* @param {*} id
|
||||
*/
|
||||
getTableRow(id: string) {
|
||||
return this.dataMap.get(id);
|
||||
}
|
||||
}
|
||||
|
||||
export function formatDate(
|
||||
date: string | number | Date | dayjs.Dayjs | null | undefined,
|
||||
formatString: string | undefined,
|
||||
) {
|
||||
return dayjs(date).format(formatString);
|
||||
}
|
||||
|
||||
export function parseDate(date: string | number | Date, formatString: string | undefined) {
|
||||
return dayjs(date, formatString);
|
||||
}
|
||||
|
||||
export function fileToBase64(file: File) {
|
||||
return new Promise<string | undefined>((resolve, reject) => {
|
||||
if (file == null) return reject();
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = e => {
|
||||
console.log('file loaded', e);
|
||||
resolve(e.target?.result as string);
|
||||
};
|
||||
reader.onerror = e => {
|
||||
console.warn('file load', e);
|
||||
reject(e);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function getObjectValue(data: ANY_OBJECT, fieldName: string) {
|
||||
if (data == null) return undefined;
|
||||
if (fieldName == null || fieldName === '') return data;
|
||||
const fieldPath = fieldName.split('.');
|
||||
let tempValue = data;
|
||||
if (Array.isArray(fieldPath)) {
|
||||
fieldPath.forEach(key => {
|
||||
if (tempValue != null) {
|
||||
tempValue = tempValue[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return tempValue;
|
||||
}
|
||||
|
||||
// 判断输入值是否一个Object
|
||||
export function isObject(obj: ANY_OBJECT) {
|
||||
return obj != null && typeof obj === 'object' && obj.toString() === '[object Object]';
|
||||
}
|
||||
|
||||
function copyObject(obj: ANY_OBJECT): ANY_OBJECT {
|
||||
if (obj == null) return obj;
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
export function deepMerge(obj1: ANY_OBJECT, obj2: ANY_OBJECT) {
|
||||
const tempObj = copyObject(obj1);
|
||||
if (obj2 != null) {
|
||||
Object.keys(obj2).forEach(key => {
|
||||
const val2 = obj2[key];
|
||||
const val1 = tempObj[key];
|
||||
if (isObject(val2)) {
|
||||
// 如果两个值都是对象,则递归合并
|
||||
if (isObject(val1)) {
|
||||
tempObj[key] = deepMerge(val1, val2);
|
||||
} else {
|
||||
tempObj[key] = copyObject(val2);
|
||||
}
|
||||
} else if (Array.isArray(val2)) {
|
||||
//console.log('......deepMerge.......', val1, val2, obj1, obj2);
|
||||
// 如果两个值都是数组,则合并数组
|
||||
if (Array.isArray(val1)) {
|
||||
tempObj[key] = val2.map((arrVal2, index) => {
|
||||
const arrVal1 = val1[index];
|
||||
if (isObject(arrVal1)) {
|
||||
return deepMerge(arrVal1, arrVal2);
|
||||
} else {
|
||||
return arrVal2;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
tempObj[key] = copyObject(val2);
|
||||
}
|
||||
} else {
|
||||
// 直接覆盖
|
||||
tempObj[key] = val2;
|
||||
}
|
||||
});
|
||||
}
|
||||
return tempObj;
|
||||
}
|
||||
Reference in New Issue
Block a user