linkmore-design
Version:
🌈 🚀lm组件库。🚀
388 lines (378 loc) • 10.8 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.checkIsSelectd = checkIsSelectd;
exports.checkStatus = checkStatus;
exports.getDataSourceIndex = getDataSourceIndex;
exports.getLeafNodes = getLeafNodes;
exports.getSelectionColText = getSelectionColText;
exports.getSelectionRowText = getSelectionRowText;
exports.isSelectCrossInvalidCol = isSelectCrossInvalidCol;
exports.isSelectCrossRowGroup = isSelectCrossRowGroup;
exports.range = void 0;
exports.transformWithColGroup = transformWithColGroup;
exports.transformWithRowGroup = transformWithRowGroup;
var _lodash = _interopRequireDefault(require("lodash"));
/**
* 生成 start 到 end 数字组成的数组
* @param {number} start
* @param {number} end
* @returns {Array<number>}
*/
const range = (start, end) => {
const array = [];
const inc = end - start > 0;
for (let i = start; inc ? i <= end : i >= end; inc ? i += 1 : i -= 1) {
inc ? array.push(i) : array.unshift(i);
}
return array;
};
/**
* 对数据进行分组
* @param {Array} data
* @param {string} key
* @return {Object}
* 时间复杂度O(n), 空间复杂度O(n)
*/
exports.range = range;
function dataGroup(data, key) {
const result = {};
data?.forEach(item => {
if (item.children) {
const temp = dataGroup(item.children, key);
Object.keys(temp)?.forEach(k => {
if (!result[k]) result[k] = [];
result[k] = result[k].concat(temp[k]);
});
} else {
const value = item[key];
result[value] = [...(result[value] || []), item];
}
});
return result;
}
/**
* 列分组数据转换
* @param columns 表格的columns属性值
* @param dataSource 表格数据源
* @param groupColKeys 列分组的keys
* @returns
*/
function transformWithColGroup(columns, dataSource, groupColKeys, groupRowKeys) {
if (!Array.isArray(groupColKeys) || !groupColKeys.length) {
return {
columns,
dataSource
};
}
columns.forEach(c => {
if (groupRowKeys.includes(c.dataIndex)) {
c.show = false;
}
});
const columnsCopy = _lodash.default.cloneDeep(columns.filter(item => item.joinCol));
const unColumns = _lodash.default.cloneDeep(columns.filter(item => !item.joinCol));
const dataSourceCopy = _lodash.default.cloneDeep(dataSource);
// 去重
const groupColKeysCopy = [...new Set(groupColKeys)];
/**
* @param {Array} source source数据源,树状结构,行分组会有children子级结构
* @param {Array} columns 列数据,用于表头,当列分组时会有children子级结构
* @param {Array<string>} oGroup 数组,列分组的keys值
* @param {string} markStr
* @returns
* 2万条数据 393ms
*/
const groupBy = (source, columns, oGroup, markStr) => {
if (!oGroup?.length) {
// 表头数据的生成,生成新的 dataIndex 值
// dataIndex最后的i:筛选的值相同需要加索引
let handledColumns = [];
source?.forEach((souItem, i) => {
handledColumns = handledColumns.concat(columns.filter(c => {
// 过滤掉(表头操作) 使用列分组作为key的项
return groupColKeysCopy.indexOf(c.dataIndex) === -1;
}).map(item => {
return {
...item,
dataIndex: `${markStr}_${item.dataIndex}_${i}`
};
}));
});
return handledColumns;
}
// 拷贝
const group = oGroup.slice();
// 获取列表的第一个值
const filterKey = group.shift();
const map = dataGroup(source, filterKey);
return Object.keys(map).map(item => ({
type: filterKey,
title: item,
key: `${item}_${filterKey}`,
children: groupBy(map[item], columns, group, `${markStr ? `${markStr}_` : ''}${filterKey}_${item}`)
}));
};
let tempColumns = groupBy(dataSourceCopy, columnsCopy, groupColKeysCopy, null);
tempColumns = unColumns.concat(tempColumns);
const keyMap = new Map();
let __index = 0;
const dataSourceBy = source => {
return [source.reduce((prev, sItem) => {
if (sItem.children && sItem.children.length) {
sItem.children = dataSourceBy(sItem.children).flat();
if (!prev) {
prev = [];
}
return [...prev, sItem];
} else {
let str = '';
// 根据筛选条件生成对应的前缀key值,比如[name, age] => 'name_xiaoming_age_18'
groupColKeysCopy?.forEach((dataIndex, i) => {
if (i !== 0) {
str += '_';
}
str += `${dataIndex}_${sItem[dataIndex]}`;
});
// 对dataSource的key值进行更改:例如:'name' => 'name_xiaoming_age_18_address'
Object.keys(sItem)?.forEach(key => {
if (key === '__index') {
return;
}
let newKey = `${str}_${key}`;
if (keyMap.has(newKey)) {
const value = keyMap.get(newKey) + 1;
keyMap.set(newKey, value);
newKey = `${newKey}_${value}`;
} else {
keyMap.set(newKey, 0);
newKey = `${newKey}_${0}`;
}
sItem[newKey] = sItem[key];
sItem[`${newKey}_originIndex`] = sItem.__index === undefined ? __index : sItem.__index;
});
__index += 1;
}
if (!prev) {
prev = {};
}
return {
...prev,
...sItem
};
}, null)];
};
const tempDataSource = dataSourceBy(dataSourceCopy).flat();
return {
columns: tempColumns,
dataSource: tempDataSource
};
}
/**
* 行分组
* @param {Array} dataSource 数据源
* @param {Array} groupRowKeys 行分组的keys
* @returns
*/
function transformWithRowGroup(dataSource, groupRowKeys) {
const groupBy = (lastFilter, oGroup, preKey) => {
if (!oGroup?.length) return lastFilter;
const group = oGroup.slice();
const filterKey = group.shift();
// 记录数据原来的位置索引信息
let i = 0;
const map = lastFilter.reduce((acc, el) => {
let value = el[filterKey];
if (value === undefined) {
value = '-';
}
acc[value] = [...(acc[value] || []), {
...el,
__index: i
}];
i += 1;
return acc;
}, {});
return Object.keys(map).map(item => {
let key;
if (preKey) {
key = `${preKey}_${filterKey}_${item}`;
} else {
key = `${filterKey}_${item}`;
}
return {
type: filterKey,
_group: item,
key,
children: groupBy(map[item], group, key)
};
});
};
return groupBy(dataSource, groupRowKeys);
}
function checkIsSelectd(i, j, start = {}, end = {}) {
const posX = j >= start.j && j <= end.j;
const negX = j <= start.j && j >= end.j;
const posY = i >= start.i && i <= end.i;
const negY = i <= start.i && i >= end.i;
return posX && posY || negX && posY || negX && negY || posX && negY;
}
function checkStatus(i, j, commiting) {
const {
start,
end
} = commiting;
const maxi = Math.max(start?.i, end.i);
const mini = Math.min(start?.i, end.i);
const maxj = Math.max(start?.j, end.j);
const minj = Math.min(start?.j, end.j);
return {
/** 是否有效拉伸 */
isVaildCommit: mini <= i && maxi >= i || minj <= j && maxj >= j
};
}
/**
* 获取选中行文本
* @param {Object}
* {
* selection: {start: {i, j}, end: {i, j}},
* columnsKeysList: Array,
* dataSource: Array
* }
* @returns {Array}
*/
function getSelectionRowText({
selection,
columnsKeysList,
dataSource
}) {
const rowtext = range(selection?.start.i, selection?.end.i).map(i => columnsKeysList.map(j => {
const columnKey = j;
const dataItem = dataSource[i];
const cell = dataItem?.[columnKey];
return cell;
}));
return rowtext;
}
/**
* 获取选中列文本
* @param {Object}
* @returns {Array}
*/
function getSelectionColText({
selection,
columns,
dataSource
}) {
const coltext = range(selection?.start.i, selection?.end.i).map(i => range(selection?.start.j, selection?.end.j).map(j => {
const columnKey = columns[j]?.dataIndex;
const dataItem = dataSource[i];
const cell = dataItem?.[columnKey];
if (columns[j]?.render) {
return columns[j]?.render?.(cell, dataItem, i);
}
return cell;
}));
return coltext;
}
/**
* 获取key所对应的原始数据的索引
* @param {Object} {key, dataSource}
* @returns {number}
*/
function getDataSourceIndex({
key,
dataSource = []
}) {
let index = -1;
const dfs = arr => {
if (!Array.isArray(arr)) {
return;
}
if (index !== -1) {
return;
}
for (let i = 0; i < arr.length; i += 1) {
const item = arr[i];
if (item[`${key}_originIndex`] !== undefined) {
index = item[`${key}_originIndex`];
return;
}
if (item.children) {
dfs(item.children);
}
}
};
dfs(dataSource);
return index;
}
/**
* 框选是否跨行分组
* @param {number} i
* @param {React.Ref} shellStatusRef
* @param {React.Ref} deepDataSourceRef
* @returns
*/
function isSelectCrossRowGroup(i, shellStatusRef, deepDataSourceRef) {
let x;
let y;
if (shellStatusRef?.current?.commiting.start.i < i) {
x = shellStatusRef?.current?.commiting.start.i;
y = i;
} else {
x = i;
y = shellStatusRef?.current?.commiting.start.i;
}
for (; x <= y; x += 1) {
if (deepDataSourceRef?.current?.length && deepDataSourceRef?.current[x]._group) {
return true;
}
}
return false;
}
/**
* 不允许跨无效列
* @param {number} i
* @param {number} j
* @param {React.Ref} shellStatusRef
* @param {React.Ref} deepDataSourceRef
* @param {React.Ref} deepColumnsRef
* @returns
*/
function isSelectCrossInvalidCol(i, j, shellStatusRef, deepDataSourceRef, deepColumnsRef) {
let x;
let y;
if (shellStatusRef?.current?.commiting.start.j < j) {
x = shellStatusRef?.current?.commiting.start.j;
y = j;
} else {
x = j;
y = shellStatusRef?.current?.commiting.start.j;
}
for (; x <= y; x += 1) {
if (deepColumnsRef?.current?.length && deepDataSourceRef?.current?.length) {
const key = deepColumnsRef?.current[x].dataIndex;
if (!(key in deepDataSourceRef?.current[i])) {
return true;
}
}
}
return false;
}
function getLeafNodes(data) {
const leafNodes = [];
function checkChildren(nodes) {
// eslint-disable-next-line no-restricted-syntax
for (const node of nodes) {
if (!node.children || node.children?.length === 0) {
leafNodes.push(node);
} else {
checkChildren(node?.children);
}
}
}
checkChildren(data);
return leafNodes;
}