Refactor storage integration from MinIO to S3

- Removed MinIO client and related imports from various modules.
- Introduced S3 client and OSS integration for object storage.
- Updated all references to MinIO methods with corresponding S3 methods.
- Added new flowme table schema to the database.
- Adjusted upload and download routes to utilize S3 for file operations.
- Removed obsolete MinIO-related files and routes.
- Ensured compatibility with existing application logic while transitioning to S3.
This commit is contained in:
2026-01-31 05:12:56 +08:00
parent 08023d6878
commit 6100e9833d
24 changed files with 1440 additions and 328 deletions

View File

@@ -1,7 +1,6 @@
import dayjs from 'dayjs';
import { minioClient } from '../../../modules/minio.ts';
import { bucketName } from '../../../modules/minio.ts';
import { BucketItemStat, CopyDestinationOptions, CopySourceOptions } from 'minio';
import { oss } from '@/app.ts';
import { StatObjectResult } from '@kevisual/oss';
type MinioListOpt = {
prefix: string;
recursive?: boolean;
@@ -20,33 +19,13 @@ export type MinioList = (MinioFile | MinioDirectory)[];
export const getMinioList = async <IS_FILE extends boolean>(opts: MinioListOpt): Promise<IS_FILE extends true ? MinioFile[] : MinioDirectory[]> => {
const prefix = opts.prefix;
const recursive = opts.recursive ?? false;
const res = await new Promise((resolve, reject) => {
let res: any[] = [];
let hasError = false;
minioClient
.listObjectsV2(bucketName, prefix, recursive)
.on('data', (data) => {
res.push(data);
})
.on('error', (err) => {
console.error('minio error', opts.prefix, err);
hasError = true;
})
.on('end', () => {
if (hasError) {
reject();
return;
} else {
resolve(res);
}
});
});
const res = await oss.listObjects(prefix, { recursive });
return res as IS_FILE extends true ? MinioFile[] : MinioDirectory[];
};
export const getFileStat = async (prefix: string, isFile?: boolean): Promise<BucketItemStat | null> => {
export const getFileStat = async (prefix: string, isFile?: boolean): Promise<StatObjectResult | null> => {
try {
const obj = await minioClient.statObject(bucketName, prefix);
if (isFile && obj.size === 0) {
const obj = await oss.statObject(prefix);
if (isFile && obj?.size === 0) {
return null;
}
return obj;
@@ -69,10 +48,7 @@ export const deleteFile = async (prefix: string): Promise<{ code: number; messag
message: 'file not found',
};
}
await minioClient.removeObject(bucketName, prefix, {
versionId: 'null',
forceDelete: true, // 强制删除
});
await oss.deleteObject(prefix);
return {
code: 200,
message: 'delete success',
@@ -89,7 +65,9 @@ export const deleteFile = async (prefix: string): Promise<{ code: number; messag
// 批量删除文件
export const deleteFiles = async (prefixs: string[]): Promise<any> => {
try {
await minioClient.removeObjects(bucketName, prefixs);
for (const prefix of prefixs) {
await oss.deleteObject(prefix);
}
return true;
} catch (e) {
console.error('delete Files Error not handle', e);
@@ -135,14 +113,9 @@ export const updateFileStat = async (
message?: string;
}> => {
try {
const source = new CopySourceOptions({ Bucket: bucketName, Object: prefix });
const destination = new CopyDestinationOptions({
Bucket: bucketName,
Object: prefix,
UserMetadata: newMetadata,
MetadataDirective: 'REPLACE',
const copyResult = await oss.replaceObject(prefix, {
...newMetadata
});
const copyResult = await minioClient.copyObject(source, destination);
console.log('copyResult', copyResult);
console.log(`Metadata for ${prefix} updated successfully.`);
return {
@@ -171,23 +144,13 @@ export const mvUserAToUserB = async (usernameA: string, usernameB: string, clear
const newPrefix = `${usernameB}/`;
const listSource = await getMinioList<true>({ prefix: oldPrefix, recursive: true });
for (const item of listSource) {
const source = new CopySourceOptions({ Bucket: bucketName, Object: item.name });
const stat = await getFileStat(item.name);
const newName = item.name.slice(oldPrefix.length);
// @ts-ignore
const metadata = stat?.userMetadata || stat.metaData;
const destination = new CopyDestinationOptions({
Bucket: bucketName,
Object: `${newPrefix}${newName}`,
UserMetadata: metadata,
MetadataDirective: 'COPY',
});
await minioClient.copyObject(source, destination);
await oss.copyObject(item.name, `${newPrefix}${newName}`);
}
if (clearOldUser) {
const files = await getMinioList<true>({ prefix: oldPrefix, recursive: true });
for (const file of files) {
await minioClient.removeObject(bucketName, file.name);
await oss.deleteObject(file.name);
}
}
};
@@ -202,7 +165,7 @@ export const backupUserA = async (usernameA: string, id: string, backName?: stri
for (const item of deleteBackup) {
const files = await getMinioList<true>({ prefix: item.prefix, recursive: true });
for (const file of files) {
await minioClient.removeObject(bucketName, file.name);
await oss.deleteObject(file.name);
}
}
}
@@ -215,6 +178,6 @@ export const backupUserA = async (usernameA: string, id: string, backName?: stri
export const deleteUser = async (username: string) => {
const list = await getMinioList<true>({ prefix: `${username}/`, recursive: true });
for (const item of list) {
await minioClient.removeObject(bucketName, item.name);
await oss.deleteObject(item.name);
}
};