@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
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useContext } from '../../composables/useContext';
|
|
3
|
+
import useViewTransition from '../../composables/useViewTransition';
|
|
4
|
+
|
|
5
|
+
defineOptions({
|
|
6
|
+
name: 'DarkModeToggle',
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const { settingsStore } = useContext();
|
|
10
|
+
|
|
11
|
+
function toggleColorScheme(event: MouseEvent) {
|
|
12
|
+
const { startViewTransition } = useViewTransition(async () => {
|
|
13
|
+
const colorScheme = settingsStore.settings.app.colorScheme === 'dark' ? 'light' : 'dark';
|
|
14
|
+
settingsStore.setColorScheme(colorScheme);
|
|
15
|
+
await settingsStore.setPreferencesSetting({
|
|
16
|
+
app: {
|
|
17
|
+
colorScheme,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
nextTick(() => {
|
|
23
|
+
startViewTransition()?.ready.then(() => {
|
|
24
|
+
const x = event.clientX;
|
|
25
|
+
const y = event.clientY;
|
|
26
|
+
const endRadius = Math.hypot(
|
|
27
|
+
Math.max(x, innerWidth - x),
|
|
28
|
+
Math.max(y, innerHeight - y),
|
|
29
|
+
);
|
|
30
|
+
const clipPath = [
|
|
31
|
+
`circle(0px at ${x}px ${y}px)`,
|
|
32
|
+
`circle(${endRadius}px at ${x}px ${y}px)`,
|
|
33
|
+
];
|
|
34
|
+
document.documentElement.animate(
|
|
35
|
+
{
|
|
36
|
+
clipPath: settingsStore.settings.app.colorScheme !== 'dark' ? clipPath : clipPath.reverse(),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
duration: 300,
|
|
40
|
+
easing: 'ease-out',
|
|
41
|
+
pseudoElement: settingsStore.settings.app.colorScheme !== 'dark' ? '::view-transition-new(root)' : '::view-transition-old(root)',
|
|
42
|
+
},
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<template>
|
|
50
|
+
<div
|
|
51
|
+
v-if="settingsStore.settings.toolbar.enableColorScheme"
|
|
52
|
+
class="inline-flex items-center justify-center cursor-pointer"
|
|
53
|
+
@click="toggleColorScheme"
|
|
54
|
+
>
|
|
55
|
+
<div
|
|
56
|
+
class="animate-icon"
|
|
57
|
+
:class="{
|
|
58
|
+
'animate-icon-day': settingsStore.settings.app.colorScheme !== 'dark',
|
|
59
|
+
}"
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
<style scoped>
|
|
65
|
+
.animate-icon {
|
|
66
|
+
--at-apply: relative size-[20px] rounded-1/2 inline-block align-middle;
|
|
67
|
+
box-shadow: inset 6px -6px 0 0 #fff; /* 比例缩小 */
|
|
68
|
+
transition: box-shadow 0.5s ease 0s, transform 0.4s ease 0.1s;
|
|
69
|
+
transform: scale(1) rotate(-2deg);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.animate-icon::before {
|
|
73
|
+
--at-apply: absolute size-[20px] content-empty rounded-[inherit] left-0 top-0 block;
|
|
74
|
+
transition: background 0.3s ease;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.animate-icon::after {
|
|
78
|
+
--at-apply: absolute top-1/2 left-1/2 size-1 -ml-0.5 -mt-0.5 rounded-[50%] content-empty block;
|
|
79
|
+
box-shadow:
|
|
80
|
+
0 -12px 0 #ffce6e,
|
|
81
|
+
0 12px 0 #ffce6e,
|
|
82
|
+
12px 0 0 #ffce6e,
|
|
83
|
+
-12px 0 0 #ffce6e,
|
|
84
|
+
8px 8px 0 #ffce6e,
|
|
85
|
+
-8px 8px 0 #ffce6e,
|
|
86
|
+
8px -8px 0 #ffce6e,
|
|
87
|
+
-8px -8px 0 #ffce6e;
|
|
88
|
+
transition: all 0.3s ease;
|
|
89
|
+
transform: scale(0);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.animate-icon-day {
|
|
93
|
+
--at-apply: size-5;
|
|
94
|
+
box-shadow: inset 10px -10px 0 0 #fff; /* 缩小后的太阳核心 */
|
|
95
|
+
transition: transform 0.3s ease 0.1s, box-shadow 0.2s ease 0s;
|
|
96
|
+
transform: scale(0.5) rotate(0deg);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.animate-icon-day::before {
|
|
100
|
+
background: #ffce6e;
|
|
101
|
+
transition: background 0.3s ease 0.1s;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.animate-icon-day::after {
|
|
105
|
+
transition: transform 0.5s ease 0.15s;
|
|
106
|
+
transform: scale(1.2);
|
|
107
|
+
}
|
|
108
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useFullscreen } from '@vueuse/core';
|
|
3
|
+
import FluentFullScreenMaximize16Filled from '~icons/fluent/full-screen-maximize-16-filled';
|
|
4
|
+
import FluentFullScreenMinimize16Filled from '~icons/fluent/full-screen-minimize-16-filled';
|
|
5
|
+
import { useContext } from '../../composables/useContext';
|
|
6
|
+
|
|
7
|
+
defineOptions({
|
|
8
|
+
name: 'Fullscreen',
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const { isFullscreen, toggle } = useFullscreen();
|
|
12
|
+
const { settingsStore } = useContext();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<div
|
|
17
|
+
v-if="settingsStore.mode === 'pc' && settingsStore.settings.toolbar.enableFullscreen"
|
|
18
|
+
class="size-5 cursor-pointer"
|
|
19
|
+
@click="toggle"
|
|
20
|
+
>
|
|
21
|
+
<FluentFullScreenMinimize16Filled v-if="isFullscreen" text="16px" />
|
|
22
|
+
<FluentFullScreenMaximize16Filled v-else text="16px" />
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import FluentArrowSync16Filled from '~icons/fluent/arrow-sync-16-filled';
|
|
3
|
+
import { useContext } from '../../composables/useContext';
|
|
4
|
+
import { useMainPage } from '../../composables/useMainPage';
|
|
5
|
+
|
|
6
|
+
defineOptions({
|
|
7
|
+
name: 'PageReload',
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const { settingsStore } = useContext();
|
|
11
|
+
const mainPage = useMainPage();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<div
|
|
16
|
+
v-if="settingsStore.settings.toolbar.enablePageReload"
|
|
17
|
+
class="size-5 cursor-pointer"
|
|
18
|
+
@click="mainPage.reload()"
|
|
19
|
+
>
|
|
20
|
+
<FluentArrowSync16Filled text="16px" />
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import IconamoonSearch from '~icons/iconamoon/search';
|
|
3
|
+
import { useContext } from '../../composables/useContext';
|
|
4
|
+
import { useGlobalSearch } from '../../composables/useGlobalSearch';
|
|
5
|
+
|
|
6
|
+
defineOptions({
|
|
7
|
+
name: 'SearchBar',
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const { settingsStore } = useContext();
|
|
11
|
+
const { toggle: toggleSearch } = useGlobalSearch();
|
|
12
|
+
|
|
13
|
+
const searchComponentsClass = computed(() => {
|
|
14
|
+
const componentsClass = {
|
|
15
|
+
'side': 'ring-1 ',
|
|
16
|
+
'head': 'bg-[var(--g-header-menu-active-bg)]',
|
|
17
|
+
'single': ' ring-1',
|
|
18
|
+
'only-side': 'ring-1',
|
|
19
|
+
'only-head': ' bg-[var(--g-header-menu-active-bg)]',
|
|
20
|
+
};
|
|
21
|
+
const menuMode = settingsStore.settings.menu.menuMode;
|
|
22
|
+
return componentsClass[menuMode];
|
|
23
|
+
});
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<template>
|
|
27
|
+
<span
|
|
28
|
+
v-if="settingsStore.settings.navSearch.enable"
|
|
29
|
+
class="group inline-flex cursor-pointer items-center gap-1 rounded-2 px-2 py-1.5 hover:ring-1 ring-inset transition ring-stone-3 dark:ring-stone-7"
|
|
30
|
+
:class="searchComponentsClass"
|
|
31
|
+
@click="toggleSearch('menu')"
|
|
32
|
+
>
|
|
33
|
+
<IconamoonSearch text="14px" />
|
|
34
|
+
<span class="text-sm transition ">{{ '搜索' }}</span>
|
|
35
|
+
<HKbd
|
|
36
|
+
v-if="settingsStore.settings.navSearch.enableHotkeys"
|
|
37
|
+
class="ml-2"
|
|
38
|
+
>
|
|
39
|
+
{{ settingsStore.os === 'mac' ? '⌥' : 'Alt' }} S
|
|
40
|
+
</HKbd>
|
|
41
|
+
</span>
|
|
42
|
+
</template>
|
|
@@ -6,7 +6,6 @@ import { Dialog, DialogDescription, DialogPanel, TransitionChild, TransitionRoot
|
|
|
6
6
|
import hotkeys from 'hotkeys-js';
|
|
7
7
|
import { cloneDeep } from 'lodash-es';
|
|
8
8
|
import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue';
|
|
9
|
-
import { useI18n } from 'vue-i18n';
|
|
10
9
|
import AntDesignCaretDownFilled from '~icons/ant-design/caret-down-filled';
|
|
11
10
|
import AntDesignCaretUpFilled from '~icons/ant-design/caret-up-filled';
|
|
12
11
|
import EpSearch from '~icons/ep/search';
|
|
@@ -22,7 +21,7 @@ import Breadcrumb from './Breadcrumb/index.vue';
|
|
|
22
21
|
import BreadcrumbItem from './Breadcrumb/item.vue';
|
|
23
22
|
|
|
24
23
|
defineOptions({
|
|
25
|
-
name: '
|
|
24
|
+
name: 'SearchPanel',
|
|
26
25
|
});
|
|
27
26
|
|
|
28
27
|
const overlayTransitionClass = ref({
|
|
@@ -45,17 +44,14 @@ const transitionClass = computed(() => {
|
|
|
45
44
|
};
|
|
46
45
|
});
|
|
47
46
|
|
|
48
|
-
const { t } = useI18n();
|
|
49
|
-
|
|
50
47
|
const router = useRouter();
|
|
51
|
-
const { settingsStore, routeStore, tabbarStore,
|
|
48
|
+
const { settingsStore, routeStore, tabbarStore, generateTitle } = useContext();
|
|
52
49
|
|
|
53
50
|
type searchTypes = 'menu' | 'tab';
|
|
54
51
|
interface listTypes {
|
|
55
52
|
path: string
|
|
56
53
|
icon?: string
|
|
57
54
|
title?: string | (() => string)
|
|
58
|
-
i18n?: string
|
|
59
55
|
link?: string
|
|
60
56
|
breadcrumb: any[]
|
|
61
57
|
}
|
|
@@ -76,13 +72,13 @@ const resultList = computed(() => {
|
|
|
76
72
|
let result = [];
|
|
77
73
|
result = sourceList.value.filter((item) => {
|
|
78
74
|
let flag = false;
|
|
79
|
-
if (
|
|
75
|
+
if (generateTitle(item.title).toString().includes(searchInput.value)) {
|
|
80
76
|
flag = true;
|
|
81
77
|
}
|
|
82
78
|
if (item.path.includes(searchInput.value)) {
|
|
83
79
|
flag = true;
|
|
84
80
|
}
|
|
85
|
-
if (item.breadcrumb.some((b: {
|
|
81
|
+
if (item.breadcrumb.some((b: { title: any }) => generateTitle(b.title).toString().includes(searchInput.value))) {
|
|
86
82
|
flag = true;
|
|
87
83
|
}
|
|
88
84
|
return flag;
|
|
@@ -155,27 +151,24 @@ function hasChildren(item: RouteRecordRaw) {
|
|
|
155
151
|
}
|
|
156
152
|
return flag;
|
|
157
153
|
}
|
|
158
|
-
function getSourceList(arr: RouteRecordRaw[], basePath?: string, icon?: string, breadcrumb?: { title?: string | (() => string)
|
|
154
|
+
function getSourceList(arr: RouteRecordRaw[], basePath?: string, icon?: string, breadcrumb?: { title?: string | (() => string) }[]) {
|
|
159
155
|
arr.forEach((item) => {
|
|
160
156
|
if (item.meta?.sidebar !== false) {
|
|
161
157
|
const breadcrumbTemp = cloneDeep(breadcrumb) || [];
|
|
162
158
|
if (item.children && hasChildren(item)) {
|
|
163
159
|
breadcrumbTemp.push({
|
|
164
160
|
title: item.meta?.title,
|
|
165
|
-
i18n: item.meta?.i18n,
|
|
166
161
|
});
|
|
167
162
|
getSourceList(item.children, resolveRoutePath(basePath, item.path), item.meta?.icon ?? icon, breadcrumbTemp);
|
|
168
163
|
}
|
|
169
164
|
else {
|
|
170
165
|
breadcrumbTemp.push({
|
|
171
166
|
title: item.meta?.title,
|
|
172
|
-
i18n: item.meta?.i18n,
|
|
173
167
|
});
|
|
174
168
|
sourceList.value.push({
|
|
175
169
|
path: resolveRoutePath(basePath, item.path),
|
|
176
170
|
icon: item.meta?.icon ?? icon,
|
|
177
171
|
title: item.meta?.title,
|
|
178
|
-
i18n: item.meta?.i18n,
|
|
179
172
|
link: item.meta?.link,
|
|
180
173
|
breadcrumb: breadcrumbTemp,
|
|
181
174
|
});
|
|
@@ -190,7 +183,6 @@ function getSourceListByTabs(arr: Tabbar.recordRaw[]) {
|
|
|
190
183
|
icon: item.icon,
|
|
191
184
|
title: item.title,
|
|
192
185
|
path: item.fullPath,
|
|
193
|
-
i18n: item.i18n,
|
|
194
186
|
breadcrumb: [],
|
|
195
187
|
});
|
|
196
188
|
});
|
|
@@ -285,8 +277,8 @@ defineExpose({
|
|
|
285
277
|
v-if="settingsStore.settings.tabbar.enable"
|
|
286
278
|
v-model="searchType"
|
|
287
279
|
:options="[
|
|
288
|
-
{ label:
|
|
289
|
-
{ label:
|
|
280
|
+
{ label: '搜索导航菜单', value: 'menu' },
|
|
281
|
+
{ label: '搜索标签页', value: 'tab' },
|
|
290
282
|
]"
|
|
291
283
|
class="mb-4 flex!"
|
|
292
284
|
@click.stop
|
|
@@ -298,7 +290,7 @@ defineExpose({
|
|
|
298
290
|
<input
|
|
299
291
|
ref="searchInputRef"
|
|
300
292
|
v-model="searchInput"
|
|
301
|
-
|
|
293
|
+
placeholder="搜索页面,支持标题、URL模糊查询"
|
|
302
294
|
class="w-full border-0 rounded-md bg-transparent px-3 text-base text-dark dark:text-white focus:outline-none placeholder-stone-4 dark:placeholder-stone-5"
|
|
303
295
|
@keydown.esc="toggle()"
|
|
304
296
|
@keydown.up.prevent="keyUp"
|
|
@@ -332,10 +324,10 @@ defineExpose({
|
|
|
332
324
|
:class="{ 'scale-120 text-ui-primary': index === actived }"
|
|
333
325
|
/>
|
|
334
326
|
<div class="flex flex-1 flex-col gap-1 truncate px-4 py-3" border-l="~ solid stone-2 dark:stone-7">
|
|
335
|
-
<div class="truncate text-base font-bold">{{
|
|
327
|
+
<div class="truncate text-base font-bold">{{ generateTitle(item.title) }}</div>
|
|
336
328
|
<Breadcrumb v-if="item.breadcrumb.length" class="truncate">
|
|
337
329
|
<BreadcrumbItem v-for="(bc, bcIndex) in item.breadcrumb" :key="bcIndex" class="text-xs">
|
|
338
|
-
{{
|
|
330
|
+
{{ generateTitle(bc.title) }}
|
|
339
331
|
</BreadcrumbItem>
|
|
340
332
|
</Breadcrumb>
|
|
341
333
|
</div>
|
|
@@ -357,7 +349,7 @@ defineExpose({
|
|
|
357
349
|
<HKbd>
|
|
358
350
|
<IonMdReturnLeft text="14px" />
|
|
359
351
|
</HKbd>
|
|
360
|
-
<span>{{
|
|
352
|
+
<span>{{ '访问' }}</span>
|
|
361
353
|
</div>
|
|
362
354
|
<div class="inline-flex items-center gap-1 text-xs">
|
|
363
355
|
<HKbd>
|
|
@@ -366,14 +358,14 @@ defineExpose({
|
|
|
366
358
|
<HKbd>
|
|
367
359
|
<AntDesignCaretDownFilled text="14px" />
|
|
368
360
|
</HKbd>
|
|
369
|
-
<span>{{
|
|
361
|
+
<span>{{ '切换' }}</span>
|
|
370
362
|
</div>
|
|
371
363
|
</div>
|
|
372
364
|
<div v-if="settingsStore.settings.navSearch.enableHotkeys" class="inline-flex items-center gap-1 text-xs">
|
|
373
365
|
<HKbd>
|
|
374
366
|
ESC
|
|
375
367
|
</HKbd>
|
|
376
|
-
<span>{{
|
|
368
|
+
<span>{{ '退出' }}</span>
|
|
377
369
|
</div>
|
|
378
370
|
</div>
|
|
379
371
|
</div>
|
|
@@ -1,130 +1,105 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import { useI18n } from 'vue-i18n';
|
|
2
|
+
import type { DropdownMenuRender } from './interface';
|
|
4
3
|
import CarbonUserAvatarFilledAlt from '~icons/carbon/user-avatar-filled-alt';
|
|
5
|
-
import FluentArrowSync16Filled from '~icons/fluent/arrow-sync-16-filled';
|
|
6
|
-
import FluentFullScreenMaximize16Filled from '~icons/fluent/full-screen-maximize-16-filled';
|
|
7
|
-
import FluentFullScreenMinimize16Filled from '~icons/fluent/full-screen-minimize-16-filled';
|
|
8
|
-
import IconamoonSearch from '~icons/iconamoon/search';
|
|
9
4
|
import MaterialSymbolsExpandMoreRounded from '~icons/material-symbols/expand-more-rounded';
|
|
10
|
-
import PhLineVerticalThin from '~icons/ph/line-vertical-thin';
|
|
11
5
|
|
|
6
|
+
import PhLineVerticalThin from '~icons/ph/line-vertical-thin';
|
|
12
7
|
import { useContext } from '../../composables/useContext';
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import useViewTransition from '../../composables/useViewTransition';
|
|
16
|
-
import DayNightSwitch from './DayNightSwitch.vue';
|
|
8
|
+
import DarkModeToggle from './DarkModeToggle.vue';
|
|
9
|
+
import Fullscreen from './Fullscreen.vue';
|
|
17
10
|
import HotkeysIntro from './HotkeysIntro.vue';
|
|
11
|
+
import PageReload from './PageReload.vue';
|
|
18
12
|
import Preferences from './Preferences/index.vue';
|
|
19
|
-
import
|
|
13
|
+
import SearchBar from './SearchBar.vue';
|
|
14
|
+
import SearchPanel from './SearchPanel.vue';
|
|
20
15
|
|
|
21
16
|
defineOptions({
|
|
22
17
|
name: 'Tools',
|
|
23
18
|
});
|
|
24
19
|
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
const props = withDefaults(
|
|
21
|
+
defineProps<{
|
|
22
|
+
// 用户菜单渲染函数
|
|
23
|
+
dropdownMenuRender?: DropdownMenuRender
|
|
24
|
+
}>(),
|
|
25
|
+
{
|
|
26
|
+
dropdownMenuRender: (({ Home, Preferences, Hotkeys, Org, Profile, Password, Logout, Divider }) => {
|
|
27
|
+
return [Home, Preferences, Divider, Hotkeys, Divider, Org, Profile, Password, Logout];
|
|
28
|
+
}) as DropdownMenuRender,
|
|
29
|
+
},
|
|
30
|
+
);
|
|
32
31
|
|
|
33
|
-
const
|
|
32
|
+
const router = useRouter();
|
|
33
|
+
const { settingsStore, userStore, generateTitle } = useContext();
|
|
34
34
|
|
|
35
35
|
const hotkeysIntroRef = ref();
|
|
36
36
|
const preferencesRef = ref();
|
|
37
37
|
|
|
38
|
-
const userMenu = computed(() =>
|
|
39
|
-
|
|
40
|
-
{
|
|
41
|
-
|
|
38
|
+
const userMenu = computed(() => {
|
|
39
|
+
return {
|
|
40
|
+
Home: {
|
|
41
|
+
key: 'home',
|
|
42
|
+
label: generateTitle(settingsStore.settings.home.title),
|
|
42
43
|
icon: 'i-ant-design:home-twotone',
|
|
43
|
-
|
|
44
|
+
onClick: () => router.push({ name: 'Home' }),
|
|
44
45
|
hide: !settingsStore.settings.home.enable,
|
|
45
46
|
},
|
|
46
|
-
{
|
|
47
|
-
|
|
47
|
+
Preferences: {
|
|
48
|
+
key: 'preferences',
|
|
49
|
+
label: '个人偏好设置',
|
|
48
50
|
icon: 'i-iconamoon-star-duotone',
|
|
49
|
-
|
|
51
|
+
onClick: () => preferencesRef.value?.open?.(),
|
|
50
52
|
hide: !settingsStore.settings.app.enableUserPreferences,
|
|
51
53
|
},
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
label: t('app.hotkeys'),
|
|
54
|
+
Hotkeys: {
|
|
55
|
+
key: 'hotkeys',
|
|
56
|
+
label: '快捷键介绍',
|
|
56
57
|
icon: 'i-iconamoon-lightning-2-duotone',
|
|
57
|
-
|
|
58
|
+
onClick: () => hotkeysIntroRef.value?.open?.(),
|
|
58
59
|
hide: settingsStore.mode !== 'pc',
|
|
59
60
|
},
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
label: t('app.changeOrg'),
|
|
61
|
+
Org: {
|
|
62
|
+
key: 'org',
|
|
63
|
+
label: '切换组织',
|
|
64
64
|
icon: 'i-iconamoon-synchronize-duotone',
|
|
65
|
-
|
|
65
|
+
onClick: () => router.push({
|
|
66
66
|
name: 'ChangeOrganization',
|
|
67
67
|
params: { orgId: userStore.user.orgId },
|
|
68
68
|
}),
|
|
69
69
|
hide: userStore.user.orgList.length <= 1,
|
|
70
70
|
},
|
|
71
|
-
{
|
|
72
|
-
|
|
71
|
+
Profile: {
|
|
72
|
+
key: 'profile',
|
|
73
|
+
label: '个人中心',
|
|
73
74
|
icon: 'i-iconamoon-profile-duotone',
|
|
74
|
-
|
|
75
|
+
onClick: () => router.push({ name: 'Profile' }),
|
|
75
76
|
},
|
|
76
|
-
{
|
|
77
|
-
|
|
77
|
+
Password: {
|
|
78
|
+
key: 'password',
|
|
79
|
+
label: '修改密码',
|
|
78
80
|
icon: 'i-iconamoon-lock-duotone',
|
|
79
|
-
|
|
81
|
+
onClick: () => router.push({
|
|
80
82
|
name: 'ChangePassword',
|
|
81
83
|
params: {
|
|
82
84
|
changePassWordToken: userStore.user.token,
|
|
83
85
|
},
|
|
84
86
|
}),
|
|
85
87
|
},
|
|
86
|
-
{
|
|
87
|
-
|
|
88
|
+
Logout: {
|
|
89
|
+
key: 'logout',
|
|
90
|
+
label: '退出登录',
|
|
88
91
|
icon: 'i-iconamoon-arrow-left-3-square-duotone',
|
|
89
|
-
|
|
92
|
+
onClick: () => userStore.logout(),
|
|
90
93
|
},
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const colorScheme = settingsStore.settings.app.colorScheme === 'dark' ? 'light' : 'dark';
|
|
97
|
-
settingsStore.setColorScheme(colorScheme);
|
|
98
|
-
await settingsStore.setPreferencesSetting({
|
|
99
|
-
app: {
|
|
100
|
-
colorScheme,
|
|
101
|
-
},
|
|
102
|
-
});
|
|
103
|
-
});
|
|
94
|
+
Divider: {
|
|
95
|
+
key: 'divider',
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
});
|
|
104
99
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const endRadius = Math.hypot(
|
|
109
|
-
Math.max(x, innerWidth - x),
|
|
110
|
-
Math.max(y, innerHeight - y),
|
|
111
|
-
);
|
|
112
|
-
const clipPath = [
|
|
113
|
-
`circle(0px at ${x}px ${y}px)`,
|
|
114
|
-
`circle(${endRadius}px at ${x}px ${y}px)`,
|
|
115
|
-
];
|
|
116
|
-
document.documentElement.animate(
|
|
117
|
-
{
|
|
118
|
-
clipPath: settingsStore.settings.app.colorScheme !== 'dark' ? clipPath : clipPath.reverse(),
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
duration: 300,
|
|
122
|
-
easing: 'ease-out',
|
|
123
|
-
pseudoElement: settingsStore.settings.app.colorScheme !== 'dark' ? '::view-transition-new(root)' : '::view-transition-old(root)',
|
|
124
|
-
},
|
|
125
|
-
);
|
|
126
|
-
});
|
|
127
|
-
}
|
|
100
|
+
const menus = computed(() => {
|
|
101
|
+
return props.dropdownMenuRender?.(userMenu.value);
|
|
102
|
+
});
|
|
128
103
|
|
|
129
104
|
const avatarError = ref(false);
|
|
130
105
|
|
|
@@ -133,73 +108,33 @@ watch(() => userStore.user.avatar, () => {
|
|
|
133
108
|
avatarError.value = false;
|
|
134
109
|
}
|
|
135
110
|
});
|
|
136
|
-
|
|
137
|
-
const searchComponentsClass = computed(() => {
|
|
138
|
-
const componentsClass = {
|
|
139
|
-
'side': 'ring-1 ',
|
|
140
|
-
'head': 'bg-[var(--g-header-menu-active-bg)]',
|
|
141
|
-
'single': ' ring-1',
|
|
142
|
-
'only-side': 'ring-1',
|
|
143
|
-
'only-head': ' bg-[var(--g-header-menu-active-bg)]',
|
|
144
|
-
};
|
|
145
|
-
const menuMode = settingsStore.settings.menu.menuMode;
|
|
146
|
-
return componentsClass[menuMode];
|
|
147
|
-
});
|
|
148
111
|
</script>
|
|
149
112
|
|
|
150
113
|
<template>
|
|
151
114
|
<div class="tools flex items-center gap-4 whitespace-nowrap px-4">
|
|
152
|
-
<
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
<HKbd
|
|
161
|
-
v-if="settingsStore.settings.navSearch.enableHotkeys"
|
|
162
|
-
class="ml-2"
|
|
163
|
-
>{{ settingsStore.os === 'mac' ? '⌥' : 'Alt' }} S</HKbd>
|
|
164
|
-
</span>
|
|
165
|
-
<div class="flex items-center empty:hidden">
|
|
166
|
-
<span
|
|
167
|
-
v-if="settingsStore.settings.navSearch.enable && settingsStore.mode === 'mobile'"
|
|
168
|
-
class="item"
|
|
169
|
-
@click="toggleSearch('menu')"
|
|
170
|
-
>
|
|
171
|
-
<IconamoonSearch text="14px" />
|
|
172
|
-
</span>
|
|
173
|
-
<span
|
|
174
|
-
v-if="settingsStore.mode === 'pc' && settingsStore.settings.toolbar.enableFullscreen"
|
|
175
|
-
class="item"
|
|
176
|
-
@click="toggle"
|
|
177
|
-
>
|
|
178
|
-
<FluentFullScreenMinimize16Filled v-if="isFullscreen" text="16px" />
|
|
179
|
-
<FluentFullScreenMaximize16Filled v-else text="16px" />
|
|
180
|
-
</span>
|
|
181
|
-
<span
|
|
182
|
-
v-if="settingsStore.settings.toolbar.enablePageReload"
|
|
183
|
-
class="item"
|
|
184
|
-
@click="mainPage.reload()"
|
|
185
|
-
>
|
|
186
|
-
<FluentArrowSync16Filled text="15px" />
|
|
187
|
-
</span>
|
|
188
|
-
<DayNightSwitch @click="toggleColorScheme" />
|
|
115
|
+
<SearchBar />
|
|
116
|
+
|
|
117
|
+
<div class="flex items-center empty:hidden gap-3">
|
|
118
|
+
<slot name="default">
|
|
119
|
+
<Fullscreen />
|
|
120
|
+
<PageReload />
|
|
121
|
+
<DarkModeToggle />
|
|
122
|
+
</slot>
|
|
189
123
|
</div>
|
|
124
|
+
|
|
190
125
|
<div flex-center cursor-pointer gap-1>
|
|
191
126
|
<img
|
|
192
127
|
v-if="userStore.user.avatar && !avatarError"
|
|
193
128
|
:src="userStore.user.avatar"
|
|
194
129
|
:onerror="() => (avatarError = true)"
|
|
195
|
-
class="
|
|
130
|
+
class="size-[24px] rounded-full"
|
|
196
131
|
>
|
|
197
132
|
<CarbonUserAvatarFilledAlt v-else text="20px" mr-2px />
|
|
198
133
|
<div class="flex-center cursor-pointer">
|
|
199
134
|
{{ userStore.userOrgName }}
|
|
200
135
|
</div>
|
|
201
|
-
<PhLineVerticalThin />
|
|
202
|
-
<HDropdownMenu :items="
|
|
136
|
+
<PhLineVerticalThin v-if="userStore?.userOrgName" />
|
|
137
|
+
<HDropdownMenu :items="menus">
|
|
203
138
|
<div flex-center cursor-pointer gap-1>
|
|
204
139
|
{{ userStore.user.account }}
|
|
205
140
|
<MaterialSymbolsExpandMoreRounded ml="5px" mr="10px" />
|
|
@@ -208,13 +143,7 @@ const searchComponentsClass = computed(() => {
|
|
|
208
143
|
</div>
|
|
209
144
|
|
|
210
145
|
<HotkeysIntro ref="hotkeysIntroRef" />
|
|
211
|
-
<
|
|
146
|
+
<SearchPanel />
|
|
212
147
|
<Preferences v-if="settingsStore.settings.app.enableUserPreferences" ref="preferencesRef" />
|
|
213
148
|
</div>
|
|
214
149
|
</template>
|
|
215
|
-
|
|
216
|
-
<style scoped>
|
|
217
|
-
.item {
|
|
218
|
-
--at-apply: flex px-2 py-1 cursor-pointer;
|
|
219
|
-
}
|
|
220
|
-
</style>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface DropdownMenu {
|
|
2
|
+
key?: string | 'divider'
|
|
3
|
+
icon?: string
|
|
4
|
+
label?: string
|
|
5
|
+
disabled?: boolean
|
|
6
|
+
hide?: boolean
|
|
7
|
+
onClick?: () => void
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type DropdownMenuRender = (items: {
|
|
11
|
+
/** 主页 */
|
|
12
|
+
Home: DropdownMenu
|
|
13
|
+
/** 个人偏好设置 */
|
|
14
|
+
Preferences: DropdownMenu
|
|
15
|
+
/** 快捷键介绍 */
|
|
16
|
+
Hotkeys: DropdownMenu
|
|
17
|
+
/** 切换组织 */
|
|
18
|
+
Org: DropdownMenu
|
|
19
|
+
/** 个人中心 */
|
|
20
|
+
Profile: DropdownMenu
|
|
21
|
+
/** 修改密码 */
|
|
22
|
+
Password: DropdownMenu
|
|
23
|
+
/** 登出 */
|
|
24
|
+
Logout: DropdownMenu
|
|
25
|
+
/** 分割线 */
|
|
26
|
+
Divider: DropdownMenu
|
|
27
|
+
}) => DropdownMenu[];
|