94 lines
2.5 KiB
TypeScript
94 lines
2.5 KiB
TypeScript
/**
|
||
* MinIO 客户端封装 - 上传、下载等操作
|
||
* 通过 getMinioConfig() 获取配置,支持主题覆盖
|
||
*/
|
||
|
||
import * as Minio from "minio";
|
||
import { getMinioConfig } from "./config";
|
||
import { getThemeConfig } from "@/config/digital/site.config";
|
||
import type { MinioConfig } from "./config";
|
||
|
||
const ensuredBuckets = new Set<string>();
|
||
|
||
/** 获取 MinIO 客户端实例(使用主题配置) */
|
||
export function getMinioClient(config?: MinioConfig): Minio.Client {
|
||
const theme = getThemeConfig();
|
||
const cfg = config || getMinioConfig(theme.services?.minio);
|
||
return new Minio.Client({
|
||
endPoint: cfg.endPoint,
|
||
port: cfg.port,
|
||
useSSL: cfg.useSSL,
|
||
accessKey: cfg.accessKey,
|
||
secretKey: cfg.secretKey,
|
||
pathStyle: true,
|
||
region: cfg.region,
|
||
});
|
||
}
|
||
|
||
export async function ensurePublicBucket(client: Minio.Client, bucket: string): Promise<void> {
|
||
if (ensuredBuckets.has(bucket)) return;
|
||
const exists = await client.bucketExists(bucket);
|
||
if (!exists) {
|
||
await client.makeBucket(bucket);
|
||
}
|
||
await client.setBucketPolicy(
|
||
bucket,
|
||
JSON.stringify({
|
||
Version: "2012-10-17",
|
||
Statement: [
|
||
{
|
||
Effect: "Allow",
|
||
Principal: { AWS: ["*"] },
|
||
Action: ["s3:GetObject"],
|
||
Resource: [`arn:aws:s3:::${bucket}/*`],
|
||
},
|
||
],
|
||
})
|
||
);
|
||
ensuredBuckets.add(bucket);
|
||
}
|
||
|
||
export interface UploadResult {
|
||
url: string;
|
||
objectKey: string;
|
||
}
|
||
|
||
/**
|
||
* 上传文件到 MinIO
|
||
* @param buffer 文件内容
|
||
* @param objectKey 对象键(含路径,如 joins/xxx.jpg)
|
||
* @param contentType MIME 类型
|
||
*/
|
||
export async function uploadBuffer(
|
||
buffer: Buffer,
|
||
objectKey: string,
|
||
contentType: string = "application/octet-stream"
|
||
): Promise<UploadResult> {
|
||
const theme = getThemeConfig();
|
||
const cfg = getMinioConfig(theme.services?.minio);
|
||
|
||
if (!cfg.enabled) {
|
||
throw new Error("MinIO 存储未启用");
|
||
}
|
||
|
||
const client = getMinioClient(cfg);
|
||
await ensurePublicBucket(client, cfg.bucket);
|
||
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): string {
|
||
const theme = getThemeConfig();
|
||
const cfg = getMinioConfig(theme.services?.minio);
|
||
const prefix = cfg.uploadPrefix.replace(/\/$/, "");
|
||
return `${prefix}/${Date.now()}_${Math.random().toString(36).slice(2)}.${ext}`;
|
||
}
|