import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react'; import { GetWebMenuInfo } from '@/services/webConfig/api'; import { message, Input, Tree, Empty, Tooltip } from 'antd'; import lodash from 'lodash'; import { FolderFilled, FileOutlined, InfoCircleOutlined, HomeOutlined } from '@ant-design/icons'; import styles from './TreeSelect.less'; const TreeSelect = (props, ref) => { const { value, onChange, menuChange, code, initCurrentMenu } = props; const [menuWebList, setMenuWebList] = useState({}); const [treeList, setTreeList] = useState({}); const [visible, setVisible] = useState(false); const [expandedKeys, setExpandedKeys] = useState([]); const [curretnMenuParmar, setCurrentMenuParmar] = useState(); useEffect(() => { console.log(333333); getMenu(); }, []); useImperativeHandle(ref, () => ({ getParmar })); const getMenu = () => { GetWebMenuInfo().then(res => { if (res.code === 0) { let tree = arrayToTree(lodash.cloneDeep(res.data), 'model', 'moduleName'); console.log(tree, 'fadsfasd'); setTreeList(tree); setMenuWebList( res.data.map(item => { let obj = { ...item, path: `${item.path}` }; if (item.code === code) { setCurrentMenuParmar(obj); initCurrentMenu(obj); } return obj; }), ); } else { message.error(res.msg); } }); }; // 定义一个函数,把数组转换成树形结构 const arrayToTree = (array, field1, field2) => { // 使用reduce方法按照第一个字段进行分组 let tree = array.reduce((acc, cur) => { let value1 = cur[field1]; // 如果累加器中没有该字段的属性,就创建一个空数组 if (!acc[value1]) { acc[value1] = []; } // 将当前元素放入对应的数组中 acc[value1].push(cur); // 返回累加器 return acc; }, {}); // 遍历对象的每个属性,使用reduce方法按照第二个字段进行分组 Object.keys(tree).forEach(key => { let array2 = tree[key]; let tree2 = array2.reduce((acc2, cur2) => { let value2 = cur2[field2]; // 如果累加器中没有该字段的属性,就创建一个空数组 if (!acc2[value2]) { acc2[value2] = []; } // 将当前元素放入对应的数组中 acc2[value2].push(cur2); // 返回累加器 return acc2; }, {}); // 将第二层的对象替换第一层的数组 tree[key] = tree2; }); // 返回树形结构对象 return tree; }; const mapTree = key => ({ key, title: key, icon: <FolderFilled />, disabled: true, children: Object.keys(treeList[key]).map(k => ({ key: k + key, title: k, icon: <FolderFilled />, disabled: true, children: treeList[key][k].map(item => ({ key: item.code, param: item, title: ( <div className={styles.treeLine}> {item.shortName} <Tooltip title={item.desc} overlayStyle={{ maxWidth: 350 }}> <InfoCircleOutlined style={{ color: '#40a9ff', padding: '2px 2px 0 0', marginLeft: '5px' }} /> </Tooltip> </div> ), icon: item.isHomePage ? <HomeOutlined /> : <FileOutlined />, })), })), }); const filterList = val => { if (!val) { val = ''; } let keys = new Set([]); let list = lodash.cloneDeep(menuWebList).filter(item => { keys.add(item.model); keys.add(item.moduleName + item.model); return item.shortName.includes(val) || item.path?.includes(val) || val?.includes(item.path); }); setExpandedKeys([...keys]); // 调用函数,传入数组 let tree = arrayToTree(list, 'model', 'moduleName'); setTreeList(tree); }; const changeValue = e => { // 过滤数组 onChange(e.target.value); filterList(e.target.value); setVisible(true); }; const onSelect = (selectedKeysValue, info) => { menuChange(info.selectedNodes[0].param); onChange(info.selectedNodes[0].param.path); setCurrentMenuParmar(info.selectedNodes[0].param); setVisible(false); }; const getParmar = () => curretnMenuParmar; const onExpand = expandedKeysValue => { setExpandedKeys(expandedKeysValue); }; return ( <div className={styles.treeSelect}> <Input allowClear placeholder="请选填写菜单功能路径" value={value} onFocus={() => filterList(value)} onClick={() => setVisible(!visible)} onChange={changeValue} onBlur={() => setVisible(false)} /> <div className={styles.dropBox} onMouseDown={event => { event.preventDefault(); }} style={{ display: visible ? 'block' : 'none' }} > <Tree onExpand={onExpand} selectedKeys={null} showIcon expandedKeys={expandedKeys} autoExpandParent onSelect={onSelect} treeData={Object.keys(treeList).map(key => mapTree(key))} style={{ width: '100%' }} /> {Object.keys(treeList).length === 0 ? <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> : null} </div> </div> ); }; export default forwardRef(TreeSelect);