app-cloudep-product-service/pkg/repository/category.go

192 lines
5.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package repository
import (
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
mgo "code.30cm.net/digimon/library-go/mongo"
"context"
"errors"
"time"
"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"
"go.mongodb.org/mongo-driver/mongo/options"
)
type CategoryRepositoryParam struct {
Conf *mgo.Conf
CacheConf cache.CacheConf
DBOpts []mon.Option
CacheOpts []cache.Option
}
type CategoryRepository struct {
DB mgo.DocumentDBWithCacheUseCase
}
func MustCategoryRepository(param CategoryRepositoryParam) repository.CategoryRepository {
e := entity.Category{}
documentDB, err := mgo.MustDocumentDBWithCache(
param.Conf,
e.CollectionName(),
param.CacheConf,
param.DBOpts,
param.CacheOpts,
)
if err != nil {
panic(err)
}
return &CategoryRepository{
DB: documentDB,
}
}
func (repo *CategoryRepository) IsCategoryExists(ctx context.Context, ids []string) []string {
// 將傳入的 string id 轉換為 ObjectID
objectIDs := make([]primitive.ObjectID, 0, len(ids))
for _, id := range ids {
objID, err := primitive.ObjectIDFromHex(id)
if err == nil { // 如果轉換失敗,忽略該 id
objectIDs = append(objectIDs, objID)
}
}
// 查詢存在的標籤
filter := bson.M{"_id": bson.M{"$in": objectIDs}}
// find 並沒有快取要快取要去其他地方做
opts := options.Find().SetProjection(bson.M{"_id": 1}) // 只返回 _id 欄位
// 執行查詢並獲取結果
var category []*entity.Category
err := repo.DB.GetClient().Find(ctx, &category, filter, opts)
if err != nil {
return []string{}
}
// 將存在的標籤ID轉換回 string並加入結果列表
existingIDs := make([]string, 0, len(category))
for _, item := range category {
existingIDs = append(existingIDs, item.ID.Hex())
}
return existingIDs
}
func (repo *CategoryRepository) Insert(ctx context.Context, data *entity.Category) error {
now := time.Now().UTC().UnixNano()
if data.ID.IsZero() {
data.ID = primitive.NewObjectID()
data.CreatedAt = now
data.UpdatedAt = now
}
_, err := repo.DB.GetClient().InsertOne(ctx, data)
return err
}
func (repo *CategoryRepository) FindOneByID(ctx context.Context, id string) (*entity.Category, error) {
oid, err := primitive.ObjectIDFromHex(id)
if err != nil {
return nil, ErrInvalidObjectID
}
var data entity.Category
rk := domain.GetCategoryRedisKey(id)
err = repo.DB.FindOne(ctx, rk, &data, bson.M{"_id": oid})
switch {
case err == nil:
return &data, nil
case errors.Is(err, mon.ErrNotFound):
return nil, ErrNotFound
default:
return nil, err
}
}
func (repo *CategoryRepository) Update(ctx context.Context, id string, data *entity.Category) (*mongo.UpdateResult, error) {
oid, err := primitive.ObjectIDFromHex(id)
if err != nil {
return nil, ErrInvalidObjectID
}
updateFields := bson.M{}
if data.Name != "" {
updateFields["name"] = data.Name
}
updateFields["updated_at"] = time.Now().UTC().UnixNano()
// 構建查找條件
filter := bson.M{"_id": oid}
update := bson.M{"$set": updateFields}
opt := options.Update().SetUpsert(false)
rk := domain.GetCategoryRedisKey(id)
res, err := repo.DB.UpdateOne(ctx, rk, filter, update, opt)
if err != nil {
return nil, err
}
// 檢查更新結果,若沒有匹配的文檔,則返回錯誤
if res.MatchedCount == 0 {
return nil, ErrNotFound // 自定義的錯誤表示未找到記錄
}
return res, err
}
func (repo *CategoryRepository) Delete(ctx context.Context, id string) (int64, error) {
oid, err := primitive.ObjectIDFromHex(id)
if err != nil {
return 0, ErrInvalidObjectID
}
rk := domain.GetCategoryRedisKey(id)
res, err := repo.DB.DeleteOne(ctx, rk, bson.M{"_id": oid})
return res, err
}
func (repo *CategoryRepository) ListCategory(ctx context.Context, params *repository.CategoryQueryParams) ([]*entity.Category, int64, error) {
// TODO 有需要列表快取實在取列表快取
// 構建查詢過濾器
filter := bson.M{}
if len(params.ID) > 0 {
objectIDs := make([]primitive.ObjectID, 0, len(params.ID))
for _, id := range params.ID {
objID, err := primitive.ObjectIDFromHex(id)
if err != nil {
continue
}
objectIDs = append(objectIDs, objID)
}
filter["_id"] = bson.M{"$in": objectIDs}
}
// 設置排序選項
opts := options.Find().SetSkip((params.PageIndex - 1) * params.PageSize).SetLimit(params.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 category []*entity.Category
err = repo.DB.GetClient().Find(ctx, &category, filter, opts)
if err != nil {
return nil, 0, err
}
return category, count, nil
}