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" "context"
"fmt" "fmt"
"io" "io"
"log"
"math/rand" "math/rand"
"mime"
"mime/multipart" "mime/multipart"
"narasi-ahli-be/app/module/ai_chat_files/mapper" "narasi-ahli-be/app/module/ai_chat_files/mapper"
"narasi-ahli-be/app/module/ai_chat_files/repository" "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) 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") filename := c.Params("filename")
result, err := _i.Repo.FindByFilename(filename) result, err := _i.Repo.FindByFilename(filename)
if err != nil { if err != nil {
return err return err
@ -307,41 +306,48 @@ func (_i *aiChatFilesService) Viewer(c *fiber.Ctx) (err error) {
bucketName := _i.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName bucketName := _i.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName
objectName := *result.FilePath 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() minioClient, err := _i.MinioStorage.ConnectMinio()
if err != nil { if err != nil {
// Return status 500 and minio connection error.
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": true, "error": true,
"msg": err.Error(), "msg": err.Error(),
}) })
} }
fileContent, err := minioClient.GetObject(ctx, bucketName, objectName, minio.GetObjectOptions{}) object, err := minioClient.GetObject(
ctx,
bucketName,
objectName,
minio.GetObjectOptions{},
)
if err != nil { if err != nil {
log.Fatalln(err) return err
} }
defer fileContent.Close() defer object.Close()
// Tentukan Content-Type berdasarkan ekstensi file // 🔥 Ambil metadata object (INI PENTING)
contentType := mime.TypeByExtension("." + getFileExtension(objectName)) stat, err := object.Stat()
if contentType == "" { if err != nil {
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 {
return err 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 { func getFileExtension(filename string) string {
// split file name // split file name
parts := strings.Split(filename, ".") parts := strings.Split(filename, ".")