
时间紧,任务重。写的有点low,拓展性不好,但能用。
import React, {useState, useEffect} from 'react';
import {TreeSelect, Spin, Badge} from '一个基于 antd 4.18.8 封装的企业内部组件库';
import localeText from '@locale';
import {forEach} from 'lodash';
import './index.less';
const {TreeSelectSearch, TreeNode} = TreeSelect;
Index.defaultProps = {
prefixCls: 'mc-treeSelect',
optionLabel: ''
};
export default function Index(props) {
const {prefixCls, onFetchData, notFoundContent,
handleChange, renderData, defaultValue, optionLabel, hasAllOption, treeDataSimpleMode,
treeNodeFilterProp, treeDefaultExpandedKeys} = props;
const [loading, setLoading] = useState(false);
const [data, setData] = useState(null);
const [searchValue, setSearchValue] = useState<string>('');
const [totalNum, setTotalNum] = useState(0);
const [allCheckedValues, setAllCheckedValues] = useState([]);
const [newValues, setNewValues] = useState(defaultValue);
useEffect(() => {
const vals: string[] = hasAllOption ? ['all'] : [];
let count = 0;
const fn = (d) => {
forEach(d, (item) => {
if (item?.children?.length) {
fn(item.children);
} else {
count++;
vals.push(item.value);
}
});
};
fn(renderData);
setTotalNum(vals.length);
if (defaultValue.length === count) {
setNewValues(vals);
}
setAllCheckedValues(vals);
setData(renderData);
}, [renderData, defaultValue]);
async function focusHandler() {
if (onFetchData) {
setLoading(true);
try {
const newData = await onFetchData() || [];
setData(newData);
} finally {
setLoading(false);
}
}
}
const renderTreeNode = (inputTreeData) => {
if (inputTreeData && inputTreeData.length) {
return inputTreeData.map((node) => {
const {isLeaf, disabled, value, title, children, nodeStatusColor} = node || {};
const renderTitle = nodeStatusColor ? (
<Badge color={nodeStatusColor} text={title} />
) : title;
return (
<TreeNode
isLeaf={isLeaf}
disabled={!!disabled}
checkable={!disabled}
value={value}
dataRef={node}
key={value}
title={renderTitle}
>
{children && children.length && renderTreeNode(children)}
</TreeNode>
);
});
}
return null;
};
return (
<div>
<TreeSelectSearch
className={prefixCls}
style={{width: 220}}
dropdownMatchSelectWidth={false}
value={newValues}
treeDefaultExpandedKeys={treeDefaultExpandedKeys}
notFoundContent={loading ? <Spin size='small' /> : notFoundContent}
onFocus={focusHandler}
searchValue={searchValue}
treeNodeFilterProp={treeNodeFilterProp || 'title'}
onSearch={(val) => {
setSearchValue(val);
}}
maxTagCount={0}
treeDataSimpleMode={treeDataSimpleMode}
maxTagPlaceholder={(val) => {
if (data?.length <= 0) {
return '';
}
if (val.length === totalNum) {
return `${optionLabel}全部选中(${totalNum - 1})`;
}
return `${optionLabel}已选择(${val.length})`;
}}
onChange={(values, labelList, extra) => {
if (hasAllOption) {
if (extra?.triggerValue === 'all') {
const temp = extra.checked ? allCheckedValues : [];
setNewValues(temp);
handleChange(temp);
} else {
const temp = values.filter((value) => value !== 'all');
if (values.find((v) => v === 'all')) {
handleChange(temp);
setNewValues(temp);
} else {
handleChange(temp.length === totalNum - 1 ? allCheckedValues : temp);
setNewValues(temp.length === totalNum - 1 ? allCheckedValues : temp);
}
}
}
}}
>
{hasAllOption && data?.length && (
<TreeNode
isLeaf
checkable
value='all'
key='all'
title={localeText('COMMON.TXT_SELECT_ALL')}
/>
)}
{data && renderTreeNode(data)}
</TreeSelectSearch>
</div>
);
}
<Form.Item
label={localeText('STATUS_RECORD.LABEL_CATEGORY')}
name='categories'
initialValue={categories}
>
<TreeSelect
hasAllOption
defaultValue={categories}
treeDefaultExpandedKeys={categories}
renderData={categoryList}
handleChange={(value) => {
statusRecordStore.setCategories(value);
}}
/>
</Form.Item>