diff --git a/src/components/custom/look-forward.vue b/src/components/custom/look-forward.vue index 7c0db0bf..085129d2 100644 --- a/src/components/custom/look-forward.vue +++ b/src/components/custom/look-forward.vue @@ -11,7 +11,9 @@ defineOptions({
-

{{ $t('common.lookForward') }}

+ +

{{ $t('common.lookForward') }}

+
diff --git a/src/locales/langs/en-us.ts b/src/locales/langs/en-us.ts index 37843e75..f41a0d45 100644 --- a/src/locales/langs/en-us.ts +++ b/src/locales/langs/en-us.ts @@ -111,6 +111,9 @@ const local: App.I18n.Schema = { home: 'Home', 'user-center': 'User Center', about: 'About', + function: 'System Function', + function_tab: 'Tab', + 'function_multi-tab': 'Multi Tab', manage: 'System Manage', manage_user: 'User Manage', 'manage_user-detail': 'User Detail', @@ -211,6 +214,32 @@ const local: App.I18n.Schema = { desc5: 'Soybean just wrote some of the workbench pages casually, and it was enough to see!' }, creativity: 'Creativity' + }, + function: { + tab: { + tabOperate: { + title: 'Tab Operation', + addTab: 'Add Tab', + addTabDesc: 'To about page', + closeTab: 'Close Tab', + closeCurrentTab: 'Close Current Tab', + closeAboutTab: 'Close "About" Tab', + addMultiTab: 'Add Multi Tab', + addMultiTabDesc1: 'To MultiTab page', + addMultiTabDesc2: 'To MultiTab page(with query params)' + }, + tabTitle: { + title: 'Tab Title', + changeTitle: 'Change Title', + change: 'Change', + resetTitle: 'Reset Title', + reset: 'Reset' + } + }, + multiTab: { + routeParam: 'Route Param', + backTab: 'Back function_tab' + } } }, form: { diff --git a/src/locales/langs/zh-cn.ts b/src/locales/langs/zh-cn.ts index 014ea07b..137bfacc 100644 --- a/src/locales/langs/zh-cn.ts +++ b/src/locales/langs/zh-cn.ts @@ -111,6 +111,9 @@ const local: App.I18n.Schema = { home: '首页', 'user-center': '个人中心', about: '关于', + function: '系统功能', + function_tab: '标签页', + 'function_multi-tab': '多标签页', manage: '系统管理', manage_user: '用户管理', 'manage_user-detail': '用户详情', @@ -211,6 +214,32 @@ const local: App.I18n.Schema = { desc5: 'Soybean 刚才把工作台页面随便写了一些,凑合能看了!' }, creativity: '创意' + }, + function: { + tab: { + tabOperate: { + title: '标签页操作', + addTab: '添加标签页', + addTabDesc: '跳转到关于页面', + closeTab: '关闭标签页', + closeCurrentTab: '关闭当前标签页', + closeAboutTab: '关闭"关于"标签页', + addMultiTab: '添加多标签页', + addMultiTabDesc1: '跳转到多标签页页面', + addMultiTabDesc2: '跳转到多标签页页面(带有查询参数)' + }, + tabTitle: { + title: '标签页标题', + changeTitle: '修改标题', + change: '修改', + resetTitle: '重置标题', + reset: '重置' + } + }, + multiTab: { + routeParam: '路由参数', + backTab: '返回 function_tab' + } } }, form: { diff --git a/src/router/elegant/imports.ts b/src/router/elegant/imports.ts index 7872a431..e4d3fd40 100644 --- a/src/router/elegant/imports.ts +++ b/src/router/elegant/imports.ts @@ -20,6 +20,8 @@ export const views: Record Promise import("@/views/_builtin/500/index.vue"), login: () => import("@/views/_builtin/login/index.vue"), about: () => import("@/views/about/index.vue"), + "function_multi-tab": () => import("@/views/function/multi-tab/index.vue"), + function_tab: () => import("@/views/function/tab/index.vue"), home: () => import("@/views/home/index.vue"), manage_role: () => import("@/views/manage/role/index.vue"), manage_route: () => import("@/views/manage/route/index.vue"), diff --git a/src/router/elegant/routes.ts b/src/router/elegant/routes.ts index 0dbf9804..f8ce9800 100644 --- a/src/router/elegant/routes.ts +++ b/src/router/elegant/routes.ts @@ -47,6 +47,42 @@ export const generatedRoutes: GeneratedRoute[] = [ order: 10 } }, + { + name: 'function', + path: '/function', + component: 'layout.base', + meta: { + title: 'function', + i18nKey: 'route.function', + icon: 'icon-park-outline:all-application', + order: 6 + }, + children: [ + { + name: 'function_multi-tab', + path: '/function/multi-tab', + component: 'view.function_multi-tab', + meta: { + title: 'function_multi-tab', + i18nKey: 'route.function_multi-tab', + icon: 'ic:round-tab', + multiTab: true, + hideInMenu: true, + activeMenu: 'function_tab' + } + }, + { + name: 'function_tab', + path: '/function/tab', + component: 'view.function_tab', + meta: { + title: 'function_tab', + i18nKey: 'route.function_tab', + icon: 'ic:round-tab' + } + } + ] + }, { name: 'home', path: '/home', diff --git a/src/router/elegant/transform.ts b/src/router/elegant/transform.ts index e0688fb9..63eb0d3f 100644 --- a/src/router/elegant/transform.ts +++ b/src/router/elegant/transform.ts @@ -151,6 +151,9 @@ const routeMap: RouteMap = { "404": "/404", "500": "/500", "about": "/about", + "function": "/function", + "function_multi-tab": "/function/multi-tab", + "function_tab": "/function/tab", "home": "/home", "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?", "manage": "/manage", diff --git a/src/store/modules/tab/index.ts b/src/store/modules/tab/index.ts index 1add834a..a4399a31 100644 --- a/src/store/modules/tab/index.ts +++ b/src/store/modules/tab/index.ts @@ -2,6 +2,7 @@ import { computed, ref } from 'vue'; import { useRouter } from 'vue-router'; import { defineStore } from 'pinia'; import { useEventListener } from '@vueuse/core'; +import type { RouteKey } from '@elegant-router/types'; import { SetupStoreId } from '@/enum'; import { useRouterPush } from '@/hooks/common/router'; import { localStg } from '@/utils/storage'; @@ -10,6 +11,7 @@ import { filterTabsByAllRoutes, filterTabsById, filterTabsByIds, + findTabByRouteName, getAllTabs, getDefaultHomeTab, getFixedTabIds, @@ -112,6 +114,23 @@ export const useTabStore = defineStore(SetupStoreId.Tab, () => { } } + /** remove active tab */ + async function removeActiveTab() { + await removeTab(activeTabId.value); + } + + /** + * remove tab by route name + * + * @param routeName route name + */ + async function removeTabByRouteName(routeName: RouteKey) { + const tab = findTabByRouteName(routeName, tabs.value); + if (!tab) return; + + await removeTab(tab.id); + } + /** * Clear tabs * @@ -192,6 +211,7 @@ export const useTabStore = defineStore(SetupStoreId.Tab, () => { const tab = tabs.value.find(item => item.id === id); if (!tab) return; + tab.oldLabel = tab.label; tab.newLabel = label; } @@ -252,6 +272,8 @@ export const useTabStore = defineStore(SetupStoreId.Tab, () => { initTabStore, addTab, removeTab, + removeActiveTab, + removeTabByRouteName, clearTabs, clearLeftTabs, clearRightTabs, diff --git a/src/store/modules/tab/shared.ts b/src/store/modules/tab/shared.ts index 2036ef3c..702180f8 100644 --- a/src/store/modules/tab/shared.ts +++ b/src/store/modules/tab/shared.ts @@ -1,5 +1,5 @@ import type { Router } from 'vue-router'; -import type { LastLevelRouteKey, RouteMap } from '@elegant-router/types'; +import type { LastLevelRouteKey, RouteKey, RouteMap } from '@elegant-router/types'; import { $t } from '@/locales'; import { getRoutePath } from '@/router/elegant/transform'; @@ -166,10 +166,12 @@ export function getFixedTabIds(tabs: App.Global.Tab[]) { * @param tabs */ function updateTabsLabel(tabs: App.Global.Tab[]) { - return tabs.map(tab => ({ + const updated = tabs.map(tab => ({ ...tab, - label: tab.newLabel || tab.label + label: tab.newLabel || tab.oldLabel || tab.label })); + + return updated; } /** @@ -194,3 +196,18 @@ export function updateTabByI18nKey(tab: App.Global.Tab) { export function updateTabsByI18nKey(tabs: App.Global.Tab[]) { return tabs.map(tab => updateTabByI18nKey(tab)); } + +/** + * find tab by route name + * + * @param name + * @param tabs + */ +export function findTabByRouteName(name: RouteKey, tabs: App.Global.Tab[]) { + const routePath = getRoutePath(name); + + const tabId = routePath; + const multiTabId = `${routePath}?`; + + return tabs.find(tab => tab.id === tabId || tab.id.startsWith(multiTabId)); +} diff --git a/src/typings/app.d.ts b/src/typings/app.d.ts index 1de1ad18..b62ae307 100644 --- a/src/typings/app.d.ts +++ b/src/typings/app.d.ts @@ -185,6 +185,12 @@ declare namespace App { * If set, the tab label will be replaced by this value */ newLabel?: string; + /** + * The old tab label + * + * when reset the tab label, the tab label will be replaced by this value + */ + oldLabel?: string; /** The tab route key */ routeKey: LastLevelRouteKey; /** The tab route path */ @@ -396,6 +402,32 @@ declare namespace App { }; creativity: string; }; + function: { + tab: { + tabOperate: { + title: string; + addTab: string; + addTabDesc: string; + closeTab: string; + closeCurrentTab: string; + closeAboutTab: string; + addMultiTab: string; + addMultiTabDesc1: string; + addMultiTabDesc2: string; + }; + tabTitle: { + title: string; + changeTitle: string; + change: string; + resetTitle: string; + reset: string; + }; + }; + multiTab: { + routeParam: string; + backTab: string; + }; + }; }; form: { userName: FormMsg; diff --git a/src/typings/components.d.ts b/src/typings/components.d.ts index c492a487..00a31432 100644 --- a/src/typings/components.d.ts +++ b/src/typings/components.d.ts @@ -41,6 +41,7 @@ declare module 'vue' { NGrid: typeof import('naive-ui')['NGrid'] NGridItem: typeof import('naive-ui')['NGridItem'] NInput: typeof import('naive-ui')['NInput'] + NInputGroup: typeof import('naive-ui')['NInputGroup'] NInputNumber: typeof import('naive-ui')['NInputNumber'] NList: typeof import('naive-ui')['NList'] NListItem: typeof import('naive-ui')['NListItem'] diff --git a/src/typings/elegant-router.d.ts b/src/typings/elegant-router.d.ts index 1da9adb7..85158df8 100644 --- a/src/typings/elegant-router.d.ts +++ b/src/typings/elegant-router.d.ts @@ -25,6 +25,9 @@ declare module "@elegant-router/types" { "404": "/404"; "500": "/500"; "about": "/about"; + "function": "/function"; + "function_multi-tab": "/function/multi-tab"; + "function_tab": "/function/tab"; "home": "/home"; "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?"; "manage": "/manage"; @@ -78,6 +81,7 @@ declare module "@elegant-router/types" { | "404" | "500" | "about" + | "function" | "home" | "login" | "manage" @@ -105,6 +109,8 @@ declare module "@elegant-router/types" { | "500" | "login" | "about" + | "function_multi-tab" + | "function_tab" | "home" | "manage_role" | "manage_route" diff --git a/src/views/function/multi-tab/index.vue b/src/views/function/multi-tab/index.vue new file mode 100644 index 00000000..cb14b8a2 --- /dev/null +++ b/src/views/function/multi-tab/index.vue @@ -0,0 +1,24 @@ + + + + + diff --git a/src/views/function/tab/index.vue b/src/views/function/tab/index.vue new file mode 100644 index 00000000..09c88fe7 --- /dev/null +++ b/src/views/function/tab/index.vue @@ -0,0 +1,88 @@ + + + + +