add get role
This commit is contained in:
parent
8ae8a17bbb
commit
2ae757f92a
|
@ -252,9 +252,9 @@ message RoleResp {
|
|||
|
||||
// 定義 PageResponse 用來對應 pager.Response
|
||||
message PageResponse {
|
||||
int32 page_index = 1; // 頁碼
|
||||
int32 page_size = 2; // 每頁顯示數量
|
||||
int32 total_pages = 3; // 總頁數
|
||||
int64 page_index = 1; // 頁碼
|
||||
int64 page_size = 2; // 每頁顯示數量
|
||||
int64 total_count = 3; // 總頁數
|
||||
}
|
||||
|
||||
// PageRoleResp 對應的 Protobuf message
|
||||
|
|
|
@ -39,3 +39,7 @@ const (
|
|||
PermissionStatusOpenCode PermissionStatus = "open"
|
||||
PermissionStatusCloseCode PermissionStatus = "close"
|
||||
)
|
||||
|
||||
const (
|
||||
AdminRoleID = "GodDog!@#"
|
||||
)
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package roleservicelogic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"ark-permission/gen_result/pb/permission"
|
||||
"ark-permission/internal/domain"
|
||||
"ark-permission/internal/entity"
|
||||
"ark-permission/internal/model"
|
||||
"ark-permission/internal/svc"
|
||||
|
||||
ers "code.30cm.net/wanderland/library-go/errors"
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
|
@ -25,19 +28,164 @@ func NewGetRoleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetRoleLo
|
|||
|
||||
// GetRole 取得搜尋的角色
|
||||
func (l *GetRoleLogic) GetRole(in *permission.GetRoleReq) (*permission.GetRoleResp, error) {
|
||||
// filter := data *Role
|
||||
// 是否全表搜尋
|
||||
// 檢查是否為全表搜尋
|
||||
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"`
|
||||
// DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
|
||||
// Permissions []string `protobuf:"bytes,3,rep,name=permissions,proto3" json:"permissions,omitempty"`
|
||||
// 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"`
|
||||
userRolePermission, err := l.svcCtx.PermissionTree.GetRolePermissionTree(rp)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &permission.GetRoleResp{}, nil
|
||||
if filter == nil {
|
||||
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,
|
||||
})
|
||||
} 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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,11 @@ package model
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -25,6 +28,9 @@ type (
|
|||
session sqlx.Session,
|
||||
roleId string,
|
||||
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 {
|
||||
|
@ -82,3 +88,99 @@ func (m *customRoleModel) TransUpdateStatusByRoleID(
|
|||
_, err := session.ExecCtx(ctx, query, status, updateTime, roleId)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
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)
|
||||
|
||||
|
@ -9,6 +14,7 @@ type (
|
|||
// and implement the added methods in customRolePermissionModel.
|
||||
RolePermissionModel interface {
|
||||
rolePermissionModel
|
||||
FindOneByRoleID(ctx context.Context, roleID string) ([]*RolePermission, error)
|
||||
}
|
||||
|
||||
customRolePermissionModel struct {
|
||||
|
@ -22,3 +28,17 @@ func NewRolePermissionModel(conn sqlx.SqlConn) RolePermissionModel {
|
|||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package model
|
||||
|
||||
import "github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ UserRoleModel = (*customUserRoleModel)(nil)
|
||||
|
||||
|
|
|
@ -2,8 +2,10 @@ package svc
|
|||
|
||||
import (
|
||||
"ark-permission/internal/config"
|
||||
"ark-permission/internal/domain"
|
||||
"ark-permission/internal/domain/repository"
|
||||
domainUseCase "ark-permission/internal/domain/usecase"
|
||||
"ark-permission/internal/entity"
|
||||
"ark-permission/internal/lib/required"
|
||||
"ark-permission/internal/model"
|
||||
repo "ark-permission/internal/repository"
|
||||
|
@ -22,10 +24,12 @@ type ServiceContext struct {
|
|||
Redis redis.Redis
|
||||
TokenRedisRepo repository.TokenRepository
|
||||
PolicyAgent domainUseCase.OpaUseCase
|
||||
PermissionTree usecase.PermissionTree
|
||||
|
||||
Conn sqlx.SqlConn
|
||||
Permission model.PermissionModel
|
||||
RoleRepo model.RoleModel
|
||||
RolePermissionRepo model.RolePermissionModel
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
|
@ -47,6 +51,30 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
|||
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{
|
||||
Config: c,
|
||||
Validate: required.MustValidator(),
|
||||
|
@ -55,9 +83,10 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
|||
Store: newRedis,
|
||||
}),
|
||||
PolicyAgent: pa,
|
||||
|
||||
Permission: model.NewPermissionModel(sqlConn),
|
||||
PermissionTree: *t,
|
||||
Permission: pm,
|
||||
RoleRepo: model.NewRoleModel(sqlConn),
|
||||
RolePermissionRepo: model.NewRolePermissionModel(sqlConn),
|
||||
Conn: sqlConn,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue