SAAS雲平臺搭建札記: (三) AntDesign + .Net Core WebAPI權限控制、動態菜單的生成

咱們知道,當下最火的前端框架,非螞蟻金服的 AntDesign 莫屬,這個框架不只在國內很是有名,在國外GitHub上React前端框架也排名第一。並且這個框架涵蓋了React、Vue、Angular等多種語言,甚至有人結合.net Core 5的新特性WebAssembly 作了Ant Design Blazor,在此爲國人點贊!html

公司的新平臺,用戶前端界面當仁不讓地使用了AntDesign for React,可使用最新版本的特性(目前版本爲4.10.1);至於爲何不使用Ant Design Pro,是由於Pro封裝的控件太多,不利於咱們自定義頁面。前端

SAAS系統,頁面上首先就是權限,咱們後臺採用中等複雜度的RBAC控制,如圖所示:vue

在界面上表示,就是程序左側的樹狀菜單,參照AntdPro的官方文檔,路由和菜單,須要在菜單的ts文檔中寫清楚各類權限組和相應菜單,顯然不符合咱們先後端分離使用動態菜單的方法。git

所以,我研究一段時間,終於找到徹底在後端生成動態菜單而且在前端的使用方法,特此分享給你們。github

傳遞到前端的菜單實體類:web

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字符串: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方法:cookie

 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權限控制、動態菜單的生成

相關文章
相關標籤/搜索