import { useEffect, useState } from 'react' import { getFileContent, getProjectTree } from '@/api/file' import Toast from '@/components/Toast/Toast' import { collectParentKeys, findNodeByKey } from './documentBrowserUtils' function useDocumentEditorWorkspace({ projectId, searchParams, setSearchParams }) { const [treeData, setTreeData] = useState([]) const [selectedFile, setSelectedFile] = useState(null) const [selectedNode, setSelectedNode] = useState(null) const [fileContent, setFileContent] = useState('') const [loading, setLoading] = useState(false) const [openKeys, setOpenKeys] = useState([]) const [selectedMenuKey, setSelectedMenuKey] = useState(null) const [isPdfSelected, setIsPdfSelected] = useState(false) const [refreshing, setRefreshing] = useState(false) const [projectName, setProjectName] = useState('') const [userRole, setUserRole] = useState('viewer') const updateFileParam = (filePath) => { const nextParams = new URLSearchParams(searchParams) if (filePath) { nextParams.set('file', filePath) } else { nextParams.delete('file') } setSearchParams(nextParams, { replace: true }) } const fetchTree = async () => { try { const res = await getProjectTree(projectId) const data = res.data || {} setTreeData(data.tree || data || []) setProjectName(data.project_name || '') setUserRole(data.user_role || 'viewer') } catch (error) { Toast.error('加载失败', '加载文件树失败') } } const clearSelection = () => { setSelectedFile(null) setSelectedNode(null) setSelectedMenuKey(null) setFileContent('') setIsPdfSelected(false) updateFileParam(null) } const loadEditableFile = async (filePath) => { setLoading(true) try { const res = await getFileContent(projectId, filePath) setSelectedFile(filePath) setFileContent(res.data.content) } catch (error) { Toast.error('加载失败', '加载文件失败') } finally { setLoading(false) } } const openNodeByKey = async (key, node = null, syncUrl = false) => { const targetNode = node || findNodeByKey(treeData, key) if (!targetNode) { return } setSelectedNode(targetNode) setSelectedMenuKey(key) if (!targetNode.isLeaf) { if (syncUrl) { updateFileParam(null) } return } if (syncUrl) { updateFileParam(key) } setOpenKeys((prev) => Array.from(new Set([...prev, ...collectParentKeys(key)]))) if (key.toLowerCase().endsWith('.pdf')) { setSelectedFile(key) setIsPdfSelected(true) setFileContent('') return } setIsPdfSelected(false) await loadEditableFile(key) } const handleMenuClick = async ({ key }) => { const node = findNodeByKey(treeData, key) if (!node) { return } await openNodeByKey(key, node, true) } const refreshCurrentDocument = async () => { setRefreshing(true) try { await fetchTree() if (selectedFile && !isPdfSelected) { await loadEditableFile(selectedFile) } } catch (error) { console.error('Refresh document editor error:', error) Toast.error('刷新失败', '请稍后重试') } finally { setRefreshing(false) } } useEffect(() => { fetchTree() }, [projectId]) useEffect(() => { if (treeData.length === 0) { return } const fileParam = searchParams.get('file') if (!fileParam || fileParam === selectedFile) { return } const targetNode = findNodeByKey(treeData, fileParam) if (!targetNode) { return } openNodeByKey(fileParam, targetNode, false) }, [treeData, searchParams]) return { treeData, selectedFile, selectedNode, fileContent, loading, openKeys, selectedMenuKey, isPdfSelected, refreshing, projectName, userRole, setOpenKeys, setSelectedNode, setSelectedFile, setSelectedMenuKey, setFileContent, fetchTree, clearSelection, loadEditableFile, openNodeByKey, handleMenuClick, refreshCurrentDocument, } } export default useDocumentEditorWorkspace