add get role

This commit is contained in:
daniel.w 2024-08-20 00:59:38 +08:00
parent 8ae8a17bbb
commit 2ae757f92a
7 changed files with 332 additions and 27 deletions

View File

@ -252,9 +252,9 @@ message RoleResp {
// PageResponse pager.Response // PageResponse pager.Response
message PageResponse { message PageResponse {
int32 page_index = 1; // int64 page_index = 1; //
int32 page_size = 2; // int64 page_size = 2; //
int32 total_pages = 3; // int64 total_count = 3; //
} }
// PageRoleResp Protobuf message // PageRoleResp Protobuf message

View File

@ -39,3 +39,7 @@ const (
PermissionStatusOpenCode PermissionStatus = "open" PermissionStatusOpenCode PermissionStatus = "open"
PermissionStatusCloseCode PermissionStatus = "close" PermissionStatusCloseCode PermissionStatus = "close"
) )
const (
AdminRoleID = "GodDog!@#"
)

View File

@ -1,11 +1,14 @@
package roleservicelogic package roleservicelogic
import ( import (
"context"
"ark-permission/gen_result/pb/permission" "ark-permission/gen_result/pb/permission"
"ark-permission/internal/domain"
"ark-permission/internal/entity"
"ark-permission/internal/model"
"ark-permission/internal/svc" "ark-permission/internal/svc"
ers "code.30cm.net/wanderland/library-go/errors"
"context"
"errors"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
) )
@ -25,19 +28,164 @@ func NewGetRoleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetRoleLo
// GetRole 取得搜尋的角色 // GetRole 取得搜尋的角色
func (l *GetRoleLogic) GetRole(in *permission.GetRoleReq) (*permission.GetRoleResp, error) { func (l *GetRoleLogic) GetRole(in *permission.GetRoleReq) (*permission.GetRoleResp, error) {
// filter := data *Role // 檢查是否為全表搜尋
// 是否全表搜尋
if in.GetAll() { if in.GetAll() {
// 不需要帶過濾條件 return l.getAllRoles()
}
// 處理分頁參數
size := int64(20)
if in.GetPageSize() != 0 {
size = in.GetPageSize()
}
index := int64(1)
if in.GetPageIndex() != 0 {
index = in.GetPageIndex()
}
// 執行角色搜尋和計算總數
roles, count, err := l.searchRolesWithCount(in, size, index)
if err != nil {
return nil, err
}
// 組裝結果
return l.buildRoleResp(roles, in.PageSize, in.PageIndex, count, in.GetPermissions()), nil
}
// getAllRoles 獲取全表角色
func (l *GetRoleLogic) getAllRoles() (*permission.GetRoleResp, error) {
// 查詢所有角色
roles, err := l.svcCtx.RoleRepo.Find(l.ctx)
if err != nil {
return nil, l.handleDBError(err, "failed to get role")
}
// 計算總數
count, err := l.svcCtx.RoleRepo.Count(l.ctx, &model.Role{})
if err != nil {
return nil, l.handleDBError(err, "failed to get role")
}
// 組裝結果
return l.buildRoleResp(roles, -1, -1, count, nil), nil
}
// searchRolesWithCount 搜尋角色並計算總數
func (l *GetRoleLogic) searchRolesWithCount(in *permission.GetRoleReq, size, index int64) ([]*model.Role, int64, error) {
// 搜尋角色
roles, err := l.svcCtx.RoleRepo.SearchRoles(l.ctx, &model.Role{
RoleId: in.GetRoleIds(),
DisplayName: in.GetDisplayName(),
Status: int64(in.GetStatus().Number()),
}, size, index)
if err != nil {
return nil, 0, err
}
// 計算總數
count, err := l.svcCtx.RoleRepo.Count(l.ctx, &model.Role{
RoleId: in.GetRoleIds(),
DisplayName: in.GetDisplayName(),
Status: int64(in.GetStatus().Number()),
})
if err != nil {
return nil, 0, l.handleDBError(err, "failed to get role")
}
list := make([]*model.Role, 0, count)
for _, item := range roles {
list = append(list, &item)
}
return list, count, nil
}
// handleDBError 處理資料庫錯誤
func (l *GetRoleLogic) handleDBError(err error, msg string) error {
if errors.Is(model.ErrNotFound, err) {
return ers.ResourceNotFound(msg)
}
return ers.DBError(err.Error())
}
// buildRoleResp 組裝角色回應
func (l *GetRoleLogic) buildRoleResp(roles []*model.Role, pageSize, pageIndex, totalCount int64, filter []string) *permission.GetRoleResp {
list := make([]*permission.RoleResp, 0, len(roles))
for _, item := range roles {
permissions := make(map[string]string)
// Admin 角色
if item.RoleId == domain.AdminRoleID {
data, err := l.svcCtx.Permission.FindAllOpenPermission(l.ctx)
if err != nil {
// log
continue
}
for _, v := range data {
permissions[v.Name] = string(domain.PermissionStatusOpenCode)
}
} else {
rolePermission, err := l.svcCtx.RolePermissionRepo.FindOneByRoleID(l.ctx, item.RoleId)
if err != nil {
// log
continue
}
var rp = make([]entity.RolePermission, 0, len(rolePermission))
for _, item := range rolePermission {
rp = append(rp, entity.RolePermission{
ID: item.Id,
RoleID: item.RoleId.Int64,
PermissionID: item.PermissionId.Int64,
CreateTime: item.CreateTime,
UpdateTime: item.UpdateTime,
})
} }
// RoleIds string `protobuf:"bytes,1,opt,name=role_ids,json=roleIds,proto3" json:"role_ids,omitempty"` userRolePermission, err := l.svcCtx.PermissionTree.GetRolePermissionTree(rp)
// DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` if err != nil {
// Permissions []string `protobuf:"bytes,3,rep,name=permissions,proto3" json:"permissions,omitempty"` return nil
// Status PermissionStatus `protobuf:"varint,4,opt,name=status,proto3,enum=permission.PermissionStatus" json:"status,omitempty"` }
// PageIndex int64 `protobuf:"varint,5,opt,name=page_index,json=pageIndex,proto3" json:"page_index,omitempty"`
// PageSize int64 `protobuf:"varint,6,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` if filter == nil {
list = append(list, &permission.RoleResp{
return &permission.GetRoleResp{}, nil Id: item.Id,
DisplayName: item.DisplayName,
RoleId: item.RoleId,
Status: permission.PermissionStatus(item.Status),
Permissions: permissions,
CreateTime: item.CreateTime,
UpdateTime: item.UpdateTime,
})
} else {
for _, p := range filter {
if userRolePermission[p] == domain.PermissionStatusOpenCode {
list = append(list, &permission.RoleResp{
Id: item.Id,
DisplayName: item.DisplayName,
RoleId: item.RoleId,
Status: permission.PermissionStatus(item.Status),
Permissions: permissions,
CreateTime: item.CreateTime,
UpdateTime: item.UpdateTime,
})
break
}
}
}
}
}
return &permission.GetRoleResp{
List: list,
Page: &permission.PageResponse{
PageSize: pageSize,
PageIndex: pageIndex,
TotalCount: totalCount,
},
}
} }

