fix:knowledge base file

This commit is contained in:
Rama Priyanto 2026-02-09 15:44:31 +07:00
parent 760d72ac7e
commit e68b01a25a
3 changed files with 55 additions and 71 deletions

View File

@ -9,6 +9,7 @@ func KnowledgeBaseResponseMapper(kb *entity.KnowledgeBase, host string) (out *re
if kb == nil {
return nil
}
out = &res.KnowledgeBaseResponse{
ID: kb.ID,

View File

@ -118,31 +118,26 @@ func (r *KnowledgeBaseRepository) Delete(id uint) (err error) {
return r.DB.DB.Delete(&entity.KnowledgeBase{}, id).Error
}
func (r *KnowledgeBaseRepository) FindByFilename(filename string) (data *entity.KnowledgeBase, fileType string, err error) {
query := r.DB.DB.Model(&entity.KnowledgeBase{}).Where("is_active = ?", true)
func (r *KnowledgeBaseRepository) FindByFilename(filename string) (*entity.KnowledgeBase, string, error) {
// cari berdasarkan url yang mengandung filename
like := "%" + filename
// journal
var kb entity.KnowledgeBase
if err := query.Where("file_journal_url LIKE ?", like).First(&kb).Error; err == nil {
return &kb, "journal", nil
if err := r.DB.DB.Where("file_journal_url LIKE ?", "%"+filename).First(&kb).Error; err == nil {
return &kb, *kb.FileJournalUrl, nil
}
// audio
if err := query.Where("file_audio_url LIKE ?", like).First(&kb).Error; err == nil {
return &kb, "audio", nil
if err := r.DB.DB.Where("file_audio_url LIKE ?", "%"+filename).First(&kb).Error; err == nil {
return &kb, *kb.FileAudioUrl, nil
}
// video
if err := query.Where("file_video_url LIKE ?", like).First(&kb).Error; err == nil {
return &kb, "video", nil
if err := r.DB.DB.Where("file_video_url LIKE ?", "%"+filename).First(&kb).Error; err == nil {
return &kb, *kb.FileVideoUrl, nil
}
return nil, "", fmt.Errorf("file not found")
}
func (r *KnowledgeBaseRepository) UpdateDocumentId(id uint, documentId int) error {
return r.DB.DB.Model(&entity.KnowledgeBase{}).
Where("id = ?", id).

View File

@ -3,7 +3,6 @@ package service
import (
"context"
"fmt"
"io"
"mime"
"mime/multipart"
"narasi-ahli-be/app/module/knowledge_base/mapper"
@ -64,7 +63,6 @@ func (s *KnowledgeBaseService) uploadFileToMinio(
minioClient *minio.Client,
bucketName string,
agentId string,
folder string,
fileHeader *multipart.FileHeader,
) (*string, error) {
@ -87,10 +85,10 @@ func (s *KnowledgeBaseService) uploadFileToMinio(
now := time.Now()
newFilename := fmt.Sprintf("%s_%d%s", filenameWithoutExt, now.UnixNano(), ext)
// ⭐ INI PATH ASLI MINIO
objectName := fmt.Sprintf(
"knowledge-base/%s/%s/%s",
"knowledge-base/%s/%s",
agentId,
folder,
newFilename,
)
@ -100,15 +98,19 @@ func (s *KnowledgeBaseService) uploadFileToMinio(
objectName,
src,
fileHeader.Size,
minio.PutObjectOptions{},
minio.PutObjectOptions{
ContentType: fileHeader.Header.Get("Content-Type"),
},
)
if err != nil {
return nil, err
}
return &newFilename, nil
// ⭐ KEMBALIKAN OBJECT PATH
return &objectName, nil
}
func (s *KnowledgeBaseService) All(req request.KnowledgeBaseQueryRequest) (data []*response.KnowledgeBaseResponse, paging paginator.Pagination, err error) {
results, paging, err := s.Repo.GetAll(req)
@ -134,52 +136,55 @@ func getFileExtension(filename string) string {
return parts[len(parts)-1]
}
func (s *KnowledgeBaseService) Viewer(c *fiber.Ctx) (err error) {
func (s *KnowledgeBaseService) Viewer(c *fiber.Ctx) error {
filename := c.Params("filename")
result, folder, err := s.Repo.FindByFilename(filename)
_, objectName, err := s.Repo.FindByFilename(filename)
if err != nil {
return err
return c.Status(404).SendString("file not found")
}
ctx := context.Background()
bucketName := s.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName
objectName := fmt.Sprintf("knowledge-base/%s/%s/%s", *result.AgentId, folder, filename)
s.Log.Info().
Str("timestamp", time.Now().Format(time.RFC3339)).
Str("Service:Resource", "KnowledgeBase:Viewer").
Interface("objectName", objectName).
Msg("")
minioClient, err := s.MinioStorage.ConnectMinio()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": true,
"msg": err.Error(),
})
return c.Status(500).SendString(err.Error())
}
fileContent, err := minioClient.GetObject(ctx, bucketName, objectName, minio.GetObjectOptions{})
opts := minio.GetObjectOptions{}
// support video streaming
if rangeHeader := c.Get("Range"); rangeHeader != "" {
opts.Set("Range", rangeHeader)
c.Status(fiber.StatusPartialContent)
c.Set("Accept-Ranges", "bytes")
}
object, err := minioClient.GetObject(ctx, bucketName, objectName, opts)
if err != nil {
return err
return c.Status(404).SendString("file not found")
}
defer fileContent.Close()
defer object.Close()
contentType := mime.TypeByExtension("." + getFileExtension(objectName))
stat, err := object.Stat()
if err != nil {
return c.Status(404).SendString("file not found")
}
contentType := stat.ContentType
if contentType == "" {
contentType = "application/octet-stream"
contentType = mime.TypeByExtension(filepath.Ext(objectName))
}
c.Set("Content-Type", contentType)
c.Set("Content-Disposition", "inline")
if _, err := io.Copy(c.Response().BodyWriter(), fileContent); err != nil {
return err
}
return nil
return c.SendStream(object)
}
func (s *KnowledgeBaseService) Show(id uint) (data *response.KnowledgeBaseResponse, err error) {
result, err := s.Repo.FindOne(id)
if err != nil {
@ -218,35 +223,18 @@ func (s *KnowledgeBaseService) Create(c *fiber.Ctx) (data *response.KnowledgeBas
ctx := context.Background()
bucketName := s.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName
journalFilename, err := s.uploadFileToMinio(ctx, minioClient, bucketName, *req.AgentId, "journal", fileJournal)
if err != nil {
return nil, err
}
audioFilename, err := s.uploadFileToMinio(ctx, minioClient, bucketName, *req.AgentId, "audio", fileAudio)
if err != nil {
return nil, err
}
videoFilename, err := s.uploadFileToMinio(ctx, minioClient, bucketName, *req.AgentId, "video", fileVideo)
if err != nil {
return nil, err
}
journalPath, _ := s.uploadFileToMinio(ctx, minioClient, bucketName, *req.AgentId, fileJournal)
audioPath, _ := s.uploadFileToMinio(ctx, minioClient, bucketName, *req.AgentId, fileAudio)
videoPath, _ := s.uploadFileToMinio(ctx, minioClient, bucketName, *req.AgentId, fileVideo)
entity := req.ToEntity()
entity := req.ToEntity()
viewerBase := s.Cfg.App.Domain + "/knowledge-base/viewer/"
entity.FileJournalUrl = journalPath
entity.FileAudioUrl = audioPath
entity.FileVideoUrl = videoPath
if journalFilename != nil {
journalUrl := viewerBase + *journalFilename
entity.FileJournalUrl = &journalUrl
}
if audioFilename != nil {
audioUrl := viewerBase + *audioFilename
entity.FileAudioUrl = &audioUrl
}
if videoFilename != nil {
videoUrl := viewerBase + *videoFilename
entity.FileVideoUrl = &videoUrl
}
if req.Status < 0 {
entity.Status = 0