項目中要實現一個給不同角色賦予菜單權限的效果,項目用的react版本16.8.6,antd版本較老,用的3.26.7,樹狀菜單展示賦權用的antd TreeSelect,要實現的效果如下圖所示
開發過程中碰到問題如下:
<TreeSelect
style={{ width: '100%' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={roleTreeList}
treeCheckable="true"
showCheckedStrategy={SHOW_ALL}
placeholder="請設置菜單權限"
onChange={onTreeChange} />
假設某個1級菜單目錄-系統管理下,有3個子菜單,用戶管理、角色管理、菜單管理,用treeselect賦權時,我只選了用戶管理和角色管理2個子菜單,實際上的treeselect values中應該要包含父級菜單系統管理的id的,但是因為系統管理下的3個子菜單沒有全部選中,即使 showCheckedStrategy={SHOW_ALL},在獲取treeselect value時是拿不到系統管理的key值的。
我通過后台來解決的,我的解決方式如下:
1.前台沒找到好的辦法,通過組件來拿到系統管理及其父節點(有可能存在多級的情況)的key值,前台傳值不變。(找到一個帖子,好像可以在前台獲取到系統管理及其父節點的key)參考https://www.cnblogs.com/makalochen/p/14103050.html
2.后台拿到前台傳過來的所有key值,遞歸查找所有父節點后,跟前台傳值做並集后做唯一值篩選。這樣保證可以拿到所有前台漏掉的父節點值。入庫時的數據不會有問題
3.這樣會導致一個新問題出現,就是由於系統管理父節點的值入庫了,在treeselect上明明應該是只顯示系統管理和用戶管理、角色管理兩個子菜單的,但是如果從庫里面拿數據的話,系統管理的key默認也是選中的,會變成了系統管理下的3個子菜單都是選中的狀態
4. 第3步中的問題我是這么處理的,數據庫中存入了系統管理的節點id,但是在treeselect綁定values值時,過濾掉這些父節點的key值,具體sql類似如下,我這里是角色賦權,在角色創建時指定角色有權限操作的菜單樹。角色表上加一個字段menuCheckStrictly,默認為true。然后入庫時父節點key值即使入庫,再取數據庫值綁定到treeselect時,由於角色menuCheckStrictly為true,會過濾掉這些父節點key值。
select m.menu_id from sys_menu m left join sys_role_menu rm on m.menu_id = rm.menu_id where rm.role_id = #{roleId}
<if test="menuCheckStrictly"> and m.menu_id not in (select m.parent_id from sys_menu m inner join sys_role_menu rm on m.menu_id = rm.menu_id and rm.role_id = #{roleId}) </if>
order by m.parent_id, m.order_num
整個操作,已經測試成功,基本達到我的要求。