import { TreeSelect, TreeSelectProps } from "antd"; import React, { useEffect, useState, useCallback } from "react"; import { getUniqueItems } from "@nice/common"; import { api } from "@nice/client" import { DefaultOptionType } from "antd/es/select"; interface DepartmentSelectProps { defaultValue?: string | string[]; value?: string | string[]; onChange?: (value: string | string[]) => void; placeholder?: string; multiple?: boolean; rootId?: string; domain?: boolean; disabled?: boolean; className?: string; } export default function DepartmentSelect({ defaultValue, value, onChange, className, placeholder = "选择单位", multiple = false, rootId = null, disabled = false, domain = undefined, }: DepartmentSelectProps) { const utils = api.useUtils(); const [listTreeData, setListTreeData] = useState< Omit[] >([]); const fetchParentDepts = useCallback( async (deptIds: string | string[], rootId?: string) => { const idsArray = Array.isArray(deptIds) ? deptIds : [deptIds]; try { return await utils.department.getParentSimpleTree.fetch({ deptIds: idsArray, rootId, domain, }); } catch (error) { console.error( "Error fetching parent departments for deptIds", idsArray, ":", error ); throw error; } }, [utils] ); const fetchDepts = useCallback(async () => { try { const rootDepts = await utils.department.getChildSimpleTree.fetch({ deptIds: [rootId], domain, }); let combinedDepts = [...rootDepts]; if (defaultValue) { const defaultDepts = await fetchParentDepts(defaultValue, rootId); combinedDepts = getUniqueItems( [...listTreeData, ...combinedDepts, ...defaultDepts], "id" ); } if (value) { const valueDepts = await fetchParentDepts(value, rootId); combinedDepts = getUniqueItems( [...listTreeData, ...combinedDepts, ...valueDepts], "id" ); } setListTreeData(combinedDepts); } catch (error) { console.error("Error fetching departments:", error); } }, [defaultValue, value, rootId, utils, fetchParentDepts]); useEffect(() => { fetchDepts(); }, [defaultValue, value, rootId, fetchDepts]); const handleChange = (newValue: any) => { if (onChange) { const processedValue = multiple && Array.isArray(newValue) ? newValue.map((item) => item.value) : newValue; onChange(processedValue); } }; const onLoadData: TreeSelectProps["loadData"] = async ({ id }) => { try { const result = await utils.department.getChildSimpleTree.fetch({ deptIds: [id], domain, }); const newItems = getUniqueItems([...listTreeData, ...result], "id"); setListTreeData(newItems); } catch (error) { console.error( "Error loading data for node with id", id, ":", error ); } }; const handleExpand = async (keys: React.Key[]) => { // console.log(keys); try { const allKeyIds = keys.map((key) => key.toString()).filter(Boolean) || []; const expandedNodes = await utils.department.getChildSimpleTree.fetch({ deptIds: allKeyIds, domain, }); const flattenedNodes = expandedNodes.flat(); const newItems = getUniqueItems( [...listTreeData, ...flattenedNodes], "id" ); setListTreeData(newItems); } catch (error) { console.error("Error expanding nodes with keys", keys, ":", error); } }; const handleDropdownVisibleChange = async (open: boolean) => { if (open) { // This will attempt to expand all nodes and fetch their children when the dropdown opens const allKeys = listTreeData.map((item) => item.id); await handleExpand(allKeys); } }; return ( handleChange(multiple ? [] : undefined)} onTreeExpand={handleExpand} onDropdownVisibleChange={handleDropdownVisibleChange} /> ); }