| | |
| | | * @Author: dminyi 1301963064@qq.com |
| | | * @Date: 2024-08-29 17:41:09 |
| | | * @LastEditors: lwh |
| | | * @LastEditTime: 2025-06-06 09:48:10 |
| | | * @LastEditTime: 2025-06-21 11:56:05 |
| | | * @FilePath: \gzDyh\gz-customerSystem\src\components\SelectObjModal\selectPerson.jsx |
| | | * @Description: 选择经办人 |
| | | */ |
| | |
| | | |
| | | /** |
| | | * visible, // 传入参数控制modal显示 |
| | | * checkKeys, // 选中,数据格式 [{value:'',label:''}] |
| | | * checkKeys, // 选中,数据格式 [{value:'',label':''}] |
| | | * type, // 'person': 选择人员 'unit': 选择组织 'dept': 选择部门 'supUnit': 督办组织 |
| | | * isCheckbox, // 是否多选 |
| | | * searchData, // 搜索条件 |
| | |
| | | const [autoExpandParent, setAutoExpandParent] = useState(true); |
| | | const [dataList, setDataList] = useState([]); |
| | | const [loading, setLoading] = useState(false); |
| | | // 新增状态:用于区分是否为搜索状态 |
| | | const [isSearchMode, setIsSearchMode] = useState(false); |
| | | |
| | | |
| | | // 获取第一层级的key |
| | | const getFirstLevelKeys = (treeData) => { |
| | | return treeData.map(item => item.value); |
| | | }; |
| | | |
| | | // tree复选框选择 |
| | | function handleCheck(checkedKeys, e) { |
| | |
| | | return parents; |
| | | }; |
| | | |
| | | // 检查节点或其子节点是否包含搜索值 |
| | | const hasMatchingChild = (node, searchValue) => { |
| | | if (node.label.indexOf(searchValue) > -1) { |
| | | return true; |
| | | } |
| | | if (node.children) { |
| | | return node.children.some(child => hasMatchingChild(child, searchValue)); |
| | | } |
| | | return false; |
| | | }; |
| | | |
| | | // 获取搜索时需要展开的所有节点key |
| | | const getExpandedKeysForSearch = (searchValue, treeData) => { |
| | | const expandedKeys = []; |
| | | |
| | | const traverse = (nodes, parentKeys = []) => { |
| | | nodes.forEach(node => { |
| | | const currentPath = [...parentKeys, node.value]; |
| | | |
| | | // 如果当前节点匹配搜索值 |
| | | if (node.label.indexOf(searchValue) > -1) { |
| | | // 添加所有父节点到展开列表 |
| | | expandedKeys.push(...parentKeys); |
| | | // 添加当前节点到展开列表 |
| | | expandedKeys.push(node.value); |
| | | } |
| | | |
| | | // 如果当前节点有子节点,继续遍历 |
| | | if (node.children && node.children.length > 0) { |
| | | traverse(node.children, currentPath); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | traverse(treeData); |
| | | return Array.from(new Set(expandedKeys)); |
| | | }; |
| | | |
| | | function handleSearch(value, dataList) { |
| | | let newExpandedKeys = []; |
| | | // 找到所有包含关键字的节点 |
| | | const matchedKeys = dataList |
| | | .filter((item) => item.label.indexOf(value) > -1) |
| | | .map((item) => item.value); |
| | | if (!value.trim()) { |
| | | // 如果搜索值为空,恢复到初始状态 |
| | | const firstLevelKeys = getFirstLevelKeys(data); |
| | | setExpandedKeys(firstLevelKeys); |
| | | setSearchValue(''); |
| | | setAutoExpandParent(false); |
| | | setIsSearchMode(false); |
| | | return; |
| | | } |
| | | |
| | | // 获取所有相关父节点 |
| | | matchedKeys.forEach((key) => { |
| | | const parents = getAllParentKeys(key, data); |
| | | newExpandedKeys = newExpandedKeys.concat(parents); |
| | | }); |
| | | |
| | | // 去重 |
| | | newExpandedKeys = Array.from(new Set(newExpandedKeys)); |
| | | // 使用新的函数来精确计算需要展开的节点 |
| | | const newExpandedKeys = getExpandedKeysForSearch(value, data); |
| | | |
| | | setExpandedKeys(newExpandedKeys); |
| | | setSearchValue(value); |
| | | setAutoExpandParent(true); |
| | | // 设置为搜索模式 |
| | | setIsSearchMode(true); |
| | | } |
| | | |
| | | function handleSearch1(value, dataList) { |
| | | let newExpandedKeys = []; |
| | | // 找到所有包含关键字的节点 |
| | | const matchedKeys = dataList |
| | | .filter((item) => item.label.indexOf(value) > -1) |
| | | .map((item) => item.value); |
| | | if (!value.trim()) { |
| | | // 如果搜索值为空,恢复到初始状态 |
| | | const firstLevelKeys = getFirstLevelKeys(data); |
| | | setExpandedKeys(firstLevelKeys); |
| | | setSearchValue(''); |
| | | setAutoExpandParent(false); |
| | | setIsSearchMode(false); |
| | | return; |
| | | } |
| | | |
| | | // 获取所有相关父节点 |
| | | matchedKeys.forEach((key) => { |
| | | const parents = getAllParentKeys(key, data); |
| | | newExpandedKeys = newExpandedKeys.concat(parents); |
| | | }); |
| | | // 使用新的函数来精确计算需要展开的节点 |
| | | const newExpandedKeys = getExpandedKeysForSearch(value, data); |
| | | |
| | | // 去重 |
| | | newExpandedKeys = Array.from(new Set(newExpandedKeys)); |
| | | setExpandedKeys(newExpandedKeys); |
| | | setSearchValue(value); |
| | | setAutoExpandParent(true); |
| | | // 设置为搜索模式 |
| | | setIsSearchMode(true); |
| | | } |
| | | |
| | | useEffect(() => { |
| | |
| | | } else { |
| | | setCheckedKeys({ keys: [], items: [] }); |
| | | } |
| | | // 重置搜索模式 |
| | | setIsSearchMode(false); |
| | | getData(); |
| | | }, [type, visible]); |
| | | |
| | | console.log('checkedKeys', checkedKeys); |
| | | |
| | | |
| | | // 搜索 |
| | | useEffect(() => { |
| | |
| | | }; |
| | | generateList(data); |
| | | setDataList(arr); |
| | | handleSearch('', arr); |
| | | |
| | | // 初始化时只展开第一层级,不调用handleSearch |
| | | if (data.length > 0 && !isSearchMode) { |
| | | const firstLevelKeys = getFirstLevelKeys(data); |
| | | setExpandedKeys(firstLevelKeys); |
| | | setAutoExpandParent(false); |
| | | } |
| | | }, [data]); |
| | | |
| | | const treeData = useMemo(() => { |
| | |
| | | const strTitle = item.label; |
| | | const index = strTitle.indexOf(searchValue); |
| | | |
| | | // 只保留包含 searchValue 的项 |
| | | if (index <= -1 && !item.children) { |
| | | // 如果有搜索值,只保留包含 searchValue 的项或有匹配子节点的项 |
| | | if (searchValue && index <= -1 && !hasMatchingChild(item, searchValue)) { |
| | | return null; // 返回 null 表示不包含在最终结果中 |
| | | } |
| | | |
| | |
| | | <div className="selectObjModal-main"> |
| | | <div style={{ width: "100%" }}> |
| | | <div className="selectObjModal-left-search" style={{ paddingRight: '0px' }}> |
| | | <Search placeholder={`查询${nameStr}名称`} onSearch={(e) => handleSearch1(e, dataList)} /> |
| | | <Search |
| | | placeholder={`查询${nameStr}名称`} |
| | | value={searchValue} |
| | | onChange={(e) => { |
| | | const value = e.target.value; |
| | | if (!value.trim()) { |
| | | // 清空搜索时恢复到初始状态 |
| | | const firstLevelKeys = getFirstLevelKeys(data); |
| | | setExpandedKeys(firstLevelKeys); |
| | | setSearchValue(''); |
| | | setAutoExpandParent(false); |
| | | setIsSearchMode(false); |
| | | } else { |
| | | // 实时搜索,使用相同的展开逻辑 |
| | | const newExpandedKeys = getExpandedKeysForSearch(value, data); |
| | | setExpandedKeys(newExpandedKeys); |
| | | setSearchValue(value); |
| | | setAutoExpandParent(true); |
| | | setIsSearchMode(true); |
| | | } |
| | | }} |
| | | onSearch={(e) => handleSearch1(e, dataList)} |
| | | /> |
| | | </div> |
| | | <div className="selectObjModal-left-main"> |
| | | <Spin loading={loading} style={{ width: '100%', height: '100%' }}> |
| | | {data.length > 0 ? ( |
| | | <Tree |
| | | checkStrictly |
| | | defaultExpandAll |
| | | // defaultExpandAll |
| | | onExpand={(newExpandedKeys) => { |
| | | setExpandedKeys(newExpandedKeys); |
| | | setAutoExpandParent(false); |
| | | }} |
| | | expandedKeys={expandedKeys} |
| | | autoExpandParent={autoExpandParent} |
| | | // autoExpandParent={autoExpandParent} |
| | | onSelect={(checkedKeys, e) => { |
| | | handleCheck(checkedKeys, e); |
| | | onOk && onOk(e.node) |