224 lines
5.6 KiB
TypeScript
224 lines
5.6 KiB
TypeScript
/**
|
|
* 解析数据层级转树结构
|
|
*
|
|
* @param data 数组数据
|
|
* @param fieldId 读取节点字段 默认 'id'
|
|
* @param fieldParentId 读取节点父节点字段 默认 'parentId'
|
|
* @param fieldChildren 设置子节点字段 默认 'children'
|
|
* @returns 层级数组
|
|
*/
|
|
export function parseDataToTree(
|
|
data: Record<string, any>[],
|
|
fieldId: string = 'id',
|
|
fieldParentId: string = 'parentId',
|
|
fieldChildren: string = 'children'
|
|
) {
|
|
// 节点分组
|
|
let map: Map<string, Record<string, any>[]> = new Map();
|
|
// 节点id
|
|
let treeIds: string[] = [];
|
|
// 树节点
|
|
let tree: Record<string, any>[] = [];
|
|
|
|
for (const item of data) {
|
|
let parentId = item[fieldParentId];
|
|
// 分组
|
|
let mapItem = map.get(parentId) ?? [];
|
|
mapItem.push(item);
|
|
map.set(parentId, mapItem);
|
|
// 记录节点id
|
|
treeIds.push(item[fieldId]);
|
|
}
|
|
|
|
for (const [key, value] of map) {
|
|
// 选择不是节点id的作为树节点
|
|
if (!treeIds.includes(key)) {
|
|
tree.push(...value);
|
|
}
|
|
}
|
|
|
|
for (const iterator of tree) {
|
|
componet(iterator);
|
|
}
|
|
|
|
/**闭包递归函数 */
|
|
function componet(iterator: Record<string, any>) {
|
|
let id = iterator[fieldId];
|
|
let item = map.get(id);
|
|
if (item) {
|
|
iterator[fieldChildren] = item;
|
|
}
|
|
if (iterator[fieldChildren]) {
|
|
for (let i of iterator[fieldChildren]) {
|
|
componet(i);
|
|
}
|
|
}
|
|
}
|
|
return tree;
|
|
}
|
|
|
|
/**
|
|
* 解析数据层级转树结构-排除节点
|
|
*
|
|
* @param data 数组数据
|
|
* @param excludeField 排除节点字段 默认 'type'
|
|
* @param excludeValue 排除节点值 默认 '0'
|
|
* @param fieldId 读取节点字段 默认 'id'
|
|
* @param fieldParentId 读取节点父节点字段 默认 'parentId'
|
|
* @param fieldChildren 设置子节点字段 默认 'children'
|
|
* @returns 层级数组
|
|
*/
|
|
export function parseDataToTreeExclude(
|
|
data: Record<string, any>[],
|
|
excludeField = 'type',
|
|
excludeValue = '0',
|
|
fieldId: string = 'id',
|
|
fieldParentId: string = 'parentId',
|
|
fieldChildren: string = 'children'
|
|
) {
|
|
// 节点分组
|
|
let map: Map<string, Record<string, any>[]> = new Map();
|
|
// 节点id
|
|
let treeIds: string[] = [];
|
|
// 树节点
|
|
let tree: Record<string, any>[] = [];
|
|
|
|
for (const item of data) {
|
|
// 排除值跳过
|
|
let exclude = item[excludeField];
|
|
if (exclude && exclude === excludeValue) {
|
|
continue;
|
|
}
|
|
let parentId = item[fieldParentId];
|
|
// 分组
|
|
let mapItem = map.get(parentId) ?? [];
|
|
mapItem.push(item);
|
|
map.set(parentId, mapItem);
|
|
// 记录节点id
|
|
treeIds.push(item[fieldId]);
|
|
}
|
|
|
|
for (const [key, value] of map) {
|
|
// 选择不是节点id的作为树节点
|
|
if (!treeIds.includes(key)) {
|
|
tree.push(...value);
|
|
}
|
|
}
|
|
|
|
for (const iterator of tree) {
|
|
componet(iterator);
|
|
}
|
|
|
|
/**闭包递归函数 */
|
|
function componet(iterator: Record<string, any>) {
|
|
let id = iterator[fieldId];
|
|
let item = map.get(id);
|
|
if (item) {
|
|
iterator[fieldChildren] = item;
|
|
}
|
|
if (iterator[fieldChildren]) {
|
|
for (let i of iterator[fieldChildren]) {
|
|
componet(i);
|
|
}
|
|
}
|
|
}
|
|
return tree;
|
|
}
|
|
|
|
/**
|
|
* 解析树结构数据转出一维id数组
|
|
*
|
|
* @param data 数组数据
|
|
* @param fieldId 读取节点字段 默认 'id'
|
|
* @param fieldChildren 读取子节点字段 默认 'children'
|
|
* @returns 层级数组
|
|
*/
|
|
export function parseTreeKeys(
|
|
data: Record<string, any>[],
|
|
fieldId: string = 'id',
|
|
fieldChildren: string = 'children'
|
|
) {
|
|
// 节点id
|
|
let treeIds: string[] | number[] = [];
|
|
componet(data);
|
|
/**闭包递归函数 */
|
|
function componet(data: Record<string, any>[]) {
|
|
if (data.length <= 0) return;
|
|
for (const iterator of data) {
|
|
let id = iterator[fieldId];
|
|
if (id) {
|
|
treeIds.push(id as never);
|
|
}
|
|
if (Array.isArray(iterator[fieldChildren])) {
|
|
componet(iterator[fieldChildren]);
|
|
}
|
|
}
|
|
}
|
|
return treeIds;
|
|
}
|
|
|
|
/**
|
|
* 解析树结构数据转出含子节点的一维id数组
|
|
*
|
|
* @param data 数组数据
|
|
* @param fieldId 读取节点字段 默认 'id'
|
|
* @param fieldChildren 读取子节点字段 默认 'children'
|
|
* @returns 层级数组
|
|
*/
|
|
export function parseTreeNodeKeys(
|
|
data: Record<string, any>[],
|
|
fieldId: string = 'id',
|
|
fieldChildren: string = 'children'
|
|
) {
|
|
// 节点id
|
|
let treeIds: string[] | number[] = [];
|
|
componet(data);
|
|
/**闭包递归函数 */
|
|
function componet(data: Record<string, any>[]) {
|
|
if (data.length <= 0) return;
|
|
for (const iterator of data) {
|
|
let nodes = iterator[fieldChildren];
|
|
if (Array.isArray(nodes) && nodes.length > 0) {
|
|
treeIds.push(iterator[fieldId] as never);
|
|
componet(iterator[fieldChildren]);
|
|
}
|
|
}
|
|
}
|
|
return treeIds;
|
|
}
|
|
|
|
/**
|
|
* 解析数据层级转级联options树结构
|
|
*
|
|
* @param data 数组数据
|
|
* @param fieldType 读取节点label字段 默认 'type'
|
|
* @param fieldLabel 读取节点label字段 默认 'name'
|
|
* @param fieldValue 读取节点value字段 默认 'value'
|
|
* @param fieldChildren 设置子节点字段 默认 'children'
|
|
* @returns 层级数组
|
|
*/
|
|
export function parseDataToOptions(
|
|
data: Record<string, any>[],
|
|
fieldType: string = 'type',
|
|
fieldLabel: string = 'label',
|
|
fieldValue: string = 'value',
|
|
fieldChildren: string = 'children'
|
|
) {
|
|
let options: Record<string, any>[] = [];
|
|
|
|
for (const v of data) {
|
|
let vType = v[fieldType];
|
|
let vLabel = v[fieldLabel];
|
|
let vValue = v[fieldValue];
|
|
const vData = { label: vLabel, value: vValue, ...v };
|
|
const item = options.find(i => i.value === vType);
|
|
if (item) {
|
|
item[fieldChildren].push(vData);
|
|
} else {
|
|
options.push({ label: vType, value: vType, [fieldChildren]: [vData] });
|
|
}
|
|
}
|
|
|
|
return options;
|
|
}
|