add get inc or dec count
This commit is contained in:
		
							parent
							
								
									30fb3b3721
								
							
						
					
					
						commit
						a3796aabdc
					
				| 
						 | 
				
			
			@ -130,7 +130,7 @@ message LikeCountReq {
 | 
			
		|||
 | 
			
		||||
// 讚/不讚數量回應
 | 
			
		||||
message LikeCountResp {
 | 
			
		||||
  string count = 1;  // 總共按讚數量
 | 
			
		||||
  int64 count = 1;  // 總共按讚數量
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 評論貼文的請求
 | 
			
		||||
| 
						 | 
				
			
			@ -174,6 +174,18 @@ message UpdateCommentReq {
 | 
			
		|||
  string content = 2;      // 更新後的評論內容
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message PostReactionActionResp {
 | 
			
		||||
  string PostID =1;         // 貼文的 ID
 | 
			
		||||
  int64 reaction_type = 2;  // 用戶的反應類型,可能是讚或不讚
 | 
			
		||||
  bool  is_increment   = 3; // 表示是否增加(true 表示增加,false 表示減少)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message IncDecLikeDislikeCountReq {
 | 
			
		||||
  string PostID =1;         // 貼文的 ID
 | 
			
		||||
  int64 reaction_type = 2;  // 用戶的反應類型,可能是讚或不讚
 | 
			
		||||
  bool  is_increment   = 3; // 表示是否增加(true 表示增加,false 表示減少)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 定義貼文服務
 | 
			
		||||
service PostService {
 | 
			
		||||
  // NewPost 新增貼文
 | 
			
		||||
| 
						 | 
				
			
			@ -184,9 +196,11 @@ service PostService {
 | 
			
		|||
  rpc UpdatePost(UpdatePostReq) returns (OKResp);
 | 
			
		||||
  // ListPosts 查詢貼文
 | 
			
		||||
  rpc ListPosts(QueryPostsReq) returns (ListPostsResp);
 | 
			
		||||
  // IncDecLikeDislikeCount 增減數量
 | 
			
		||||
  rpc IncDecLikeDislikeCount(IncDecLikeDislikeCountReq) returns (OKResp);
 | 
			
		||||
 | 
			
		||||
  // Like 點讚/取消讚 貼文
 | 
			
		||||
  rpc Like(LikeReq) returns (OKResp);
 | 
			
		||||
  rpc Like(LikeReq) returns (PostReactionActionResp);
 | 
			
		||||
  // GetLikeStatus 取得讚/不讚狀態
 | 
			
		||||
  rpc GetLikeStatus(GetLikeStatusReq) returns (GetLikeStatusResp);
 | 
			
		||||
  // LikeList 取得讚/不讚列表
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ const (
 | 
			
		|||
 | 
			
		||||
type LikeType int8
 | 
			
		||||
 | 
			
		||||
func (l LikeType) ToInt32() int8 {
 | 
			
		||||
func (l LikeType) ToInt8() int8 {
 | 
			
		||||
	return int8(l)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,11 @@
 | 
			
		|||
package postservicelogic
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
 | 
			
		||||
	"app-cloudep-tweeting-service/gen_result/pb/tweeting"
 | 
			
		||||
	"app-cloudep-tweeting-service/internal/domain"
 | 
			
		||||
	"app-cloudep-tweeting-service/internal/svc"
 | 
			
		||||
	ers "code.30cm.net/digimon/library-go/errs"
 | 
			
		||||
	"context"
 | 
			
		||||
 | 
			
		||||
	"github.com/zeromicro/go-zero/core/logx"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -23,9 +24,35 @@ func NewCountLikeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CountLi
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type countLikeReq struct {
 | 
			
		||||
	PostID       string          `json:"post_id" validate:"required"`                 // 貼文的 ID
 | 
			
		||||
	ReactionType domain.LikeType `json:"reaction_type" validate:"required,oneof=1 2"` // 用戶的反應類型,可能是讚或不讚
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CountLike 取得讚/不讚數量
 | 
			
		||||
func (l *CountLikeLogic) CountLike(in *tweeting.LikeCountReq) (*tweeting.LikeCountResp, error) {
 | 
			
		||||
	// todo: add your logic here and delete this line
 | 
			
		||||
	// 驗證資料
 | 
			
		||||
	if err := l.svcCtx.Validate.ValidateAll(&countLikeReq{
 | 
			
		||||
		PostID:       in.GetTargetId(),
 | 
			
		||||
		ReactionType: domain.LikeType(in.GetLikeType()),
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		return nil, ers.InvalidFormat(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &tweeting.LikeCountResp{}, nil
 | 
			
		||||
	count, err := l.svcCtx.PostLikeModel.Count(l.ctx, in.GetTargetId(), domain.LikeType(in.GetLikeType()))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		e := domain.PostMongoErrorL(
 | 
			
		||||
			logx.WithContext(l.ctx),
 | 
			
		||||
			[]logx.LogField{
 | 
			
		||||
				{Key: "req", Value: in},
 | 
			
		||||
				{Key: "func", Value: "PostLikeModel.Count"},
 | 
			
		||||
				{Key: "err", Value: err},
 | 
			
		||||
			},
 | 
			
		||||
			"failed to count like or dislike").Wrap(err)
 | 
			
		||||
		return nil, e
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &tweeting.LikeCountResp{
 | 
			
		||||
		Count: count,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
package postservicelogic
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"app-cloudep-tweeting-service/internal/domain"
 | 
			
		||||
	model "app-cloudep-tweeting-service/internal/model/mongo"
 | 
			
		||||
	ers "code.30cm.net/digimon/library-go/errs"
 | 
			
		||||
	"context"
 | 
			
		||||
 | 
			
		||||
	"app-cloudep-tweeting-service/gen_result/pb/tweeting"
 | 
			
		||||
	"app-cloudep-tweeting-service/internal/svc"
 | 
			
		||||
 | 
			
		||||
	"github.com/zeromicro/go-zero/core/logx"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IncDecLikeDislikeCountLogic struct {
 | 
			
		||||
	ctx    context.Context
 | 
			
		||||
	svcCtx *svc.ServiceContext
 | 
			
		||||
	logx.Logger
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewIncDecLikeDislikeCountLogic(ctx context.Context, svcCtx *svc.ServiceContext) *IncDecLikeDislikeCountLogic {
 | 
			
		||||
	return &IncDecLikeDislikeCountLogic{
 | 
			
		||||
		ctx:    ctx,
 | 
			
		||||
		svcCtx: svcCtx,
 | 
			
		||||
		Logger: logx.WithContext(ctx),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type postReactionAction struct {
 | 
			
		||||
	PostID       string          `json:"post_id" validate:"required"`                 // 貼文的 ID
 | 
			
		||||
	ReactionType domain.LikeType `json:"reaction_type" validate:"required,oneof=1 2"` // 用戶的反應類型,可能是讚或不讚
 | 
			
		||||
	IsIncrement  bool            `json:"is_increment" validate:"required"`            // 表示是否增加(true 表示增加,false 表示減少)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IncDecLikeDislikeCount 增減數量
 | 
			
		||||
func (l *IncDecLikeDislikeCountLogic) IncDecLikeDislikeCount(in *tweeting.IncDecLikeDislikeCountReq) (*tweeting.OKResp, error) {
 | 
			
		||||
	// 驗證資料
 | 
			
		||||
	if err := l.svcCtx.Validate.ValidateAll(&postReactionAction{
 | 
			
		||||
		PostID:       in.GetPostID(),
 | 
			
		||||
		ReactionType: domain.LikeType(in.GetReactionType()),
 | 
			
		||||
		IsIncrement:  in.GetIsIncrement(),
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		return nil, ers.InvalidFormat(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := l.svcCtx.PostModel.IncDecLikeDislikeCountLogic(l.ctx, &model.PostReactionAction{
 | 
			
		||||
		PostID:       in.GetPostID(),
 | 
			
		||||
		ReactionType: domain.LikeType(in.GetReactionType()),
 | 
			
		||||
		IsIncrement:  in.GetIsIncrement(),
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		e := domain.PostMongoErrorL(
 | 
			
		||||
			logx.WithContext(l.ctx),
 | 
			
		||||
			[]logx.LogField{
 | 
			
		||||
				{Key: "req", Value: in},
 | 
			
		||||
				{Key: "func", Value: "PostModel.IncDecLikeDislikeCountLogic"},
 | 
			
		||||
				{Key: "err", Value: err},
 | 
			
		||||
			},
 | 
			
		||||
			"failed to inc like or dislike").Wrap(err)
 | 
			
		||||
		return nil, e
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &tweeting.OKResp{}, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -29,21 +29,19 @@ func NewLikeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LikeLogic {
 | 
			
		|||
type likeReq struct {
 | 
			
		||||
	Target string `json:"target" validate:"required"`
 | 
			
		||||
	UID    string `json:"uid" validate:"required"`
 | 
			
		||||
	LikeType domain.LikeType `json:"like_type" validate:"required,oneof=1 2"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Like 點讚/取消讚 貼文
 | 
			
		||||
func (l *LikeLogic) Like(in *tweeting.LikeReq) (*tweeting.OKResp, error) {
 | 
			
		||||
func (l *LikeLogic) Like(in *tweeting.LikeReq) (*tweeting.PostReactionActionResp, error) {
 | 
			
		||||
	// 驗證資料
 | 
			
		||||
	if err := l.svcCtx.Validate.ValidateAll(&likeReq{
 | 
			
		||||
		Target: in.TargetId,
 | 
			
		||||
		UID:    in.GetUid(),
 | 
			
		||||
		LikeType: domain.LikeType(in.GetLikeType()),
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		return nil, ers.InvalidFormat(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := l.svcCtx.PostLikeModel.LikeDislike(l.ctx, &model.PostLikes{
 | 
			
		||||
	likeResp, err := l.svcCtx.PostLikeModel.LikeDislike(l.ctx, &model.PostLikes{
 | 
			
		||||
		TargetID: in.GetTargetId(),
 | 
			
		||||
		UID:      in.GetUid(),
 | 
			
		||||
		Type:     int8(in.GetLikeType()),
 | 
			
		||||
| 
						 | 
				
			
			@ -60,5 +58,11 @@ func (l *LikeLogic) Like(in *tweeting.LikeReq) (*tweeting.OKResp, error) {
 | 
			
		|||
		return nil, e
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &tweeting.OKResp{}, nil
 | 
			
		||||
	// 將文章的數量增加或減少的功能,是業務邏輯,從外面再決定要不要丟MQ 後算,或是怎麼算
 | 
			
		||||
 | 
			
		||||
	return &tweeting.PostReactionActionResp{
 | 
			
		||||
		PostID:       likeResp.PostID,
 | 
			
		||||
		ReactionType: int64(likeResp.ReactionType),
 | 
			
		||||
		IsIncrement:  likeResp.IsIncrement,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,9 +19,16 @@ type (
 | 
			
		|||
	// and implement the added methods in customPost_likesModel.
 | 
			
		||||
	Post_likesModel interface {
 | 
			
		||||
		post_likesModel
 | 
			
		||||
		LikeDislike(ctx context.Context, postLike *PostLikes) error
 | 
			
		||||
		LikeDislike(ctx context.Context, postLike *PostLikes) (*PostReactionAction, error)
 | 
			
		||||
		FindLikeUsers(ctx context.Context, param *QueryPostLikeReq) ([]*PostLikes, int64, error)
 | 
			
		||||
		FindUIDPostLikeStatus(ctx context.Context, param *QueryUIDPostLikeStatusReq) ([]UIDPostLikeStatusResp, error)
 | 
			
		||||
		Count(ctx context.Context, target string, likeType domain.LikeType) (int64, error)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	PostReactionAction struct {
 | 
			
		||||
		PostID       string          // 貼文的 ID
 | 
			
		||||
		ReactionType domain.LikeType // 用戶的反應類型,可能是讚或不讚
 | 
			
		||||
		IsIncrement  bool            // 表示是否增加(true 表示增加,false 表示減少)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	QueryPostLikeReq struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +62,12 @@ func NewPost_likesModel(url, db, collection string) Post_likesModel {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *defaultPost_likesModel) LikeDislike(ctx context.Context, postLike *PostLikes) error {
 | 
			
		||||
func (m *defaultPost_likesModel) LikeDislike(ctx context.Context, postLike *PostLikes) (*PostReactionAction, error) {
 | 
			
		||||
	result := &PostReactionAction{
 | 
			
		||||
		PostID:       postLike.TargetID,
 | 
			
		||||
		ReactionType: domain.LikeType(postLike.Type),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 使用 target_id、uid、type 來查詢資料是否存在
 | 
			
		||||
	filter := bson.M{
 | 
			
		||||
		"target_id": postLike.TargetID,
 | 
			
		||||
| 
						 | 
				
			
			@ -69,23 +81,27 @@ func (m *defaultPost_likesModel) LikeDislike(ctx context.Context, postLike *Post
 | 
			
		|||
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		// 資料存在,進行刪除操作
 | 
			
		||||
		result.IsIncrement = false
 | 
			
		||||
		_, err = m.conn.DeleteOne(ctx, filter)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err // 刪除失敗
 | 
			
		||||
			return nil, err // 刪除失敗
 | 
			
		||||
		}
 | 
			
		||||
		return nil // 刪除成功
 | 
			
		||||
 | 
			
		||||
		return result, nil // 刪除成功
 | 
			
		||||
	} else if errors.Is(mongo.ErrNoDocuments, err) {
 | 
			
		||||
		// 資料不存在,進行插入操作
 | 
			
		||||
		result.IsIncrement = true
 | 
			
		||||
		postLike.ID = primitive.NewObjectID() // 設置新的 ObjectID
 | 
			
		||||
		postLike.CreateAt = time.Now().UTC().UnixNano()
 | 
			
		||||
		_, err = m.conn.InsertOne(ctx, postLike)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err // 插入失敗
 | 
			
		||||
			return nil, err // 插入失敗
 | 
			
		||||
		}
 | 
			
		||||
		return nil // 插入成功
 | 
			
		||||
 | 
			
		||||
		return result, nil // 插入成功
 | 
			
		||||
	} else {
 | 
			
		||||
		// 其他錯誤
 | 
			
		||||
		return err
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -171,3 +187,8 @@ func (m *defaultPost_likesModel) FindUIDPostLikeStatus(ctx context.Context, para
 | 
			
		|||
 | 
			
		||||
	return results, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c customPost_likesModel) Count(ctx context.Context, target string, likeType domain.LikeType) (int64, error) {
 | 
			
		||||
	// TODO implement me
 | 
			
		||||
	panic("implement me")
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
package model
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"app-cloudep-tweeting-service/internal/domain"
 | 
			
		||||
	"context"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +25,7 @@ type (
 | 
			
		|||
		DeleteMany(ctx context.Context, id ...string) (int64, error)
 | 
			
		||||
		UpdateOptional(ctx context.Context, data *Post) (*mongo.UpdateResult, error)
 | 
			
		||||
		Find(ctx context.Context, param *QueryPostModelReq) ([]*Post, int64, error)
 | 
			
		||||
		IncDecLikeDislikeCountLogic(ctx context.Context, param *PostReactionAction) error
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	customPostModel struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -192,3 +194,39 @@ func (m *defaultPostModel) Find(ctx context.Context, param *QueryPostModelReq) (
 | 
			
		|||
		return nil, 0, err
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *customPostModel) IncDecLikeDislikeCountLogic(ctx context.Context, param *PostReactionAction) error {
 | 
			
		||||
	// 建立篩選條件,找到要更新的貼文
 | 
			
		||||
	filter := bson.M{"_id": param.PostID}
 | 
			
		||||
 | 
			
		||||
	// 初始化更新操作
 | 
			
		||||
	update := bson.M{}
 | 
			
		||||
 | 
			
		||||
	// 根據 ReactionType 和 IsIncrement 決定更新邏輯
 | 
			
		||||
	if param.ReactionType == domain.LikeTypeLike {
 | 
			
		||||
		if param.IsIncrement {
 | 
			
		||||
			// 增加 like 計數
 | 
			
		||||
			update = bson.M{"$inc": bson.M{"like": 1}}
 | 
			
		||||
		} else {
 | 
			
		||||
			// 減少 like 計數
 | 
			
		||||
			update = bson.M{"$inc": bson.M{"like": -1}}
 | 
			
		||||
		}
 | 
			
		||||
	} else if param.ReactionType == domain.LikeTypeDisLike {
 | 
			
		||||
		if param.IsIncrement {
 | 
			
		||||
			// 增加 dislike 計數
 | 
			
		||||
			update = bson.M{"$inc": bson.M{"dislike": 1}}
 | 
			
		||||
		} else {
 | 
			
		||||
			// 減少 dislike 計數
 | 
			
		||||
			update = bson.M{"$inc": bson.M{"dislike": -1}}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 執行更新操作
 | 
			
		||||
	key := prefixPostCacheKey + param.PostID
 | 
			
		||||
	_, err := c.conn.UpdateOne(ctx, key, filter, update)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err // 返回錯誤信息
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil // 成功返回 nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,8 +46,14 @@ func (s *PostServiceServer) ListPosts(ctx context.Context, in *tweeting.QueryPos
 | 
			
		|||
	return l.ListPosts(in)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IncDecLikeDislikeCount 增減數量
 | 
			
		||||
func (s *PostServiceServer) IncDecLikeDislikeCount(ctx context.Context, in *tweeting.IncDecLikeDislikeCountReq) (*tweeting.OKResp, error) {
 | 
			
		||||
	l := postservicelogic.NewIncDecLikeDislikeCountLogic(ctx, s.svcCtx)
 | 
			
		||||
	return l.IncDecLikeDislikeCount(in)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Like 點讚/取消讚 貼文
 | 
			
		||||
func (s *PostServiceServer) Like(ctx context.Context, in *tweeting.LikeReq) (*tweeting.OKResp, error) {
 | 
			
		||||
func (s *PostServiceServer) Like(ctx context.Context, in *tweeting.LikeReq) (*tweeting.PostReactionActionResp, error) {
 | 
			
		||||
	l := postservicelogic.NewLikeLogic(ctx, s.svcCtx)
 | 
			
		||||
	return l.Like(in)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue