优化工具函数
This commit is contained in:
@@ -1,180 +1,499 @@
|
|||||||
/**
|
/*
|
||||||
* 工具类
|
* @Descripttion: 工具集
|
||||||
|
* @version: 2.0
|
||||||
|
* @LastEditors: sakuya
|
||||||
|
* @LastEditTime: 2026年1月15日
|
||||||
*/
|
*/
|
||||||
const tool = {
|
|
||||||
/**
|
import CryptoJS from "crypto-js";
|
||||||
* 本地存储操作
|
import sysConfig from "@/config";
|
||||||
*/
|
|
||||||
data: {
|
const tool = {};
|
||||||
/**
|
|
||||||
* 设置本地存储
|
/**
|
||||||
* @param {string} key - 键名
|
* 检查是否为有效的值(非null、非undefined、非空字符串、非空数组、非空对象)
|
||||||
* @param {*} value - 值
|
* @param {*} value - 要检查的值
|
||||||
*/
|
* @returns {boolean}
|
||||||
set(key, value) {
|
*/
|
||||||
if (typeof value === 'object') {
|
tool.isValid = function (value) {
|
||||||
localStorage.setItem(key, JSON.stringify(value))
|
if (value === null || value === undefined) {
|
||||||
} else {
|
return false;
|
||||||
localStorage.setItem(key, value)
|
}
|
||||||
|
if (typeof value === "string" && value.trim() === "") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Array.isArray(value) && value.length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (typeof value === "object" && Object.keys(value).length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 防抖函数
|
||||||
|
* @param {Function} func - 要执行的函数
|
||||||
|
* @param {number} wait - 等待时间(毫秒)
|
||||||
|
* @param {boolean} immediate - 是否立即执行
|
||||||
|
* @returns {Function}
|
||||||
|
*/
|
||||||
|
tool.debounce = function (func, wait = 300, immediate = false) {
|
||||||
|
let timeout;
|
||||||
|
return function (...args) {
|
||||||
|
const context = this;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
if (immediate && !timeout) {
|
||||||
|
func.apply(context, args);
|
||||||
|
}
|
||||||
|
timeout = setTimeout(() => {
|
||||||
|
timeout = null;
|
||||||
|
if (!immediate) {
|
||||||
|
func.apply(context, args);
|
||||||
}
|
}
|
||||||
},
|
}, wait);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取本地存储
|
* 节流函数
|
||||||
* @param {string} key - 键名
|
* @param {Function} func - 要执行的函数
|
||||||
* @param {*} defaultValue - 默认值
|
* @param {number} wait - 等待时间(毫秒)
|
||||||
* @returns {*}
|
* @param {Object} options - 配置选项 { leading: boolean, trailing: boolean }
|
||||||
*/
|
* @returns {Function}
|
||||||
get(key, defaultValue = null) {
|
*/
|
||||||
const value = localStorage.getItem(key)
|
tool.throttle = function (func, wait = 300, options = {}) {
|
||||||
if (!value) {
|
let timeout;
|
||||||
return defaultValue
|
let previous = 0;
|
||||||
|
const { leading = true, trailing = true } = options;
|
||||||
|
|
||||||
|
return function (...args) {
|
||||||
|
const context = this;
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
if (!previous && !leading) {
|
||||||
|
previous = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
const remaining = wait - (now - previous);
|
||||||
|
|
||||||
|
if (remaining <= 0 || remaining > wait) {
|
||||||
|
if (timeout) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = null;
|
||||||
}
|
}
|
||||||
try {
|
previous = now;
|
||||||
return JSON.parse(value)
|
func.apply(context, args);
|
||||||
} catch (e) {
|
} else if (!timeout && trailing) {
|
||||||
return value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除本地存储
|
|
||||||
* @param {string} key - 键名
|
|
||||||
*/
|
|
||||||
remove(key) {
|
|
||||||
localStorage.removeItem(key)
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清空本地存储
|
|
||||||
*/
|
|
||||||
clear() {
|
|
||||||
localStorage.clear()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 树形结构转列表
|
|
||||||
* @param {Array} tree - 树形结构数据
|
|
||||||
* @param {string} childrenKey - 子节点键名
|
|
||||||
* @returns {Array} 扁平化后的数组
|
|
||||||
*/
|
|
||||||
tree_to_list(tree, childrenKey = 'children') {
|
|
||||||
if (!tree || !Array.isArray(tree)) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = []
|
|
||||||
|
|
||||||
const traverse = (nodes) => {
|
|
||||||
if (!nodes || !Array.isArray(nodes)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
nodes.forEach((node) => {
|
|
||||||
result.push(node)
|
|
||||||
if (node[childrenKey] && node[childrenKey].length > 0) {
|
|
||||||
traverse(node[childrenKey])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
traverse(tree)
|
|
||||||
return result
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 列表转树形结构
|
|
||||||
* @param {Array} list - 列表数据
|
|
||||||
* @param {string} idKey - ID键名
|
|
||||||
* @param {string} parentIdKey - 父ID键名
|
|
||||||
* @param {string} childrenKey - 子节点键名
|
|
||||||
* @returns {Array} 树形结构数据
|
|
||||||
*/
|
|
||||||
list_to_tree(list, idKey = 'id', parentIdKey = 'parentId', childrenKey = 'children') {
|
|
||||||
if (!list || !Array.isArray(list)) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
const map = {}
|
|
||||||
const roots = []
|
|
||||||
|
|
||||||
// 创建映射表
|
|
||||||
list.forEach((item) => {
|
|
||||||
map[item[idKey]] = { ...item, [childrenKey]: [] }
|
|
||||||
})
|
|
||||||
|
|
||||||
// 构建树形结构
|
|
||||||
list.forEach((item) => {
|
|
||||||
const node = map[item[idKey]]
|
|
||||||
const parentId = item[parentIdKey]
|
|
||||||
|
|
||||||
if (parentId && map[parentId]) {
|
|
||||||
map[parentId][childrenKey].push(node)
|
|
||||||
} else {
|
|
||||||
roots.push(node)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return roots
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 深拷贝
|
|
||||||
* @param {*} obj - 要拷贝的对象
|
|
||||||
* @returns {*} 拷贝后的对象
|
|
||||||
*/
|
|
||||||
deepClone(obj) {
|
|
||||||
if (obj === null || typeof obj !== 'object') {
|
|
||||||
return obj
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(obj)) {
|
|
||||||
return obj.map((item) => this.deepClone(item))
|
|
||||||
}
|
|
||||||
|
|
||||||
const cloned = {}
|
|
||||||
for (const key in obj) {
|
|
||||||
if (obj.hasOwnProperty(key)) {
|
|
||||||
cloned[key] = this.deepClone(obj[key])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cloned
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 防抖函数
|
|
||||||
* @param {Function} func - 要防抖的函数
|
|
||||||
* @param {number} wait - 等待时间
|
|
||||||
* @returns {Function}
|
|
||||||
*/
|
|
||||||
debounce(func, wait = 300) {
|
|
||||||
let timeout
|
|
||||||
return function (...args) {
|
|
||||||
clearTimeout(timeout)
|
|
||||||
timeout = setTimeout(() => {
|
timeout = setTimeout(() => {
|
||||||
func.apply(this, args)
|
previous = leading ? Date.now() : 0;
|
||||||
}, wait)
|
timeout = null;
|
||||||
|
func.apply(context, args);
|
||||||
|
}, remaining);
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 节流函数
|
* 深拷贝对象(支持循环引用)
|
||||||
* @param {Function} func - 要节流的函数
|
* @param {*} obj - 要拷贝的对象
|
||||||
* @param {number} wait - 等待时间
|
* @param {WeakMap} hash - 用于检测循环引用
|
||||||
* @returns {Function}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
throttle(func, wait = 300) {
|
tool.deepClone = function (obj, hash = new WeakMap()) {
|
||||||
let timeout
|
if (obj === null || typeof obj !== "object") {
|
||||||
return function (...args) {
|
return obj;
|
||||||
if (!timeout) {
|
}
|
||||||
timeout = setTimeout(() => {
|
|
||||||
func.apply(this, args)
|
if (hash.has(obj)) {
|
||||||
timeout = null
|
return hash.get(obj);
|
||||||
}, wait)
|
}
|
||||||
}
|
|
||||||
|
const clone = Array.isArray(obj) ? [] : {};
|
||||||
|
hash.set(obj, clone);
|
||||||
|
|
||||||
|
for (const key in obj) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||||
|
clone[key] = tool.deepClone(obj[key], hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export default tool
|
return clone;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* localStorage */
|
||||||
|
tool.data = {
|
||||||
|
set(key, data, datetime = 0) {
|
||||||
|
//加密
|
||||||
|
if (sysConfig.LS_ENCRYPTION == "AES") {
|
||||||
|
data = tool.crypto.AES.encrypt(
|
||||||
|
JSON.stringify(data),
|
||||||
|
sysConfig.LS_ENCRYPTION_key,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let cacheValue = {
|
||||||
|
content: data,
|
||||||
|
datetime:
|
||||||
|
parseInt(datetime) === 0
|
||||||
|
? 0
|
||||||
|
: new Date().getTime() + parseInt(datetime) * 1000,
|
||||||
|
};
|
||||||
|
return localStorage.setItem(key, JSON.stringify(cacheValue));
|
||||||
|
},
|
||||||
|
get(key) {
|
||||||
|
try {
|
||||||
|
const value = JSON.parse(localStorage.getItem(key));
|
||||||
|
if (value) {
|
||||||
|
let nowTime = new Date().getTime();
|
||||||
|
if (nowTime > value.datetime && value.datetime != 0) {
|
||||||
|
localStorage.removeItem(key);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//解密
|
||||||
|
if (sysConfig.LS_ENCRYPTION == "AES") {
|
||||||
|
value.content = JSON.parse(
|
||||||
|
tool.crypto.AES.decrypt(
|
||||||
|
value.content,
|
||||||
|
sysConfig.LS_ENCRYPTION_key,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return value.content;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (err) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remove(key) {
|
||||||
|
return localStorage.removeItem(key);
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
return localStorage.clear();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*sessionStorage*/
|
||||||
|
tool.session = {
|
||||||
|
set(table, settings) {
|
||||||
|
const _set = JSON.stringify(settings);
|
||||||
|
return sessionStorage.setItem(table, _set);
|
||||||
|
},
|
||||||
|
get(table) {
|
||||||
|
const data = sessionStorage.getItem(table);
|
||||||
|
try {
|
||||||
|
return JSON.parse(data);
|
||||||
|
} catch (err) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remove(table) {
|
||||||
|
return sessionStorage.removeItem(table);
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
return sessionStorage.clear();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*cookie*/
|
||||||
|
tool.cookie = {
|
||||||
|
/**
|
||||||
|
* 设置cookie
|
||||||
|
* @param {string} name - cookie名称
|
||||||
|
* @param {string} value - cookie值
|
||||||
|
* @param {Object} config - 配置选项
|
||||||
|
*/
|
||||||
|
set(name, value, config = {}) {
|
||||||
|
const cfg = {
|
||||||
|
expires: null,
|
||||||
|
path: null,
|
||||||
|
domain: null,
|
||||||
|
secure: false,
|
||||||
|
httpOnly: false,
|
||||||
|
sameSite: "Lax",
|
||||||
|
...config,
|
||||||
|
};
|
||||||
|
let cookieStr = `${name}=${encodeURIComponent(value)}`;
|
||||||
|
if (cfg.expires) {
|
||||||
|
const exp = new Date();
|
||||||
|
exp.setTime(exp.getTime() + parseInt(cfg.expires) * 1000);
|
||||||
|
cookieStr += `;expires=${exp.toUTCString()}`;
|
||||||
|
}
|
||||||
|
if (cfg.path) {
|
||||||
|
cookieStr += `;path=${cfg.path}`;
|
||||||
|
}
|
||||||
|
if (cfg.domain) {
|
||||||
|
cookieStr += `;domain=${cfg.domain}`;
|
||||||
|
}
|
||||||
|
if (cfg.secure) {
|
||||||
|
cookieStr += `;secure`;
|
||||||
|
}
|
||||||
|
if (cfg.sameSite) {
|
||||||
|
cookieStr += `;SameSite=${cfg.sameSite}`;
|
||||||
|
}
|
||||||
|
document.cookie = cookieStr;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 获取cookie
|
||||||
|
* @param {string} name - cookie名称
|
||||||
|
* @returns {string|null}
|
||||||
|
*/
|
||||||
|
get(name) {
|
||||||
|
const arr = document.cookie.match(
|
||||||
|
new RegExp("(^| )" + name + "=([^;]*)(;|$)"),
|
||||||
|
);
|
||||||
|
if (arr != null) {
|
||||||
|
return decodeURIComponent(arr[2]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 删除cookie
|
||||||
|
* @param {string} name - cookie名称
|
||||||
|
*/
|
||||||
|
remove(name) {
|
||||||
|
const exp = new Date();
|
||||||
|
exp.setTime(exp.getTime() - 1);
|
||||||
|
document.cookie = `${name}=;expires=${exp.toUTCString()}`;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Fullscreen */
|
||||||
|
/**
|
||||||
|
* 切换全屏状态
|
||||||
|
* @param {HTMLElement} element - 要全屏的元素
|
||||||
|
*/
|
||||||
|
tool.screen = function (element) {
|
||||||
|
const isFull = !!(
|
||||||
|
document.webkitIsFullScreen ||
|
||||||
|
document.mozFullScreen ||
|
||||||
|
document.msFullscreenElement ||
|
||||||
|
document.fullscreenElement
|
||||||
|
);
|
||||||
|
if (isFull) {
|
||||||
|
if (document.exitFullscreen) {
|
||||||
|
document.exitFullscreen();
|
||||||
|
} else if (document.msExitFullscreen) {
|
||||||
|
document.msExitFullscreen();
|
||||||
|
} else if (document.mozCancelFullScreen) {
|
||||||
|
document.mozCancelFullScreen();
|
||||||
|
} else if (document.webkitExitFullscreen) {
|
||||||
|
document.webkitExitFullscreen();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (element.requestFullscreen) {
|
||||||
|
element.requestFullscreen();
|
||||||
|
} else if (element.msRequestFullscreen) {
|
||||||
|
element.msRequestFullscreen();
|
||||||
|
} else if (element.mozRequestFullScreen) {
|
||||||
|
element.mozRequestFullScreen();
|
||||||
|
} else if (element.webkitRequestFullscreen) {
|
||||||
|
element.webkitRequestFullscreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 复制对象(浅拷贝) */
|
||||||
|
/**
|
||||||
|
* 浅拷贝对象
|
||||||
|
* @param {*} obj - 要拷贝的对象
|
||||||
|
* @returns {*} - 拷贝后的对象
|
||||||
|
*/
|
||||||
|
tool.objCopy = function (obj) {
|
||||||
|
if (obj === null || typeof obj !== "object") {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
return JSON.parse(JSON.stringify(obj));
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 日期格式化 */
|
||||||
|
/**
|
||||||
|
* 格式化日期
|
||||||
|
* @param {Date|string|number} date - 日期对象、时间戳或日期字符串
|
||||||
|
* @param {string} fmt - 格式化字符串,默认 "yyyy-MM-dd hh:mm:ss"
|
||||||
|
* @returns {string} - 格式化后的日期字符串
|
||||||
|
*/
|
||||||
|
tool.dateFormat = function (date, fmt = "yyyy-MM-dd hh:mm:ss") {
|
||||||
|
if (!date) return "";
|
||||||
|
const dateObj = new Date(date);
|
||||||
|
if (isNaN(dateObj.getTime())) return "";
|
||||||
|
|
||||||
|
const o = {
|
||||||
|
"M+": dateObj.getMonth() + 1, // 月份
|
||||||
|
"d+": dateObj.getDate(), // 日
|
||||||
|
"h+": dateObj.getHours(), // 小时
|
||||||
|
"m+": dateObj.getMinutes(), // 分
|
||||||
|
"s+": dateObj.getSeconds(), // 秒
|
||||||
|
"q+": Math.floor((dateObj.getMonth() + 3) / 3), // 季度
|
||||||
|
S: dateObj.getMilliseconds(), // 毫秒
|
||||||
|
};
|
||||||
|
if (/(y+)/.test(fmt)) {
|
||||||
|
fmt = fmt.replace(
|
||||||
|
RegExp.$1,
|
||||||
|
(dateObj.getFullYear() + "").substr(4 - RegExp.$1.length),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for (const k in o) {
|
||||||
|
if (new RegExp("(" + k + ")").test(fmt)) {
|
||||||
|
fmt = fmt.replace(
|
||||||
|
RegExp.$1,
|
||||||
|
RegExp.$1.length == 1
|
||||||
|
? o[k]
|
||||||
|
: ("00" + o[k]).substr(("" + o[k]).length),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 千分符 */
|
||||||
|
/**
|
||||||
|
* 格式化数字,添加千分位分隔符
|
||||||
|
* @param {number|string} num - 要格式化的数字
|
||||||
|
* @param {number} decimals - 保留小数位数,默认为0
|
||||||
|
* @returns {string} - 格式化后的字符串
|
||||||
|
*/
|
||||||
|
tool.groupSeparator = function (num, decimals = 0) {
|
||||||
|
if (num === null || num === undefined || num === "") return "";
|
||||||
|
const numStr = Number(num).toFixed(decimals);
|
||||||
|
const parts = numStr.split(".");
|
||||||
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||||
|
return parts.join(".");
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 常用加解密 */
|
||||||
|
tool.crypto = {
|
||||||
|
//MD5加密
|
||||||
|
MD5(data) {
|
||||||
|
return CryptoJS.MD5(data).toString();
|
||||||
|
},
|
||||||
|
//BASE64加解密
|
||||||
|
BASE64: {
|
||||||
|
encrypt(data) {
|
||||||
|
return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data));
|
||||||
|
},
|
||||||
|
decrypt(cipher) {
|
||||||
|
return CryptoJS.enc.Base64.parse(cipher).toString(
|
||||||
|
CryptoJS.enc.Utf8,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
//AES加解密
|
||||||
|
AES: {
|
||||||
|
encrypt(data, secretKey, config = {}) {
|
||||||
|
if (secretKey.length % 8 != 0) {
|
||||||
|
console.warn(
|
||||||
|
"[SCUI error]: 秘钥长度需为8的倍数,否则解密将会失败。",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const result = CryptoJS.AES.encrypt(
|
||||||
|
data,
|
||||||
|
CryptoJS.enc.Utf8.parse(secretKey),
|
||||||
|
{
|
||||||
|
iv: CryptoJS.enc.Utf8.parse(config.iv || ""),
|
||||||
|
mode: CryptoJS.mode[config.mode || "ECB"],
|
||||||
|
padding: CryptoJS.pad[config.padding || "Pkcs7"],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return result.toString();
|
||||||
|
},
|
||||||
|
decrypt(cipher, secretKey, config = {}) {
|
||||||
|
const result = CryptoJS.AES.decrypt(
|
||||||
|
cipher,
|
||||||
|
CryptoJS.enc.Utf8.parse(secretKey),
|
||||||
|
{
|
||||||
|
iv: CryptoJS.enc.Utf8.parse(config.iv || ""),
|
||||||
|
mode: CryptoJS.mode[config.mode || "ECB"],
|
||||||
|
padding: CryptoJS.pad[config.padding || "Pkcs7"],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return CryptoJS.enc.Utf8.stringify(result);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 树形数据转扁平数组 */
|
||||||
|
/**
|
||||||
|
* 将树形结构转换为扁平数组
|
||||||
|
* @param {Array} tree - 树形数组
|
||||||
|
* @param {Object} config - 配置项 { children: "children" }
|
||||||
|
* @returns {Array} - 扁平化后的数组
|
||||||
|
*/
|
||||||
|
tool.treeToList = function (tree, config = { children: "children" }) {
|
||||||
|
const result = [];
|
||||||
|
tree.forEach((item) => {
|
||||||
|
const tmp = { ...item };
|
||||||
|
const childrenKey = config.children || "children";
|
||||||
|
|
||||||
|
if (tmp[childrenKey] && tmp[childrenKey].length > 0) {
|
||||||
|
result.push({ ...item });
|
||||||
|
const childrenRoutes = tool.treeToList(tmp[childrenKey], config);
|
||||||
|
result.push(...childrenRoutes);
|
||||||
|
} else {
|
||||||
|
result.push(tmp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 获取父节点数据(保留原有函数名) */
|
||||||
|
/**
|
||||||
|
* 根据ID获取父节点数据
|
||||||
|
* @param {Array} list - 数据列表
|
||||||
|
* @param {number|string} targetId - 目标ID
|
||||||
|
* @param {Object} config - 配置项 { pid: "parent_id", idField: "id", field: [] }
|
||||||
|
* @returns {*} - 父节点数据或指定字段
|
||||||
|
*/
|
||||||
|
tool.get_parents = function (
|
||||||
|
list,
|
||||||
|
targetId = 0,
|
||||||
|
config = { pid: "parent_id", idField: "id", field: [] },
|
||||||
|
) {
|
||||||
|
let res = null;
|
||||||
|
list.forEach((item) => {
|
||||||
|
if (item[config.idField || "id"] === targetId) {
|
||||||
|
if (config.field && config.field.length > 1) {
|
||||||
|
res = {};
|
||||||
|
config.field.forEach((field) => {
|
||||||
|
res[field] = item[field];
|
||||||
|
});
|
||||||
|
} else if (config.field && config.field.length === 1) {
|
||||||
|
res = item[config.field[0]];
|
||||||
|
} else {
|
||||||
|
res = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 获取数据字段 */
|
||||||
|
/**
|
||||||
|
* 从数据对象中提取指定字段
|
||||||
|
* @param {Object} data - 数据对象
|
||||||
|
* @param {Array} fields - 字段名数组
|
||||||
|
* @returns {*} - 提取的字段数据
|
||||||
|
*/
|
||||||
|
tool.getDataField = function (data, fields = []) {
|
||||||
|
if (!data || typeof data !== "object") {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
if (fields.length === 0) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
if (fields.length === 1) {
|
||||||
|
return data[fields[0]];
|
||||||
|
} else {
|
||||||
|
const result = {};
|
||||||
|
fields.forEach((field) => {
|
||||||
|
result[field] = data[field];
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 兼容旧函数名
|
||||||
|
tool.tree_to_list = tool.treeToList;
|
||||||
|
tool.get_data_field = tool.getDataField;
|
||||||
|
|
||||||
|
export default tool;
|
||||||
|
|||||||
Reference in New Issue
Block a user