feature/post #1
|
@ -130,7 +130,7 @@ message LikeCountReq {
|
||||||
|
|
||||||
// 讚/不讚數量回應
|
// 讚/不讚數量回應
|
||||||
message LikeCountResp {
|
message LikeCountResp {
|
||||||
string count = 1; // 總共按讚數量
|
int64 count = 1; // 總共按讚數量
|
||||||
}
|
}
|
||||||
|
|
||||||
// 評論貼文的請求
|
// 評論貼文的請求
|
||||||
|
@ -174,6 +174,18 @@ message UpdateCommentReq {
|
||||||
string content = 2; // 更新後的評論內容
|
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 {
|
service PostService {
|
||||||
// NewPost 新增貼文
|
// NewPost 新增貼文
|
||||||
|
@ -184,9 +196,11 @@ service PostService {
|
||||||
rpc UpdatePost(UpdatePostReq) returns (OKResp);
|
rpc UpdatePost(UpdatePostReq) returns (OKResp);
|
||||||
// ListPosts 查詢貼文
|
// ListPosts 查詢貼文
|
||||||
rpc ListPosts(QueryPostsReq) returns (ListPostsResp);
|
rpc ListPosts(QueryPostsReq) returns (ListPostsResp);
|
||||||
|
// IncDecLikeDislikeCount 增減數量
|
||||||
|
rpc IncDecLikeDislikeCount(IncDecLikeDislikeCountReq) returns (OKResp);
|
||||||
|
|
||||||
// Like 點讚/取消讚 貼文
|
// Like 點讚/取消讚 貼文
|
||||||
rpc Like(LikeReq) returns (OKResp);
|
rpc Like(LikeReq) returns (PostReactionActionResp);
|
||||||
// GetLikeStatus 取得讚/不讚狀態
|
// GetLikeStatus 取得讚/不讚狀態
|
||||||
rpc GetLikeStatus(GetLikeStatusReq) returns (GetLikeStatusResp);
|
rpc GetLikeStatus(GetLikeStatusReq) returns (GetLikeStatusResp);
|
||||||
// LikeList 取得讚/不讚列表
|
// LikeList 取得讚/不讚列表
|
||||||
|
|
|
@ -14,7 +14,7 @@ const (
|
||||||
|
|
||||||
type LikeType int8
|
type LikeType int8
|
||||||
|
|
||||||
func (l LikeType) ToInt32() int8 {
|
func (l LikeType) ToInt8() int8 {
|
||||||
return int8(l)
|
return int8(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package postservicelogic
|
package postservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
|
|
||||||
"app-cloudep-tweeting-service/gen_result/pb/tweeting"
|
"app-cloudep-tweeting-service/gen_result/pb/tweeting"
|
||||||
|
"app-cloudep-tweeting-service/internal/domain"
|
||||||
"app-cloudep-tweeting-service/internal/svc"
|
"app-cloudep-tweeting-service/internal/svc"
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"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 取得讚/不讚數量
|
// CountLike 取得讚/不讚數量
|
||||||
func (l *CountLikeLogic) CountLike(in *tweeting.LikeCountReq) (*tweeting.LikeCountResp, error) {
|
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{
|
||||||
return &tweeting.LikeCountResp{}, nil
|
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 {
|
type likeReq struct {
|
||||||
Target string `json:"target" validate:"required"`
|
Target string `json:"target" validate:"required"`
|
||||||
UID string `json:"uid" validate:"required"`
|
UID string `json:"uid" validate:"required"`
|
||||||
LikeType domain.LikeType `json:"like_type" validate:"required,oneof=1 2"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like 點讚/取消讚 貼文
|
// 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{
|
if err := l.svcCtx.Validate.ValidateAll(&likeReq{
|
||||||
Target: in.TargetId,
|
Target: in.TargetId,
|
||||||
UID: in.GetUid(),
|
UID: in.GetUid(),
|
||||||
LikeType: domain.LikeType(in.GetLikeType()),
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, ers.InvalidFormat(err.Error())
|
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(),
|
TargetID: in.GetTargetId(),
|
||||||
UID: in.GetUid(),
|
UID: in.GetUid(),
|
||||||
Type: int8(in.GetLikeType()),
|
Type: int8(in.GetLikeType()),
|
||||||
|
@ -60,5 +58,11 @@ func (l *LikeLogic) Like(in *tweeting.LikeReq) (*tweeting.OKResp, error) {
|
||||||
return nil, e
|
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.
|
// and implement the added methods in customPost_likesModel.
|
||||||
Post_likesModel interface {
|
Post_likesModel interface {
|
||||||
post_likesModel
|
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)
|
FindLikeUsers(ctx context.Context, param *QueryPostLikeReq) ([]*PostLikes, int64, error)
|
||||||
FindUIDPostLikeStatus(ctx context.Context, param *QueryUIDPostLikeStatusReq) ([]UIDPostLikeStatusResp, 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 {
|
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 來查詢資料是否存在
|
// 使用 target_id、uid、type 來查詢資料是否存在
|
||||||
filter := bson.M{
|
filter := bson.M{
|
||||||
"target_id": postLike.TargetID,
|
"target_id": postLike.TargetID,
|
||||||
|
@ -69,23 +81,27 @@ func (m *defaultPost_likesModel) LikeDislike(ctx context.Context, postLike *Post
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// 資料存在,進行刪除操作
|
// 資料存在,進行刪除操作
|
||||||
|
result.IsIncrement = false
|
||||||
_, err = m.conn.DeleteOne(ctx, filter)
|
_, err = m.conn.DeleteOne(ctx, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err // 刪除失敗
|
return nil, err // 刪除失敗
|
||||||
}
|
}
|
||||||
return nil // 刪除成功
|
|
||||||
|
return result, nil // 刪除成功
|
||||||
} else if errors.Is(mongo.ErrNoDocuments, err) {
|
} else if errors.Is(mongo.ErrNoDocuments, err) {
|
||||||
// 資料不存在,進行插入操作
|
// 資料不存在,進行插入操作
|
||||||
|
result.IsIncrement = true
|
||||||
postLike.ID = primitive.NewObjectID() // 設置新的 ObjectID
|
postLike.ID = primitive.NewObjectID() // 設置新的 ObjectID
|
||||||
postLike.CreateAt = time.Now().UTC().UnixNano()
|
postLike.CreateAt = time.Now().UTC().UnixNano()
|
||||||
_, err = m.conn.InsertOne(ctx, postLike)
|
_, err = m.conn.InsertOne(ctx, postLike)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err // 插入失敗
|
return nil, err // 插入失敗
|
||||||
}
|
}
|
||||||
return nil // 插入成功
|
|
||||||
|
return result, nil // 插入成功
|
||||||
} else {
|
} else {
|
||||||
// 其他錯誤
|
// 其他錯誤
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,3 +187,8 @@ func (m *defaultPost_likesModel) FindUIDPostLikeStatus(ctx context.Context, para
|
||||||
|
|
||||||
return results, nil
|
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
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-tweeting-service/internal/domain"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -24,6 +25,7 @@ type (
|
||||||
DeleteMany(ctx context.Context, id ...string) (int64, error)
|
DeleteMany(ctx context.Context, id ...string) (int64, error)
|
||||||
UpdateOptional(ctx context.Context, data *Post) (*mongo.UpdateResult, error)
|
UpdateOptional(ctx context.Context, data *Post) (*mongo.UpdateResult, error)
|
||||||
Find(ctx context.Context, param *QueryPostModelReq) ([]*Post, int64, error)
|
Find(ctx context.Context, param *QueryPostModelReq) ([]*Post, int64, error)
|
||||||
|
IncDecLikeDislikeCountLogic(ctx context.Context, param *PostReactionAction) error
|
||||||
}
|
}
|
||||||
|
|
||||||
customPostModel struct {
|
customPostModel struct {
|
||||||
|
@ -192,3 +194,39 @@ func (m *defaultPostModel) Find(ctx context.Context, param *QueryPostModelReq) (
|
||||||
return nil, 0, err
|
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)
|
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 點讚/取消讚 貼文
|
// 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)
|
l := postservicelogic.NewLikeLogic(ctx, s.svcCtx)
|
||||||
return l.Like(in)
|
return l.Like(in)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue