• 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>

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

  • 相关阅读:
    Plahte
    Sound 静音问题
    【模板】线段树 2
    winform GDI基础(四)简单截屏
    winform GDI基础(二)画带圆角的矩形框
    winform GDI基础(三)实现画笔
    winform GDI基础(一)
    winform播放视频(windows media player)
    c# 锁的使用
    C#Task学习
  • 原文地址:https://www.cnblogs.com/wishit/p/16173034.html
Copyright © 2020-2023  润新知