201 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
		
		
			
		
	
	
			201 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
| 
								 | 
							
								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)
							 | 
						||
| 
								 | 
							
								}
							 |