vboot框架 后台动态获取权限的实现方法

vboot框架 后台动态获取权限的实现方法

前言:

  以前用的框架总感觉有不舒服的地方,然后就一直在寻找一个理想的框架,研究了几十个框架,vboot框架让我眼前一亮,

上手后发现服务端权限角色功能没有实现,一度想抛弃,后来下决心费点功夫补充一下,没办法实在太喜欢这个框架了,

还有很多需要完善的地方,目前只实现了:用户的角色权限(菜单权限、按钮权限)的基本功能,其他的(部门权限、岗位权限、群组权限)没有实现

 基本能满足一般项目的要求

感谢框架的作者,也感谢我的好友“风清扬”给与的大力帮助,水平有限仅供参考,欢迎提出宝贵意见

 

相关文档:https://vvbin.cn/doc-next/guide/auth.html#%E5%90%8E%E5%8F%B0%E5%8A%A8%E6%80%81%E8%8E%B7%E5%8F%96

一、vboot-net后台需要修改的几个地方:

1、SysOrgUser.cs增加一个字段

    [SugarColumn(ColumnDescription = "系统管理员", DefaultValue="0", IsNullable = true)]
    public int AdminType { get; set; }

2、AdminType.cs 修改:普通账号 None=0

public enum AdminType
    {
        /// <summary>
        /// 超级管理员
        /// </summary>
        [Description("超级管理员")]
        SuperAdmin = 1,

        /// <summary>
        /// 管理员
        /// </summary>
        [Description("管理员")]
        Admin = 2,

        /// <summary>
        /// 普通账号
        /// </summary>
        [Description("普通账号")]
        None = 0
    }

3、PubAuthInitService.cs 

  所有的comp = "/sys/org/dept/index.vue"去掉【.vue】,前端会自动补上.vue,

  否则找不到页面,如果数据库已生成可直接改数据库表的数据

 二、vboot-net后台

1、PubAuthApi.cs增加以下接口

     [HttpGet("/getMenuList")]
        [AllowAnonymous]
        public async Task<dynamic> getMenuList()
        {
            //生成树形菜单
            List<RouteItem> treelist = await _loginService.GetMenuList(_userManager.UserId, _userManager.User.AdminType);
            return treelist;
        }

        [HttpGet("/getPermCode")]
        [AllowAnonymous]
        public async Task<List<string>> getPermCode()
        {
            //按钮权限标识
            List<string> permlist = await _loginService.GetPermCode(_userManager.UserId, _userManager.User.AdminType);
            return permlist;
        }

2、LoginService.cs的完整代码如下

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Furion.DependencyInjection;
using Furion.FriendlyException;
using SqlSugar;
using Vboot.Core.Common;
using Vboot.Core.Module.Pub.Auth;
using Vboot.Core.Module.Sys;

namespace Vboot.Core.Module.Pub
{
    public class LoginService : ITransient
    {
        private readonly ISqlSugarRepository<SysOrgUser> _repo;

        public LoginService(ISqlSugarRepository<SysOrgUser> repo)
        {
            _repo = repo;
        }
        
        public async Task<DbUser> getDbUser(string username)
        {
            const string sql = "select id,name,pacod,retag from sys_org_user where usnam=@username and avtag=1";
            var dbUser = await _repo.Ado.SqlQuerySingleAsync<DbUser>(sql, new{username});
            // if (dbUser == null)
            // {
            //     throw new Exception("账号不存在或密码错误");
            // }
            if (dbUser == null)
            {
                throw Oops.Oh(ErrorCode.D1000);
            }
            return dbUser;
        }

        /// <summary>
        /// 根据当前登录用户生成菜单树
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="admintype"></param>
        /// <returns></returns>
        public async Task<List<RouteItem>> GetMenuList(string userid, int admintype)
        {
            List<RouteItem> rootList = await GetRootList(userid, admintype);
            List<RouteItem> routeList = await GetRouteList(userid, admintype);
            List<RouteItem> treelist = GetMenuTreeList(routeList, rootList);
            return treelist;
        }

