diff --git a/.vscode/settings.json b/.vscode/settings.json index 0cbfa452..ece7b1f2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -222,5 +222,7 @@ "vitest.disableWorkspaceWarning": true, "cSpell.words": ["tinymce"], "typescript.tsdk": "node_modules/typescript/lib", - "editor.linkedEditing": true // 自动同步更改html标签 + "editor.linkedEditing": true, // 自动同步更改html标签, + "vscodeCustomCodeColor.highlightValue": "v-access", // v-access显示的颜色 + "vscodeCustomCodeColor.highlightValueColor": "#CCFFFF" } diff --git a/CHANGELOG.md b/CHANGELOG.md index ab3d09ce..30a09d48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,14 @@ - 用户管理 新增从参数取默认密码 - 全局表格加上id 方便进行缓存列排序的操作 +- 支持菜单名称i18n **BUG FIXES** - 登录页面 关闭租户后下拉框没有正常隐藏 - 字典管理 关闭租户不应显示`同步租户字典`按钮 - 登录日志 漏掉了登录日志日期查询 +- 登出相关逻辑在并发(非await)情况下重复执行的问题 **OTHERS** diff --git a/apps/web-antd/src/api/request.ts b/apps/web-antd/src/api/request.ts index 2bdc1c7d..989ddda1 100644 --- a/apps/web-antd/src/api/request.ts +++ b/apps/web-antd/src/api/request.ts @@ -34,8 +34,11 @@ const { apiURL, clientId, enableEncrypt } = useAppConfig( import.meta.env.PROD, ); -/** 控制是否弹窗 防止登录超时请求多个api会弹窗多次 */ -let showTimeoutToast = true; +/** + * 是否已经处在登出过程中了 一个标志位 + * 主要是防止一个页面会请求多个api 都401 会导致登出执行多次 + */ +let isLogoutProcessing = false; function createRequestClient(baseURL: string) { const client = new RequestClient({ @@ -234,18 +237,16 @@ function createRequestClient(baseURL: string) { let timeoutMsg = ''; switch (code) { case 401: { + // 已经在登出过程中 不再执行 + if (isLogoutProcessing) { + return; + } + isLogoutProcessing = true; const _msg = '登录超时, 请重新登录'; const userStore = useAuthStore(); - userStore.logout().then(() => { - /** 只弹窗一次 */ - if (showTimeoutToast) { - showTimeoutToast = false; - message.error(_msg); - /** 定时器 3s后再开启弹窗 */ - setTimeout(() => { - showTimeoutToast = true; - }, 3000); - } + userStore.logout().finally(() => { + message.error(_msg); + isLogoutProcessing = false; }); // 不再执行下面逻辑 return; diff --git a/apps/web-antd/src/locales/langs/en-US.json b/apps/web-antd/src/locales/langs/en-US.json index 2fac357b..ece9278c 100644 --- a/apps/web-antd/src/locales/langs/en-US.json +++ b/apps/web-antd/src/locales/langs/en-US.json @@ -84,6 +84,7 @@ } }, "menu": { + "root": "Root", "system": { "root": "System", "user": "User", diff --git a/apps/web-antd/src/locales/langs/zh-CN.json b/apps/web-antd/src/locales/langs/zh-CN.json index b6036dea..9ad8e04e 100644 --- a/apps/web-antd/src/locales/langs/zh-CN.json +++ b/apps/web-antd/src/locales/langs/zh-CN.json @@ -84,6 +84,7 @@ } }, "menu": { + "root": "根目录", "system": { "root": "系统管理", "user": "用户管理", diff --git a/apps/web-antd/src/views/system/menu/menu-drawer.vue b/apps/web-antd/src/views/system/menu/menu-drawer.vue index 0298f946..e07224e9 100644 --- a/apps/web-antd/src/views/system/menu/menu-drawer.vue +++ b/apps/web-antd/src/views/system/menu/menu-drawer.vue @@ -43,12 +43,16 @@ const [BasicForm, formApi] = useVbenForm({ async function setupMenuSelect() { // menu const menuArray = await menuList(); + // support i18n + menuArray.forEach((item) => { + item.menuName = $t(item.menuName); + }); // const folderArray = menuArray.filter((item) => item.menuType === 'M'); const menuTree = listToTree(menuArray, { id: 'menuId', pid: 'parentId' }); const fullMenuTree = [ { menuId: 0, - menuName: '根目录', + menuName: $t('menu.root'), children: menuTree, }, ]; diff --git a/apps/web-antd/src/views/tool/gen/edit-steps/basic-setting.vue b/apps/web-antd/src/views/tool/gen/edit-steps/basic-setting.vue index 9edaf73a..76bef792 100644 --- a/apps/web-antd/src/views/tool/gen/edit-steps/basic-setting.vue +++ b/apps/web-antd/src/views/tool/gen/edit-steps/basic-setting.vue @@ -4,6 +4,7 @@ import type { Column, GenInfo } from '#/api/tool/gen/model'; import { inject, onMounted, type Ref } from 'vue'; import { useVbenForm } from '@vben/common-ui'; +import { $t } from '@vben/locales'; import { addFullName, listToTree } from '@vben/utils'; import { Col, Row } from 'ant-design-vue'; @@ -66,12 +67,16 @@ async function initTreeSelect(columns: Column[]) { */ async function initMenuSelect() { const list = await menuList(); + // support i18n + list.forEach((item) => { + item.menuName = $t(item.menuName); + }); const tree = listToTree(list, { id: 'menuId', pid: 'parentId' }); const treeData = [ { - fullName: '根目录', + fullName: $t('menu.root'), menuId: 0, - menuName: '根目录', + menuName: $t('menu.root'), children: tree, }, ]; diff --git a/apps/web-antd/types/directive.d.ts b/apps/web-antd/types/directive.d.ts new file mode 100644 index 00000000..06b9f553 --- /dev/null +++ b/apps/web-antd/types/directive.d.ts @@ -0,0 +1,13 @@ +import type { Directive } from 'vue'; + +declare module 'vue' { + export interface ComponentCustomProperties { + /** + * 判断权限: v-access:code="" + * 判断角色 v-access:role="" + * VueOfficial插件暂时不支持判断modifer/arg + * @see https://github.com/vuejs/language-tools/issues/4810 + */ + vAccess: Directive; + } +}