From 2bc16b232d72a227e6d28a92e77584bb178600ea Mon Sep 17 00:00:00 2001 From: Michael Li Date: Tue, 8 Aug 2023 18:41:16 +0800 Subject: [PATCH] add get user star tweets logic for guest visitor --- internal/core/cs/user.go | 38 +++++++++++++++++++++++ internal/core/tweets.go | 3 +- internal/dao/jinzhu/dbr/post_star.go | 46 +++++++++++++++++----------- internal/dao/jinzhu/tweets.go | 33 +++++++++++++++++--- internal/servants/base/base.go | 15 +++++++++ internal/servants/web/core.go | 4 +-- internal/servants/web/loose.go | 43 ++++++++++++-------------- 7 files changed, 132 insertions(+), 50 deletions(-) diff --git a/internal/core/cs/user.go b/internal/core/cs/user.go index d2331ff7..ee60df96 100644 --- a/internal/core/cs/user.go +++ b/internal/core/cs/user.go @@ -4,9 +4,28 @@ package cs +const ( + RelationUnknow RelationTyp = iota + RelationSelf + RelationFriend + RelationFollower + RelationFollowing + RelationAdmin + RelationGuest +) + type ( // UserInfoList 用户信息列表 UserInfoList []*UserInfo + + // + RelationTyp uint8 + + VistUser struct { + Username string + UserId int64 + RelTyp RelationTyp + } ) // UserInfo 用户基本信息 @@ -18,3 +37,22 @@ type UserInfo struct { Avatar string `json:"avatar"` IsAdmin bool `json:"is_admin"` } + +func (t RelationTyp) String() string { + switch t { + case RelationSelf: + return "self" + case RelationFriend: + return "friend" + case RelationFollower: + return "follower" + case RelationFollowing: + return "following" + case RelationAdmin: + return "admin" + case RelationUnknow: + fallthrough + default: + return "unknow relation" + } +} diff --git a/internal/core/tweets.go b/internal/core/tweets.go index f5250b44..9cb2e54a 100644 --- a/internal/core/tweets.go +++ b/internal/core/tweets.go @@ -15,7 +15,7 @@ type TweetService interface { GetPosts(conditions ms.ConditionsT, offset, limit int) ([]*ms.Post, error) GetPostCount(conditions ms.ConditionsT) (int64, error) GetUserPostStar(postID, userID int64) (*ms.PostStar, error) - GetUserPostStars(userID int64, offset, limit int) ([]*ms.PostStar, error) + GetUserPostStars(userID int64, limit int, offset int) ([]*ms.PostStar, error) GetUserPostStarCount(userID int64) (int64, error) GetUserPostCollection(postID, userID int64) (*ms.PostCollection, error) GetUserPostCollections(userID int64, offset, limit int) ([]*ms.PostCollection, error) @@ -23,6 +23,7 @@ type TweetService interface { GetPostAttatchmentBill(postID, userID int64) (*ms.PostAttachmentBill, error) GetPostContentsByIDs(ids []int64) ([]*ms.PostContent, error) GetPostContentByID(id int64) (*ms.PostContent, error) + ListUserStarTweets(user *cs.VistUser, limit int, offset int) ([]*ms.PostStar, int64, error) } // TweetManageService 推文管理服务,包括创建/删除/更新推文 diff --git a/internal/dao/jinzhu/dbr/post_star.go b/internal/dao/jinzhu/dbr/post_star.go index ca598ec8..33173e4b 100644 --- a/internal/dao/jinzhu/dbr/post_star.go +++ b/internal/dao/jinzhu/dbr/post_star.go @@ -7,6 +7,7 @@ package dbr import ( "time" + "github.com/rocboss/paopao-ce/internal/core/cs" "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -52,18 +53,14 @@ func (p *PostStar) Delete(db *gorm.DB) error { }).Error } -func (p *PostStar) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*PostStar, error) { - var stars []*PostStar - var err error +func (p *PostStar) List(db *gorm.DB, conditions *ConditionsT, typ cs.RelationTyp, limit int, offset int) (res []*PostStar, err error) { tn := db.NamingStrategy.TableName("PostStar") + "." - if offset >= 0 && limit > 0 { db = db.Offset(offset).Limit(limit) } if p.UserID > 0 { db = db.Where(tn+"user_id = ?", p.UserID) } - for k, v := range *conditions { if k == "ORDER" { db = db.Order(v) @@ -71,18 +68,24 @@ func (p *PostStar) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) db = db.Where(tn+k, v) } } - - db = db.Joins("Post").Where("visibility <> ? OR (visibility = ? AND ? = ?)", PostVisitPrivate, PostVisitPrivate, clause.Column{Table: "Post", Name: "user_id"}, p.UserID).Order(clause.OrderByColumn{Column: clause.Column{Table: "Post", Name: "id"}, Desc: true}) - if err = db.Find(&stars).Error; err != nil { - return nil, err + db = db.Joins("Post") + switch typ { + case cs.RelationAdmin: + // admin have all permition to visit all type tweets + case cs.RelationFriend: + db = db.Where("visibility = ? OR visibility = ?", PostVisitPublic, PostVisitFriend) + case cs.RelationSelf: + db = db.Where("visibility <> ? OR (visibility = ? AND ? = ?)", PostVisitPrivate, PostVisitPrivate, clause.Column{Table: "Post", Name: "user_id"}, p.UserID) + default: + db = db.Where("visibility=?", PostVisitPublic) } - return stars, nil + db = db.Order(clause.OrderByColumn{Column: clause.Column{Table: "Post", Name: "id"}, Desc: true}) + err = db.Find(&res).Error + return } -func (p *PostStar) Count(db *gorm.DB, conditions *ConditionsT) (int64, error) { - var count int64 +func (p *PostStar) Count(db *gorm.DB, typ cs.RelationTyp, conditions *ConditionsT) (res int64, err error) { tn := db.NamingStrategy.TableName("PostStar") + "." - if p.PostID > 0 { db = db.Where(tn+"post_id = ?", p.PostID) } @@ -94,10 +97,17 @@ func (p *PostStar) Count(db *gorm.DB, conditions *ConditionsT) (int64, error) { db = db.Where(tn+k, v) } } - - db = db.Joins("Post").Where("visibility <> ? OR (visibility = ? AND ? = ?)", PostVisitPrivate, PostVisitPrivate, clause.Column{Table: "Post", Name: "user_id"}, p.UserID) - if err := db.Model(p).Count(&count).Error; err != nil { - return 0, err + db = db.Joins("Post") + switch typ { + case cs.RelationAdmin: + // admin have all permition to visit all type tweets + case cs.RelationFriend: + db = db.Where("visibility = ? OR visibility = ?", PostVisitPublic, PostVisitFriend) + case cs.RelationSelf: + db = db.Where("visibility <> ? OR (visibility = ? AND ? = ?)", PostVisitPrivate, PostVisitPrivate, clause.Column{Table: "Post", Name: "user_id"}, p.UserID) + default: + db = db.Where("visibility=?", PostVisitPublic) } - return count, nil + err = db.Model(p).Count(&res).Error + return } diff --git a/internal/dao/jinzhu/tweets.go b/internal/dao/jinzhu/tweets.go index a79ab923..e0733ce0 100644 --- a/internal/dao/jinzhu/tweets.go +++ b/internal/dao/jinzhu/tweets.go @@ -404,21 +404,46 @@ func (s *tweetSrv) GetUserPostStar(postID, userID int64) (*ms.PostStar, error) { return star.Get(s.db) } -func (s *tweetSrv) GetUserPostStars(userID int64, offset, limit int) ([]*ms.PostStar, error) { +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", - }, offset, limit) + }, cs.RelationSelf, limit, offset) +} + +func (s *tweetSrv) ListUserStarTweets(user *cs.VistUser, limit int, offset int) (res []*ms.PostStar, total int64, err error) { + var userId int64 + typ := user.RelTyp + if typ == cs.RelationSelf { + userId = user.UserId + } else { + user := &dbr.User{ + Username: user.Username, + } + if user, err = user.Get(s.db); err != nil { + return + } + userId = user.ID + } + star := &dbr.PostStar{ + UserID: userId, + } + if total, err = star.Count(s.db, typ, &dbr.ConditionsT{}); err != nil { + return + } + res, err = star.List(s.db, &dbr.ConditionsT{ + "ORDER": s.db.NamingStrategy.TableName("PostStar") + ".id DESC", + }, typ, limit, offset) + return } func (s *tweetSrv) GetUserPostStarCount(userID int64) (int64, error) { star := &dbr.PostStar{ UserID: userID, } - return star.Count(s.db, &dbr.ConditionsT{}) + return star.Count(s.db, cs.RelationSelf, &dbr.ConditionsT{}) } func (s *tweetSrv) GetUserPostCollection(postID, userID int64) (*ms.PostCollection, error) { diff --git a/internal/servants/base/base.go b/internal/servants/base/base.go index 1825fe98..f886af25 100644 --- a/internal/servants/base/base.go +++ b/internal/servants/base/base.go @@ -17,6 +17,7 @@ import ( "github.com/gin-gonic/gin" "github.com/rocboss/paopao-ce/internal/conf" "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" "github.com/rocboss/paopao-ce/internal/dao/cache" @@ -274,6 +275,20 @@ func (s *DaoServant) GetTweetList(conditions ms.ConditionsT, offset, limit int) return posts, postFormated, err } +func (s *DaoServant) RelationTypFrom(me *ms.User, username string) cs.RelationTyp { + if me == nil { + return cs.RelationGuest + } + if me.IsAdmin { + return cs.RelationAdmin + } else if me.Username == username { + return cs.RelationSelf + } + // TODO: other releation detect logic + // but return guest to all for now + return cs.RelationGuest +} + func NewBindAnyFn() func(c *gin.Context, obj any) mir.Error { if conf.UseSentryGin() { return bindAnySentry diff --git a/internal/servants/web/core.go b/internal/servants/web/core.go index 923b0261..c1337fe9 100644 --- a/internal/servants/web/core.go +++ b/internal/servants/web/core.go @@ -240,7 +240,7 @@ func (s *coreSrv) UserPhoneBind(req *web.UserPhoneBindReq) mir.Error { } func (s *coreSrv) GetStars(req *web.GetStarsReq) (*web.GetStarsResp, mir.Error) { - stars, err := s.Ds.GetUserPostStars(req.UserId, (req.Page-1)*req.PageSize, req.PageSize) + stars, err := s.Ds.GetUserPostStars(req.UserId, req.PageSize, (req.Page-1)*req.PageSize) if err != nil { logrus.Errorf("Ds.GetUserPostStars err: %s", err) return nil, web.ErrGetStarsFailed @@ -250,7 +250,6 @@ func (s *coreSrv) GetStars(req *web.GetStarsReq) (*web.GetStarsResp, mir.Error) logrus.Errorf("Ds.GetUserPostStars err: %s", err) return nil, web.ErrGetStarsFailed } - var posts []*ms.Post for _, star := range stars { posts = append(posts, star.Post) @@ -261,7 +260,6 @@ func (s *coreSrv) GetStars(req *web.GetStarsReq) (*web.GetStarsResp, mir.Error) return nil, web.ErrGetStarsFailed } resp := base.PageRespFrom(postsFormated, req.Page, req.PageSize, totalRows) - return (*web.GetStarsResp)(resp), nil } diff --git a/internal/servants/web/loose.go b/internal/servants/web/loose.go index 983c5108..d05d8bb7 100644 --- a/internal/servants/web/loose.go +++ b/internal/servants/web/loose.go @@ -62,16 +62,16 @@ func (s *looseSrv) Timeline(req *web.TimelineReq) (*web.TimelineResp, mir.Error) } func (s *looseSrv) GetUserTweets(req *web.GetUserTweetsReq) (res *web.GetUserTweetsResp, err mir.Error) { - isSelf := (req.User != nil && req.User.Username == req.Username) + relTyp := s.RelationTypFrom(req.User, req.Username) switch req.Style { case web.UserPostsStyleComment: - res, err = s.getUserCommentTweets(req, isSelf) + res, err = s.getUserCommentTweets(req, relTyp) case web.UserPostsStyleHighlight: - res, err = s.getUserHighlightTweets(req, isSelf) + res, err = s.getUserHighlightTweets(req, relTyp) case web.UserPostsStyleMedia: - res, err = s.getUserMediaTweets(req, isSelf) + res, err = s.getUserMediaTweets(req, relTyp) case web.UserPostsStyleStar: - res, err = s.getUserStarTweets(req, isSelf) + res, err = s.getUserStarTweets(req, relTyp) case web.UserPostsStylePost: fallthrough default: @@ -80,33 +80,24 @@ func (s *looseSrv) GetUserTweets(req *web.GetUserTweetsReq) (res *web.GetUserTwe return } -func (s *looseSrv) getUserCommentTweets(req *web.GetUserTweetsReq, isSelf bool) (*web.GetUserTweetsResp, mir.Error) { +func (s *looseSrv) getUserCommentTweets(req *web.GetUserTweetsReq, relTyp cs.RelationTyp) (*web.GetUserTweetsResp, mir.Error) { // TODO: add implement logic resp := base.PageRespFrom(nil, req.Page, req.PageSize, 0) return (*web.GetUserTweetsResp)(resp), nil } -func (s *looseSrv) getUserHighlightTweets(req *web.GetUserTweetsReq, isSelf bool) (*web.GetUserTweetsResp, mir.Error) { +func (s *looseSrv) getUserHighlightTweets(req *web.GetUserTweetsReq, relTyp cs.RelationTyp) (*web.GetUserTweetsResp, mir.Error) { // TODO: add implement logic resp := base.PageRespFrom(nil, req.Page, req.PageSize, 0) return (*web.GetUserTweetsResp)(resp), nil } -func (s *looseSrv) getUserMediaTweets(req *web.GetUserTweetsReq, isSelf bool) (*web.GetUserTweetsResp, mir.Error) { +func (s *looseSrv) getUserMediaTweets(req *web.GetUserTweetsReq, relTyp cs.RelationTyp) (*web.GetUserTweetsResp, mir.Error) { // TODO: add implement logic resp := base.PageRespFrom(nil, req.Page, req.PageSize, 0) return (*web.GetUserTweetsResp)(resp), nil } -func (s *looseSrv) getUserStarTweets(req *web.GetUserTweetsReq, isSelf bool) (*web.GetUserTweetsResp, mir.Error) { - if isSelf { - return s.getSelfStarTweets(req) - } - // TODO: add implement logic for not self star tweets - resp := base.PageRespFrom(nil, req.Page, req.PageSize, 0) - return (*web.GetUserTweetsResp)(resp), nil -} - func (s *looseSrv) getSelfCommentTweets(req *web.GetUserTweetsReq) (*web.GetUserTweetsResp, mir.Error) { // TODO: add implement logic resp := base.PageRespFrom(nil, req.Page, req.PageSize, 0) @@ -119,20 +110,24 @@ func (s *looseSrv) getSelfMediaTweets(req *web.GetUserTweetsReq) (*web.GetUserTw return (*web.GetUserTweetsResp)(resp), nil } -func (s *looseSrv) getSelfStarTweets(req *web.GetUserTweetsReq) (*web.GetUserTweetsResp, mir.Error) { - stars, err := s.Ds.GetUserPostStars(req.User.ID, (req.Page-1)*req.PageSize, req.PageSize) - if err != nil { - logrus.Errorf("Ds.GetUserPostStars err: %s", err) - return nil, web.ErrGetStarsFailed +func (s *looseSrv) getUserStarTweets(req *web.GetUserTweetsReq, relTyp cs.RelationTyp) (*web.GetUserTweetsResp, mir.Error) { + user := &cs.VistUser{ + Username: req.Username, + RelTyp: relTyp, } - totalRows, err := s.Ds.GetUserPostStarCount(req.User.ID) + if relTyp == cs.RelationSelf { + user.UserId = req.User.ID + } + stars, totalRows, err := s.Ds.ListUserStarTweets(user, req.PageSize, (req.Page-1)*req.PageSize) if err != nil { logrus.Errorf("Ds.GetUserPostStars err: %s", err) return nil, web.ErrGetStarsFailed } var posts []*ms.Post for _, star := range stars { - posts = append(posts, star.Post) + if star.Post != nil { + posts = append(posts, star.Post) + } } postsFormated, err := s.Ds.MergePosts(posts) if err != nil {