Files
code-center/src/routes/file/module/get-minio-list.ts
abearxiong 6100e9833d 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.
2026-01-31 05:12:56 +08:00

184 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import dayjs from 'dayjs';
import { oss } from '@/app.ts';
import { StatObjectResult } from '@kevisual/oss';
type MinioListOpt = {
prefix: string;
recursive?: boolean;
};
export type MinioFile = {
name: string;
size: number;
lastModified: Date;
etag: string;
};
export type MinioDirectory = {
prefix: string;
size: number;
};
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 oss.listObjects(prefix, { recursive });
return res as IS_FILE extends true ? MinioFile[] : MinioDirectory[];
};
export const getFileStat = async (prefix: string, isFile?: boolean): Promise<StatObjectResult | null> => {
try {
const obj = await oss.statObject(prefix);
if (isFile && obj?.size === 0) {
return null;
}
return obj;
} catch (e) {
if (e.code === 'NotFound') {
return null;
}
console.error('get File Stat Error not handle', e);
return null;
}
};
export const deleteFile = async (prefix: string): Promise<{ code: number; message: string }> => {
try {
const fileStat = await getFileStat(prefix);
if (!fileStat) {
console.warn(`File not found: ${prefix}`);
return {
code: 404,
message: 'file not found',
};
}
await oss.deleteObject(prefix);
return {
code: 200,
message: 'delete success',
};
} catch (e) {
console.error('delete File Error not handle', e);
return {
code: 500,
message: 'delete failed',
};
}
};
// 批量删除文件
export const deleteFiles = async (prefixs: string[]): Promise<any> => {
try {
for (const prefix of prefixs) {
await oss.deleteObject(prefix);
}
return true;
} catch (e) {
console.error('delete Files Error not handle', e);
return false;
}
};
export const deleteFileByPrefix = async (prefix: string): Promise<any> => {
try {
const allFiles = await getMinioList<true>({ prefix, recursive: true });
const files = allFiles.filter((item) => item.name.startsWith(prefix));
await deleteFiles(files.map((item) => item.name));
return true;
} catch (e) {
console.error('delete File Error not handle', e);
return false;
}
};
type GetMinioListAndSetToAppListOpts = {
username: string;
appKey: string;
version: string;
};
// 批量列出文件并设置到appList的files中
export const getMinioListAndSetToAppList = async (opts: GetMinioListAndSetToAppListOpts) => {
const { username, appKey, version } = opts;
const minioList = await getMinioList({ prefix: `${username}/${appKey}/${version}`, recursive: true });
const files = minioList;
return files as MinioFile[];
};
/**
* 更新文件的元数据
* @param prefix 文件前缀
* @param newMetadata 新的元数据
* @returns
*/
export const updateFileStat = async (
prefix: string,
newMetadata: Record<string, string>,
): Promise<{
code: number;
data: any;
message?: string;
}> => {
try {
const copyResult = await oss.replaceObject(prefix, {
...newMetadata
});
console.log('copyResult', copyResult);
console.log(`Metadata for ${prefix} updated successfully.`);
return {
code: 200,
data: copyResult,
message: 'update metadata success',
};
} catch (e) {
console.error('Error updating file stat', e);
return {
code: 500,
data: null,
message: `update metadata failed. ${e.message}`,
};
}
};
/**
* 将用户A的文件移动到用户B
* @param usernameA
* @param usernameB
* @param clearOldUser 是否清除用户A的文件
*/
export const mvUserAToUserB = async (usernameA: string, usernameB: string, clearOldUser = false) => {
const oldPrefix = `${usernameA}/`;
const newPrefix = `${usernameB}/`;
const listSource = await getMinioList<true>({ prefix: oldPrefix, recursive: true });
for (const item of listSource) {
const newName = item.name.slice(oldPrefix.length);
await oss.copyObject(item.name, `${newPrefix}${newName}`);
}
if (clearOldUser) {
const files = await getMinioList<true>({ prefix: oldPrefix, recursive: true });
for (const file of files) {
await oss.deleteObject(file.name);
}
}
};
export const backupUserA = async (usernameA: string, id: string, backName?: string) => {
const today = backName || dayjs().format('YYYY-MM-DD-HH-mm');
const backupAllPrefix = `private/backup/${id}/`;
const backupPrefix = `private/backup/${id}/${today}`;
const backupList = await getMinioList<false>({ prefix: backupAllPrefix });
const backupListSort = backupList.sort((a, b) => -a.prefix.localeCompare(b.prefix));
if (backupListSort.length > 2) {
const deleteBackup = backupListSort.slice(2);
for (const item of deleteBackup) {
const files = await getMinioList<true>({ prefix: item.prefix, recursive: true });
for (const file of files) {
await oss.deleteObject(file.name);
}
}
}
await mvUserAToUserB(usernameA, backupPrefix, false);
};
/**
* 删除用户
* @param username
*/
export const deleteUser = async (username: string) => {
const list = await getMinioList<true>({ prefix: `${username}/`, recursive: true });
for (const item of list) {
await oss.deleteObject(item.name);
}
};