View File

@ -2,8 +2,11 @@ package model
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx" "github.com/zeromicro/go-zero/core/stores/sqlx"
"strings"
"time" "time"
) )
@ -25,6 +28,9 @@ type (
session sqlx.Session, session sqlx.Session,
roleId string, roleId string,
displayName string) error displayName string) error
Find(ctx context.Context) ([]*Role, error)
Count(ctx context.Context, role *Role) (int64, error)
SearchRoles(ctx context.Context, role *Role, pageIndex, PageSize int64) (result []Role, err error)
} }
customRoleModel struct { customRoleModel struct {
@ -82,3 +88,99 @@ func (m *customRoleModel) TransUpdateStatusByRoleID(
_, err := session.ExecCtx(ctx, query, status, updateTime, roleId) _, err := session.ExecCtx(ctx, query, status, updateTime, roleId)
return err return err
} }
func (m *defaultRoleModel) Find(ctx context.Context) ([]*Role, error) {
query := fmt.Sprintf("select %s from %s", roleRows, m.table)
var resp []*Role
err := m.conn.QueryRowsCtx(ctx, &resp, query)
switch {
case err == nil:
return resp, nil
case errors.Is(err, sqlc.ErrNotFound):
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultRoleModel) Count(ctx context.Context, role *Role) (int64, error) {
var conditions []string
var args []any
// 構建條件
if role.RoleId != "" {
conditions = append(conditions, "`role_id` = ?")
args = append(args, role.RoleId)
}
if role.DisplayName != "" {
conditions = append(conditions, "`display_name` = ?")
args = append(args, role.DisplayName)
}
if role.Status != 0 {
conditions = append(conditions, "`status` = ?")
args = append(args, role.Status)
}
// 構建基礎查詢語句
query := fmt.Sprintf("select COUNT(*) from %s", m.table)
// 如果有條件,添加 WHERE 子句
if len(conditions) > 0 {
query += " where " + strings.Join(conditions, " AND ")
}
var resp int64
err := m.conn.QueryRowCtx(ctx, &resp, query, args...)
switch {
case err == nil:
return resp, nil
case errors.Is(err, sqlc.ErrNotFound):
return 0, ErrNotFound
default:
return 0, err
}
}
func (m *customRoleModel) SearchRoles(ctx context.Context, role *Role, pageIndex, PageSize int64) (result []Role, err error) {
var conditions []string
var args []any
// 構建條件
if role.RoleId != "" {
conditions = append(conditions, "`role_id` = ?")
args = append(args, role.RoleId)
}
if role.DisplayName != "" {
conditions = append(conditions, "`display_name` = ?")
args = append(args, role.DisplayName)
}
if role.Status != 0 {
conditions = append(conditions, "`status` = ?")
args = append(args, role.Status)
}
// 構建基礎查詢語句
query := fmt.Sprintf("select * from %s", m.table)
// 如果有條件,添加 WHERE 子句
if len(conditions) > 0 {
query += " where " + strings.Join(conditions, " AND ")
}
// 添加排序和分頁
query += " order by `id` desc limit ? offset ?"
args = append(args, PageSize, (pageIndex-1)*PageSize)
// 執行查詢
err = m.conn.QueryRowCtx(ctx, &result, query, args...)
switch {
case err == nil:
return result, nil
case errors.Is(err, sqlc.ErrNotFound):
return nil, ErrNotFound
default:
return nil, err
}
}

View File

@ -1,6 +1,11 @@
package model package model
import "github.com/zeromicro/go-zero/core/stores/sqlx" import (
"context"
"fmt"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ RolePermissionModel = (*customRolePermissionModel)(nil) var _ RolePermissionModel = (*customRolePermissionModel)(nil)
@ -9,6 +14,7 @@ type (
// and implement the added methods in customRolePermissionModel. // and implement the added methods in customRolePermissionModel.
RolePermissionModel interface { RolePermissionModel interface {
rolePermissionModel rolePermissionModel
FindOneByRoleID(ctx context.Context, roleID string) ([]*RolePermission, error)
} }
customRolePermissionModel struct { customRolePermissionModel struct {
@ -22,3 +28,17 @@ func NewRolePermissionModel(conn sqlx.SqlConn) RolePermissionModel {
defaultRolePermissionModel: newRolePermissionModel(conn), defaultRolePermissionModel: newRolePermissionModel(conn),
} }
} }
func (m *customRolePermissionModel) FindOneByRoleID(ctx context.Context, roleID string) ([]*RolePermission, error) {
var resp []*RolePermission
query := fmt.Sprintf("select %s from %s where `role_id` = ?", userRoleRows, m.table)
err := m.conn.QueryRowsCtx(ctx, &resp, query, roleID)
switch err {
case nil:
return resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}

View File

@ -1,6 +1,8 @@
package model package model
import "github.com/zeromicro/go-zero/core/stores/sqlx" import (
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ UserRoleModel = (*customUserRoleModel)(nil) var _ UserRoleModel = (*customUserRoleModel)(nil)

View File

@ -2,8 +2,10 @@ package svc
import ( import (
"ark-permission/internal/config" "ark-permission/internal/config"
"ark-permission/internal/domain"
"ark-permission/internal/domain/repository" "ark-permission/internal/domain/repository"
domainUseCase "ark-permission/internal/domain/usecase" domainUseCase "ark-permission/internal/domain/usecase"
"ark-permission/internal/entity"
"ark-permission/internal/lib/required" "ark-permission/internal/lib/required"
"ark-permission/internal/model" "ark-permission/internal/model"
repo "ark-permission/internal/repository" repo "ark-permission/internal/repository"
@ -22,10 +24,12 @@ type ServiceContext struct {
Redis redis.Redis Redis redis.Redis
TokenRedisRepo repository.TokenRepository TokenRedisRepo repository.TokenRepository
PolicyAgent domainUseCase.OpaUseCase PolicyAgent domainUseCase.OpaUseCase
PermissionTree usecase.PermissionTree
Conn sqlx.SqlConn Conn sqlx.SqlConn
Permission model.PermissionModel Permission model.PermissionModel
RoleRepo model.RoleModel RoleRepo model.RoleModel
RolePermissionRepo model.RolePermissionModel
} }
func NewServiceContext(c config.Config) *ServiceContext { func NewServiceContext(c config.Config) *ServiceContext {
@ -47,6 +51,30 @@ func NewServiceContext(c config.Config) *ServiceContext {
panic(err) panic(err)
} }
t := usecase.NewPermissionTree()
pm := model.NewPermissionModel(sqlConn)
permission, err := pm.FindAllOpenPermission(context.Background())
if err != nil {
panic(err)
}
for _, item := range permission {
err := t.AddPermission(item.Id, entity.Permission{
ID: item.Id,
Parent: item.Parent.Int64,
Name: item.Name,
HTTPPath: item.HttpPath,
HTTPMethod: item.HttpMethod,
Status: int(item.Status),
Type: domain.PermissionType(item.Type),
CreateTime: item.CreateTime,
UpdateTime: item.UpdateTime,
})
if err != nil {
continue
}
}
return &ServiceContext{ return &ServiceContext{
Config: c, Config: c,
Validate: required.MustValidator(), Validate: required.MustValidator(),
@ -55,9 +83,10 @@ func NewServiceContext(c config.Config) *ServiceContext {
Store: newRedis, Store: newRedis,
}), }),
PolicyAgent: pa, PolicyAgent: pa,
PermissionTree: *t,
Permission: model.NewPermissionModel(sqlConn), Permission: pm,
RoleRepo: model.NewRoleModel(sqlConn), RoleRepo: model.NewRoleModel(sqlConn),
RolePermissionRepo: model.NewRolePermissionModel(sqlConn),
Conn: sqlConn, Conn: sqlConn,
} }
} }