Commit ee0eb18114ebd977e677721223a8510ede9770cf

Authored by ww
1 parent 195ab9cb

fix: role assign disabled not has permission menu item

@@ -14,6 +14,7 @@ @@ -14,6 +14,7 @@
14 "PROTOBUF", 14 "PROTOBUF",
15 "SNMP", 15 "SNMP",
16 "unref", 16 "unref",
  17 + "vben",
17 "VITE" 18 "VITE"
18 ] 19 ]
19 } 20 }
@@ -18,3 +18,32 @@ export interface RouteItem { @@ -18,3 +18,32 @@ export interface RouteItem {
18 * @description: Get menu return value 18 * @description: Get menu return value
19 */ 19 */
20 export type getMenuListResultModel = RouteItem[]; 20 export type getMenuListResultModel = RouteItem[];
  21 +
  22 +export interface Meta {
  23 + title: string;
  24 + menuType: string;
  25 + status: string;
  26 + icon: string;
  27 + isLink: boolean;
  28 + ignoreKeepAlive: boolean;
  29 + hideMenu: boolean;
  30 +}
  31 +
  32 +export interface MenuRecord {
  33 + id: string;
  34 + createTime: string;
  35 + updateTime: string;
  36 + name: string;
  37 + children: MenuRecord[];
  38 + path: string;
  39 + type: string;
  40 + permission: string;
  41 + sort: number;
  42 + component: string;
  43 + meta: Meta;
  44 + disabled?: boolean;
  45 + isDictCompareDisabled?: boolean;
  46 + icon?: string;
  47 + title?: string;
  48 + key?: string;
  49 +}
@@ -9,18 +9,20 @@ @@ -9,18 +9,20 @@
9 > 9 >
10 <BasicForm @register="registerForm"> 10 <BasicForm @register="registerForm">
11 <template #menu> 11 <template #menu>
12 - <BasicTree  
13 - v-if="treeData.length"  
14 - checkable  
15 - toolbar  
16 - :expandedKeys="treeExpandData"  
17 - ref="treeRef"  
18 - :treeData="treeData"  
19 - :replaceFields="{ title: 'menuName' }"  
20 - :checkedKeys="roleMenus"  
21 - @check="handleCheckClick"  
22 - title="菜单分配"  
23 - /> 12 + <Spin :spinning="spinning">
  13 + <BasicTree
  14 + v-if="treeData.length"
  15 + checkable
  16 + toolbar
  17 + :expandedKeys="treeExpandData"
  18 + ref="treeRef"
  19 + :treeData="treeData"
  20 + :replace-fields="{ title: 'name', key: 'id' }"
  21 + :checkedKeys="roleMenus"
  22 + @check="handleCheckClick"
  23 + title="菜单分配"
  24 + />
  25 + </Spin>
24 </template> 26 </template>
25 </BasicForm> 27 </BasicForm>
26 </BasicDrawer> 28 </BasicDrawer>
@@ -28,7 +30,7 @@ @@ -28,7 +30,7 @@
28 <script lang="ts"> 30 <script lang="ts">
29 import { defineComponent, ref, computed, unref, nextTick } from 'vue'; 31 import { defineComponent, ref, computed, unref, nextTick } from 'vue';
30 import { BasicForm, useForm } from '/@/components/Form/index'; 32 import { BasicForm, useForm } from '/@/components/Form/index';
31 - import { formSchema } from './role.data'; 33 + import { formSchema, KeysTypeEnum, RoleMenuDictEnum } from './role.data';
32 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; 34 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
33 import { BasicTree, TreeItem } from '/@/components/Tree'; 35 import { BasicTree, TreeItem } from '/@/components/Tree';
34 import { useMessage } from '/@/hooks/web/useMessage'; 36 import { useMessage } from '/@/hooks/web/useMessage';
@@ -36,22 +38,28 @@ @@ -36,22 +38,28 @@
36 // 加载菜单数据 38 // 加载菜单数据
37 import { getMenuList, getMenusIdsByRoleId } from '/@/api/sys/menu'; 39 import { getMenuList, getMenusIdsByRoleId } from '/@/api/sys/menu';
38 import { useI18n } from '/@/hooks/web/useI18n'; 40 import { useI18n } from '/@/hooks/web/useI18n';
39 - import { RouteItem } from '/@/api/sys/model/menuModel'; 41 + import { MenuRecord } from '/@/api/sys/model/menuModel';
40 import { saveOrUpdateRoleInfoWithMenu } from '/@/api/system/system'; 42 import { saveOrUpdateRoleInfoWithMenu } from '/@/api/system/system';
  43 + import { findDictItemByCode } from '/@/api/system/dict';
  44 + import { RoleEnum } from '/@/enums/roleEnum';
  45 + import { Spin } from 'ant-design-vue';
  46 +
  47 + type TreeData = MenuRecord & TreeItem;
  48 +
41 export default defineComponent({ 49 export default defineComponent({
42 name: 'RoleDrawer', 50 name: 'RoleDrawer',
43 - components: { BasicDrawer, BasicForm, BasicTree }, 51 + components: { BasicDrawer, BasicForm, BasicTree, Spin },
44 emits: ['success', 'register'], 52 emits: ['success', 'register'],
45 setup(_, { emit }) { 53 setup(_, { emit }) {
46 - const treeExpandData = ref([]); 54 + const treeExpandData = ref<string[]>([]);
47 const isUpdate = ref<boolean>(true); 55 const isUpdate = ref<boolean>(true);
48 - const treeData = ref<TreeItem[]>([]); 56 + const treeData = ref<TreeData[]>([]);
49 const roleMenus = ref<string[]>([]); 57 const roleMenus = ref<string[]>([]);
50 const allCheckedKeys = ref<string[]>([]); 58 const allCheckedKeys = ref<string[]>([]);
51 const roleId = ref<string>(''); 59 const roleId = ref<string>('');
52 const treeRef = ref(); 60 const treeRef = ref();
53 - const checked: any = ref([]); //需要选中的节点  
54 - const pidArr: any = ref([]); //获取父节点 61 + const checked = ref<string[]>([]); //需要选中的节点
  62 + const spinning = ref(false);
55 63
56 const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({ 64 const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
57 labelWidth: 100, 65 labelWidth: 100,
@@ -59,24 +67,18 @@ @@ -59,24 +67,18 @@
59 showActionButtonGroup: false, 67 showActionButtonGroup: false,
60 }); 68 });
61 69
62 - // 递归函数,将RouteItem里面的字段换名称  
63 - function processChildren(items: RouteItem[]) {  
64 - items.forEach((item) => {  
65 - item.menuName = t(item.meta.title);  
66 - item.icon = item.meta.icon;  
67 - item.key = item.id;  
68 - if (item.children) {  
69 - processChildren(item.children); 70 + const originMenus = ref();
  71 +
  72 + const transformName = (data: TreeData[]) => {
  73 + return data.map((item) => {
  74 + item.name = t(item.name);
  75 + if (item.children && item.children.length) {
  76 + item.children = transformName(item.children as unknown as TreeData[]);
70 } 77 }
  78 + return item;
71 }); 79 });
72 - }  
73 - function lookForAllId(data = [], arr = []) {  
74 - for (const item of data) {  
75 - arr.push(item.id);  
76 - }  
77 - return arr;  
78 - }  
79 - const originMenus = ref(); 80 + };
  81 +
80 const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => { 82 const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
81 allCheckedKeys.value = []; 83 allCheckedKeys.value = [];
82 originMenus.value = []; 84 originMenus.value = [];
@@ -84,53 +86,52 @@ @@ -84,53 +86,52 @@
84 resetFields(); 86 resetFields();
85 roleId.value = ''; 87 roleId.value = '';
86 // 在打开弹窗时清除所有选择的菜单 88 // 在打开弹窗时清除所有选择的菜单
87 - treeRef.value && treeRef.value.checkAll(false); 89 + treeRef.value && treeRef.value?.setCheckedKeys([]);
88 isUpdate.value = data.isUpdate; 90 isUpdate.value = data.isUpdate;
89 - // 需要在setFieldsValue之前先填充treeData,否则Tree组件可能会报key not exist警告  
90 - if (!unref(treeData).length) {  
91 - // 获取全部的菜单  
92 - const menuListModel = await getMenuList();  
93 - processChildren(menuListModel);  
94 - treeData.value = menuListModel;  
95 - //修复角色菜单新增-全部展开问题-只展开第一级即可  
96 - nextTick(() => {  
97 - const getAllIds = lookForAllId(treeData.value, []);  
98 - treeExpandData.value = getAllIds;  
99 - });  
100 - }  
101 - // 更新  
102 - if (unref(isUpdate)) {  
103 - allCheckedKeys.value = [];  
104 - checked.value = [];  
105 - //通过角色id去获取角色对应的菜单的ids  
106 - roleMenus.value = await getMenusIdsByRoleId(data.record.id);  
107 - originMenus.value = [...roleMenus.value];  
108 -  
109 - const getAllIds = lookForAllId(treeData.value, []);  
110 - treeExpandData.value = getAllIds;  
111 - for (let item of treeData.value) {  
112 - if (item?.children != 0) {  
113 - pidArr.value.push(item.key);  
114 - }  
115 - for (let item1 of item?.children) {  
116 - if (item1?.children != 0) {  
117 - pidArr.value.push(item1.key);  
118 - }  
119 - } 91 + const roleType = data?.record?.roleType || RoleEnum.SYS_ADMIN;
  92 + try {
  93 + spinning.value = true;
  94 + // 需要在setFieldsValue之前先填充treeData,否则Tree组件可能会报key not exist警告
  95 +
  96 + if (!unref(treeData).length) {
  97 + // 获取全部的菜单
  98 + const menuListModel = await getMenuList();
  99 + treeData.value = transformName(menuListModel as unknown as TreeData[]);
  100 + //修复角色菜单新增-全部展开问题-只展开第一级即可
  101 + await nextTick();
  102 + const getExpandKeys = unref(treeData).map((item) => item.id);
  103 + treeExpandData.value = getExpandKeys;
120 } 104 }
121 - for (let item of roleMenus.value) {  
122 - let isP = pidArr.value.includes(item);  
123 - if (!isP) {  
124 - checked.value.push(item);  
125 - } 105 +
  106 + const keys = await getPermissionByRole(roleType);
  107 + const { keyType } = RoleMenuDictEnum[roleType];
  108 + treeData.value = getPermissionTreeData(
  109 + unref(treeData) as unknown as TreeData[],
  110 + keys,
  111 + keyType
  112 + );
  113 +
  114 + // 更新
  115 + if (unref(isUpdate)) {
  116 + allCheckedKeys.value = [];
  117 + checked.value = [];
  118 + roleId.value = data.record.id;
  119 +
  120 + //通过角色id去获取角色对应的菜单的ids
  121 + originMenus.value = roleMenus.value = await getMenusIdsByRoleId(data.record.id);
  122 +
  123 + const getExpandKeys = unref(treeData).map((item) => item.id);
  124 + treeExpandData.value = getExpandKeys;
  125 +
  126 + await nextTick();
  127 + treeRef.value.setCheckedKeys(roleMenus.value);
  128 + setFieldsValue(data.record);
  129 + } else {
126 } 130 }
127 - nextTick(() => {  
128 - treeRef.value.setCheckedKeys(checked.value);  
129 - // const expandTreeIds = lookForAllId(treeData.value);  
130 - // treeRef.value.setExpandedKeys(expandTreeIds);  
131 - });  
132 - roleId.value = data.record.id;  
133 - setFieldsValue(data.record); 131 + } catch (error) {
  132 + throw error;
  133 + } finally {
  134 + spinning.value = false;
134 } 135 }
135 }); 136 });
136 137
@@ -146,7 +147,7 @@ @@ -146,7 +147,7 @@
146 name: values.name, 147 name: values.name,
147 remark: values.remark, 148 remark: values.remark,
148 status: values.status, 149 status: values.status,
149 - menu: allCheckedKeys.value.length ? allCheckedKeys.value : originMenus.value, 150 + menu: unref(treeRef).getCheckedKeys() || [],
150 }; 151 };
151 if (req.menu == undefined) return createMessage.error('请勾选权限菜单'); 152 if (req.menu == undefined) return createMessage.error('请勾选权限菜单');
152 saveOrUpdateRoleInfoWithMenu(req).then(() => { 153 saveOrUpdateRoleInfoWithMenu(req).then(() => {
@@ -165,7 +166,74 @@ @@ -165,7 +166,74 @@
165 allCheckedKeys.value = [...checkedNodes, ...halfCheckedKeys]; 166 allCheckedKeys.value = [...checkedNodes, ...halfCheckedKeys];
166 }; 167 };
167 168
  169 + const getPermissionByRole = async (roleType: RoleEnum) => {
  170 + try {
  171 + const { key } = RoleMenuDictEnum[roleType];
  172 + const res = await findDictItemByCode({ dictCode: key });
  173 + return res.map((item) => item.itemValue);
  174 + } catch (error) {}
  175 + return [];
  176 + };
  177 +
  178 + const getPermissionTreeData = (
  179 + data: MenuRecord[],
  180 + permissionKeys: string[],
  181 + keysType: KeysTypeEnum
  182 + ) => {
  183 + const setDisabled = (data: MenuRecord[], flag: boolean) => {
  184 + return data.map((item) => {
  185 + item.name = t(item.name);
  186 + if (item.children && item.children.length) {
  187 + item.children = setDisabled(item.children, flag);
  188 + }
  189 + return {
  190 + ...item,
  191 + disabled: flag,
  192 + icon: item.meta.icon,
  193 + } as TreeData;
  194 + });
  195 + };
  196 +
  197 + const permissionCompare = (
  198 + data: MenuRecord[],
  199 + permissionKeys: string[],
  200 + keysType: KeysTypeEnum
  201 + ) => {
  202 + return data.map((item) => {
  203 + item.name = t(item.name);
  204 + const findFlag = permissionKeys.includes(item.permission);
  205 + if (findFlag) item.isDictCompareDisabled = true;
  206 + const disabledFlag = keysType === KeysTypeEnum.DISABLED ? findFlag : !findFlag;
  207 + item.disabled = disabledFlag;
  208 +
  209 + if (item.isDictCompareDisabled && item.children && item.children.length) {
  210 + setDisabled(item.children, disabledFlag);
  211 + } else {
  212 + if (item.children && item.children.length) {
  213 + item.children = permissionCompare(item.children, permissionKeys, keysType);
  214 + item.disabled = item.children.every((temp) => temp.disabled);
  215 + }
  216 + }
  217 + return {
  218 + ...item,
  219 + icon: item.meta.icon,
  220 + } as TreeData;
  221 + });
  222 + };
  223 +
  224 + const result = permissionCompare(data, permissionKeys, keysType).map((item) => {
  225 + if (item.children && item.children.length) {
  226 + const rootDisabledFlag = item.children.every((temp) => temp.disabled);
  227 + item.disabled = rootDisabledFlag;
  228 + }
  229 + return item;
  230 + });
  231 +
  232 + return result;
  233 + };
  234 +
168 return { 235 return {
  236 + spinning,
169 registerDrawer, 237 registerDrawer,
170 registerForm, 238 registerForm,
171 getTitle, 239 getTitle,
@@ -185,9 +253,11 @@ @@ -185,9 +253,11 @@
185 :deep(.vben-basic-tree) { 253 :deep(.vben-basic-tree) {
186 width: 100% !important; 254 width: 100% !important;
187 } 255 }
  256 +
188 :deep(.is-unflod) { 257 :deep(.is-unflod) {
189 display: none !important; 258 display: none !important;
190 } 259 }
  260 +
191 :deep(.is-flod) { 261 :deep(.is-flod) {
192 display: none !important; 262 display: none !important;
193 } 263 }
1 import { BasicColumn } from '/@/components/Table'; 1 import { BasicColumn } from '/@/components/Table';
2 import { FormSchema } from '/@/components/Table'; 2 import { FormSchema } from '/@/components/Table';
  3 +import { RoleEnum } from '/@/enums/roleEnum';
  4 +
  5 +export enum KeysTypeEnum {
  6 + DISABLED = 'disabled',
  7 + ENABLED = 'enabled',
  8 +}
  9 +
  10 +export const RoleMenuDictEnum: Recordable<{ key: string; keyType: KeysTypeEnum }> = {
  11 + [RoleEnum.PLATFORM_ADMIN]: { key: 'enabled_platform_admin_auth', keyType: KeysTypeEnum.ENABLED },
  12 + [RoleEnum.SYS_ADMIN]: { key: 'enabled_sysadmin_auth', keyType: KeysTypeEnum.ENABLED },
  13 + [RoleEnum.TENANT_ADMIN]: { key: 'disabled_tenant_auth', keyType: KeysTypeEnum.DISABLED },
  14 +};
3 15
4 export const columns: BasicColumn[] = [ 16 export const columns: BasicColumn[] = [
5 { 17 {
@@ -9,19 +9,21 @@ @@ -9,19 +9,21 @@
9 > 9 >
10 <BasicForm @register="registerForm"> 10 <BasicForm @register="registerForm">
11 <template #menu> 11 <template #menu>
12 - <BasicTree  
13 - v-if="treeData.length > 0"  
14 - :treeData="treeData"  
15 - :expandedKeys="treeExpandData"  
16 - :replaceFields="{ title: 'menuName' }"  
17 - :checkedKeys="roleMenus"  
18 - @check="handleCheckClick"  
19 - checkable  
20 - toolbar  
21 - ref="treeRef"  
22 - title="权限分配"  
23 - :defaultExpandAll="true"  
24 - /> 12 + <Spin :spinning="spinning">
  13 + <BasicTree
  14 + v-if="treeData.length"
  15 + :treeData="treeData"
  16 + :expandedKeys="treeExpandData"
  17 + :replaceFields="{ title: 'name', key: 'id' }"
  18 + :checkedKeys="roleMenus"
  19 + @check="handleCheckClick"
  20 + checkable
  21 + toolbar
  22 + ref="treeRef"
  23 + title="权限分配"
  24 + :defaultExpandAll="true"
  25 + />
  26 + </Spin>
25 </template> 27 </template>
26 </BasicForm> 28 </BasicForm>
27 </BasicDrawer> 29 </BasicDrawer>
@@ -36,17 +38,22 @@ @@ -36,17 +38,22 @@
36 // 加载菜单数据 38 // 加载菜单数据
37 import { getMenuList, getMenusIdsByRoleId } from '/@/api/sys/menu'; 39 import { getMenuList, getMenusIdsByRoleId } from '/@/api/sys/menu';
38 import { useI18n } from '/@/hooks/web/useI18n'; 40 import { useI18n } from '/@/hooks/web/useI18n';
39 - import { RouteItem } from '/@/api/sys/model/menuModel'; 41 + import { MenuRecord } from '/@/api/sys/model/menuModel';
40 import { saveOrUpdateRoleInfoWithMenu } from '/@/api/system/system'; 42 import { saveOrUpdateRoleInfoWithMenu } from '/@/api/system/system';
41 import { RoleEnum } from '/@/enums/roleEnum'; 43 import { RoleEnum } from '/@/enums/roleEnum';
42 import { useMessage } from '/@/hooks/web/useMessage'; 44 import { useMessage } from '/@/hooks/web/useMessage';
  45 + import { KeysTypeEnum, RoleMenuDictEnum } from '../../system/role/role.data';
  46 + import { findDictItemByCode } from '/@/api/system/dict';
  47 + import { Spin } from 'ant-design-vue';
  48 +
  49 + type TreeData = MenuRecord & TreeItem;
43 50
44 export default defineComponent({ 51 export default defineComponent({
45 name: 'RoleDrawer', 52 name: 'RoleDrawer',
46 - components: { BasicDrawer, BasicForm, BasicTree }, 53 + components: { BasicDrawer, BasicForm, BasicTree, Spin },
47 emits: ['success', 'register'], 54 emits: ['success', 'register'],
48 setup(_, { emit }) { 55 setup(_, { emit }) {
49 - const treeExpandData = ref([]); 56 + const treeExpandData = ref<string[]>([]);
50 57
51 const isUpdate = ref(true); 58 const isUpdate = ref(true);
52 const treeData = ref<TreeItem[]>([]); 59 const treeData = ref<TreeItem[]>([]);
@@ -54,8 +61,8 @@ @@ -54,8 +61,8 @@
54 const allCheckedKeys = ref<string[]>([]); 61 const allCheckedKeys = ref<string[]>([]);
55 const roleId = ref(''); 62 const roleId = ref('');
56 const treeRef = ref(); 63 const treeRef = ref();
57 - const checked: any = ref([]); //需要选中的节点  
58 - const pidArr: any = ref([]); //获取父节点 64 + const checked = ref<string[]>([]); //需要选中的节点
  65 + const spinning = ref(false);
59 66
60 const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({ 67 const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
61 labelWidth: 90, 68 labelWidth: 90,
@@ -63,77 +70,71 @@ @@ -63,77 +70,71 @@
63 showActionButtonGroup: false, 70 showActionButtonGroup: false,
64 }); 71 });
65 72
66 - function processChildren(items: RouteItem[]) {  
67 - items.map((item) => {  
68 - item.menuName = t(item.meta.title);  
69 - item.icon = item.meta.icon;  
70 - item.key = item.id;  
71 - if (item.children) {  
72 - processChildren(item.children); 73 + const originMenus = ref();
  74 +
  75 + const transformName = (data: TreeData[]) => {
  76 + return data.map((item) => {
  77 + item.name = t(item.name);
  78 + if (item.children && item.children.length) {
  79 + item.children = transformName(item.children as unknown as TreeData[]);
73 } 80 }
  81 + return item;
74 }); 82 });
75 - }  
76 - function lookForAllId(data = [], arr = []) {  
77 - for (const item of data) {  
78 - arr.push(item.id);  
79 - }  
80 - return arr;  
81 - } 83 + };
82 84
83 - const originMenus = ref();  
84 const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => { 85 const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
85 - setDrawerProps({ confirmLoading: false });  
86 allCheckedKeys.value = []; 86 allCheckedKeys.value = [];
87 originMenus.value = []; 87 originMenus.value = [];
88 - treeExpandData.value;  
89 allCheckedKeys.value.length = 0; 88 allCheckedKeys.value.length = 0;
90 resetFields(); 89 resetFields();
91 roleId.value = ''; 90 roleId.value = '';
92 // 在打开弹窗时清除所有选择的菜单 91 // 在打开弹窗时清除所有选择的菜单
93 - treeRef.value && treeRef.value.checkAll(false); 92 + treeRef.value && treeRef.value?.setCheckedKeys([]);
94 isUpdate.value = data.isUpdate; 93 isUpdate.value = data.isUpdate;
95 - // 需要在setFieldsValue之前先填充treeData,否则Tree组件可能会报key not exist警告  
96 - if (!unref(treeData).length) {  
97 - // 获取全部的菜单  
98 - const menuListModel = await getMenuList();  
99 - processChildren(menuListModel);  
100 - treeData.value = menuListModel;  
101 - //修复角色菜单新增-全部展开问题-只展开第一级即可  
102 - nextTick(() => {  
103 - const getAllIds = lookForAllId(treeData.value, []);  
104 - treeExpandData.value = getAllIds;  
105 - });  
106 - }  
107 - // 更新  
108 - if (unref(isUpdate)) {  
109 - allCheckedKeys.value = [];  
110 - checked.value = [];  
111 - //通过角色id去获取角色对应的菜单的ids  
112 - roleMenus.value = await getMenusIdsByRoleId(data.record.id);  
113 - originMenus.value = [...roleMenus.value];  
114 - const getAllIds = lookForAllId(treeData.value, []);  
115 - treeExpandData.value = getAllIds;  
116 - for (let item of treeData.value) {  
117 - if (item?.children != 0) {  
118 - pidArr.value.push(item.key);  
119 - }  
120 - for (let item1 of item?.children) {  
121 - if (item1?.children != 0) {  
122 - pidArr.value.push(item1.key);  
123 - }  
124 - } 94 + const roleType = data?.record?.roleType || RoleEnum.TENANT_ADMIN;
  95 + try {
  96 + spinning.value = true;
  97 + // 需要在setFieldsValue之前先填充treeData,否则Tree组件可能会报key not exist警告
  98 +
  99 + if (!unref(treeData).length) {
  100 + // 获取全部的菜单
  101 + const menuListModel = await getMenuList();
  102 + treeData.value = transformName(menuListModel as unknown as TreeData[]);
  103 + //修复角色菜单新增-全部展开问题-只展开第一级即可
  104 + await nextTick();
  105 + const getExpandKeys = unref(treeData).map((item) => item.id);
  106 + treeExpandData.value = getExpandKeys;
125 } 107 }
126 - for (let item of roleMenus.value) {  
127 - let isP = pidArr.value.includes(item);  
128 - if (!isP) {  
129 - checked.value.push(item);  
130 - } 108 +
  109 + const keys = await getPermissionByRole(roleType);
  110 + const { keyType } = RoleMenuDictEnum[roleType];
  111 + treeData.value = getPermissionTreeData(
  112 + unref(treeData) as unknown as TreeData[],
  113 + keys,
  114 + keyType
  115 + );
  116 +
  117 + // 更新
  118 + if (unref(isUpdate)) {
  119 + allCheckedKeys.value = [];
  120 + checked.value = [];
  121 + roleId.value = data.record.id;
  122 +
  123 + //通过角色id去获取角色对应的菜单的ids
  124 + originMenus.value = roleMenus.value = await getMenusIdsByRoleId(data.record.id);
  125 +
  126 + const getExpandKeys = unref(treeData).map((item) => item.id);
  127 + treeExpandData.value = getExpandKeys;
  128 +
  129 + await nextTick();
  130 + treeRef.value.setCheckedKeys(roleMenus.value);
  131 + setFieldsValue(data.record);
  132 + } else {
131 } 133 }
132 - nextTick(() => {  
133 - treeRef.value.setCheckedKeys(checked.value);  
134 - });  
135 - roleId.value = data.record.id;  
136 - setFieldsValue(data.record); 134 + } catch (error) {
  135 + throw error;
  136 + } finally {
  137 + spinning.value = false;
137 } 138 }
138 }); 139 });
139 const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色')); 140 const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));
@@ -150,7 +151,7 @@ @@ -150,7 +151,7 @@
150 remark: values.remark, 151 remark: values.remark,
151 status: values.status, 152 status: values.status,
152 roleType: RoleEnum.TENANT_ADMIN, 153 roleType: RoleEnum.TENANT_ADMIN,
153 - menu: allCheckedKeys.value.length ? allCheckedKeys.value : originMenus.value, 154 + menu: unref(treeRef).getCheckedKeys() || [],
154 }; 155 };
155 if (req.menu == undefined) return createMessage.error('请勾选权限菜单'); 156 if (req.menu == undefined) return createMessage.error('请勾选权限菜单');
156 const res = await saveOrUpdateRoleInfoWithMenu(req); 157 const res = await saveOrUpdateRoleInfoWithMenu(req);
@@ -173,7 +174,74 @@ @@ -173,7 +174,74 @@
173 allCheckedKeys.value = [...checkedNodes, ...halfCheckedKeys]; 174 allCheckedKeys.value = [...checkedNodes, ...halfCheckedKeys];
174 }; 175 };
175 176
  177 + const getPermissionByRole = async (roleType: RoleEnum) => {
  178 + try {
  179 + const { key } = RoleMenuDictEnum[roleType];
  180 + const res = await findDictItemByCode({ dictCode: key });
  181 + return res.map((item) => item.itemValue);
  182 + } catch (error) {}
  183 + return [];
  184 + };
  185 +
  186 + const getPermissionTreeData = (
  187 + data: MenuRecord[],
  188 + permissionKeys: string[],
  189 + keysType: KeysTypeEnum
  190 + ) => {
  191 + const setDisabled = (data: MenuRecord[], flag: boolean) => {
  192 + return data.map((item) => {
  193 + item.name = t(item.name);
  194 + if (item.children && item.children.length) {
  195 + item.children = setDisabled(item.children, flag);
  196 + }
  197 + return {
  198 + ...item,
  199 + disabled: flag,
  200 + icon: item.meta.icon,
  201 + } as TreeData;
  202 + });
  203 + };
  204 +
  205 + const permissionCompare = (
  206 + data: MenuRecord[],
  207 + permissionKeys: string[],
  208 + keysType: KeysTypeEnum
  209 + ) => {
  210 + return data.map((item) => {
  211 + item.name = t(item.name);
  212 + const findFlag = permissionKeys.includes(item.permission);
  213 + if (findFlag) item.isDictCompareDisabled = true;
  214 + const disabledFlag = keysType === KeysTypeEnum.DISABLED ? findFlag : !findFlag;
  215 + item.disabled = disabledFlag;
  216 +
  217 + if (item.isDictCompareDisabled && item.children && item.children.length) {
  218 + setDisabled(item.children, disabledFlag);
  219 + } else {
  220 + if (item.children && item.children.length) {
  221 + item.children = permissionCompare(item.children, permissionKeys, keysType);
  222 + item.disabled = item.children.every((temp) => temp.disabled);
  223 + }
  224 + }
  225 + return {
  226 + ...item,
  227 + icon: item.meta.icon,
  228 + } as TreeData;
  229 + });
  230 + };
  231 +
  232 + const result = permissionCompare(data, permissionKeys, keysType).map((item) => {
  233 + if (item.children && item.children.length) {
  234 + const rootDisabledFlag = item.children.every((temp) => temp.disabled);
  235 + item.disabled = rootDisabledFlag;
  236 + }
  237 + return item;
  238 + });
  239 +
  240 + return result;
  241 + };
  242 +
176 return { 243 return {
  244 + spinning,
177 registerDrawer, 245 registerDrawer,
178 registerForm, 246 registerForm,
179 getTitle, 247 getTitle,
@@ -192,9 +260,11 @@ @@ -192,9 +260,11 @@
192 :deep(.vben-basic-tree) { 260 :deep(.vben-basic-tree) {
193 width: 100% !important; 261 width: 100% !important;
194 } 262 }
  263 +
195 :deep(.is-unflod) { 264 :deep(.is-unflod) {
196 display: none !important; 265 display: none !important;
197 } 266 }
  267 +
198 :deep(.is-flod) { 268 :deep(.is-flod) {
199 display: none !important; 269 display: none !important;
200 } 270 }