Private
Public Access
1
0

新增: 云OSS存储集成(七牛云+阿里云)+多桶导航+GBK编码自动转换

This commit is contained in:
2026-05-05 03:18:47 +08:00
parent eb5b85e007
commit b4f4b4627d
34 changed files with 5225 additions and 48 deletions

View File

@@ -7,13 +7,14 @@ import type { FsTransport } from './transport'
import { WailsTransport } from './wails-transport'
import { HttpTransport } from './http-transport'
import { SftpTransport } from './sftp-transport'
import { OssTransport } from './oss-transport'
import { getFileServerBaseURL } from './file-server'
import {
LoadConnectionProfiles, SaveConnectionProfile, DeleteConnectionProfile,
SftpGetSystemInfo, GetLocalSystemInfo,
} from '@bindings/u-desk/app'
export type ConnectionType = 'local' | 'remote' | 'sftp'
export type ConnectionType = 'local' | 'remote' | 'sftp' | 'qiniu' | 'aliyun'
export interface ConnectionProfile {
id: string | number
@@ -25,6 +26,11 @@ export interface ConnectionProfile {
username?: string
password?: string
keyPath?: string
accessKey?: string
secretKey?: string
bucket?: string
region?: string
endpoint?: string
lastConnected?: number
}
@@ -124,6 +130,11 @@ class ConnectionManagerImpl {
keyPath: profile.keyPath || '',
type: profile.type,
token: profile.token || '',
access_key: profile.accessKey || '',
secret_key: profile.secretKey || '',
bucket: profile.bucket || '',
region: profile.region || '',
endpoint: profile.endpoint || '',
lastConnected: profile.lastConnected ? Math.floor(profile.lastConnected / 1000) : undefined,
})
}
@@ -189,7 +200,7 @@ class ConnectionManagerImpl {
isRemote(): boolean {
const t = this.activeProfile?.type
return t === 'remote' || t === 'sftp'
return t === 'remote' || t === 'sftp' || t === 'qiniu' || t === 'aliyun'
}
getSystemInfo(profileId: string): SystemInfo | undefined {
@@ -210,6 +221,11 @@ class ConnectionManagerImpl {
const data = await SftpGetSystemInfo(t.sessionId)
if (data) Object.assign(info, snakeToCamel(data))
}
} else if (profile.type === 'qiniu' || profile.type === 'aliyun') {
// OSS 无系统信息可采集
info.diskUsage = '-'
info.cpuUsage = '-'
info.memUsage = '-'
} else if (profile.type === 'remote') {
const t = this.getTransportFor(profileId)
if (t instanceof HttpTransport) {
@@ -243,16 +259,16 @@ class ConnectionManagerImpl {
const profile = this._profiles.find(p => p.id === profileId)
if (!profile) return Promise.reject(new Error(`连接配置不存在: ${profileId}`))
this._activeId = profileId
// 池中已有,直接复用
if (this._pool.has(profileId)) {
this._activeId = profileId
this.setState('connected')
return
}
// 新建连接并入池
// 新建连接并入池(成功后再设 activeId
await this.buildAndPool(profileId, profile)
this._activeId = profileId
}
/** 断开指定 profile 并从池移除 */
@@ -260,14 +276,15 @@ class ConnectionManagerImpl {
if (profileId === 'local-default') return
const t = this._pool.get(profileId)
if (t instanceof SftpTransport) { t.disconnect() }
if (t instanceof OssTransport) { t.disconnect() }
this._pool.delete(profileId)
}
/** 断开所有远程连接(保留 local */
disconnectAll(): void {
for (const [id, t] of this._pool) {
if (id !== 'local-default' && t instanceof SftpTransport) {
t.disconnect()
if (id !== 'local-default') {
if (t instanceof SftpTransport || t instanceof OssTransport) t.disconnect()
}
}
this._pool.clear()
@@ -294,7 +311,7 @@ class ConnectionManagerImpl {
this._profiles[idx] = { ...this._profiles[idx], ...updates }
await this.persistProfile(this._profiles[idx])
// 连接参数变更 → 淘汰旧连接,下次 connect 时重建
const EVICT_KEYS = ['host', 'port', 'token', 'username', 'password', 'keyPath'] as const
const EVICT_KEYS = ['host', 'port', 'token', 'username', 'password', 'keyPath', 'accessKey', 'secretKey', 'bucket', 'region', 'endpoint'] as const
if (EVICT_KEYS.some(k => k in updates)) {
this.disconnectProfile(id)
if (id === this._activeId) {
@@ -346,6 +363,23 @@ class ConnectionManagerImpl {
return
}
// OSS (qiniu / aliyun)
if (profile.type === 'qiniu' || profile.type === 'aliyun') {
this.setState('connecting')
try {
const t = new OssTransport(profile)
await t.connect()
this._pool.set(profileId, t)
this.setState('connected')
this.updateProfile(profileId, { lastConnected: Date.now() })
} catch (err) {
this._pool.delete(profileId)
this.setState('error')
throw err
}
return
}
// remote / http agent
this.setState('connecting')
try {