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