2026-09-15 23:23:47 +03:30
|
|
|
package repository
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
|
|
|
|
|
"dating-app/internal/models"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type UserRepository struct {
|
|
|
|
|
db *gorm.DB
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewUserRepository(db *gorm.DB) *UserRepository {
|
|
|
|
|
return &UserRepository{db: db}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *UserRepository) FindByPhone(phone string) (*models.User, error) {
|
|
|
|
|
var user models.User
|
|
|
|
|
err := r.db.Where("phone = ?", phone).First(&user).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return &user, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *UserRepository) FindByID(id uint) (*models.User, error) {
|
|
|
|
|
var user models.User
|
|
|
|
|
err := r.db.First(&user, id).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return &user, nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-19 22:17:12 +03:30
|
|
|
// FindByIDs چند کاربر رو با هم در یک کوئری برمیگردونه (بهجای یک FindByID
|
|
|
|
|
// جدا بهازای هر id)؛ برای لیستهایی مثل مچها که باید اطلاعات طرف مقابل
|
|
|
|
|
// چندین مچ رو یکجا نشون بدن.
|
|
|
|
|
func (r *UserRepository) FindByIDs(ids []uint) ([]models.User, error) {
|
|
|
|
|
var users []models.User
|
|
|
|
|
if len(ids) == 0 {
|
|
|
|
|
return users, nil
|
|
|
|
|
}
|
|
|
|
|
err := r.db.Where("id IN ?", ids).Find(&users).Error
|
|
|
|
|
return users, err
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-15 23:23:47 +03:30
|
|
|
// GetOrCreateByPhone کاربر را با شمارهی دادهشده پیدا میکند یا در صورت نبود میسازد.
|
|
|
|
|
func (r *UserRepository) GetOrCreateByPhone(phone string) (*models.User, bool, error) {
|
|
|
|
|
var user models.User
|
|
|
|
|
err := r.db.Where("phone = ?", phone).First(&user).Error
|
|
|
|
|
if err == nil {
|
|
|
|
|
return &user, false, nil
|
|
|
|
|
}
|
|
|
|
|
if err != gorm.ErrRecordNotFound {
|
|
|
|
|
return nil, false, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
user = models.User{
|
|
|
|
|
Phone: phone,
|
|
|
|
|
State: models.UserStateInactive,
|
|
|
|
|
IsActive: true,
|
|
|
|
|
CurrentStep: models.StepBasicInfo,
|
|
|
|
|
}
|
|
|
|
|
if err := r.db.Create(&user).Error; err != nil {
|
|
|
|
|
return nil, false, err
|
|
|
|
|
}
|
|
|
|
|
return &user, true, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ListPendingApproval کاربرانی که آنبوردینگ رو تکمیل کردن و منتظر بررسی ادمیناند
|
|
|
|
|
// رو به ترتیب قدیمیترین اول برمیگردونه.
|
|
|
|
|
func (r *UserRepository) ListPendingApproval() ([]models.User, error) {
|
|
|
|
|
var users []models.User
|
|
|
|
|
err := r.db.
|
|
|
|
|
Where("is_onboarded = ? AND approval_status = ?", true, models.ApprovalPending).
|
|
|
|
|
Order("updated_at asc").
|
|
|
|
|
Find(&users).Error
|
|
|
|
|
return users, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ListDiscoverable کاندیداهای بخش دوستیابی رو برمیگردونه: تاییدشده، فعال،
|
|
|
|
|
// جنسیت مخالف کاربر (بهعنوان سادهترین فرض پیشفرض؛ فیلد ترجیح جنسیتی/گرایش
|
|
|
|
|
// هنوز توی سیستم وجود نداره) و کسایی که قبلاً روشون سواپ نزده.
|
|
|
|
|
// چون فاصله باید توی Go محاسبه بشه (haversine)، یک batch بزرگتر از حد
|
|
|
|
|
// نهایی برمیگردونه تا بعد از فیلتر فاصله همچنان گزینهی کافی بمونه.
|
|
|
|
|
func (r *UserRepository) ListDiscoverable(currentUserID uint, oppositeGender models.Gender, minAge, maxAge int, batchSize int) ([]models.User, error) {
|
|
|
|
|
var users []models.User
|
|
|
|
|
now := time.Now()
|
|
|
|
|
minBirth := now.AddDate(-maxAge-1, 0, 1)
|
|
|
|
|
maxBirth := now.AddDate(-minAge, 0, 0)
|
|
|
|
|
|
|
|
|
|
err := r.db.
|
|
|
|
|
Where("id != ?", currentUserID).
|
|
|
|
|
Where("is_onboarded = ? AND approval_status = ? AND is_active = ?", true, models.ApprovalApproved, true).
|
|
|
|
|
Where("gender = ?", oppositeGender).
|
|
|
|
|
Where("birth_date BETWEEN ? AND ?", minBirth, maxBirth).
|
|
|
|
|
Where("NOT EXISTS (SELECT 1 FROM swipes s WHERE s.swiper_id = ? AND s.swiped_id = users.id)", currentUserID).
|
|
|
|
|
Order("id asc").
|
|
|
|
|
Limit(batchSize).
|
|
|
|
|
Find(&users).Error
|
|
|
|
|
return users, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *UserRepository) Save(user *models.User) error {
|
|
|
|
|
return r.db.Save(user).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *UserRepository) UpdateFields(user *models.User, fields map[string]interface{}) error {
|
|
|
|
|
return r.db.Model(user).Updates(fields).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *UserRepository) DB() *gorm.DB {
|
|
|
|
|
return r.db
|
|
|
|
|
}
|