/** * MinIO SDK - 上传、下载,随时可调用 * 复制自 digital 项目 */ import * as Minio from "minio"; import { getMinioConfig } from "../config"; export interface UploadResult { url: string; objectKey: string; } /** 获取 MinIO 客户端实例 */ export function getMinioClient(overrides?: { bucket?: string; uploadPrefix?: string }): Minio.Client { const cfg = getMinioConfig(overrides); return new Minio.Client({ endPoint: cfg.endPoint, port: cfg.port, useSSL: cfg.useSSL, accessKey: cfg.accessKey, secretKey: cfg.secretKey, pathStyle: true, region: cfg.region, }); } /** * 上传文件到 MinIO * @param buffer 文件内容 * @param objectKey 对象键(含路径) * @param contentType MIME 类型 */ export async function uploadBuffer( buffer: Buffer, objectKey: string, contentType: string = "application/octet-stream", overrides?: { bucket?: string; uploadPrefix?: string } ): Promise { const cfg = getMinioConfig(overrides); if (!cfg.enabled) throw new Error("MinIO 存储未启用"); const client = getMinioClient(overrides); await client.putObject(cfg.bucket, objectKey, buffer, buffer.length, { "Content-Type": contentType, }); const url = `${cfg.publicUrl}/${objectKey}`; return { url, objectKey }; } /** * 生成上传用的对象键 * @param ext 文件扩展名 */ export function generateObjectKey(ext: string, overrides?: { uploadPrefix?: string }): string { const cfg = getMinioConfig(overrides); const prefix = cfg.uploadPrefix.replace(/\/$/, ""); return `${prefix}/${Date.now()}_${Math.random().toString(36).slice(2)}.${ext}`; }