Skip to content

Commit

Permalink
feat: 当前用户角色权限变更时实时更新权限菜单
Browse files Browse the repository at this point in the history
  • Loading branch information
buqiyuan committed Mar 28, 2022
1 parent 98ce7a1 commit adbda89
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 162 deletions.
25 changes: 12 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
},
"dependencies": {
"@ant-design/icons-vue": "^6.1.0",
"@vueuse/core": "^8.1.2",
"@vueuse/core": "^8.2.0",
"ant-design-vue": "3.1.0-rc.2",
"axios": "^0.26.1",
"core-js": "^3.21.1",
Expand All @@ -47,28 +47,27 @@
"vue-i18n": "9.2.0-beta.30",
"vue-router": "^4.0.14",
"vue-types": "^4.1.1",
"xlsx": "^0.18.4"
"xlsx": "^0.18.5"
},
"devDependencies": {
"@commitlint/cli": "^16.2.3",
"@commitlint/config-conventional": "^16.2.1",
"@types/lodash-es": "^4.17.6",
"@types/node": "^17.0.22",
"@types/node": "^17.0.23",
"@types/webpack-env": "^1.16.3",
"@typescript-eslint/eslint-plugin": "^5.16.0",
"@typescript-eslint/parser": "^5.16.0",
"@vue/cli-plugin-babel": "^5.0.3",
"@vue/cli-plugin-eslint": "^5.0.3",
"@vue/cli-plugin-router": "^5.0.3",
"@vue/cli-plugin-typescript": "^5.0.3",
"@vue/cli-plugin-vuex": "^5.0.3",
"@vue/cli-service": "^5.0.3",
"@vue/cli-plugin-babel": "^5.0.4",
"@vue/cli-plugin-eslint": "^5.0.4",
"@vue/cli-plugin-router": "^5.0.4",
"@vue/cli-plugin-typescript": "^5.0.4",
"@vue/cli-service": "^5.0.4",
"@vue/eslint-config-typescript": "^10.0.0",
"babel-plugin-import": "^1.13.3",
"commitizen": "^4.2.4",
"compression-webpack-plugin": "^9.2.0",
"conventional-changelog-cli": "^2.2.2",
"eslint": "^8.11.0",
"eslint": "^8.12.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "2.25.4",
"eslint-plugin-prettier": "^4.0.0",
Expand All @@ -79,16 +78,16 @@
"lint-staged": "^12.3.7",
"path-browserify": "^1.0.1",
"postcss-html": "^1.3.0",
"prettier": "^2.6.0",
"prettier": "^2.6.1",
"regenerator-runtime": "^0.13.9",
"stylelint": "^14.6.0",
"stylelint": "^14.6.1",
"stylelint-config-html": "^1.0.0",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-recommended": "^7.0.0",
"stylelint-config-standard": "^25.0.0",
"stylelint-order": "^5.0.0",
"svg-sprite-loader": "^6.0.11",
"typescript": "^4.6.2",
"typescript": "^4.6.3",
"unplugin-vue-define-options": "^0.5.0",
"vue-cli-plugin-windicss": "^1.1.3",
"vue-eslint-parser": "^8.3.0"
Expand Down
5 changes: 4 additions & 1 deletion src/core/socket/event-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
* Socket事件名定义
*/

// 强制踢下线
/** 强制踢下线 */
export const EVENT_KICK = 'kick';

/** 当前用户的角色权限或所拥有的菜单信息被更新时 重新获取最新的权限菜单 */
export const EVENT_UPDATE_MENU = 'update_menu';
5 changes: 2 additions & 3 deletions src/layout/header/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<component :is="collapsed ? MenuUnfoldOutlined : MenuFoldOutlined" />
</span>
<Breadcrumb>
<template v-for="(routeItem, rotueIndex) in menus" :key="routeItem.name">
<template v-for="(routeItem, rotueIndex) in menus" :key="routeItem?.name">
<Breadcrumb.Item>
<TitleI18n :title="routeItem?.meta?.title" />
<template v-if="routeItem?.children?.length" #overlay>
Expand Down Expand Up @@ -58,7 +58,7 @@
<script lang="tsx" setup>
import { computed } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { useRouter, useRoute, RouteRecordRaw } from 'vue-router';
import {
QuestionCircleOutlined,
SettingOutlined,
Expand All @@ -79,7 +79,6 @@
Tooltip,
} from 'ant-design-vue';
import { Search, FullScreen } from './components';
import type { RouteRecordRaw } from 'vue-router';
import { LocalePicker } from '@/components/basic/locale-picker';
import { useUserStore } from '@/store/modules/user';
import { useLockscreenStore } from '@/store/modules/lockscreen';
Expand Down
20 changes: 1 addition & 19 deletions src/layout/tabs/tabs-view.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
const tabsViewStore = useTabsViewStore();
const keepAliveStore = useKeepAliveStore();
const activeKey = computed(() => route.fullPath);
const activeKey = computed(() => tabsViewStore.getCurrentTab?.fullPath);
// 标签页列表
const tabsList = computed(() => tabsViewStore.getTabsList);
Expand Down Expand Up @@ -147,17 +147,6 @@
// tabsViewMutations.initTabs(routes)
// 将当前组件从keep-alive缓存中移除
const delCurrCompFromKeepAlive = () => {
if (route.meta.keepAlive) {
const name = router.currentRoute.value.matched.find((item) => item.name == route.name)
?.components?.default.name;
if (name) {
keepAliveStore.remove(name);
}
}
};
watch(
() => route.fullPath,
() => {
Expand All @@ -183,14 +172,8 @@
if (tabsList.value.length === 1) {
return message.warning('这已经是最后一页,不能再关闭了!');
}
delCurrCompFromKeepAlive();
// tabsViewMutations.closeCurrentTabs(route)
tabsViewStore.closeCurrentTab(route);
// 如果关闭的是当前页
if (activeKey.value === route.fullPath) {
const currentRoute = tabsList.value[Math.max(0, tabsList.value.length - 1)];
router.push(currentRoute);
}
};
// tabs 编辑(remove || add)
const editTabItem = (targetKey, action: string) => {
Expand All @@ -205,7 +188,6 @@
// 刷新页面
const reloadPage = () => {
delCurrCompFromKeepAlive();
router.replace({
name: REDIRECT_NAME,
params: {
Expand Down
25 changes: 19 additions & 6 deletions src/store/modules/tabsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,17 @@ export const useTabsViewStore = defineStore({
return !item.meta?.hideInTabs && router.hasRoute(item.name!);
});
},
/** 当前activity tab */
getCurrentTab: (state) => {
const currentRoute = router.currentRoute.value!;
return state.tabsList.find((item) => {
return !item.meta?.hideInTabs && item.fullPath === currentRoute.fullPath;
});
},
},
actions: {
/** 将已关闭的标签页的组件从keep-alive中移除 */
delCompFormClosedTabs(closedTabs: RouteLocationNormalized[]) {
delCompFromClosedTabs(closedTabs: RouteLocationNormalized[]) {
const keepAliveStore = useKeepAliveStore();
const routes = router.getRoutes();
const compNames = closedTabs.reduce<string[]>((prev, curr) => {
Expand Down Expand Up @@ -56,30 +63,36 @@ export const useTabsViewStore = defineStore({
/** 关闭左侧 */
closeLeftTabs(route) {
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
this.delCompFormClosedTabs(this.tabsList.splice(0, index));
this.delCompFromClosedTabs(this.tabsList.splice(0, index));
},
/** 关闭右侧 */
closeRightTabs(route) {
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
this.delCompFormClosedTabs(this.tabsList.splice(index + 1));
this.delCompFromClosedTabs(this.tabsList.splice(index + 1));
},
/** 关闭其他 */
closeOtherTabs(route) {
const targetIndex = this.tabsList.findIndex((item) => item.fullPath === route.fullPath);
if (targetIndex !== -1) {
const current = this.tabsList.splice(targetIndex, 1);
this.delCompFormClosedTabs(this.tabsList);
this.delCompFromClosedTabs(this.tabsList);
this.tabsList = current;
}
},
/** 关闭当前页 */
closeCurrentTab(route) {
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
this.delCompFormClosedTabs(this.tabsList.splice(index, 1));
const isDelCurrentTab = Object.is(this.getCurrentTab, this.tabsList[index]);
this.delCompFromClosedTabs(this.tabsList.splice(index, 1));
// 如果关闭的tab就是当前激活的tab,则重定向页面
if (isDelCurrentTab) {
const currentRoute = this.tabsList[Math.max(0, this.tabsList.length - 1)];
router.push(currentRoute);
}
},
/** 关闭全部 */
closeAllTabs() {
this.delCompFormClosedTabs(this.tabsList);
this.delCompFromClosedTabs(this.tabsList);
this.tabsList = [];
localStorage.removeItem(TABS_ROUTES);
},
Expand Down
14 changes: 7 additions & 7 deletions src/store/modules/user.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type RouteRecordRaw } from 'vue-router';
import { defineStore } from 'pinia';
import { useWsStore } from './ws';
import type { RouteRecordRaw } from 'vue-router';
import { store } from '@/store';
import { login } from '@/api/login';
import { ACCESS_TOKEN_KEY } from '@/enums/cacheEnum';
Expand Down Expand Up @@ -44,21 +44,21 @@ export const useUserStore = defineStore({
},
},
actions: {
// 清空token及用户信息
/** 清空token及用户信息 */
resetToken() {
this.avatar = this.token = this.name = '';
this.perms = [];
this.menus = [];
this.userInfo = {};
Storage.clear();
},
// 登录成功保存token
/** 登录成功保存token */
setToken(token: string) {
this.token = token ?? '';
const ex = 7 * 24 * 60 * 60 * 1000;
Storage.set(ACCESS_TOKEN_KEY, this.token, ex);
},
// 登录
/** 登录 */
async login(params: API.LoginParams) {
try {
const { data } = await login(params);
Expand All @@ -68,7 +68,7 @@ export const useUserStore = defineStore({
return Promise.reject(error);
}
},
// 登录成功之后, 获取用户信息以及生成权限路由
/** 登录成功之后, 获取用户信息以及生成权限路由 */
async afterLogin() {
try {
const wsStore = useWsStore();
Expand All @@ -80,14 +80,14 @@ export const useUserStore = defineStore({
// 生成路由
const generatorResult = generatorDynamicRouter(menus);
this.menus = generatorResult.menus.filter((item) => !item.meta?.hideInMenu);
wsStore.initSocket();
!wsStore.client && wsStore.initSocket();

return { menus, perms, userInfo };
} catch (error) {
// return this.logout();
}
},
// 登出
/** 登出 */
async logout() {
await logout();
const wsStore = useWsStore();
Expand Down
24 changes: 23 additions & 1 deletion src/store/modules/ws.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { defineStore } from 'pinia';
import { Modal } from 'ant-design-vue';
import type { SocketIOWrapperType, SocketStatusType } from '@/core/socket/socket-io';
import router from '@/router';
import { store } from '@/store';
import { EVENT_KICK } from '@/core/socket/event-type';
import { EVENT_KICK, EVENT_UPDATE_MENU } from '@/core/socket/event-type';
import { SocketIOWrapper, SocketStatus } from '@/core/socket/socket-io';
import { useUserStore } from '@/store/modules/user';
import { useTabsViewStore } from '@/store/modules/tabsView';

interface WsState {
client: SocketIOWrapperType | null;
Expand Down Expand Up @@ -51,6 +53,26 @@ export const useWsStore = defineStore({
},
});
});
ws.subscribe(EVENT_UPDATE_MENU, async () => {
const userStore = useUserStore();
const tabsViewStore = useTabsViewStore();
console.log('EVENT_UPDATE_MENU', EVENT_UPDATE_MENU);

await userStore.afterLogin();
const currentRoute = router.currentRoute.value!;
const hasRoute = router.hasRoute(currentRoute.name!);
if (Object.is(hasRoute, false)) {
Modal.warning({
title: '提示',
content: `您的权限已被管理员修改,暂无当前页面预览权限!`,
centered: true,
okText: '关闭当前页',
onOk() {
tabsViewStore.closeCurrentTab(currentRoute);
},
});
}
});
this.setClient(ws);
},

Expand Down
6 changes: 1 addition & 5 deletions src/views/demos/form/dynamic-form/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@
<a-button class="mr-2" @click="deleteField"> 删除字段11 </a-button>
</div>
<a-card>
<schema-form ref="dynamicForm" v-bind="formProps">
<template #operate-button>
<a-button type="primary" @click="confirm"> 确定 </a-button>
</template>
</schema-form>
<schema-form ref="dynamicForm" v-bind="formProps" @submit="confirm"> </schema-form>
</a-card>
</div>
</template>
Expand Down
6 changes: 1 addition & 5 deletions src/views/demos/form/rule-form/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@
</template>
</Alert>
<a-card>
<schema-form ref="dynamicForm" v-bind="formProps">
<template #operate-button>
<a-button type="primary" @click="confirm"> 确定 </a-button>
</template>
</schema-form>
<schema-form ref="dynamicForm" v-bind="formProps" @submit="confirm"> </schema-form>
</a-card>
</div>
</template>
Expand Down
6 changes: 1 addition & 5 deletions src/views/demos/form/use-form/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@
<a-button class="mr-2" @click="deleteField"> 删除字段11 </a-button>
</div>
<a-card>
<SchemaForm>
<template #operate-button>
<a-button type="primary" @click="confirm"> 确定 </a-button>
</template>
</SchemaForm>
<SchemaForm @submit="confirm"> </SchemaForm>
</a-card>
</div>
</template>
Expand Down

1 comment on commit adbda89

@vercel
Copy link

@vercel vercel bot commented on adbda89 Mar 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.