package repository import ( "context" "fmt" "time" "code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/entity" "code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/repository" mgo "code.30cm.net/digimon/library-go/mongo" "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 RoleRepositoryParam struct { Conf *mgo.Conf DBOpts []mon.Option } type RoleRepository struct { DB mgo.DocumentDBUseCase } func NewRoleRepository(param RoleRepositoryParam) repository.RoleRepository { e := entity.Role{} db, err := mgo.NewDocumentDB(param.Conf, e.Collection(), param.DBOpts...) if err != nil { panic(err) } return &RoleRepository{ DB: db, } } func (repo *RoleRepository) List(ctx context.Context, params repository.ListQuery) ([]*entity.Role, int64, error) { // 構建查詢條件 filter := bson.M{} if params.Name != nil { filter["name"] = *params.Name } if params.ClientID != nil { filter["client_id"] = *params.ClientID } if params.Status != nil { filter["status"] = *params.Status } if params.UID != nil { filter["uid"] = *params.UID } // 計算符合條件的總數 count, err := repo.DB.GetClient().CountDocuments(ctx, filter) if err != nil { return nil, 0, err } // 構建查詢選項(分頁) opts := options.Find(). SetSkip(params.PageSize * (params.PageIndex - 1)). SetLimit(params.PageSize) // 執行查詢 var result = make([]*entity.Role, 0, params.PageSize) err = repo.DB.GetClient().Find(ctx, &result, filter, opts) if err != nil { return nil, 0, err } return result, count, nil } func (repo *RoleRepository) GetByID(ctx context.Context, id string) (*entity.Role, error) { oid, err := primitive.ObjectIDFromHex(id) if err != nil { return nil, ErrInvalidObjectID } var result entity.Role err = repo.DB.GetClient().FindOne(ctx, &result, bson.M{"_id": oid}) if err != nil { return nil, err } return &result, nil } func (repo *RoleRepository) GetByUID(ctx context.Context, uid string) (*entity.Role, error) { var result entity.Role err := repo.DB.GetClient().FindOne(ctx, &result, bson.M{"uid": uid}) if err != nil { return nil, err } return &result, nil } func (repo *RoleRepository) All(ctx context.Context, clientID *string) ([]*entity.Role, error) { opt := options.Find().SetSort(bson.M{"_id": 1}) filter := bson.M{} if clientID != nil { filter["client_id"] = *clientID } result := make([]*entity.Role, 0) err := repo.DB.GetClient().Find(ctx, &result, filter, opt) if err != nil { return nil, err } return result, nil } // Create 建立新的 Role func (repo *RoleRepository) Create(ctx context.Context, role *entity.Role) error { if role == nil { return fmt.Errorf("failed to get role") } if role.ID.IsZero() { now := time.Now().UTC().UnixNano() role.ID = primitive.NewObjectID() role.CreateAt = now role.UpdateAt = now } _, err := repo.DB.GetClient().InsertOne(ctx, role) return err } func (repo *RoleRepository) Update(ctx context.Context, role repository.UpdateReq) error { now := time.Now().UTC().UnixNano() // 動態構建更新內容 updateFields := bson.M{ "update_at": now, // 確保 `updateAt` 總是更新 } if role.Name != nil { updateFields["name"] = *role.Name } if role.Status != nil { updateFields["status"] = *role.Status } if role.UID != nil { updateFields["uid"] = *role.UID } if role.ClientID != nil { updateFields["client_id"] = *role.ClientID } oid, err := primitive.ObjectIDFromHex(role.ID) if err != nil { return ErrInvalidObjectID } _, err = repo.DB.GetClient().UpdateOne(ctx, bson.M{"_id": oid}, bson.M{"$set": updateFields}) if err != nil { return err } return nil } func (repo *RoleRepository) Delete(ctx context.Context, id string) error { oid, err := primitive.ObjectIDFromHex(id) if err != nil { return ErrInvalidObjectID } _, err = repo.DB.GetClient().DeleteOne(ctx, bson.M{"_id": oid}) if err != nil { return err } return nil } func (repo *RoleRepository) Index20250224UP(ctx context.Context) (*mongo.Cursor, error) { repo.DB.PopulateMultiIndex(ctx, []string{ "name", "client_id", "status", "uid", }, []int32{1, 1, 1, 1}, false) repo.DB.PopulateIndex(ctx, "uid", 1, false) return repo.DB.GetClient().Indexes().List(ctx) }