239 lines
5.9 KiB
Go
239 lines
5.9 KiB
Go
package repository
|
|
|
|
import (
|
|
"backend/pkg/library/errs/code"
|
|
"backend/pkg/permission/domain"
|
|
"backend/pkg/permission/domain/permission"
|
|
"context"
|
|
"errors"
|
|
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
|
"time"
|
|
|
|
"backend/pkg/library/errs"
|
|
"backend/pkg/library/mongo"
|
|
"backend/pkg/permission/domain/entity"
|
|
"backend/pkg/permission/domain/repository"
|
|
|
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
|
"github.com/zeromicro/go-zero/core/stores/mon"
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
mongodriver "go.mongodb.org/mongo-driver/v2/mongo"
|
|
)
|
|
|
|
type UserRoleRepositoryParam struct {
|
|
Conf *mongo.Conf
|
|
CacheConf cache.CacheConf
|
|
DBOpts []mon.Option
|
|
CacheOpts []cache.Option
|
|
}
|
|
|
|
type UserRoleRepository struct {
|
|
DB mongo.DocumentDBWithCacheUseCase
|
|
}
|
|
|
|
// NewUserRoleRepository 創建用戶角色倉庫實例
|
|
func NewUserRoleRepository(param UserRoleRepositoryParam) repository.UserRoleRepository {
|
|
e := entity.UserRole{}
|
|
documentDB, err := mongo.MustDocumentDBWithCache(
|
|
param.Conf,
|
|
e.CollectionName(),
|
|
param.CacheConf,
|
|
param.DBOpts,
|
|
param.CacheOpts,
|
|
)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return &UserRoleRepository{
|
|
DB: documentDB,
|
|
}
|
|
}
|
|
|
|
func (repo *UserRoleRepository) Create(ctx context.Context, userRole *entity.UserRole) error {
|
|
now := time.Now()
|
|
userRole.CreateTime = now
|
|
userRole.UpdateTime = now
|
|
id := bson.NewObjectID()
|
|
userRole.ID = id
|
|
|
|
rk := domain.GetUserRoleRedisKey(id.Hex())
|
|
userRole.CreateTime = time.Now()
|
|
userRole.UpdateTime = time.Now()
|
|
|
|
_, err := repo.DB.InsertOne(ctx, rk, userRole)
|
|
if err != nil {
|
|
// 檢查是否為重複鍵錯誤
|
|
if mongodriver.IsDuplicateKeyError(err) {
|
|
return errs.ResourceAlreadyExist("failed to insert user role")
|
|
}
|
|
|
|
return errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repo *UserRoleRepository) GetByID(ctx context.Context, id string) (*entity.UserRole, error) {
|
|
var userRole entity.UserRole
|
|
objID, err := bson.ObjectIDFromHex(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rk := domain.GetUserRoleRedisKey(id)
|
|
err = repo.DB.FindOne(ctx, rk, &userRole, bson.M{"_id": objID})
|
|
if err != nil {
|
|
if errors.Is(err, mongodriver.ErrNoDocuments) {
|
|
return nil, errs.ResourceNotFoundWithScope(
|
|
code.CloudEPPermission,
|
|
domain.FailedToGetRoleByID,
|
|
"failed to get user role by id")
|
|
}
|
|
|
|
return nil, errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
|
}
|
|
|
|
return &userRole, nil
|
|
}
|
|
|
|
func (repo *UserRoleRepository) GetByUserAndRole(ctx context.Context, uid, roleUID string) (*entity.UserRole, error) {
|
|
filter := bson.M{
|
|
"uid": uid,
|
|
"role_uid": roleUID,
|
|
"status": permission.StatusActive,
|
|
}
|
|
|
|
var userRole entity.UserRole
|
|
err := repo.DB.GetClient().Find(ctx, &userRole, filter)
|
|
if err != nil {
|
|
if errors.Is(err, mongodriver.ErrNoDocuments) {
|
|
return nil, errs.ResourceNotFoundWithScope(code.CloudEPPermission, 0, "failed to get user and role")
|
|
}
|
|
|
|
return nil, errs.DatabaseErrorWithScope(code.CloudEPPermission, 0, err.Error())
|
|
}
|
|
|
|
return &userRole, nil
|
|
}
|
|
|
|
func (repo *UserRoleRepository) Update(ctx context.Context, id string, userRole *entity.UserRole) error {
|
|
userRole.UpdateTime = time.Now()
|
|
objID, err := bson.ObjectIDFromHex(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
update := bson.M{
|
|
"$set": bson.M{
|
|
"status": userRole.Status,
|
|
"update_time": userRole.UpdateTime,
|
|
},
|
|
}
|
|
|
|
rk := domain.GetUserRoleRedisKey(id)
|
|
|
|
_, err = repo.DB.UpdateOne(ctx, rk, bson.M{"_id": objID}, update)
|
|
if err != nil {
|
|
return errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repo *UserRoleRepository) Delete(ctx context.Context, id string) error {
|
|
objID, err := bson.ObjectIDFromHex(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
rk := domain.GetUserRoleRedisKey(id)
|
|
_, err = repo.DB.DeleteOne(ctx, rk, bson.M{"_id": objID})
|
|
if err != nil {
|
|
return errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repo *UserRoleRepository) List(ctx context.Context, filter repository.UserRoleFilter) ([]*entity.UserRole, error) {
|
|
query := bson.M{}
|
|
if filter.Brand != "" {
|
|
query["brand"] = filter.Brand
|
|
}
|
|
if filter.UID != "" {
|
|
query["uid"] = filter.UID
|
|
}
|
|
if filter.RoleUID != "" {
|
|
query["role_uid"] = filter.RoleUID
|
|
}
|
|
if filter.Status != nil {
|
|
query["status"] = *filter.Status
|
|
}
|
|
|
|
var userRoles []*entity.UserRole
|
|
err := repo.DB.GetClient().Find(ctx, &userRoles, query)
|
|
if err != nil {
|
|
return nil, errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
|
}
|
|
|
|
err = repo.DB.GetClient().Find(ctx,
|
|
&userRoles, query,
|
|
options.Find().SetLimit(int64(filter.Limit)),
|
|
options.Find().SetSkip(int64(filter.Skip)))
|
|
if err != nil {
|
|
return nil, errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
|
}
|
|
|
|
return userRoles, nil
|
|
}
|
|
|
|
func (repo *UserRoleRepository) GetUserRolesByUID(ctx context.Context, uid string) ([]*entity.UserRole, error) {
|
|
status := permission.StatusActive
|
|
filter := repository.UserRoleFilter{
|
|
UID: uid,
|
|
Status: &status,
|
|
}
|
|
|
|
return repo.List(ctx, filter)
|
|
}
|
|
|
|
func (repo *UserRoleRepository) DeleteByUserAndRole(ctx context.Context, uid, roleUID string) error {
|
|
filter := repository.UserRoleFilter{
|
|
UID: uid,
|
|
RoleUID: roleUID,
|
|
}
|
|
list, err := repo.List(ctx, filter)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(list) == 0 {
|
|
return nil
|
|
}
|
|
|
|
for _, item := range list {
|
|
_ = repo.DB.DelCache(ctx, domain.GetUserRoleRedisKey(item.ID.Hex()))
|
|
}
|
|
|
|
_, err = repo.DB.GetClient().DeleteMany(ctx, filter)
|
|
if err != nil {
|
|
return errs.DBErrorWithScope(code.CloudEPPermission, err.Error())
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Index20241226001UP 創建索引
|
|
func (repo *UserRoleRepository) Index20241226001UP(ctx context.Context) (*mongodriver.Cursor, error) {
|
|
// 等價於 db.account.createIndex({ "login_id": 1, "platform": 1}, {unique: true})
|
|
repo.DB.PopulateMultiIndex(ctx, []string{
|
|
"uid",
|
|
"role_uid",
|
|
}, []int32{1, 1}, true)
|
|
|
|
// 等價於 db.account.createIndex({"create_at": 1})
|
|
repo.DB.PopulateIndex(ctx, "uid", 1, false)
|
|
repo.DB.PopulateIndex(ctx, "status", 1, false)
|
|
|
|
return repo.DB.GetClient().Indexes().List(ctx)
|
|
}
|