|
|
|
|
// Copyright 2022 ROC. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a MIT style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package jinzhu
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/rocboss/paopao-ce/internal/core"
|
|
|
|
|
"github.com/rocboss/paopao-ce/internal/core/cs"
|
|
|
|
|
"github.com/rocboss/paopao-ce/internal/core/ms"
|
|
|
|
|
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
|
|
|
|
|
"github.com/rocboss/paopao-ce/pkg/debug"
|
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
_ core.TweetService = (*tweetSrv)(nil)
|
|
|
|
|
_ core.TweetManageService = (*tweetManageSrv)(nil)
|
|
|
|
|
_ core.TweetHelpService = (*tweetHelpSrv)(nil)
|
|
|
|
|
|
|
|
|
|
_ core.TweetServantA = (*tweetSrvA)(nil)
|
|
|
|
|
_ core.TweetManageServantA = (*tweetManageSrvA)(nil)
|
|
|
|
|
_ core.TweetHelpServantA = (*tweetHelpSrvA)(nil)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type tweetSrv struct {
|
|
|
|
|
db *gorm.DB
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type tweetManageSrv struct {
|
|
|
|
|
cacheIndex core.CacheIndexService
|
|
|
|
|
db *gorm.DB
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type tweetHelpSrv struct {
|
|
|
|
|
db *gorm.DB
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type tweetSrvA struct {
|
|
|
|
|
db *gorm.DB
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type tweetManageSrvA struct {
|
|
|
|
|
db *gorm.DB
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type tweetHelpSrvA struct {
|
|
|
|
|
db *gorm.DB
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newTweetService(db *gorm.DB) core.TweetService {
|
|
|
|
|
return &tweetSrv{
|
|
|
|
|
db: db,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newTweetManageService(db *gorm.DB, cacheIndex core.CacheIndexService) core.TweetManageService {
|
|
|
|
|
return &tweetManageSrv{
|
|
|
|
|
cacheIndex: cacheIndex,
|
|
|
|
|
db: db,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newTweetHelpService(db *gorm.DB) core.TweetHelpService {
|
|
|
|
|
return &tweetHelpSrv{
|
|
|
|
|
db: db,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newTweetServantA(db *gorm.DB) core.TweetServantA {
|
|
|
|
|
return &tweetSrvA{
|
|
|
|
|
db: db,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newTweetManageServantA(db *gorm.DB) core.TweetManageServantA {
|
|
|
|
|
return &tweetManageSrvA{
|
|
|
|
|
db: db,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newTweetHelpServantA(db *gorm.DB) core.TweetHelpServantA {
|
|
|
|
|
return &tweetHelpSrvA{
|
|
|
|
|
db: db,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MergePosts post数据整合
|
|
|
|
|
func (s *tweetHelpSrv) MergePosts(posts []*ms.Post) ([]*ms.PostFormated, error) {
|
|
|
|
|
postIds := make([]int64, 0, len(posts))
|
|
|
|
|
userIds := make([]int64, 0, len(posts))
|
|
|
|
|
for _, post := range posts {
|
|
|
|
|
postIds = append(postIds, post.ID)
|
|
|
|
|
userIds = append(userIds, post.UserID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
postContents, err := s.getPostContentsByIDs(postIds)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
users, err := s.getUsersByIDs(userIds)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
userMap := make(map[int64]*dbr.UserFormated, len(users))
|
|
|
|
|
for _, user := range users {
|
|
|
|
|
userMap[user.ID] = user.Format()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
contentMap := make(map[int64][]*dbr.PostContentFormated, len(postContents))
|
|
|
|
|
for _, content := range postContents {
|
|
|
|
|
contentMap[content.PostID] = append(contentMap[content.PostID], content.Format())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 数据整合
|
|
|
|
|
postsFormated := make([]*dbr.PostFormated, 0, len(posts))
|
|
|
|
|
for _, post := range posts {
|
|
|
|
|
postFormated := post.Format()
|
|
|
|
|
postFormated.User = userMap[post.UserID]
|
|
|
|
|
postFormated.Contents = contentMap[post.ID]
|
|
|
|
|
postsFormated = append(postsFormated, postFormated)
|
|
|
|
|
}
|
|
|
|
|
return postsFormated, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RevampPosts post数据整形修复
|
|
|
|
|
func (s *tweetHelpSrv) RevampPosts(posts []*ms.PostFormated) ([]*ms.PostFormated, error) {
|
|
|
|
|
postIds := make([]int64, 0, len(posts))
|
|
|
|
|
userIds := make([]int64, 0, len(posts))
|
|
|
|
|
for _, post := range posts {
|
|
|
|
|
postIds = append(postIds, post.ID)
|
|
|
|
|
userIds = append(userIds, post.UserID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
postContents, err := s.getPostContentsByIDs(postIds)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
users, err := s.getUsersByIDs(userIds)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
userMap := make(map[int64]*dbr.UserFormated, len(users))
|
|
|
|
|
for _, user := range users {
|
|
|
|
|
userMap[user.ID] = user.Format()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
contentMap := make(map[int64][]*dbr.PostContentFormated, len(postContents))
|
|
|
|
|
for _, content := range postContents {
|
|
|
|
|
contentMap[content.PostID] = append(contentMap[content.PostID], content.Format())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 数据整合
|
|
|
|
|
for _, post := range posts {
|
|
|
|
|
post.User = userMap[post.UserID]
|
|
|
|
|
post.Contents = contentMap[post.ID]
|
|
|
|
|
}
|
|
|
|
|
return posts, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetHelpSrv) getPostContentsByIDs(ids []int64) ([]*dbr.PostContent, error) {
|
|
|
|
|
return (&dbr.PostContent{}).List(s.db, &dbr.ConditionsT{
|
|
|
|
|
"post_id IN ?": ids,
|
|
|
|
|
"ORDER": "sort ASC",
|
|
|
|
|
}, 0, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetHelpSrv) getUsersByIDs(ids []int64) ([]*dbr.User, error) {
|
|
|
|
|
user := &dbr.User{}
|
|
|
|
|
|
|
|
|
|
return user.List(s.db, &dbr.ConditionsT{
|
|
|
|
|
"id IN ?": ids,
|
|
|
|
|
}, 0, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) CreatePostCollection(postID, userID int64) (*ms.PostCollection, error) {
|
|
|
|
|
collection := &dbr.PostCollection{
|
|
|
|
|
PostID: postID,
|
|
|
|
|
UserID: userID,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return collection.Create(s.db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) DeletePostCollection(p *ms.PostCollection) error {
|
|
|
|
|
return p.Delete(s.db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) CreatePostContent(content *ms.PostContent) (*ms.PostContent, error) {
|
|
|
|
|
return content.Create(s.db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) CreateAttachment(obj *ms.Attachment) (int64, error) {
|
|
|
|
|
attachment, err := obj.Create(s.db)
|
|
|
|
|
return attachment.ID, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) CreatePost(post *ms.Post) (*ms.Post, error) {
|
|
|
|
|
post.LatestRepliedOn = time.Now().Unix()
|
|
|
|
|
p, err := post.Create(s.db)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
s.cacheIndex.SendAction(core.IdxActCreatePost, post)
|
|
|
|
|
return p, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) DeletePost(post *ms.Post) ([]string, error) {
|
|
|
|
|
var mediaContents []string
|
|
|
|
|
postId := post.ID
|
|
|
|
|
postContent := &dbr.PostContent{}
|
|
|
|
|
err := s.db.Transaction(
|
|
|
|
|
func(tx *gorm.DB) error {
|
|
|
|
|
if contents, err := postContent.MediaContentsByPostId(tx, postId); err == nil {
|
|
|
|
|
mediaContents = contents
|
|
|
|
|
} else {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删推文
|
|
|
|
|
if err := post.Delete(tx); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删内容
|
|
|
|
|
if err := postContent.DeleteByPostId(tx, postId); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删评论
|
|
|
|
|
if contents, err := s.deleteCommentByPostId(tx, postId); err == nil {
|
|
|
|
|
mediaContents = append(mediaContents, contents...)
|
|
|
|
|
} else {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if tags := strings.Split(post.Tags, ","); len(tags) > 0 {
|
|
|
|
|
// 删tag,宽松处理错误,有错误不会回滚
|
|
|
|
|
deleteTags(tx, tags)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s.cacheIndex.SendAction(core.IdxActDeletePost, post)
|
|
|
|
|
return mediaContents, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) deleteCommentByPostId(db *gorm.DB, postId int64) ([]string, error) {
|
|
|
|
|
comment := &dbr.Comment{}
|
|
|
|
|
commentContent := &dbr.CommentContent{}
|
|
|
|
|
|
|
|
|
|
// 获取推文的所有评论id
|
|
|
|
|
commentIds, err := comment.CommentIdsByPostId(db, postId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取评论的媒体内容
|
|
|
|
|
mediaContents, err := commentContent.MediaContentsByCommentId(db, commentIds)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删评论
|
|
|
|
|
if err = comment.DeleteByPostId(db, postId); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删评论内容
|
|
|
|
|
if err = commentContent.DeleteByCommentIds(db, commentIds); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删评论的评论
|
|
|
|
|
if err = (&dbr.CommentReply{}).DeleteByCommentIds(db, commentIds); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mediaContents, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) LockPost(post *ms.Post) error {
|
|
|
|
|
post.IsLock = 1 - post.IsLock
|
|
|
|
|
return post.Update(s.db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) StickPost(post *ms.Post) error {
|
|
|
|
|
post.IsTop = 1 - post.IsTop
|
|
|
|
|
if err := post.Update(s.db); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
s.cacheIndex.SendAction(core.IdxActStickPost, post)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) HighlightPost(userId int64, postId int64) (res int, err error) {
|
|
|
|
|
var post dbr.Post
|
|
|
|
|
tx := s.db.Begin()
|
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
post.Get(tx)
|
|
|
|
|
if err = tx.Where("id = ? AND is_del = 0", postId).First(&post).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if post.UserID != userId {
|
|
|
|
|
return 0, cs.ErrNoPermission
|
|
|
|
|
}
|
|
|
|
|
post.IsEssence = 1 - post.IsEssence
|
|
|
|
|
if err = post.Update(tx); err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
tx.Commit()
|
|
|
|
|
return post.IsEssence, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) VisiblePost(post *ms.Post, visibility cs.TweetVisibleType) (err error) {
|
|
|
|
|
oldVisibility := post.Visibility
|
|
|
|
|
post.Visibility = ms.PostVisibleT(visibility)
|
|
|
|
|
// TODO: 这个判断是否可以不要呢
|
|
|
|
|
if oldVisibility == ms.PostVisibleT(visibility) {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
// 私密推文 特殊处理
|
|
|
|
|
if visibility == cs.TweetVisitPrivate {
|
|
|
|
|
// 强制取消置顶
|
|
|
|
|
// TODO: 置顶推文用户是否有权设置成私密? 后续完善
|
|
|
|
|
post.IsTop = 0
|
|
|
|
|
}
|
|
|
|
|
tx := s.db.Begin()
|
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
if err = post.Update(tx); err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// tag处理
|
|
|
|
|
tags := strings.Split(post.Tags, ",")
|
|
|
|
|
// TODO: 暂时宽松不处理错误,这里或许可以有优化,后续完善
|
|
|
|
|
if oldVisibility == dbr.PostVisitPrivate {
|
|
|
|
|
// 从私密转为非私密才需要重新创建tag
|
|
|
|
|
createTags(tx, post.UserID, tags)
|
|
|
|
|
} else if visibility == cs.TweetVisitPrivate {
|
|
|
|
|
// 从非私密转为私密才需要删除tag
|
|
|
|
|
deleteTags(tx, tags)
|
|
|
|
|
}
|
|
|
|
|
tx.Commit()
|
|
|
|
|
s.cacheIndex.SendAction(core.IdxActVisiblePost, post)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) UpdatePost(post *ms.Post) (err error) {
|
|
|
|
|
if err = post.Update(s.db); err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
s.cacheIndex.SendAction(core.IdxActUpdatePost, post)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) CreatePostStar(postID, userID int64) (*ms.PostStar, error) {
|
|
|
|
|
star := &dbr.PostStar{
|
|
|
|
|
PostID: postID,
|
|
|
|
|
UserID: userID,
|
|
|
|
|
}
|
|
|
|
|
return star.Create(s.db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrv) DeletePostStar(p *ms.PostStar) error {
|
|
|
|
|
return p.Delete(s.db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetPostByID(id int64) (*ms.Post, error) {
|
|
|
|
|
post := &dbr.Post{
|
|
|
|
|
Model: &dbr.Model{
|
|
|
|
|
ID: id,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
return post.Get(s.db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetPosts(conditions ms.ConditionsT, offset, limit int) ([]*ms.Post, error) {
|
|
|
|
|
return (&dbr.Post{}).List(s.db, conditions, offset, limit)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) ListUserTweets(userId int64, style uint8, justEssence bool, limit, offset int) (res []*ms.Post, total int64, err error) {
|
|
|
|
|
db := s.db.Table(_post_).Where("user_id = ?", userId)
|
|
|
|
|
switch style {
|
|
|
|
|
case cs.StyleUserTweetsAdmin:
|
|
|
|
|
fallthrough
|
|
|
|
|
case cs.StyleUserTweetsSelf:
|
|
|
|
|
db = db.Where("visibility >= ?", cs.TweetVisitPrivate)
|
|
|
|
|
case cs.StyleUserTweetsFriend:
|
|
|
|
|
db = db.Where("visibility >= ?", cs.TweetVisitFriend)
|
|
|
|
|
case cs.StyleUserTweetsFollowing:
|
|
|
|
|
db = db.Where("visibility >= ?", cs.TweetVisitFollowing)
|
|
|
|
|
case cs.StyleUserTweetsGuest:
|
|
|
|
|
fallthrough
|
|
|
|
|
default:
|
|
|
|
|
db = db.Where("visibility >= ?", cs.TweetVisitPublic)
|
|
|
|
|
}
|
|
|
|
|
if justEssence {
|
|
|
|
|
db = db.Where("is_essence=1")
|
|
|
|
|
}
|
|
|
|
|
if err = db.Count(&total).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if offset >= 0 && limit > 0 {
|
|
|
|
|
db = db.Offset(offset).Limit(limit)
|
|
|
|
|
}
|
|
|
|
|
if err = db.Order("is_top DESC, latest_replied_on DESC").Find(&res).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) ListIndexNewestTweets(limit, offset int) (res []*ms.Post, total int64, err error) {
|
|
|
|
|
db := s.db.Table(_post_).Where("visibility >= ?", cs.TweetVisitPublic)
|
|
|
|
|
if err = db.Count(&total).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if offset >= 0 && limit > 0 {
|
|
|
|
|
db = db.Offset(offset).Limit(limit)
|
|
|
|
|
}
|
|
|
|
|
if err = db.Order("is_top DESC, latest_replied_on DESC").Find(&res).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) ListIndexHotsTweets(limit, offset int) (res []*ms.Post, total int64, err error) {
|
|
|
|
|
db := s.db.Table(_post_).Joins(fmt.Sprintf("LEFT JOIN %s metric ON %s.id=metric.post_id", _post_metric_, _post_)).Where("visibility >= ?", cs.TweetVisitPublic)
|
|
|
|
|
if err = db.Count(&total).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if offset >= 0 && limit > 0 {
|
|
|
|
|
db = db.Offset(offset).Limit(limit)
|
|
|
|
|
}
|
|
|
|
|
if err = db.Order("is_top DESC, metric.rank_score DESC, latest_replied_on DESC").Find(&res).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) ListSyncSearchTweets(limit, offset int) (res []*ms.Post, total int64, err error) {
|
|
|
|
|
db := s.db.Table(_post_).Where("visibility >= ?", cs.TweetVisitFriend)
|
|
|
|
|
if err = db.Count(&total).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if offset >= 0 && limit > 0 {
|
|
|
|
|
db = db.Offset(offset).Limit(limit)
|
|
|
|
|
}
|
|
|
|
|
if err = db.Find(&res).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) ListFollowingTweets(userId int64, limit, offset int) (res []*ms.Post, total int64, err error) {
|
|
|
|
|
beFriendIds, beFollowIds, xerr := s.getUserRelation(userId)
|
|
|
|
|
if xerr != nil {
|
|
|
|
|
return nil, 0, xerr
|
|
|
|
|
}
|
|
|
|
|
beFriendCount, beFollowCount := len(beFriendIds), len(beFollowIds)
|
|
|
|
|
db := s.db.Table(_post_)
|
|
|
|
|
//可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开',
|
|
|
|
|
switch {
|
|
|
|
|
case beFriendCount > 0 && beFollowCount > 0:
|
|
|
|
|
db = db.Where("user_id=? OR (visibility>=50 AND user_id IN(?)) OR (visibility>=60 AND user_id IN(?))", userId, beFriendIds, beFollowIds)
|
|
|
|
|
case beFriendCount > 0 && beFollowCount == 0:
|
|
|
|
|
db = db.Where("user_id=? OR (visibility>=50 AND user_id IN(?))", userId, beFriendIds)
|
|
|
|
|
case beFriendCount == 0 && beFollowCount > 0:
|
|
|
|
|
db = db.Where("user_id=? OR (visibility>=60 AND user_id IN(?))", userId, beFollowIds)
|
|
|
|
|
case beFriendCount == 0 && beFollowCount == 0:
|
|
|
|
|
db = db.Where("user_id = ?", userId)
|
|
|
|
|
}
|
|
|
|
|
if err = db.Count(&total).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if offset >= 0 && limit > 0 {
|
|
|
|
|
db = db.Offset(offset).Limit(limit)
|
|
|
|
|
}
|
|
|
|
|
if err = db.Order("is_top DESC, latest_replied_on DESC").Find(&res).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) getUserRelation(userId int64) (beFriendIds []int64, beFollowIds []int64, err error) {
|
|
|
|
|
if err = s.db.Table(_contact_).Where("friend_id=?", userId).Select("user_id").Find(&beFriendIds).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if err = s.db.Table(_following_).Where("user_id=?", userId).Select("follow_id").Find(&beFollowIds).Error; err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// 即是好友又是关注者,保留好友去除关注者
|
|
|
|
|
for _, id := range beFriendIds {
|
|
|
|
|
for i := 0; i < len(beFollowIds); i++ {
|
|
|
|
|
// 找到item即删,数据库已经保证唯一性
|
|
|
|
|
if beFollowIds[i] == id {
|
|
|
|
|
lastIdx := len(beFollowIds) - 1
|
|
|
|
|
beFollowIds[i] = beFollowIds[lastIdx]
|
|
|
|
|
beFollowIds = beFollowIds[:lastIdx]
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetPostCount(conditions ms.ConditionsT) (int64, error) {
|
|
|
|
|
return (&dbr.Post{}).Count(s.db, conditions)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetUserPostStar(postID, userID int64) (*ms.PostStar, error) {
|
|
|
|
|
star := &dbr.PostStar{
|
|
|
|
|
PostID: postID,
|
|
|
|
|
UserID: userID,
|
|
|
|
|
}
|
|
|
|
|
return star.Get(s.db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetUserPostStars(userID int64, limit int, offset int) ([]*ms.PostStar, error) {
|
|
|
|
|
star := &dbr.PostStar{
|
|
|
|
|
UserID: userID,
|
|
|
|
|
}
|
|
|
|
|
return star.List(s.db, &dbr.ConditionsT{
|
|
|
|
|
"ORDER": s.db.NamingStrategy.TableName("PostStar") + ".id DESC",
|
|
|
|
|
}, cs.RelationSelf, limit, offset)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) ListUserStarTweets(user *cs.VistUser, limit int, offset int) (res []*ms.PostStar, total int64, err error) {
|
|
|
|
|
star := &dbr.PostStar{
|
|
|
|
|
UserID: user.UserId,
|
|
|
|
|
}
|
|
|
|
|
if total, err = star.Count(s.db, user.RelTyp, &dbr.ConditionsT{}); err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
res, err = star.List(s.db, &dbr.ConditionsT{
|
|
|
|
|
"ORDER": s.db.NamingStrategy.TableName("PostStar") + ".id DESC",
|
|
|
|
|
}, user.RelTyp, limit, offset)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) getUserTweets(db *gorm.DB, user *cs.VistUser, limit int, offset int) (res []*ms.Post, total int64, err error) {
|
|
|
|
|
visibilities := []core.PostVisibleT{core.PostVisitPublic}
|
|
|
|
|
switch user.RelTyp {
|
|
|
|
|
case cs.RelationAdmin, cs.RelationSelf:
|
|
|
|
|
visibilities = append(visibilities, core.PostVisitPrivate, core.PostVisitFriend)
|
|
|
|
|
case cs.RelationFriend:
|
|
|
|
|
visibilities = append(visibilities, core.PostVisitFriend)
|
|
|
|
|
case cs.RelationGuest:
|
|
|
|
|
fallthrough
|
|
|
|
|
default:
|
|
|
|
|
// nothing
|
|
|
|
|
}
|
|
|
|
|
db = db.Where("visibility IN ? AND is_del=0", visibilities)
|
|
|
|
|
err = db.Count(&total).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if offset >= 0 && limit > 0 {
|
|
|
|
|
db = db.Offset(offset).Limit(limit)
|
|
|
|
|
}
|
|
|
|
|
err = db.Order("latest_replied_on DESC").Find(&res).Error
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) ListUserMediaTweets(user *cs.VistUser, limit int, offset int) ([]*ms.Post, int64, error) {
|
|
|
|
|
db := s.db.Table(_post_by_media_).Where("user_id=?", user.UserId)
|
|
|
|
|
return s.getUserTweets(db, user, limit, offset)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) ListUserCommentTweets(user *cs.VistUser, limit int, offset int) ([]*ms.Post, int64, error) {
|
|
|
|
|
db := s.db.Table(_post_by_comment_).Where("comment_user_id=?", user.UserId)
|
|
|
|
|
return s.getUserTweets(db, user, limit, offset)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetUserPostStarCount(userID int64) (int64, error) {
|
|
|
|
|
star := &dbr.PostStar{
|
|
|
|
|
UserID: userID,
|
|
|
|
|
}
|
|
|
|
|
return star.Count(s.db, cs.RelationSelf, &dbr.ConditionsT{})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetUserPostCollection(postID, userID int64) (*ms.PostCollection, error) {
|
|
|
|
|
star := &dbr.PostCollection{
|
|
|
|
|
PostID: postID,
|
|
|
|
|
UserID: userID,
|
|
|
|
|
}
|
|
|
|
|
return star.Get(s.db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetUserPostCollections(userID int64, offset, limit int) ([]*ms.PostCollection, error) {
|
|
|
|
|
collection := &dbr.PostCollection{
|
|
|
|
|
UserID: userID,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return collection.List(s.db, &dbr.ConditionsT{
|
|
|
|
|
"ORDER": s.db.NamingStrategy.TableName("PostCollection") + ".id DESC",
|
|
|
|
|
}, offset, limit)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetUserPostCollectionCount(userID int64) (int64, error) {
|
|
|
|
|
collection := &dbr.PostCollection{
|
|
|
|
|
UserID: userID,
|
|
|
|
|
}
|
|
|
|
|
return collection.Count(s.db, &dbr.ConditionsT{})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetUserWalletBills(userID int64, offset, limit int) ([]*ms.WalletStatement, error) {
|
|
|
|
|
statement := &dbr.WalletStatement{
|
|
|
|
|
UserID: userID,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return statement.List(s.db, &dbr.ConditionsT{
|
|
|
|
|
"ORDER": "id DESC",
|
|
|
|
|
}, offset, limit)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetUserWalletBillCount(userID int64) (int64, error) {
|
|
|
|
|
statement := &dbr.WalletStatement{
|
|
|
|
|
UserID: userID,
|
|
|
|
|
}
|
|
|
|
|
return statement.Count(s.db, &dbr.ConditionsT{})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetPostAttatchmentBill(postID, userID int64) (*ms.PostAttachmentBill, error) {
|
|
|
|
|
bill := &dbr.PostAttachmentBill{
|
|
|
|
|
PostID: postID,
|
|
|
|
|
UserID: userID,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bill.Get(s.db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetPostContentsByIDs(ids []int64) ([]*ms.PostContent, error) {
|
|
|
|
|
return (&dbr.PostContent{}).List(s.db, &dbr.ConditionsT{
|
|
|
|
|
"post_id IN ?": ids,
|
|
|
|
|
"ORDER": "sort ASC",
|
|
|
|
|
}, 0, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrv) GetPostContentByID(id int64) (*ms.PostContent, error) {
|
|
|
|
|
return (&dbr.PostContent{
|
|
|
|
|
Model: &dbr.Model{
|
|
|
|
|
ID: id,
|
|
|
|
|
},
|
|
|
|
|
}).Get(s.db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrvA) TweetInfoById(id int64) (*cs.TweetInfo, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return nil, debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrvA) TweetItemById(id int64) (*cs.TweetItem, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return nil, debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrvA) UserTweets(visitorId, userId int64) (cs.TweetList, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return nil, debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrvA) ReactionByTweetId(userId int64, tweetId int64) (*cs.ReactionItem, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return nil, debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrvA) UserReactions(userId int64, offset int, limit int) (cs.ReactionList, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return nil, debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrvA) FavoriteByTweetId(userId int64, tweetId int64) (*cs.FavoriteItem, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return nil, debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrvA) UserFavorites(userId int64, offset int, limit int) (cs.FavoriteList, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return nil, debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetSrvA) AttachmentByTweetId(userId int64, tweetId int64) (*cs.AttachmentBill, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return nil, debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrvA) CreateAttachment(obj *cs.Attachment) (int64, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return 0, debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrvA) CreateTweet(userId int64, req *cs.NewTweetReq) (*cs.TweetItem, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return nil, debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrvA) DeleteTweet(userId int64, tweetId int64) ([]string, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return nil, debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrvA) LockTweet(userId int64, tweetId int64) error {
|
|
|
|
|
// TODO
|
|
|
|
|
return debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrvA) StickTweet(userId int64, tweetId int64) error {
|
|
|
|
|
// TODO
|
|
|
|
|
return debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrvA) VisibleTweet(userId int64, visibility cs.TweetVisibleType) error {
|
|
|
|
|
// TODO
|
|
|
|
|
return debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrvA) CreateReaction(userId int64, tweetId int64) error {
|
|
|
|
|
// TODO
|
|
|
|
|
return debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrvA) DeleteReaction(userId int64, reactionId int64) error {
|
|
|
|
|
// TODO
|
|
|
|
|
return debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrvA) CreateFavorite(userId int64, tweetId int64) error {
|
|
|
|
|
// TODO
|
|
|
|
|
return debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetManageSrvA) DeleteFavorite(userId int64, favoriteId int64) error {
|
|
|
|
|
// TODO
|
|
|
|
|
return debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetHelpSrvA) RevampTweets(tweets cs.TweetList) (cs.TweetList, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return nil, debug.ErrNotImplemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *tweetHelpSrvA) MergeTweets(tweets cs.TweetInfo) (cs.TweetList, error) {
|
|
|
|
|
// TODO
|
|
|
|
|
return nil, debug.ErrNotImplemented
|
|
|
|
|
}
|