        /// <summary>
        /// 获取当前登录用户的PermCode
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="admintype"></param>
        /// <returns></returns>
        public async Task<List<string>> GetPermCode(string userid, int admintype)
        {
            List<string> perm = new List<string>();
            string sql;
            if (admintype == (int)AdminType.SuperAdmin)
            {
                sql = $@"SELECT perm 
                        FROM sys_auth_menu 
                        WHERE type='B'";
            }
            else
            {
                sql = $@"SELECT perm 
                            FROM sys_auth_menu 
                            WHERE type='B' AND shtag=1 AND avtag=1 AND id IN 
                            (
                                SELECT mid
                                FROM sys_auth_role_menu a 
                                LEFT JOIN sys_auth_role_org b ON b.rid=a.rid 
                                WHERE b.oid='{userid}'
                            )";
            }
            List<SysAuthMenu> menulist = await _repo.Context.SqlQueryable<SysAuthMenu>(sql).ToListAsync();
            for (int i = 0; i < menulist.Count; i++)
            {
                perm.Add(menulist[i].perm);
            }
            return perm;
        }

        /// <summary>
        /// 从数据库获取菜单列表转换成前端需要的格式
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="admintype"></param>
        /// <returns></returns>
        private async Task<List<RouteItem>> GetRouteList(string userid, int admintype)
        {
            string sql;
            if (admintype == (int)AdminType.SuperAdmin)
            {
                sql = $@"SELECT id,pid,ornum,name,icon,path,comp,code,redirect 
                        FROM sys_auth_menu 
                        where type!='B' 
                        ORDER BY ornum";
            }
            else
            {
                sql = $@"SELECT id,pid,ornum,name,icon,path,comp,code,redirect  
                        FROM sys_auth_menu 
                        WHERE type!='B' AND shtag=1 AND avtag=1 and id IN 
                        (
                            SELECT a.mid  
                            FROM sys_auth_role_menu a 
                            LEFT JOIN sys_auth_role b ON b.id=a.rid 
                            LEFT JOIN sys_auth_role_org c ON c.rid=b.id 
                            WHERE c.oid='{userid}'  
                        )
                        ORDER BY ornum";
            }
            List<RouteItem> routelist = await ToWebmenuList(sql);
            return routelist;
        }

        /// <summary>
        /// 取当前登录用户权限的根菜单列表
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="admintype"></param>
        /// <returns></returns>
        private async Task<List<RouteItem>> GetRootList(string userid, int admintype)
        {
            string sql;
            if (admintype == (int)AdminType.SuperAdmin)
            {
                sql = $@"SELECT id,pid,ornum,name,icon,path,comp,code,redirect 
                        FROM sys_auth_menu 
                        WHERE pid is null and type!='B' 
                        ORDER BY ornum";
            }
            else
            {
                sql = $@"SELECT id,pid,ornum,name,icon,path,comp,code,redirect 
                        FROM sys_auth_menu 
                        WHERE id IN
                        (
                            SELECT pid 
                            FROM 
                            (
                                SELECT id,pid,ornum,name,icon,path,comp,code,redirect 
                                FROM sys_auth_menu 
                                WHERE type!='B' AND shtag=1 AND avtag=1 and id IN 
                                (
                                    SELECT a.mid  
                                    FROM sys_auth_role_menu a 
                                    LEFT JOIN sys_auth_role b ON b.id=a.rid 
                                    LEFT JOIN sys_auth_role_org c ON c.rid=b.id 
                                    WHERE c.oid='{userid}' 
                                )
                            ) a 
                        ) 
                        AND id NOT IN
                        (
                            SELECT id 
                            FROM 
                            (
                                SELECT id,pid,ornum,name,icon,path,comp,code,redirect 
                                FROM sys_auth_menu 
                                WHERE type!='B' AND shtag=1 AND avtag=1 and id IN 
                                (
                                    SELECT a.mid  
                                    FROM sys_auth_role_menu a 
                                    LEFT JOIN sys_auth_role b ON b.id=a.rid 
                                    LEFT JOIN sys_auth_role_org c ON c.rid=b.id 
                                    WHERE c.oid='{userid}'
                                )
                            ) b 
                        ) 
                        ORDER BY ornum";
            }
            List<RouteItem> rootlist = await ToWebmenuList(sql);
            return rootlist;
        }

