feature/post #1
|
@ -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
|
||||
|
||||
return &tweeting.LikeCountResp{}, nil
|
||||
// 驗證資料
|
||||
if err := l.svcCtx.Validate.ValidateAll(&countLikeReq{
|
||||
PostID: in.GetTargetId(),
|
||||
ReactionType: domain.LikeType(in.GetLikeType()),
|
||||
}); err != nil {
|
||||
return nil, ers.InvalidFormat(err.Error())
|
||||
}
|
||||
|
||||
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