Private
Public Access
1
0
Files

GO-DESK-10: SFTP 直连支持

版本: v0.5.0 | 状态: 开发中 | 分支: fs-only-v3 → u-desk-sftp

概述

为 U-Desk 新增 SFTPSSH File Transfer Protocol直连模式作为第三种文件系统传输方式与现有的本地模式Wails IPC和远程 HTTP Agent 模式并列。

用户无需在目标机器部署任何 Agent 服务,仅需 SSH 账号即可直接浏览和操作远程 Linux 服务器的文件系统。

架构设计

FsTransport (interface)
├── WailsTransport     → Wails IPC → FileSystemService (本地 os)
├── HttpTransport      → HTTP REST → u-fs-agent (远程部署)
└── SftpTransport [NEW]→ Wails IPC → SftpService → pkg/sftp (SSH/SFTP)

核心原则:复用现有 FsTransport 接口抽象,前端组件无感知。

技术方案

后端Go

新增依赖

  • github.com/pkg/sftp — SFTP 客户端库
  • golang.org/x/crypto/ssh — SSH 协议(已在 indirect 中,提升为 direct

新增包 internal/sftp/4 个文件):

文件 职责
config.go Config 结构体Host/Port/Username/Password/KeyPath/Timeout
client.go Managersync.Map 连接池,以 host:port 为 key+ Client单连接封装SSH 握手、健康检查、自动重连、双认证)
service.go Service(对齐 FileSystemService 返回格式的文件操作方法)
errors.go ConnectionError + ToUserMessage() 中文友好错误映射

连接管理

  • host:port 为 key 的 sync.Map 连接池
  • 支持密码认证 / 私钥文件认证(二选一)
  • WithRetry(fn) — 操作前检查健康度断线自动重连3 次,指数退避)
  • IsHealthy() — 通过 Stat("/") 探测
  • 切换 profile 时复用已有连接(避免重复 SSH 握手)

App 层新增绑定方法12 个):

SftpConnect(req)        → connID          建立连接
SftpDisconnect(connID)                   断开连接
SftpListDir(connID, path)                列目录
SftpReadFile(connID, path)              读文件
SftpWriteFile(req)                       写文件
SftpGetFileInfo(connID, path)            文件信息
SftpCreateDir(connID, path)             创建目录
SftpCreateFile(connID, path)            创建文件
SftpDeletePath(connID, path)            删除
SftpRenamePath(req)                     重命名
SftpDownloadToTemp(connID, path)        下载到临时目录(预览用)
SftpGetCommonPaths(connID)              远程主机常用路径

前端TypeScript/Vue

新建 frontend/src/api/sftp-transport.ts

  • 实现 FsTransport 接口的完整 23 个方法
  • connect()/disconnect()/requireConn() 管理 SFTP 会话生命周期
  • downloadForPreview(remotePath) 下载远程文件到本地临时目录(带缓存)
  • ZIP/回收站/openPath 等不适用方法抛出 "暂未实现"

修改 connection-manager.ts

  • ConnectionType 扩展:'local' | 'remote' | 'sftp'
  • ConnectionProfile 新增字段:username?, password?, keyPath?
  • applyActive() 增加 sftp 分支(创建 SftpTransport → connect() → 连通性检查)
  • 新增 isSftp() 方法
  • isRemote() 扩展为包含 'sftp'
  • getFileServerBaseURL() sftp 模式返回 'http://localhost:8073'
  • 切换/删除 profile 时显式断开 SFTP 连接

修改 ConnectionDialog.vue

  • 新增连接类型选择器RadioGroup: HTTP Agent / SFTP
  • SFTP 类型显示额外字段:用户名(默认 root、密码、私钥路径
  • HTTP Agent 类型保持原有 Token 字段
  • 默认端口根据类型切换SFTP=22HTTP=9876
  • addProfile 时 type 使用表单选择的值

修改 ConnectionIndicator.vue

  • .dot.sftp 样式(紫色 #7c3aed
  • dotClass(p) 函数返回 local/remote/sftp
  • "更多操作"按钮条件从 type === 'remote' 改为 type !== 'local'

修改 Sidebar.vue

  • 模式标签区分显示:本地(绿)/远程(蓝)/SFTP(紫)
  • 新增 isSftp 响应式变量

修改 useFilePreview.ts

  • SFTP 模式下 updatePreviewUrl() 先调用 downloadForPreview() 下载到本地临时目录
  • 下载完成后使用 http://localhost:8073/localfs/{temp_path} 预览(复用现有 LocalFileServer
  • 已下载文件缓存避免重复下载

文件预览方案

策略:下载到本地临时目录 + 复用 LocalFileServer

用户点击 SFTP 远程文件
  → useFilePreview 检测 isSftp()
  → SftpTransport.downloadForPreview(remotePath)
  → Go 后端 SFTP 下载到 %TEMP%/udesk-sftp-preview-{filename}
  → 返回本地绝对路径
  → 预览 URL = http://localhost:8073/localfs/{temp_path}
  → 现有 LocalFileServer 直接提供服务

临时文件管理

  • 启动时清理上次遗留的 udesk-sftp-preview-* 文件(ServiceStartup 中调用 CleanupTempFiles()
  • 关闭时清理本次创建的临时文件(ServiceShutdown 中调用)
  • SftpTransport 内部维护 remotePath → localTempPath 缓存

文件变更清单

新增5 个)

文件 说明
internal/sftp/config.go SFTP 配置结构体
internal/sftp/client.go SSH/SFTP 连接管理器
internal/sftp/service.go SFTP 文件操作服务
internal/sftp/errors.go 错误处理 + 用户友好消息
frontend/src/api/sftp-transport.ts 前端 FsTransport 实现

修改8 个)

文件 变更
go.mod 添加 github.com/pkg/sftp 依赖
internal/filesystem/fs.go formatBytes 导出为 FormatBytes
app.go +sftpService 字段 + 12 个绑定方法 + Shutdown 扩展 + 清理临时文件
frontend/src/api/connection-manager.ts 类型扩展 + sftp 分支 + isSftp()
frontend/src/.../ConnectionDialog.vue 类型选择器 + SFTP 表单
frontend/src/.../ConnectionIndicator.vue sftp 样式 + dotClass
frontend/src/.../Sidebar.vue SFTP 模式标签
frontend/src/.../useFilePreview.ts SFTP 下载预览

自动生成

文件 触发方式
frontend/src/wailsjs/v3-bindings/u-desk/app.ts wails dev 启动时重新生成

与现有模式的对比

特性 本地 (WailsTransport) 远程 (HttpTransport) SFTP (SftpTransport)
协议 Wails IPC HTTP REST SSH/SFTP
目标要求 本地桌面 部署 u-fs-agent SSH 服务
认证 Bearer Token 密码 / 私钥
文件预览 LocalFileServer Agent 反向代理 下载到临时目录
ZIP 支持
回收站
延迟 < 10ms 取决于网络 取决于网络(首次握手 ~2s
连接复用 N/A 每次请求 HTTP sync.Map 连接池

后续迭代方向

Phase 2体验完善

  • 密钥文件选择器Wails OpenFileDialog
  • 断线重连 UI 提示 + 手动重连按钮
  • 大文件传输进度显示
  • saveBase64File 二进制上传支持

Phase 3高级功能

  • SSH known_hosts 安全验证(替换 InsecureIgnoreHostKey
  • TCP KeepAlive + 应用层心跳防空闲断开
  • 端口转发SOCKS5/本地转发)
  • 符号链接处理选项
  • 并发传输队列 + 带宽限制