2024-01-24 04:59:31 -05:00
|
|
|
|
import React, {useEffect, useMemo, useState} from 'react';
|
2024-01-25 04:56:53 -05:00
|
|
|
|
import {Input, Tree} from 'antd';
|
2024-02-05 03:34:41 -05:00
|
|
|
|
import {FolderOutlined, FileMarkdownOutlined, FileOutlined} from '@ant-design/icons';
|
2024-01-25 05:46:51 -05:00
|
|
|
|
import "./index.less"
|
2024-02-05 03:34:41 -05:00
|
|
|
|
|
2024-01-25 04:56:53 -05:00
|
|
|
|
const {Search} = Input;
|
2024-02-05 03:34:41 -05:00
|
|
|
|
import {useSelector, useDispatch} from "react-redux";
|
2024-02-04 01:42:20 -05:00
|
|
|
|
import {addTableBarItem} from "../../redux/tableBarItem_reducer";
|
2024-02-04 21:59:35 -05:00
|
|
|
|
import {readDir} from "../../utils/File";
|
|
|
|
|
import {nextDirAdd} from "../../redux/dirMessage_reducer";
|
2024-02-05 03:34:41 -05:00
|
|
|
|
// const defaultData = [];
|
2024-01-12 00:13:58 -05:00
|
|
|
|
// 将树平铺用于查找
|
|
|
|
|
const dataList = [];
|
|
|
|
|
const generateList = (data) => {
|
|
|
|
|
for (let i = 0; i < data.length; i++) {
|
|
|
|
|
const node = data[i];
|
2024-01-25 04:56:53 -05:00
|
|
|
|
const {key, title, icon} = node;
|
2024-01-12 00:13:58 -05:00
|
|
|
|
dataList.push({
|
|
|
|
|
key,
|
|
|
|
|
title,
|
|
|
|
|
icon
|
|
|
|
|
});
|
|
|
|
|
if (node.children) {
|
|
|
|
|
generateList(node.children);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-02-05 03:34:41 -05:00
|
|
|
|
// generateList(defaultData);
|
2024-01-12 00:13:58 -05:00
|
|
|
|
const getParentKey = (key, tree) => {
|
|
|
|
|
let parentKey;
|
|
|
|
|
for (let i = 0; i < tree.length; i++) {
|
|
|
|
|
const node = tree[i];
|
|
|
|
|
if (node.children) {
|
|
|
|
|
if (node.children.some((item) => item.key === key)) {
|
|
|
|
|
parentKey = node.key;
|
|
|
|
|
} else if (getParentKey(key, node.children)) {
|
|
|
|
|
parentKey = getParentKey(key, node.children);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return parentKey;
|
|
|
|
|
};
|
2024-01-24 04:59:31 -05:00
|
|
|
|
|
2024-01-25 04:56:53 -05:00
|
|
|
|
function generateChildList(fileList) {
|
2024-01-24 04:59:31 -05:00
|
|
|
|
const result = []
|
|
|
|
|
for (let i = 0; i < fileList.length; i++) {
|
2024-02-05 03:34:41 -05:00
|
|
|
|
const {fileName, filePath, dirFlag, childList} = fileList[i];
|
2024-02-04 21:59:35 -05:00
|
|
|
|
const childListM = []
|
2024-02-05 03:34:41 -05:00
|
|
|
|
if (Array.isArray(childList) && childList.length > 0) {
|
2024-02-04 21:59:35 -05:00
|
|
|
|
childListM.push(...generateChildList(childList));
|
|
|
|
|
}
|
2024-01-24 04:59:31 -05:00
|
|
|
|
result.push({
|
2024-01-25 04:56:53 -05:00
|
|
|
|
"key": filePath,
|
|
|
|
|
"title": fileName,
|
2024-02-05 03:34:41 -05:00
|
|
|
|
"icon": dirFlag ? <FolderOutlined/> : fileName.endsWith(".md") ? <FileMarkdownOutlined/> : <FileOutlined/>,
|
2024-01-25 04:56:53 -05:00
|
|
|
|
"dirFlag": dirFlag,
|
2024-02-04 21:59:35 -05:00
|
|
|
|
"children": childListM
|
2024-01-24 04:59:31 -05:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2024-01-25 04:56:53 -05:00
|
|
|
|
|
2024-02-05 03:34:41 -05:00
|
|
|
|
/**
|
|
|
|
|
* 将文件信息改为树信息
|
|
|
|
|
* @param fileDirDate
|
|
|
|
|
* @returns {*[]}
|
|
|
|
|
*/
|
|
|
|
|
const flushTree = (fileDirDate) => {
|
2024-02-03 23:30:40 -05:00
|
|
|
|
const defaultValueStateSet = [];
|
2024-02-05 03:34:41 -05:00
|
|
|
|
if (Array.isArray(fileDirDate) && fileDirDate.length > 0) {
|
2024-02-03 23:30:40 -05:00
|
|
|
|
for (let i = 0; i < fileDirDate.length; i++) {
|
|
|
|
|
const node = fileDirDate[i];
|
|
|
|
|
console.log("node:", node)
|
|
|
|
|
const {fileName, filePath, childList, dirFlag} = node;
|
|
|
|
|
const childListM = []
|
2024-02-05 03:34:41 -05:00
|
|
|
|
if (Array.isArray(childList) && childList.length > 0) {
|
2024-02-03 23:30:40 -05:00
|
|
|
|
childListM.push(...generateChildList(childList));
|
2024-01-27 22:48:48 -05:00
|
|
|
|
}
|
2024-02-05 03:34:41 -05:00
|
|
|
|
defaultValueStateSet.push({
|
|
|
|
|
"key": filePath,
|
|
|
|
|
"title": fileName,
|
|
|
|
|
"icon": <FolderOutlined/>,
|
|
|
|
|
"dirFlag": dirFlag,
|
|
|
|
|
"children": childListM
|
|
|
|
|
});
|
2024-02-03 23:30:40 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-02-05 03:34:41 -05:00
|
|
|
|
return defaultValueStateSet;
|
|
|
|
|
}
|
2024-02-05 21:11:26 -05:00
|
|
|
|
const ItemTree = (prop) => {
|
|
|
|
|
console.log("prop.filePath:",prop.filePath)
|
2024-02-05 03:34:41 -05:00
|
|
|
|
const [expandedKeys, setExpandedKeys] = useState([]);
|
|
|
|
|
const [searchValue, setSearchValue] = useState('');
|
|
|
|
|
const dispatch = useDispatch()
|
|
|
|
|
const [autoExpandParent, setAutoExpandParent] = useState(true);
|
2024-02-05 21:11:26 -05:00
|
|
|
|
// let filePath = useSelector(state => state.dirMessage.data);
|
|
|
|
|
const [defaultValueState, setDefaultValueState] = useState(flushTree(prop.filePath));
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setDefaultValueState(flushTree(prop.filePath))
|
|
|
|
|
}, [prop]);
|
2024-01-12 00:13:58 -05:00
|
|
|
|
const onExpand = (newExpandedKeys) => {
|
|
|
|
|
setExpandedKeys(newExpandedKeys);
|
|
|
|
|
setAutoExpandParent(false);
|
|
|
|
|
};
|
2024-02-05 03:34:41 -05:00
|
|
|
|
|
|
|
|
|
const addChildNode = (valueState, fileStateList) => {
|
|
|
|
|
valueState.forEach(file => {
|
|
|
|
|
if (fileStateList[0].key.startsWith(file.key)){
|
|
|
|
|
if (file.key === fileStateList[0].key) {
|
|
|
|
|
file.children = fileStateList[0].children
|
|
|
|
|
} else if (Array.isArray(file.children) && file.children.length > 0) {
|
|
|
|
|
addChildNode(file.children, fileStateList)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-12 00:13:58 -05:00
|
|
|
|
const onChange = (e) => {
|
2024-01-25 04:56:53 -05:00
|
|
|
|
const {value} = e.target;
|
2024-01-12 00:13:58 -05:00
|
|
|
|
const newExpandedKeys = dataList
|
|
|
|
|
.map((item) => {
|
|
|
|
|
if (item.title.indexOf(value) > -1) {
|
2024-02-05 03:34:41 -05:00
|
|
|
|
return getParentKey(item.key, defaultValueState);
|
2024-01-12 00:13:58 -05:00
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
})
|
|
|
|
|
.filter((item, i, self) => !!(item && self.indexOf(item) === i));
|
|
|
|
|
setExpandedKeys(newExpandedKeys);
|
|
|
|
|
setSearchValue(value);
|
|
|
|
|
setAutoExpandParent(true);
|
|
|
|
|
};
|
2024-01-25 04:56:53 -05:00
|
|
|
|
const onSelect = (selectedKeys, e) => {
|
2024-02-04 21:59:35 -05:00
|
|
|
|
if (e.selected) {
|
2024-01-25 04:56:53 -05:00
|
|
|
|
console.log('onSelect.selectedKeys', selectedKeys, e)
|
2024-02-05 03:34:41 -05:00
|
|
|
|
if (e.node.dirFlag) {
|
2024-02-04 21:59:35 -05:00
|
|
|
|
// 加载目录下一级文件信息
|
2024-02-05 03:34:41 -05:00
|
|
|
|
if (!Array.isArray(e.node.children) || e.node.children.length === 0) {
|
|
|
|
|
readDir(e.node.key).then(fileStateList => {
|
|
|
|
|
if (Array.isArray(fileStateList[0].childList) && fileStateList[0].childList.length > 0) {
|
|
|
|
|
dispatch(nextDirAdd({selectDirKey: e.node.key, fileStateList}))
|
|
|
|
|
// 添加下级节点
|
|
|
|
|
addChildNode(defaultValueState, flushTree(fileStateList))
|
|
|
|
|
const result = [...defaultValueState]
|
|
|
|
|
console.log("[...defaultValueState]:",result)
|
|
|
|
|
setDefaultValueState(result)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
// 打开当前目录
|
|
|
|
|
expandedKeys.push(e.node.key)
|
|
|
|
|
setExpandedKeys([...expandedKeys]);
|
|
|
|
|
setAutoExpandParent(false);
|
|
|
|
|
} else {
|
2024-02-04 21:59:35 -05:00
|
|
|
|
// 打开文件
|
2024-02-05 03:34:41 -05:00
|
|
|
|
dispatch(addTableBarItem({
|
|
|
|
|
label: e.node.title,
|
|
|
|
|
children: e.node.key,
|
|
|
|
|
key: e.node.key,
|
|
|
|
|
activeKey: e.node.key
|
|
|
|
|
}))
|
2024-02-04 21:59:35 -05:00
|
|
|
|
}
|
2024-01-25 02:26:23 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-01-24 04:59:31 -05:00
|
|
|
|
// const treeData = useMemo(() => {
|
|
|
|
|
// const loop = (data) =>
|
|
|
|
|
// data.map((item) => {
|
|
|
|
|
// const strTitle = item.title;
|
|
|
|
|
// const index = strTitle.indexOf(searchValue);
|
|
|
|
|
// const beforeStr = strTitle.substring(0, index);
|
|
|
|
|
// const afterStr = strTitle.slice(index + searchValue.length);
|
|
|
|
|
// const title =
|
|
|
|
|
// index > -1 ? (
|
|
|
|
|
// <span>{beforeStr}
|
|
|
|
|
// <span className="site-tree-search-value">{searchValue}</span>{afterStr}</span>
|
|
|
|
|
// ) : (
|
|
|
|
|
// <span>{strTitle}</span>
|
|
|
|
|
// );
|
|
|
|
|
// if (item.children) {
|
|
|
|
|
// return {
|
|
|
|
|
// title,
|
|
|
|
|
// key: item.key,
|
|
|
|
|
// icon: item.icon,
|
|
|
|
|
// children: loop(item.children),
|
|
|
|
|
// };
|
|
|
|
|
// }
|
|
|
|
|
// return {
|
|
|
|
|
// title,
|
|
|
|
|
// icon: item.icon,
|
|
|
|
|
// key: item.key,
|
|
|
|
|
// };
|
|
|
|
|
// });
|
|
|
|
|
// return loop(defaultData);
|
|
|
|
|
// }, [searchValue]);
|
2024-01-12 00:13:58 -05:00
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<Search
|
|
|
|
|
style={{marginBottom: 8,}}
|
|
|
|
|
placeholder="Search"
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
/>
|
|
|
|
|
<Tree
|
|
|
|
|
// 展开/收起节点时触发
|
|
|
|
|
onExpand={onExpand}
|
|
|
|
|
//(受控)展开指定的树节点
|
|
|
|
|
expandedKeys={expandedKeys}
|
|
|
|
|
// 是否自动展开父节点
|
|
|
|
|
autoExpandParent={autoExpandParent}
|
2024-01-25 04:56:53 -05:00
|
|
|
|
showIcon={true}
|
2024-01-12 00:13:58 -05:00
|
|
|
|
// treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点(key 在整个树范围内唯一)
|
2024-01-24 04:59:31 -05:00
|
|
|
|
treeData={defaultValueState}
|
2024-01-25 02:26:23 -05:00
|
|
|
|
onSelect={onSelect}
|
2024-01-12 00:13:58 -05:00
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
export default ItemTree;
|