116 lines
3.4 KiB
TypeScript
116 lines
3.4 KiB
TypeScript
import type OSS from 'ali-oss'
|
|
import {
|
|
getSTSToken,
|
|
getOssSignatureUrl,
|
|
checkOssSignatureUrlIsExist,
|
|
} from '@apis/oss'
|
|
import type { STSTokenResponse, UploadParams, UploadResult } from '../type'
|
|
import { OSSBucketType } from '../type'
|
|
import { StorageAdapter } from './base'
|
|
|
|
// 常量定义
|
|
const OSS_REGION = 'oss-cn-hangzhou'
|
|
|
|
export class OSSClient extends StorageAdapter<OSS> {
|
|
private static instance: OSSClient
|
|
|
|
// 获取默认实例键值
|
|
protected getDefaultInstanceKey(): string {
|
|
return 'bty-oss-token'
|
|
}
|
|
|
|
// 获取提供商前缀
|
|
protected getProviderPrefix(): string {
|
|
return 'custom-oss'
|
|
}
|
|
|
|
// 默认获取STS Token的方法
|
|
protected async defaultGetSTSToken(): Promise<STSTokenResponse> {
|
|
return getSTSToken()
|
|
}
|
|
|
|
// 获取默认OSSClient单例
|
|
public static getInstance(): OSSClient {
|
|
if (!OSSClient.instance) {
|
|
OSSClient.instance = new OSSClient()
|
|
}
|
|
return OSSClient.instance
|
|
}
|
|
|
|
// 创建自定义OSSClient实例
|
|
public static createCustomInstance(
|
|
getSTSTokenFn: () => Promise<STSTokenResponse>,
|
|
): OSSClient {
|
|
return new OSSClient(getSTSTokenFn)
|
|
}
|
|
|
|
// 刷新OSS客户端
|
|
protected async refreshClient(): Promise<void> {
|
|
const token = await this.getSTSToken()
|
|
const aliOssModule: any = await import('ali-oss')
|
|
const OSSSdk: typeof OSS = aliOssModule.default || (aliOssModule as any)
|
|
this.client = new OSSSdk({
|
|
region: token.region || OSS_REGION,
|
|
accessKeyId: token.access_key_id,
|
|
accessKeySecret: token.access_key_secret,
|
|
stsToken: token.security_token,
|
|
secure: true,
|
|
...(Reflect.has(token, 'secure') ? { secure: token.secure } : {}),
|
|
})
|
|
this.bucketMap = {
|
|
[OSSBucketType.PRIVATE]: token.data_bucket,
|
|
[OSSBucketType.PUBLIC]: token.resource_bucket,
|
|
} as Record<OSSBucketType, string>
|
|
}
|
|
|
|
// 上传文件
|
|
public async upload(params: UploadParams): Promise<UploadResult> {
|
|
try {
|
|
const client = await this.getClient()
|
|
const bucketName =
|
|
params.custom_bucket ||
|
|
this.getBucketName(params.bucketType || OSSBucketType.PRIVATE)
|
|
client!.useBucket(bucketName)
|
|
|
|
const result = await client.put(
|
|
params.filePath,
|
|
params.file,
|
|
params.options || {},
|
|
)
|
|
const url = (result.res as any)?.requestUrls?.[0]?.split('?')?.[0]
|
|
return { url, result }
|
|
} catch (error) {
|
|
console.error('File upload failed:', error)
|
|
throw new Error(`File upload failed: ${(error as Error).message}`)
|
|
}
|
|
}
|
|
|
|
public async multipartUpload(params: UploadParams): Promise<UploadResult> {
|
|
try {
|
|
const client = await this.getClient()
|
|
const bucketName =
|
|
params.custom_bucket ||
|
|
this.getBucketName(params.bucketType || OSSBucketType.PRIVATE)
|
|
client!.useBucket(bucketName)
|
|
const result = await client.multipartUpload(
|
|
params.filePath,
|
|
params.file,
|
|
params.options || {},
|
|
)
|
|
const url = (result.res as any)?.requestUrls?.[0]?.split('?')?.[0]
|
|
return { url, result }
|
|
} catch (error) {
|
|
console.error('File upload failed:', error)
|
|
throw new Error(`File upload failed: ${(error as Error).message}`)
|
|
}
|
|
}
|
|
|
|
public async getOssSignatureUrl(key: string, params?: Record<string, any>) {
|
|
return getOssSignatureUrl(key, params)
|
|
}
|
|
|
|
public async checkOssSignatureUrlIsExist(url: string) {
|
|
return checkOssSignatureUrlIsExist(url)
|
|
}
|
|
}
|