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

193 lines
5.0 KiB
Go
Raw Normal View History

2025-04-04 07:39:49 +00:00
package repository
import (
2025-04-06 02:08:46 +00:00
"context"
"errors"
2025-04-04 07:39:49 +00:00
"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"
"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
}