- 新增收藏功能:favorite 服务与 handler、FavoriteButton 组件 - 新增关注功能:follow 服务与 handler、FollowButton 组件 - 用户主页适配关注/粉丝与收藏展示 - flash 消息工具、广告与侧边栏组件微调
105 lines
3.0 KiB
Go
105 lines
3.0 KiB
Go
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
|
|
}
|