UNPKG

linkmore-design

Version:

🌈 🚀lm组件库。🚀

1,465 lines (1,436 loc) 61.1 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _sortable = require("@dnd-kit/sortable"); var _moment = _interopRequireDefault(require("moment")); var _checkbox = _interopRequireDefault(require("../checkbox")); var _datePicker = _interopRequireDefault(require("../date-picker")); var _form = _interopRequireDefault(require("../form")); var _iconFont = _interopRequireDefault(require("../icon-font")); var _input = _interopRequireDefault(require("../input")); var _inputNumber = _interopRequireDefault(require("../input-number")); var _toFixed = require("../lm-table/toFixed"); var _radio = _interopRequireDefault(require("../radio")); var _select = _interopRequireDefault(require("../select")); var _switch = _interopRequireDefault(require("../switch")); var _table = _interopRequireDefault(require("../table")); var _ahooks = require("ahooks"); var _classnames = _interopRequireDefault(require("classnames")); var _immer = require("immer"); var _lodash = require("lodash"); var _react = _interopRequireWildcard(require("react")); var _configProvider = _interopRequireDefault(require("../config-provider")); var _context = require("../config-provider/context"); var _empty = _interopRequireDefault(require("../empty")); var _en_US = _interopRequireDefault(require("../locale/en_US")); var _uploadOss = _interopRequireDefault(require("../upload-oss")); var _components = require("./components"); var _resizableHeader = _interopRequireDefault(require("./components/resizableHeader")); var _DndContainer = _interopRequireDefault(require("./DndContainer")); var _DragHandle = _interopRequireDefault(require("./DragHandle")); var _sortableBoxCol = _interopRequireDefault(require("./sortableBoxCol")); var _sortableItem = _interopRequireDefault(require("./sortableItem")); var _sortableItemCol = _interopRequireDefault(require("./sortableItemCol")); var _util = require("./util"); var _virtual = require("./virtual"); /* tslint:disable */ /* eslint-disable no-unused-vars */ const { UploadBtn } = _uploadOss.default; const EditableContext = /*#__PURE__*/_react.default.createContext(null); // | 'Hide(隐藏)=0' // | 'Read(只读)=1' const decimalLists = ['amount', 'price', 'number']; // 表格行 const EditableRow = ({ index, virtual, ...props }) => { const [form] = _form.default.useForm(); const { dataKey, pushAllForm } = props; pushAllForm?.(form, dataKey, index); return /*#__PURE__*/_react.default.createElement(_form.default, { form: form, disabled: props.disabled || false, component: false }, /*#__PURE__*/_react.default.createElement(EditableContext.Provider, { value: form }, virtual ? /*#__PURE__*/_react.default.createElement(_virtual.VirtualRow, props) : /*#__PURE__*/_react.default.createElement("tr", props))); }; const EditableSortRow = ({ index, ...props }) => { const [form] = _form.default.useForm(); const { dataKey, pushAllForm } = props; pushAllForm?.(form, dataKey, index); return /*#__PURE__*/_react.default.createElement(_form.default, { form: form, disabled: props.disabled || false, component: false }, /*#__PURE__*/_react.default.createElement(EditableContext.Provider, { value: form }, /*#__PURE__*/_react.default.createElement(_sortableItem.default, props))); }; const UploadSingle = props => { const { value, onChange, editEnum } = props; const handleDelete = () => { onChange?.(); }; return /*#__PURE__*/_react.default.createElement("div", { className: "upload_single" }, value ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_iconFont.default, { type: "lmweb-link", style: { fontSize: 14, color: '#1890ff' } }), /*#__PURE__*/_react.default.createElement("a", { href: `${value?.externalUrl}/${value?.filePath}${value?.realFileName}`, target: "_blank", rel: "noreferrer" }, value?.fileName), /*#__PURE__*/_react.default.createElement(_iconFont.default, { type: "lmweb-delete", style: { fontSize: 14, color: '#1890ff' }, onClick: handleDelete })) : /*#__PURE__*/_react.default.createElement(UploadBtn, (0, _extends2.default)({}, editEnum, { value: value, onChange: onChange }))); }; const InputRange = ({ value = ['', ''], onChange, record, rowIndex, colIndex, validator, ...editEnum }) => { // 输入值改变 const history = (0, _react.useRef)([]); const [nValue, setValue] = (0, _react.useState)([]); const { locale: contextLocale = _en_US.default } = _react.default.useContext(_context.ConfigContext); const tableLocale = { ...contextLocale.Table }; (0, _react.useEffect)(() => { setValue(value); }, value); const handleFocus = () => { history.current.push(nValue); }; const handleInput = (e, type) => { const v = type === 'prev' ? [e.target.value, nValue[1]] : [nValue[0], e.target.value]; setValue(v); onChange(v); history.current.push(v); }; const handleBlur = (e, type) => { const isFun = (0, _lodash.isFunction)(validator); // 验证历史记录 const traverse = arr => { if (!arr || !arr.length) { if (type === 'prev') { setValue(['', nValue[1]]); } else if (type === 'next') { setValue([nValue[0], '']); } history.current = []; return; } const value = arr.pop(); if (isFun && validator(record, value, rowIndex, colIndex)) { setValue(value); history.current = []; } else { traverse(arr); } }; traverse(history.current); }; return /*#__PURE__*/_react.default.createElement("div", { className: "lm_editTable_wrapperRange" }, /*#__PURE__*/_react.default.createElement("div", { className: "inputRange" }, /*#__PURE__*/_react.default.createElement(_input.default, (0, _extends2.default)({ value: nValue?.[0], placeholder: tableLocale.placeholder || '请输入', onFocus: e => handleFocus(), onBlur: e => handleBlur(e, 'prev'), onChange: e => handleInput(e, 'prev') }, editEnum)), "~", /*#__PURE__*/_react.default.createElement(_input.default, (0, _extends2.default)({ value: nValue?.[1], placeholder: tableLocale.placeholder || '请输入', onFocus: e => handleFocus(), onBlur: e => handleBlur(e, 'next'), onChange: e => handleInput(e, 'next') }, editEnum)))); }; /* 表格单元格 editEnum: 下拉框时的数据数组(非数组时是配置设置) valueType: 编辑框配置(多选) */ const EditableCell = props => { const { record = {}, rowKey, isEdit, col = {}, rowIndex, colIndex, handleTableRowDelete, handleTableRowAdd, quickOpetateClearAll, getLength, isHoverEdit, editEnum, valueType, children, handleSave, handleAdd, handleDelete, handleCopy, handlePaste, itemProps, initialiZindex, columnsValueDecimal, // reWriteOriginSource, ...restProps } = props; /** 去除移入移出功能,保留最纯粹的功能,优化性能 */ const { onMouseEnter, onMouseLeave, ...clearProps } = restProps; const { componentProps = {}, dataIndex, decimalType } = col; /** 是否正在编辑中 */ const [editing, setEditing] = (0, _react.useState)(false); const inputRef = (0, _react.useRef)(null); const form = (0, _react.useContext)(EditableContext); const { locale: contextLocale = _en_US.default } = _react.default.useContext(_context.ConfigContext); const tableLocale = { ...contextLocale.Table }; const [hoverStatus, setHoverStatus] = (0, _react.useState)(false); (0, _react.useEffect)(() => { if (editing) { inputRef?.current?.focus(); } }, [editing]); const toggleEdit = () => { setEditing(!editing); // form.setFieldsValue({ [dataIndex]: record[dataIndex] }); }; // 校验保存 const save = async row => { try { const values = row ? (0, _lodash.omit)(row, 'onChange') : await form.getFieldsValue(); const resultComponentProps = (0, _lodash.isFunction)(componentProps) ? componentProps?.(record, col) : componentProps; // console.time('testForEach'); /** 如果属于中有唯一性,并且当前的值与唯一值不一致,则改变其他的 */ if (resultComponentProps.isOnlyValue !== undefined && values[dataIndex] !== record[dataIndex] && ![undefined, null].includes(values[dataIndex])) { handleSave({ ...record, ...values, [rowKey]: record?.[rowKey] }, { only: { key: dataIndex, value: resultComponentProps.isOnlyValue } }); } else { handleSave({ ...record, ...values, [rowKey]: record?.[rowKey] }); } // console.timeEnd('testForEach'); await form.validateFields([dataIndex]); if (col?.hoverEdit) { toggleEdit(); } } catch (errInfo) {} }; // 触发保存 const handleFormItemChange = e => { save?.(); }; /** 快捷刷子,把当前的所有列的值,刷成当前的选中的列 */ const copyKey = (e, type) => { e?.stopPropagation(); const { dataIndex } = col; handleCopy?.(dataIndex, record[dataIndex], type, props.rowIndex); }; const Control = con => { let resultComponentProps = (0, _lodash.isFunction)(componentProps) ? componentProps?.(record, col) : componentProps; if ((0, _lodash.isFunction)(componentProps) && col?.newOptions?.length) { resultComponentProps = { ...resultComponentProps, options: col?.newOptions }; } const clearAttrComponentProps = (0, _lodash.omit)(resultComponentProps, ['optionOnly', 'isOnlyValue', 'quickcopy']); const mergeColDecimal = { number: null, price: null, amount: 2, ...(columnsValueDecimal || {}) }; switch (con) { case 'input': return /*#__PURE__*/_react.default.createElement(_input.default, (0, _extends2.default)({ onPressEnter: handleFormItemChange, onBlur: handleFormItemChange, ref: inputRef, placeholder: tableLocale.placeholder || '请输入' }, clearAttrComponentProps, { addonBefore: resultComponentProps.addonBefore ? /*#__PURE__*/_react.default.createElement(_form.default.Item, { name: [col.dataIndex, 'addonBeforeValue'], noStyle: true }, /*#__PURE__*/_react.default.cloneElement(resultComponentProps.addonBefore, { onChange: handleFormItemChange })) : null, addonAfter: resultComponentProps.addonAfter ? /*#__PURE__*/_react.default.createElement(_form.default.Item, { name: [col.dataIndex, 'addonAfterValue'], noStyle: true }, /*#__PURE__*/_react.default.cloneElement(resultComponentProps.addonAfter, { onChange: handleFormItemChange })) : null })); case 'inputRange': return /*#__PURE__*/_react.default.createElement(InputRange, (0, _extends2.default)({ onChange: handleFormItemChange // ref={inputRef} }, resultComponentProps, { record: record, rowIndex: rowIndex, colIndex: colIndex })); case 'number': return /*#__PURE__*/_react.default.createElement(_inputNumber.default, (0, _extends2.default)({ onPressEnter: handleFormItemChange, onBlur: handleFormItemChange, style: { width: editEnum?.width || '100%' }, placeholder: tableLocale.placeholder || '请输入', ref: inputRef, precision: mergeColDecimal[col.decimalType] || 0 }, clearAttrComponentProps)); case 'date': // @ts-ignore return /*#__PURE__*/_react.default.createElement(_datePicker.default, (0, _extends2.default)({ onChange: handleFormItemChange // getPopupContainer={(triggerNode: any) => // triggerNode.closest(SCROLL_POSITION_DOT_CLASS_NAME) || document.body // } }, clearAttrComponentProps)); case 'select': return /*#__PURE__*/_react.default.createElement(_select.default, (0, _extends2.default)({ showSearch: true, allowClear: true, placeholder: tableLocale.placeholderSelect || '请选择', ref: inputRef, style: { width: '100%' }, filterOption: (input, option) => option.children?.toLowerCase()?.indexOf(input.toLowerCase()) >= 0 // getPopupContainer={(triggerNode: any) => // triggerNode.closest(SCROLL_POSITION_DOT_CLASS_NAME) || document.body // } }, clearAttrComponentProps, { onChange: handleFormItemChange })); case 'multiple': return /*#__PURE__*/_react.default.createElement(_select.default, (0, _extends2.default)({ mode: "multiple", showSearch: true, allowClear: true, placeholder: tableLocale.placeholderSelect || '请选择', ref: inputRef, filterOption: (input, option) => option.children?.toLowerCase().indexOf(input.toLowerCase()) >= 0, onChange: handleFormItemChange, onDeselect: handleFormItemChange // getPopupContainer={(triggerNode: any) => // triggerNode.closest(SCROLL_POSITION_DOT_CLASS_NAME) || document.body // } }, clearAttrComponentProps)); case 'checkbox': return /*#__PURE__*/_react.default.createElement(_checkbox.default.Group, (0, _extends2.default)({ onChange: handleFormItemChange, ref: inputRef }, clearAttrComponentProps)); case 'checkboxSingle': return /*#__PURE__*/_react.default.createElement(_checkbox.default, (0, _extends2.default)({ onChange: handleFormItemChange, ref: inputRef }, clearAttrComponentProps)); case 'radio': return /*#__PURE__*/_react.default.createElement(_radio.default, (0, _extends2.default)({ onChange: handleFormItemChange }, clearAttrComponentProps)); case 'radioGroup': return /*#__PURE__*/_react.default.createElement(_radio.default.Group, (0, _extends2.default)({ onChange: handleFormItemChange, ref: inputRef }, clearAttrComponentProps)); case 'switch': return /*#__PURE__*/_react.default.createElement(_switch.default, (0, _extends2.default)({ size: "small" }, clearAttrComponentProps, { onChange: handleFormItemChange })); case 'upload': return /*#__PURE__*/_react.default.createElement(UploadSingle, { editEnum: resultComponentProps, ref: inputRef, onChange: handleFormItemChange }); case 'operate': case 'lm_edit_opetate': return /*#__PURE__*/_react.default.createElement(_components.QuickOpetate, (0, _extends2.default)({ record: record, rowKey: rowKey, handleAdd: handleTableRowAdd, handleDelete: handleTableRowDelete, getLength: getLength, quickOpetateClearAll: quickOpetateClearAll }, resultComponentProps)); case 'render': { const { render } = resultComponentProps; const fromData = form?.getFieldsValue(); return render?.({ ...(!(0, _util.isObjEmpty)(fromData) ? { ...record, [dataIndex]: fromData[dataIndex] } : record), onChange: save }, rowIndex); } default: return /*#__PURE__*/_react.default.createElement(_input.default, (0, _extends2.default)({ onPressEnter: handleFormItemChange, onBlur: handleFormItemChange, ref: inputRef }, resultComponentProps)); } }; const getMemoChildNode = (0, _react.useMemo)(() => { const { editable, dataIndex, formProps, componentProps, hoverEdit } = col; const carryOutFormProps = (0, _lodash.isFunction)(formProps) ? formProps?.(record, col) : formProps; const resultComponentProps = (0, _lodash.isFunction)(componentProps) ? componentProps?.(record, col) : componentProps; let childNode = children; if (hoverEdit && !editing) { childNode = /*#__PURE__*/_react.default.createElement("div", { className: "editable-cell-value-wrap", style: { minHeight: '22px' }, onClick: toggleEdit }, childNode); } else if (isEdit && editable) { childNode = (0, _util.isExpandRow)(childNode) ? /*#__PURE__*/_react.default.createElement("div", { style: { display: 'flex', flexDirection: 'row', flexWrap: 'nowrap' } }, (0, _util.isExpandRow)(childNode) && childNode[0], /*#__PURE__*/_react.default.createElement(_form.default.Item, (0, _extends2.default)({ errorPlacement: "right", valuePropName: editable === 'switch' ? 'checked' : 'value', style: { margin: 0 }, noStyle: !!formProps ? false : true }, carryOutFormProps, { name: dataIndex }), Control(editable))) : /*#__PURE__*/_react.default.createElement(_form.default.Item, (0, _extends2.default)({ errorPlacement: "right", valuePropName: editable === 'switch' ? 'checked' : 'value', style: { margin: 0 }, noStyle: !!formProps ? false : true }, carryOutFormProps, { name: dataIndex }), Control(editable)); if (editable === 'input' && (resultComponentProps?.addonBefore || resultComponentProps?.addonAfter)) { childNode = (0, _util.isExpandRow)(childNode) ? /*#__PURE__*/_react.default.createElement("div", { style: { display: 'flex', flexDirection: 'row', flexWrap: 'nowrap' } }, (0, _util.isExpandRow)(childNode) && childNode[0], /*#__PURE__*/_react.default.createElement(_form.default.Item, (0, _extends2.default)({ errorPlacement: "right", style: { margin: 0 } }, carryOutFormProps, { noStyle: !!formProps ? false : true, name: [dataIndex, 'value'] }), Control(editable))) : /*#__PURE__*/_react.default.createElement(_form.default.Item, (0, _extends2.default)({ errorPlacement: "right", style: { margin: 0 } }, carryOutFormProps, { noStyle: !!formProps ? false : true, name: [dataIndex, 'value'] }), Control(editable)); } } else if (!isEdit && componentProps?.options) { return componentProps?.options?.find(item => item.value === record[dataIndex])?.label || childNode; } return childNode; }, [col, isEdit, editing, getLength, record]); // 出现死循环找我 (0, _react.useEffect)(() => { const { editable, dataIndex } = col; if (isEdit && editable) { form?.setFieldsValue({ [dataIndex]: editable === 'date' && record[dataIndex] ? (0, _moment.default)(record[dataIndex]) : record[dataIndex] }); } }, [record]); const handleTdHover = () => { setHoverStatus(true); }; const handleTdMouseOut = () => { setHoverStatus(false); }; const handleTdPaste = (e, type) => { handlePaste(e, type, { rowIndex, colIndex, dataIndex }); }; return /*#__PURE__*/_react.default.createElement("td", (0, _extends2.default)({}, (0, _lodash.omit)(clearProps, ['dataIndex']), { className: (0, _classnames.default)(clearProps?.className, 'lm_custom_cell_td'), onMouseEnter: componentProps.quickcopy ? handleTdHover : undefined, onMouseLeave: componentProps.quickcopy ? handleTdMouseOut : undefined, onPaste: handleTdPaste, style: col?.fixed ? { ...clearProps?.style, zIndex: (initialiZindex || 0) - (Number(col?.order) || 0) } : { ...clearProps?.style }, key: `r${rowIndex}_c${colIndex}` }), hoverStatus && props.rowIndex > 0 && /*#__PURE__*/_react.default.createElement("span", { className: "quick_copy_warp quick_copy_up", onClick: e => copyKey(e, 'up') }, /*#__PURE__*/_react.default.createElement(_iconFont.default, { type: "lmweb-icon_up" })), getMemoChildNode, hoverStatus && props.rowIndex < props.getLength - 1 && /*#__PURE__*/_react.default.createElement("span", { className: "quick_copy_warp quick_copy_down", onClick: e => copyKey(e, 'down') }, /*#__PURE__*/_react.default.createElement(_iconFont.default, { type: "lmweb-icon_down" }))); }; /** true 不刷新, false 刷新 */ const MemoEditableCell = /*#__PURE__*/(0, _react.memo)(EditableCell, (prev, next) => { const pickProps = ['record', 'colIndex']; const p = (0, _lodash.pick)(prev, pickProps); const n = (0, _lodash.pick)(next, pickProps); if (next?.shouldUpdate) { return false; } // console.log(!checkMemoShouldUploadSpecialFun(prev, next), isEqual(p, n), '22', prev.record, next.record) // console.log('333', checkMemoShouldUploadSpecialFun(prev, next), isEqual(p, n)) /** TODO: 在record中带有children,子列表数据修改之后,会导致父级的record对比不一样 */ if (!(0, _util.checkMemoShouldUploadSpecialFun)(prev, next)) { return false; } return (0, _lodash.isEqual)(p, n); }); const EditTable = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => { const { /** dataSource */ value: defaultData, /** 表头 */ columns: defaultColumns, /** 是否开启编辑模式 */ isEdit, /** 底下是否需要默认出现add */ isAdd = false, onChange, // 触发粘贴事件 onPaste, rowKey = '_ID', /** 整个表格为hover点击模式 */ rowHoverEdit, /** 是否在form表单中使用 */ isUseForm = true, isHoverEdit, /** 使用快捷操作选项 */ useQuickOpetate, quickOpetateClearAll = true, rowSelection, /** 需要disabled的列 */ rowDisabled, /** 开启虚拟化 */ virtual, /** 开启行排序 */ sortOpen, /** 表格是否为编辑状态 */ disabled, /** 开启列排序 */ colSortOpen, /** 是否开启索引列 */ indexCol = false, filterChange, size = 'middle', recordCreatorProps, shouldUpdate = false, loading = false, /** 是否要开启自适应 */ autoSizer = false, initialiZindex = 100, resizable = false, /** 空状态数据 */ emptyProps, roleFiledKeys = [], columnsValueDecimal = { amount: 2 }, ...resetProps } = props; const [dataSource, setDataSource] = (0, _ahooks.useControllableValue)({ value: (0, _util.checkRowKeyByDataSource)(props.value, rowKey), onChange: props.onChange }); const { locale: contextLocale = _en_US.default } = _react.default.useContext(_context.ConfigContext); const tableLocale = { ...contextLocale.Table }; const [columns, setColumns] = (0, _react.useState)(defaultColumns); const transformRowSelect = (selectedRowKeys, selectedRows, info) => rowSelection?.onChange?.(selectedRowKeys, selectedRows, info); const [localRowSelectList, setLocalRowSelectList] = (0, _ahooks.useControllableValue)({ value: { selectedRows: rowSelection?.selectedRows || rowSelection?.selectedRowKeys || [] }, onChange: rowSelection?.onChange ? transformRowSelect : undefined }); const [localDisabledRows] = (0, _ahooks.useControllableValue)({ value: { disabledRows: rowDisabled?.disabledRows || [] } }); /** TODO: 当前展开的列 */ const [expandedRowKeys, setExpandedRowKeys] = (0, _react.useState)([]); const dataSourceRef = (0, _react.useRef)(dataSource); const deepDataSourceRef = (0, _react.useRef)((0, _util.deepDataSourcePreKeys)(dataSource, rowKey)); dataSourceRef.current = dataSource; deepDataSourceRef.current = (0, _util.deepDataSourcePreKeys)(dataSource, rowKey); const disabledDataSourceRowKeys = (0, _react.useRef)((0, _util.checkTableRowIsDisable)(deepDataSourceRef.current, localDisabledRows.disabledRows, rowKey)); disabledDataSourceRowKeys.current = (0, _util.checkTableRowIsDisable)(deepDataSourceRef.current, localDisabledRows.disabledRows, rowKey); const columnsRef = (0, _react.useRef)(defaultColumns); (0, _react.useEffect)(() => { setColumns(defaultColumns); }, [defaultColumns]); const tableWarpRef = (0, _react.useRef)(null); const autoSizerRef = (0, _react.useRef)(null); const allFormListRef = (0, _react.useRef)({}); const scrollToIndexRef = (0, _react.useRef)(null); const [checkForm] = _form.default.useForm(); const onColSortEnd = (active, over) => { const oldIndex = columns.findIndex(item => item.dataIndex === active); const newIndex = columns.findIndex(item => item.dataIndex === over); filterChange?.((0, _sortable.arrayMove)(columns, oldIndex, newIndex)?.map((item, index) => ({ ...item, order: index }))); }; // 删除 const handleDelete = key => { const nValue = dataSource.filter(item => item[rowKey] !== key); setDataSource(nValue); }; /** 点击底部添加按钮添加 */ const handleAdd = (0, _lodash.debounce)(row => { const addDataInfo = (0, _lodash.isFunction)(recordCreatorProps?.initData) ? recordCreatorProps?.initData?.() : recordCreatorProps?.initData; const res = (0, _immer.produce)(dataSourceRef.current, draft => { draft.push({ [rowKey]: `${Date.now()}`, ...(addDataInfo || {}) }); }); setDataSource(res); }, 40); // const reWriteOriginSource = (rowKey: string, rowValue, dataIndex: number, nextValue) => { // setDataSource((prevDataSource) => { // return prevDataSource?.map((item) => { // if (get(item, rowKey) === rowValue) { // set(item, dataIndex, nextValue) // } // return item // }) // }) // } // @ts-ignore /** 删除当前行 */ const handleTableRowDelete = (0, _lodash.debounce)(key => { const rkey = (0, _lodash.isObject)(key) ? key[rowKey] : key; const preKeys = deepDataSourceRef?.current?.[rkey]?.preKeys; if (preKeys.length > 1) { /** 说明删除的是children中的数据 */ function filter(data, key) { let newData = data?.filter(x => x[rowKey] !== key); newData?.forEach(x => { if (x.children) { let c = filter(x.children, key); x.children = c; if (!c.length) { delete x.children; } } }); return newData; } const res = filter(dataSourceRef.current, key); setDataSource(res); } else { if (dataSourceRef.current?.length === 1 && !quickOpetateClearAll) { return false; } const res = (0, _immer.produce)(dataSourceRef.current, draft => { const index = draft.findIndex(item => key === item[rowKey]); if (index !== -1) { draft.splice(index, 1); } }); setDataSource(res); } return null; }, 40); /** 替换当前行 */ const handleTableRowReplace = (0, _lodash.debounce)((record, defaultRecord) => { const rkey = (0, _lodash.isObject)(record) ? record[rowKey] : record; const preKeys = deepDataSourceRef?.current?.[rkey]?.preKeys; // const res = cloneDeep(dataSourceRef.current) const deep = children => { return children.map(item => { if (item[rowKey] === rkey) { return defaultRecord; } else if (preKeys.includes(item[rowKey]) && item.children) { const child = deep(item.children); return { ...item, children: child }; } else { return item; } }); }; const res = deep(dataSourceRef.current); setDataSource(res); }, 20); /** 快捷添加 */ const handleTableRowAdd = (0, _lodash.debounce)((record, isAppendInChindren, defaultRecord) => { const rkey = (0, _lodash.isObject)(record) ? record[rowKey] : record; const preKeys = deepDataSourceRef?.current?.[rkey]?.preKeys; const res = (0, _immer.produce)(dataSourceRef.current, draft => { if (preKeys?.length > 1) { function deeps(children) { children?.forEach((item, index) => { if (preKeys?.includes(item[rowKey])) { if (item[rowKey] === rkey) { if (isAppendInChindren) { if (item?.children) { if (Array.isArray(defaultRecord)) { item?.children?.push(...defaultRecord); } else { item?.children?.push(defaultRecord || { [rowKey]: `${Date.now()}` }); } } else { if (Array.isArray(defaultRecord)) { item.children = [...defaultRecord]; } else { item.children = [defaultRecord || { [rowKey]: `${Date.now()}` }]; } } !expandedRowKeys.includes(item[rowKey]) && setExpandedRowKeys([...expandedRowKeys, item[rowKey]]); } else { if (Array.isArray(defaultRecord)) { children.splice(index + 1, 0, ...defaultRecord); } else { children.splice(index + 1, 0, defaultRecord || { [rowKey]: `${Date.now()}` }); } } } else if (item.children) { deeps(item.children); } } }); } deeps(draft); } else { const index = draft.findIndex(item => rkey === item[rowKey]); if (index !== -1) { if (isAppendInChindren) { if (draft[index].children?.length) { if (Array.isArray(defaultRecord)) { draft[index].children?.push(...defaultRecord); } else { draft[index].children?.push(defaultRecord || { [rowKey]: `${Date.now()}` }); } } else { draft[index].children = Array.isArray(defaultRecord) ? [...defaultRecord] : [defaultRecord || { [rowKey]: `${Date.now()}` }]; } !expandedRowKeys.includes(draft[index]?.[rowKey]) && setExpandedRowKeys([...expandedRowKeys, draft[index]?.[rowKey]]); } else { if (Array.isArray(defaultRecord)) { draft.splice(index + 1, 0, ...defaultRecord); } else { draft.splice(index + 1, 0, defaultRecord || { [rowKey]: `${Date.now()}` }); } } } } }); setDataSource(res); }, 50); const handleSave = (row, options) => { const preKeys = deepDataSourceRef?.current?.[row[rowKey]]?.preKeys; if (options?.only) { const res = (0, _immer.produce)(dataSourceRef.current, draft => { if (options?.only) { const { key, value } = options?.only; if (preKeys?.length > 1) { function deeps(children) { children?.forEach(item => { if (preKeys.includes(item[rowKey])) { if (item[rowKey] === row[rowKey]) { children?.forEach(c => { c[key] = value; }); Object.keys(item)?.forEach(v => { item[v] = row[v] || item[v]; }); } else if (item.children) { deeps(item.children); } } }); } deeps(draft); } else { draft?.forEach((item, index) => { if (row[rowKey] === item[rowKey]) { draft[index] = row; } else { draft[index][key] = value; } }); } } else { if (preKeys?.length > 1) { function deeps(children) { children?.forEach(item => { if (preKeys.includes(item[rowKey])) { if (item[rowKey] === row[rowKey]) { Object.keys(row)?.forEach(v => { item[v] = row[v] || item[v]; }); } else if (item.children) { deeps(item.children); } } }); } deeps(draft); } else { const index = draft.findIndex(item => row[rowKey] === item[rowKey]); if (index !== -1) { draft[index] = row; } } } }); setDataSource(res); } else { handleTableRowReplace(row[rowKey], row); } }; /** 快捷刷子功能 */ const handleCopy = async (key, value, type, rowIndex) => { const res = (0, _immer.produce)(dataSourceRef.current, draft => { draft?.forEach((item, index) => { if (type === 'up' && index < rowIndex || type === 'down' && index > rowIndex) { item[key] = value; } }); }); const formatCopyDataSource = props.copyFormat ? await props.copyFormat(res, { key, value, type, rowIndex }) : res; setDataSource(formatCopyDataSource); }; /* 快捷粘贴功能 */ const handlePaste = (event, type, { rowIndex, colIndex, dataIndex }) => { // let curDataSource = dataSourceRef.current // const curColIndex = columns.findIndex((v) => v.dataIndex === dataIndex) // 当前列Index // const datas = curDataSource.concat(new Array(rowIndex + pasteValues.length - curDataSource.length).fill({})) // const _ID = Date.now() // const newData = datas.map((record = {}, index) => { // // 若选中的行索引 // if (index >= rowIndex) { // const newRowArr = pasteValues[index - rowIndex] // 获取插入的行数据 // newRowArr.forEach((val, valIndex) => { // const curDataIndex = columns[curColIndex + valIndex].dataIndex // record[curDataIndex] = val // }) // } // return { _ID: _ID + index, ...record } // }) // data.map((record, index) => { // console.log('record', record[colIndex]) // // const curPaste = pasteValues[index]; // 当前粘贴行数据 // // record[dataIndex] = record[dataIndex] + curPaste[colIndex] // }) // 根据列的索引获取列 /* 打平列结构: 排除了group */ const flatColumns = arr => { return arr.reduce((pre, cur) => { const child = cur?.children?.length ? flatColumns(cur.children) : [cur]; return [...pre, ...child]; }, []); // const result = [] // for (let i = 0; i < arr.length; i++) { // const item = arr[i] // if (item?.children?.length) { // const child = flatColumns(item.children) // result.push(...child) // continue // } // result.push(item) // } // return result }; const getColumnsByIndex = colIndex => flatColumns(columns)?.[colIndex]; onPaste?.({ event, type, dataSource, getColumnsByIndex, rowIndex, colIndex, dataIndex }); }; /** 判断columne中有没有带optionOnly参数 */ const hasDisableOptions = (0, _react.useMemo)(() => { const hasOnlyOptionsDatas = columns.filter(item => { const resultComponentProps = (0, _lodash.isFunction)(item?.componentProps) ? item?.componentProps?.({}, item) : item?.componentProps; return resultComponentProps?.optionOnly; }); // const hasOnlyOptionsDatas = columns.filter((item) => item?.componentProps?.optionOnly) if (hasOnlyOptionsDatas.length) { return hasOnlyOptionsDatas?.map(item => item.dataIndex); } return false; }, [columns]); /** 动态获取disabled的props数据源 */ const DisableOptions = (0, _react.useMemo)(() => { const newColumns = columns?.map(item => { const resultComponentProps = (0, _lodash.isFunction)(item.componentProps) ? item.componentProps?.({}, item) : item.componentProps; const { optionOnly, options } = resultComponentProps || {}; if (optionOnly && options) { const { dataIndex } = item; const dataIndexData = dataSource?.map(d => d[dataIndex]); const newOptions = options?.map(o => { return { ...o, disabled: !!dataIndexData.includes(o?.value) }; }); if ((0, _lodash.isFunction)(item.componentProps)) { return { ...item, newOptions }; } return { ...item, componentProps: { ...item.componentProps, options: newOptions } }; } else { return item; } }); return newColumns; }, [columns, dataSource]); const memoOptions = (0, _react.useMemo)(() => { return hasDisableOptions ? [DisableOptions] : []; }, [hasDisableOptions, DisableOptions]); const typeofRoleFiledKeys = _react.default.useMemo(() => { let roleHideKeys = []; let roleReadOnlyKeys = []; roleFiledKeys.forEach(item => { if (item.type === 0) { roleHideKeys.push(item.key); } else if (item.type === 1) { roleReadOnlyKeys.push(item.key); } }); return { roleHideKeys, roleReadOnlyKeys }; }, [roleFiledKeys]); const handleResize = dataIndex => (e, { size }) => { console.log(dataIndex, size, 'index, size', columns); const nextColumns = [...columns]?.map(item => { return item.dataIndex === dataIndex ? { ...item, width: size.width } : item; }); // let i = index // const nextColumns = [...resultColumns] // nextColumns.forEach((item, index) => { // if (index <= i && item.show === false) { // i += 1 // } // }) // nextColumns[i] = { // ...nextColumns[i], // width: size.width, // } console.log(nextColumns, 'nextColumns'); setColumns(nextColumns); }; /** 列宽拖动结束事件 */ const endResize = () => { setTimeout(() => { filterChange?.(columns); }); }; /** 组装之后的最终columns */ const resultColumns = (0, _react.useMemo)(() => { const rColumns = hasDisableOptions ? DisableOptions : columns; let localColumns = [sortOpen ? { title: tableLocale?.sort || '排序', dataIndex: '_sort', width: 60, maxWidth: 60, className: 'drag-visible', fixed: 'left', order: -2, render: (_, record) => { return /*#__PURE__*/_react.default.createElement(_DragHandle.default, { id: record?.[rowKey] || record?.id }); } } : null, indexCol ? (0, _lodash.isBoolean)(indexCol) ? { title: '', dataIndex: '_index', width: 48, maxWidth: 48, ellipsis: true, fixed: 'left', order: -1, render: (_, record, index) => { return deepDataSourceRef.current?.[record[rowKey]]?.['_deepIds']?.join('-') || `${index + 1}`; } } : { title: '', dataIndex: '_index', width: 48, ellipsis: true, maxWidth: 48, order: -1, fixed: 'left', ...(indexCol || {}), render: (_, record, index) => { if ((0, _lodash.isFunction)(indexCol?.render)) { return indexCol?.render?.(record, deepDataSourceRef.current?.[record[rowKey]]?.['_deepIds']); } return deepDataSourceRef.current?.[record[rowKey]]?.['_deepIds']?.join('-') || `${index + 1}`; } } : null, ...rColumns, useQuickOpetate ? { title: tableLocale?.opetate || '操作', dataIndex: 'lm_edit_opetate', width: 88, maxWidth: 88, fixed: 'right', editable: 'lm_edit_opetate', className: 'lm_edit_opetate', componentProps: { options: Array.isArray(useQuickOpetate) ? useQuickOpetate : ['add', 'delete'] } } : null].filter(item => item && item?.show !== false); localColumns = localColumns?.map((item, index) => { const mergeColDecimal = { number: null, price: null, amount: 2, ...(columnsValueDecimal || {}) }; const { decimalType } = item; const hasDecimal = decimalLists?.includes(decimalType); return { ...item, align: item.align || (hasDecimal ? 'right' : 'left'), render: item.render ? item.render : hasDecimal && !!mergeColDecimal[decimalType] ? text => /*#__PURE__*/_react.default.createElement("span", { style: { textAlign: 'right' } }, (0, _toFixed.toFixedNumber)(text, mergeColDecimal[decimalType])) : null, order: [null, undefined].includes(item.order) ? index : item.order }; }).sort((a, b) => a.order - b.order); const leftColumns = []; const mainColumns = []; const rightColumns = []; localColumns?.forEach(item => { if (item?.fixed === 'left' || item?.fixed === true) { leftColumns.push(item); } else if (item?.fixed === 'right') { rightColumns.push(item); } else { mainColumns.push(item); } }); localColumns = [...leftColumns, ...mainColumns, ...rightColumns]; const { roleHideKeys, roleReadOnlyKeys } = typeofRoleFiledKeys; /** 为了支持colums中的分组之后,进行递归处理 */ const mapColumns = (col, index) => { if (!col.editable && !col.children?.length && col?.dataIndex === '_sort') { const fn = col?.render; return { ...col, render: (text, record, i) => fn?.(dataSource[i]?.[col.dataIndex], dataSource[i], i) }; } if (isEdit && col?.render && col?.editable === 'render') { // delete col.render try { delete col.render; } catch { col = (0, _lodash.omit)(col, ['render']); } } /** TODO: 如果存在只读列表中,则默认添加一个disable,但可以被外部的覆盖 */ if (!(0, _lodash.isFunction)(col.componentProps) && col.editable && col.editable !== 'render' && roleReadOnlyKeys.includes(col.roleKey || col.dataIndex)) { col.componentProps = { disabled: true, ...(col.componentProps || {}) }; } const newCol = { onCell: (record, rowIndex) => { return { getLength: dataSource.length, rowKey, record, col, rowIndex, colIndex: index, initialiZindex, quickOpetateClearAll, handleTableRowDelete, handleTableRowAdd, editable: col.editable, dataIndex: col.dataIndex, itemProps: col.itemProps, shouldUpdate, isEdit, isHoverEdit, handleAdd, handleDelete, handleCopy, handlePaste, editEnum: typeof col.editEnum === 'function' ? col.editEnum(record) : col.editEnum, valueType: typeof col.valueType === 'function' ? col.valueType(record) : col.valueType, handleSave, columnsValueDecimal }; }, ...col }; if (col?.children) { return { ...col, children: col.children?.map((chilCol, chilIndex) => mapColumns(chilCol, index + chilIndex)) }; } return newCol; }; const { result } = localColumns.reduce((pre, cur) => { const result = mapColumns(cur, pre.colIndex); const chilLen = cur?.children?.length; const nextColIndex = pre.colIndex + 1 + (chilLen ? chilLen - 1 : 0); return { result: [...pre.result, result], colIndex: nextColIndex }; }, { result: [], colIndex: 0 }); // const res = localColumns?.map((col, index) => mapColumns(col, col.children.length + index)) const filterRoleColumns = columns => { let obj = []; columns?.forEach((item, i) => { if (resizable) { item.onHeaderCell = column => { return { width: column.width, dataIndex: column.dataIndex, onResize: handleResize(item.dataIndex), onResizeStop: endResize }; }; } if (!roleHideKeys.includes(item.roleKey || item.dataIndex)) { obj.push({ ...item, children: filterRoleColumns(item.children) }); } }); return obj; }; const res = filterRoleColumns(result || []); columnsRef.current = res; return res; }, [columns, isAdd, sortOpen, useQuickOpetate, dataSource, roleFiledKeys, resizable, [...memoOptions]]); const onSortEnd = (active, over) => { const cloneArr = [...dataSourceRef.current]; const oldIndex = cloneArr.findIndex(v => v[rowKey] === active); const newIndex = cloneArr.findIndex(v => v[rowKey] === over); setDataSource((0, _sortable.arrayMove)(cloneArr, oldIndex, newIndex)); }; const colDraggableContainer = (0, _react.useCallback)(({ ...props }) => { return /*#__PURE__*/_react.default.createElement("tr", null, _react.default.Children?.map(props.children, child => { if (child?.props?.column?.fixed) { return child; } return /*#__PURE__*/_react.default.createElement(_sortableItemCol.default, { id: child.key }, child); })); }, [columns]); (0, _react.useImperativeHandle)(ref, () => ({ setRow: handleSave, getCheckboxRecords: () => localRowSelectList.selectedRows, deleteRowData: data => handleTableRowDelete(data), addRowData: (data, defaultValue, addInChild) => { return addInChild === 'replace' ? handleTableRowReplace(data, defaultValue) : handleTableRowAdd(data, addInChild, defaultValue); }, getData: () => dataSourceRef.current, clearSelect: () => { setLocalRowSelectList({ selectedRows: [] }); }, customSetCheckboxRecords: value => { setLocalRowSelectList({ selectedRows: value }); }, columns: columns.map(item => { return (0, _lodash.omit)(item, ['render', 'sorter', 'onFilter', 'filters', 'componentProps', 'formProps', 'editable']); }), // verify: async () => { // let allRule = {} // let time // let fullNum = 0 // columns.forEach((col: any) => { // if (col?.formProps?.rules) { // allRule[col.dataIndex] = col?.formProps?.rules || [] // } // }) // const validator = new AsyncValidator(allRule); // let flag = true // let messageIndex = null // let errorRowKey = null // let errorInfo = null // const deepValidator = async (data, index) => { // for (let i = 0; i < data.length; i++) { // if (flag) { // try { // await validator.validate(data[i], (errors, fields) => { // if (errors) { // errorInfo = { errors, fields, value: data[i] }; // flag = false // messageIndex = index === null ? i : index // errorRowKey = data?.[i]?.[rowKey] // } else if (data[i].children) { // deepValidator(data[i].children, i) // } // }) // } catch (error) { // break; // } // } // } // } // await deepValidator(dataSource, null) // console.log(flag, 'fff') // if (flag) { // return Promise.resolve(dataSource) // } else { // setTimeout(() => { // if (messageIndex !== null) { // scrollToIndexRef.current?.(messageIndex, { align: 'center' }) // time = setInterval(async () => { // fullNum++ // if (fullNum > 5) { // clearInterval(time) // } else { // const form = (Object.values(allFormListRef.current || []).find((item: any) => item.key === errorRowKey) as any)?.form // if (form) { // try { // await form.validateFields() // console.log('验证成功') // } catch (error) { // console.log('验证失败', error) // return error // } finally { // clearInterval(time) // } // } // } // }, 500) // } // }, 100) // return Promise.reject(errorInfo) // } // }, verify: async () => { if (virtual) { let time; let fullNum = 0; let flag = true; let messageIndex = null; let errorRowKey = null; let errorInfo = null; const deepValidator = async (data, index) => { for (let i = 0; i < data.length; i++) { if (flag) { try { checkForm.resetFields(); checkForm.setFieldsValue(data[i]); await checkForm.validateFields(); if (data[i].children) { await deepValidator(data[i].children, i); } } catch (error) { errorInfo = { error, value: data[i] }; flag = false; messageIndex = index === null ? i : index; errorRowKey = data?.[i]?.[rowKey]; break; } } } }; await deepValidator(dataSource, null); if (flag) { return Promise.resolve(dataSource); } else { setTimeout(() => { if (messageIndex !== null) { scrollToIndexRef.current?.(messageIndex, { align: 'center' }); time = setInterval(async () => {