Compare commits

..

No commits in common. "master" and "v0.0.2" have entirely different histories.

6 changed files with 25 additions and 66 deletions

View File

@ -14,7 +14,6 @@ type Comments struct {
ParentCommentID string `bson:"parent_comment_id"` // 父留言 id沒有就空白 ParentCommentID string `bson:"parent_comment_id"` // 父留言 id沒有就空白
Message string `bson:"message"` // 留言內容 Message string `bson:"message"` // 留言內容
Level comment.Level `bson:"level"` // 等級,數字較小的為上層 Level comment.Level `bson:"level"` // 等級,數字較小的為上層
IsVisitable bool `bson:"is_visitable"` // 是否隱藏
UpdatedAt int64 `bson:"updated_at"` // 更新時間 UpdatedAt int64 `bson:"updated_at"` // 更新時間
CreatedAt int64 `bson:"created_at"` // 建立時間 CreatedAt int64 `bson:"created_at"` // 建立時間
} }

View File

@ -10,9 +10,8 @@ import (
type CommentRepository interface { type CommentRepository interface {
CreateComment(ctx context.Context, comment *entity.Comments) error // 新增留言 // 根據 ID 獲取單條留言 CreateComment(ctx context.Context, comment *entity.Comments) error // 新增留言 // 根據 ID 獲取單條留言
DeleteCommentByID(ctx context.Context, id string) error // 根據 ID 刪除留言 // 刪除某留言的所有子留言 DeleteCommentByID(ctx context.Context, id string) error // 根據 ID 刪除留言 // 刪除某留言的所有子留言
UpdateCommentMessage(ctx context.Context, id string, message string, isVisitable bool) error // 更新留言內容 UpdateCommentMessage(ctx context.Context, id string, message string) error // 更新留言內容
ListComments(ctx context.Context, req ListCommentRequest) ([]*entity.Comments, int64, error) // 分頁列出留言 ListComments(ctx context.Context, req ListCommentRequest) ([]*entity.Comments, int64, error) // 分頁列出留言
GetCommentByID(ctx context.Context, id string) (*entity.Comments, error)
} }
type ListCommentRequest struct { type ListCommentRequest struct {
@ -21,5 +20,4 @@ type ListCommentRequest struct {
ReferenceID *string ReferenceID *string
ParentID *string ParentID *string
Level comment.Level Level comment.Level
IsVisitable *bool
} }

View File

@ -14,7 +14,7 @@ type CommentUseCase interface {
// RemoveCommentItem 移除 CommentItem 列表 // RemoveCommentItem 移除 CommentItem 列表
RemoveCommentItem(ctx context.Context, id string) error RemoveCommentItem(ctx context.Context, id string) error
// UpdateCommentMessage 更新 // UpdateCommentMessage 更新
UpdateCommentMessage(ctx context.Context, id string, message string, isVisitable bool) error UpdateCommentMessage(ctx context.Context, id string, message string) error
} }
type CreateCommentDocs struct { type CreateCommentDocs struct {
@ -22,7 +22,6 @@ type CreateCommentDocs struct {
ReferenceID string `bson:"reference_id"` // 參考的 id ex product_id or product_item_id 之類的 ReferenceID string `bson:"reference_id"` // 參考的 id ex product_id or product_item_id 之類的
ParentCommentID string `bson:"parent_comment_id"` // 父留言 id 沒有就空白 ParentCommentID string `bson:"parent_comment_id"` // 父留言 id 沒有就空白
Message string `bson:"message"` // 留言內容 Message string `bson:"message"` // 留言內容
IsVisitable bool `bson:"is_visitable"` // 是否可見
} }
type CommentDocs struct { type CommentDocs struct {
@ -32,7 +31,6 @@ type CommentDocs struct {
ParentCommentID string `json:"parent_comment_id"` // 父留言 id 沒有就空白 ParentCommentID string `json:"parent_comment_id"` // 父留言 id 沒有就空白
Message string `json:"message"` // 留言內容 Message string `json:"message"` // 留言內容
Replies []*CommentDocs `json:"replies"` // 子留言 Replies []*CommentDocs `json:"replies"` // 子留言
IsVisitable bool `json:"is_visitable"` // 留言是否可見
UpdatedAt int64 `json:"updated_at"` // 更新時間 UpdatedAt int64 `json:"updated_at"` // 更新時間
CreatedAt int64 `json:"created_at"` // 建立時間 CreatedAt int64 `json:"created_at"` // 建立時間
} }
@ -43,5 +41,4 @@ type ListCommentRequest struct {
ReferenceID *string ReferenceID *string
ParentID *string ParentID *string
IsSub bool IsSub bool
IsVisitable *bool
} }

View File

@ -25,8 +25,6 @@ type MockCommentRepository struct {
isgomock struct{} isgomock struct{}
} }
// MockCommentRepositoryMockRecorder is the mock recorder for MockCommentRepository. // MockCommentRepositoryMockRecorder is the mock recorder for MockCommentRepository.
type MockCommentRepositoryMockRecorder struct { type MockCommentRepositoryMockRecorder struct {
mock *MockCommentRepository mock *MockCommentRepository

View File

@ -72,23 +72,7 @@ func (repo *CommentRepository) DeleteCommentByID(ctx context.Context, id string)
return err return err
} }
func (repo *CommentRepository) GetCommentByID(ctx context.Context, id string) (*entity.Comments, error) { func (repo *CommentRepository) UpdateCommentMessage(ctx context.Context, id string, message string) error {
oid, err := primitive.ObjectIDFromHex(id)
if err != nil {
return nil, ErrInvalidObjectID
}
result := entity.Comments{}
rk := domain.GetCommentRedisKey(id)
err = repo.DB.FindOne(ctx, rk, &result, bson.M{"_id": oid})
if err != nil {
return nil, err
}
return &result, nil
}
func (repo *CommentRepository) UpdateCommentMessage(ctx context.Context, id string, message string, isVisitable bool) error {
// 驗證 ObjectID 是否有效 // 驗證 ObjectID 是否有效
oid, err := primitive.ObjectIDFromHex(id) oid, err := primitive.ObjectIDFromHex(id)
if err != nil { if err != nil {
@ -97,9 +81,8 @@ func (repo *CommentRepository) UpdateCommentMessage(ctx context.Context, id stri
// 初始化更新字段 // 初始化更新字段
updates := bson.M{ updates := bson.M{
"message": message, // 更新留言內容 "message": message, // 更新留言內容
"is_visitable": isVisitable, "updated_at": time.Now().UTC().UnixNano(), // 更新時間
"updated_at": time.Now().UTC().UnixNano(), // 更新時間
} }
// 查詢條件:根據 _id 查詢 // 查詢條件:根據 _id 查詢
@ -127,20 +110,11 @@ func (repo *CommentRepository) ListComments(ctx context.Context, req repository.
filter := bson.M{} filter := bson.M{}
if req.ParentID != nil { if req.ParentID != nil {
filter["parent_comment_id"] = req.ParentID filter["parent_comment_id"] = req.ParentID
} else {
filter["parent_comment_id"] = bson.M{
"$in": []interface{}{"", nil},
}
} }
if req.ReferenceID != nil { if req.ReferenceID != nil {
filter["reference_id"] = req.ReferenceID filter["reference_id"] = req.ReferenceID
} }
if req.IsVisitable != nil {
filter["is_visitable"] = req.IsVisitable
}
// 設置排序選項 // 設置排序選項
opts := options.Find().SetSkip((req.PageIndex - 1) * req.PageSize).SetLimit(req.PageSize) opts := options.Find().SetSkip((req.PageIndex - 1) * req.PageSize).SetLimit(req.PageSize)
opts.SetSort(bson.D{{Key: "created_at", Value: -1}}) opts.SetSort(bson.D{{Key: "created_at", Value: -1}})

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"google.golang.org/protobuf/proto"
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain" "code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain"
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/comment" "code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/comment"
@ -38,7 +37,6 @@ func (use *CommentUseCase) CreateCommentItem(ctx context.Context, info usecase.C
UID: info.UID, UID: info.UID,
ReferenceID: info.ReferenceID, ReferenceID: info.ReferenceID,
Level: comment.TopLevelComment, Level: comment.TopLevelComment,
IsVisitable: true,
} }
snappyContent := snappy.Encode(nil, []byte(info.Message)) snappyContent := snappy.Encode(nil, []byte(info.Message))
insert.Message = base64.StdEncoding.EncodeToString(snappyContent) insert.Message = base64.StdEncoding.EncodeToString(snappyContent)
@ -66,7 +64,11 @@ func (use *CommentUseCase) CreateCommentItem(ctx context.Context, info usecase.C
} }
func (use *CommentUseCase) GetCommentItem(ctx context.Context, id string) (*usecase.CommentDocs, error) { func (use *CommentUseCase) GetCommentItem(ctx context.Context, id string) (*usecase.CommentDocs, error) {
byID, err := use.Comment.GetCommentByID(ctx, id) item, _, err := use.Comment.ListComments(ctx, repository.ListCommentRequest{
ReferenceID: &id,
PageIndex: 1,
PageSize: 20,
})
if err != nil { if err != nil {
return nil, errs.DatabaseErrorWithScopeL( return nil, errs.DatabaseErrorWithScopeL(
code.CloudEPComment, code.CloudEPComment,
@ -77,30 +79,26 @@ func (use *CommentUseCase) GetCommentItem(ctx context.Context, id string) (*usec
{Key: "func", Value: "Comment.ListComments"}, {Key: "func", Value: "Comment.ListComments"},
{Key: "err", Value: err.Error()}, {Key: "err", Value: err.Error()},
}, },
"failed to get byID").Wrap(err) "failed to get comment").Wrap(err)
} }
decodeB64Content, _ := base64.StdEncoding.DecodeString(byID.Message) decodeB64Content, _ := base64.StdEncoding.DecodeString(item[0].Message)
snappyContent, _ := snappy.Decode(nil, decodeB64Content) snappyContent, _ := snappy.Decode(nil, decodeB64Content)
byID.Message = string(snappyContent) item[0].Message = string(snappyContent)
return &usecase.CommentDocs{ return &usecase.CommentDocs{
ID: byID.ID.Hex(), ID: item[0].ID.Hex(),
UID: byID.UID, UID: item[0].UID,
ReferenceID: byID.ReferenceID, ReferenceID: item[0].ReferenceID,
ParentCommentID: byID.ParentCommentID, ParentCommentID: item[0].ParentCommentID,
Message: byID.Message, Message: item[0].Message,
IsVisitable: byID.IsVisitable, UpdatedAt: item[0].UpdatedAt,
UpdatedAt: byID.UpdatedAt, CreatedAt: item[0].CreatedAt,
CreatedAt: byID.CreatedAt,
}, nil }, nil
} }
func (use *CommentUseCase) UpdateCommentMessage(ctx context.Context, id string, message string, isVisitable bool) error { func (use *CommentUseCase) UpdateCommentMessage(ctx context.Context, id string, message string) error {
snappyContent := snappy.Encode(nil, []byte(message)) err := use.Comment.UpdateCommentMessage(ctx, id, message)
msg := base64.StdEncoding.EncodeToString(snappyContent)
err := use.Comment.UpdateCommentMessage(ctx, id, msg, isVisitable)
if err != nil { if err != nil {
return errs.DatabaseErrorWithScopeL( return errs.DatabaseErrorWithScopeL(
code.CloudEPComment, code.CloudEPComment,
@ -143,9 +141,7 @@ func (use *CommentUseCase) ListComment(ctx context.Context, req usecase.ListComm
PageSize: req.PageSize, PageSize: req.PageSize,
PageIndex: req.PageIndex, PageIndex: req.PageIndex,
ReferenceID: req.ReferenceID, ReferenceID: req.ReferenceID,
IsVisitable: req.IsVisitable,
}) })
if err != nil { if err != nil {
return nil, 0, errs.DatabaseErrorWithScopeL( return nil, 0, errs.DatabaseErrorWithScopeL(
code.CloudEPComment, code.CloudEPComment,
@ -179,7 +175,6 @@ func (use *CommentUseCase) ListComment(ctx context.Context, req usecase.ListComm
Message: decodedMessage, Message: decodedMessage,
UpdatedAt: item.UpdatedAt, UpdatedAt: item.UpdatedAt,
CreatedAt: item.CreatedAt, CreatedAt: item.CreatedAt,
IsVisitable: item.IsVisitable,
Replies: replyMap[item.ID.Hex()], Replies: replyMap[item.ID.Hex()],
}) })
} }
@ -194,10 +189,9 @@ func (use *CommentUseCase) buildReplies(ctx context.Context, parentComments []*e
for _, item := range parentComments { for _, item := range parentComments {
id := item.ID.Hex() id := item.ID.Hex()
subComments, _, err := use.Comment.ListComments(ctx, repository.ListCommentRequest{ subComments, _, err := use.Comment.ListComments(ctx, repository.ListCommentRequest{
ParentID: &id, ParentID: &id,
PageSize: 20, PageSize: 20,
PageIndex: 1, // 可調整分頁大小 PageIndex: 1, // 可調整分頁大小
IsVisitable: proto.Bool(item.IsVisitable),
}) })
if err != nil { if err != nil {
continue continue
@ -215,7 +209,6 @@ func (use *CommentUseCase) buildReplies(ctx context.Context, parentComments []*e
UID: sub.UID, UID: sub.UID,
ReferenceID: sub.ReferenceID, ReferenceID: sub.ReferenceID,
ParentCommentID: sub.ParentCommentID, ParentCommentID: sub.ParentCommentID,
IsVisitable: sub.IsVisitable,
Message: decodedMessage, Message: decodedMessage,
UpdatedAt: sub.UpdatedAt, UpdatedAt: sub.UpdatedAt,
CreatedAt: sub.CreatedAt, CreatedAt: sub.CreatedAt,