package repository import ( "context" "time" "code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/entity" "code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/permission" "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 PermissionRepositoryParam struct { Conf *mgo.Conf DBOpts []mon.Option } type PermissionRepository struct { DB mgo.DocumentDBUseCase } // TODO 量小不需要 Redis 以後有需要再增加 func NewPermissionRepository(param PermissionRepositoryParam) repository.PermissionRepository { e := entity.Permission{} db, err := mgo.NewDocumentDB(param.Conf, e.Collection(), param.DBOpts...) if err != nil { panic(err) } return &PermissionRepository{ DB: db, } } func (repo *PermissionRepository) Insert(ctx context.Context, data entity.Permission) error { if data.ID.IsZero() { now := time.Now().UTC().UnixNano() data.ID = primitive.NewObjectID() data.CreateAt = now data.UpdateAt = now } _, err := repo.DB.GetClient().InsertOne(ctx, data) return err } func (repo *PermissionRepository) Update(ctx context.Context, id string, req repository.UpdatePermission) error { now := time.Now().UTC().UnixNano() // 動態構建更新內容 updateFields := bson.M{ "update_at": now, // 確保 `updateAt` 總是更新 } if req.Name != nil { updateFields["name"] = *req.Name } if req.HTTPMethod != nil { updateFields["http_method"] = *req.HTTPMethod } if req.HTTPPath != nil { updateFields["http_path"] = *req.HTTPPath } if req.Status != nil { updateFields["status"] = *req.Status } if req.Type != nil { updateFields["type"] = *req.Type } if req.ParentID != nil { updateFields["parent"] = *req.ParentID } oid, err := primitive.ObjectIDFromHex(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 *PermissionRepository) 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 *PermissionRepository) GetAll(ctx context.Context, status *permission.Status) ([]entity.Permission, error) { filter := bson.M{} if status != nil { filter["status"] = status } opt := options.Find().SetSort(bson.M{"id": 1}) result := make([]entity.Permission, 0) err := repo.DB.GetClient().Find(ctx, &result, filter, opt) if err != nil { return nil, err } return result, nil } func (repo *PermissionRepository) GetAllIntoIDMap(ctx context.Context, status *permission.Status) (map[string]entity.Permission, error) { permissions, err := repo.GetAll(ctx, status) if err != nil { return nil, err } permissionMap := make(map[string]entity.Permission) for _, v := range permissions { permissionMap[v.Name] = v } return permissionMap, nil } func (repo *PermissionRepository) FindOne(ctx context.Context, query repository.PermissionQuery) (entity.Permission, error) { filter := bson.M{"http_method": query.HTTPMethod, "http_path": query.HTTPPath} var result entity.Permission err := repo.DB.GetClient().FindOne(ctx, &result, filter) if err != nil { return entity.Permission{}, err } return result, nil } func (repo *PermissionRepository) FindByNames(ctx context.Context, names []string) ([]entity.Permission, error) { result := make([]entity.Permission, 0) // 使用 $in 操作符查詢 name 在 names 切片中的文件 filter := bson.M{"name": bson.M{"$in": names}} err := repo.DB.GetClient().Find(ctx, &result, filter) if err != nil { return []entity.Permission{}, err } return result, nil } func (repo *PermissionRepository) Index20250214UP(ctx context.Context) (*mongo.Cursor, error) { // 等價於 db.account.createIndex({ "http_method": 1, "http_path": 1}, {unique: false}) repo.DB.PopulateMultiIndex(ctx, []string{ "http_method", "http_path", }, []int32{1, 1}, false) // 等價於 db.account.createIndex({"create_at": 1}) repo.DB.PopulateIndex(ctx, "name", 1, true) return repo.DB.GetClient().Indexes().List(ctx) }