From df76bceab22cb2f146d4c2baf28ce28829f63878 Mon Sep 17 00:00:00 2001 From: lvjunzhao <967725@dms.yudean.com> Date: Sat, 8 Feb 2025 09:21:26 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat:=E7=AD=89=E4=BF=9D=20feat:=E7=AD=89?= =?UTF-8?q?=E4=BF=9D-=E5=AF=B9/role/auth=20=E6=8E=A5=E5=8F=A3=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E6=9D=83=E9=99=90=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E5=92=8C4=E4=B8=AA=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=EF=BC=8C=E6=8C=89=E9=92=AE=EF=BC=8C=E5=AD=97=E6=AE=B5=EF=BC=8C?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=20=E5=BC=80=E5=88=86=E3=80=82=20feat:?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=9D=83=E9=99=90-=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=89=8B=E5=8A=A8=E7=99=BB=E5=87=BA=E8=A7=92=E8=89=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/system/role/index.ts | 21 ++ src/api/system/role/model/index.ts | 1 + src/views/system/dataAuthority/index.vue | 6 +- .../system/role/components/RoleAuthModal.vue | 235 +++++++++++++++--- src/views/system/role/index.vue | 50 +++- 5 files changed, 271 insertions(+), 42 deletions(-) diff --git a/src/api/system/role/index.ts b/src/api/system/role/index.ts index 02af2b8..9cdb17f 100644 --- a/src/api/system/role/index.ts +++ b/src/api/system/role/index.ts @@ -24,6 +24,7 @@ enum Api { Desktop = '/desktop/relation', AppMenu = '/app/menu/simple-tree', AppMenuAuth = '/organization/role/app-auth', + LogoutRole = '/system/authorize/logoutRole', } /** @@ -371,3 +372,23 @@ export async function getRoleMulti(ids: String, mode: ErrorMessageMode = 'modal' }, ); } + +/** + * @description: 角色接口登出授权 + */ +export async function logoutByRoleId( + id: string, + mode: ErrorMessageMode = 'modal', +) { + return defHttp.get( + { + url: Api.LogoutRole, + params: { + id, + }, + }, + { + errorMessageMode: mode, + }, + ); +} \ No newline at end of file diff --git a/src/api/system/role/model/index.ts b/src/api/system/role/model/index.ts index 6685cb8..9751572 100644 --- a/src/api/system/role/model/index.ts +++ b/src/api/system/role/model/index.ts @@ -46,6 +46,7 @@ export interface RoleUserModel { export interface RoleSetAuthParams { id: string; + type: number; menuIds: string[]; //菜单ids buttonIds: string[]; //按钮ids columnIds: string[]; diff --git a/src/views/system/dataAuthority/index.vue b/src/views/system/dataAuthority/index.vue index 3f345b7..cb30c27 100644 --- a/src/views/system/dataAuthority/index.vue +++ b/src/views/system/dataAuthority/index.vue @@ -2,7 +2,7 @@ @@ -20,12 +20,12 @@ :actions="[ { icon: 'clarity:note-edit-line', - auth: 'index:edit', + auth: 'dataAuth:edit', onClick: handleEdit.bind(null, record), }, { icon: 'ant-design:delete-outlined', - auth: 'index:delete', + auth: 'dataAuth:delete', color: 'error', popConfirm: { title: t('是否确认删除'), diff --git a/src/views/system/role/components/RoleAuthModal.vue b/src/views/system/role/components/RoleAuthModal.vue index 055f52e..b3fead1 100644 --- a/src/views/system/role/components/RoleAuthModal.vue +++ b/src/views/system/role/components/RoleAuthModal.vue @@ -6,13 +6,13 @@ :title="t('功能授权')" destroy-on-close @ok="handleSubmit" - width="90%" + :width=modalLength() > - +
{{ t('系统功能') }}
@@ -31,7 +31,7 @@
- +
{{ t('按钮权限') }}
@@ -45,7 +45,7 @@ />
- +
{{ t('字段权限') }}
@@ -59,7 +59,7 @@ />
- +
{{ t('表单权限') }}
@@ -117,6 +117,7 @@ const fieldFilterKeys = ref([]); const rowId = ref(''); + const typeKey = ref(4); function getTree(tree) { if (!tree) { @@ -125,9 +126,26 @@ return tree; } + function spanLength() { + if (typeKey.value == 4) { + return "6"; + } else { + return "24"; + } + } + + function modalLength() { + if (typeKey.value == 4) { + return "90%"; + } else { + return "40%"; + } + } + const [registerRoleAuthModal, { setModalProps, closeModal }] = useModalInner(async (data) => { setModalProps({ confirmLoading: false }); rowId.value = data.id; + typeKey.value = data.key; treeData.value = await getMenuSimpleTree(); buttonData.value = await getMenuButtonList(); @@ -143,37 +161,123 @@ let btnCheckedKey = []; let colCheckedKey = []; let fieldCheckedKey = []; - menuKeys.value.forEach((o) => { - getParentKeys(menuCheckedKey, treeData.value, o); - }); - menuKeys.value = menuCheckedKey; - getTree(unref(treeRef)).setCheckedKeys(authList.menuIds); - initTree(menuCheckedKey); + if (typeKey.value == 4) { + menuKeys.value.forEach((o) => { + getParentKeys(menuCheckedKey, treeData.value, o); + }); + menuKeys.value = menuCheckedKey; + getTree(unref(treeRef)).setCheckedKeys(authList.menuIds); + initTree(menuCheckedKey); - btnKeys.value.forEach((o) => { - getParentKeys(btnCheckedKey, buttonSelectData.value, o); - }); - btnKeys.value = btnCheckedKey; - colKeys.value.forEach((o) => { - getParentKeys(colCheckedKey, columnSelectData.value, o); - }); - colKeys.value = colCheckedKey; + let lostBtnKey = []; + btnKeys.value.forEach((o) => { + // getParentKeys(btnCheckedKey, buttonSelectData.value, o, lostBtnKey); + getParentKeysAndLost(btnCheckedKey, buttonSelectData.value, o, lostBtnKey); + }); + if (lostBtnKey) { + let menuIds = []; + buttonData.value.forEach((but) => { + if (lostBtnKey.includes(but.id)) { + menuIds.push(but.menuId); + } + }); + menuIds.forEach((key) => { + getParentKeys(btnCheckedKey, treeData.value, key); + }); + findMenuTree(buttonSelectData.value, treeData.value, btnCheckedKey, 'button'); + } + btnKeys.value = btnCheckedKey; + + let lostColKey = []; + colKeys.value.forEach((o) => { + // getParentKeys(colCheckedKey, columnSelectData.value, o); + getParentKeysAndLost(colCheckedKey, columnSelectData.value, o, lostColKey); + }); + if (lostColKey) { + let menuIds = []; + columnData.value.forEach((but) => { + if (lostColKey.includes(but.id)) { + menuIds.push(but.menuId); + } + }); + menuIds.forEach((key) => { + getParentKeys(colCheckedKey, treeData.value, key); + }); + findMenuTree(columnSelectData.value, treeData.value, colCheckedKey, 'column'); + } + colKeys.value = colCheckedKey; - fieldKeys.value.forEach((o) => { - getParentKeys(fieldCheckedKey, fieldSelectData.value, o); - }); - fieldKeys.value = fieldCheckedKey; + let lostFieldKey = []; + fieldKeys.value.forEach((o) => { + // getParentKeys(fieldCheckedKey, fieldSelectData.value, o); + getParentKeysAndLost(fieldCheckedKey, fieldSelectData.value, o, lostFieldKey); + }); + if (lostFieldKey) { + let menuIds = []; + columnData.value.forEach((but) => { + if (lostFieldKey.includes(but.id)) { + menuIds.push(but.menuId); + } + }); + menuIds.forEach((key) => { + getParentKeys(fieldCheckedKey, treeData.value, key); + }); + findMenuTree(fieldSelectData.value, treeData.value, fieldCheckedKey, 'field'); + } + fieldKeys.value = fieldCheckedKey; - nextTick(() => { - getTree(unref(ButtonRef))?.setCheckedKeys(authList.buttonIds); - getTree(unref(ColumnRef))?.setCheckedKeys(authList.columnIds); - getTree(unref(FieldRef))?.setCheckedKeys(authList.formIds); - getTree(unref(ButtonRef)).expandAll(true); - getTree(unref(ColumnRef)).expandAll(true); - getTree(unref(FieldRef)).expandAll(true); - }); + nextTick(() => { + getTree(unref(ButtonRef))?.setCheckedKeys(authList.buttonIds); + getTree(unref(ColumnRef))?.setCheckedKeys(authList.columnIds); + getTree(unref(FieldRef))?.setCheckedKeys(authList.formIds); + getTree(unref(ButtonRef)).expandAll(true); + getTree(unref(ColumnRef)).expandAll(true); + getTree(unref(FieldRef)).expandAll(true); + }); - getTree(unref(treeRef)).expandAll(true); + getTree(unref(treeRef)).expandAll(true); + } else { + if (typeKey.value == 0) { + menuKeys.value.forEach((o) => { + getParentKeys(menuCheckedKey, treeData.value, o); + }); + menuKeys.value = menuCheckedKey; + getTree(unref(treeRef)).setCheckedKeys(authList.menuIds); + getTree(unref(treeRef)).expandAll(true); + } + const fullMenuKey = []; + getFullMenu(fullMenuKey, treeData.value); + initTree(fullMenuKey); + if (typeKey.value == 1) { + btnKeys.value.forEach((o) => { + getParentKeys(btnCheckedKey, buttonData.value, o); + }); + btnKeys.value = btnCheckedKey; + getTree(unref(ButtonRef))?.setCheckedKeys(authList.buttonIds); + getTree(unref(ButtonRef)).expandAll(true); + } + else if (typeKey.value == 2) { + colKeys.value.forEach((o) => { + getParentKeys(colCheckedKey, columnData.value, o); + }); + colKeys.value = colCheckedKey; + nextTick(() => { + getTree(unref(ColumnRef))?.setCheckedKeys(authList.columnIds); + getTree(unref(ColumnRef)).expandAll(true); + }); + } + else if (typeKey.value == 3) { + fieldKeys.value.forEach((o) => { + getParentKeys(fieldCheckedKey, fieldData.value, o); + }); + fieldKeys.value = fieldCheckedKey; + nextTick(() => { + getTree(unref(FieldRef))?.setCheckedKeys(authList.formIds); + getTree(unref(FieldRef)).expandAll(true); + }); + } + + } }); async function handleSubmit() { @@ -197,6 +301,7 @@ await RoleSetAuth({ id: rowId.value, + type: typeKey.value, menuIds: menuKeys.value, buttonIds: btnKeys.value, columnIds: colKeys.value, @@ -230,7 +335,8 @@ const menuSelect: string[] = [...e.halfCheckedKeys, ...keys]; - initTree(menuSelect); + //选择菜单的时候。对应后面的button column field 只进行增量添加 + incrementTree(menuSelect); menuKeys.value = menuSelect; } @@ -251,6 +357,20 @@ getTree(unref(ColumnRef))?.setExpandedKeys(menuSelect); getTree(unref(FieldRef))?.setExpandedKeys(menuSelect); } + function incrementTree(addMenuSelect) { + btnFilterKeys.value = []; + colFilterKeys.value = []; + fieldFilterKeys.value = []; + + findMenuTree(buttonSelectData.value, treeData.value, addMenuSelect, 'button'); + findMenuTree(columnSelectData.value, treeData.value, addMenuSelect, 'column'); + findMenuTree(fieldSelectData.value, treeData.value, addMenuSelect, 'field'); + + let newBtnSelect = [...new Set([...btnKeys.value, ...addMenuSelect])]; + getTree(unref(ButtonRef))?.setExpandedKeys(newBtnSelect); + getTree(unref(ColumnRef))?.setExpandedKeys([...new Set([...colKeys.value, ...addMenuSelect])]); + getTree(unref(FieldRef))?.setExpandedKeys([...new Set([...fieldKeys.value, ...addMenuSelect])]); + } function getParentKeys(checkedKey, arr, keys) { for (let i = 0; i < arr.length; i++) { let o = arr[i]; @@ -265,12 +385,43 @@ } } } + // keys获取对应的菜单 返回给chackedKey,如果该keys 不在原先过滤后的数组arr中的话,把keys 记录lostKey抛出给外面二次处理,减少全数据过滤的内存处理 + function getParentKeysAndLost(checkedKey, arr, keys, lostKey) { + for (let i = 0; i < arr.length; i++) { + let o = arr[i]; + if (o.id == keys) { + checkedKey.push(o.id); + if (o.parentId > 0 && !checkedKey.includes(o.parentId)) { + checkedKey.push(o.parentId); + } + } + if (o.children?.length > 0) { + getParentKeys(checkedKey, o.children, keys); + } + } + if (!checkedKey.includes(keys)) { + lostKey.push(keys); + } + } function findMenuTree(menuSelectTree, treeData, keys, type) { for (let i = 0; i < treeData.length; i++) { let o = cloneDeep(treeData[i]); if (keys.includes(o.id)) { - o.children = []; - menuSelectTree.push(o); + let hadData = false; + let index = 0; + for (let j = 0; j < menuSelectTree.length; j++) { + if (menuSelectTree[j].id == o.id) { + hadData = true; + index = j; + break; + } + } + if (!hadData) { + o.children = []; + menuSelectTree.push(o); + } else { + o = menuSelectTree[index]; + } if (treeData[i].children?.length > 0) { findMenuTree(o.children, treeData[i].children, keys, type); } else { @@ -285,6 +436,15 @@ } } } + function getFullMenu(menuKeys, treeData) { + for (let i = 0; i < treeData.length; i++) { + let o = cloneDeep(treeData[i]); + menuKeys.push(o.id); + if (treeData[i].children?.length > 0) { + getFullMenu(menuKeys, treeData[i].children) + } + } + } function getAuthData(list, id, type) { let arr: TreeItem[] = []; @@ -375,6 +535,9 @@ columnSelectData, fieldSelectData, t, + typeKey, + spanLength, + modalLength, }; }, }); diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index 0bf62de..23c31c9 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -13,9 +13,24 @@ {{ t('查看成员') }} - + + + + + {{ t('功能授权') }} + + + {{ t('移动端功能授权') }} @@ -25,6 +40,9 @@ {{ t('首页授权') }} + + {{ t('登出角色用户') }} + - + {{ t('功能授权') }} From 273eb0f438f03e6e9d5c64aec87b717d9c70945a Mon Sep 17 00:00:00 2001 From: lvjunzhao <967725@dms.yudean.com> Date: Sat, 8 Feb 2025 11:15:29 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat:=E7=AD=89=E4=BF=9D=203.=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E7=99=BB=E5=87=BA=E8=AF=B4=E6=98=8E=E6=96=87=EF=BC=9A?= =?UTF-8?q?=E8=AF=A5=E8=A7=92=E8=89=B2=E6=89=80=E6=9C=89=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=B0=86=E8=87=AA=E5=8A=A8=E7=99=BB=E5=87=BA?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E4=BD=BF=E4=BB=96=E4=BB=AC=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E8=AE=A9=E6=9D=83=E9=99=90=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=94=9F=E6=95=88=E3=80=82=E8=AF=B7=E6=B3=A8=E6=84=8F=EF=BC=8C?= =?UTF-8?q?=E8=AF=A5=E6=93=8D=E4=BD=9C=E5=8F=AF=E8=83=BD=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=B8=A2=E5=A4=B1=E4=BB=96=E4=BB=AC=E6=AD=A3?= =?UTF-8?q?=E5=9C=A8=E4=BF=AE=E6=94=B9=E7=9A=84=E5=86=85=E5=AE=B9=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/system/role/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index 8b67efc..9b7b857 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -400,7 +400,7 @@ } Modal.confirm({ title: '确认是否登出角色用户?', - // content: '确认是否登出角色用户', + content: '该角色所有在线用户将自动登出,以使他们重新登录让权限修改生效。请注意,该操作可能导致用户丢失他们正在修改的内容!', okText: '是', okType: 'danger', cancelText: '否', From f549bae16129c2ccd2c689a369e3ca378b806a5e Mon Sep 17 00:00:00 2001 From: lvjunzhao <967725@dms.yudean.com> Date: Sat, 8 Feb 2025 14:23:27 +0800 Subject: [PATCH 5/5] =?UTF-8?q?feat:=E7=AD=89=E4=BF=9D=204.=20handleAuth:?= =?UTF-8?q?=20MenuProps=20=E7=9A=84=E5=BC=95=E7=94=A8key=20=E5=A4=84?= =?UTF-8?q?=E7=90=86=20=E9=81=97=E6=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/system/role/index.vue | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index 9b7b857..f3712f1 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -118,6 +118,7 @@ import { Switch, Modal } from 'ant-design-vue'; import { PageWrapper } from '/@/components/Page'; import { useModal } from '/@/components/Modal'; + import type { MenuProps } from 'ant-design-vue'; import { useI18n } from '/@/hooks/web/useI18n'; const { t } = useI18n(); export const columns: BasicColumn[] = [ @@ -274,14 +275,14 @@ id: res.id, }); } - function handleAuth() { + const handleAuth: MenuProps['onClick'] = e => { let res = warning(true); if (!res) { return; } - openRoleUserModal(true, { id: res.id, + key: e.key, }); } function handleAppAuth() {