fix:ai chat file viewer

This commit is contained in:
Rama Priyanto 2026-01-08 14:49:23 +07:00
parent 775b06ac89
commit b6bb1f4007
1 changed files with 28 additions and 22 deletions

View File

@ -4,9 +4,7 @@ import (
"context"
"fmt"
"io"
"log"
"math/rand"
"mime"
"mime/multipart"
"narasi-ahli-be/app/module/ai_chat_files/mapper"
"narasi-ahli-be/app/module/ai_chat_files/repository"
@ -296,8 +294,9 @@ func (_i *aiChatFilesService) Delete(id uint) error {
return _i.Repo.Update(id, result)
}
func (_i *aiChatFilesService) Viewer(c *fiber.Ctx) (err error) {
func (_i *aiChatFilesService) Viewer(c *fiber.Ctx) error {
filename := c.Params("filename")
result, err := _i.Repo.FindByFilename(filename)
if err != nil {
return err
@ -307,41 +306,48 @@ func (_i *aiChatFilesService) Viewer(c *fiber.Ctx) (err error) {
bucketName := _i.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName
objectName := *result.FilePath
_i.Log.Info().Str("timestamp", time.Now().
Format(time.RFC3339)).Str("Service:Resource", "AiChat:Uploads").
Interface("data", objectName).Msg("")
// Create minio connection.
minioClient, err := _i.MinioStorage.ConnectMinio()
if err != nil {
// Return status 500 and minio connection error.
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": true,
"msg": err.Error(),
})
}
fileContent, err := minioClient.GetObject(ctx, bucketName, objectName, minio.GetObjectOptions{})
object, err := minioClient.GetObject(
ctx,
bucketName,
objectName,
minio.GetObjectOptions{},
)
if err != nil {
log.Fatalln(err)
return err
}
defer fileContent.Close()
defer object.Close()
// Tentukan Content-Type berdasarkan ekstensi file
contentType := mime.TypeByExtension("." + getFileExtension(objectName))
if contentType == "" {
contentType = "application/octet-stream" // fallback jika tidak ada tipe MIME yang cocok
}
c.Set("Content-Type", contentType)
if _, err := io.Copy(c.Response().BodyWriter(), fileContent); err != nil {
// 🔥 Ambil metadata object (INI PENTING)
stat, err := object.Stat()
if err != nil {
return err
}
return
// 🔥 Content-Type yang BENAR
if stat.ContentType != "" {
c.Set("Content-Type", stat.ContentType)
} else {
// fallback kalau metadata kosong
c.Type(filepath.Ext(objectName))
}
// 🔥 WAJIB untuk preview media
c.Set("Content-Disposition", "inline")
c.Set("Accept-Ranges", "bytes")
// 🔥 BIARKAN FIBER HANDLE STREAMING
return c.SendStream(object)
}
func getFileExtension(filename string) string {
// split file name
parts := strings.Split(filename, ".")