258 lines
7.0 KiB
Go
258 lines
7.0 KiB
Go
package services
|
|
|
|
import (
|
|
"bbs-go/internal/cache"
|
|
"bbs-go/internal/models"
|
|
"bbs-go/internal/models/constants"
|
|
"bbs-go/internal/pkg/event"
|
|
"bbs-go/internal/repositories"
|
|
|
|
"github.com/emirpasic/gods/sets/hashset"
|
|
"github.com/mlogclub/simple/common/dates"
|
|
"github.com/mlogclub/simple/sqls"
|
|
"github.com/mlogclub/simple/web/params"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
var UserFollowService = newUserFollowService()
|
|
|
|
func newUserFollowService() *userFollowService {
|
|
return &userFollowService{}
|
|
}
|
|
|
|
type userFollowService struct {
|
|
}
|
|
|
|
func (s *userFollowService) Get(id int64) *models.UserFollow {
|
|
return repositories.UserFollowRepository.Get(sqls.DB(), id)
|
|
}
|
|
|
|
func (s *userFollowService) Take(where ...interface{}) *models.UserFollow {
|
|
return repositories.UserFollowRepository.Take(sqls.DB(), where...)
|
|
}
|
|
|
|
func (s *userFollowService) Find(cnd *sqls.Cnd) []models.UserFollow {
|
|
return repositories.UserFollowRepository.Find(sqls.DB(), cnd)
|
|
}
|
|
|
|
func (s *userFollowService) FindOne(cnd *sqls.Cnd) *models.UserFollow {
|
|
return repositories.UserFollowRepository.FindOne(sqls.DB(), cnd)
|
|
}
|
|
|
|
func (s *userFollowService) FindPageByParams(params *params.QueryParams) (list []models.UserFollow, paging *sqls.Paging) {
|
|
return repositories.UserFollowRepository.FindPageByParams(sqls.DB(), params)
|
|
}
|
|
|
|
func (s *userFollowService) FindPageByCnd(cnd *sqls.Cnd) (list []models.UserFollow, paging *sqls.Paging) {
|
|
return repositories.UserFollowRepository.FindPageByCnd(sqls.DB(), cnd)
|
|
}
|
|
|
|
func (s *userFollowService) Count(cnd *sqls.Cnd) int64 {
|
|
return repositories.UserFollowRepository.Count(sqls.DB(), cnd)
|
|
}
|
|
|
|
func (s *userFollowService) Create(t *models.UserFollow) error {
|
|
return repositories.UserFollowRepository.Create(sqls.DB(), t)
|
|
}
|
|
|
|
func (s *userFollowService) Update(t *models.UserFollow) error {
|
|
return repositories.UserFollowRepository.Update(sqls.DB(), t)
|
|
}
|
|
|
|
func (s *userFollowService) Updates(id int64, columns map[string]interface{}) error {
|
|
return repositories.UserFollowRepository.Updates(sqls.DB(), id, columns)
|
|
}
|
|
|
|
func (s *userFollowService) UpdateColumn(id int64, name string, value interface{}) error {
|
|
return repositories.UserFollowRepository.UpdateColumn(sqls.DB(), id, name, value)
|
|
}
|
|
|
|
func (s *userFollowService) Delete(id int64) {
|
|
repositories.UserFollowRepository.Delete(sqls.DB(), id)
|
|
}
|
|
|
|
func (s *userFollowService) Follow(userId, otherId int64) error {
|
|
if userId == otherId {
|
|
// 自己关注自己,不进行处理。
|
|
// return errors.New("自己不能关注自己")
|
|
return nil
|
|
}
|
|
|
|
if s.IsFollowed(userId, otherId) {
|
|
return nil
|
|
}
|
|
|
|
err := sqls.DB().Transaction(func(tx *gorm.DB) error {
|
|
// 如果对方也关注了我,那么更新状态为互相关注
|
|
otherFollowed := tx.Exec("update t_user_follow set status = ? where user_id = ? and other_id = ?",
|
|
constants.FollowStatusBoth, otherId, userId).RowsAffected > 0
|
|
status := constants.FollowStatusFollow
|
|
if otherFollowed {
|
|
status = constants.FollowStatusBoth
|
|
}
|
|
|
|
if err := repositories.UserRepository.Updates(tx, userId, map[string]interface{}{
|
|
"follow_count": gorm.Expr("follow_count + 1"),
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
cache.UserCache.Invalidate(userId)
|
|
|
|
if err := repositories.UserRepository.Updates(tx, otherId, map[string]interface{}{
|
|
"fans_count": gorm.Expr("fans_count + 1"),
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
cache.UserCache.Invalidate(otherId)
|
|
|
|
return repositories.UserFollowRepository.Create(tx, &models.UserFollow{
|
|
UserId: userId,
|
|
OtherId: otherId,
|
|
Status: status,
|
|
CreateTime: dates.NowTimestamp(),
|
|
})
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 发送mq消息
|
|
event.Send(event.FollowEvent{
|
|
UserId: userId,
|
|
OtherId: otherId,
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func (s *userFollowService) UnFollow(userId, otherId int64) error {
|
|
if userId == otherId {
|
|
// 自己关注自己,不进行处理。
|
|
return nil
|
|
}
|
|
if !s.IsFollowed(userId, otherId) {
|
|
return nil
|
|
}
|
|
err := sqls.DB().Transaction(func(tx *gorm.DB) error {
|
|
success := tx.Where("user_id = ? and other_id = ?", userId, otherId).Delete(models.UserFollow{}).RowsAffected > 0
|
|
if success {
|
|
tx.Exec("update t_user_follow set status = ? where user_id = ? and other_id = ?",
|
|
constants.FollowStatusFollow, otherId, userId)
|
|
}
|
|
|
|
if err := tx.Model(&models.User{}).Where("id = ? and follow_count > 0", userId).Updates(map[string]interface{}{
|
|
"follow_count": gorm.Expr("follow_count - 1"),
|
|
}).Error; err != nil {
|
|
return err
|
|
}
|
|
cache.UserCache.Invalidate(userId)
|
|
|
|
if err := tx.Model(&models.User{}).Where("id = ? and fans_count > 0", otherId).Updates(map[string]interface{}{
|
|
"fans_count": gorm.Expr("fans_count - 1"),
|
|
}).Error; err != nil {
|
|
return err
|
|
}
|
|
cache.UserCache.Invalidate(otherId)
|
|
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 发送mq消息
|
|
event.Send(event.UnFollowEvent{
|
|
UserId: userId,
|
|
OtherId: otherId,
|
|
})
|
|
return nil
|
|
}
|
|
|
|
// GetFans 粉丝列表
|
|
func (s *userFollowService) GetFans(userId int64, cursor int64, limit int) (itemList []int64, nextCursor int64, hasMore bool) {
|
|
cnd := sqls.NewCnd().Eq("other_id", userId)
|
|
if cursor > 0 {
|
|
cnd.Lt("id", cursor)
|
|
}
|
|
cnd.Desc("id").Limit(limit)
|
|
list := repositories.UserFollowRepository.Find(sqls.DB(), cnd)
|
|
|
|
if len(list) > 0 {
|
|
nextCursor = list[len(list)-1].Id
|
|
hasMore = len(list) >= limit
|
|
for _, e := range list {
|
|
itemList = append(itemList, e.UserId)
|
|
}
|
|
} else {
|
|
nextCursor = cursor
|
|
}
|
|
return
|
|
}
|
|
|
|
// GetFollows 关注列表
|
|
func (s *userFollowService) GetFollows(userId int64, cursor int64, limit int) (itemList []int64, nextCursor int64, hasMore bool) {
|
|
cnd := sqls.NewCnd().Eq("user_id", userId)
|
|
if cursor > 0 {
|
|
cnd.Lt("id", cursor)
|
|
}
|
|
cnd.Desc("id").Limit(limit)
|
|
list := repositories.UserFollowRepository.Find(sqls.DB(), cnd)
|
|
|
|
if len(list) > 0 {
|
|
nextCursor = list[len(list)-1].Id
|
|
hasMore = len(list) >= limit
|
|
for _, e := range list {
|
|
itemList = append(itemList, e.OtherId)
|
|
}
|
|
} else {
|
|
nextCursor = cursor
|
|
}
|
|
return
|
|
}
|
|
|
|
// ScanFans 扫描粉丝
|
|
func (s *userFollowService) ScanFans(userId int64, handle func(fansId int64)) {
|
|
var cursor int64 = 0
|
|
for {
|
|
list := s.Find(sqls.NewCnd().Eq("other_id", userId).Gt("id", cursor).Asc("id").Limit(100))
|
|
if len(list) == 0 {
|
|
break
|
|
}
|
|
cursor = list[len(list)-1].Id
|
|
for _, item := range list {
|
|
handle(item.UserId)
|
|
}
|
|
}
|
|
}
|
|
|
|
// ScanFollowed 扫描关注的用户
|
|
func (s *userFollowService) ScanFollowed(userId int64, handle func(followUserId int64)) {
|
|
var cursor int64 = 0
|
|
for {
|
|
list := s.Find(sqls.NewCnd().Eq("user_id", userId).Gt("id", cursor).Asc("id").Limit(100))
|
|
if len(list) == 0 {
|
|
break
|
|
}
|
|
cursor = list[len(list)-1].Id
|
|
for _, item := range list {
|
|
handle(item.OtherId)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *userFollowService) IsFollowed(userId, otherId int64) bool {
|
|
if userId == otherId {
|
|
return false
|
|
}
|
|
set := s.IsFollowedUsers(userId, otherId)
|
|
return set.Contains(otherId)
|
|
}
|
|
|
|
func (s *userFollowService) IsFollowedUsers(userId int64, otherIds ...int64) hashset.Set {
|
|
set := hashset.New()
|
|
list := s.Find(sqls.NewCnd().Eq("user_id", userId).In("other_id", otherIds))
|
|
for _, follow := range list {
|
|
set.Add(follow.OtherId)
|
|
}
|
|
return *set
|
|
}
|