• SAAS云平台搭建札记: (三) AntDesign + .Net Core WebAPI权限控制、动态菜单的生成


    我们知道,当下最火的前端框架,非蚂蚁金服的 AntDesign 莫属,这个框架不仅在国内非常有名,在国外GitHub上React前端框架也排名第一。而且这个框架涵盖了React、Vue、Angular等多种语言,甚至有人结合.net Core 5的新特性WebAssembly 做了Ant Design Blazor,在此为国人点赞!

    公司的新平台,用户前端界面当仁不让地使用了AntDesign for React,可以使用最新版本的特性(目前版本为4.10.1);至于为什么不使用Ant Design Pro,是因为Pro封装的控件太多,不利于我们自定义页面。

    SAAS系统,页面上首先就是权限,我们后台采用中等复杂度的RBAC控制,如图所示:

    在界面上表示,就是程序左侧的树状菜单,参照AntdPro的官方文档,路由和菜单,需要在菜单的ts文档中写清楚各种权限组和相应菜单,显然不符合我们前后端分离使用动态菜单的方法。

    因此,我研究一段时间,终于找到完全在后端生成动态菜单并且在前端的使用方法,特此分享给大家。

    传递到前端的菜单实体类:

    1     public class 菜单实体类
    2     {
    3         public string key { get; set; }
    4         public string icon { get; set; }
    5         public string title { get; set; }
    6         public string link { get; set; }
    7         public IEnumerable<PortalMenu> children { get; set; }
    8     }

    实际上是一个递归结构的json字符串:

      1 {
      2     "returnCode": 0,
      3     "errorMsg": null,
      4     "data": {
      5         "portalMenus": [{
      6             "key": "R0HGQWqTzE9gzg",
      7             "icon": "DashboardOutlined",
      8             "title": "查询",
      9             "link": "/Wuire",
     10             "children": []
     11         }, {
     12             "key": "g9asSJsw9yx6w",
     13             "icon": "HomeOutlined",
     14             "title": "管理",
     15             "children": [{
     16                 "key": "GBvD0rfpsYa6w",
     17                 "title": "设定",
     18                 "link": "/Willage",
     19                 "children": []
     20             }, {
     21                 "key": "L3LD2SrK84g",
     22                 "title": "管理",
     23                 "link": "/Wuse",
     24                 "children": []
     25             }, {
     26                 "key": "Wdvue6w",
     27                 "title": "管理",
     28                 "link": "/Wner",
     29                 "children": []
     30             }]
     31         }, {
     32             "key": "R3JvXJWQk6d6A",
     33             "icon": "ContactsOutlined",
     34             "title": "",
     35             "children": [{
     36                 "key": "IIJCXkQfPyzg",
     37                 "title": "群发",
     38                 "children": [{
     39                     "key": "hnhrfYWq29w",
     40                     "title": "邮件",
     41                     "link": "/Wend",
     42                     "children": []
     43                 }, {
     44                     "key": "gF7a1XnHQ",
     45                     "title": "群板",
     46                     "link": "/Wdule",
     47                     "children": []
     48                 }, {
     49                     "key": "a8yaA-u6PNQ",
     50                     "title": "历史",
     51                     "link": "/Wtory",
     52                     "children": []
     53                 }]
     54             }, {
     55                 "key": "CI03foxpw",
     56                 "title": "群发",
     57                 "children": [{
     58                     "key": "giaPpeiEoY1Rg",
     59                     "title": "短信",
     60                     "link": "/Wend",
     61                     "children": []
     62                 }, {
     63                     "key": "ewpJBHTcZLjutGQ",
     64                     "title": "模板",
     65                     "link": "/Wuodule",
     66                     "children": []
     67                 }, {
     68                     "key": "0B3qVuvVXpA",
     69                     "title": "历史",
     70                     "link": "/Wtory",
     71                     "children": []
     72                 }]
     73             }, {
     74                 "key": "7foEYA",
     75                 "title": "信印",
     76                 "link": "/Wurint",
     77                 "children": []
     78             }]
     79         }, {
     80             "key": "f3l981rYVQ",
     81             "icon": "PayCircleOutlined",
     82             "title": "费",
     83             "children": [{
     84                 "key": "DIw69fx0d3Q",
     85                 "title": "每",
     86                 "link": "/Wufei",
     87                 "children": []
     88             }, {
     89                 "key": "PBLCWp73mUV8kA",
     90                 "title": "收定",
     91                 "link": "/WMonth",
     92                 "children": []
     93             }, {
     94                 "key": "jT8bbGMc5EVIw",
     95                 "title": "定",
     96                 "link": "/Wting/ShowfeiXiangmu",
     97                 "children": []
     98             }, {
     99                 "key": "eUsfeeeOzbw",
    100                 "title": "表",
    101                 "link": "/Wufei/Daily",
    102                 "children": []
    103             }]
    104         }, {
    105             "key": "RsLTvHziej3eeg",
    106             "icon": "ToolOutlined",
    107             "title": "理",
    108             "children": [{
    109                 "key": "jTqs3ne_FJSxqg",
    110                 "title": "报",
    111                 "link": "/WuAdd",
    112                 "children": []
    113             }, {
    114                 "key": "GTJetl8mFEQ",
    115                 "title": "馈",
    116                 "link": "/Wudback",
    117                 "children": []
    118             }, {
    119                 "key": "MFtdebYGvg",
    120                 "title": "询",
    121                 "link": "/Wuyu/Inquire",
    122                 "children": []
    123             }]
    124         }, {
    125             "key": "OTzJmw",
    126             "icon": "MailOutlined",
    127             "title": "理",
    128             "children": [{
    129                 "key": "5x9__uzbmQ",
    130                 "title": "发息",
    131                 "link": "/Managend",
    132                 "children": []
    133             }, {
    134                 "key": "D6dGz0J-u98iGXw",
    135                 "title": "盒",
    136                 "link": "/Manage/Inbox",
    137                 "children": []
    138             }, {
    139                 "key": "xNE-jOp4khOHQ",
    140                 "title": "群发",
    141                 "link": "/ManagpSend",
    142                 "children": []
    143             }, {
    144                 "key": "DbIxzw6Q",
    145                 "title": "群发",
    146                 "link": "/ManaSend",
    147                 "children": []
    148             }, {
    149                 "key": "JRO7RUL54zaQ",
    150                 "title": "群发",
    151                 "link": "/ManaoupSend",
    152                 "children": []
    153             }]
    154         }, {
    155             "key": "rKYgJZdxqQ",
    156             "icon": "TeamOutlined",
    157             "title": "用理",
    158             "children": [{
    159                 "key": "VpTCpsvOsFyUZQ",
    160                 "icon": "UserOutlined",
    161                 "title": "管理",
    162                 "link": "/Mar/List",
    163                 "children": []
    164             }, {
    165                 "key": "YVaswUMx3g",
    166                 "icon": "ClusterOutlined",
    167                 "title": "部管理",
    168                 "link": "/Manist",
    169                 "children": []
    170             }, {
    171                 "key": "nYIdFQ9K0fiNiw",
    172                 "icon": "TeamOutlined",
    173                 "title": "用管理",
    174                 "link": "/MapList",
    175                 "children": []
    176             }, {
    177                 "key": "5cFzOGcLIQ",
    178                 "icon": "KeyOutlined",
    179                 "title": "用管理",
    180                 "link": "/Manage/UsAuthority",
    181                 "children": []
    182             }]
    183         }, {
    184             "key": "ab6MCJ9hNUOIfC5ofROgOw",
    185             "icon": "SettingOutlined",
    186             "title": "系统设置",
    187             "children": [{
    188                 "key": "PUGYrEbEZ6Q",
    189                 "title": "基本设置",
    190                 "link": "/Manaasic",
    191                 "children": []
    192             }, {
    193                 "key": "ueve6vGuOGKD8w",
    194                 "title": "域名设置",
    195                 "link": "/Manas/Domain",
    196                 "children": []
    197             }]
    198         }, {
    199             "key": "46lZGOCDyk6saVYzZwdsJA",
    200             "icon": "FileTextOutlined",
    201             "title": "日志管理",
    202             "children": [{
    203                 "key": "ZPi2io3l_EGATyr-9KFk2A",
    204                 "title": "系统日志",
    205                 "link": "/Manage/Log/Sys",
    206                 "children": []
    207             }, {
    208                 "key": "Ze8mGMsbmkKTXtPQ",
    209                 "title": "操作日志",
    210                 "link": "/Manage/Log/Operate",
    211                 "children": []
    212             }]
    213         }],
    214         "defaultMenuId": "RTzE9gzg"
    215     }
    216 }

    前端页面接收后,处理下一二三级菜单,加上图标,就可以渲染出来了:

     1 ......
     2 
     3   state = {
     4     collapsed: false,
     5     openKeys: [],
     6     menus: null,
     7     defaultMenuId: null,
     8   };
     9 
    10   async componentDidMount() {
    11     var menus = await getUserMenus();
    12     var allMenus = await this.getSubMenus(menus.portalMenus);
    13     this.setState({ menus: allMenus, defaultMenuId: menus.defaultMenuId });
    14   }
    15 
    16   getSubMenus = (children) =>{
    17     let menuInfo = [];
    18     children.forEach(ele=>{
    19       if (ele.children && ele.children.length > 0) {
    20         menuInfo.push(<SubMenu key={ele.key} title={ele.title} icon={GetIconByName(ele.icon)}>{this.getSubMenus(ele.children)}</SubMenu>);
    21       } else {
    22         menuInfo.push(<Menu.Item key={ele.key} icon={GetIconByName(ele.icon)}><Link to={ele.link}>{ele.title}</Link></Menu.Item>);
    23       }
    24     });
    25     return menuInfo;
    26   };
    27 
    28   render() {
    29     return (
    30       <Router>
    31         <Layout>
    32           <Sider trigger={null} collapsible collapsed={this.state.collapsed}>
    33             <div className="logo">
    34               .
    35             </div>
    36             <Menu theme="dark" mode="inline"
    37               defaultSelectedKeys = {[this.state.defaultMenuId]}
    38               openKeys={this.state.openKeys}
    39               onOpenChange={this.onOpenChange}>
    40               {this.state.menus}
    41             </Menu>
    42           </Sider>
    43 ......

    至此,左边的菜单就按照每个人的不同权限渲染出来了。

    附:前端的getUserMenus和Comm方法:

     1 //用户取菜单
     2 async function getUserMenus() {
     3     var result = await Comm(....);    
     4     return result.data;
     5 }
     6 
     7 async function Comm(code, ...){
     8   var body = {};
     9   body.Code = code;
    10   body.data = ...;
    11 
    12   var cookie = getCookie(global.......);
    13   var headers = {};
    14   headers["Content-Type"] = 'application/json';
    15   if(cookie){
    16     headers.token = cookie;
    17   }
    18   
    19   const response = await fetch(global.webApiUrl,{
    20       method: 'POST', 
    21       body: JSON.stringify(body), 
    22       headers: new Headers(headers)
    23     });
    24   const rep = await response.json();
    25   return rep;
    26 }

        SAAS云平台搭建札记系列文章:

        SAAS云平台搭建札记: (一)浅论SAAS多租户自助云服务平台的产品、服务和订单

        SAAS云平台搭建札记: (二)Linux Unbutu下.Net Core整套运行环境的搭建

        SAAS云平台搭建札记: (三) AntDesign + .Net Core WebAPI权限控制、动态菜单的生成

  • 相关阅读:
    VC笔记
    安卓开发,调用系统相册或相机选择图片
    安卓gradle时报错"ERROR: Plugin with id 'com.android.application' not found."
    安卓开发 利用百度识图api进行物体识别(java版)
    安卓使用讯飞SDK
    《构建之法》读书笔记1
    安卓开发 利用百度识图api进行物体识别
    安卓使用讯飞sdk报错
    Android webview学习
    open failed: EACCES (Permission denied)
  • 原文地址:https://www.cnblogs.com/thanks/p/14266485.html
Copyright © 2020-2023  润新知