diff --git a/src/ui/Desktop/Apps/File Manager/FileManagerGrid.tsx b/src/ui/Desktop/Apps/File Manager/FileManagerGrid.tsx index c53e743a..38ba9365 100644 --- a/src/ui/Desktop/Apps/File Manager/FileManagerGrid.tsx +++ b/src/ui/Desktop/Apps/File Manager/FileManagerGrid.tsx @@ -185,16 +185,22 @@ export function FileManagerGrid({ const handleFileClick = (file: FileItem, event: React.MouseEvent) => { event.stopPropagation(); + console.log('File clicked:', file.name, 'Current selected:', selectedFiles.length); + if (event.detail === 2) { // 双击打开 + console.log('Double click - opening file'); onFileOpen(file); } else { // 单击选择 const multiSelect = event.ctrlKey || event.metaKey; const rangeSelect = event.shiftKey; + console.log('Single click - multiSelect:', multiSelect, 'rangeSelect:', rangeSelect); + if (rangeSelect && selectedFiles.length > 0) { // 范围选择 (Shift+点击) + console.log('Range selection'); const lastSelected = selectedFiles[selectedFiles.length - 1]; const currentIndex = files.findIndex(f => f.path === file.path); const lastIndex = files.findIndex(f => f.path === lastSelected.path); @@ -203,19 +209,23 @@ export function FileManagerGrid({ const start = Math.min(currentIndex, lastIndex); const end = Math.max(currentIndex, lastIndex); const rangeFiles = files.slice(start, end + 1); + console.log('Range selection result:', rangeFiles.length, 'files'); onSelectionChange(rangeFiles); } } else if (multiSelect) { // 多选 (Ctrl+点击) + console.log('Multi selection'); const isSelected = selectedFiles.some(f => f.path === file.path); if (isSelected) { + console.log('Removing from selection'); onSelectionChange(selectedFiles.filter(f => f.path !== file.path)); } else { + console.log('Adding to selection'); onSelectionChange([...selectedFiles, file]); } } else { // 单选 - onFileSelect(file); + console.log('Single selection - should select only:', file.name); onSelectionChange([file]); } } @@ -241,6 +251,7 @@ export function FileManagerGrid({ case 'A': if (event.ctrlKey || event.metaKey) { event.preventDefault(); + console.log('Ctrl+A pressed - selecting all files:', files.length); onSelectionChange([...files]); } break; @@ -374,6 +385,17 @@ export function FileManagerGrid({ {files.map((file) => { const isSelected = selectedFiles.some(f => f.path === file.path); + // 详细调试路径比较 + if (selectedFiles.length > 0) { + console.log(`\n=== File: ${file.name} ===`); + console.log(`File path: "${file.path}"`); + console.log(`Selected files:`, selectedFiles.map(f => `"${f.path}"`)); + console.log(`Path comparison results:`, selectedFiles.map(f => + `"${f.path}" === "${file.path}" -> ${f.path === file.path}` + )); + console.log(`Final isSelected: ${isSelected}`); + } + return (
handleFileClick(file, e)} onContextMenu={(e) => { e.preventDefault(); diff --git a/src/ui/Desktop/Apps/File Manager/FileManagerModern.tsx b/src/ui/Desktop/Apps/File Manager/FileManagerModern.tsx index bf43d7c6..233103d2 100644 --- a/src/ui/Desktop/Apps/File Manager/FileManagerModern.tsx +++ b/src/ui/Desktop/Apps/File Manager/FileManagerModern.tsx @@ -27,7 +27,8 @@ import { createSSHFolder, deleteSSHItem, renameSSHItem, - connectSSH + connectSSH, + getSSHStatus } from "@/ui/main-axios.ts"; interface FileItem { @@ -83,7 +84,7 @@ export function FileManagerModern({ initialHost, onClose }: FileManagerModernPro selectFile, selectAll, clearSelection, - setSelectedFiles + setSelection } = useFileSelection(); const { isDragging, dragHandlers } = useDragAndDrop({ @@ -111,11 +112,24 @@ export function FileManagerModern({ initialHost, onClose }: FileManagerModernPro try { setIsLoading(true); + console.log("Initializing SSH connection for host:", currentHost.name, "ID:", currentHost.id); + // 使用主机ID作为会话ID const sessionId = currentHost.id.toString(); + console.log("Using session ID:", sessionId); // 调用connectSSH建立连接 - await connectSSH(sessionId, { + console.log("Connecting to SSH with config:", { + hostId: currentHost.id, + ip: currentHost.ip, + port: currentHost.port, + username: currentHost.username, + authType: currentHost.authType, + credentialId: currentHost.credentialId, + userId: currentHost.userId + }); + + const result = await connectSSH(sessionId, { hostId: currentHost.id, ip: currentHost.ip, port: currentHost.port, @@ -128,26 +142,67 @@ export function FileManagerModern({ initialHost, onClose }: FileManagerModernPro userId: currentHost.userId }); + console.log("SSH connection result:", result); setSshSessionId(sessionId); + console.log("SSH session ID set to:", sessionId); } catch (error: any) { - toast.error(t("fileManager.failedToConnect")); console.error("SSH connection failed:", error); + toast.error(t("fileManager.failedToConnect") + ": " + (error.message || error)); } finally { setIsLoading(false); } } async function loadDirectory(path: string) { - if (!sshSessionId) return; + if (!sshSessionId) { + console.error("Cannot load directory: no SSH session ID"); + return; + } try { setIsLoading(true); + console.log("Loading directory:", path, "with session ID:", sshSessionId); + + // 首先检查SSH连接状态 + try { + const status = await getSSHStatus(sshSessionId); + console.log("SSH connection status:", status); + + if (!status.connected) { + console.log("SSH not connected, attempting to reconnect..."); + await initializeSSHConnection(); + return; // 重连后会触发useEffect重新加载目录 + } + } catch (statusError) { + console.log("Failed to get SSH status, attempting to reconnect..."); + await initializeSSHConnection(); + return; + } + const contents = await listSSHFiles(sshSessionId, path); - setFiles(contents || []); + console.log("Directory contents loaded:", contents?.length || 0, "items"); + console.log("Raw file data from backend:", contents); + + // 为文件添加完整路径 + const filesWithPath = (contents || []).map(file => ({ + ...file, + path: path + (path.endsWith("/") ? "" : "/") + file.name + })); + + console.log("Files with constructed paths:", filesWithPath.map(f => ({ name: f.name, path: f.path }))); + + setFiles(filesWithPath); clearSelection(); } catch (error: any) { - toast.error(t("fileManager.failedToLoadDirectory")); console.error("Failed to load directory:", error); + + // 如果是连接错误,尝试重连 + if (error.message?.includes("connection") || error.message?.includes("established")) { + console.log("Connection error detected, attempting to reconnect..."); + await initializeSSHConnection(); + } else { + toast.error(t("fileManager.failedToLoadDirectory") + ": " + (error.message || error)); + } } finally { setIsLoading(false); } @@ -440,9 +495,9 @@ export function FileManagerModern({ initialHost, onClose }: FileManagerModernPro {}} // 不再需要这个回调,使用onSelectionChange onFileOpen={handleFileOpen} - onSelectionChange={setSelectedFiles} + onSelectionChange={setSelection} currentPath={currentPath} isLoading={isLoading} onPathChange={setCurrentPath} diff --git a/src/ui/Desktop/Apps/File Manager/hooks/useFileSelection.ts b/src/ui/Desktop/Apps/File Manager/hooks/useFileSelection.ts index 2cf0eeda..2f4e07d2 100644 --- a/src/ui/Desktop/Apps/File Manager/hooks/useFileSelection.ts +++ b/src/ui/Desktop/Apps/File Manager/hooks/useFileSelection.ts @@ -68,6 +68,11 @@ export function useFileSelection() { return selectedFiles.length; }, [selectedFiles]); + const setSelection = useCallback((files: FileItem[]) => { + console.log('Setting selection to:', files.map(f => f.name)); + setSelectedFiles(files); + }, []); + return { selectedFiles, selectFile, @@ -77,6 +82,6 @@ export function useFileSelection() { toggleSelection, isSelected, getSelectedCount, - setSelectedFiles + setSelection }; } \ No newline at end of file