package model import ( "context" "fmt" "permission/reborn-mongo/domain/entity" "github.com/zeromicro/go-zero/core/stores/cache" "github.com/zeromicro/go-zero/core/stores/monc" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo/options" ) var _ PermissionModel = (*customPermissionModel)(nil) type ( // PermissionModel go-zero model 介面 PermissionModel interface { Insert(ctx context.Context, data *entity.Permission) error FindOne(ctx context.Context, id primitive.ObjectID) (*entity.Permission, error) FindOneByName(ctx context.Context, name string) (*entity.Permission, error) FindOneByHTTP(ctx context.Context, path, method string) (*entity.Permission, error) FindMany(ctx context.Context, filter bson.M, opts ...*options.FindOptions) ([]*entity.Permission, error) FindAllActive(ctx context.Context) ([]*entity.Permission, error) Update(ctx context.Context, data *entity.Permission) error Delete(ctx context.Context, id primitive.ObjectID) error } customPermissionModel struct { *monc.Model } ) // NewPermissionModel 建立 Permission Model (帶 cache) func NewPermissionModel(url, db, collection string, c cache.CacheConf) PermissionModel { return &customPermissionModel{ Model: monc.MustNewModel(url, db, collection, c), } } func (m *customPermissionModel) Insert(ctx context.Context, data *entity.Permission) error { if data.ID.IsZero() { data.ID = primitive.NewObjectID() } data.TimeStamp = entity.NewTimeStamp() key := permissionIDKey(data.ID) _, err := m.InsertOneNoCache(ctx, key, data) return err } func (m *customPermissionModel) FindOne(ctx context.Context, id primitive.ObjectID) (*entity.Permission, error) { var data entity.Permission key := permissionIDKey(id) err := m.Model.FindOneNoCache(ctx, &data, bson.M{ "_id": id, "status": bson.M{"$ne": entity.StatusDeleted}, }) if err != nil { if err == monc.ErrNotFound { return nil, ErrNotFound } return nil, err } return &data, nil } func (m *customPermissionModel) FindOneByName(ctx context.Context, name string) (*entity.Permission, error) { var data entity.Permission key := permissionNameKey(name) err := m.FindOne(ctx, key, &data, func() (interface{}, error) { err := m.Model.FindOne(ctx, &data, bson.M{ "name": name, "status": bson.M{"$ne": entity.StatusDeleted}, }) if err != nil { return nil, err } return &data, nil }) if err != nil { if err == monc.ErrNotFound { return nil, ErrNotFound } return nil, err } return &data, nil } func (m *customPermissionModel) FindOneByHTTP(ctx context.Context, path, method string) (*entity.Permission, error) { var data entity.Permission key := permissionHTTPKey(path, method) err := m.FindOne(ctx, key, &data, func() (interface{}, error) { err := m.Model.FindOne(ctx, &data, bson.M{ "http_path": path, "http_method": method, "status": bson.M{"$ne": entity.StatusDeleted}, }) if err != nil { return nil, err } return &data, nil }) if err != nil { if err == monc.ErrNotFound { return nil, ErrNotFound } return nil, err } return &data, nil } func (m *customPermissionModel) FindMany(ctx context.Context, filter bson.M, opts ...*options.FindOptions) ([]*entity.Permission, error) { if filter == nil { filter = bson.M{} } filter["status"] = bson.M{"$ne": entity.StatusDeleted} var data []*entity.Permission err := m.Model.Find(ctx, &data, filter, opts...) if err != nil { return nil, err } return data, nil } func (m *customPermissionModel) FindAllActive(ctx context.Context) ([]*entity.Permission, error) { key := "cache:permission:list:active" var data []*entity.Permission err := m.QueryRow(ctx, &data, key, func(conn *monc.Model) error { return m.Model.Find(ctx, &data, bson.M{"status": entity.StatusActive}, options.Find().SetSort(bson.D{{Key: "parent_id", Value: 1}, {Key: "_id", Value: 1}})) }) if err != nil { return nil, err } return data, nil } func (m *customPermissionModel) Update(ctx context.Context, data *entity.Permission) error { data.UpdateTimestamp() key := permissionIDKey(data.ID) _, err := m.Model.ReplaceOneNoCache(ctx, key, bson.M{"_id": data.ID}, data) return err } func (m *customPermissionModel) Delete(ctx context.Context, id primitive.ObjectID) error { key := permissionIDKey(id) _, err := m.Model.UpdateOneNoCache(ctx, key, bson.M{"_id": id}, bson.M{ "$set": bson.M{ "status": entity.StatusDeleted, "update_time": entity.NewTimeStamp().UpdateTime, }, }) return err } // Cache keys func permissionIDKey(id primitive.ObjectID) string { return fmt.Sprintf("cache:permission:id:%s", id.Hex()) } func permissionNameKey(name string) string { return fmt.Sprintf("cache:permission:name:%s", name) } func permissionHTTPKey(path, method string) string { return fmt.Sprintf("cache:permission:http:%s:%s", method, path) }