87 lines
2.2 KiB
Go
87 lines
2.2 KiB
Go
|
|
package service
|
||
|
|
|
||
|
|
import (
|
||
|
|
"errors"
|
||
|
|
|
||
|
|
"dating-app/internal/models"
|
||
|
|
"dating-app/internal/repository"
|
||
|
|
)
|
||
|
|
|
||
|
|
const MaxPhotosPerUser = 6
|
||
|
|
|
||
|
|
var (
|
||
|
|
ErrTooManyPhotos = errors.New("حداکثر تعداد عکس مجاز رو داری")
|
||
|
|
ErrPhotoNotOwned = errors.New("این عکس متعلق به تو نیست")
|
||
|
|
ErrInvalidImage = errors.New("فرمت فایل باید jpg، png یا webp باشه")
|
||
|
|
ErrImageTooLarge = errors.New("حجم عکس نباید بیشتر از ۵ مگابایت باشه")
|
||
|
|
)
|
||
|
|
|
||
|
|
const MaxPhotoSizeBytes = 5 * 1024 * 1024
|
||
|
|
|
||
|
|
type ProfileService struct {
|
||
|
|
photoRepo *repository.PhotoRepository
|
||
|
|
userRepo *repository.UserRepository
|
||
|
|
storage PhotoStorage
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewProfileService(photoRepo *repository.PhotoRepository, userRepo *repository.UserRepository, storage PhotoStorage) *ProfileService {
|
||
|
|
return &ProfileService{photoRepo: photoRepo, userRepo: userRepo, storage: storage}
|
||
|
|
}
|
||
|
|
|
||
|
|
var allowedImageExts = map[string]bool{
|
||
|
|
".jpg": true, ".jpeg": true, ".png": true, ".webp": true,
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *ProfileService) UploadPhoto(userID uint, ext string, data []byte) (*models.Photo, error) {
|
||
|
|
if !allowedImageExts[ext] {
|
||
|
|
return nil, ErrInvalidImage
|
||
|
|
}
|
||
|
|
if len(data) > MaxPhotoSizeBytes {
|
||
|
|
return nil, ErrImageTooLarge
|
||
|
|
}
|
||
|
|
|
||
|
|
count, err := s.photoRepo.CountByUser(userID)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
if count >= MaxPhotosPerUser {
|
||
|
|
return nil, ErrTooManyPhotos
|
||
|
|
}
|
||
|
|
|
||
|
|
url, err := s.storage.Save(userID, ext, data)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
photo := &models.Photo{UserID: userID, URL: url, SortOrder: int(count)}
|
||
|
|
if err := s.photoRepo.Create(photo); err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return photo, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *ProfileService) DeletePhoto(userID, photoID uint) error {
|
||
|
|
photo, err := s.photoRepo.FindByID(photoID)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
if photo.UserID != userID {
|
||
|
|
return ErrPhotoNotOwned
|
||
|
|
}
|
||
|
|
if err := s.photoRepo.Delete(photoID); err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
return s.storage.Delete(photo.URL)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *ProfileService) ListPhotos(userID uint) ([]models.Photo, error) {
|
||
|
|
return s.photoRepo.ListByUser(userID)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *ProfileService) UpdateLocation(user *models.User, lat, lng float64) error {
|
||
|
|
return s.userRepo.UpdateFields(user, map[string]interface{}{
|
||
|
|
"latitude": lat,
|
||
|
|
"longitude": lng,
|
||
|
|
})
|
||
|
|
}
|