一步步实现微服务权限管理系统(12)
前言
- 前端参考了很多框架,可谓百花齐放,但很多封装过剩,不利于学习和应用,最终我选择了 [vue-pure-admin](https://github.com/pure-admin/vue-pure-admin)
- 后端我将使用 go-zero 来带领大家一步步实现一个权限管理系统
- 本系列项目存放在 purezeroadmin 中,每一部分我都将打tag,并保证每个tag能正常运行。请多点赞和评论。
- 后面示例均为
purezeroadmin
项目为例,你们可以根据需要自建工程来进行试验。均采用vscode
进行试验。 go-zero
常用命令我将放入其对应的makefile
文件中。
本节概述
- 前端角色管理相关逻辑修改
- 后端增加相应数据和接口
前端修改
src/views/system/role/utils/hook.tsx
- 状态值改为数字
const form = reactive({
name: "",
code: "",
status: 1
});
- 页码和页大小作为参数传递
async function onSearch() {
loading.value = true;
const { data } = await getRoleList({
...toRaw(form),
page: pagination.currentPage,
pageSize: pagination.pageSize
});
dataList.value = data.list;
pagination.total = data.total;
setTimeout(() => {
loading.value = false;
}, 500);
}
src/views/system/role/index.vue
状态值改为数字
<el-option label="已启用" :value="1" />
<el-option label="已停用" :value="0" />
src/api/system.ts
获取角色菜单改为 get
方式
/** 获取角色管理-权限-菜单权限 */
export const getRoleMenu = (data?: object) => {
return http.request<Result>("get", "/api/role-menu", { data });
};
后端修改
user-api/api/user.api
改动
增加 /api/role
/api/role-menu
/api/role-menu-ids
3个路由,用于查询角色,查询角色菜单,查询角色菜单所有id
type (
UserRoleReq {
Name string `json:"name,optional"`
Code string `json:"code,optional"`
Status *int64 `json:"status,optional"`
Page int64 `json:"page,default=1"`
PageSize int64 `json:"pageSize,default=10"`
}
UserRoleData {
Id int64 `json:"id"`
Code string `json:"code"`
Name string `json:"name"`
Status int64 `json:"status"`
Remark string `json:"remark"`
CreateTime int64 `json:"createTime"`
UpdateTime int64 `json:"updateTime"`
}
UserRoleResp {
List []*UserRoleData `json:"list"`
Total int64 `json:"total"`
}
)
@server (
jwt: Auth // 开启 jwt 认证
)
service user-api {
@doc "获取路由"
@handler userRole
post /api/role (UserRoleReq) returns ([]*UserRoleResp)
}
type (
UserRoleMenuReq {}
UserRoleMenu {
ParentId int64 `json:"parentId"`
Id int64 `json:"id"`
MenuType int64 `json:"menuType"`
Title string `json:"title"`
}
)
@server (
jwt: Auth // 开启 jwt 认证
)
service user-api {
@doc "获取菜单"
@handler userMenu
get /api/role-menu (UserRoleMenuReq) returns ([]*UserRoleMenu)
}
type (
UserRoleMenuIDReq {
Id int64 `json:"id"`
}
)
@server (
jwt: Auth // 开启 jwt 认证
)
service user-api {
@doc "获取菜单详情"
@handler userMenuID
post /api/role-menu-ids (UserRoleMenuIDReq) returns ([]int64)
}
models
文件夹修改
user-api/models/tbrolemodel.go
增加根据状态值筛选
TbRoleModel interface {
tbRoleModel
withSession(session sqlx.Session) TbRoleModel
FindAll(ctx context.Context) ([]*TbRole, error)
FindList(ctx context.Context, name, code string, status *int64, page, pageSize int64) ([]*TbRole, int64, error)
}
...
func (m *customTbRoleModel) FindList(ctx context.Context, name, code string, status *int64, page, pageSize int64) ([]*TbRole, int64, error) {
base := ""
needAnd := false
if name != "" {
base += fmt.Sprintf("name = '%s'", name)
needAnd = true
}
if code != "" {
if needAnd {
base += " and "
}
base += fmt.Sprintf("code = '%s'", code)
}
if status != nil {
if needAnd {
base += " and "
}
base += fmt.Sprintf("status = %v", *status)
}
if base != "" {
base = " where " + base
}
var total int64
err := m.conn.QueryRowCtx(ctx, &total, "select count(*) from tb_role"+base)
if err != nil {
return nil, 0, err
}
var list []*TbRole
err = m.conn.QueryRowsCtx(ctx, &list, fmt.Sprintf("select * from tb_role%s limit ?,?", base), (page-1)*pageSize, pageSize)
return list, total, err
}
user-api/models/tbroutermodel.go
增加获取所有路由
...
func (m *customTbRouterModel) FindAll(ctx context.Context) ([]*TbRouter, error) {
var resp []*TbRouter
err := m.conn.QueryRowsCtx(ctx, &resp, "select * from tb_router")
return resp, err
}
user-api/helper/helper.go
增加
func GetAuthsInfos(ctx context.Context, svcCtx *svc.ServiceContext) (tbUser *models.TbUser, mTbRole map[int64]*models.TbRole, err error) {
userID, err := GetUserIDFromContext(ctx)
if err != nil {
return nil, nil, err
}
tbUser, err = svcCtx.TbUserModel.FindOne(ctx, userID)
if err != nil {
return nil, nil, err
}
mTbRole = make(map[int64]*models.TbRole)
if tbUser.Username == "admin" {
tbRoles, err := svcCtx.TbRoleModel.FindAll(ctx)
if err != nil {
return nil, nil, err
}
for _, tbRole := range tbRoles {
mTbRole[tbRole.Id] = tbRole
}
return tbUser, mTbRole, nil
}
roles, err := jsonutil.ToArray[string](tbUser.Roles)
if err != nil {
return nil, nil, err
}
for _, role := range roles {
tbRole, err := svcCtx.TbRoleModel.FindOneByCode(ctx, role)
if err != nil {
return nil, nil, err
}
mTbRole[tbRole.Id] = tbRole
}
return tbUser, mTbRole, nil
}
logic修改
user-api/internal/logic/usermenuidlogic.go
根据角色ID获取菜单ID
func (l *UserMenuIDLogic) UserMenuID(req *types.UserRoleMenuIDReq) (resp []int64, err error) {
_, mTbRole, err := helper.GetAuthsInfos(l.ctx, l.svcCtx)
if err != nil {
return nil, err
}
tbRole, ok := mTbRole[req.Id]
if !ok {
return nil, errors.New("无对应校色权限")
}
rolePermissions, err := jsonutil.ToArray[string](tbRole.Permissions)
if err != nil {
return nil, err
}
routers, err := l.svcCtx.TbRouterModel.FindAll(l.ctx)
if err != nil {
return nil, err
}
for _, router := range routers {
if !helper.RouterPass(l.svcCtx, router, []string{tbRole.Code}, rolePermissions) {
continue
}
resp = append(resp, router.Id)
}
return resp, nil
}
user-api/internal/logic/userrolelogic.go
获取角色数据
func (l *UserRoleLogic) UserRole(req *types.UserRoleReq) (resp *types.UserRoleResp, err error) {
list, total, err := l.svcCtx.TbRoleModel.FindList(l.ctx, req.Name, req.Code, req.Status, req.Page, req.PageSize)
if err != nil {
return nil, err
}
resp = &types.UserRoleResp{
List: make([]*types.UserRoleData, len(list)),
Total: total,
}
for i, tbRole := range list {
resp.List[i] = &types.UserRoleData{
Id: tbRole.Id,
Code: tbRole.Code,
Name: tbRole.Name,
Status: tbRole.Status,
Remark: tbRole.Remark,
CreateTime: tbRole.CreateTs,
UpdateTime: tbRole.UpdateTs,
}
}
return resp, nil
}
user-api/internal/logic/usermenulogic.go
获取角色菜单数据
func (l *UserMenuLogic) UserMenu(req *types.UserRoleMenuReq) (resp []*types.UserRoleMenu, err error) {
userID, err := helper.GetUserIDFromContext(l.ctx)
if err != nil {
return nil, err
}
tbUser, err := l.svcCtx.TbUserModel.FindOne(l.ctx, userID)
if err != nil {
return nil, err
}
roles, permissions, err := helper.GetAuths(l.ctx, l.svcCtx, tbUser)
if err != nil {
return nil, err
}
err = l.GetMenuByParentID(0, roles, permissions, &resp)
if err != nil {
return nil, err
}
return resp, nil
}
func (l *UserMenuLogic) GetMenuByParentID(parentID int64, roles, permissions []string, roleMenus *[]*types.UserRoleMenu) (err error) {
routers, err := l.svcCtx.TbRouterModel.FindAllFromParentID(l.ctx, parentID)
if err != nil {
return err
}
for _, v := range routers {
if pass := helper.RouterPass(l.svcCtx, v, roles, permissions); pass {
*roleMenus = append(*roleMenus, &types.UserRoleMenu{
ParentId: v.ParentId,
Id: v.Id,
MenuType: v.MenuType,
Title: v.MetaTitle,
})
err = l.GetMenuByParentID(v.Id, roles, permissions, roleMenus)
if err != nil {
return err
}
}
}
return nil
}
测试
- 前端测试,可发现权限页面出现
- 权限获取正常
tag版本
purezeroadmin
项目下
git checkout v1.11.0
接下来
权限编辑