This commit is contained in:
dap 2024-10-07 10:31:01 +08:00
commit 5720279063
28 changed files with 151 additions and 134 deletions

View File

@ -1,9 +1,10 @@
<script lang="ts" setup>
import { computed, onMounted } from 'vue';
import { computed, onMounted, watch } from 'vue';
import { useRouter } from 'vue-router';
import { AuthenticationLoginExpiredModal } from '@vben/common-ui';
import { VBEN_DOC_URL, VBEN_GITHUB_URL } from '@vben/constants';
import { useWatermark } from '@vben/hooks';
import { BookOpenText, CircleHelp, MdiGithub, ProfileIcon } from '@vben/icons';
import {
BasicLayout,
@ -28,6 +29,7 @@ const userStore = useUserStore();
const authStore = useAuthStore();
const accessStore = useAccessStore();
const router = useRouter();
const { destroyWatermark, updateWatermark } = useWatermark();
const tenantStore = useTenantStore();
const menus = computed(() => {
@ -91,6 +93,21 @@ onMounted(() => notifyStore.startListeningMessage());
function handleViewAll() {
message.warning('暂未开放');
}
watch(
() => preferences.app.watermark,
async (enable) => {
if (enable) {
await updateWatermark({
content: `${userStore.userInfo?.username}`,
});
} else {
destroyWatermark();
}
},
{
immediate: true,
},
);
</script>
<template>

View File

@ -34,9 +34,7 @@ function setupCommonGuard(router: Router) {
router.afterEach((to) => {
// 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行
if (preferences.tabbar.enable) {
loadedPaths.add(to.path);
}
loadedPaths.add(to.path);
// 关闭页面加载进度条
if (preferences.transition.progress) {

View File

@ -1,10 +1,11 @@
<script lang="ts" setup>
import type { NotificationItem } from '@vben/layouts';
import { computed, ref } from 'vue';
import { computed, ref, watch } from 'vue';
import { AuthenticationLoginExpiredModal } from '@vben/common-ui';
import { VBEN_DOC_URL, VBEN_GITHUB_URL } from '@vben/constants';
import { useWatermark } from '@vben/hooks';
import { BookOpenText, CircleHelp, MdiGithub } from '@vben/icons';
import {
BasicLayout,
@ -54,6 +55,7 @@ const notifications = ref<NotificationItem[]>([
const userStore = useUserStore();
const authStore = useAuthStore();
const accessStore = useAccessStore();
const { destroyWatermark, updateWatermark } = useWatermark();
const showDot = computed(() =>
notifications.value.some((item) => !item.isRead),
);
@ -103,6 +105,21 @@ function handleNoticeClear() {
function handleMakeAll() {
notifications.value.forEach((item) => (item.isRead = true));
}
watch(
() => preferences.app.watermark,
async (enable) => {
if (enable) {
await updateWatermark({
content: `${userStore.userInfo?.username}`,
});
} else {
destroyWatermark();
}
},
{
immediate: true,
},
);
</script>
<template>

View File

@ -34,9 +34,7 @@ function setupCommonGuard(router: Router) {
router.afterEach((to) => {
// 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行
if (preferences.tabbar.enable) {
loadedPaths.add(to.path);
}
loadedPaths.add(to.path);
// 关闭页面加载进度条
if (preferences.transition.progress) {

View File

@ -1,10 +1,11 @@
<script lang="ts" setup>
import type { NotificationItem } from '@vben/layouts';
import { computed, ref } from 'vue';
import { computed, ref, watch } from 'vue';
import { AuthenticationLoginExpiredModal } from '@vben/common-ui';
import { VBEN_DOC_URL, VBEN_GITHUB_URL } from '@vben/constants';
import { useWatermark } from '@vben/hooks';
import { BookOpenText, CircleHelp, MdiGithub } from '@vben/icons';
import {
BasicLayout,
@ -54,6 +55,7 @@ const notifications = ref<NotificationItem[]>([
const userStore = useUserStore();
const authStore = useAuthStore();
const accessStore = useAccessStore();
const { destroyWatermark, updateWatermark } = useWatermark();
const showDot = computed(() =>
notifications.value.some((item) => !item.isRead),
);
@ -103,6 +105,22 @@ function handleNoticeClear() {
function handleMakeAll() {
notifications.value.forEach((item) => (item.isRead = true));
}
watch(
() => preferences.app.watermark,
async (enable) => {
if (enable) {
await updateWatermark({
content: `${userStore.userInfo?.username}`,
});
} else {
destroyWatermark();
}
},
{
immediate: true,
},
);
</script>
<template>

View File

@ -34,9 +34,7 @@ function setupCommonGuard(router: Router) {
router.afterEach((to) => {
// 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行
if (preferences.tabbar.enable) {
loadedPaths.add(to.path);
}
loadedPaths.add(to.path);
// 关闭页面加载进度条
if (preferences.transition.progress) {

View File

@ -234,7 +234,6 @@ const defaultPreferences: Preferences = {
showIcon: true,
showMaximize: true,
showMore: true,
showRefresh: true,
styleType: 'chrome',
},
theme: {
@ -262,6 +261,7 @@ const defaultPreferences: Preferences = {
notification: true,
sidebarToggle: true,
themeToggle: true,
refresh: true,
},
};
```
@ -421,8 +421,6 @@ interface TabbarPreferences {
showMaximize: boolean;
/** Whether to show the more button */
showMore: boolean;
/** Whether to show the refresh button */
showRefresh: boolean;
/** Tab style */
styleType: TabsStyleType;
}
@ -469,6 +467,8 @@ interface WidgetPreferences {
lockScreen: boolean;
/** Whether notification widget is displayed */
notification: boolean;
/** Whether to show the refresh button */
refresh: boolean;
/** Whether sidebar show/hide widget is displayed */
sidebarToggle: boolean;
/** Whether theme switch widget is displayed */

View File

@ -256,7 +256,6 @@ const defaultPreferences: Preferences = {
showIcon: true,
showMaximize: true,
showMore: true,
showRefresh: true,
styleType: 'chrome',
},
theme: {
@ -282,6 +281,7 @@ const defaultPreferences: Preferences = {
languageToggle: true,
lockScreen: true,
notification: true,
refresh: true,
sidebarToggle: true,
themeToggle: true,
},
@ -445,8 +445,6 @@ interface TabbarPreferences {
showMaximize: boolean;
/** 显示更多按钮 */
showMore: boolean;
/** 显示刷新按钮 */
showRefresh: boolean;
/** 标签页风格 */
styleType: TabsStyleType;
}
@ -494,6 +492,8 @@ interface WidgetPreferences {
lockScreen: boolean;
/** 是否显示通知部件 */
notification: boolean;
/** 显示刷新按钮 */
refresh: boolean;
/** 是否显示侧边栏显示/隐藏部件 */
sidebarToggle: boolean;
/** 是否显示主题切换部件 */

View File

@ -81,7 +81,6 @@ exports[`defaultPreferences immutability test > should not modify the config obj
"showIcon": true,
"showMaximize": true,
"showMore": true,
"showRefresh": true,
"styleType": "chrome",
},
"theme": {
@ -107,6 +106,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
"languageToggle": true,
"lockScreen": true,
"notification": true,
"refresh": true,
"sidebarToggle": true,
"themeToggle": true,
},

View File

@ -81,7 +81,7 @@ const defaultPreferences: Preferences = {
showIcon: true,
showMaximize: true,
showMore: true,
showRefresh: true,
styleType: 'chrome',
},
theme: {
@ -107,6 +107,7 @@ const defaultPreferences: Preferences = {
languageToggle: true,
lockScreen: true,
notification: true,
refresh: true,
sidebarToggle: true,
themeToggle: true,
},

View File

@ -169,8 +169,6 @@ interface TabbarPreferences {
showMaximize: boolean;
/** 显示更多按钮 */
showMore: boolean;
/** 显示刷新按钮 */
showRefresh: boolean;
/** 标签页风格 */
styleType: TabsStyleType;
}
@ -218,6 +216,8 @@ interface WidgetPreferences {
lockScreen: boolean;
/** 是否显示通知部件 */
notification: boolean;
/** 显示刷新按钮 */
refresh: boolean;
/** 是否显示侧边栏显示/隐藏部件 */
sidebarToggle: boolean;
/** 是否显示主题切换部件 */

View File

@ -1,3 +1,2 @@
export { default as TabsToolMore } from './tool-more.vue';
export { default as TabsToolRefresh } from './tool-refresh.vue';
export { default as TabsToolScreen } from './tool-screen.vue';

View File

@ -1,31 +0,0 @@
<script lang="ts" setup>
import { ref } from 'vue';
import { RotateCw } from '@vben-core/icons';
const emit = defineEmits<{ refresh: [] }>();
const loading = ref(false);
function handleClick() {
loading.value = true;
setTimeout(() => {
loading.value = false;
}, 1000);
emit('refresh');
}
</script>
<template>
<div
class="flex-center hover:bg-muted hover:text-foreground text-muted-foreground border-border h-full cursor-pointer border-l px-[9px] text-lg font-semibold"
@click="handleClick"
>
<RotateCw
:class="{
'animate-spin duration-1000': loading,
}"
class="size-4"
/>
</div>
</template>

View File

@ -1,8 +1,6 @@
import type { Watermark, WatermarkOptions } from 'watermark-js-plus';
import { nextTick, onUnmounted, ref, watch } from 'vue';
import { preferences } from '@vben/preferences';
import { nextTick, onUnmounted, ref } from 'vue';
const watermark = ref<Watermark>();
const cachedOptions = ref<Partial<WatermarkOptions>>({
@ -67,15 +65,6 @@ export function useWatermark() {
watermark.value?.destroy();
}
watch(
() => preferences.app.watermark,
(enable) => {
if (!enable) {
destroyWatermark();
}
},
);
onUnmounted(() => {
destroyWatermark();
});

View File

@ -3,5 +3,5 @@
### header
- 支持N个自定义插槽命名方式header-right-nheader-left-n
- header-left-n ,排序方式:1-4 ,breadcrumb6-x
- header-right-n ,排序方式:1-4global-search6-9theme-toggle11-14language-toggle16-19fullscreen21-24notification26-29user-dropdown30-x
- header-left-n ,排序方式:0-19 ,breadcrumb 21-x
- header-right-n ,排序方式:0-49global-search51-59theme-toggle61-69language-toggle71-79fullscreen81-89notification91-149user-dropdown151-x

View File

@ -1,9 +1,11 @@
<script lang="ts" setup>
import { computed, useSlots } from 'vue';
import { useRefresh } from '@vben/hooks';
import { RotateCw } from '@vben/icons';
import { preferences, usePreferences } from '@vben/preferences';
import { useAccessStore } from '@vben/stores';
import { VbenFullScreen } from '@vben-core/shadcn-ui';
import { VbenFullScreen, VbenIconButton } from '@vben-core/shadcn-ui';
import {
GlobalSearch,
@ -29,45 +31,49 @@ withDefaults(defineProps<Props>(), {
const emit = defineEmits<{ clearPreferencesAndLogout: [] }>();
const REFERENCE_VALUE = 50;
const accessStore = useAccessStore();
const { globalSearchShortcutKey, preferencesButtonPosition } = usePreferences();
const slots = useSlots();
const { refresh } = useRefresh();
const rightSlots = computed(() => {
const list = [{ index: 100, name: 'user-dropdown' }];
const list = [{ index: REFERENCE_VALUE + 100, name: 'user-dropdown' }];
if (preferences.widget.globalSearch) {
list.push({
index: 5,
index: REFERENCE_VALUE,
name: 'global-search',
});
}
if (preferencesButtonPosition.value.header) {
list.push({
index: 10,
index: REFERENCE_VALUE + 10,
name: 'preferences',
});
}
if (preferences.widget.themeToggle) {
list.push({
index: 15,
index: REFERENCE_VALUE + 20,
name: 'theme-toggle',
});
}
if (preferences.widget.languageToggle) {
list.push({
index: 20,
index: REFERENCE_VALUE + 30,
name: 'language-toggle',
});
}
if (preferences.widget.fullscreen) {
list.push({
index: 25,
index: REFERENCE_VALUE + 40,
name: 'fullscreen',
});
}
if (preferences.widget.notification) {
list.push({
index: 30,
index: REFERENCE_VALUE + 50,
name: 'notification',
});
}
@ -82,7 +88,14 @@ const rightSlots = computed(() => {
});
const leftSlots = computed(() => {
const list: any[] = [];
const list: Array<{ index: number; name: string }> = [];
if (preferences.widget.refresh) {
list.push({
index: 0,
name: 'refresh',
});
}
Object.keys(slots).forEach((key) => {
const name = key.split('-');
@ -100,16 +113,22 @@ function clearPreferencesAndLogout() {
<template>
<template
v-for="slot in leftSlots.filter((item) => item.index < 5)"
v-for="slot in leftSlots.filter((item) => item.index < REFERENCE_VALUE)"
:key="slot.name"
>
<slot :name="slot.name"></slot>
<slot :name="slot.name">
<template v-if="slot.name === 'refresh'">
<VbenIconButton class="my-0 rounded-md" @click="refresh">
<RotateCw class="size-4" />
</VbenIconButton>
</template>
</slot>
</template>
<div class="flex-center hidden lg:block">
<slot name="breadcrumb"></slot>
</div>
<template
v-for="slot in leftSlots.filter((item) => item.index > 5)"
v-for="slot in leftSlots.filter((item) => item.index > REFERENCE_VALUE)"
:key="slot.name"
>
<slot :name="slot.name"></slot>

View File

@ -3,14 +3,14 @@ import type { MenuRecordRaw } from '@vben/types';
import { computed, useSlots, watch } from 'vue';
import { useWatermark } from '@vben/hooks';
import { useRefresh } from '@vben/hooks';
import { $t } from '@vben/locales';
import {
preferences,
updatePreferences,
usePreferences,
} from '@vben/preferences';
import { useLockStore, useUserStore } from '@vben/stores';
import { useLockStore } from '@vben/stores';
import { deepToRaw, mapTree } from '@vben/utils';
import { VbenAdminLayout } from '@vben-core/layout-ui';
import { Toaster, VbenBackTop, VbenLogo } from '@vben-core/shadcn-ui';
@ -44,9 +44,8 @@ const {
sidebarCollapsed,
theme,
} = usePreferences();
const userStore = useUserStore();
const { updateWatermark } = useWatermark();
const lockStore = useLockStore();
const { refresh } = useRefresh();
const sidebarTheme = computed(() => {
const dark = isDark.value || preferences.theme.semiDarkSidebar;
@ -129,20 +128,6 @@ function clearPreferencesAndLogout() {
emit('clearPreferencesAndLogout');
}
watch(
() => preferences.app.watermark,
async (val) => {
if (val) {
await updateWatermark({
content: `${userStore.userInfo?.username}`,
});
}
},
{
immediate: true,
},
);
watch(
() => preferences.app.layout,
async (val) => {
@ -156,6 +141,9 @@ watch(
},
);
//
watch(() => preferences.app.locale, refresh);
const slots = useSlots();
const headerSlots = computed(() => {
return Object.keys(slots).filter((key) => key.startsWith('header-'));
@ -267,7 +255,6 @@ const headerSlots = computed(() => {
/>
</template>
<template #mixed-menu>
<!-- :collapse="!preferences.sidebar.collapsedShowTitle" -->
<LayoutMixedMenu
:active-path="extraActiveMenu"
:menus="wrapperMenus(headerMenus)"
@ -308,6 +295,7 @@ const headerSlots = computed(() => {
<template #content>
<LayoutContent />
</template>
<template v-if="preferences.transition.loading" #content-overlay>
<LayoutContentSpinner />
</template>

View File

@ -5,12 +5,7 @@ import { useRoute } from 'vue-router';
import { useContentMaximize, useTabs } from '@vben/hooks';
import { preferences } from '@vben/preferences';
import { useTabbarStore } from '@vben/stores';
import {
TabsToolMore,
TabsToolRefresh,
TabsToolScreen,
TabsView,
} from '@vben-core/tabs-ui';
import { TabsToolMore, TabsToolScreen, TabsView } from '@vben-core/tabs-ui';
import { useTabbar } from './use-tabbar';
@ -23,7 +18,7 @@ defineProps<{ showIcon?: boolean; theme?: string }>();
const route = useRoute();
const tabbarStore = useTabbarStore();
const { contentIsMaximize, toggleMaximize } = useContentMaximize();
const { refreshTab, unpinTab } = useTabs();
const { unpinTab } = useTabs();
const {
createContextMenus,
@ -66,10 +61,6 @@ if (!preferences.tabbar.persist) {
@update:active="handleClick"
/>
<div class="flex-center h-full">
<TabsToolRefresh
v-if="preferences.tabbar.showRefresh"
@refresh="refreshTab"
/>
<TabsToolMore v-if="preferences.tabbar.showMore" :menus="menus" />
<TabsToolScreen
v-if="preferences.tabbar.showMaximize"

View File

@ -20,7 +20,6 @@ const tabbarPersist = defineModel<boolean>('tabbarPersist');
const tabbarDragable = defineModel<boolean>('tabbarDragable');
const tabbarStyleType = defineModel<string>('tabbarStyleType');
const tabbarShowMore = defineModel<boolean>('tabbarShowMore');
const tabbarShowRefresh = defineModel<boolean>('tabbarShowRefresh');
const tabbarShowMaximize = defineModel<boolean>('tabbarShowMaximize');
const styleItems = computed((): SelectOption[] => [
@ -60,9 +59,6 @@ const styleItems = computed((): SelectOption[] => [
<SwitchItem v-model="tabbarShowMore" :disabled="!tabbarEnable">
{{ $t('preferences.tabbar.showMore') }}
</SwitchItem>
<SwitchItem v-model="tabbarShowRefresh" :disabled="!tabbarEnable">
{{ $t('preferences.tabbar.showRefresh') }}
</SwitchItem>
<SwitchItem v-model="tabbarShowMaximize" :disabled="!tabbarEnable">
{{ $t('preferences.tabbar.showMaximize') }}
</SwitchItem>

View File

@ -22,6 +22,7 @@ const widgetLockScreen = defineModel<boolean>('widgetLockScreen');
const appPreferencesButtonPosition = defineModel<string>(
'appPreferencesButtonPosition',
);
const widgetRefresh = defineModel<boolean>('widgetRefresh');
const positionItems = computed((): SelectOption[] => [
{
@ -61,6 +62,9 @@ const positionItems = computed((): SelectOption[] => [
<SwitchItem v-model="widgetSidebarToggle">
{{ $t('preferences.widget.sidebarToggle') }}
</SwitchItem>
<SwitchItem v-model="widgetRefresh">
{{ $t('preferences.widget.refresh') }}
</SwitchItem>
<SelectItem v-model="appPreferencesButtonPosition" :items="positionItems">
{{ $t('preferences.position.title') }}
</SelectItem>

View File

@ -100,7 +100,6 @@ const breadcrumbHideOnlyOne = defineModel<boolean>('breadcrumbHideOnlyOne');
const tabbarEnable = defineModel<boolean>('tabbarEnable');
const tabbarShowIcon = defineModel<boolean>('tabbarShowIcon');
const tabbarShowMore = defineModel<boolean>('tabbarShowMore');
const tabbarShowRefresh = defineModel<boolean>('tabbarShowRefresh');
const tabbarShowMaximize = defineModel<boolean>('tabbarShowMaximize');
const tabbarPersist = defineModel<boolean>('tabbarPersist');
const tabbarDragable = defineModel<boolean>('tabbarDragable');
@ -145,6 +144,7 @@ const widgetNotification = defineModel<boolean>('widgetNotification');
const widgetThemeToggle = defineModel<boolean>('widgetThemeToggle');
const widgetSidebarToggle = defineModel<boolean>('widgetSidebarToggle');
const widgetLockScreen = defineModel<boolean>('widgetLockScreen');
const widgetRefresh = defineModel<boolean>('widgetRefresh');
const {
diffPreference,
@ -345,7 +345,6 @@ async function handleReset() {
v-model:tabbar-show-icon="tabbarShowIcon"
v-model:tabbar-show-maximize="tabbarShowMaximize"
v-model:tabbar-show-more="tabbarShowMore"
v-model:tabbar-show-refresh="tabbarShowRefresh"
v-model:tabbar-style-type="tabbarStyleType"
/>
</Block>
@ -359,6 +358,7 @@ async function handleReset() {
v-model:widget-language-toggle="widgetLanguageToggle"
v-model:widget-lock-screen="widgetLockScreen"
v-model:widget-notification="widgetNotification"
v-model:widget-refresh="widgetRefresh"
v-model:widget-sidebar-toggle="widgetSidebarToggle"
v-model:widget-theme-toggle="widgetThemeToggle"
/>

View File

@ -143,7 +143,7 @@ const vbenFormOptions = computed(() => {
props.api.reload(formValues);
},
handleReset: async () => {
formApi.resetForm();
await formApi.resetForm();
const formValues = formApi.form.values;
props.api.reload(formValues);
},

View File

@ -213,7 +213,6 @@
"enable": "Enable Tab Bar",
"icon": "Show Tabbar Icon",
"showMore": "Show More Button",
"showRefresh": "Show Refresh Button",
"showMaximize": "Show Maximize Button",
"persist": "Persist Tabs",
"dragable": "Enable Dragable Sort",
@ -325,7 +324,8 @@
"languageToggle": "Enable Language Toggle",
"notification": "Enable Notification",
"sidebarToggle": "Enable Sidebar Toggle",
"lockScreen": "Enable Lock Screen"
"lockScreen": "Enable Lock Screen",
"refresh": "Enable Refresh"
}
},
"ui": {

View File

@ -213,7 +213,6 @@
"enable": "启用标签栏",
"icon": "显示标签栏图标",
"showMore": "显示更多按钮",
"showRefresh": "显示刷新按钮",
"showMaximize": "显示最大化按钮",
"persist": "持久化标签页",
"dragable": "启动拖拽排序",
@ -325,7 +324,8 @@
"languageToggle": "启用语言切换",
"notification": "启用通知",
"sidebarToggle": "启用侧边栏切换",
"lockScreen": "启用锁屏"
"lockScreen": "启用锁屏",
"refresh": "启用刷新"
}
},
"ui": {

View File

@ -1,10 +1,11 @@
<script lang="ts" setup>
import type { NotificationItem } from '@vben/layouts';
import { computed, ref } from 'vue';
import { computed, ref, watch } from 'vue';
import { AuthenticationLoginExpiredModal } from '@vben/common-ui';
import { VBEN_DOC_URL, VBEN_GITHUB_URL } from '@vben/constants';
import { useWatermark } from '@vben/hooks';
import { BookOpenText, CircleHelp, MdiGithub } from '@vben/icons';
import {
BasicLayout,
@ -54,6 +55,7 @@ const notifications = ref<NotificationItem[]>([
const userStore = useUserStore();
const authStore = useAuthStore();
const accessStore = useAccessStore();
const { destroyWatermark, updateWatermark } = useWatermark();
const showDot = computed(() =>
notifications.value.some((item) => !item.isRead),
);
@ -103,6 +105,22 @@ function handleNoticeClear() {
function handleMakeAll() {
notifications.value.forEach((item) => (item.isRead = true));
}
watch(
() => preferences.app.watermark,
async (enable) => {
if (enable) {
await updateWatermark({
content: `${userStore.userInfo?.username}`,
});
} else {
destroyWatermark();
}
},
{
immediate: true,
},
);
</script>
<template>

View File

@ -33,10 +33,7 @@ function setupCommonGuard(router: Router) {
router.afterEach((to) => {
// 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行
if (preferences.tabbar.enable) {
loadedPaths.add(to.path);
}
loadedPaths.add(to.path);
// 关闭页面加载进度条
if (preferences.transition.progress) {

View File

@ -475,8 +475,8 @@ catalogs:
specifier: ^2.1.6
version: 2.1.6
vxe-pc-ui:
specifier: ^4.2.13
version: 4.2.13
specifier: ^4.2.14
version: 4.2.14
vxe-table:
specifier: ^4.7.84
version: 4.7.85
@ -1698,7 +1698,7 @@ importers:
version: 3.5.11(typescript@5.6.2)
vxe-pc-ui:
specifier: 'catalog:'
version: 4.2.13
version: 4.2.14
vxe-table:
specifier: 'catalog:'
version: 4.7.85
@ -10766,8 +10766,8 @@ packages:
peerDependencies:
vue: ^3.5.11
vxe-pc-ui@4.2.13:
resolution: {integrity: sha512-zTI0pDAO0sJ5Snvv8zDnvxMcZt2dKg5RPrtOXsHpSuAW+B2dS/grdn7bvj7RVpgb/cSx4fdNoVmmU5U6HLufAA==}
vxe-pc-ui@4.2.14:
resolution: {integrity: sha512-yXZo7axUmn62bksPKFwOHafGJTDH7QXsvhWVwr/xb+vM4wLA14WUijyEnAJJvY78lM5FB8cIFZqwahOhj1Pu8w==}
vxe-table@4.7.85:
resolution: {integrity: sha512-sNQ4jKnU6vZkStTK2JDDKgIz5kKCCWtTtOVl7dpNsLJ16NYWMCDlNby5m/DJC+xa0dPvSdr7+AH4TXfD1vpRFg==}
@ -21256,13 +21256,13 @@ snapshots:
vooks: 0.2.12(vue@3.5.11(typescript@5.6.2))
vue: 3.5.11(typescript@5.6.2)
vxe-pc-ui@4.2.13:
vxe-pc-ui@4.2.14:
dependencies:
'@vxe-ui/core': 4.0.12
vxe-table@4.7.85:
dependencies:
vxe-pc-ui: 4.2.13
vxe-pc-ui: 4.2.14
w3c-keyname@2.2.8: {}

View File

@ -173,7 +173,7 @@ catalog:
vue-i18n: ^10.0.3
vue-router: ^4.4.5
vue-tsc: ^2.1.6
vxe-pc-ui: ^4.2.13
vxe-pc-ui: ^4.2.14
vxe-table: ^4.7.84
watermark-js-plus: ^1.5.7
zod: ^3.23.8