2025-01-15 05:17:30 +00:00
|
|
|
package repository
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
2025-01-15 05:25:55 +00:00
|
|
|
"time"
|
|
|
|
|
2025-01-15 05:46:36 +00:00
|
|
|
"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"
|
|
|
|
|
2025-01-15 05:25:55 +00:00
|
|
|
mgo "code.30cm.net/digimon/library-go/mongo"
|
2025-01-15 05:17:30 +00:00
|
|
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
|
|
|
"github.com/zeromicro/go-zero/core/stores/mon"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
|
|
)
|
|
|
|
|
|
|
|
type CommentRepositoryParam struct {
|
|
|
|
Conf *mgo.Conf
|
|
|
|
CacheConf cache.CacheConf
|
|
|
|
DBOpts []mon.Option
|
|
|
|
CacheOpts []cache.Option
|
|
|
|
}
|
|
|
|
|
|
|
|
type CommentRepository struct {
|
|
|
|
DB mgo.DocumentDBWithCacheUseCase
|
|
|
|
}
|
|
|
|
|
|
|
|
func MustCommentRepository(param CommentRepositoryParam) repository.CommentRepository {
|
|
|
|
e := entity.Comments{}
|
|
|
|
documentDB, err := mgo.MustDocumentDBWithCache(
|
|
|
|
param.Conf,
|
|
|
|
e.CollectionName(),
|
|
|
|
param.CacheConf,
|
|
|
|
param.DBOpts,
|
|
|
|
param.CacheOpts,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &CommentRepository{
|
|
|
|
DB: documentDB,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (repo *CommentRepository) CreateComment(ctx context.Context, comment *entity.Comments) error {
|
|
|
|
now := time.Now().UTC().UnixNano()
|
|
|
|
if comment.ID.IsZero() {
|
|
|
|
comment.ID = primitive.NewObjectID()
|
|
|
|
comment.CreatedAt = now
|
|
|
|
comment.UpdatedAt = now
|
|
|
|
}
|
|
|
|
|
|
|
|
rk := domain.GetCommentRedisKey(comment.ID.Hex())
|
|
|
|
_, err := repo.DB.InsertOne(ctx, rk, comment)
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (repo *CommentRepository) DeleteCommentByID(ctx context.Context, id string) error {
|
|
|
|
oid, err := primitive.ObjectIDFromHex(id)
|
|
|
|
if err != nil {
|
|
|
|
return ErrInvalidObjectID
|
|
|
|
}
|
|
|
|
|
|
|
|
rk := domain.GetCommentRedisKey(id)
|
|
|
|
_, err = repo.DB.DeleteOne(ctx, rk, bson.M{"_id": oid})
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (repo *CommentRepository) UpdateCommentMessage(ctx context.Context, id string, message string) error {
|
|
|
|
// 驗證 ObjectID 是否有效
|
|
|
|
oid, err := primitive.ObjectIDFromHex(id)
|
|
|
|
if err != nil {
|
|
|
|
return ErrInvalidObjectID
|
|
|
|
}
|
|
|
|
|
|
|
|
// 初始化更新字段
|
|
|
|
updates := bson.M{
|
|
|
|
"message": message, // 更新留言內容
|
|
|
|
"updated_at": time.Now().UTC().UnixNano(), // 更新時間
|
|
|
|
}
|
|
|
|
|
|
|
|
// 查詢條件:根據 _id 查詢
|
|
|
|
filter := bson.M{
|
|
|
|
"_id": oid,
|
|
|
|
}
|
|
|
|
|
|
|
|
rk := domain.GetCommentRedisKey(id)
|
|
|
|
// 執行更新操作
|
|
|
|
res, err := repo.DB.UpdateOne(ctx, rk, filter, bson.M{"$set": updates})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// 驗證是否有匹配的記錄被更新
|
|
|
|
if res.MatchedCount == 0 {
|
|
|
|
return ErrNotFound
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (repo *CommentRepository) ListComments(ctx context.Context, req repository.ListCommentRequest) ([]*entity.Comments, int64, error) {
|
|
|
|
// 構建查詢過濾器
|
|
|
|
filter := bson.M{}
|
|
|
|
if req.ParentID != nil {
|
|
|
|
filter["parent_comment_id"] = req.ParentID
|
2025-01-15 07:16:58 +00:00
|
|
|
} else {
|
|
|
|
filter["parent_comment_id"] = bson.M{
|
|
|
|
"$in": []interface{}{"", nil},
|
|
|
|
}
|
2025-01-15 05:17:30 +00:00
|
|
|
}
|
2025-01-15 07:16:58 +00:00
|
|
|
|
2025-01-15 05:17:30 +00:00
|
|
|
if req.ReferenceID != nil {
|
|
|
|
filter["reference_id"] = req.ReferenceID
|
|
|
|
}
|
|
|
|
|
|
|
|
// 設置排序選項
|
|
|
|
opts := options.Find().SetSkip((req.PageIndex - 1) * req.PageSize).SetLimit(req.PageSize)
|
|
|
|
opts.SetSort(bson.D{{Key: "created_at", Value: -1}})
|
|
|
|
|
|
|
|
// 查詢符合條件的總數
|
|
|
|
count, err := repo.DB.GetClient().CountDocuments(ctx, filter)
|
|
|
|
if err != nil {
|
|
|
|
return nil, 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// 執行查詢並獲取結果
|
|
|
|
var data []*entity.Comments
|
|
|
|
err = repo.DB.GetClient().Find(ctx, &data, filter, opts)
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case err == nil:
|
|
|
|
return data, count, nil
|
|
|
|
case errors.Is(err, mon.ErrNotFound):
|
|
|
|
return nil, 0, ErrNotFound
|
|
|
|
default:
|
|
|
|
return nil, 0, err
|
|
|
|
}
|
|
|
|
}
|