package repository import ( "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" "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 } else { filter["parent_comment_id"] = bson.M{ "$in": []interface{}{"", nil}, } } 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 } }