- 新增收藏功能: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"
|
||
)
|
||
|
||
// FavoriteService 收藏服务:收藏公开可见,公开列表只出 published 帖
|
||
type FavoriteService struct {
|
||
db *gorm.DB
|
||
posts *PostService
|
||
}
|
||
|
||
func NewFavoriteService(db *gorm.DB) *FavoriteService {
|
||
return &FavoriteService{db: db}
|
||
}
|
||
|
||
// WithPosts 注入帖子服务(列表复用 PostListItem 组装与最后回复填充)
|
||
func (s *FavoriteService) WithPosts(p *PostService) *FavoriteService {
|
||
s.posts = p
|
||
return s
|
||
}
|
||
|
||
// Toggle 切换收藏状态:已收藏则取消,未收藏则收藏。返回 (favorited, error)
|
||
func (s *FavoriteService) Toggle(postID, userID uint) (bool, error) {
|
||
var post model.Post
|
||
if err := s.db.First(&post, postID).Error; err != nil {
|
||
return false, errors.New("帖子不存在")
|
||
}
|
||
|
||
var fav model.Favorite
|
||
err := s.db.Where("post_id = ? AND user_id = ?", postID, userID).First(&fav).Error
|
||
if err == nil {
|
||
if err := s.db.Delete(&fav).Error; err != nil {
|
||
return true, err
|
||
}
|
||
return false, nil
|
||
}
|
||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||
return false, err
|
||
}
|
||
if err := s.db.Create(&model.Favorite{PostID: postID, UserID: userID}).Error; err != nil {
|
||
return false, err
|
||
}
|
||
return true, nil
|
||
}
|
||
|
||
// HasFavorited 判断用户是否已收藏某帖子
|
||
func (s *FavoriteService) HasFavorited(postID, userID uint) bool {
|
||
var count int64
|
||
s.db.Model(&model.Favorite{}).Where("post_id = ? AND user_id = ?", postID, userID).Count(&count)
|
||
return count > 0
|
||
}
|
||
|
||
// BatchHasFavorited 批量查询用户对多个帖子的收藏状态,返回 postID -> bool
|
||
func (s *FavoriteService) BatchHasFavorited(postIDs []uint, userID uint) map[uint]bool {
|
||
result := make(map[uint]bool)
|
||
if len(postIDs) == 0 || userID == 0 {
|
||
return result
|
||
}
|
||
var favs []model.Favorite
|
||
s.db.Where("post_id IN ? AND user_id = ?", postIDs, userID).Find(&favs)
|
||
for _, f := range favs {
|
||
result[f.PostID] = true
|
||
}
|
||
return result
|
||
}
|
||
|
||
// List 用户收藏的帖子列表(公开可见,仅 published;按收藏时间倒序)
|
||
func (s *FavoriteService) List(userID uint, page, size int) ([]PostListItem, int64, error) {
|
||
if page < 1 {
|
||
page = 1
|
||
}
|
||
if size < 1 || size > 50 {
|
||
size = 20
|
||
}
|
||
query := s.db.Model(&model.Post{}).
|
||
Joins("JOIN favorites ON favorites.post_id = posts.id").
|
||
Where("favorites.user_id = ? AND posts.status = ?", userID, model.ContentStatusPublished)
|
||
var total int64
|
||
if err := query.Count(&total).Error; err != nil {
|
||
return nil, 0, err
|
||
}
|
||
var posts []model.Post
|
||
offset := (page - 1) * size
|
||
if err := query.Select("posts.*").Order("favorites.created_at DESC").Offset(offset).Limit(size).
|
||
Preload("Board").Preload("User").Preload("User.Badges.Badge").Find(&posts).Error; err != nil {
|
||
return nil, 0, err
|
||
}
|
||
items := toPostListItems(posts)
|
||
if s.posts != nil {
|
||
s.posts.fillLastReply(items)
|
||
}
|
||
return items, total, nil
|
||
}
|
||
|
||
// CountByUser 用户收藏数量
|
||
func (s *FavoriteService) CountByUser(userID uint) int64 {
|
||
var count int64
|
||
s.db.Model(&model.Favorite{}).Where("user_id = ?", userID).Count(&count)
|
||
return count
|
||
}
|