chore: oss 库 完善

This commit is contained in:
xiaojunnuo
2025-04-27 01:31:46 +08:00
parent 5abce916a8
commit 2943e0e58d
13 changed files with 232 additions and 82 deletions
+4 -2
View File
@@ -9,6 +9,7 @@ export type OssClientRemoveByOpts = {
};
export type OssFileItem = {
//文件全路径
path: string;
size: number;
//毫秒时间戳
@@ -71,17 +72,18 @@ export abstract class BaseOssClient<A> implements IOssClient {
// do nothing
}
abstract remove(fileName: string): Promise<void>;
abstract remove(fileName: string, opts?: { joinRootDir?: boolean }): Promise<void>;
abstract upload(fileName: string, fileContent: Buffer): Promise<void>;
abstract download(fileName: string, savePath: string): Promise<void>;
abstract listDir(dir: string): Promise<OssFileItem[]>;
async removeBy(removeByOpts: OssClientRemoveByOpts): Promise<void> {
const list = await this.listDir(removeByOpts.dir);
// removeByOpts.beforeDays = 0;
const beforeDate = dayjs().subtract(removeByOpts.beforeDays, "day");
for (const item of list) {
if (item.lastModified && item.lastModified < beforeDate.valueOf()) {
await this.remove(item.path);
await this.remove(item.path, { joinRootDir: false });
}
}
}
@@ -37,7 +37,7 @@ export default class AliOssClientImpl extends BaseOssClient<AliossAccess> {
};
});
}
async upload(filePath: string, fileContent: Buffer) {
async upload(filePath: string, fileContent: Buffer | string) {
const key = this.join(this.rootDir, filePath);
this.logger.info(`开始上传文件: ${key}`);
await this.client.uploadFile(key, fileContent);
@@ -45,8 +45,11 @@ export default class AliOssClientImpl extends BaseOssClient<AliossAccess> {
this.logger.info(`文件上传成功: ${filePath}`);
}
async remove(filePath: string) {
const key = this.join(this.rootDir, filePath);
async remove(filePath: string, opts?: { joinRootDir?: boolean }) {
if (opts?.joinRootDir !== false) {
filePath = this.join(this.rootDir, filePath);
}
const key = filePath;
// remove file from alioss
await this.client.removeFile(key);
this.logger.info(`文件删除成功: ${key}`);
@@ -5,23 +5,52 @@ import fs from "fs";
import { FtpAccess, FtpClient } from "../../ftp/index.js";
export default class FtpOssClientImpl extends BaseOssClient<FtpAccess> {
async download(fileName: string, savePath: string) {}
async listDir(dir: string) {
return [];
join(...strs: string[]) {
const str = super.join(...strs);
if (!str.startsWith("/")) {
return "/" + str;
}
return str;
}
async upload(filePath: string, fileContent: Buffer) {
async download(fileName: string, savePath: string) {
const client = this.getFtpClient();
await client.connect(async client => {
const tmpFilePath = path.join(os.tmpdir(), "cert", "http", filePath);
const dir = path.dirname(tmpFilePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
const path = this.join(this.rootDir, fileName);
await client.download(path, savePath);
});
}
async listDir(dir: string) {
const client = this.getFtpClient();
return await client.connect(async (client: FtpClient) => {
const path = this.join(this.rootDir, dir);
const res = await client.listDir(path);
return res.map(item => {
return {
path: this.join(path, item.name),
size: item.size,
lastModified: item.modifiedAt.getTime(),
};
});
});
}
async upload(filePath: string, fileContent: Buffer | string) {
const client = this.getFtpClient();
await client.connect(async client => {
let tmpFilePath = fileContent as string;
if (typeof fileContent !== "string") {
tmpFilePath = path.join(os.tmpdir(), "cert", "oss", filePath);
const dir = path.dirname(tmpFilePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(tmpFilePath, fileContent);
}
fs.writeFileSync(tmpFilePath, fileContent);
try {
// Write file to temp path
const path = this.join(this.rootDir, filePath);
await client.upload(path, tmpFilePath);
await client.upload(tmpFilePath, path);
} finally {
// Remove temp file
fs.unlinkSync(tmpFilePath);
@@ -36,11 +65,14 @@ export default class FtpOssClientImpl extends BaseOssClient<FtpAccess> {
});
}
async remove(filePath: string) {
async remove(filePath: string, opts?: { joinRootDir?: boolean }) {
if (opts?.joinRootDir !== false) {
filePath = this.join(this.rootDir, filePath);
}
const client = this.getFtpClient();
await client.connect(async client => {
const path = this.join(this.rootDir, filePath);
await client.client.remove(path);
await client.client.remove(filePath);
this.logger.info(`删除文件成功: ${filePath}`);
});
}
}
@@ -29,19 +29,22 @@ export default class QiniuOssClientImpl extends BaseOssClient<QiniuOssAccess> {
const res = await this.client.listDir(this.access.bucket, path);
return res.items.map(item => {
return {
path: item.name,
path: item.key,
size: item.fsize,
lastModified: item.putTime,
//ns ,纳秒,去掉低4位 为毫秒
lastModified: Math.floor(item.putTime / 10000),
};
});
}
async upload(filePath: string, fileContent: Buffer) {
async upload(filePath: string, fileContent: Buffer | string) {
const path = this.join(this.rootDir, filePath);
await this.client.uploadFile(this.access.bucket, path, fileContent);
}
async remove(filePath: string) {
const path = this.join(this.rootDir, filePath);
await this.client.removeFile(this.access.bucket, path);
async remove(filePath: string, opts?: { joinRootDir?: boolean }) {
if (opts?.joinRootDir !== false) {
filePath = this.join(this.rootDir, filePath);
}
await this.client.removeFile(this.access.bucket, filePath);
}
}
@@ -79,8 +79,11 @@ export default class S3OssClientImpl extends BaseOssClient<S3Access> {
this.logger.info(`文件上传成功: ${filePath}`);
}
async remove(filePath: string) {
const key = path.join(this.rootDir, filePath);
async remove(filePath: string, opts?: { joinRootDir?: boolean }) {
if (opts?.joinRootDir !== false) {
filePath = this.join(this.rootDir, filePath);
}
const key = filePath;
// @ts-ignore
const { DeleteObjectCommand } = await import("@aws-sdk/client-s3");
await this.client.send(
@@ -1,31 +1,51 @@
import { BaseOssClient, OssClientRemoveByOpts, OssFileItem } from "../api.js";
import { BaseOssClient, OssFileItem } from "../api.js";
import path from "path";
import os from "os";
import fs from "fs";
import { SftpAccess, SshAccess, SshClient } from "../../ssh/index.js";
export default class SftpOssClientImpl extends BaseOssClient<SftpAccess> {
download(fileName: string, savePath: string): Promise<void> {
throw new Error("Method not implemented.");
async download(fileName: string, savePath: string): Promise<void> {
const path = this.join(this.rootDir, fileName);
const client = new SshClient(this.logger);
const access = await this.ctx.accessService.getById<SshAccess>(this.access.sshAccess);
await client.download({
connectConf: access,
filePath: path,
savePath,
});
}
removeBy(removeByOpts: OssClientRemoveByOpts): Promise<void> {
throw new Error("Method not implemented.");
}
listDir(dir: string): Promise<OssFileItem[]> {
throw new Error("Method not implemented.");
}
async upload(filePath: string, fileContent: Buffer) {
const tmpFilePath = path.join(os.tmpdir(), "cert", "http", filePath);
// Write file to temp path
const dir = path.dirname(tmpFilePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
async listDir(dir: string): Promise<OssFileItem[]> {
const path = this.join(this.rootDir, dir);
const client = new SshClient(this.logger);
const access = await this.ctx.accessService.getById<SshAccess>(this.access.sshAccess);
const res = await client.listDir({
connectConf: access,
dir: path,
});
return res.map(item => {
return {
path: this.join(path, item.filename),
size: item.size,
lastModified: item.attrs.atime * 1000,
};
});
}
async upload(filePath: string, fileContent: Buffer | string) {
let tmpFilePath = fileContent as string;
if (typeof fileContent !== "string") {
tmpFilePath = path.join(os.tmpdir(), "cert", "oss", filePath);
const dir = path.dirname(tmpFilePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(tmpFilePath, fileContent);
}
fs.writeFileSync(tmpFilePath, fileContent);
const access = await this.ctx.accessService.getById<SshAccess>(this.access.sshAccess);
const key = this.rootDir + filePath;
const key = this.join(this.rootDir, filePath);
try {
const client = new SshClient(this.logger);
await client.uploadFiles({
@@ -37,6 +57,7 @@ export default class SftpOssClientImpl extends BaseOssClient<SftpAccess> {
remotePath: key,
},
],
uploadType: "sftp",
opts: {
mode: this.access?.fileMode ?? undefined,
},
@@ -47,13 +68,15 @@ export default class SftpOssClientImpl extends BaseOssClient<SftpAccess> {
}
}
async remove(filePath: string) {
async remove(filePath: string, opts?: { joinRootDir?: boolean }) {
const access = await this.ctx.accessService.getById<SshAccess>(this.access.sshAccess);
const client = new SshClient(this.logger);
const key = this.rootDir + filePath;
if (opts?.joinRootDir !== false) {
filePath = this.join(this.rootDir, filePath);
}
await client.removeFiles({
connectConf: access,
files: [key],
files: [filePath],
});
}
}
@@ -4,6 +4,7 @@ import os from "os";
import fs from "fs";
import { SshAccess, SshClient } from "../../ssh/index.js";
//废弃
export default class SshOssClientImpl extends BaseOssClient<SshAccess> {
download(fileName: string, savePath: string): Promise<void> {
throw new Error("Method not implemented.");
@@ -43,12 +44,14 @@ export default class SshOssClientImpl extends BaseOssClient<SshAccess> {
}
}
async remove(filePath: string) {
async remove(filePath: string, opts?: { joinRootDir?: boolean }) {
if (opts?.joinRootDir !== false) {
filePath = this.join(this.rootDir, filePath);
}
const client = new SshClient(this.logger);
const key = this.rootDir + filePath;
await client.removeFiles({
connectConf: this.access,
files: [key],
files: [filePath],
});
}
}
@@ -38,13 +38,17 @@ export default class TencentOssClientImpl extends BaseOssClient<TencentCosAccess
};
});
}
async upload(filePath: string, fileContent: Buffer) {
async upload(filePath: string, fileContent: Buffer | string) {
const key = this.join(this.rootDir, filePath);
await this.client.uploadFile(key, fileContent);
this.logger.info(`文件上传成功: ${filePath}`);
}
async remove(filePath: string) {
const key = this.join(this.rootDir, filePath);
await this.client.removeFile(key);
async remove(filePath: string, opts?: { joinRootDir?: boolean }) {
if (opts?.joinRootDir !== false) {
filePath = this.join(this.rootDir, filePath);
}
await this.client.removeFile(filePath);
this.logger.info(`文件删除成功: ${filePath}`);
}
}