From dbdc777ed45cdc5f0bca5586d32f070e2845ce1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=80=A7=E9=A9=8A?= Date: Fri, 28 Feb 2025 09:39:42 +0800 Subject: [PATCH] feat:add tree --- pkg/domain/entity/role.go | 2 +- pkg/domain/permission/type.go | 2 +- pkg/domain/repository/role_permission.go | 4 +- pkg/domain/usecase/error.go | 2 +- pkg/domain/usecase/permission.go | 9 +- pkg/domain/usecase/role.go | 15 +- pkg/domain/usecase/role_permission.go | 10 +- pkg/repository/role_permission.go | 38 +++-- pkg/repository/role_permission_test.go | 10 +- pkg/usecase/permiission.go | 97 +++++++++++ pkg/usecase/permission_tree.go | 197 +++++++++++------------ pkg/usecase/role.go | 1 - pkg/usecase/role_permission.go | 174 +++++++++++++++----- 13 files changed, 380 insertions(+), 181 deletions(-) diff --git a/pkg/domain/entity/role.go b/pkg/domain/entity/role.go index 8fcc3de..1d421ac 100644 --- a/pkg/domain/entity/role.go +++ b/pkg/domain/entity/role.go @@ -26,7 +26,7 @@ import ( type Role struct { ID primitive.ObjectID `bson:"_id,omitempty"` Name string `bson:"name"` // 角色名稱 - UID string `bson:"uid"` + UID string `bson:"uid"` // 限定角色的管理範圍:例如,只有 UID 對應的使用者可以修改或刪除這個角色。 ClientID string `bson:"client_id"` Status permission.Status `bson:"status"` // 例如 1: 啟用, 0: 停用 CreateAt int64 `bson:"create_at"` diff --git a/pkg/domain/permission/type.go b/pkg/domain/permission/type.go index 02b0fa6..4a74707 100644 --- a/pkg/domain/permission/type.go +++ b/pkg/domain/permission/type.go @@ -7,4 +7,4 @@ const ( FrontendUser ) -const AdminRoleUID = "GodDog" +const AdminRoleUID = "GD1000001" // 管理員 GodDog 1000001 diff --git a/pkg/domain/repository/role_permission.go b/pkg/domain/repository/role_permission.go index 6e8f309..0f87bdf 100644 --- a/pkg/domain/repository/role_permission.go +++ b/pkg/domain/repository/role_permission.go @@ -10,8 +10,8 @@ import ( type RolePermissionRepository interface { Get(ctx context.Context, roleID string) ([]*entity.RolePermission, error) GetByPermissionID(ctx context.Context, permissionIDs []string) ([]*entity.RolePermission, error) - Create(ctx context.Context, entity entity.RolePermission) error - Delete(ctx context.Context, roleID string, permission string) error + Create(ctx context.Context, entity []entity.RolePermission) error + Delete(ctx context.Context, roleID string, permissions []string) error RolePermissionIndex } diff --git a/pkg/domain/usecase/error.go b/pkg/domain/usecase/error.go index ae72163..b6b0afe 100644 --- a/pkg/domain/usecase/error.go +++ b/pkg/domain/usecase/error.go @@ -3,5 +3,5 @@ package usecase import "fmt" var ( - NotFoundError = fmt.Errorf("permission not found") + ErrNotFound = fmt.Errorf("permission not found") ) diff --git a/pkg/domain/usecase/permission.go b/pkg/domain/usecase/permission.go index 31eea6c..2f79115 100644 --- a/pkg/domain/usecase/permission.go +++ b/pkg/domain/usecase/permission.go @@ -10,12 +10,13 @@ import ( type PermissionUseCase interface { Insert(ctx context.Context, req CreatePermissionReq) error Del(ctx context.Context, id string) error - Update(ctx context.Context, req UpdatePermissionReq) error - Get(ctx context.Context, id string) (entity.Permission, error) - List(ctx context.Context, param ListParam) ([]entity.Permission, int64, error) - All(ctx context.Context, status *permission.Status) + Update(ctx context.Context, id string, req UpdatePermissionReq) error + All(ctx context.Context, status *permission.Status) ([]entity.Permission, error) // FilterAll 用樹的結構,使得付節點若關閉,子節點也不會顯示 FilterAll(ctx context.Context) ([]entity.Permission, error) + + // Get(ctx context.Context, id string) (entity.Permission, error) + // List(ctx context.Context, param ListParam) ([]entity.Permission, int64, error) } type CreatePermissionReq struct { diff --git a/pkg/domain/usecase/role.go b/pkg/domain/usecase/role.go index d587532..75c003a 100644 --- a/pkg/domain/usecase/role.go +++ b/pkg/domain/usecase/role.go @@ -10,19 +10,20 @@ type RoleUseCase interface { List(ctx context.Context, param ListQuery) ([]Role, int64, error) All(ctx context.Context, clientID *string) ([]Role, error) GetByID(ctx context.Context, id string) (*Role, error) - GetByUID(ctx context.Context, uid string) (*Role, error) + GetByUID(ctx context.Context, uid string) (*Role, error) // -> 限定角色的管理範圍:查詢誰建立的,用某個角色管理,目前用不到 Create(ctx context.Context, role CreateRoleReq) error Update(ctx context.Context, id string, data CreateRoleReq) error Delete(ctx context.Context, id string) error } type ListQuery struct { - PageSize int64 // 必填 - PageIndex int64 // 必填 - ClientID *string - UID *string - Name *string - Status *permission.Status + PageSize int64 // 必填 + PageIndex int64 // 必填 + ClientID *string + UID *string + Name *string + Status *permission.Status + Permission []string } type Role struct { diff --git a/pkg/domain/usecase/role_permission.go b/pkg/domain/usecase/role_permission.go index 9484078..46b3036 100644 --- a/pkg/domain/usecase/role_permission.go +++ b/pkg/domain/usecase/role_permission.go @@ -7,12 +7,12 @@ import ( ) type RolePermissionUseCase interface { - Get(ctx context.Context, roleID string) (permission.Permissions, error) - GetByRoleUID(ctx context.Context, uid string) (permission.Permissions, error) - GetByUser(ctx context.Context, uid string) (UserPermission, error) + Get(ctx context.Context, roleID string) (permission.Permissions, error) // -> role 有哪些Permission Create(ctx context.Context, roleID string, permissions permission.Permissions) error Delete(ctx context.Context, roleID string, permissions permission.Permissions) error List(ctx context.Context, req ListQuery) (RoleResp, error) + //GetByRoleUID(ctx context.Context, uid string) (permission.Permissions, error) + //GetByUser(ctx context.Context, uid string) (UserPermission, error) } type UserPermission struct { @@ -26,6 +26,6 @@ type UserRoleCountResp struct { } type RoleResp struct { - List []UserRoleCountResp `json:"list"` - Total int64 `json:"total"` + Roles []Role + Total int64 `json:"total"` } diff --git a/pkg/repository/role_permission.go b/pkg/repository/role_permission.go index 1ed2ba8..f723260 100644 --- a/pkg/repository/role_permission.go +++ b/pkg/repository/role_permission.go @@ -59,26 +59,40 @@ func (repo *RolePermissionRepository) GetByPermissionID(ctx context.Context, per return result, nil } -func (repo *RolePermissionRepository) Create(ctx context.Context, role entity.RolePermission) error { - if role.ID.IsZero() { - now := time.Now().UTC().UnixNano() - role.ID = primitive.NewObjectID() - role.CreateAt = now - role.UpdateAt = now +func (repo *RolePermissionRepository) Create(ctx context.Context, roles []entity.RolePermission) error { + if len(roles) == 0 { + return nil // 如果 roles 是空的,則不執行任何操作 } - _, err := repo.DB.GetClient().InsertOne(ctx, role) + now := time.Now().UTC().UnixNano() + + // 將 []entity.RolePermission 轉換為 []interface{} + var roleInterfaces []interface{} + for i := range roles { + if roles[i].ID.IsZero() { + roles[i].ID = primitive.NewObjectID() + roles[i].CreateAt = now + roles[i].UpdateAt = now + } + roleInterfaces = append(roleInterfaces, roles[i]) + } + + _, err := repo.DB.GetClient().InsertMany(ctx, roleInterfaces) return err } -func (repo *RolePermissionRepository) Delete(ctx context.Context, roleID string, permission string) error { - filter := bson.M{ - "role_id": roleID, - "permission_id": permission, +func (repo *RolePermissionRepository) Delete(ctx context.Context, roleID string, permissions []string) error { + if len(permissions) == 0 { + return nil // 如果 permissions 為空,則不執行刪除操作 } - _, err := repo.DB.GetClient().DeleteOne(ctx, filter) + filter := bson.M{ + "role_id": roleID, + "permission_id": bson.M{"$in": permissions}, // 使用 $in 刪除多個 permission_id + } + + _, err := repo.DB.GetClient().DeleteMany(ctx, filter) if err != nil { return err } diff --git a/pkg/repository/role_permission_test.go b/pkg/repository/role_permission_test.go index 48206bb..06471aa 100644 --- a/pkg/repository/role_permission_test.go +++ b/pkg/repository/role_permission_test.go @@ -74,7 +74,7 @@ func TestRolePermissionRepository_Create(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - err := repo.Create(context.Background(), tc.input) + err := repo.Create(context.Background(), []entity.RolePermission{tc.input}) if tc.expectErr { assert.Error(t, err, "應該返回錯誤") @@ -97,7 +97,7 @@ func TestRolePermissionRepository_Delete(t *testing.T) { PermissionID: "perm_1", } - err = repo.Create(context.Background(), existingRolePermission) + err = repo.Create(context.Background(), []entity.RolePermission{existingRolePermission}) assert.NoError(t, err, "應該成功插入測試資料") testCases := []struct { @@ -122,7 +122,7 @@ func TestRolePermissionRepository_Delete(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - err := repo.Delete(context.Background(), tc.roleID, tc.permission) + err := repo.Delete(context.Background(), tc.roleID, []string{tc.permission}) if tc.expectErr { assert.Error(t, err, "應該返回錯誤") @@ -158,7 +158,7 @@ func TestRolePermissionRepository_GetByPermissionID(t *testing.T) { } for _, rp := range existingRolePermissions { - err := repo.Create(context.Background(), rp) + err := repo.Create(context.Background(), []entity.RolePermission{rp}) assert.NoError(t, err, "應該成功插入測試資料") } @@ -227,7 +227,7 @@ func TestRolePermissionRepository_Get(t *testing.T) { } for _, rp := range existingRolePermissions { - err := repo.Create(context.Background(), rp) + err := repo.Create(context.Background(), []entity.RolePermission{rp}) assert.NoError(t, err, "應該成功插入測試資料") } diff --git a/pkg/usecase/permiission.go b/pkg/usecase/permiission.go index aed2454..80ff643 100644 --- a/pkg/usecase/permiission.go +++ b/pkg/usecase/permiission.go @@ -1 +1,98 @@ package usecase + +import ( + "context" + + "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" + "code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/usecase" +) + +type PermissionUseCaseParam struct { + permissionRepository repository.PermissionRepository +} + +type PermissionUseCase struct { + PermissionUseCaseParam +} + +func NewPermissionUseCase(param PermissionUseCaseParam) usecase.PermissionUseCase { + return &PermissionUseCase{ + PermissionUseCaseParam: param, + } +} + +func (use *PermissionUseCase) Insert(ctx context.Context, req usecase.CreatePermissionReq) error { + insert := entity.Permission{ + Name: req.Name, + HTTPMethod: req.HTTPMethod, + HTTPPath: req.HTTPPath, + Status: req.Status, + Type: req.Type, + } + if req.Parent != nil { + insert.Parent = *req.Parent + } + + err := use.permissionRepository.Insert(ctx, insert) + if err != nil { + return err + } + + return nil +} + +func (use *PermissionUseCase) Del(ctx context.Context, id string) error { + err := use.Del(ctx, id) + if err != nil { + return err + } + + return nil +} + +func (use *PermissionUseCase) Update(ctx context.Context, id string, req usecase.UpdatePermissionReq) error { + update := repository.UpdatePermission{ + Name: req.Name, + HTTPMethod: req.HTTPMethod, + HTTPPath: req.HTTPPath, + Status: req.Status, + Type: req.Type, + } + + err := use.permissionRepository.Update(ctx, id, update) + if err != nil { + return err + } + + return nil +} + +func (use *PermissionUseCase) All(ctx context.Context, status *permission.Status) ([]entity.Permission, error) { + all, err := use.permissionRepository.GetAll(ctx, status) + if err != nil { + return nil, err + } + + return all, nil +} + +func (use *PermissionUseCase) FilterAll(ctx context.Context) ([]entity.Permission, error) { + all, err := use.permissionRepository.GetAll(ctx, nil) + if err != nil { + return nil, err + } + + nodes, err := GeneratePermissionTree(all).filterOpenNodes() + if err != nil { + return nil, err + } + + result := make([]entity.Permission, 0, len(nodes)) + for _, item := range nodes { + result = append(result, item) + } + + return result, nil +} diff --git a/pkg/usecase/permission_tree.go b/pkg/usecase/permission_tree.go index 0d109b8..ae3238a 100644 --- a/pkg/usecase/permission_tree.go +++ b/pkg/usecase/permission_tree.go @@ -3,6 +3,8 @@ package usecase import ( "sync" + "code.30cm.net/digimon/library-go/errs" + "code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/entity" "code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/permission" @@ -26,6 +28,8 @@ type PermissionNode struct { Children []*PermissionNode } +const rootName = "root" + // GeneratePermissionTree 根據扁平權限資料建立樹,並掛在 dummy root 下 func GeneratePermissionTree(permissions []entity.Permission) *PermissionTree { tree := &PermissionTree{ @@ -45,7 +49,7 @@ func GeneratePermissionTree(permissions []entity.Permission) *PermissionTree { // 2. 建立 dummy root 節點 tree.root = &PermissionNode{ - Data: entity.Permission{ID: primitive.NewObjectID(), Name: "root"}, + Data: entity.Permission{ID: primitive.NewObjectID(), Name: rootName}, Children: []*PermissionNode{}, } @@ -125,106 +129,93 @@ func (tree *PermissionTree) filterOpenNodes() (map[string]entity.Permission, err return result, nil } -//// getFullParentPermissionIDs -//// 根據傳入的權限狀態 (Permissions) 回傳完整的權限 ID 列表,包含所有祖先。 -//// 如果某個節點為非葉節點,則會檢查其子節點是否有啟用,否則該節點不會被展開。 -//func (tree *PermissionTree) getFullParentPermissionIDs(permissions permission.Permissions) ([]string, error) { -// tree.mu.RLock() -// defer tree.mu.RUnlock() -// -// exist := make(map[string]bool) -// var ids []string -// -// for name, status := range permissions { -// if status != permission.OpenPermission { -// continue -// } -// idList, ok := tree.nameToIDs[name] -// if !ok { -// return nil, NotFoundError -// } -// for _, pid := range idList { -// node, exists := tree.nodes[pid] -// if !exists || node == nil { -// return nil, NotFoundError -// } -// // 如果為父節點,檢查其子節點是否有啟用,若都關閉則不展開 -// if len(node.Children) > 0 { -// var childOpen bool -// for _, child := range node.Children { -// if childStatus, ok := permissions[child.Data.Name]; ok && childStatus == permission.OpenPermission { -// childOpen = true -// break -// } -// } -// if !childOpen { -// continue -// } -// } -// // 將該節點及所有祖先(直到 dummy root,不包括 dummy root)加入結果 -// for cur := node; cur != nil && cur.Data.Name != "root"; cur = cur.Parent { -// if !exist[cur.Data.ID.Hex()] { -// ids = append(ids, cur.Data.ID.Hex()) -// exist[cur.Data.ID.Hex()] = true -// } -// } -// } -// } -// -// return ids, nil -//} +// getFullParentPermission 根據 role permission 找出完整 path permission status +func (tree *PermissionTree) getFullParentPermission(rolePermissions []*entity.RolePermission) permission.Permissions { + status := permission.Permissions{} -//// getFullParentPermissionStatus -//// 根據傳入的權限狀態 (Permissions) 回傳完整的權限狀態,包含所有祖先的名稱設為啟用。 -//func (tree *PermissionTree) getFullParentPermissionStatus(permissions permission.Permissions) (permission.Permissions, error) { -// tree.mu.RLock() -// defer tree.mu.RUnlock() -// -// result := make(permission.Permissions) -// exist := make(map[string]bool) -// -// for name, status := range permissions { -// if status != permission.OpenPermission { -// continue -// } -// idList, ok := tree.nameToIDs[name] -// if !ok { -// return nil, NotFoundError -// } -// for _, pid := range idList { -// node, exists := tree.nodes[pid] -// if !exists || node == nil { -// return nil, NotFoundError -// } -// // 將該節點及所有祖先標記為啟用 -// for cur := node; cur != nil && cur.Data.Name != "root"; cur = cur.Parent { -// if !exist[cur.Data.ID.Hex()] { -// result[cur.Data.Name] = permission.OpenPermission -// exist[cur.Data.ID.Hex()] = true -// } -// } -// } -// } -// -// return result, nil -//} -// -//// getFullParentPermission -//// 根據角色權限 (RolePermission) 列表,回傳完整的權限狀態(名稱->狀態),包含所有祖先 -//func (tree *PermissionTree) getFullParentPermission(rolePermissions []entity.RolePermission) permission.Permissions { -// tree.mu.RLock() -// defer tree.mu.RUnlock() -// -// result := make(permission.Permissions) -// for _, rp := range rolePermissions { -// node, ok := tree.nodes[rp.PermissionID] -// if !ok || node == nil { -// continue -// } -// // 將該節點及所有祖先設為啟用 -// for cur := node; cur != nil && cur.Data.Name != "root"; cur = cur.Parent { -// result[cur.Data.Name] = permission.OpenPermission -// } -// } -// return result -//} + for _, v := range rolePermissions { + node := tree.getNode(v.PermissionID) + + if node == nil { + return nil + } + + if _, ok := status[node.Data.Name]; ok { + continue + } + + status[node.Data.Name] = permission.StatusCode(node.Data.Status.String()) + + // 往上找node(父) + for node.Parent != nil { + np := node.Parent + if np == nil || np.Data.Name == rootName { + break + } + parent := tree.getNode(np.Data.ID.Hex()) + if parent == nil { + continue + } + + status[parent.Data.Name] = permission.StatusCode(parent.Data.Status.String()) + } + + } + + return status +} + +// getFullParentPermissionIDs 根據 permissions 找出所有完整 permission +// 比如B的父權限是A,給B權限就要回傳A與B權限id +func (tree *PermissionTree) getFullParentPermissionIDs(permissions permission.Permissions) ([]string, error) { + exist := make(map[string]bool) + ids := make([]string, 0) + + for name, status := range permissions { + if status != permission.OpenPermission { + continue + } + + pIDs, ok := tree.names[name] + if !ok { + return nil, errs.ResourceNotFound("failed to get node") + } + + for _, pID := range pIDs { + node := tree.getNode(pID) + if node == nil { + return nil, errs.ResourceNotFound("failed to get node") + } + + // 如果有子node代表不是最底層權限而是父node,就必須檢查此父node底下子node權限是否有開啟 + if len(node.Children) > 0 { + var can bool + for _, ch := range node.Children { + if v, ok := permissions[ch.Data.Name]; ok && v == permission.OpenPermission { + can = true + + break + } + } + + if !can { + continue + } + } + + for node.Parent != nil { + np := node.Parent + if np == nil || np.Data.Name == rootName { + break + } + if _, ok := exist[np.Data.ID.Hex()]; !ok { + ids = append(ids, np.Data.ID.Hex()) + exist[np.Data.ID.Hex()] = true + } + } + + } + } + + return ids, nil +} diff --git a/pkg/usecase/role.go b/pkg/usecase/role.go index fff7c17..73a29bc 100644 --- a/pkg/usecase/role.go +++ b/pkg/usecase/role.go @@ -191,7 +191,6 @@ func (use *RoleUseCase) Update(ctx context.Context, id string, data usecase.Crea err := use.roleRepository.Update(ctx, repository.UpdateReq{ ID: id, Name: &data.Name, - UID: &data.UID, ClientID: &data.ClientID, Status: &data.Status, }) diff --git a/pkg/usecase/role_permission.go b/pkg/usecase/role_permission.go index 73a7191..5a0c218 100644 --- a/pkg/usecase/role_permission.go +++ b/pkg/usecase/role_permission.go @@ -3,12 +3,17 @@ package usecase import ( "context" + "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" "code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/usecase" ) type RolePermissionUseCaseParam struct { - //rolePermissionRepository repository.RolePermissionRepository + rolePermissionRepository repository.RolePermissionRepository + permissionRepository repository.PermissionRepository + roleRepository repository.RoleRepository + userRoleRepository repository.UserRoleRepository } type RolePermissionUseCase struct { @@ -21,53 +26,144 @@ func NewRolePermissionUseCase(param RolePermissionUseCaseParam) usecase.RolePerm } } +// Get 拿到這個 Role ID 底下有哪些權限是開的 func (use *RolePermissionUseCase) Get(ctx context.Context, roleID string) (permission.Permissions, error) { - //rolePermissions, err := use.rolePermissionRepository.Get(ctx, roleID) - //if err != nil && !errors.Is(err, repository.ErrRecordNotFound) { - // return nil, usecase.InternalError{Err: fmt.Errorf("permissionRepo.Get error: %w", err)} - //} - // - //permissions, err := uc.PermissionRepo.All(ctx) - //if err != nil && !errors.Is(err, repository.ErrRecordNotFound) { - // return nil, usecase.InternalError{Err: fmt.Errorf("permissionRepo.AllStatus error: %w", err)} - //} - // - //// TODO cache http://jira.logintt.com:8080/browse/ESC-2046 - //return GeneratePermissionTree(permissions).getFullParentPermission(rolePermissions), nil - //get, err := use.rolePermissionRepository.Get(ctx, roleID) - //if err != nil { - // return nil, err - //} - // - //permissions := make(permission.Permissions, len(get)) - //for _, item := range get { - // permissions[item.PermissionID] = item. - //} - // - return permission.Permissions{}, nil -} + // 拿到這個 role 底下有哪些 Permission + rolePermission, err := use.rolePermissionRepository.Get(ctx, roleID) + if err != nil { + return nil, err + } + p, err := use.permissionRepository.GetAll(ctx, nil) // -> 開的關的 permission 都會拿到 + if err != nil { + return nil, err + } -func (use *RolePermissionUseCase) GetByRoleUID(ctx context.Context, uid string) (permission.Permissions, error) { - //TODO implement me - panic("implement me") -} - -func (use *RolePermissionUseCase) GetByUser(ctx context.Context, uid string) (usecase.UserPermission, error) { - //TODO implement me - panic("implement me") + return GeneratePermissionTree(p).getFullParentPermission(rolePermission), nil } func (use *RolePermissionUseCase) Create(ctx context.Context, roleID string, permissions permission.Permissions) error { - //TODO implement me - panic("implement me") + // 如果加了一個,要把上面的節點都加入才可以 + permissionIDs, err := use.getPermissionIDs(ctx, permissions) + if err != nil { + return err + } + insert := make([]entity.RolePermission, 0, len(permissions)) + + for _, permissionID := range permissionIDs { + insert = append(insert, entity.RolePermission{ + RoleID: roleID, + PermissionID: permissionID, + }) + } + + err = use.rolePermissionRepository.Create(ctx, insert) + if err != nil { + return err + } + + return nil +} + +func (use *RolePermissionUseCase) getPermissionIDs(ctx context.Context, setPermissions permission.Permissions) ([]string, error) { + p, err := use.permissionRepository.GetAll(ctx, nil) + if err != nil { + return nil, err + } + + return GeneratePermissionTree(p).getFullParentPermissionIDs(setPermissions) } func (use *RolePermissionUseCase) Delete(ctx context.Context, roleID string, permissions permission.Permissions) error { - //TODO implement me - panic("implement me") + // 如果加了一個,要把上面的節點都加入才可以 + permissionIDs, err := use.getPermissionIDs(ctx, permissions) + if err != nil { + return err + } + del := make([]string, 0, len(permissions)) + for _, permissionID := range permissionIDs { + del = append(del, permissionID) + } + + err = use.rolePermissionRepository.Delete(ctx, roleID, del) + if err != nil { + return err + } + + return nil } func (use *RolePermissionUseCase) List(ctx context.Context, req usecase.ListQuery) (usecase.RoleResp, error) { - //TODO implement me - panic("implement me") + roles, total, err := use.roleRepository.List(ctx, repository.ListQuery{ + PageIndex: req.PageIndex, + PageSize: req.PageSize, + ClientID: req.ClientID, + UID: req.UID, + Name: req.Name, + Status: req.Status, + }) + if err != nil { + return usecase.RoleResp{}, err + } + + result := make([]usecase.Role, 0, len(roles)) + for _, item := range roles { + result = append(result, usecase.Role{ + ID: item.ID.Hex(), + UID: item.UID, + Name: item.Name, + Status: item.Status, + ClientID: item.ClientID, + }) + } + + return usecase.RoleResp{ + Total: total, + Roles: result, + }, nil } + +//// GetByRoleUID 拿到這個 UID 底下有哪些權限是開的 +//func (use *RolePermissionUseCase) GetByRoleUID(ctx context.Context, uid string) (permission.Permissions, error) { +// permissions := make(permission.Permissions) +// +// // admin權限 +// if uid == permission.AdminRoleUID { +// data, err := use.permissionRepository.GetAll(ctx, nil) +// if err != nil { +// return nil, err +// } +// +// for _, v := range data { +// permissions[v.Name] = permission.OpenPermission +// } +// } else { +// role, err := use.roleRepository.GetByUID(ctx, uid) +// if err != nil { +// return nil, err +// } +// +// permissions, err = use.Get(ctx, role.ID.Hex()) +// if err != nil { +// return nil, err +// } +// } +// +// return permissions, nil +//} +// +//func (use *RolePermissionUseCase) GetByUser(ctx context.Context, uid string) (usecase.UserPermission, error) { +// userRole, err := use.userRoleRepository.GetByUserID(ctx, uid) +// if err != nil { +// return usecase.UserPermission{}, err +// } +// +// p, err := use.Get(ctx, userRole.RoleID) +// if err != nil { +// return usecase.UserPermission{}, err +// } +// +// return usecase.UserPermission{ +// RoleID: userRole.RoleID, +// Permissions: p, +// }, nil +//}