feat: image upload & preview untuk bug reports via MinIO
- Upload hingga 3 gambar per bug report (FileInput multi-select) - Backend: POST /api/upload/image → MinIO, GET /api/bugs/images → presigned URL redirect - Auto-create bucket jika belum ada saat server start - Preview gambar fullscreen saat thumbnail diklik - Diterapkan di /bug-reports dan /apps/$appId/errors - Migrasi storage dari Seafile ke MinIO (minio SDK v8) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
36
src/lib/minio.ts
Normal file
36
src/lib/minio.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { Client } from 'minio'
|
||||
import { env } from './env'
|
||||
|
||||
const client = new Client({
|
||||
endPoint: env.MINIO_ENDPOINT,
|
||||
port: env.MINIO_PORT,
|
||||
useSSL: env.MINIO_USE_SSL,
|
||||
accessKey: env.MINIO_ACCESS_KEY,
|
||||
secretKey: env.MINIO_SECRET_KEY,
|
||||
})
|
||||
|
||||
// Auto-create bucket if it doesn't exist
|
||||
client.bucketExists(env.MINIO_BUCKET).then(async (exists) => {
|
||||
if (!exists) {
|
||||
await client.makeBucket(env.MINIO_BUCKET)
|
||||
console.log(`[MinIO] Bucket "${env.MINIO_BUCKET}" created.`)
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('[MinIO] Failed to check/create bucket:', err.message)
|
||||
})
|
||||
|
||||
export async function uploadBugImage(file: File): Promise<string> {
|
||||
const ext = file.name.split('.').pop()?.toLowerCase() ?? 'bin'
|
||||
const objectName = `${env.MINIO_UPLOAD_DIR}/${crypto.randomUUID()}.${ext}`
|
||||
const buffer = Buffer.from(await file.arrayBuffer())
|
||||
|
||||
await client.putObject(env.MINIO_BUCKET, objectName, buffer, file.size, {
|
||||
'Content-Type': file.type,
|
||||
})
|
||||
|
||||
return objectName // e.g. bug-reports/uuid.jpg
|
||||
}
|
||||
|
||||
export async function getMinioDownloadUrl(objectName: string): Promise<string> {
|
||||
return client.presignedGetObject(env.MINIO_BUCKET, objectName, 3600)
|
||||
}
|
||||
Reference in New Issue
Block a user