新增: 云OSS存储集成(七牛云+阿里云)+多桶导航+GBK编码自动转换
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* OSS Transport — 通过 Wails IPC 调用 Go 后端 OSS 客户端
|
||||
*/
|
||||
|
||||
import type {
|
||||
FsTransport, FileItem, FileOperationResult, DetectTypeResult,
|
||||
} from './transport'
|
||||
import type { ConnectionProfile } from './connection-manager'
|
||||
import {
|
||||
OssConnect, OssDisconnect, OssListDir, OssReadFile,
|
||||
OssWriteFile, OssGetFileInfo, OssCreateDir, OssCreateFile,
|
||||
OssDeletePath, OssRenamePath, OssDownloadToTemp, OssGetCommonPaths,
|
||||
OssWriteBase64File, OssGetSignedURL,
|
||||
} from '@bindings/u-desk/app'
|
||||
|
||||
function transformFile(file: any): FileItem {
|
||||
return { ...file, is_dir: file.is_dir, mod_time: file.mod_time }
|
||||
}
|
||||
|
||||
function transformFileList(files: any[]): FileItem[] {
|
||||
return files.map(transformFile)
|
||||
}
|
||||
|
||||
const PREVIEW_CACHE_MAX = 50
|
||||
|
||||
export class OssTransport implements FsTransport {
|
||||
private profile: ConnectionProfile
|
||||
private connID: string | null = null
|
||||
private previewCache = new Map<string, string>()
|
||||
private previewOrder: string[] = []
|
||||
|
||||
constructor(profile: ConnectionProfile) {
|
||||
this.profile = profile
|
||||
}
|
||||
|
||||
async connect(): Promise<string> {
|
||||
const result = await OssConnect({
|
||||
provider: this.profile.type,
|
||||
access_key: this.profile.accessKey || '',
|
||||
secret_key: this.profile.secretKey || '',
|
||||
endpoint: this.profile.endpoint || '',
|
||||
})
|
||||
this.connID = result
|
||||
return result
|
||||
}
|
||||
|
||||
get sessionId(): string | null { return this.connID }
|
||||
|
||||
async disconnect(): Promise<void> {
|
||||
if (this.connID) {
|
||||
try { await OssDisconnect(this.connID) } catch (e) {
|
||||
console.warn('[OSS] disconnect error:', e)
|
||||
}
|
||||
this.connID = null
|
||||
}
|
||||
this.previewCache.clear()
|
||||
this.previewOrder = []
|
||||
}
|
||||
|
||||
private requireConn(): string {
|
||||
if (!this.connID) throw new Error('OSS 未连接')
|
||||
return this.connID
|
||||
}
|
||||
|
||||
// ====== 文件列表与信息 ======
|
||||
|
||||
async listDir(path: string): Promise<FileItem[]> {
|
||||
return transformFileList(await OssListDir(this.requireConn(), path))
|
||||
}
|
||||
|
||||
async getFileInfo(path: string): Promise<Record<string, any>> {
|
||||
return OssGetFileInfo(this.requireConn(), path)
|
||||
}
|
||||
|
||||
// ====== 文件读写 ======
|
||||
|
||||
async readFile(path: string): Promise<string> {
|
||||
return OssReadFile(this.requireConn(), path)
|
||||
}
|
||||
|
||||
async writeFile(path: string, content: string): Promise<void> {
|
||||
await OssWriteFile(this.requireConn(), path, content)
|
||||
}
|
||||
|
||||
async saveBase64File(path: string, content: string): Promise<void> {
|
||||
if (!content) throw new Error('无效的 base64 内容')
|
||||
await OssWriteBase64File(this.requireConn(), path, content)
|
||||
}
|
||||
|
||||
// ====== 文件操作 ======
|
||||
|
||||
async createFile(dirPath: string, filename: string): Promise<FileOperationResult> {
|
||||
const fullPath = dirPath.replace(/\/$/, '') + '/' + filename
|
||||
return OssCreateFile(this.requireConn(), fullPath)
|
||||
}
|
||||
|
||||
async createDir(parentPath: string, dirname: string): Promise<FileOperationResult> {
|
||||
const fullPath = parentPath.replace(/\/$/, '') + '/' + dirname
|
||||
return OssCreateDir(this.requireConn(), fullPath)
|
||||
}
|
||||
|
||||
async deletePath(path: string): Promise<FileOperationResult> {
|
||||
return OssDeletePath(this.requireConn(), path)
|
||||
}
|
||||
|
||||
async renamePath(oldPath: string, newPath: string): Promise<FileOperationResult> {
|
||||
return OssRenamePath({
|
||||
conn_id: this.requireConn(),
|
||||
old_path: oldPath,
|
||||
new_path: newPath,
|
||||
})
|
||||
}
|
||||
|
||||
// ====== ZIP 操作(不支持)======
|
||||
|
||||
async listZipContents(_zipPath: string): Promise<FileItem[]> {
|
||||
throw new Error('ZIP 操作在 OSS 模式暂未实现')
|
||||
}
|
||||
|
||||
async extractFileFromZip(_zipPath: string, _filePath: string): Promise<string> {
|
||||
throw new Error('ZIP 操作在 OSS 模式暂未实现')
|
||||
}
|
||||
|
||||
async extractFileFromZipToTemp(_zipPath: string, _filePath: string): Promise<string> {
|
||||
throw new Error('ZIP 操作在 OSS 模式暂未实现')
|
||||
}
|
||||
|
||||
async getZipFileInfo(_zipPath: string, _filePath: string): Promise<FileItem> {
|
||||
throw new Error('ZIP 操作在 OSS 模式暂未实现')
|
||||
}
|
||||
|
||||
// ====== 系统操作 ======
|
||||
|
||||
async openPath(_path: string): Promise<void> {
|
||||
throw new Error('OSS 模式不支持打开本地路径')
|
||||
}
|
||||
|
||||
async getFileServerURL(): Promise<string> {
|
||||
return ''
|
||||
}
|
||||
|
||||
getPreviewToken(): string {
|
||||
return ''
|
||||
}
|
||||
|
||||
async resolveShortcut(_lnkPath: string): Promise<any> {
|
||||
return null
|
||||
}
|
||||
|
||||
async detectFileTypeByContent(_path: string): Promise<DetectTypeResult> {
|
||||
return { extension: '', category: 'unknown', mime_type: '', confidence: 0 }
|
||||
}
|
||||
|
||||
async getCommonPaths(): Promise<Record<string, string>> {
|
||||
return OssGetCommonPaths(this.requireConn())
|
||||
}
|
||||
|
||||
// ====== 回收站(无)======
|
||||
|
||||
async getRecycleBinEntries(): Promise<any[]> {
|
||||
return []
|
||||
}
|
||||
|
||||
async restoreFromRecycleBin(_path: string): Promise<void> {}
|
||||
|
||||
async deletePermanently(_path: string): Promise<void> {}
|
||||
|
||||
async emptyRecycleBin(): Promise<void> {}
|
||||
|
||||
// ====== 预览辅助 ======
|
||||
|
||||
async downloadForPreview(remotePath: string): Promise<string> {
|
||||
if (this.previewCache.has(remotePath)) {
|
||||
this.previewOrder = this.previewOrder.filter(p => p !== remotePath)
|
||||
this.previewOrder.push(remotePath)
|
||||
return this.previewCache.get(remotePath)!
|
||||
}
|
||||
const localPath = await OssDownloadToTemp(this.requireConn(), remotePath)
|
||||
|
||||
if (this.previewOrder.length >= PREVIEW_CACHE_MAX) {
|
||||
const oldest = this.previewOrder.shift()!
|
||||
this.previewCache.delete(oldest)
|
||||
}
|
||||
|
||||
this.previewCache.set(remotePath, localPath)
|
||||
this.previewOrder.push(remotePath)
|
||||
return localPath
|
||||
}
|
||||
|
||||
/** 获取预签名 URL(用于直接预览) */
|
||||
async getSignedUrl(key: string): Promise<string> {
|
||||
return OssGetSignedURL(this.requireConn(), key)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user