feat(remote): 完善文件传输功能及WebSocket支持

This commit is contained in:
2026-03-10 01:41:02 +08:00
parent 6d5520dfa5
commit 84e455d9a6
19 changed files with 1263 additions and 5 deletions

View File

@@ -262,6 +262,124 @@ ipcMain.handle("clipboard-write-text", async (event, text) => {
return { success: false, error: error.message };
}
});
ipcMain.handle("remote-fetch-drives", async (_event, serverHost, port, password) => {
try {
let url = `http://${serverHost}:${port}/api/files/drives`;
if (password) {
url += `?password=${encodeURIComponent(password)}`;
}
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch drives: ${response.statusText}`);
}
const data = await response.json();
const items = data.items || [];
return {
success: true,
data: items.map((item) => ({
name: item.name,
path: item.name,
type: item.isDirectory ? "dir" : "file",
size: item.size,
modified: ""
}))
};
} catch (error) {
log2.error("Remote fetch drives failed:", error);
return { success: false, error: error.message };
}
});
ipcMain.handle("remote-fetch-files", async (_event, serverHost, port, filePath, password) => {
try {
let url = `http://${serverHost}:${port}/api/files/browse?path=${encodeURIComponent(filePath)}&allowSystem=true`;
if (password) {
url += `&password=${encodeURIComponent(password)}`;
}
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch files: ${response.statusText}`);
}
const data = await response.json();
const items = data.items || [];
return {
success: true,
data: items.map((item) => ({
name: item.name,
path: data.currentPath ? `${data.currentPath}/${item.name}` : item.name,
type: item.isDirectory ? "dir" : "file",
size: item.size,
modified: item.modified?.toString()
}))
};
} catch (error) {
log2.error("Remote fetch files failed:", error);
return { success: false, error: error.message };
}
});
ipcMain.handle("remote-upload-file", async (_event, serverHost, port, filePath, remotePath, password) => {
try {
const win = electronState.getMainWindow();
if (!win) {
throw new Error("No window found");
}
const fullPath = path2.resolve(filePath);
if (!fs2.existsSync(fullPath)) {
throw new Error("File not found");
}
const fileBuffer = fs2.readFileSync(fullPath);
const fileName = path2.basename(fullPath);
let url = `http://${serverHost}:${port}/api/files/upload`;
if (password) {
url += `?password=${encodeURIComponent(password)}`;
}
const formData = new FormData();
const blob = new Blob([fileBuffer]);
formData.append("file", blob, fileName);
if (remotePath) {
formData.append("path", remotePath);
}
const response = await fetch(url, {
method: "POST",
body: formData
});
if (!response.ok) {
throw new Error(`Upload failed: ${response.statusText}`);
}
return { success: true };
} catch (error) {
log2.error("Remote upload failed:", error);
return { success: false, error: error.message };
}
});
ipcMain.handle("remote-download-file", async (_event, serverHost, port, fileName, remotePath, password) => {
try {
const win = electronState.getMainWindow();
if (!win) {
throw new Error("No window found");
}
let url = `http://${serverHost}:${port}/api/files/${encodeURIComponent(fileName)}`;
if (password) {
url += `?password=${encodeURIComponent(password)}`;
}
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Download failed: ${response.statusText}`);
}
const buffer = await response.arrayBuffer();
const { filePath } = await dialog2.showSaveDialog(win, {
title: "\u4FDD\u5B58\u6587\u4EF6",
defaultPath: fileName
});
if (!filePath) {
return { success: false, canceled: true };
}
fs2.writeFileSync(filePath, Buffer.from(buffer));
return { success: true, filePath };
} catch (error) {
log2.error("Remote download failed:", error);
return { success: false, error: error.message };
}
});
async function startServer() {
if (electronState.isDevelopment()) {
log2.info("In dev mode, assuming external servers are running.");