@pubinfo/core 2.0.0-rc.2 → 2.0.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AppSetting-D2RJrc9O.js → AppSetting-BI-oNc4e.js} +19 -19
- package/dist/{HCheckList.vue_vue_type_script_setup_true_lang-DusVz35O.js → HCheckList.vue_vue_type_script_setup_true_lang-BdLpkcoh.js} +1 -1
- package/dist/{HToggle-DMcVgMVY.js → HToggle-DxdWLgp-.js} +1 -1
- package/dist/{PreferencesContent-Dtd9rtew.js → PreferencesContent-CCYkZeCT.js} +52 -52
- package/dist/{SettingBreadcrumb-QSCSviKM.js → SettingBreadcrumb-BTyfiy4k.js} +5 -5
- package/dist/{SettingCopyright-Dr5P6yfq.js → SettingCopyright-g6UHi8pZ.js} +2 -2
- package/dist/{SettingEnableTransition-DGiHEbCI.js → SettingEnableTransition-Ci-5bhbR.js} +12 -12
- package/dist/{SettingHome-CEPcBlds.js → SettingHome-K4Iel0Hr.js} +8 -8
- package/dist/{SettingMenu-BJdjnRA6.js → SettingMenu-BYLWzA5i.js} +14 -14
- package/dist/{SettingMode-BnuCHoEY.js → SettingMode-tRisyKtg.js} +3 -3
- package/dist/{SettingNavSearch-CiU4BmlU.js → SettingNavSearch-CSM6mPf8.js} +6 -6
- package/dist/{SettingOther-DTHjVlFe.js → SettingOther-Bj5KF_vC.js} +11 -11
- package/dist/{SettingPage-D75_Nf05.js → SettingPage-CFjmrVI7.js} +2 -2
- package/dist/{SettingTabbar-D48dzvgA.js → SettingTabbar-uFYiaZhK.js} +13 -13
- package/dist/{SettingThemes-D-8vTs5n.js → SettingThemes-C-tMq9o5.js} +12 -12
- package/dist/{SettingToolbar-DjIjm9V-.js → SettingToolbar-BfDzijNU.js} +10 -10
- package/dist/{SettingTopbar-Cg30OTH3.js → SettingTopbar-DTDv4NXD.js} +6 -6
- package/dist/{SettingWidthMode-BKV_7kb8.js → SettingWidthMode-PkiwrHe3.js} +11 -11
- package/dist/{TopThinMode-JFYsp_lJ.js → TopThinMode-BrvA8pV0.js} +3 -3
- package/dist/built-in/authentication/alova/helper.d.ts +34 -0
- package/dist/built-in/authentication/alova/token.d.ts +16 -0
- package/dist/built-in/authentication/helper.d.ts +10 -1
- package/dist/built-in/index.d.ts +0 -1
- package/dist/built-in/layout-component/Layout.vue.d.ts +1 -0
- package/dist/built-in/layout-component/components/Tools/Fullscreen.vue.d.ts +2 -0
- package/dist/built-in/layout-component/components/Tools/PageReload.vue.d.ts +2 -0
- package/dist/built-in/layout-component/components/Tools/SearchBar.vue.d.ts +2 -0
- package/dist/built-in/layout-component/components/Tools/index.vue.d.ts +47 -1
- package/dist/built-in/layout-component/components/Tools/interface.d.ts +26 -0
- package/dist/built-in/layout-component/components/ui/HDropdownMenu.vue.d.ts +2 -7
- package/dist/built-in/layout-component/components/ui/HSlideover.vue.d.ts +1 -1
- package/dist/built-in/layout-component/composables/useContext.d.ts +1 -1
- package/dist/built-in/layout-component/composables/useHotkey.d.ts +1 -5
- package/dist/built-in/layout-component/composables/useMainPage.d.ts +1 -1
- package/dist/built-in/layout-component/composables/useMenu.d.ts +1 -1
- package/dist/built-in/layout-component/composables/useTabbar.d.ts +1 -1
- package/dist/built-in/layout-component/composables/useTitle.d.ts +3 -2
- package/dist/built-in/layout-component/composables/useWatermark.d.ts +3 -1
- package/dist/built-in/layout-component/index.d.ts +9 -6
- package/dist/built-in/layout-component/utils/index.d.ts +0 -1
- package/dist/{colors-CODcBxrF.js → colors-VoaDbOhe.js} +1 -1
- package/dist/core/interface.d.ts +14 -5
- package/dist/core/request.d.ts +2 -8
- package/dist/features/api/modules/auth/renzhengfuwu.d.ts +8 -8
- package/dist/features/api/modules/configData/heibaimingdanfuwu.d.ts +5 -5
- package/dist/features/api/modules/configData/xitongpeizhifuwu.d.ts +14 -14
- package/dist/features/api/modules/configData/zidifuwu.d.ts +10 -10
- package/dist/features/api/modules/rbac/gangweijiekou.d.ts +6 -6
- package/dist/features/api/modules/rbac/jiaosejiekou.d.ts +7 -7
- package/dist/features/api/modules/rbac/pubJiaosezukongzhiqi.d.ts +7 -7
- package/dist/features/api/modules/rbac/shujuquanxianzhubiaokongzhiqi.d.ts +9 -9
- package/dist/features/api/modules/rbac/yonghujiekou.d.ts +15 -15
- package/dist/features/api/modules/rbac/yonghushoucangbiaojiekou.d.ts +5 -5
- package/dist/features/api/modules/rbac/yonghuzuijinchangyongbiaojiekou.d.ts +4 -4
- package/dist/features/api/modules/rbac/ziyuanjiekou.d.ts +13 -13
- package/dist/features/api/modules/rbac/zuhuguanlijiekou.d.ts +5 -5
- package/dist/features/api/modules/rbac/zuzhijiaosebiaokongzhiqi.d.ts +4 -4
- package/dist/features/api/modules/rbac/zuzhijiekou.d.ts +9 -9
- package/dist/features/api/system/user.d.ts +4 -4
- package/dist/{index-RT-QBzm0.js → index-BSevJVD5.js} +10 -15
- package/dist/{index-BVLkBCRY.js → index-BfGqLWFB.js} +6418 -6439
- package/dist/{index-DQn1WFMa.js → index-CYoFRwvw.js} +2 -2
- package/dist/{index-DmcblkoZ.js → index-ConeY38N.js} +13 -13
- package/dist/{index-BAoB7aoj.js → index-DV3hkzKA.js} +1 -1
- package/dist/{index-D4_xmL_A.js → index-Ddw98rJ5.js} +25 -25
- package/dist/{index-DvJr0paY.js → index-DrC787X_.js} +2 -2
- package/dist/{index-BROqFYXS.js → index-Dv9ndBoi.js} +1 -1
- package/dist/{index-Jd3PYkpj.js → index-IAYhIBQH.js} +16815 -16694
- package/dist/index.d.ts +4 -2
- package/dist/index.js +53 -55
- package/dist/{pick-BLJM77QN.js → pick-vpv9EEvu.js} +1 -1
- package/dist/style.css +1 -1
- package/package.json +11 -11
- package/src/built-in/authentication/alova/helper.ts +158 -0
- package/src/built-in/authentication/alova/token.ts +122 -0
- package/src/built-in/authentication/helper.ts +7 -3
- package/src/built-in/authentication/index.ts +6 -20
- package/src/built-in/index.ts +0 -1
- package/src/built-in/layout-component/Layout.vue +11 -22
- package/src/built-in/layout-component/components/Header/TopMode/index.vue +4 -4
- package/src/built-in/layout-component/components/Menu/item.vue +3 -3
- package/src/built-in/layout-component/components/Sidebar/MainSidebar.vue +4 -4
- package/src/built-in/layout-component/components/Sidebar/index.vue +1 -1
- package/src/built-in/layout-component/components/Tools/DarkModeToggle.vue +108 -0
- package/src/built-in/layout-component/components/Tools/Fullscreen.vue +24 -0
- package/src/built-in/layout-component/components/Tools/PageReload.vue +22 -0
- package/src/built-in/layout-component/components/Tools/SearchBar.vue +42 -0
- package/src/built-in/layout-component/components/Tools/{Search.vue → SearchPanel.vue} +13 -21
- package/src/built-in/layout-component/components/Tools/index.vue +71 -142
- package/src/built-in/layout-component/components/Tools/interface.ts +27 -0
- package/src/built-in/layout-component/components/Topbar/Tabbar/MoreAction.vue +9 -12
- package/src/built-in/layout-component/components/Topbar/Tabbar/index.vue +12 -15
- package/src/built-in/layout-component/components/Topbar/Toolbar/Favorites.vue +4 -7
- package/src/built-in/layout-component/components/Topbar/Toolbar/index.vue +6 -6
- package/src/built-in/layout-component/components/ui/HDropdownMenu.vue +19 -26
- package/src/built-in/layout-component/composables/useContext.ts +1 -1
- package/src/built-in/layout-component/composables/useGetComputedStyle.ts +2 -3
- package/src/built-in/layout-component/composables/useHotkey.ts +6 -10
- package/src/built-in/layout-component/composables/useMainPage.ts +5 -6
- package/src/built-in/layout-component/composables/useMenu.ts +3 -5
- package/src/built-in/layout-component/composables/useTabbar.ts +3 -5
- package/src/built-in/layout-component/composables/useTitle.ts +10 -17
- package/src/built-in/layout-component/composables/useWatermark.ts +25 -12
- package/src/built-in/layout-component/index.ts +21 -12
- package/src/built-in/layout-component/provider.ts +7 -3
- package/src/built-in/layout-component/utils/index.ts +0 -1
- package/src/built-in/settings/router.ts +5 -1
- package/src/core/interface.ts +18 -5
- package/src/core/request.ts +35 -15
- package/src/features/router/systemRoutes.ts +0 -1
- package/src/features/stores/modules/favorites.ts +0 -1
- package/src/features/stores/modules/route.ts +2 -9
- package/src/features/stores/modules/tabbar.ts +0 -3
- package/src/features/stores/utils/routerHelper.ts +38 -4
- package/src/index.ts +7 -11
- package/types/vue-router.d.ts +0 -3
- package/dist/built-in/layout-component/utils/eventBus.d.ts +0 -5
- package/dist/built-in/locales/helpler.d.ts +0 -594
- package/dist/built-in/locales/index.d.ts +0 -5
- package/dist/built-in/locales/lang/en.json.d.ts +0 -99
- package/dist/built-in/locales/lang/zh-cn.json.d.ts +0 -100
- package/dist/built-in/locales/lang/zh-tw.json.d.ts +0 -100
- package/dist/built-in/locales/ui.d.ts +0 -3
- package/src/built-in/layout-component/components/Tools/DayNightSwitch.vue +0 -70
- package/src/built-in/layout-component/utils/eventBus.ts +0 -8
- package/src/built-in/locales/helpler.ts +0 -76
- package/src/built-in/locales/index.ts +0 -20
- package/src/built-in/locales/lang/en.json +0 -96
- package/src/built-in/locales/lang/zh-cn.json +0 -97
- package/src/built-in/locales/lang/zh-tw.json +0 -97
- package/src/built-in/locales/ui.ts +0 -3
- /package/dist/built-in/layout-component/components/Tools/{DayNightSwitch.vue.d.ts → DarkModeToggle.vue.d.ts} +0 -0
- /package/dist/built-in/layout-component/components/Tools/{Search.vue.d.ts → SearchPanel.vue.d.ts} +0 -0
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import type { Tabbar } from '#/tabbar';
|
|
3
3
|
import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue';
|
|
4
4
|
import Sortable from 'sortablejs';
|
|
5
|
-
import { useI18n } from 'vue-i18n';
|
|
6
5
|
import EpClose from '~icons/ep/close';
|
|
7
6
|
import EpSearch from '~icons/ep/search';
|
|
8
7
|
import PhArrowLineLeft from '~icons/ph/arrow-line-left';
|
|
@@ -13,8 +12,8 @@ import RiPushpin2Fill from '~icons/ri/pushpin-2-fill';
|
|
|
13
12
|
import { PubinfoIcon } from '@/features/components';
|
|
14
13
|
import { useContext } from '../../../composables/useContext';
|
|
15
14
|
import { useGlobalSearch } from '../../../composables/useGlobalSearch';
|
|
16
|
-
import useTabbar from '../../../composables/useTabbar';
|
|
17
|
-
import Search from '../../Tools/
|
|
15
|
+
import { useTabbar } from '../../../composables/useTabbar';
|
|
16
|
+
import Search from '../../Tools/SearchPanel.vue';
|
|
18
17
|
|
|
19
18
|
defineOptions({
|
|
20
19
|
name: 'TabbarMoreAction',
|
|
@@ -22,12 +21,10 @@ defineOptions({
|
|
|
22
21
|
|
|
23
22
|
const router = useRouter();
|
|
24
23
|
|
|
25
|
-
const { settingsStore, tabbarStore,
|
|
24
|
+
const { settingsStore, tabbarStore, generateTitle } = useContext();
|
|
26
25
|
|
|
27
26
|
const tabbar = useTabbar();
|
|
28
27
|
|
|
29
|
-
const { t } = useI18n();
|
|
30
|
-
|
|
31
28
|
const activedTabId = computed(() => tabbar.getId());
|
|
32
29
|
|
|
33
30
|
const dropdownTabContainerRef = ref();
|
|
@@ -99,22 +96,22 @@ function iconName(isActive: boolean, icon: Tabbar.recordRaw['icon'], activeIcon:
|
|
|
99
96
|
<template #dropdown>
|
|
100
97
|
<div class="quick-button">
|
|
101
98
|
<button v-if="settingsStore.settings.navSearch.enable" class="button" @click="actionCommand('search-tabs')">
|
|
102
|
-
<HTooltip
|
|
99
|
+
<HTooltip text="搜索标签页">
|
|
103
100
|
<EpSearch />
|
|
104
101
|
</HTooltip>
|
|
105
102
|
</button>
|
|
106
103
|
<button class="button" :disabled="!tabbar.checkCloseOtherSide()" @click="actionCommand('other-side')">
|
|
107
|
-
<HTooltip
|
|
104
|
+
<HTooltip text="关闭其它标签页">
|
|
108
105
|
<EpClose />
|
|
109
106
|
</HTooltip>
|
|
110
107
|
</button>
|
|
111
108
|
<button class="button" :disabled="!tabbar.checkCloseLeftSide()" @click="actionCommand('left-side')">
|
|
112
|
-
<HTooltip
|
|
109
|
+
<HTooltip text="关闭左侧标签页">
|
|
113
110
|
<PhArrowLineLeft />
|
|
114
111
|
</HTooltip>
|
|
115
112
|
</button>
|
|
116
113
|
<button class="button" :disabled="!tabbar.checkCloseRightSide()" @click="actionCommand('right-side')">
|
|
117
|
-
<HTooltip
|
|
114
|
+
<HTooltip text="关闭右侧标签页">
|
|
118
115
|
<PhArrowLineRight />
|
|
119
116
|
</HTooltip>
|
|
120
117
|
</button>
|
|
@@ -127,9 +124,9 @@ function iconName(isActive: boolean, icon: Tabbar.recordRaw['icon'], activeIcon:
|
|
|
127
124
|
'no-drag': element.isPermanent || element.isPin,
|
|
128
125
|
}"
|
|
129
126
|
>
|
|
130
|
-
<div :key="element.tabId" class="title" :title="element.customTitleList.find(item => item.fullPath === element.fullPath)?.title ||
|
|
127
|
+
<div :key="element.tabId" class="title" :title="element.customTitleList.find(item => item.fullPath === element.fullPath)?.title || generateTitle(element.title)" @click="router.push(element.fullPath)">
|
|
131
128
|
<PubinfoIcon v-if="settingsStore.settings.tabbar.enableIcon && iconName(element.tabId === activedTabId, element.icon, element.activeIcon)" :name="iconName(element.tabId === activedTabId, element.icon, element.activeIcon)!" />
|
|
132
|
-
{{ element.customTitleList.find(item => item.fullPath === element.fullPath)?.title ||
|
|
129
|
+
{{ element.customTitleList.find(item => item.fullPath === element.fullPath)?.title || generateTitle(element.title) }}
|
|
133
130
|
</div>
|
|
134
131
|
<div v-if="!element.isPermanent && element.isPin" class="action-icon" @click.stop="tabbarStore.unPin(element.tabId)">
|
|
135
132
|
<RiPushpin2Fill />
|
|
@@ -4,15 +4,14 @@ import ContextMenu from '@imengyu/vue3-context-menu';
|
|
|
4
4
|
import { useMagicKeys } from '@vueuse/core';
|
|
5
5
|
import hotkeys from 'hotkeys-js';
|
|
6
6
|
import Sortable from 'sortablejs';
|
|
7
|
-
import { useI18n } from 'vue-i18n';
|
|
8
7
|
import Message from 'vue-m-message';
|
|
9
8
|
import RiCloseFill from '~icons/ri/close-fill';
|
|
10
9
|
import RiPushpin2Fill from '~icons/ri/pushpin-2-fill';
|
|
11
10
|
import { PubinfoIcon } from '@/features/components';
|
|
12
11
|
import { storage } from '@/utils';
|
|
13
12
|
import { useContext } from '../../../composables/useContext';
|
|
14
|
-
import useMainPage from '../../../composables/useMainPage';
|
|
15
|
-
import useTabbar from '../../../composables/useTabbar';
|
|
13
|
+
import { useMainPage } from '../../../composables/useMainPage';
|
|
14
|
+
import { useTabbar } from '../../../composables/useTabbar';
|
|
16
15
|
import MoreAction from './MoreAction.vue';
|
|
17
16
|
import '@imengyu/vue3-context-menu/lib/vue3-context-menu.css';
|
|
18
17
|
|
|
@@ -23,15 +22,13 @@ defineOptions({
|
|
|
23
22
|
const route = useRoute();
|
|
24
23
|
const router = useRouter();
|
|
25
24
|
|
|
26
|
-
const { settingsStore, tabbarStore,
|
|
25
|
+
const { settingsStore, tabbarStore, generateTitle } = useContext();
|
|
27
26
|
|
|
28
27
|
const tabbar = useTabbar();
|
|
29
28
|
const mainPage = useMainPage();
|
|
30
29
|
|
|
31
30
|
const keys = useMagicKeys({ reactive: true });
|
|
32
31
|
|
|
33
|
-
const { t } = useI18n();
|
|
34
|
-
|
|
35
32
|
const activedTabId = computed(() => tabbar.getId());
|
|
36
33
|
const isShowMoreAction = computed(() => tabbarStore.list.length > 1 && (tabbar.checkCloseOtherSide() || tabbar.checkCloseLeftSide() || tabbar.checkCloseRightSide()));
|
|
37
34
|
|
|
@@ -162,13 +159,13 @@ function onTabbarContextmenu(event: MouseEvent, routeItem: Tabbar.recordRaw) {
|
|
|
162
159
|
customClass: 'tabbar-contextmenu',
|
|
163
160
|
items: [
|
|
164
161
|
{
|
|
165
|
-
label:
|
|
162
|
+
label: '重新加载',
|
|
166
163
|
icon: 'i-ri-refresh-line',
|
|
167
164
|
disabled: routeItem.tabId !== activedTabId.value,
|
|
168
165
|
onClick: () => mainPage.reload(),
|
|
169
166
|
},
|
|
170
167
|
{
|
|
171
|
-
label:
|
|
168
|
+
label: '关闭标签页',
|
|
172
169
|
icon: 'i-ri-close-line',
|
|
173
170
|
disabled: tabbarStore.list.length <= 1 || routeItem.isPin || routeItem.isPermanent,
|
|
174
171
|
divided: true,
|
|
@@ -177,7 +174,7 @@ function onTabbarContextmenu(event: MouseEvent, routeItem: Tabbar.recordRaw) {
|
|
|
177
174
|
},
|
|
178
175
|
},
|
|
179
176
|
{
|
|
180
|
-
label: routeItem.isPin ?
|
|
177
|
+
label: routeItem.isPin ? '取消固定' : '固定',
|
|
181
178
|
icon: routeItem.isPin ? 'i-lucide-pin-off' : 'i-lucide-pin',
|
|
182
179
|
// 主页不允许被固定,因为如果固定主页且主页未启用,会导致登录时进入路由死循环状态
|
|
183
180
|
disabled: routeItem.fullPath === '/' || routeItem.isPermanent,
|
|
@@ -191,7 +188,7 @@ function onTabbarContextmenu(event: MouseEvent, routeItem: Tabbar.recordRaw) {
|
|
|
191
188
|
},
|
|
192
189
|
},
|
|
193
190
|
{
|
|
194
|
-
label:
|
|
191
|
+
label: '最大化',
|
|
195
192
|
icon: 'i-ri-picture-in-picture-exit-line',
|
|
196
193
|
onClick: () => {
|
|
197
194
|
if (routeItem.tabId !== activedTabId.value) {
|
|
@@ -202,21 +199,21 @@ function onTabbarContextmenu(event: MouseEvent, routeItem: Tabbar.recordRaw) {
|
|
|
202
199
|
},
|
|
203
200
|
},
|
|
204
201
|
{
|
|
205
|
-
label:
|
|
202
|
+
label: '关闭其它标签页',
|
|
206
203
|
disabled: !tabbar.checkCloseOtherSide(routeItem.tabId),
|
|
207
204
|
onClick: () => {
|
|
208
205
|
tabbar.closeOtherSide(routeItem.tabId);
|
|
209
206
|
},
|
|
210
207
|
},
|
|
211
208
|
{
|
|
212
|
-
label:
|
|
209
|
+
label: '关闭左侧标签页',
|
|
213
210
|
disabled: !tabbar.checkCloseLeftSide(routeItem.tabId),
|
|
214
211
|
onClick: () => {
|
|
215
212
|
tabbar.closeLeftSide(routeItem.tabId);
|
|
216
213
|
},
|
|
217
214
|
},
|
|
218
215
|
{
|
|
219
|
-
label:
|
|
216
|
+
label: '关闭右侧标签页',
|
|
220
217
|
disabled: !tabbar.checkCloseRightSide(routeItem.tabId),
|
|
221
218
|
onClick: () => {
|
|
222
219
|
tabbar.closeRightSide(routeItem.tabId);
|
|
@@ -319,7 +316,7 @@ onUnmounted(() => {
|
|
|
319
316
|
'actived': element.tabId === activedTabId,
|
|
320
317
|
'no-drag': element.isPermanent || element.isPin,
|
|
321
318
|
}"
|
|
322
|
-
:title="element.customTitleList.find(item => item.fullPath === element.fullPath)?.title ||
|
|
319
|
+
:title="element.customTitleList.find(item => item.fullPath === element.fullPath)?.title || generateTitle(element.title)"
|
|
323
320
|
@click="router.push(element.fullPath)"
|
|
324
321
|
@dblclick="settingsStore.setMainPageMaximize()"
|
|
325
322
|
@contextmenu="onTabbarContextmenu($event, element)"
|
|
@@ -333,7 +330,7 @@ onUnmounted(() => {
|
|
|
333
330
|
:name="iconName(element.tabId === activedTabId, element.icon, element.activeIcon)!"
|
|
334
331
|
class="icon"
|
|
335
332
|
/>
|
|
336
|
-
{{ element.customTitleList.find(item => item.fullPath === element.fullPath)?.title ||
|
|
333
|
+
{{ element.customTitleList.find(item => item.fullPath === element.fullPath)?.title || generateTitle(element.title) }}
|
|
337
334
|
</div>
|
|
338
335
|
<div v-if="!element.isPermanent && element.isPin" class="action-icon" @click.stop="tabbarStore.unPin(element.tabId)" @dblclick.stop>
|
|
339
336
|
<RiPushpin2Fill text="10px" />
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { isUndefined } from 'lodash-es';
|
|
3
3
|
import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue';
|
|
4
4
|
import Sortable from 'sortablejs';
|
|
5
|
-
import { useI18n } from 'vue-i18n';
|
|
6
5
|
import FluentDelete24Filled from '~icons/fluent/delete-24-filled';
|
|
7
6
|
import FluentStarAdd16Regular from '~icons/fluent/star-add-16-regular';
|
|
8
7
|
import FluentStarDismiss16Regular from '~icons/fluent/star-dismiss-16-regular';
|
|
@@ -15,9 +14,7 @@ defineOptions({
|
|
|
15
14
|
|
|
16
15
|
const route = useRoute();
|
|
17
16
|
const router = useRouter();
|
|
18
|
-
const { favoritesStore, routeStore,
|
|
19
|
-
const { t } = useI18n();
|
|
20
|
-
|
|
17
|
+
const { favoritesStore, routeStore, generateTitle } = useContext();
|
|
21
18
|
const favoritesContainerRef = ref<HTMLElement | null>(null);
|
|
22
19
|
|
|
23
20
|
let _favoritesSortable: Sortable | null = null;
|
|
@@ -46,7 +43,7 @@ watch(favoritesContainerRef, (newSortableContainer) => {
|
|
|
46
43
|
<div class="favorites-container w-80 dark:bg-[var(--g-container-bg)]">
|
|
47
44
|
<div class="flex items-center justify-between px-4 py-3">
|
|
48
45
|
<div class="text-sm font-bold">
|
|
49
|
-
{{
|
|
46
|
+
{{ '我的收藏夾' }}
|
|
50
47
|
</div>
|
|
51
48
|
<template v-if="favoritesStore.canAdd(route.fullPath, routeStore.routes)">
|
|
52
49
|
<FluentStarAdd16Regular
|
|
@@ -81,13 +78,13 @@ watch(favoritesContainerRef, (newSortableContainer) => {
|
|
|
81
78
|
<div
|
|
82
79
|
v-for="item in favoritesStore.list"
|
|
83
80
|
:key="item.fullPath"
|
|
84
|
-
:title="
|
|
81
|
+
:title="generateTitle(item.title)"
|
|
85
82
|
class="draggable-item relative w-[calc(50%-0.25rem)] flex cursor-pointer items-center gap-1 rounded px-2 py-2 ring-1 ring-stone-3 ring-inset hover:bg-stone-1 dark:ring-stone-7 dark:hover:bg-dark/50"
|
|
86
83
|
@click="router.push(item.fullPath)"
|
|
87
84
|
>
|
|
88
85
|
<PubinfoIcon v-if="item.icon" :name="item.icon" :size="18" />
|
|
89
86
|
<div class="name flex-1 truncate pe-4">
|
|
90
|
-
{{
|
|
87
|
+
{{ generateTitle(item.title) }}
|
|
91
88
|
</div>
|
|
92
89
|
<FluentDelete24Filled
|
|
93
90
|
text-12px
|
|
@@ -17,7 +17,7 @@ defineOptions({
|
|
|
17
17
|
const route = useRoute();
|
|
18
18
|
const router = useRouter();
|
|
19
19
|
|
|
20
|
-
const { settingsStore, menuStore,
|
|
20
|
+
const { settingsStore, menuStore, generateTitle } = useContext();
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* 计算属性:是否启用子菜单折叠按钮
|
|
@@ -52,7 +52,7 @@ const breadcrumbIsShow = computed(() =>
|
|
|
52
52
|
function createHomeBreadcrumb() {
|
|
53
53
|
return {
|
|
54
54
|
path: '/',
|
|
55
|
-
title:
|
|
55
|
+
title: generateTitle(settingsStore.settings.home.title),
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -78,7 +78,7 @@ const breadcrumbList = computed(() => {
|
|
|
78
78
|
breadcrumbList.push({
|
|
79
79
|
path: `__MAIN__${index}`,
|
|
80
80
|
mainIndex: index,
|
|
81
|
-
title:
|
|
81
|
+
title: generateTitle(menuStore.allMenus[index].meta?.title),
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
84
|
}
|
|
@@ -88,7 +88,7 @@ const breadcrumbList = computed(() => {
|
|
|
88
88
|
if (item.hide === false) {
|
|
89
89
|
breadcrumbList.push({
|
|
90
90
|
path: item.path,
|
|
91
|
-
title:
|
|
91
|
+
title: generateTitle(item.title),
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
94
|
});
|
|
@@ -155,14 +155,14 @@ function getCurrentBreadcrumb(path: string) {
|
|
|
155
155
|
const main = menuStore.allMenus[idx];
|
|
156
156
|
if (main) {
|
|
157
157
|
const mapNode = (r: any): any => ({
|
|
158
|
-
title:
|
|
158
|
+
title: generateTitle(r.meta?.title),
|
|
159
159
|
path: r.path,
|
|
160
160
|
children: (r.children || [])
|
|
161
161
|
.filter((c: any) => c.meta?.sidebar !== false)
|
|
162
162
|
.map((c: any) => mapNode(c)),
|
|
163
163
|
});
|
|
164
164
|
return {
|
|
165
|
-
title:
|
|
165
|
+
title: generateTitle(main.meta?.title),
|
|
166
166
|
path,
|
|
167
167
|
children: (main.children || [])
|
|
168
168
|
.filter(c => c.meta?.sidebar !== false)
|
|
@@ -1,20 +1,13 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import type { DropdownMenu } from '../Tools/interface';
|
|
2
3
|
import { PubinfoIcon } from '@/features/components';
|
|
3
4
|
|
|
4
5
|
const props = defineProps<{
|
|
5
|
-
items:
|
|
6
|
-
icon?: string
|
|
7
|
-
label: string
|
|
8
|
-
disabled?: boolean
|
|
9
|
-
hide?: boolean
|
|
10
|
-
handle?: () => void
|
|
11
|
-
}[][]
|
|
6
|
+
items: DropdownMenu[]
|
|
12
7
|
}>();
|
|
13
8
|
|
|
14
9
|
const myItems = computed(() => {
|
|
15
|
-
return props.items.
|
|
16
|
-
return item.filter(v => !v.hide);
|
|
17
|
-
}).filter(v => v.length);
|
|
10
|
+
return props.items.filter(item => !item?.hide);
|
|
18
11
|
});
|
|
19
12
|
</script>
|
|
20
13
|
|
|
@@ -27,23 +20,23 @@ const myItems = computed(() => {
|
|
|
27
20
|
:auto-hide="false"
|
|
28
21
|
>
|
|
29
22
|
<slot />
|
|
23
|
+
|
|
30
24
|
<template #popper>
|
|
31
|
-
<div
|
|
32
|
-
v-for="(item, index) in myItems"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
</button>
|
|
25
|
+
<div class="dark:bg-[var(--g-container-bg)] py-1">
|
|
26
|
+
<template v-for="(item, index) in myItems" :key="index">
|
|
27
|
+
<div v-if="item?.key === 'divider'" border-b="~ solid stone-2 dark:stone-7 last:size-0" class="my-1" />
|
|
28
|
+
|
|
29
|
+
<div v-else class="px-1">
|
|
30
|
+
<button
|
|
31
|
+
:disabled="item.disabled"
|
|
32
|
+
class="w-full flex cursor-pointer items-center gap-2 border-size-0 rounded-md bg-inherit px-2 py-1.5 text-sm text-dark disabled:cursor-not-allowed dark:text-white disabled:opacity-50 hover:not-disabled:bg-stone-1 dark:hover:not-disabled:bg-stone-9"
|
|
33
|
+
@click="item?.onClick"
|
|
34
|
+
>
|
|
35
|
+
<PubinfoIcon v-if="item?.icon" :name="item.icon" />
|
|
36
|
+
{{ item?.label }}
|
|
37
|
+
</button>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
47
40
|
</div>
|
|
48
41
|
</template>
|
|
49
42
|
</VMenu>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useContext } from './useContext';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 获取指定元素的计算样式属性值
|
|
@@ -17,8 +17,7 @@ type unit = `${string}px`;
|
|
|
17
17
|
* @returns 包含主侧边栏和子侧边栏实际宽度的计算属性对象。
|
|
18
18
|
*/
|
|
19
19
|
export function useGetSidebarActualWidth() {
|
|
20
|
-
const settingsStore =
|
|
21
|
-
const menuStore = useMenuStore();
|
|
20
|
+
const { settingsStore, menuStore } = useContext();
|
|
22
21
|
|
|
23
22
|
const mainSidebarActualWidth = computed<unit>(() => {
|
|
24
23
|
const menuMode = settingsStore.settings.menu.menuMode;
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import type { useMenuStore, useSettingsStore } from '@/features/stores';
|
|
2
1
|
import hotkeys from 'hotkeys-js';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
2
|
+
import { useContext } from './useContext';
|
|
3
|
+
import { useMainPage } from './useMainPage';
|
|
4
|
+
import { useMenu } from './useMenu';
|
|
5
|
+
|
|
6
|
+
export function useHotkey() {
|
|
7
|
+
const { settingsStore, menuStore } = useContext();
|
|
5
8
|
|
|
6
|
-
export function useHotkey({
|
|
7
|
-
menuStore,
|
|
8
|
-
settingsStore,
|
|
9
|
-
}: {
|
|
10
|
-
menuStore: ReturnType<typeof useMenuStore>
|
|
11
|
-
settingsStore: ReturnType<typeof useSettingsStore>
|
|
12
|
-
}) {
|
|
13
9
|
const mainPage = useMainPage();
|
|
14
10
|
const menu = useMenu();
|
|
15
11
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import useTabbar from './useTabbar';
|
|
1
|
+
import { useContext } from './useContext';
|
|
2
|
+
import { useTabbar } from './useTabbar';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* 用于主页面功能的自定义钩子。
|
|
@@ -9,13 +9,12 @@ import useTabbar from './useTabbar';
|
|
|
9
9
|
* - resetCustomTitle: 重置当前页面的自定义标题。
|
|
10
10
|
* - maximize: 设置主页面的最大化状态。
|
|
11
11
|
*/
|
|
12
|
-
export
|
|
12
|
+
export function useMainPage() {
|
|
13
|
+
const { settingsStore, tabbarStore } = useContext();
|
|
14
|
+
|
|
13
15
|
const route = useRoute();
|
|
14
16
|
const router = useRouter();
|
|
15
17
|
|
|
16
|
-
const settingsStore = useSettingsStore();
|
|
17
|
-
const tabbarStore = useTabbarStore();
|
|
18
|
-
|
|
19
18
|
const tabbar = useTabbar();
|
|
20
19
|
|
|
21
20
|
/**
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import type { Menu } from '#/menu';
|
|
2
2
|
import { message } from 'ant-design-vue';
|
|
3
|
-
import {
|
|
3
|
+
import { useContext } from './useContext';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* 用于管理菜单功能的自定义组合函数。
|
|
7
7
|
* @returns 一个包含 `switchTo` 函数的对象。
|
|
8
8
|
*/
|
|
9
|
-
export
|
|
9
|
+
export function useMenu() {
|
|
10
|
+
const { settingsStore, menuStore } = useContext();
|
|
10
11
|
const router = useRouter();
|
|
11
12
|
|
|
12
|
-
const settingsStore = useSettingsStore();
|
|
13
|
-
const menuStore = useMenuStore();
|
|
14
|
-
|
|
15
13
|
function switchTo(index: number | string, mainRouter?: Menu.recordMainRaw) {
|
|
16
14
|
if (mainRouter && mainRouter.meta?.isDev) {
|
|
17
15
|
message.info('暂未上线,敬请期待!');
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import type { RouteLocationRaw } from 'vue-router';
|
|
2
2
|
import Message from 'vue-m-message';
|
|
3
|
-
import {
|
|
3
|
+
import { useContext } from './useContext';
|
|
4
4
|
|
|
5
|
-
export
|
|
5
|
+
export function useTabbar() {
|
|
6
|
+
const { settingsStore, tabbarStore } = useContext();
|
|
6
7
|
const route = useRoute();
|
|
7
8
|
const router = useRouter();
|
|
8
9
|
|
|
9
|
-
const settingsStore = useSettingsStore();
|
|
10
|
-
const tabbarStore = useTabbarStore();
|
|
11
|
-
|
|
12
10
|
function getId() {
|
|
13
11
|
return settingsStore.settings.tabbar.mergeTabsBy === 'activeMenu' ? (route.meta.activeMenu ?? route.fullPath) : route.fullPath;
|
|
14
12
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useSettingsStore } from '@/features/stores';
|
|
1
|
+
import type { useSettingsStore } from '@/features/stores';
|
|
3
2
|
|
|
4
|
-
export function useTitle(appTitle: string) {
|
|
5
|
-
const settingsStore = useSettingsStore();
|
|
6
|
-
const { t, te } = useI18n();
|
|
3
|
+
export function useTitle(appTitle: string, settingsStore: ReturnType<typeof useSettingsStore>) {
|
|
7
4
|
const routeInfo = useRoute();
|
|
5
|
+
|
|
8
6
|
watch(
|
|
9
7
|
[
|
|
10
8
|
() => settingsStore.settings.app.enableDynamicTitle,
|
|
@@ -14,11 +12,7 @@ export function useTitle(appTitle: string) {
|
|
|
14
12
|
() => {
|
|
15
13
|
if (settingsStore.settings.app.enableDynamicTitle && settingsStore.title) {
|
|
16
14
|
const title = settingsStore.customTitleList.find(item => item.fullPath === routeInfo.fullPath)?.title
|
|
17
|
-
|| (
|
|
18
|
-
routeInfo.meta.breadcrumbNeste?.at(-1)?.i18n
|
|
19
|
-
? generateI18nTitle(routeInfo.meta.breadcrumbNeste?.at(-1)?.i18n, settingsStore.title)
|
|
20
|
-
: generateI18nTitle(routeInfo.meta.i18n, settingsStore.title)
|
|
21
|
-
);
|
|
15
|
+
|| generateTitle(settingsStore.title);
|
|
22
16
|
document.title = `${title} - ${appTitle}`;
|
|
23
17
|
}
|
|
24
18
|
else {
|
|
@@ -28,14 +22,13 @@ export function useTitle(appTitle: string) {
|
|
|
28
22
|
{
|
|
29
23
|
deep: true,
|
|
30
24
|
});
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
: defaultTitle;
|
|
25
|
+
|
|
26
|
+
function generateTitle(defaultTitle: string | (() => any) = '[ 无标题 ]') {
|
|
27
|
+
return typeof defaultTitle === 'function'
|
|
28
|
+
? defaultTitle()
|
|
29
|
+
: defaultTitle;
|
|
37
30
|
}
|
|
38
31
|
return {
|
|
39
|
-
|
|
32
|
+
generateTitle,
|
|
40
33
|
};
|
|
41
34
|
}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import mitt from 'mitt';
|
|
2
|
+
import { watermark } from '../utils';
|
|
3
|
+
import { useContext } from './useContext';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const eventBus = mitt();
|
|
6
|
+
|
|
7
|
+
export function useWatermark() {
|
|
8
|
+
const { settingsStore, userStore } = useContext();
|
|
7
9
|
const { init, remove } = watermark();
|
|
8
10
|
|
|
9
|
-
eventBus.on('updateWatermark',
|
|
11
|
+
eventBus.on('updateWatermark', updateWatermark);
|
|
12
|
+
|
|
13
|
+
function updateWatermark() {
|
|
10
14
|
if (settingsStore.settings.watermark.enable) {
|
|
11
15
|
loadWatermark();
|
|
12
16
|
window.addEventListener('resize', loadWatermark);
|
|
@@ -15,13 +19,17 @@ export default function useWatermark() {
|
|
|
15
19
|
removeWatermark();
|
|
16
20
|
window.removeEventListener('resize', loadWatermark);
|
|
17
21
|
}
|
|
18
|
-
}
|
|
22
|
+
}
|
|
19
23
|
|
|
20
|
-
watch(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
watch(
|
|
25
|
+
() => settingsStore.settings.app.colorScheme,
|
|
26
|
+
() => {
|
|
27
|
+
if (settingsStore.settings.watermark.enable) {
|
|
28
|
+
loadWatermark();
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{ immediate: true },
|
|
32
|
+
);
|
|
25
33
|
|
|
26
34
|
function getTextVal() {
|
|
27
35
|
const type = settingsStore.settings.watermark.text;
|
|
@@ -63,5 +71,10 @@ export default function useWatermark() {
|
|
|
63
71
|
return {
|
|
64
72
|
loadWatermark,
|
|
65
73
|
removeWatermark,
|
|
74
|
+
updateWatermark,
|
|
66
75
|
};
|
|
67
76
|
}
|
|
77
|
+
|
|
78
|
+
export function updateWatermark() {
|
|
79
|
+
eventBus.emit('updateWatermark');
|
|
80
|
+
}
|
|
@@ -7,18 +7,17 @@ import { Provider as LayoutProvider } from './provider';
|
|
|
7
7
|
import Layout from './Layout.vue';
|
|
8
8
|
import LayoutContent from './components/Content/index.vue';
|
|
9
9
|
import LayoutHeader from './components/Header/index.vue';
|
|
10
|
+
import LayoutSidebar from './components/Sidebar/index.vue';
|
|
11
|
+
import LayoutTopbar from './components/Topbar/index.vue';
|
|
10
12
|
|
|
11
13
|
import Logo from './components/Logo/index.vue';
|
|
12
|
-
import Menu from './components/Menu/index.vue';
|
|
13
14
|
import Tools from './components/Tools/index.vue';
|
|
15
|
+
import Fullscreen from './components/Tools/Fullscreen.vue';
|
|
16
|
+
import PageReload from './components/Tools/PageReload.vue';
|
|
17
|
+
import DarkModeToggle from './components/Tools/DarkModeToggle.vue';
|
|
14
18
|
|
|
15
|
-
import Topbar from './components/Topbar/index.vue';
|
|
16
|
-
import Sidebar from './components/Sidebar/index.vue';
|
|
17
19
|
import Copyright from './components/Copyright/index.vue';
|
|
18
20
|
|
|
19
|
-
import SettingBar from './components/SettingBar/index.vue';
|
|
20
|
-
import BackTop from './components/BackTop/index.vue';
|
|
21
|
-
|
|
22
21
|
import FloatingVue from 'floating-vue';
|
|
23
22
|
import Message from 'vue-m-message';
|
|
24
23
|
import 'vue-m-message/dist/style.css';
|
|
@@ -62,20 +61,30 @@ export function LayoutComponent(): ModuleOptions {
|
|
|
62
61
|
};
|
|
63
62
|
}
|
|
64
63
|
|
|
64
|
+
export type { DropdownMenu, DropdownMenuRender } from './components/Tools/interface';
|
|
65
|
+
|
|
66
|
+
export const Tool = {
|
|
67
|
+
Fullscreen,
|
|
68
|
+
PageReload,
|
|
69
|
+
DarkModeToggle,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
Layout.Provider = LayoutProvider;
|
|
73
|
+
Layout.Header = LayoutHeader;
|
|
74
|
+
Layout.Content = LayoutContent;
|
|
75
|
+
Layout.Sidebar = LayoutSidebar;
|
|
76
|
+
Layout.Topbar = LayoutTopbar;
|
|
77
|
+
|
|
65
78
|
export {
|
|
66
79
|
LayoutProvider,
|
|
67
80
|
Layout,
|
|
68
81
|
LayoutContent,
|
|
69
82
|
LayoutHeader,
|
|
83
|
+
LayoutSidebar,
|
|
84
|
+
LayoutTopbar,
|
|
70
85
|
|
|
71
86
|
Logo,
|
|
72
|
-
Menu,
|
|
73
87
|
Tools,
|
|
74
88
|
|
|
75
|
-
Topbar,
|
|
76
|
-
Sidebar,
|
|
77
89
|
Copyright,
|
|
78
|
-
|
|
79
|
-
SettingBar,
|
|
80
|
-
BackTop,
|
|
81
90
|
};
|
|
@@ -38,7 +38,7 @@ export const Provider = defineComponent({
|
|
|
38
38
|
const tabbarStore = useTabbarStore();
|
|
39
39
|
const favoritesStore = useFavoritesStore();
|
|
40
40
|
|
|
41
|
-
const {
|
|
41
|
+
const { generateTitle } = useTitle(props.appTitle, settingsStore);
|
|
42
42
|
|
|
43
43
|
createContext({
|
|
44
44
|
settingsStore,
|
|
@@ -52,13 +52,17 @@ export const Provider = defineComponent({
|
|
|
52
52
|
|
|
53
53
|
appTitle: props.appTitle,
|
|
54
54
|
isDev: props.isDev,
|
|
55
|
-
|
|
55
|
+
generateTitle,
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
return () => h(
|
|
59
59
|
PubinfoProvider,
|
|
60
60
|
{},
|
|
61
|
-
() => slots?.default?.(
|
|
61
|
+
() => slots?.default?.({
|
|
62
|
+
allMenus: menuStore.allMenus,
|
|
63
|
+
sidebarMenus: menuStore.sidebarMenus,
|
|
64
|
+
activedMenuIndex: menuStore.actived,
|
|
65
|
+
}),
|
|
62
66
|
);
|
|
63
67
|
},
|
|
64
68
|
});
|