Compare commits
6 Commits
Author | SHA1 | Date |
---|---|---|
|
0dcd5fcf11 | |
|
0010f216f3 | |
|
283d196f6b | |
|
35b850d53d | |
|
efff638ab5 | |
|
56145d71af |
|
@ -7,7 +7,7 @@ package comment
|
|||
import (
|
||||
"context"
|
||||
|
||||
"app-cloudep-comment-server/gen_result/pb/comment"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/gen_result/pb/comment"
|
||||
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
"google.golang.org/grpc"
|
||||
|
|
|
@ -5,10 +5,10 @@ import (
|
|||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"app-cloudep-comment-server/gen_result/pb/comment"
|
||||
"app-cloudep-comment-server/internal/config"
|
||||
commentServer "app-cloudep-comment-server/internal/server/comment"
|
||||
"app-cloudep-comment-server/internal/svc"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/gen_result/pb/comment"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/internal/config"
|
||||
commentServer "code.30cm.net/digimon/app-cloudep-comment-server/internal/server/comment"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/conf"
|
||||
"github.com/zeromicro/go-zero/core/service"
|
||||
|
|
2
go.mod
2
go.mod
|
@ -1,4 +1,4 @@
|
|||
module app-cloudep-comment-server
|
||||
module code.30cm.net/digimon/app-cloudep-comment-server
|
||||
|
||||
go 1.23.4
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ package commentlogic
|
|||
import (
|
||||
"context"
|
||||
|
||||
"app-cloudep-comment-server/gen_result/pb/comment"
|
||||
"app-cloudep-comment-server/internal/svc"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/gen_result/pb/comment"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
|
|
@ -7,9 +7,9 @@ package server
|
|||
import (
|
||||
"context"
|
||||
|
||||
"app-cloudep-comment-server/gen_result/pb/comment"
|
||||
commentlogic "app-cloudep-comment-server/internal/logic/comment"
|
||||
"app-cloudep-comment-server/internal/svc"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/gen_result/pb/comment"
|
||||
commentlogic "code.30cm.net/digimon/app-cloudep-comment-server/internal/logic/comment"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/internal/svc"
|
||||
)
|
||||
|
||||
type CommentServer struct {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package svc
|
||||
|
||||
import "app-cloudep-comment-server/internal/config"
|
||||
import "code.30cm.net/digimon/app-cloudep-comment-server/internal/config"
|
||||
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package entity
|
||||
|
||||
import (
|
||||
"app-cloudep-comment-server/pkg/domain/comment"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/comment"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
@ -14,6 +14,7 @@ type Comments struct {
|
|||
ParentCommentID string `bson:"parent_comment_id"` // 父留言 id,沒有就空白
|
||||
Message string `bson:"message"` // 留言內容
|
||||
Level comment.Level `bson:"level"` // 等級,數字較小的為上層
|
||||
IsVisitable bool `bson:"is_visitable"` // 是否隱藏
|
||||
UpdatedAt int64 `bson:"updated_at"` // 更新時間
|
||||
CreatedAt int64 `bson:"created_at"` // 建立時間
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"app-cloudep-comment-server/pkg/domain/comment"
|
||||
"app-cloudep-comment-server/pkg/domain/entity"
|
||||
"context"
|
||||
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/comment"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/entity"
|
||||
)
|
||||
|
||||
type CommentRepository interface {
|
||||
CreateComment(ctx context.Context, comment *entity.Comments) error // 新增留言 // 根據 ID 獲取單條留言
|
||||
DeleteCommentByID(ctx context.Context, id string) error // 根據 ID 刪除留言 // 刪除某留言的所有子留言
|
||||
UpdateCommentMessage(ctx context.Context, id string, message string) error // 更新留言內容
|
||||
UpdateCommentMessage(ctx context.Context, id string, message string, isVisitable bool) error // 更新留言內容
|
||||
ListComments(ctx context.Context, req ListCommentRequest) ([]*entity.Comments, int64, error) // 分頁列出留言
|
||||
GetCommentByID(ctx context.Context, id string) (*entity.Comments, error)
|
||||
}
|
||||
|
||||
type ListCommentRequest struct {
|
||||
|
@ -19,4 +21,5 @@ type ListCommentRequest struct {
|
|||
ReferenceID *string
|
||||
ParentID *string
|
||||
Level comment.Level
|
||||
IsVisitable *bool
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ type CommentUseCase interface {
|
|||
// RemoveCommentItem 移除 CommentItem 列表
|
||||
RemoveCommentItem(ctx context.Context, id string) error
|
||||
// UpdateCommentMessage 更新
|
||||
UpdateCommentMessage(ctx context.Context, id string, message string) error
|
||||
UpdateCommentMessage(ctx context.Context, id string, message string, isVisitable bool) error
|
||||
}
|
||||
|
||||
type CreateCommentDocs struct {
|
||||
|
@ -22,6 +22,7 @@ type CreateCommentDocs struct {
|
|||
ReferenceID string `bson:"reference_id"` // 參考的 id ex product_id or product_item_id 之類的
|
||||
ParentCommentID string `bson:"parent_comment_id"` // 父留言 id 沒有就空白
|
||||
Message string `bson:"message"` // 留言內容
|
||||
IsVisitable bool `bson:"is_visitable"` // 是否可見
|
||||
}
|
||||
|
||||
type CommentDocs struct {
|
||||
|
@ -31,6 +32,7 @@ type CommentDocs struct {
|
|||
ParentCommentID string `json:"parent_comment_id"` // 父留言 id 沒有就空白
|
||||
Message string `json:"message"` // 留言內容
|
||||
Replies []*CommentDocs `json:"replies"` // 子留言
|
||||
IsVisitable bool `json:"is_visitable"` // 留言是否可見
|
||||
UpdatedAt int64 `json:"updated_at"` // 更新時間
|
||||
CreatedAt int64 `json:"created_at"` // 建立時間
|
||||
}
|
||||
|
@ -41,4 +43,5 @@ type ListCommentRequest struct {
|
|||
ReferenceID *string
|
||||
ParentID *string
|
||||
IsSub bool
|
||||
IsVisitable *bool
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
package mock
|
||||
|
||||
import (
|
||||
entity "app-cloudep-comment-server/pkg/domain/entity"
|
||||
repository "app-cloudep-comment-server/pkg/domain/repository"
|
||||
entity "code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/entity"
|
||||
repository "code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/repository"
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
|
@ -25,6 +25,8 @@ type MockCommentRepository struct {
|
|||
isgomock struct{}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MockCommentRepositoryMockRecorder is the mock recorder for MockCommentRepository.
|
||||
type MockCommentRepositoryMockRecorder struct {
|
||||
mock *MockCommentRepository
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"app-cloudep-comment-server/pkg/domain"
|
||||
"app-cloudep-comment-server/pkg/domain/entity"
|
||||
"app-cloudep-comment-server/pkg/domain/repository"
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/entity"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/repository"
|
||||
|
||||
mgo "code.30cm.net/digimon/library-go/mongo"
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||
|
@ -71,7 +72,23 @@ func (repo *CommentRepository) DeleteCommentByID(ctx context.Context, id string)
|
|||
return err
|
||||
}
|
||||
|
||||
func (repo *CommentRepository) UpdateCommentMessage(ctx context.Context, id string, message string) error {
|
||||
func (repo *CommentRepository) GetCommentByID(ctx context.Context, id string) (*entity.Comments, 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 是否有效
|
||||
oid, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
|
@ -81,6 +98,7 @@ func (repo *CommentRepository) UpdateCommentMessage(ctx context.Context, id stri
|
|||
// 初始化更新字段
|
||||
updates := bson.M{
|
||||
"message": message, // 更新留言內容
|
||||
"is_visitable": isVisitable,
|
||||
"updated_at": time.Now().UTC().UnixNano(), // 更新時間
|
||||
}
|
||||
|
||||
|
@ -109,11 +127,20 @@ func (repo *CommentRepository) ListComments(ctx context.Context, req repository.
|
|||
filter := bson.M{}
|
||||
if req.ParentID != nil {
|
||||
filter["parent_comment_id"] = req.ParentID
|
||||
} else {
|
||||
filter["parent_comment_id"] = bson.M{
|
||||
"$in": []interface{}{"", nil},
|
||||
}
|
||||
}
|
||||
|
||||
if req.ReferenceID != nil {
|
||||
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.SetSort(bson.D{{Key: "created_at", Value: -1}})
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"app-cloudep-comment-server/pkg/domain/entity"
|
||||
"app-cloudep-comment-server/pkg/domain/repository"
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/entity"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/repository"
|
||||
|
||||
mgo "code.30cm.net/digimon/library-go/mongo"
|
||||
"github.com/alicebob/miniredis/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
package usecase
|
||||
|
||||
import (
|
||||
"app-cloudep-comment-server/pkg/domain"
|
||||
"app-cloudep-comment-server/pkg/domain/comment"
|
||||
"app-cloudep-comment-server/pkg/domain/entity"
|
||||
"app-cloudep-comment-server/pkg/domain/repository"
|
||||
"app-cloudep-comment-server/pkg/domain/usecase"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"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/comment"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/entity"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/repository"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/usecase"
|
||||
|
||||
"github.com/golang/snappy"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
@ -36,6 +38,7 @@ func (use *CommentUseCase) CreateCommentItem(ctx context.Context, info usecase.C
|
|||
UID: info.UID,
|
||||
ReferenceID: info.ReferenceID,
|
||||
Level: comment.TopLevelComment,
|
||||
IsVisitable: true,
|
||||
}
|
||||
snappyContent := snappy.Encode(nil, []byte(info.Message))
|
||||
insert.Message = base64.StdEncoding.EncodeToString(snappyContent)
|
||||
|
@ -63,11 +66,7 @@ func (use *CommentUseCase) CreateCommentItem(ctx context.Context, info usecase.C
|
|||
}
|
||||
|
||||
func (use *CommentUseCase) GetCommentItem(ctx context.Context, id string) (*usecase.CommentDocs, error) {
|
||||
item, _, err := use.Comment.ListComments(ctx, repository.ListCommentRequest{
|
||||
ReferenceID: &id,
|
||||
PageIndex: 1,
|
||||
PageSize: 20,
|
||||
})
|
||||
byID, err := use.Comment.GetCommentByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, errs.DatabaseErrorWithScopeL(
|
||||
code.CloudEPComment,
|
||||
|
@ -78,26 +77,30 @@ func (use *CommentUseCase) GetCommentItem(ctx context.Context, id string) (*usec
|
|||
{Key: "func", Value: "Comment.ListComments"},
|
||||
{Key: "err", Value: err.Error()},
|
||||
},
|
||||
"failed to get comment").Wrap(err)
|
||||
"failed to get byID").Wrap(err)
|
||||
}
|
||||
|
||||
decodeB64Content, _ := base64.StdEncoding.DecodeString(item[0].Message)
|
||||
decodeB64Content, _ := base64.StdEncoding.DecodeString(byID.Message)
|
||||
snappyContent, _ := snappy.Decode(nil, decodeB64Content)
|
||||
item[0].Message = string(snappyContent)
|
||||
byID.Message = string(snappyContent)
|
||||
|
||||
return &usecase.CommentDocs{
|
||||
ID: item[0].ID.Hex(),
|
||||
UID: item[0].UID,
|
||||
ReferenceID: item[0].ReferenceID,
|
||||
ParentCommentID: item[0].ParentCommentID,
|
||||
Message: item[0].Message,
|
||||
UpdatedAt: item[0].UpdatedAt,
|
||||
CreatedAt: item[0].CreatedAt,
|
||||
ID: byID.ID.Hex(),
|
||||
UID: byID.UID,
|
||||
ReferenceID: byID.ReferenceID,
|
||||
ParentCommentID: byID.ParentCommentID,
|
||||
Message: byID.Message,
|
||||
IsVisitable: byID.IsVisitable,
|
||||
UpdatedAt: byID.UpdatedAt,
|
||||
CreatedAt: byID.CreatedAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (use *CommentUseCase) UpdateCommentMessage(ctx context.Context, id string, message string) error {
|
||||
err := use.Comment.UpdateCommentMessage(ctx, id, message)
|
||||
func (use *CommentUseCase) UpdateCommentMessage(ctx context.Context, id string, message string, isVisitable bool) error {
|
||||
snappyContent := snappy.Encode(nil, []byte(message))
|
||||
msg := base64.StdEncoding.EncodeToString(snappyContent)
|
||||
|
||||
err := use.Comment.UpdateCommentMessage(ctx, id, msg, isVisitable)
|
||||
if err != nil {
|
||||
return errs.DatabaseErrorWithScopeL(
|
||||
code.CloudEPComment,
|
||||
|
@ -140,7 +143,9 @@ func (use *CommentUseCase) ListComment(ctx context.Context, req usecase.ListComm
|
|||
PageSize: req.PageSize,
|
||||
PageIndex: req.PageIndex,
|
||||
ReferenceID: req.ReferenceID,
|
||||
IsVisitable: req.IsVisitable,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, 0, errs.DatabaseErrorWithScopeL(
|
||||
code.CloudEPComment,
|
||||
|
@ -174,6 +179,7 @@ func (use *CommentUseCase) ListComment(ctx context.Context, req usecase.ListComm
|
|||
Message: decodedMessage,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
CreatedAt: item.CreatedAt,
|
||||
IsVisitable: item.IsVisitable,
|
||||
Replies: replyMap[item.ID.Hex()],
|
||||
})
|
||||
}
|
||||
|
@ -191,6 +197,7 @@ func (use *CommentUseCase) buildReplies(ctx context.Context, parentComments []*e
|
|||
ParentID: &id,
|
||||
PageSize: 20,
|
||||
PageIndex: 1, // 可調整分頁大小
|
||||
IsVisitable: proto.Bool(item.IsVisitable),
|
||||
})
|
||||
if err != nil {
|
||||
continue
|
||||
|
@ -208,6 +215,7 @@ func (use *CommentUseCase) buildReplies(ctx context.Context, parentComments []*e
|
|||
UID: sub.UID,
|
||||
ReferenceID: sub.ReferenceID,
|
||||
ParentCommentID: sub.ParentCommentID,
|
||||
IsVisitable: sub.IsVisitable,
|
||||
Message: decodedMessage,
|
||||
UpdatedAt: sub.UpdatedAt,
|
||||
CreatedAt: sub.CreatedAt,
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
package usecase
|
||||
|
||||
import (
|
||||
"app-cloudep-comment-server/pkg/domain/comment"
|
||||
"app-cloudep-comment-server/pkg/domain/entity"
|
||||
"app-cloudep-comment-server/pkg/domain/repository"
|
||||
"app-cloudep-comment-server/pkg/domain/usecase"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/comment"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/entity"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/repository"
|
||||
"code.30cm.net/digimon/app-cloudep-comment-server/pkg/domain/usecase"
|
||||
|
||||
"github.com/golang/snappy"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
mockRepo "app-cloudep-comment-server/pkg/mock/repository"
|
||||
err "app-cloudep-comment-server/pkg/repository"
|
||||
mockRepo "code.30cm.net/digimon/app-cloudep-comment-server/pkg/mock/repository"
|
||||
err "code.30cm.net/digimon/app-cloudep-comment-server/pkg/repository"
|
||||
)
|
||||
|
||||
func TestCommentUseCase_CreateCommentItem(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue