|
@@ -1,7 +1,7 @@
|
|
|
-import React, { useState, useEffect, useMemo } from "react";
|
|
|
+import React, {useState, useEffect, useMemo} from "react";
|
|
|
import styles from "../../css/Tree.module.css";
|
|
|
-import { SearchOutlined } from "@ant-design/icons";
|
|
|
-import { Input, Tree } from "antd";
|
|
|
+import {SearchOutlined} from "@ant-design/icons";
|
|
|
+import {Input, Tooltip, Tree} from "antd";
|
|
|
import type {
|
|
|
DepartmentNode,
|
|
|
EnhancedDepartmentNode,
|
|
@@ -9,26 +9,27 @@ import type {
|
|
|
TreeDataNode,
|
|
|
} from "./prop.ts";
|
|
|
import "../../css/ant.css";
|
|
|
-import type { TreeProps } from "antd";
|
|
|
-import { getOrganizations } from "../../api/index.ts";
|
|
|
+import type {TreeProps} from "antd";
|
|
|
+import {getOrganizations} from "../../api/index.ts";
|
|
|
|
|
|
// 定义 props 类型
|
|
|
interface ChildComponentProps {
|
|
|
onSelectFn: (message: string) => void; // 函数类型
|
|
|
}
|
|
|
-const TreeComponent: React.FC<ChildComponentProps> = ({ onSelectFn }) => {
|
|
|
+
|
|
|
+const TreeComponent: React.FC<ChildComponentProps> = ({onSelectFn}) => {
|
|
|
const [inputValue, setInputValue] = useState("");
|
|
|
const [isComposing, setIsComposing] = useState(false); // 是否处于拼音输入状态
|
|
|
- const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
|
|
|
+ const [expandedKeys, setExpandedKeys] = useState<string[]>([]);
|
|
|
const [autoExpandParent, setAutoExpandParent] = useState(true);
|
|
|
const [departmentData, setDepartmentData] = useState([]);
|
|
|
- const [dataList, setDataList] = useState<{ deptID: React.Key; deptName: string }[]>([]);
|
|
|
+ const [dataList, setDataList] = useState<{ deptID: string; deptName: string }[]>([]);
|
|
|
|
|
|
const generateList = (data: DepartmentNodeObj[]) => {
|
|
|
for (let i = 0; i < data.length; i++) {
|
|
|
const node = data[i];
|
|
|
- const { deptID, deptName } = node;
|
|
|
- setDataList([...dataList, { deptID, deptName }]);
|
|
|
+ const {deptID, deptName} = node;
|
|
|
+ setDataList([...dataList, {deptID, deptName}]);
|
|
|
if (node.childNodes) {
|
|
|
generateList(node.childNodes);
|
|
|
}
|
|
@@ -55,48 +56,65 @@ const TreeComponent: React.FC<ChildComponentProps> = ({ onSelectFn }) => {
|
|
|
getOrganizations().then((res) => {
|
|
|
setDepartmentData(res.data ?? []);
|
|
|
});
|
|
|
+ setAutoExpandParent(true);
|
|
|
}, []);
|
|
|
|
|
|
useEffect(() => {
|
|
|
+ setExpandedKeys([departmentData?.[0]?.deptID]);
|
|
|
generateList(departmentData);
|
|
|
}, [departmentData]);
|
|
|
|
|
|
const treeData = useMemo(() => {
|
|
|
- const loop = (data: DepartmentNode[]) =>
|
|
|
- data.map((item: DepartmentNode): EnhancedDepartmentNode => {
|
|
|
- const strTitle = item.deptName as string;
|
|
|
- const index = strTitle.indexOf(inputValue);
|
|
|
- const beforeStr = strTitle.substring(0, index);
|
|
|
- const afterStr = strTitle.slice(index + inputValue.length);
|
|
|
- const deptName =
|
|
|
- index > -1 ? (
|
|
|
- <>
|
|
|
- {beforeStr}
|
|
|
- <span className={styles["site-tree-search-value"]}>
|
|
|
- {inputValue}
|
|
|
- </span>
|
|
|
- {afterStr}
|
|
|
- </>
|
|
|
- ) : (
|
|
|
- <span key={item.deptID}>{strTitle}</span>
|
|
|
- );
|
|
|
- return {
|
|
|
- deptName,
|
|
|
- deptID: item.deptID,
|
|
|
- childNodes: item.childNodes ? loop(item.childNodes) : null,
|
|
|
- };
|
|
|
- });
|
|
|
- return loop(departmentData);
|
|
|
+ if (!inputValue) return departmentData;
|
|
|
+ const filterNode = (node) => {
|
|
|
+ // 如果当前节点匹配,直接保留
|
|
|
+ if (node.deptName.toLowerCase().includes(inputValue.toLowerCase())) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ // 递归检查子节点
|
|
|
+ if (node.childNodes) {
|
|
|
+ node.childNodes = node.childNodes.filter(filterNode);
|
|
|
+ return node.childNodes.length > 0; // 保留有匹配子节点的父级
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ };
|
|
|
+ const td = JSON.parse(JSON.stringify(departmentData)).filter(filterNode);
|
|
|
+ setExpandedKeys([td?.[0]?.deptID]);
|
|
|
+ return td;
|
|
|
+ // const loop = (data: DepartmentNode[]) => data.map((item: DepartmentNode): EnhancedDepartmentNode => {
|
|
|
+ // const strTitle = item.deptName as string;
|
|
|
+ // const index = strTitle.indexOf(inputValue);
|
|
|
+ // const beforeStr = strTitle.substring(0, index);
|
|
|
+ // const afterStr = strTitle.slice(index + inputValue.length);
|
|
|
+ // const deptName =
|
|
|
+ // index > -1 ? (
|
|
|
+ // <>
|
|
|
+ // {beforeStr}
|
|
|
+ // <span className={styles["site-tree-search-value"]}>
|
|
|
+ // {inputValue}
|
|
|
+ // </span>
|
|
|
+ // {afterStr}
|
|
|
+ // </>
|
|
|
+ // ) : (
|
|
|
+ // <span key={item.deptID}>{strTitle}</span>
|
|
|
+ // );
|
|
|
+ // return {
|
|
|
+ // deptName,
|
|
|
+ // deptID: item.deptID,
|
|
|
+ // childNodes: item.childNodes ? loop(item.childNodes) : null,
|
|
|
+ // };
|
|
|
+ // });
|
|
|
+ // return loop(departmentData);
|
|
|
}, [inputValue, departmentData]);
|
|
|
|
|
|
- const onExpand = (newExpandedKeys: React.Key[]) => {
|
|
|
+ const onExpand = (newExpandedKeys: string[]) => {
|
|
|
setExpandedKeys(newExpandedKeys);
|
|
|
setAutoExpandParent(false);
|
|
|
};
|
|
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
|
if (!isComposing) {
|
|
|
// 拼音输入完成后触发
|
|
|
- const { value } = e.target;
|
|
|
+ const {value} = e.target;
|
|
|
setInputValue(value ?? "");
|
|
|
const newExpandedKeys = dataList.map((item) => {
|
|
|
if (item.deptName.indexOf(value) > -1) {
|
|
@@ -120,36 +138,42 @@ const TreeComponent: React.FC<ChildComponentProps> = ({ onSelectFn }) => {
|
|
|
onSelectFn(selectK.length ? String(selectK[0]) : "");
|
|
|
};
|
|
|
return (
|
|
|
- <div className={styles.ct}>
|
|
|
- <div className={styles.tit}>
|
|
|
- <div className={styles.title}>责任部门</div>
|
|
|
- <Input
|
|
|
- defaultValue={inputValue}
|
|
|
- placeholder="请输入部门名称搜索"
|
|
|
- allowClear
|
|
|
- onChange={handleChange}
|
|
|
- onCompositionStart={handleCompositionStart}
|
|
|
- onCompositionEnd={handleCompositionEnd}
|
|
|
- suffix={<SearchOutlined style={{ color: "#c2c8d1" }} />}
|
|
|
- style={{ marginBottom: 8 }}
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div className={styles.tree}>
|
|
|
- <Tree
|
|
|
- blockNode={true}
|
|
|
- treeData={treeData as TreeDataNode[]}
|
|
|
- onExpand={onExpand}
|
|
|
- expandedKeys={expandedKeys}
|
|
|
- autoExpandParent={autoExpandParent}
|
|
|
- fieldNames={{
|
|
|
- title: "deptName",
|
|
|
- key: "deptID",
|
|
|
- children: "childNodes",
|
|
|
- }}
|
|
|
- onSelect={onSelect}
|
|
|
- />
|
|
|
+ <div className={styles.ct}>
|
|
|
+ <div className={styles.tit}>
|
|
|
+ <div className={styles.title}>责任部门</div>
|
|
|
+ <Input
|
|
|
+ defaultValue={inputValue}
|
|
|
+ placeholder="请输入部门名称搜索"
|
|
|
+ allowClear
|
|
|
+ onChange={handleChange}
|
|
|
+ onCompositionStart={handleCompositionStart}
|
|
|
+ onCompositionEnd={handleCompositionEnd}
|
|
|
+ suffix={<SearchOutlined style={{color: "#c2c8d1"}}/>}
|
|
|
+ style={{marginBottom: 8}}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div className={styles.tree}>
|
|
|
+ <Tree
|
|
|
+ blockNode={true}
|
|
|
+ treeData={treeData as TreeDataNode[]}
|
|
|
+ titleRender={(nodeData) => (
|
|
|
+ <Tooltip title={nodeData.deptName}>
|
|
|
+ <span className={styles['title-c']}>{nodeData.deptName}</span>
|
|
|
+ </Tooltip>
|
|
|
+ )}
|
|
|
+ onExpand={onExpand}
|
|
|
+ expandedKeys={expandedKeys}
|
|
|
+ defaultExpandParent={true}
|
|
|
+ autoExpandParent={autoExpandParent}
|
|
|
+ fieldNames={{
|
|
|
+ title: "deptName",
|
|
|
+ key: "deptID",
|
|
|
+ children: "childNodes",
|
|
|
+ }}
|
|
|
+ onSelect={onSelect}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
);
|
|
|
};
|
|
|
|