93 lines
2.5 KiB
Go
93 lines
2.5 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"eslogad-be/internal/contract"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type FileStorage interface {
|
|
Upload(ctx context.Context, bucket, key string, content []byte, contentType string) (string, error)
|
|
EnsureBucket(ctx context.Context, bucket string) error
|
|
}
|
|
|
|
type FileServiceImpl struct {
|
|
storage FileStorage
|
|
userProcessor UserProcessor
|
|
profileBucket string
|
|
docBucket string
|
|
}
|
|
|
|
func NewFileService(storage FileStorage, userProcessor UserProcessor, profileBucket, docBucket string) *FileServiceImpl {
|
|
return &FileServiceImpl{storage: storage, userProcessor: userProcessor, profileBucket: profileBucket, docBucket: docBucket}
|
|
}
|
|
|
|
func (s *FileServiceImpl) UploadProfileAvatar(ctx context.Context, userID uuid.UUID, filename string, content []byte, contentType string) (string, error) {
|
|
if err := s.storage.EnsureBucket(ctx, s.profileBucket); err != nil {
|
|
return "", err
|
|
}
|
|
ext := strings.ToLower(strings.TrimPrefix(filepath.Ext(filename), "."))
|
|
if ext := mimeExtFromContentType(contentType); ext != "" {
|
|
ext = ext
|
|
}
|
|
key := buildObjectKey("profile", userID, ext)
|
|
url, err := s.storage.Upload(ctx, s.profileBucket, key, content, contentType)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
_, _ = s.userProcessor.UpdateUserProfile(ctx, userID, &contract.UpdateUserProfileRequest{AvatarURL: &url})
|
|
return url, nil
|
|
}
|
|
|
|
func (s *FileServiceImpl) UploadDocument(ctx context.Context, userID uuid.UUID, filename string, content []byte, contentType string) (string, string, error) {
|
|
if err := s.storage.EnsureBucket(ctx, s.docBucket); err != nil {
|
|
return "", "", err
|
|
}
|
|
ext := strings.ToLower(strings.TrimPrefix(filepath.Ext(filename), "."))
|
|
if ext := mimeExtFromContentType(contentType); ext != "" {
|
|
ext = ext
|
|
}
|
|
key := buildObjectKey("documents", userID, ext)
|
|
url, err := s.storage.Upload(ctx, s.docBucket, key, content, contentType)
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
return url, key, nil
|
|
}
|
|
|
|
func buildObjectKey(prefix string, userID uuid.UUID, ext string) string {
|
|
now := time.Now().UTC()
|
|
parts := []string{
|
|
prefix,
|
|
userID.String(),
|
|
now.Format("2006/01/02"),
|
|
uuid.New().String(),
|
|
}
|
|
key := strings.Join(parts, "/")
|
|
if ext != "" {
|
|
key += "." + ext
|
|
}
|
|
return key
|
|
}
|
|
|
|
func mimeExtFromContentType(ct string) string {
|
|
switch strings.ToLower(ct) {
|
|
case "image/jpeg", "image/jpg":
|
|
return "jpg"
|
|
case "image/png":
|
|
return "png"
|
|
case "image/webp":
|
|
return "webp"
|
|
case "application/pdf":
|
|
return "pdf"
|
|
default:
|
|
return ""
|
|
}
|
|
}
|