Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/design",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/icons",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/shared",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// eslint-disable-next-line vue/prefer-import-from-vue
|
||||
import { isFunction, isObject, isString } from '@vue/shared';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/typings",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/composables",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/preferences",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/form-ui",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/layout-ui",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/menu-ui",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -374,10 +374,10 @@ $namespace: vben;
|
||||
var(--menu-item-margin-x);
|
||||
font-size: var(--menu-font-size);
|
||||
color: var(--menu-item-color);
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
list-style: none;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
background: var(--menu-item-background-color);
|
||||
border: none;
|
||||
border-radius: var(--menu-item-radius);
|
||||
@@ -701,8 +701,8 @@ $namespace: vben;
|
||||
width: var(--menu-item-icon-size);
|
||||
height: var(--menu-item-icon-size);
|
||||
margin-right: 8px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { VbenIcon } from '@vben-core/shadcn-ui';
|
||||
import { useMenuContext } from '../hooks';
|
||||
|
||||
interface Props extends MenuItemProps {
|
||||
isMenuMore: boolean;
|
||||
isMenuMore?: boolean;
|
||||
isTopLevelMenuSubmenu: boolean;
|
||||
level?: number;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,10 @@ export interface DrawerProps {
|
||||
* 弹窗描述
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* 在关闭时销毁抽屉
|
||||
*/
|
||||
destroyOnClose?: boolean;
|
||||
/**
|
||||
* 是否显示底部
|
||||
* @default true
|
||||
@@ -143,10 +147,6 @@ export interface DrawerApiOptions extends DrawerState {
|
||||
* 独立的抽屉组件
|
||||
*/
|
||||
connectedComponent?: Component;
|
||||
/**
|
||||
* 在关闭时销毁抽屉。仅在使用 connectedComponent 时有效
|
||||
*/
|
||||
destroyOnClose?: boolean;
|
||||
/**
|
||||
* 关闭前的回调,返回 false 可以阻止关闭
|
||||
* @returns
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import type { DrawerProps, ExtendedDrawerApi } from './drawer';
|
||||
|
||||
import { computed, provide, ref, useId, watch } from 'vue';
|
||||
import { computed, provide, ref, unref, useId, watch } from 'vue';
|
||||
|
||||
import {
|
||||
useIsMobile,
|
||||
@@ -35,6 +35,7 @@ interface Props extends DrawerProps {
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
appendToMain: false,
|
||||
closeIconPlacement: 'right',
|
||||
destroyOnClose: true,
|
||||
drawerApi: undefined,
|
||||
submitting: false,
|
||||
zIndex: 1000,
|
||||
@@ -63,6 +64,7 @@ const {
|
||||
confirmText,
|
||||
contentClass,
|
||||
description,
|
||||
destroyOnClose,
|
||||
footer: showFooter,
|
||||
footerClass,
|
||||
header: showHeader,
|
||||
@@ -131,6 +133,29 @@ const getAppendTo = computed(() => {
|
||||
? `#${ELEMENT_ID_MAIN_CONTENT}>div:not(.absolute)>div`
|
||||
: undefined;
|
||||
});
|
||||
|
||||
/**
|
||||
* destroyOnClose功能完善
|
||||
*/
|
||||
// 是否打开过
|
||||
const hasOpened = ref(false);
|
||||
const isClosed = ref(true);
|
||||
watch(
|
||||
() => state?.value?.isOpen,
|
||||
(value) => {
|
||||
isClosed.value = false;
|
||||
if (value && !unref(hasOpened)) {
|
||||
hasOpened.value = true;
|
||||
}
|
||||
},
|
||||
);
|
||||
function handleClosed() {
|
||||
isClosed.value = true;
|
||||
props.drawerApi?.onClosed();
|
||||
}
|
||||
const getForceMount = computed(() => {
|
||||
return !unref(destroyOnClose) && unref(hasOpened);
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Sheet
|
||||
@@ -144,15 +169,17 @@ const getAppendTo = computed(() => {
|
||||
cn('flex w-[520px] flex-col', drawerClass, {
|
||||
'!w-full': isMobile || placement === 'bottom' || placement === 'top',
|
||||
'max-h-[100vh]': placement === 'bottom' || placement === 'top',
|
||||
hidden: isClosed,
|
||||
})
|
||||
"
|
||||
:modal="modal"
|
||||
:open="state?.isOpen"
|
||||
:side="placement"
|
||||
:z-index="zIndex"
|
||||
:force-mount="getForceMount"
|
||||
:overlay-blur="overlayBlur"
|
||||
@close-auto-focus="handleFocusOutside"
|
||||
@closed="() => drawerApi?.onClosed()"
|
||||
@closed="handleClosed"
|
||||
@escape-key-down="escapeKeyDown"
|
||||
@focus-outside="handleFocusOutside"
|
||||
@interact-outside="interactOutside"
|
||||
|
||||
@@ -21,7 +21,9 @@ import VbenDrawer from './drawer.vue';
|
||||
|
||||
const USER_DRAWER_INJECT_KEY = Symbol('VBEN_DRAWER_INJECT');
|
||||
|
||||
const DEFAULT_DRAWER_PROPS: Partial<DrawerProps> = {};
|
||||
const DEFAULT_DRAWER_PROPS: Partial<DrawerProps> = {
|
||||
destroyOnClose: true,
|
||||
};
|
||||
|
||||
export function setDefaultDrawerProps(props: Partial<DrawerProps>) {
|
||||
Object.assign(DEFAULT_DRAWER_PROPS, props);
|
||||
|
||||
@@ -9,7 +9,9 @@ import VbenModal from './modal.vue';
|
||||
|
||||
const USER_MODAL_INJECT_KEY = Symbol('VBEN_MODAL_INJECT');
|
||||
|
||||
const DEFAULT_MODAL_PROPS: Partial<ModalProps> = {};
|
||||
const DEFAULT_MODAL_PROPS: Partial<ModalProps> = {
|
||||
destroyOnClose: true,
|
||||
};
|
||||
|
||||
export function setDefaultModalProps(props: Partial<ModalProps>) {
|
||||
Object.assign(DEFAULT_MODAL_PROPS, props);
|
||||
@@ -72,7 +74,7 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
|
||||
|
||||
mergedOptions.onClosed = () => {
|
||||
options.onClosed?.();
|
||||
if (options.destroyOnClose) {
|
||||
if (mergedOptions.destroyOnClose) {
|
||||
injectData.reCreateModal?.();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/shadcn-ui",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"#main": "./dist/index.mjs",
|
||||
"#module": "./dist/index.mjs",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
|
||||
@@ -10,7 +10,7 @@ import TabsIndicator from './tabs-indicator.vue';
|
||||
|
||||
interface Props {
|
||||
defaultValue?: string;
|
||||
tabs: SegmentedItem[];
|
||||
tabs?: SegmentedItem[];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/tabs-ui",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/constants",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/access",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/common-ui",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -9,7 +9,7 @@ export function useCaptchaPoints() {
|
||||
}
|
||||
|
||||
function clearPoints() {
|
||||
points.splice(0, points.length);
|
||||
points.splice(0);
|
||||
}
|
||||
return {
|
||||
addPoint,
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
padding: 0 4px 2px;
|
||||
font-size: 0.9em;
|
||||
line-height: 0.9;
|
||||
color: hsl(var(--secondary-foreground));
|
||||
vertical-align: 2px;
|
||||
color: hsl(var(--secondary-foreground));
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
background-color: hsl(var(--secondary));
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
&.jv-string {
|
||||
color: hsl(var(--primary));
|
||||
word-break: break-word;
|
||||
overflow-wrap: break-word;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1072,8 +1072,8 @@ watch(
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
content: '';
|
||||
outline: 1px dashed #d6d6d6;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.resize-stick {
|
||||
|
||||
@@ -37,7 +37,7 @@ defineOptions({
|
||||
⚡ 面试手册
|
||||
</a>
|
||||
<a
|
||||
href="http://static.yudao.iocoder.cn/mp/Aix9975.jpeg"
|
||||
href="http://static.yudao.iocoder.cn/mp/xinyu370.jpeg"
|
||||
target="_blank"
|
||||
class="text-primary hover:text-primary/80 text-sm"
|
||||
>
|
||||
|
||||
@@ -18,7 +18,7 @@ import DocLink from './doc-link.vue';
|
||||
import ThirdPartyLogin from './third-party-login.vue';
|
||||
|
||||
interface Props extends AuthenticationProps {
|
||||
formSchema: VbenFormSchema[];
|
||||
formSchema?: VbenFormSchema[];
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
|
||||
@@ -14,7 +14,7 @@ import { VbenButton } from '@vben-core/shadcn-ui';
|
||||
import Title from './auth-title.vue';
|
||||
|
||||
interface Props {
|
||||
formSchema: VbenFormSchema[];
|
||||
formSchema?: VbenFormSchema[];
|
||||
/**
|
||||
* @zh_CN 是否处于加载处理状态
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,7 @@ import { computed } from 'vue';
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@vben-core/shadcn-ui';
|
||||
|
||||
interface Props {
|
||||
tabs: TabOption[];
|
||||
tabs?: TabOption[];
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from '@vben-core/shadcn-ui';
|
||||
|
||||
interface Props {
|
||||
items: AnalysisOverviewItem[];
|
||||
items?: AnalysisOverviewItem[];
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '@vben-core/shadcn-ui';
|
||||
|
||||
interface Props {
|
||||
items: WorkbenchProjectItem[];
|
||||
items?: WorkbenchProjectItem[];
|
||||
title: string;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ defineEmits(['click']);
|
||||
'border-r-0': index % 3 === 2,
|
||||
'border-b-0': index < 3,
|
||||
'pb-4': index > 2,
|
||||
'rounded-bl-xl': index === items.length - 3,
|
||||
'rounded-br-xl': index === items.length - 1,
|
||||
}"
|
||||
class="border-border group w-full cursor-pointer border-r border-t p-4 transition-all hover:shadow-xl md:w-1/2 lg:w-1/3"
|
||||
>
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '@vben-core/shadcn-ui';
|
||||
|
||||
interface Props {
|
||||
items: WorkbenchQuickNavItem[];
|
||||
items?: WorkbenchQuickNavItem[];
|
||||
title: string;
|
||||
}
|
||||
|
||||
@@ -35,8 +35,10 @@ defineEmits(['click']);
|
||||
<div
|
||||
:class="{
|
||||
'border-r-0': index % 3 === 2,
|
||||
'pb-4': index > 2,
|
||||
'border-b-0': index < 3,
|
||||
'pb-4': index > 2,
|
||||
'rounded-bl-xl': index === items.length - 3,
|
||||
'rounded-br-xl': index === items.length - 1,
|
||||
}"
|
||||
class="flex-col-center border-border group w-1/3 cursor-pointer border-r border-t py-8 hover:shadow-xl"
|
||||
@click="$emit('click', item)"
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '@vben-core/shadcn-ui';
|
||||
|
||||
interface Props {
|
||||
items: WorkbenchTodoItem[];
|
||||
items?: WorkbenchTodoItem[];
|
||||
title: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '@vben-core/shadcn-ui';
|
||||
|
||||
interface Props {
|
||||
items: WorkbenchTrendItem[];
|
||||
items?: WorkbenchTrendItem[];
|
||||
title: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/hooks",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/layouts",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
interface Props {
|
||||
companyName: string;
|
||||
companyName?: string;
|
||||
companySiteLink?: string;
|
||||
date: string;
|
||||
date?: string;
|
||||
icp?: string;
|
||||
icpLink?: string;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
updatePreferences,
|
||||
usePreferences,
|
||||
} from '@vben/preferences';
|
||||
import { useLockStore } from '@vben/stores';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
import { cloneDeep, mapTree } from '@vben/utils';
|
||||
|
||||
import { VbenAdminLayout } from '@vben-core/layout-ui';
|
||||
@@ -49,7 +49,7 @@ const {
|
||||
sidebarCollapsed,
|
||||
theme,
|
||||
} = usePreferences();
|
||||
const lockStore = useLockStore();
|
||||
const accessStore = useAccessStore();
|
||||
const { refresh } = useRefresh();
|
||||
|
||||
const sidebarTheme = computed(() => {
|
||||
@@ -356,7 +356,7 @@ const headerSlots = computed(() => {
|
||||
/>
|
||||
|
||||
<Transition v-if="preferences.widget.lockScreen" name="slide-up">
|
||||
<slot v-if="lockStore.isLockScreen" name="lock-screen"></slot>
|
||||
<slot v-if="accessStore.isLockScreen" name="lock-screen"></slot>
|
||||
</Transition>
|
||||
|
||||
<template v-if="preferencesButtonPosition.fixed">
|
||||
|
||||
@@ -11,7 +11,7 @@ import { useNavigation } from './use-navigation';
|
||||
|
||||
interface Props extends MenuProps {
|
||||
collapse?: boolean;
|
||||
menus: MenuRecordRaw[];
|
||||
menus?: MenuRecordRaw[];
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { MenuProps } from '@vben-core/menu-ui';
|
||||
import { Menu } from '@vben-core/menu-ui';
|
||||
|
||||
interface Props extends MenuProps {
|
||||
menus: MenuRecordRaw[];
|
||||
menus?: MenuRecordRaw[];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
|
||||
@@ -24,7 +24,7 @@ defineOptions({
|
||||
});
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{ enableShortcutKey?: boolean; menus: MenuRecordRaw[] }>(),
|
||||
defineProps<{ enableShortcutKey?: boolean; menus?: MenuRecordRaw[] }>(),
|
||||
{
|
||||
enableShortcutKey: true,
|
||||
menus: () => [],
|
||||
|
||||
@@ -18,7 +18,7 @@ defineOptions({
|
||||
});
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{ keyword: string; menus: MenuRecordRaw[] }>(),
|
||||
defineProps<{ keyword?: string; menus?: MenuRecordRaw[] }>(),
|
||||
{
|
||||
keyword: '',
|
||||
menus: () => [],
|
||||
|
||||
@@ -3,7 +3,7 @@ import { computed, reactive, ref } from 'vue';
|
||||
|
||||
import { LockKeyhole } from '@vben/icons';
|
||||
import { $t, useI18n } from '@vben/locales';
|
||||
import { storeToRefs, useLockStore } from '@vben/stores';
|
||||
import { storeToRefs, useAccessStore } from '@vben/stores';
|
||||
|
||||
import { useScrollLock } from '@vben-core/composables';
|
||||
import { useVbenForm, z } from '@vben-core/form-ui';
|
||||
@@ -26,7 +26,7 @@ withDefaults(defineProps<Props>(), {
|
||||
defineEmits<{ toLogin: [] }>();
|
||||
|
||||
const { locale } = useI18n();
|
||||
const lockStore = useLockStore();
|
||||
const accessStore = useAccessStore();
|
||||
|
||||
const now = useNow();
|
||||
const meridiem = useDateFormat(now, 'A');
|
||||
@@ -35,7 +35,7 @@ const minute = useDateFormat(now, 'mm');
|
||||
const date = useDateFormat(now, 'YYYY-MM-DD dddd', { locales: locale.value });
|
||||
|
||||
const showUnlockForm = ref(false);
|
||||
const { lockScreenPassword } = storeToRefs(lockStore);
|
||||
const { lockScreenPassword } = storeToRefs(accessStore);
|
||||
|
||||
const [Form, { form, validate }] = useVbenForm(
|
||||
reactive({
|
||||
@@ -66,7 +66,7 @@ async function handleSubmit() {
|
||||
const { valid } = await validate();
|
||||
if (valid) {
|
||||
if (validPass.value) {
|
||||
lockStore.unlockScreen();
|
||||
accessStore.unlockScreen();
|
||||
} else {
|
||||
form.setFieldError('password', $t('authentication.passwordErrorTip'));
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ defineOptions({
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
disabled?: boolean;
|
||||
items: SelectOption[];
|
||||
items?: SelectOption[];
|
||||
multiple?: boolean;
|
||||
onBtnClick?: (value: string) => void;
|
||||
placeholder?: string;
|
||||
|
||||
@@ -7,7 +7,7 @@ defineOptions({
|
||||
name: 'PreferenceToggleItem',
|
||||
});
|
||||
|
||||
withDefaults(defineProps<{ disabled?: boolean; items: SelectOption[] }>(), {
|
||||
withDefaults(defineProps<{ disabled?: boolean; items?: SelectOption[] }>(), {
|
||||
disabled: false,
|
||||
items: () => [],
|
||||
});
|
||||
|
||||
@@ -132,8 +132,8 @@ function toggleTheme(event: MouseEvent) {
|
||||
&__sun {
|
||||
@apply fill-foreground/90 stroke-none;
|
||||
|
||||
transition: transform 1.6s cubic-bezier(0.25, 0, 0.2, 1);
|
||||
transform-origin: center center;
|
||||
transition: transform 1.6s cubic-bezier(0.25, 0, 0.2, 1);
|
||||
|
||||
&:hover > svg > & {
|
||||
@apply fill-foreground/90;
|
||||
@@ -143,10 +143,10 @@ function toggleTheme(event: MouseEvent) {
|
||||
&__sun-beams {
|
||||
@apply stroke-foreground/90 stroke-[2px];
|
||||
|
||||
transform-origin: center center;
|
||||
transition:
|
||||
transform 1.6s cubic-bezier(0.5, 1.5, 0.75, 1.25),
|
||||
opacity 0.6s cubic-bezier(0.25, 0, 0.3, 1);
|
||||
transform-origin: center center;
|
||||
|
||||
&:hover > svg > & {
|
||||
@apply stroke-foreground;
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useHoverToggle } from '@vben/hooks';
|
||||
import { LockKeyhole, LogOut } from '@vben/icons';
|
||||
import { $t } from '@vben/locales';
|
||||
import { preferences, usePreferences } from '@vben/preferences';
|
||||
import { useLockStore } from '@vben/stores';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
import { isWindowsOs } from '@vben/utils';
|
||||
|
||||
import { useVbenModal } from '@vben-core/popup-ui';
|
||||
@@ -82,7 +82,7 @@ const emit = defineEmits<{ logout: [] }>();
|
||||
|
||||
const { globalLockScreenShortcutKey, globalLogoutShortcutKey } =
|
||||
usePreferences();
|
||||
const lockStore = useLockStore();
|
||||
const accessStore = useAccessStore();
|
||||
const [LockModal, lockModalApi] = useVbenModal({
|
||||
connectedComponent: LockScreenModal,
|
||||
});
|
||||
@@ -133,7 +133,7 @@ function handleOpenLock() {
|
||||
|
||||
function handleSubmitLock(lockScreenPassword: string) {
|
||||
lockModalApi.close();
|
||||
lockStore.lockScreen(lockScreenPassword);
|
||||
accessStore.lockScreen(lockScreenPassword);
|
||||
}
|
||||
|
||||
function handleLogout() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/plugins",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -24,8 +24,8 @@ export function useVbenVxeGrid(options: VxeGridProps) {
|
||||
return () => h(VxeGrid, { ...props, ...attrs, api: extendedApi }, slots);
|
||||
},
|
||||
{
|
||||
inheritAttrs: false,
|
||||
name: 'VbenVxeGrid',
|
||||
inheritAttrs: false,
|
||||
},
|
||||
);
|
||||
// Add reactivity support
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/request",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/icons",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/locales",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/preferences",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/stores",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -25,6 +25,7 @@
|
||||
"@vben-core/typings": "workspace:*",
|
||||
"pinia": "catalog:",
|
||||
"pinia-plugin-persistedstate": "catalog:",
|
||||
"secure-ls": "catalog:",
|
||||
"vue": "catalog:",
|
||||
"vue-router": "catalog:"
|
||||
}
|
||||
|
||||
@@ -27,6 +27,14 @@ interface AccessState {
|
||||
* 是否已经检查过权限
|
||||
*/
|
||||
isAccessChecked: boolean;
|
||||
/**
|
||||
* 是否锁屏状态
|
||||
*/
|
||||
isLockScreen: boolean;
|
||||
/**
|
||||
* 锁屏密码
|
||||
*/
|
||||
lockScreenPassword?: string;
|
||||
/**
|
||||
* 登录是否过期
|
||||
*/
|
||||
@@ -65,6 +73,10 @@ export const useAccessStore = defineStore('core-access', {
|
||||
}
|
||||
return findMenu(this.accessMenus, path);
|
||||
},
|
||||
lockScreen(password: string) {
|
||||
this.isLockScreen = true;
|
||||
this.lockScreenPassword = password;
|
||||
},
|
||||
setAccessCodes(codes: string[]) {
|
||||
this.accessCodes = codes;
|
||||
},
|
||||
@@ -89,10 +101,21 @@ export const useAccessStore = defineStore('core-access', {
|
||||
setTenantId(tenantId: null | number) {
|
||||
this.tenantId = tenantId;
|
||||
},
|
||||
unlockScreen() {
|
||||
this.isLockScreen = false;
|
||||
this.lockScreenPassword = undefined;
|
||||
},
|
||||
},
|
||||
persist: {
|
||||
// 持久化
|
||||
pick: ['accessToken', 'refreshToken', 'tenantId'],
|
||||
pick: [
|
||||
'accessToken',
|
||||
'refreshToken',
|
||||
'accessCodes',
|
||||
'tenantId',
|
||||
'isLockScreen',
|
||||
'lockScreenPassword',
|
||||
],
|
||||
},
|
||||
state: (): AccessState => ({
|
||||
accessCodes: [],
|
||||
@@ -100,6 +123,8 @@ export const useAccessStore = defineStore('core-access', {
|
||||
accessRoutes: [],
|
||||
accessToken: null,
|
||||
isAccessChecked: false,
|
||||
isLockScreen: false,
|
||||
lockScreenPassword: undefined,
|
||||
loginExpired: false,
|
||||
refreshToken: null,
|
||||
tenantId: null,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
export * from './access';
|
||||
export * from './lock';
|
||||
export * from './tabbar';
|
||||
export * from './user';
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import { createPinia, setActivePinia } from 'pinia';
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
import { useLockStore } from './lock';
|
||||
|
||||
describe('useLockStore', () => {
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia());
|
||||
});
|
||||
|
||||
it('should initialize with correct default state', () => {
|
||||
const store = useLockStore();
|
||||
expect(store.isLockScreen).toBe(false);
|
||||
expect(store.lockScreenPassword).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should lock screen with a password', () => {
|
||||
const store = useLockStore();
|
||||
store.lockScreen('1234');
|
||||
expect(store.isLockScreen).toBe(true);
|
||||
expect(store.lockScreenPassword).toBe('1234');
|
||||
});
|
||||
|
||||
it('should unlock screen and clear password', () => {
|
||||
const store = useLockStore();
|
||||
store.lockScreen('1234');
|
||||
store.unlockScreen();
|
||||
expect(store.isLockScreen).toBe(false);
|
||||
expect(store.lockScreenPassword).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -1,33 +0,0 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
interface AppState {
|
||||
/**
|
||||
* 是否锁屏状态
|
||||
*/
|
||||
isLockScreen: boolean;
|
||||
/**
|
||||
* 锁屏密码
|
||||
*/
|
||||
lockScreenPassword?: string;
|
||||
}
|
||||
|
||||
export const useLockStore = defineStore('core-lock', {
|
||||
actions: {
|
||||
lockScreen(password: string) {
|
||||
this.isLockScreen = true;
|
||||
this.lockScreenPassword = password;
|
||||
},
|
||||
|
||||
unlockScreen() {
|
||||
this.isLockScreen = false;
|
||||
this.lockScreenPassword = undefined;
|
||||
},
|
||||
},
|
||||
persist: {
|
||||
pick: ['isLockScreen', 'lockScreenPassword'],
|
||||
},
|
||||
state: (): AppState => ({
|
||||
isLockScreen: false,
|
||||
lockScreenPassword: undefined,
|
||||
}),
|
||||
});
|
||||
@@ -3,6 +3,7 @@ import type { Pinia } from 'pinia';
|
||||
import type { App } from 'vue';
|
||||
|
||||
import { createPinia } from 'pinia';
|
||||
import SecureLS from 'secure-ls';
|
||||
|
||||
let pinia: Pinia;
|
||||
|
||||
@@ -20,11 +21,27 @@ export async function initStores(app: App, options: InitStoreOptions) {
|
||||
const { createPersistedState } = await import('pinia-plugin-persistedstate');
|
||||
pinia = createPinia();
|
||||
const { namespace } = options;
|
||||
const ls = new SecureLS({
|
||||
encodingType: 'aes',
|
||||
encryptionSecret: import.meta.env.VITE_APP_STORE_SECURE_KEY,
|
||||
isCompression: true,
|
||||
// @ts-ignore secure-ls does not have a type definition for this
|
||||
metaKey: `${namespace}-secure-meta`,
|
||||
});
|
||||
pinia.use(
|
||||
createPersistedState({
|
||||
// key $appName-$store.id
|
||||
key: (storeKey) => `${namespace}-${storeKey}`,
|
||||
storage: localStorage,
|
||||
storage: import.meta.env.DEV
|
||||
? localStorage
|
||||
: {
|
||||
getItem(key) {
|
||||
return ls.get(key);
|
||||
},
|
||||
setItem(key, value) {
|
||||
ls.set(key, value);
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
app.use(pinia);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/styles",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/types",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/utils",
|
||||
"version": "5.5.4",
|
||||
"version": "5.5.5",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
||||
Reference in New Issue
Block a user