        /// <summary>
        /// 取菜单列表转web端格式列表
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        private async Task<List<RouteItem>> ToWebmenuList(string sql)
        {
            List<RouteItem> list = new List<RouteItem>();
            var menulist = await _repo.Context
                .SqlQueryable<SysAuthMenu>(sql)
                .ToListAsync();
            for (int i = 0; i < menulist.Count; i++)
            {
                RouteMeta meta = new RouteMeta();
                meta.orderNo = menulist[i].ornum;
                meta.icon = menulist[i].icon;
                meta.title = menulist[i].name;

                RouteItem item = new RouteItem();
                item.id = menulist[i].id;
                item.pid = menulist[i].pid;
                item.path = menulist[i].path;
                item.component = menulist[i].comp;
                //item.component = "/sys/auth/role/index";
                item.name = menulist[i].code;
                item.redirect = menulist[i].redirect;
                item.meta = meta;
                item.children = new List<RouteItem>();

                list.Add(item);
            }
            return list;
        }
        /// <summary>
        /// 生成树形菜单
        /// </summary>
        /// <param name="menulist"></param>
        /// <param name="rootlist"></param>
        /// <returns></returns>
        private List<RouteItem> GetMenuTreeList(List<RouteItem> menulist, List<RouteItem> rootlist)
        {
            if (menulist == null)
            {
                menulist = new List<RouteItem>();
            }
            List<RouteItem> treelist = new List<RouteItem>();
            treelist.AddRange(rootlist);
            GetChildrenList(menulist, rootlist);
            return treelist;
        }
        /// <summary>
        /// 取子菜单
        /// </summary>
        /// <param name="menulist"></param>
        /// <param name="plist"></param>
        private void GetChildrenList(List<RouteItem> menulist, List<RouteItem> plist)
        {
            foreach (RouteItem item in plist)
            {
                List<RouteItem> childrenlist = menulist.Where(p => p.pid == item.id).ToList();
                item.children.AddRange(childrenlist);
                GetChildrenList(menulist, childrenlist);
            }
        }
    }
    public class RouteMeta
    {
        public int? orderNo { get; set; }
        // title
        public string title { get; set; }
        //// dynamic router level.
        //public int? dynamicLevel{get;set;}
        //// dynamic router real route path (For performance).
        //public string realPath{get;set;}
        //// Whether to ignore permissions
        //public bool? ignoreAuth{get;set;}
        //// role info RoleEnum[]
        //public object roles { get; set; }
        //// Whether not to cache
        //ignoreKeepAlive?: boolean;
        //// Is it fixed on tab
        //affix?: boolean;
        //icon on tab
        public string icon { get; set; }
        //frameSrc?: string;
        //// current page transition
        //transitionName?: string;
        //// Whether the route has been dynamically added
        //hideBreadcrumb?: boolean;
        //// Hide submenu
        //hideChildrenInMenu?: boolean;
        //// Carrying parameters
        //carryParam?: boolean;
        //// Used internally to mark single-level menus
        //single?: boolean;
        //// Currently active menu
        //currentActiveMenu?: string;
        //// Never show in tab
        //hideTab?: boolean;
        //// Never show in menu
        //hideMenu?: boolean;
        //isLink?: boolean;
        //// only build for Menu
        //ignoreRoute?: boolean;
        //// Hide path for children
        //hidePathForChildren?: boolean;
    }
    public class RouteItem
    {
        public string id { get; set; }
        public string pid { get; set; }
        public string path { get; set; }
        //  component: any;
        public object component { get; set; }

        public RouteMeta meta { get; set; }
        public string name { get; set; }
        //alias?: string | string[];
        public string redirect { get; set; }
        //public bool? caseSensitive{get;set;}
        public List<RouteItem> children { get; set; }
    }
}

三、前端vboot-vben

1、projectSetting.ts 权限模式改为 BACK 模式

// Permission mode
  //permissionMode: PermissionModeEnum.ROUTE_MAPPING,
  permissionMode: PermissionModeEnum.BACK,

2、BACK模式下默认访问views路径不是pages路径,所以要把pages下相应的目录及文件要拷贝到views下,如下图所示:

3、前端按钮权限的实现 v-auth="'权限标识'"

<vxe-button v-auth="'dept:delete'" @click="deleteEvent($refs.xGrid)">删 除</vxe-button>

到此,用户的菜单权限、按钮权限基本就完成了,亲测可用

 

posted @ 2022-04-21 16:19  中国结  阅读(521)  评论(0编辑  收藏  举报