diff --git a/main_dc/yalarba/api_yal/internal/repository/account_repository_impl.go b/main_dc/yalarba/api_yal/internal/repository/account_repository_impl.go new file mode 100644 index 0000000..d148d02 --- /dev/null +++ b/main_dc/yalarba/api_yal/internal/repository/account_repository_impl.go @@ -0,0 +1,88 @@ +package repository + +import ( + "api_yal/internal/models" + "gorm.io/gorm" +) + +// accountRepositoryImpl реализация интерфейса AccountRepository +type accountRepositoryImpl struct { + db *gorm.DB +} + +// NewAccountRepository создает новый экземпляр репозитория аккаунтов +func NewAccountRepository(db *gorm.DB) AccountRepository { + return &accountRepositoryImpl{db: db} +} + +// Create создает новый аккаунт +func (r *accountRepositoryImpl) Create(account *models.Account) error { + return r.db.Create(account).Error +} + +// GetByID возвращает аккаунт по ID +func (r *accountRepositoryImpl) GetByID(id uint) (*models.Account, error) { + var account models.Account + err := r.db.Preload("Objects").First(&account, id).Error + if err != nil { + return nil, err + } + return &account, nil +} + +// GetByEmail возвращает аккаунт по email +func (r *accountRepositoryImpl) GetByEmail(email string) (*models.Account, error) { + var account models.Account + err := r.db.Preload("Objects").Where("email = ?", email).First(&account).Error + if err != nil { + return nil, err + } + return &account, nil +} + +// Update обновляет существующий аккаунт +func (r *accountRepositoryImpl) Update(account *models.Account) error { + return r.db.Save(account).Error +} + +// Delete помечает аккаунт как удаленный +func (r *accountRepositoryImpl) Delete(id uint) error { + return r.db.Delete(&models.Account{}, id).Error +} + +// List возвращает список аккаунтов с пагинацией +func (r *accountRepositoryImpl) List(offset, limit int) ([]models.Account, error) { + var accounts []models.Account + err := r.db.Preload("Objects").Offset(offset).Limit(limit).Find(&accounts).Error + if err != nil { + return nil, err + } + return accounts, nil +} + +// Count возвращает общее количество аккаунтов +func (r *accountRepositoryImpl) Count() (int64, error) { + var count int64 + err := r.db.Model(&models.Account{}).Count(&count).Error + return count, err +} + +// Search находит аккаунты по email или полному имени +func (r *accountRepositoryImpl) Search(query string, offset, limit int) ([]models.Account, error) { + var accounts []models.Account + err := r.db.Preload("Objects").Where("email LIKE ? OR full_name LIKE ?", "%"+query+"%", "%"+query+"%").Offset(offset).Limit(limit).Find(&accounts).Error + if err != nil { + return nil, err + } + return accounts, nil +} + +// GetObjects возвращает все объекты, принадлежащие аккаунту +func (r *accountRepositoryImpl) GetObjects(accountID uint) ([]models.Object, error) { + var objects []models.Object + err := r.db.Where("owner_id = ?", accountID).Find(&objects).Error + if err != nil { + return nil, err + } + return objects, nil +} \ No newline at end of file diff --git a/main_dc/yalarba/api_yal/internal/repository/appeal_repository_impl.go b/main_dc/yalarba/api_yal/internal/repository/appeal_repository_impl.go new file mode 100644 index 0000000..4c33692 --- /dev/null +++ b/main_dc/yalarba/api_yal/internal/repository/appeal_repository_impl.go @@ -0,0 +1,212 @@ +package repository + +import ( + "api_yal/internal/models" + "gorm.io/gorm" +) + +// appealRepositoryImpl реализация интерфейса AppealRepository +type appealRepositoryImpl struct { + db *gorm.DB +} + +// NewAppealRepository создает новый экземпляр репозитория обращений +func NewAppealRepository(db *gorm.DB) AppealRepository { + return &appealRepositoryImpl{db: db} +} + +// Create созда��т новое обращение +func (r *appealRepositoryImpl) Create(appeal *models.Appeal) error { + return r.db.Create(appeal).Error +} + +// GetByID возвращает обращение по ID +func (r *appealRepositoryImpl) GetByID(id uint) (*models.Appeal, error) { + var appeal models.Appeal + err := r.db.Preload("Author").Preload("Object").Preload("Feedback").Preload("Comment").Preload("AssignedTo").First(&appeal, id).Error + if err != nil { + return nil, err + } + return &appeal, nil +} + +// Update обновляет существующее обращение +func (r *appealRepositoryImpl) Update(appeal *models.Appeal) error { + return r.db.Save(appeal).Error +} + +// Delete помечает обращение как удаленное +func (r *appealRepositoryImpl) Delete(id uint) error { + return r.db.Delete(&models.Appeal{}, id).Error +} + +// List возвращает список обращений с пагинацией +func (r *appealRepositoryImpl) List(offset, limit int) ([]models.Appeal, error) { + var appeals []models.Appeal + err := r.db.Preload("Author").Preload("Object").Offset(offset).Limit(limit).Find(&appeals).Error + if err != nil { + return nil, err + } + return appeals, nil +} + +// Count возвращает общее количество обращений +func (r *appealRepositoryImpl) Count() (int64, error) { + var count int64 + err := r.db.Model(&models.Appeal{}).Count(&count).Error + return count, err +} + +// ListByStatus возвращает обращения по статусу +func (r *appealRepositoryImpl) ListByStatus(status models.AppealStatus, offset, limit int) ([]models.Appeal, error) { + var appeals []models.Appeal + err := r.db.Preload("Author").Preload("Object").Where("status = ?", status).Offset(offset).Limit(limit).Find(&appeals).Error + if err != nil { + return nil, err + } + return appeals, nil +} + +// ListByType возвращает обращения по типу +func (r *appealRepositoryImpl) ListByType(typeAppeal models.AppealType, offset, limit int) ([]models.Appeal, error) { + var appeals []models.Appeal + err := r.db.Preload("Author").Preload("Object").Where("type = ?", typeAppeal).Offset(offset).Limit(limit).Find(&appeals).Error + if err != nil { + return nil, err + } + return appeals, nil +} + +// ListByPriority возвращает обращения по приоритету +func (r *appealRepositoryImpl) ListByPriority(priority models.AppealPriority, offset, limit int) ([]models.Appeal, error) { + var appeals []models.Appeal + err := r.db.Preload("Author").Preload("Object").Where("priority = ?", priority).Offset(offset).Limit(limit).Find(&appeals).Error + if err != nil { + return nil, err + } + return appeals, nil +} + +// Search находит обращения по заголовку или сообщению +func (r *appealRepositoryImpl) Search(query string, offset, limit int) ([]models.Appeal, error) { + var appeals []models.Appeal + err := r.db.Preload("Author").Preload("Object").Where("title LIKE ? OR message LIKE ?", "%"+query+"%", "%"+query+"%").Offset(offset).Limit(limit).Find(&appeals).Error + if err != nil { + return nil, err + } + return appeals, nil +} + +// GetAuthor возвращает автора обращения +func (r *appealRepositoryImpl) GetAuthor(appealID uint) (*models.Account, error) { + var appeal models.Appeal + err := r.db.Select("author_id").First(&appeal, appealID).Error + if err != nil { + return nil, err + } + if appeal.AuthorID == nil { + return nil, gorm.ErrRecordNotFound + } + return r.GetAccountByID(*appeal.AuthorID) +} + +// GetObject возвращает объект, связанный с обращением +func (r *appealRepositoryImpl) GetObject(appealID uint) (*models.Object, error) { + var appeal models.Appeal + err := r.db.Select("object_id").First(&appeal, appealID).Error + if err != nil { + return nil, err + } + if appeal.ObjectID == nil { + return nil, gorm.ErrRecordNotFound + } + return r.GetObjectByID(*appeal.ObjectID) +} + +// GetFeedback возвращает отзыв, связанный с обращением +func (r *appealRepositoryImpl) GetFeedback(appealID uint) (*models.Feedback, error) { + var appeal models.Appeal + err := r.db.Select("feedback_id").First(&appeal, appealID).Error + if err != nil { + return nil, err + } + if appeal.FeedbackID == nil { + return nil, gorm.ErrRecordNotFound + } + return r.GetFeedbackByID(*appeal.FeedbackID) +} + +// GetComment возвращает комментарий, связанный с обращением +func (r *appealRepositoryImpl) GetComment(appealID uint) (*models.Comment, error) { + var appeal models.Appeal + err := r.db.Select("comment_id").First(&appeal, appealID).Error + if err != nil { + return nil, err + } + if appeal.CommentID == nil { + return nil, gorm.ErrRecordNotFound + } + return r.GetCommentByID(*appeal.CommentID) +} + +// AssignTo назначает ответственного за обработку обращения +func (r *appealRepositoryImpl) AssignTo(appealID uint, assignedToID *uint) error { + return r.db.Model(&models.Appeal{}).Where("id = ?", appealID).Update("assigned_to_id", assignedToID).Error +} + +// UpdateStatus обновляет статус обращения +func (r *appealRepositoryImpl) UpdateStatus(appealID uint, status models.AppealStatus) error { + return r.db.Model(&models.Appeal{}).Where("id = ?", appealID).Update("status", status).Error +} + +// CreateHistory создает запись в истории изменений статуса +func (r *appealRepositoryImpl) CreateHistory(history *models.AppealHistory) error { + return r.db.Create(history).Error +} + +// ListHistory возвращает историю изменений статуса обращения +func (r *appealRepositoryImpl) ListHistory(appealID uint, offset, limit int) ([]models.AppealHistory, error) { + var histories []models.AppealHistory + err := r.db.Preload("User").Where("appeal_id = ?", appealID).Offset(offset).Limit(limit).Find(&histories).Error + if err != nil { + return nil, err + } + return histories, nil +} + +// Вспомогательные методы для получения связанных сущностей +func (r *appealRepositoryImpl) GetAccountByID(id uint) (*models.Account, error) { + var account models.Account + err := r.db.First(&account, id).Error + if err != nil { + return nil, err + } + return &account, nil +} + +func (r *appealRepositoryImpl) GetObjectByID(id uint) (*models.Object, error) { + var object models.Object + err := r.db.First(&object, id).Error + if err != nil { + return nil, err + } + return &object, nil +} + +func (r *appealRepositoryImpl) GetFeedbackByID(id uint) (*models.Feedback, error) { + var feedback models.Feedback + err := r.db.First(&feedback, id).Error + if err != nil { + return nil, err + } + return &feedback, nil +} + +func (r *appealRepositoryImpl) GetCommentByID(id uint) (*models.Comment, error) { + var comment models.Comment + err := r.db.First(&comment, id).Error + if err != nil { + return nil, err + } + return &comment, nil +} \ No newline at end of file diff --git a/main_dc/yalarba/api_yal/internal/repository/comment_repository_impl.go b/main_dc/yalarba/api_yal/internal/repository/comment_repository_impl.go new file mode 100644 index 0000000..f1c708b --- /dev/null +++ b/main_dc/yalarba/api_yal/internal/repository/comment_repository_impl.go @@ -0,0 +1,157 @@ +package repository + +import ( + "api_yal/internal/models" + "gorm.io/gorm" +) + +// commentRepositoryImpl реализация интерфейса CommentRepository +type commentRepositoryImpl struct { + db *gorm.DB +} + +// NewCommentRepository создает новый экземпляр репозитория комментариев +func NewCommentRepository(db *gorm.DB) CommentRepository { + return &commentRepositoryImpl{db: db} +} + +// Create создает новый комментарий +func (r *commentRepositoryImpl) Create(comment *models.Comment) error { + return r.db.Create(comment).Error +} + +// GetByID возвращает комментарий по ID +func (r *commentRepositoryImpl) GetByID(id uint) (*models.Comment, error) { + var comment models.Comment + err := r.db.Preload("Author").Preload("Feedback").Preload("Parent").Preload("Replies").First(&comment, id).Error + if err != nil { + return nil, err + } + return &comment, nil +} + +// Update обновляет существующий комментарий +func (r *commentRepositoryImpl) Update(comment *models.Comment) error { + return r.db.Save(comment).Error +} + +// Delete помечает комментарий как удаленный +func (r *commentRepositoryImpl) Delete(id uint) error { + return r.db.Delete(&models.Comment{}, id).Error +} + +// List возвращает список комментариев с пагинацией +func (r *commentRepositoryImpl) List(offset, limit int) ([]models.Comment, error) { + var comments []models.Comment + err := r.db.Preload("Author").Preload("Feedback").Offset(offset).Limit(limit).Find(&comments).Error + if err != nil { + return nil, err + } + return comments, nil +} + +// Count возвращает общее количество комментариев +func (r *commentRepositoryImpl) Count() (int64, error) { + var count int64 + err := r.db.Model(&models.Comment{}).Count(&count).Error + return count, err +} + +// ListByFeedback возвращает комментарии по отзыву +func (r *commentRepositoryImpl) ListByFeedback(feedbackID uint, offset, limit int) ([]models.Comment, error) { + var comments []models.Comment + err := r.db.Preload("Author").Where("feedback_id = ?", feedbackID).Order("created_at asc").Offset(offset).Limit(limit).Find(&comments).Error + if err != nil { + return nil, err + } + return comments, nil +} + +// ListByAuthor возвращает комментарии по автору +func (r *commentRepositoryImpl) ListByAuthor(authorID uint, offset, limit int) ([]models.Comment, error) { + var comments []models.Comment + err := r.db.Preload("Feedback").Where("author_id = ?", authorID).Order("created_at desc").Offset(offset).Limit(limit).Find(&comments).Error + if err != nil { + return nil, err + } + return comments, nil +} + +// ListReplies возвращает ответы на комментарий +func (r *commentRepositoryImpl) ListReplies(parentID uint, offset, limit int) ([]models.Comment, error) { + var replies []models.Comment + err := r.db.Preload("Author").Where("parent_id = ?", parentID).Order("created_at asc").Offset(offset).Limit(limit).Find(&replies).Error + if err != nil { + return nil, err + } + return replies, nil +} + +// GetAuthor возвращает автора комментария +func (r *commentRepositoryImpl) GetAuthor(commentID uint) (*models.Account, error) { + var comment models.Comment + err := r.db.Select("author_id").First(&comment, commentID).Error + if err != nil { + return nil, err + } + return r.getAccountByID(comment.AuthorID) +} + +// GetFeedback возвращает отзыв, к которому относится комментарий +func (r *commentRepositoryImpl) GetFeedback(commentID uint) (*models.Feedback, error) { + var comment models.Comment + err := r.db.Select("feedback_id").First(&comment, commentID).Error + if err != nil { + return nil, err + } + return r.getFeedbackByID(comment.FeedbackID) +} + +// GetParent возвращает родительский комментарий +func (r *commentRepositoryImpl) GetParent(commentID uint) (*models.Comment, error) { + var comment models.Comment + err := r.db.Select("parent_id").First(&comment, commentID).Error + if err != nil { + return nil, err + } + if comment.ParentID == nil { + return nil, nil // No parent + } + return r.GetByID(*comment.ParentID) +} + +// GetRepliesCount возвращает количество ответов на комментарий +func (r *commentRepositoryImpl) GetRepliesCount(commentID uint) (int64, error) { + var count int64 + err := r.db.Model(&models.Comment{}).Where("parent_id = ?", commentID).Count(&count).Error + return count, err +} + +// MarkAsEdited помечает комментарий как отредактированный +func (r *commentRepositoryImpl) MarkAsEdited(id uint) error { + return r.db.Model(&models.Comment{}).Where("id = ?", id).Update("is_edited", true).Error +} + +// ToggleVerification переключает статус верификации комментария +func (r *commentRepositoryImpl) ToggleVerification(id uint, verified bool) error { + return r.db.Model(&models.Comment{}).Where("id = ?", id).Update("is_verified", verified).Error +} + +// Вспомогательные методы для получения связанных сущностей +func (r *commentRepositoryImpl) getAccountByID(id uint) (*models.Account, error) { + var account models.Account + err := r.db.First(&account, id).Error + if err != nil { + return nil, err + } + return &account, nil +} + +func (r *commentRepositoryImpl) getFeedbackByID(id uint) (*models.Feedback, error) { + var feedback models.Feedback + err := r.db.First(&feedback, id).Error + if err != nil { + return nil, err + } + return &feedback, nil +} \ No newline at end of file diff --git a/main_dc/yalarba/api_yal/internal/repository/feedback_repository_impl.go b/main_dc/yalarba/api_yal/internal/repository/feedback_repository_impl.go new file mode 100644 index 0000000..df203aa --- /dev/null +++ b/main_dc/yalarba/api_yal/internal/repository/feedback_repository_impl.go @@ -0,0 +1,159 @@ +package repository + +import ( + "api_yal/internal/models" + "gorm.io/gorm" +) + +// feedbackRepositoryImpl реализация интерфейса FeedbackRepository +type feedbackRepositoryImpl struct { + db *gorm.DB +} + +// NewFeedbackRepository создает новый экземпляр репозитория отзывов +func NewFeedbackRepository(db *gorm.DB) FeedbackRepository { + return &feedbackRepositoryImpl{db: db} +} + +// Create создает новый отзыв +func (r *feedbackRepositoryImpl) Create(feedback *models.Feedback) error { + return r.db.Create(feedback).Error +} + +// GetByID возвращает отзыв по ID +func (r *feedbackRepositoryImpl) GetByID(id uint) (*models.Feedback, error) { + var feedback models.Feedback + err := r.db.Preload("Owner").Preload("Object").Preload("Comments").First(&feedback, id).Error + if err != nil { + return nil, err + } + return &feedback, nil +} + +// Update обновляет существующий отзыв +func (r *feedbackRepositoryImpl) Update(feedback *models.Feedback) error { + return r.db.Save(feedback).Error +} + +// Delete помечает отзыв как удаленный +func (r *feedbackRepositoryImpl) Delete(id uint) error { + return r.db.Delete(&models.Feedback{}, id).Error +} + +// List возвращает список отзывов с пагинацией +func (r *feedbackRepositoryImpl) List(offset, limit int) ([]models.Feedback, error) { + var feedbacks []models.Feedback + err := r.db.Preload("Owner").Preload("Object").Offset(offset).Limit(limit).Find(&feedbacks).Error + if err != nil { + return nil, err + } + return feedbacks, nil +} + +// Count возвращает общее количество отзывов +func (r *feedbackRepositoryImpl) Count() (int64, error) { + var count int64 + err := r.db.Model(&models.Feedback{}).Count(&count).Error + return count, err +} + +// ListByOwner возвращает отзывы по владельцу +func (r *feedbackRepositoryImpl) ListByOwner(ownerID uint, offset, limit int) ([]models.Feedback, error) { + var feedbacks []models.Feedback + err := r.db.Preload("Object").Where("owner_id = ?", ownerID).Offset(offset).Limit(limit).Find(&feedbacks).Error + if err != nil { + return nil, err + } + return feedbacks, nil +} + +// ListByObject возвращает отзывы по объекту +func (r *feedbackRepositoryImpl) ListByObject(objectID uint, offset, limit int) ([]models.Feedback, error) { + var feedbacks []models.Feedback + err := r.db.Preload("Owner").Where("object_id = ?", objectID).Offset(offset).Limit(limit).Find(&feedbacks).Error + if err != nil { + return nil, err + } + return feedbacks, nil +} + +// ListByPlatform возвращает отзывы по платформе +func (r *feedbackRepositoryImpl) ListByPlatform(platform models.PlatformType, offset, limit int) ([]models.Feedback, error) { + var feedbacks []models.Feedback + err := r.db.Preload("Owner").Preload("Object").Where("platform = ?", platform).Offset(offset).Limit(limit).Find(&feedbacks).Error + if err != nil { + return nil, err + } + return feedbacks, nil +} + +// GetOwner возвращает владельца отзыва +func (r *feedbackRepositoryImpl) GetOwner(feedbackID uint) (*models.Account, error) { + var feedback models.Feedback + err := r.db.Select("owner_id").First(&feedback, feedbackID).Error + if err != nil { + return nil, err + } + return r.getAccountByID(feedback.OwnerID) +} + +// GetObject возвращает объект, к которому относится отзыв +func (r *feedbackRepositoryImpl) GetObject(feedbackID uint) (*models.Object, error) { + var feedback models.Feedback + err := r.db.Select("object_id").First(&feedback, feedbackID).Error + if err != nil { + return nil, err + } + return r.getObjectByID(feedback.ObjectID) +} + +// GetComments возвращает комментарии к отзыву +func (r *feedbackRepositoryImpl) GetComments(feedbackID uint, offset, limit int) ([]models.Comment, error) { + var comments []models.Comment + err := r.db.Where("feedback_id = ?", feedbackID).Order("created_at asc").Offset(offset).Limit(limit).Find(&comments).Error + if err != nil { + return nil, err + } + return comments, nil +} + +// GetCommentCount возвращает количество комментариев к отзыву +func (r *feedbackRepositoryImpl) GetCommentCount(feedbackID uint) (int, error) { + var count int64 + err := r.db.Model(&models.Comment{}).Where("feedback_id = ?", feedbackID).Count(&count).Error + return int(count), err +} + +// UpdateCommentCount обновляет количество комментариев у отзыва +func (r *feedbackRepositoryImpl) UpdateCommentCount(feedbackID uint, count int) error { + return r.db.Model(&models.Feedback{}).Where("id = ?", feedbackID).Update("comment_count", count).Error +} + +// Search находит отзывы по тексту +func (r *feedbackRepositoryImpl) Search(query string, offset, limit int) ([]models.Feedback, error) { + var feedbacks []models.Feedback + err := r.db.Preload("Owner").Preload("Object").Where("text LIKE ?", "%"+query+"%").Offset(offset).Limit(limit).Find(&feedbacks).Error + if err != nil { + return nil, err + } + return feedbacks, nil +} + +// Вспомогательные методы для получения связанных сущностей +func (r *feedbackRepositoryImpl) getAccountByID(id uint) (*models.Account, error) { + var account models.Account + err := r.db.First(&account, id).Error + if err != nil { + return nil, err + } + return &account, nil +} + +func (r *feedbackRepositoryImpl) getObjectByID(id uint) (*models.Object, error) { + var object models.Object + err := r.db.First(&object, id).Error + if err != nil { + return nil, err + } + return &object, nil +} \ No newline at end of file diff --git a/main_dc/yalarba/api_yal/internal/repository/object_repository_impl.go b/main_dc/yalarba/api_yal/internal/repository/object_repository_impl.go new file mode 100644 index 0000000..492b917 --- /dev/null +++ b/main_dc/yalarba/api_yal/internal/repository/object_repository_impl.go @@ -0,0 +1,192 @@ +package repository + +import ( + "api_yal/internal/models" + "gorm.io/gorm" +) + +// objectRepositoryImpl реализация интерфейса ObjectRepository +type objectRepositoryImpl struct { + db *gorm.DB +} + +// NewObjectRepository создает новый экземпляр репозитория объектов +func NewObjectRepository(db *gorm.DB) ObjectRepository { + return &objectRepositoryImpl{db: db} +} + +// Create создает новый объект +func (r *objectRepositoryImpl) Create(object *models.Object) error { + return r.db.Create(object).Error +} + +// GetByID возвращает объект по ID +func (r *objectRepositoryImpl) GetByID(id uint) (*models.Object, error) { + var object models.Object + err := r.db.Preload("Owner").Preload("TouristRating").Preload("EntrepreneurRating").Preload("Ratings").Preload("Feedbacks").First(&object, id).Error + if err != nil { + return nil, err + } + return &object, nil +} + +// Update обновляет существующий объект +func (r *objectRepositoryImpl) Update(object *models.Object) error { + return r.db.Save(object).Error +} + +// Delete помечает объект как удаленный +func (r *objectRepositoryImpl) Delete(id uint) error { + return r.db.Delete(&models.Object{}, id).Error +} + +// List возвращает список объектов с пагинацией +func (r *objectRepositoryImpl) List(offset, limit int) ([]models.Object, error) { + var objects []models.Object + err := r.db.Preload("Owner").Offset(offset).Limit(limit).Find(&objects).Error + if err != nil { + return nil, err + } + return objects, nil +} + +// Count возвращает общее количество объектов +func (r *objectRepositoryImpl) Count() (int64, error) { + var count int64 + err := r.db.Model(&models.Object{}).Count(&count).Error + return count, err +} + +// ListByOwner возвращает объекты по владельцу +func (r *objectRepositoryImpl) ListByOwner(ownerID uint, offset, limit int) ([]models.Object, error) { + var objects []models.Object + err := r.db.Preload("Owner").Where("owner_id = ?", ownerID).Offset(offset).Limit(limit).Find(&objects).Error + if err != nil { + return nil, err + } + return objects, nil +} + +// ListByType возвращает объекты по типу +func (r *objectRepositoryImpl) ListByType(objectType string, offset, limit int) ([]models.Object, error) { + var objects []models.Object + err := r.db.Preload("Owner").Where("type = ?", objectType).Offset(offset).Limit(limit).Find(&objects).Error + if err != nil { + return nil, err + } + return objects, nil +} + +// ListByStatus возвращает объекты по статусу +func (r *objectRepositoryImpl) ListByStatus(isActive bool, offset, limit int) ([]models.Object, error) { + var objects []models.Object + err := r.db.Preload("Owner").Where("is_active = ?", isActive).Offset(offset).Limit(limit).Find(&objects).Error + if err != nil { + return nil, err + } + return objects, nil +} + +// Search находит объекты по названию, типу или адресу +func (r *objectRepositoryImpl) Search(query string, offset, limit int) ([]models.Object, error) { + var objects []models.Object + err := r.db.Preload("Owner").Where("short_name LIKE ? OR long_name LIKE ? OR type LIKE ? OR address LIKE ?", "%"+query+"%", "%"+query+"%", "%"+query+"%", "%"+query+"%").Offset(offset).Limit(limit).Find(&objects).Error + if err != nil { + return nil, err + } + return objects, nil +} + +// GetOwner возвращает владельца объекта +func (r *objectRepositoryImpl) GetOwner(objectID uint) (*models.Account, error) { + var object models.Object + err := r.db.Select("owner_id").First(&object, objectID).Error + if err != nil { + return nil, err + } + return r.getAccountByID(object.OwnerID) +} + +// GetTouristRating возвращает туристический рейтинг объекта +func (r *objectRepositoryImpl) GetTouristRating(objectID uint) (*models.Rating, error) { + return r.getRatingByObjectAndPlatform(objectID, models.PlatformTourist) +} + +// GetEntrepreneurRating возвращает рейтинг для предпринимателей +func (r *objectRepositoryImpl) GetEntrepreneurRating(objectID uint) (*models.Rating, error) { + return r.getRatingByObjectAndPlatform(objectID, models.PlatformEntrepreneur) +} + +// GetRatings возвращает все рейтинги объекта +func (r *objectRepositoryImpl) GetRatings(objectID uint) ([]models.Rating, error) { + var ratings []models.Rating + err := r.db.Where("object_id = ?", objectID).Find(&ratings).Error + if err != nil { + return nil, err + } + return ratings, nil +} + +// GetFeedbacks возвращает отзывы об объекте +func (r *objectRepositoryImpl) GetFeedbacks(objectID uint, offset, limit int) ([]models.Feedback, error) { + var feedbacks []models.Feedback + err := r.db.Preload("Owner").Where("object_id = ?", objectID).Offset(offset).Limit(limit).Find(&feedbacks).Error + if err != nil { + return nil, err + } + return feedbacks, nil +} + +// GetFeedbackCount возвращает количество отзывов об объекте +func (r *objectRepositoryImpl) GetFeedbackCount(objectID uint) (int, error) { + var count int64 + err := r.db.Model(&models.Feedback{}).Where("object_id = ?", objectID).Count(&count).Error + return int(count), err +} + +// UpdateFeedbackCount обновляет количество отзывов у объекта +func (r *objectRepositoryImpl) UpdateFeedbackCount(objectID uint, count int) error { + return r.db.Model(&models.Object{}).Where("id = ?", objectID).Update("feedback_count", count).Error +} + +// ToggleVerification переключает статус верификации объекта +func (r *objectRepositoryImpl) ToggleVerification(id uint, verified bool) error { + return r.db.Model(&models.Object{}).Where("id = ?", id).Update("is_verified", verified).Error +} + +// GetNearby возвращает объекты в радиусе +func (r *objectRepositoryImpl) GetNearby(latitude, longitude, radius float64, offset, limit int) ([]models.Object, error) { + var objects []models.Object + // Используем формулу Haversine для поиска объектов в радиусе + query := `SELECT *, + (6371 * acos(cos(radians(?)) * cos(radians(latitude)) * cos(radians(longitude) - radians(?)) + sin(radians(?)) * sin(radians(latitude)))) AS distance + FROM objects + HAVING distance < ? + ORDER BY distance + LIMIT ? OFFSET ?` + + err := r.db.Raw(query, latitude, longitude, latitude, radius, limit, offset).Scan(&objects).Error + if err != nil { + return nil, err + } + return objects, nil +} + +// Вспомогательные методы для получения связанных сущностей +func (r *objectRepositoryImpl) getAccountByID(id uint) (*models.Account, error) { + var account models.Account + err := r.db.First(&account, id).Error + if err != nil { + return nil, err + } + return &account, nil +} + +func (r *objectRepositoryImpl) getRatingByObjectAndPlatform(objectID uint, platform models.PlatformType) (*models.Rating, error) { + var rating models.Rating + err := r.db.Where("object_id = ? AND platform = ?", objectID, platform).First(&rating).Error + if err != nil { + return nil, err + } + return &rating, nil +} \ No newline at end of file diff --git a/main_dc/yalarba/api_yal/internal/repository/rating_repository_impl.go b/main_dc/yalarba/api_yal/internal/repository/rating_repository_impl.go new file mode 100644 index 0000000..a2c2f22 --- /dev/null +++ b/main_dc/yalarba/api_yal/internal/repository/rating_repository_impl.go @@ -0,0 +1,175 @@ +package repository + +import ( + "api_yal/internal/models" + "gorm.io/gorm" +) + +// ratingRepositoryImpl реализация интерфейса RatingRepository +type ratingRepositoryImpl struct { + db *gorm.DB +} + +// NewRatingRepository создает новый экземпляр репозитория рейтингов +func NewRatingRepository(db *gorm.DB) RatingRepository { + return &ratingRepositoryImpl{db: db} +} + +// Create создает новый рейтинг +func (r *ratingRepositoryImpl) Create(rating *models.Rating) error { + return r.db.Create(rating).Error +} + +// GetByID возвращает рейтинг по ID +func (r *ratingRepositoryImpl) GetByID(id uint) (*models.Rating, error) { + var rating models.Rating + err := r.db.Preload("Object").Preload("VoteBreakdown").First(&rating, id).Error + if err != nil { + return nil, err + } + return &rating, nil +} + +// GetByObjectAndPlatform возвращает рейтинг объекта для конкретной платформы +func (r *ratingRepositoryImpl) GetByObjectAndPlatform(objectID uint, platform models.PlatformType) (*models.Rating, error) { + var rating models.Rating + err := r.db.Preload("VoteBreakdown").Where("object_id = ? AND platform = ?", objectID, platform).First(&rating).Error + if err != nil { + return nil, err + } + return &rating, nil +} + +// Update обновляет существующий рейтинг +func (r *ratingRepositoryImpl) Update(rating *models.Rating) error { + return r.db.Save(rating).Error +} + +// Delete удаляет рейтинг +func (r *ratingRepositoryImpl) Delete(id uint) error { + return r.db.Delete(&models.Rating{}, id).Error +} + +// List возвращает список рейтингов с пагинацией +func (r *ratingRepositoryImpl) List(offset, limit int) ([]models.Rating, error) { + var ratings []models.Rating + err := r.db.Preload("Object").Offset(offset).Limit(limit).Find(&ratings).Error + if err != nil { + return nil, err + } + return ratings, nil +} + +// Count возвращает общее количество рейтингов +func (r *ratingRepositoryImpl) Count() (int64, error) { + var count int64 + err := r.db.Model(&models.Rating{}).Count(&count).Error + return count, err +} + +// ListByObject возвращает все рейтинги объекта +func (r *ratingRepositoryImpl) ListByObject(objectID uint) ([]models.Rating, error) { + var ratings []models.Rating + err := r.db.Preload("VoteBreakdown").Where("object_id = ?", objectID).Find(&ratings).Error + if err != nil { + return nil, err + } + return ratings, nil +} + +// ListByOwner возвращает рейтинги по владельцу +func (r *ratingRepositoryImpl) ListByOwner(ownerID uint, offset, limit int) ([]models.Rating, error) { + var ratings []models.Rating + err := r.db.Preload("Object").Where("owner_id = ?", ownerID).Offset(offset).Limit(limit).Find(&ratings).Error + if err != nil { + return nil, err + } + return ratings, nil +} + +// ListByPlatform возвращает рейтинги по платформе +func (r *ratingRepositoryImpl) ListByPlatform(platform models.PlatformType, offset, limit int) ([]models.Rating, error) { + var ratings []models.Rating + err := r.db.Preload("Object").Where("platform = ?", platform).Offset(offset).Limit(limit).Find(&ratings).Error + if err != nil { + return nil, err + } + return ratings, nil +} + +// GetObject возвращает объект, к которому относится рейтинг +func (r *ratingRepositoryImpl) GetObject(ratingID uint) (*models.Object, error) { + var rating models.Rating + err := r.db.Select("object_id").First(&rating, ratingID).Error + if err != nil { + return nil, err + } + return r.getObjectByID(rating.ObjectID) +} + +// GetVoteBreakdown возвращает детализацию голосов для рейтинга +func (r *ratingRepositoryImpl) GetVoteBreakdown(ratingID uint) (*models.VoteBreakdown, error) { + var breakdown models.VoteBreakdown + err := r.db.Where("rating_id = ?", ratingID).First(&breakdown).Error + if err != nil { + return nil, err + } + return &breakdown, nil +} + +// UpdateVoteBreakdown обновляет детализацию голосов +func (r *ratingRepositoryImpl) UpdateVoteBreakdown(breakdown *models.VoteBreakdown) error { + return r.db.Save(breakdown).Error +} + +// CreateRatingVote созд��ет новый голос в рейтинге +func (r *ratingRepositoryImpl) CreateRatingVote(vote *models.RatingVote) error { + return r.db.Create(vote).Error +} + +// GetRatingVote возвращает голос пользователя по цели и платформе +func (r *ratingRepositoryImpl) GetRatingVote(targetID uint, voterID uint, platform models.PlatformType) (*models.RatingVote, error) { + var vote models.RatingVote + err := r.db.Where("target_id = ? AND voter_id = ? AND platform = ?", targetID, voterID, platform).First(&vote).Error + if err != nil { + return nil, err + } + return &vote, nil +} + +// UpdateRatingVote обновляет существующий голос +func (r *ratingRepositoryImpl) UpdateRatingVote(vote *models.RatingVote) error { + return r.db.Save(vote).Error +} + +// DeleteRatingVote удаляет голос +func (r *ratingRepositoryImpl) DeleteRatingVote(id uint) error { + return r.db.Delete(&models.RatingVote{}, id).Error +} + +// CountVotesByTarget возвращает количество голосов по цели и платформе +func (r *ratingRepositoryImpl) CountVotesByTarget(targetID uint, platform models.PlatformType) (int64, error) { + var count int64 + err := r.db.Model(&models.RatingVote{}).Where("target_id = ? AND platform = ?", targetID, platform).Count(&count).Error + return count, err +} + +// CalculateAverageScore рассчитывает средний балл на основе VoteBreakdown +func (r *ratingRepositoryImpl) CalculateAverageScore(breakdown *models.VoteBreakdown) float64 { + totalVotes := breakdown.Score1 + breakdown.Score2 + breakdown.Score3 + breakdown.Score4 + breakdown.Score5 + if totalVotes == 0 { + return 0.0 + } + totalScore := float64(breakdown.Score1*1 + breakdown.Score2*2 + breakdown.Score3*3 + breakdown.Score4*4 + breakdown.Score5*5) + return totalScore / float64(totalVotes) +} + +// Вспомогательный метод для получения объекта +func (r *ratingRepositoryImpl) getObjectByID(id uint) (*models.Object, error) { + var object models.Object + err := r.db.First(&object, id).Error + if err != nil { + return nil, err + } + return &object, nil +} \ No newline at end of file