optimize visible post logic add tags/search-index process logic

pull/106/head
alimy 2 years ago
parent 2a527202c0
commit ba4023d0a7

@ -6,6 +6,7 @@ const (
IdxActUpdatePost
IdxActDeletePost
IdxActStickPost
IdxActVisiblePost
)
type IndexActionT uint8
@ -22,6 +23,8 @@ func (a IndexActionT) String() string {
return "delete post"
case IdxActStickPost:
return "stick post"
case IdxActVisiblePost:
return "visible post"
default:
return "unknow action"
}

@ -34,7 +34,7 @@ type DataService interface {
DeletePost(post *model.Post) error
LockPost(post *model.Post) error
StickPost(post *model.Post) error
VisibilityPost(post *model.Post) error
VisiblePost(post *model.Post, visibility model.PostVisibleT) error
GetPostByID(id int64) (*model.Post, error)
GetPosts(conditions *model.ConditionsT, offset, limit int) ([]*model.Post, error)
MergePosts(posts []*model.Post) ([]*model.PostFormated, error)

@ -92,7 +92,12 @@ func (s *simpleCacheIndexServant) startIndexPosts() {
}
case action := <-s.indexActionCh:
switch action {
case core.IdxActCreatePost, core.IdxActUpdatePost, core.IdxActDeletePost, core.IdxActStickPost:
// TODO: 这里列出来是因为后续可能会精细化处理每种情况
case core.IdxActCreatePost,
core.IdxActUpdatePost,
core.IdxActDeletePost,
core.IdxActStickPost,
core.IdxActVisiblePost:
// prevent many update post in least time
if len(s.indexPosts) != 0 {
logrus.Debugf("remove index posts by action %s", action)

@ -1,6 +1,7 @@
package dao
import (
"strings"
"time"
"github.com/rocboss/paopao-ce/internal/core"
@ -39,8 +40,44 @@ func (d *dataServant) StickPost(post *model.Post) error {
return nil
}
func (d *dataServant) VisibilityPost(post *model.Post) error {
return post.Update(d.engine)
func (d *dataServant) VisiblePost(post *model.Post, visibility model.PostVisibleT) error {
oldVisibility := post.Visibility
post.Visibility = visibility
// TODO: 这个判断是否可以不要呢
if oldVisibility == visibility {
return nil
}
// 私密推文 特殊处理
if visibility == model.PostVisitPrivate {
// 强制取消置顶
// TODO: 置顶推文用户是否有权设置成私密? 后续完善
post.IsTop = 0
}
db := d.engine.Begin()
err := post.Update(db)
if err != nil {
db.Rollback()
return err
}
// tag处理
tags := strings.Split(post.Tags, ",")
for _, t := range tags {
tag := &model.Tag{
Tag: t,
}
// TODO: 暂时宽松不处理错误,这里或许可以有优化,后续完善
if oldVisibility == model.PostVisitPrivate {
// 从私密转为非私密才需要重新创建tag
d.createTag(db, tag)
} else if visibility == model.PostVisitPrivate {
// 从非私密转为私密才需要删除tag
d.deleteTag(db, tag)
}
}
db.Commit()
d.indexActive(core.IdxActVisiblePost)
return nil
}
func (d *dataServant) GetPostByID(id int64) (*model.Post, error) {

@ -1,17 +1,32 @@
package dao
import "github.com/rocboss/paopao-ce/internal/model"
import (
"github.com/rocboss/paopao-ce/internal/model"
"gorm.io/gorm"
)
func (d *dataServant) CreateTag(tag *model.Tag) (*model.Tag, error) {
return d.createTag(d.engine, tag)
}
func (d *dataServant) DeleteTag(tag *model.Tag) error {
return d.deleteTag(d.engine, tag)
}
func (d *dataServant) GetTags(conditions *model.ConditionsT, offset, limit int) ([]*model.Tag, error) {
return (&model.Tag{}).List(d.engine, conditions, offset, limit)
}
func (d *dataServant) createTag(db *gorm.DB, tag *model.Tag) (*model.Tag, error) {
t, err := tag.Get(d.engine)
if err != nil {
tag.QuoteNum = 1
return tag.Create(d.engine)
return tag.Create(db)
}
// 更新
t.QuoteNum++
err = t.Update(d.engine)
err = t.Update(db)
if err != nil {
return nil, err
@ -20,16 +35,11 @@ func (d *dataServant) CreateTag(tag *model.Tag) (*model.Tag, error) {
return t, nil
}
func (d *dataServant) DeleteTag(tag *model.Tag) error {
tag, err := tag.Get(d.engine)
func (d *dataServant) deleteTag(db *gorm.DB, tag *model.Tag) error {
tag, err := tag.Get(db)
if err != nil {
return err
}
tag.QuoteNum--
return tag.Update(d.engine)
}
func (d *dataServant) GetTags(conditions *model.ConditionsT, offset, limit int) ([]*model.Tag, error) {
return (&model.Tag{}).List(d.engine, conditions, offset, limit)
return tag.Update(db)
}

@ -8,12 +8,13 @@ import (
)
// PostVisibleT 可访问类型0公开1私密2好友
type PostVisibleT int
type PostVisibleT uint8
const (
PostVisitPublic PostVisibleT = iota
PostVisitPrivate
PostVisitFriend
PostVisitInvalid
)
type Post struct {
@ -156,3 +157,18 @@ func (p *Post) Count(db *gorm.DB, conditions *ConditionsT) (int64, error) {
func (p *Post) Update(db *gorm.DB) error {
return db.Model(&Post{}).Where("id = ? AND is_del = ?", p.Model.ID, 0).Save(p).Error
}
func (p PostVisibleT) String() string {
switch p {
case PostVisitPublic:
return "public"
case PostVisitPrivate:
return "private"
case PostVisitFriend:
return "friend"
case PostVisitInvalid:
return "invalid"
default:
return "unknow"
}
}

@ -288,7 +288,7 @@ func StickPost(c *gin.Context) {
})
}
func VisibilityPost(c *gin.Context) {
func VisiblePost(c *gin.Context) {
param := service.PostVisibilityReq{}
response := app.NewResponse(c)
valid, errs := app.BindAndValid(c, &param)
@ -298,24 +298,10 @@ func VisibilityPost(c *gin.Context) {
return
}
user, _ := c.Get("USER")
// 获取Post
postFormated, err := service.GetPost(param.ID)
if err != nil {
logrus.Errorf("service.GetPost err: %v\n", err)
response.ToErrorResponse(errcode.GetPostFailed)
return
}
if postFormated.UserID != user.(*model.User).ID && !user.(*model.User).IsAdmin {
response.ToErrorResponse(errcode.NoPermission)
return
}
err = service.VisibilityPost(param.ID, param.Visibility)
if err != nil {
logrus.Errorf("service.LockPost err: %v\n", err)
response.ToErrorResponse(errcode.LockPostFailed)
user, _ := userFrom(c)
if err := service.VisiblePost(user, param.ID, param.Visibility); err != nil {
logrus.Errorf("service.VisiblePost err: %v\n", err)
response.ToErrorResponse(err)
return
}

@ -564,3 +564,12 @@ func GetUserWalletBills(c *gin.Context) {
response.ToResponseList(bills, totalRows)
}
func userFrom(c *gin.Context) (*model.User, bool) {
if u, exists := c.Get("USER"); exists {
user, ok := u.(*model.User)
return user, ok
}
logrus.Debugln("user not exist")
return nil, false
}

@ -168,7 +168,7 @@ func NewRouter() *gin.Engine {
privApi.POST("/post/stick", api.StickPost)
// 修改动态可见度
privApi.POST("/post/visibility", api.VisibilityPost)
privApi.POST("/post/visibility", api.VisiblePost)
// 发布动态评论
privApi.POST("/post/comment", api.CreatePostComment)

@ -11,6 +11,7 @@ import (
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/errcode"
"github.com/rocboss/paopao-ce/pkg/util"
"github.com/rocboss/paopao-ce/pkg/zinc"
"github.com/sirupsen/logrus"
@ -219,16 +220,42 @@ func StickPost(id int64) error {
return nil
}
func VisibilityPost(id int64, visibility model.PostVisibleT) error {
post, _ := ds.GetPostByID(id)
func VisiblePost(user *model.User, postId int64, visibility model.PostVisibleT) *errcode.Error {
if visibility >= model.PostVisitInvalid {
return errcode.InvalidParams
}
// 修改可见度
post.Visibility = visibility
err := ds.VisibilityPost(post)
post, err := ds.GetPostByID(postId)
if err != nil {
return errcode.GetPostFailed
}
if err := checkPermision(user, post.UserID); err != nil {
return err
}
// 相同属性,不需要操作了
oldVisibility := post.Visibility
if oldVisibility == visibility {
logrus.Infof("sample visibility no need operate postId: %d", postId)
return nil
}
if err = ds.VisiblePost(post, visibility); err != nil {
logrus.Warnf("update post failure: %v", err)
return errcode.VisblePostFailed
}
// 搜索处理
if oldVisibility == model.PostVisitPrivate {
// 从私密转为非私密需要push
logrus.Debugf("visible post set to re-public to add search index: %d, visibility: %s", post.ID, visibility)
go PushPostToSearch(post)
} else if visibility == model.PostVisitPrivate {
// 从非私密转为私密需要删除索引
logrus.Debugf("visible post set to private to delete search index: %d, visibility: %s", post.ID, visibility)
go DeleteSearchPost(post)
}
return nil
}

@ -394,3 +394,11 @@ func GetSuggestTags(keyword string) ([]string, error) {
func IsFriend(userId, friendId int64) bool {
return ds.IsFriend(userId, friendId)
}
// checkPermision 检查是否拥有者或管理员
func checkPermision(user *model.User, targetUserId int64) *errcode.Error {
if user == nil || (user.ID != targetUserId && !user.IsAdmin) {
return errcode.NoPermission
}
return nil
}

@ -35,6 +35,7 @@ var (
InsuffientDownloadMoney = NewError(30009, "附件下载失败:账户资金不足")
DownloadExecFail = NewError(30010, "附件下载失败:扣费失败")
StickPostFailed = NewError(30011, "动态置顶失败")
VisblePostFailed = NewError(30012, "更新可见性失败")
GetCommentsFailed = NewError(40001, "获取评论列表失败")
CreateCommentFailed = NewError(40002, "评论发布失败")

Loading…
Cancel
Save