6

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

 3 years ago
source link: https://www.daqianduan.com/17162.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Vf6Bze.jpg

我们知道,当下最火的前端框架,非蚂蚁金服的 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控制,如图所示:

zyuaIj.png

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

fYVZfy.png

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

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

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权限控制、动态菜单的生成

#感谢您访问本站#
#本文转载自互联网,若侵权,请联系删除,谢谢!657271#qq.com#

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK