package service import ( "errors" "github.com/freefire/jiang13-bbs/model" "gorm.io/gorm" ) // FollowService 关注服务(仅用户;关注时给对方发通知) type FollowService struct { db *gorm.DB notif *NotificationService } func NewFollowService(db *gorm.DB) *FollowService { return &FollowService{db: db} } // WithNotification 注入通知服务(关注成功时落库一条 follow 通知) func (s *FollowService) WithNotification(n *NotificationService) *FollowService { s.notif = n return s } // Toggle 切换关注状态:已关注则取关,未关注则关注。返回 (following, error) func (s *FollowService) Toggle(followerID, targetID uint) (bool, error) { if followerID == targetID { return false, errors.New("不能关注自己") } var target model.User if err := s.db.First(&target, targetID).Error; err != nil { return false, errors.New("用户不存在") } if target.Banned { return false, errors.New("该用户已被封禁") } var follow model.Follow err := s.db.Where("follower_id = ? AND following_id = ?", followerID, targetID).First(&follow).Error if err == nil { if err := s.db.Delete(&follow).Error; err != nil { return true, err } return false, nil } if !errors.Is(err, gorm.ErrRecordNotFound) { return false, err } if err := s.db.Create(&model.Follow{FollowerID: followerID, FollowingID: targetID}).Error; err != nil { return false, err } if s.notif != nil { s.notif.Create(targetID, followerID, model.NotificationTypeFollow, 0, 0, "") } return true, nil } // IsFollowing 判断 followerID 是否已关注 targetID func (s *FollowService) IsFollowing(followerID, targetID uint) bool { if followerID == 0 || targetID == 0 || followerID == targetID { return false } var count int64 s.db.Model(&model.Follow{}).Where("follower_id = ? AND following_id = ?", followerID, targetID).Count(&count) return count > 0 } // ListFollowing 用户关注的人列表(公开;按关注时间倒序) func (s *FollowService) ListFollowing(userID uint, page, size int) ([]model.User, int64, error) { if page < 1 { page = 1 } if size < 1 || size > 50 { size = 20 } query := s.db.Model(&model.User{}). Joins("JOIN follows ON follows.following_id = users.id"). Where("follows.follower_id = ?", userID) var total int64 if err := query.Count(&total).Error; err != nil { return nil, 0, err } var users []model.User offset := (page - 1) * size if err := query.Select("users.*").Order("follows.created_at DESC").Offset(offset).Limit(size).Find(&users).Error; err != nil { return nil, 0, err } return users, total, nil } // CountFollowing 关注数量 func (s *FollowService) CountFollowing(userID uint) int64 { var count int64 s.db.Model(&model.Follow{}).Where("follower_id = ?", userID).Count(&count) return count } // CountFollowers 粉丝数量 func (s *FollowService) CountFollowers(userID uint) int64 { var count int64 s.db.Model(&model.Follow{}).Where("following_id = ?", userID).Count(&count) return count }