This commit is contained in:
dap
2025-04-28 13:19:57 +08:00
90 changed files with 380 additions and 260 deletions

View File

@@ -2,5 +2,5 @@ ports:
- port: 5555 - port: 5555
onOpen: open-preview onOpen: open-preview
tasks: tasks:
- init: corepack enable && pnpm install - init: npm i -g corepack && pnpm install
command: pnpm run dev:play command: pnpm run dev:play

View File

@@ -60,7 +60,7 @@ git clone https://github.com/vbenjs/vue-vben-admin.git
```bash ```bash
cd vue-vben-admin cd vue-vben-admin
corepack enable npm i -g corepack
pnpm install pnpm install

View File

@@ -60,7 +60,7 @@ git clone https://github.com/vbenjs/vue-vben-admin.git
```bash ```bash
cd vue-vben-admin cd vue-vben-admin
corepack enable npm i -g corepack
pnpm install pnpm install
``` ```

View File

@@ -3,3 +3,6 @@ VITE_APP_TITLE=Plus Admin
# 应用命名空间用于缓存、store等功能的前缀确保隔离 # 应用命名空间用于缓存、store等功能的前缀确保隔离
VITE_APP_NAMESPACE=vben-web-antd VITE_APP_NAMESPACE=vben-web-antd
# 对store进行加密的密钥在将store持久化到localStorage时会使用该密钥进行加密
VITE_APP_STORE_SECURE_KEY=please-replace-me-with-your-own-key

View File

@@ -87,8 +87,8 @@ const withDefaultPlaceholder = <T extends Component>(
componentProps: Recordable<any> = {}, componentProps: Recordable<any> = {},
) => { ) => {
return defineComponent({ return defineComponent({
inheritAttrs: false,
name: component.name, name: component.name,
inheritAttrs: false,
setup: (props: any, { attrs, expose, slots }) => { setup: (props: any, { attrs, expose, slots }) => {
const placeholder = const placeholder =
props?.placeholder || props?.placeholder ||
@@ -162,20 +162,34 @@ async function initComponentAdapter() {
// 如果你的组件体积比较大,可以使用异步加载 // 如果你的组件体积比较大,可以使用异步加载
// Button: () => // Button: () =>
// import('xxx').then((res) => res.Button), // import('xxx').then((res) => res.Button),
ApiSelect: withDefaultPlaceholder(ApiComponent, 'select', { ApiSelect: withDefaultPlaceholder(
component: Select, {
loadingSlot: 'suffixIcon', ...ApiComponent,
visibleEvent: 'onDropdownVisibleChange', name: 'ApiSelect',
modelPropName: 'value', },
}), 'select',
ApiTreeSelect: withDefaultPlaceholder(ApiComponent, 'select', { {
component: TreeSelect, component: Select,
fieldNames: { label: 'label', value: 'value', children: 'children' }, loadingSlot: 'suffixIcon',
loadingSlot: 'suffixIcon', visibleEvent: 'onDropdownVisibleChange',
modelPropName: 'value', modelPropName: 'value',
optionsPropName: 'treeData', },
visibleEvent: 'onVisibleChange', ),
}), ApiTreeSelect: withDefaultPlaceholder(
{
...ApiComponent,
name: 'ApiTreeSelect',
},
'select',
{
component: TreeSelect,
fieldNames: { label: 'label', value: 'value', children: 'children' },
loadingSlot: 'suffixIcon',
modelPropName: 'value',
optionsPropName: 'treeData',
visibleEvent: 'onVisibleChange',
},
),
AutoComplete, AutoComplete,
Checkbox, Checkbox,
CheckboxGroup, CheckboxGroup,

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/docs", "name": "@vben/docs",
"version": "5.5.4", "version": "5.5.5",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "vitepress build", "build": "vitepress build",

View File

@@ -58,7 +58,7 @@ Open a terminal in your code directory and execute the following commands:
cd vue-vben-admin cd vue-vben-admin
# Enable the project-specified version of pnpm # Enable the project-specified version of pnpm
corepack enable npm i -g corepack
# Install dependencies # Install dependencies
pnpm install pnpm install

View File

@@ -114,8 +114,6 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
```ts ```ts
const dashboardMenus = [ const dashboardMenus = [
{ {
// 这里固定写死 BasicLayout不可更改
component: 'BasicLayout',
meta: { meta: {
order: -1, order: -1,
title: 'page.dashboard.title', title: 'page.dashboard.title',
@@ -144,6 +142,16 @@ const dashboardMenus = [
}, },
], ],
}, },
{
name: 'Test',
path: '/test',
component: '/test/index',
meta: {
title: 'page.test',
// 部分特殊页面如果不需要基础布局页面顶部和侧边栏可将noBasicLayout设置为true
noBasicLayout: true,
},
},
]; ];
``` ```

View File

@@ -58,7 +58,7 @@ git clone https://gitee.com/annsion/vue-vben-admin.git
cd vue-vben-admin cd vue-vben-admin
# 使用项目指定的pnpm版本进行依赖安装 # 使用项目指定的pnpm版本进行依赖安装
corepack enable npm i -g corepack
# 安装依赖 # 安装依赖
pnpm install pnpm install

View File

@@ -20,6 +20,9 @@ hero:
- theme: alt - theme: alt
text: 在 GitHub 查看 text: 在 GitHub 查看
link: https://github.com/vbenjs/vue-vben-admin link: https://github.com/vbenjs/vue-vben-admin
- theme: alt
text: DeepWiki 文档
link: https://deepwiki.com/vbenjs/vue-vben-admin
features: features:
- icon: 🚀 - icon: 🚀

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/commitlint-config", "name": "@vben/commitlint-config",
"version": "5.5.4", "version": "5.5.5",
"private": true, "private": true,
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",

View File

@@ -10,7 +10,15 @@ export async function vue(): Promise<Linter.Config[]> {
interopDefault(import('@typescript-eslint/parser')), interopDefault(import('@typescript-eslint/parser')),
] as const); ] as const);
const flatEssential = pluginVue.configs?.['flat/essential'] || [];
const flatStronglyRecommended =
pluginVue.configs?.['flat/strongly-recommended'] || [];
const flatRecommended = pluginVue.configs?.['flat/recommended'] || [];
return [ return [
...flatEssential,
...flatStronglyRecommended,
...flatRecommended,
{ {
files: ['**/*.vue'], files: ['**/*.vue'],
languageOptions: { languageOptions: {
@@ -43,12 +51,9 @@ export async function vue(): Promise<Linter.Config[]> {
plugins: { plugins: {
vue: pluginVue, vue: pluginVue,
}, },
processor: pluginVue.processors['.vue'], processor: pluginVue.processors?.['.vue'],
rules: { rules: {
...pluginVue.configs.base.rules, ...pluginVue.configs?.base?.rules,
...pluginVue.configs['vue3-essential'].rules,
...pluginVue.configs['vue3-strongly-recommended'].rules,
...pluginVue.configs['vue3-recommended'].rules,
'vue/attribute-hyphenation': [ 'vue/attribute-hyphenation': [
'error', 'error',
@@ -131,7 +136,6 @@ export async function vue(): Promise<Linter.Config[]> {
'vue/require-default-prop': 'error', 'vue/require-default-prop': 'error',
'vue/require-explicit-emits': 'error', 'vue/require-explicit-emits': 'error',
'vue/require-prop-types': 'off', 'vue/require-prop-types': 'off',
'vue/script-setup-uses-vars': 'error',
'vue/singleline-html-element-content-newline': 'off', 'vue/singleline-html-element-content-newline': 'off',
'vue/space-infix-ops': 'error', 'vue/space-infix-ops': 'error',
'vue/space-unary-ops': ['error', { nonwords: false, words: true }], 'vue/space-unary-ops': ['error', { nonwords: false, words: true }],

View File

@@ -43,6 +43,7 @@ export default {
'stylelint-scss', 'stylelint-scss',
], ],
rules: { rules: {
'at-rule-no-deprecated': null,
'at-rule-no-unknown': [ 'at-rule-no-unknown': [
true, true,
{ {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/stylelint-config", "name": "@vben/stylelint-config",
"version": "5.5.4", "version": "5.5.5",
"private": true, "private": true,
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/node-utils", "name": "@vben/node-utils",
"version": "5.5.4", "version": "5.5.5",
"private": true, "private": true,
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/tailwind-config", "name": "@vben/tailwind-config",
"version": "5.5.4", "version": "5.5.5",
"private": true, "private": true,
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/tsconfig", "name": "@vben/tsconfig",
"version": "5.5.4", "version": "5.5.5",
"private": true, "private": true,
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/vite-config", "name": "@vben/vite-config",
"version": "5.5.4", "version": "5.5.5",
"private": true, "private": true,
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",

View File

@@ -1,6 +1,6 @@
{ {
"name": "vben-admin-monorepo", "name": "vben-admin-monorepo",
"version": "5.5.4", "version": "5.5.5",
"private": true, "private": true,
"keywords": [ "keywords": [
"monorepo", "monorepo",
@@ -107,7 +107,7 @@
"@ast-grep/napi": "catalog:", "@ast-grep/napi": "catalog:",
"@ctrl/tinycolor": "catalog:", "@ctrl/tinycolor": "catalog:",
"clsx": "catalog:", "clsx": "catalog:",
"esbuild": "0.24.0", "esbuild": "0.25.3",
"pinia": "catalog:", "pinia": "catalog:",
"vue": "catalog:" "vue": "catalog:"
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben-core/design", "name": "@vben-core/design",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben-core/icons", "name": "@vben-core/icons",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben-core/shared", "name": "@vben-core/shared",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,3 +1,4 @@
// eslint-disable-next-line vue/prefer-import-from-vue
import { isFunction, isObject, isString } from '@vue/shared'; import { isFunction, isObject, isString } from '@vue/shared';
/** /**

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben-core/typings", "name": "@vben-core/typings",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben-core/composables", "name": "@vben-core/composables",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben-core/preferences", "name": "@vben-core/preferences",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben-core/form-ui", "name": "@vben-core/form-ui",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben-core/layout-ui", "name": "@vben-core/layout-ui",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben-core/menu-ui", "name": "@vben-core/menu-ui",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -10,7 +10,7 @@ import { VbenIcon } from '@vben-core/shadcn-ui';
import { useMenuContext } from '../hooks'; import { useMenuContext } from '../hooks';
interface Props extends MenuItemProps { interface Props extends MenuItemProps {
isMenuMore: boolean; isMenuMore?: boolean;
isTopLevelMenuSubmenu: boolean; isTopLevelMenuSubmenu: boolean;
level?: number; level?: number;
} }

View File

@@ -47,6 +47,10 @@ function onAlertClosed() {
isConfirm.value = false; isConfirm.value = false;
} }
function onEscapeKeyDown() {
isConfirm.value = false;
}
const getIconRender = computed(() => { const getIconRender = computed(() => {
let iconRender: Component | null = null; let iconRender: Component | null = null;
if (props.icon) { if (props.icon) {
@@ -116,13 +120,11 @@ function handleCancel() {
const loading = ref(false); const loading = ref(false);
async function handleOpenChange(val: boolean) { async function handleOpenChange(val: boolean) {
const confirmState = isConfirm.value; await nextTick(); // 等待标记isConfirm状态
isConfirm.value = false;
await nextTick();
if (!val && props.beforeClose) { if (!val && props.beforeClose) {
loading.value = true; loading.value = true;
try { try {
const res = await props.beforeClose({ isConfirm: confirmState }); const res = await props.beforeClose({ isConfirm: isConfirm.value });
if (res !== false) { if (res !== false) {
open.value = false; open.value = false;
} }
@@ -142,6 +144,7 @@ async function handleOpenChange(val: boolean) {
:overlay-blur="overlayBlur" :overlay-blur="overlayBlur"
@opened="emits('opened')" @opened="emits('opened')"
@closed="onAlertClosed" @closed="onAlertClosed"
@escape-key-down="onEscapeKeyDown"
:class=" :class="
cn( cn(
containerClass, containerClass,

View File

@@ -52,6 +52,10 @@ export interface DrawerProps {
* 弹窗描述 * 弹窗描述
*/ */
description?: string; description?: string;
/**
* 在关闭时销毁抽屉
*/
destroyOnClose?: boolean;
/** /**
* 是否显示底部 * 是否显示底部
* @default true * @default true
@@ -143,10 +147,6 @@ export interface DrawerApiOptions extends DrawerState {
* 独立的抽屉组件 * 独立的抽屉组件
*/ */
connectedComponent?: Component; connectedComponent?: Component;
/**
* 在关闭时销毁抽屉。仅在使用 connectedComponent 时有效
*/
destroyOnClose?: boolean;
/** /**
* 关闭前的回调,返回 false 可以阻止关闭 * 关闭前的回调,返回 false 可以阻止关闭
* @returns * @returns

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { DrawerProps, ExtendedDrawerApi } from './drawer'; import type { DrawerProps, ExtendedDrawerApi } from './drawer';
import { computed, provide, ref, useId, watch } from 'vue'; import { computed, provide, ref, unref, useId, watch } from 'vue';
import { import {
useIsMobile, useIsMobile,
@@ -35,6 +35,7 @@ interface Props extends DrawerProps {
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
appendToMain: false, appendToMain: false,
closeIconPlacement: 'right', closeIconPlacement: 'right',
destroyOnClose: true,
drawerApi: undefined, drawerApi: undefined,
submitting: false, submitting: false,
zIndex: 1000, zIndex: 1000,
@@ -63,6 +64,7 @@ const {
confirmText, confirmText,
contentClass, contentClass,
description, description,
destroyOnClose,
footer: showFooter, footer: showFooter,
footerClass, footerClass,
header: showHeader, header: showHeader,
@@ -131,6 +133,29 @@ const getAppendTo = computed(() => {
? `#${ELEMENT_ID_MAIN_CONTENT}>div:not(.absolute)>div` ? `#${ELEMENT_ID_MAIN_CONTENT}>div:not(.absolute)>div`
: undefined; : 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> </script>
<template> <template>
<Sheet <Sheet
@@ -144,15 +169,17 @@ const getAppendTo = computed(() => {
cn('flex w-[520px] flex-col', drawerClass, { cn('flex w-[520px] flex-col', drawerClass, {
'!w-full': isMobile || placement === 'bottom' || placement === 'top', '!w-full': isMobile || placement === 'bottom' || placement === 'top',
'max-h-[100vh]': placement === 'bottom' || placement === 'top', 'max-h-[100vh]': placement === 'bottom' || placement === 'top',
hidden: isClosed,
}) })
" "
:modal="modal" :modal="modal"
:open="state?.isOpen" :open="state?.isOpen"
:side="placement" :side="placement"
:z-index="zIndex" :z-index="zIndex"
:force-mount="getForceMount"
:overlay-blur="overlayBlur" :overlay-blur="overlayBlur"
@close-auto-focus="handleFocusOutside" @close-auto-focus="handleFocusOutside"
@closed="() => drawerApi?.onClosed()" @closed="handleClosed"
@escape-key-down="escapeKeyDown" @escape-key-down="escapeKeyDown"
@focus-outside="handleFocusOutside" @focus-outside="handleFocusOutside"
@interact-outside="interactOutside" @interact-outside="interactOutside"

View File

@@ -21,7 +21,9 @@ import VbenDrawer from './drawer.vue';
const USER_DRAWER_INJECT_KEY = Symbol('VBEN_DRAWER_INJECT'); 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>) { export function setDefaultDrawerProps(props: Partial<DrawerProps>) {
Object.assign(DEFAULT_DRAWER_PROPS, props); Object.assign(DEFAULT_DRAWER_PROPS, props);

View File

@@ -17,7 +17,9 @@ import VbenModal from './modal.vue';
const USER_MODAL_INJECT_KEY = Symbol('VBEN_MODAL_INJECT'); 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>) { export function setDefaultModalProps(props: Partial<ModalProps>) {
Object.assign(DEFAULT_MODAL_PROPS, props); Object.assign(DEFAULT_MODAL_PROPS, props);
@@ -86,7 +88,7 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
mergedOptions.onClosed = () => { mergedOptions.onClosed = () => {
options.onClosed?.(); options.onClosed?.();
if (options.destroyOnClose) { if (mergedOptions.destroyOnClose) {
injectData.reCreateModal?.(); injectData.reCreateModal?.();
} }
}; };

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben-core/shadcn-ui", "name": "@vben-core/shadcn-ui",
"version": "5.5.4", "version": "5.5.5",
"#main": "./dist/index.mjs", "#main": "./dist/index.mjs",
"#module": "./dist/index.mjs", "#module": "./dist/index.mjs",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",

View File

@@ -41,7 +41,6 @@ watch(
innerValue.value.length > 0 ? innerValue.value[0] : undefined; innerValue.value.length > 0 ? innerValue.value[0] : undefined;
} }
}, },
{ immediate: true },
); );
watch( watch(
@@ -60,7 +59,7 @@ watch(
innerValue.value = val === undefined ? [] : [val as ValueType]; innerValue.value = val === undefined ? [] : [val as ValueType];
} }
}, },
{ deep: true }, { deep: true, immediate: true },
); );
async function onBtnClick(value: ValueType) { async function onBtnClick(value: ValueType) {

View File

@@ -10,7 +10,7 @@ import TabsIndicator from './tabs-indicator.vue';
interface Props { interface Props {
defaultValue?: string; defaultValue?: string;
tabs: SegmentedItem[]; tabs?: SegmentedItem[];
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {

View File

@@ -1,4 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { CircleX } from '@vben-core/icons';
import { import {
Select, Select,
SelectContent, SelectContent,
@@ -8,6 +10,7 @@ import {
} from '../../ui'; } from '../../ui';
interface Props { interface Props {
allowClear?: boolean;
class?: any; class?: any;
// 弹出层的类名 // 弹出层的类名
contentClass?: any; contentClass?: any;
@@ -15,12 +18,27 @@ interface Props {
placeholder?: string; placeholder?: string;
} }
const props = defineProps<Props>(); const props = withDefaults(defineProps<Props>(), {
allowClear: false,
});
const modelValue = defineModel<string>();
function handleClear() {
modelValue.value = undefined;
}
</script> </script>
<template> <template>
<Select> <Select v-model="modelValue">
<SelectTrigger :class="props.class"> <SelectTrigger :class="props.class" class="flex w-full items-center">
<SelectValue :placeholder="placeholder" /> <SelectValue class="flex-auto text-left" :placeholder="placeholder" />
<CircleX
@pointerdown.stop
@click.stop.prevent="handleClear"
v-if="allowClear && modelValue"
data-clear-button
class="mr-1 size-4 cursor-pointer opacity-50 hover:opacity-100"
/>
</SelectTrigger> </SelectTrigger>
<SelectContent :class="props.contentClass"> <SelectContent :class="props.contentClass">
<template v-for="item in options" :key="item.value"> <template v-for="item in options" :key="item.value">

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben-core/tabs-ui", "name": "@vben-core/tabs-ui",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/constants", "name": "@vben/constants",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/access", "name": "@vben/access",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/common-ui", "name": "@vben/common-ui",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -9,7 +9,7 @@ export function useCaptchaPoints() {
} }
function clearPoints() { function clearPoints() {
points.splice(0, points.length); points.splice(0);
} }
return { return {
addPoint, addPoint,

View File

@@ -65,7 +65,7 @@
&.jv-string { &.jv-string {
color: hsl(var(--primary)); color: hsl(var(--primary));
word-break: break-word; overflow-wrap: break-word;
white-space: normal; white-space: normal;
} }
} }

View File

@@ -3,18 +3,20 @@ import type { VbenFormSchema } from '@vben-core/form-ui';
import type { AuthenticationProps, LoginAndRegisterParams } from './types'; import type { AuthenticationProps, LoginAndRegisterParams } from './types';
import { computed, onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
import { useVbenForm } from '@vben-core/form-ui'; import { useVbenForm } from '@vben-core/form-ui';
import { VbenButton, VbenCheckbox } from '@vben-core/shadcn-ui'; import { VbenButton, VbenCheckbox } from '@vben-core/shadcn-ui';
import { cloneDeep } from '@vben-core/shared/utils'; import { cloneDeep } from '@vben-core/shared/utils';
import { computed, onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import Title from './auth-title.vue'; import Title from './auth-title.vue';
import ThirdPartyLogin from './third-party-login.vue'; import ThirdPartyLogin from './third-party-login.vue';
interface Props extends AuthenticationProps { interface Props extends AuthenticationProps {
formSchema: VbenFormSchema[]; formSchema?: VbenFormSchema[];
} }
defineOptions({ defineOptions({

View File

@@ -1,17 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import type { Recordable } from '@vben/types'; import type { Recordable } from '@vben/types';
import type { VbenFormSchema } from '@vben-core/form-ui'; import type { VbenFormSchema } from '@vben-core/form-ui';
import { $t } from '@vben/locales';
import { useVbenForm } from '@vben-core/form-ui';
import { VbenButton } from '@vben-core/shadcn-ui';
import { computed, reactive } from 'vue'; import { computed, reactive } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { $t } from '@vben/locales';
import { useVbenForm } from '@vben-core/form-ui';
import { VbenButton } from '@vben-core/shadcn-ui';
import Title from './auth-title.vue'; import Title from './auth-title.vue';
interface Props { interface Props {
formSchema: VbenFormSchema[]; formSchema?: VbenFormSchema[];
/** /**
* @zh_CN 是否处于加载处理状态 * @zh_CN 是否处于加载处理状态
*/ */

View File

@@ -6,7 +6,7 @@ import { computed } from 'vue';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@vben-core/shadcn-ui'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@vben-core/shadcn-ui';
interface Props { interface Props {
tabs: TabOption[]; tabs?: TabOption[];
} }
defineOptions({ defineOptions({

View File

@@ -12,7 +12,7 @@ import {
} from '@vben-core/shadcn-ui'; } from '@vben-core/shadcn-ui';
interface Props { interface Props {
items: AnalysisOverviewItem[]; items?: AnalysisOverviewItem[];
} }
defineOptions({ defineOptions({

View File

@@ -10,7 +10,7 @@ import {
} from '@vben-core/shadcn-ui'; } from '@vben-core/shadcn-ui';
interface Props { interface Props {
items: WorkbenchProjectItem[]; items?: WorkbenchProjectItem[];
title: string; title: string;
} }
@@ -37,6 +37,8 @@ defineEmits(['click']);
'border-r-0': index % 3 === 2, 'border-r-0': index % 3 === 2,
'border-b-0': index < 3, 'border-b-0': index < 3,
'pb-4': index > 2, '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" 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"
> >

View File

@@ -10,7 +10,7 @@ import {
} from '@vben-core/shadcn-ui'; } from '@vben-core/shadcn-ui';
interface Props { interface Props {
items: WorkbenchQuickNavItem[]; items?: WorkbenchQuickNavItem[];
title: string; title: string;
} }
@@ -35,8 +35,10 @@ defineEmits(['click']);
<div <div
:class="{ :class="{
'border-r-0': index % 3 === 2, 'border-r-0': index % 3 === 2,
'pb-4': index > 2,
'border-b-0': index < 3, '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" 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)" @click="$emit('click', item)"

View File

@@ -10,7 +10,7 @@ import {
} from '@vben-core/shadcn-ui'; } from '@vben-core/shadcn-ui';
interface Props { interface Props {
items: WorkbenchTodoItem[]; items?: WorkbenchTodoItem[];
title: string; title: string;
} }

View File

@@ -10,7 +10,7 @@ import {
} from '@vben-core/shadcn-ui'; } from '@vben-core/shadcn-ui';
interface Props { interface Props {
items: WorkbenchTrendItem[]; items?: WorkbenchTrendItem[];
title: string; title: string;
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/hooks", "name": "@vben/hooks",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/layouts", "name": "@vben/layouts",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,8 +1,8 @@
<script lang="ts" setup> <script lang="ts" setup>
interface Props { interface Props {
companyName: string; companyName?: string;
companySiteLink?: string; companySiteLink?: string;
date: string; date?: string;
icp?: string; icp?: string;
icpLink?: string; icpLink?: string;
} }

View File

@@ -12,7 +12,7 @@ import {
updatePreferences, updatePreferences,
usePreferences, usePreferences,
} from '@vben/preferences'; } from '@vben/preferences';
import { useLockStore } from '@vben/stores'; import { useAccessStore } from '@vben/stores';
import { cloneDeep, mapTree } from '@vben/utils'; import { cloneDeep, mapTree } from '@vben/utils';
import { VbenAdminLayout } from '@vben-core/layout-ui'; import { VbenAdminLayout } from '@vben-core/layout-ui';
@@ -49,7 +49,7 @@ const {
sidebarCollapsed, sidebarCollapsed,
theme, theme,
} = usePreferences(); } = usePreferences();
const lockStore = useLockStore(); const accessStore = useAccessStore();
const { refresh } = useRefresh(); const { refresh } = useRefresh();
const sidebarTheme = computed(() => { const sidebarTheme = computed(() => {
@@ -356,7 +356,7 @@ const headerSlots = computed(() => {
/> />
<Transition v-if="preferences.widget.lockScreen" name="slide-up"> <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> </Transition>
<template v-if="preferencesButtonPosition.fixed"> <template v-if="preferencesButtonPosition.fixed">

View File

@@ -1,15 +1,17 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { MenuRecordRaw } from '@vben/types'; import type { MenuRecordRaw } from '@vben/types';
import type { MenuProps } from '@vben-core/menu-ui'; import type { MenuProps } from '@vben-core/menu-ui';
import { Menu } from '@vben-core/menu-ui';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { Menu } from '@vben-core/menu-ui';
import { useNavigation } from './use-navigation'; import { useNavigation } from './use-navigation';
interface Props extends MenuProps { interface Props extends MenuProps {
collapse?: boolean; collapse?: boolean;
menus: MenuRecordRaw[]; menus?: MenuRecordRaw[];
} }
withDefaults(defineProps<Props>(), { withDefaults(defineProps<Props>(), {

View File

@@ -1,11 +1,12 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { MenuRecordRaw } from '@vben/types'; import type { MenuRecordRaw } from '@vben/types';
import type { MenuProps } from '@vben-core/menu-ui'; import type { MenuProps } from '@vben-core/menu-ui';
import { Menu } from '@vben-core/menu-ui'; import { Menu } from '@vben-core/menu-ui';
interface Props extends MenuProps { interface Props extends MenuProps {
menus: MenuRecordRaw[]; menus?: MenuRecordRaw[];
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {

View File

@@ -1,6 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import type { MenuRecordRaw } from '@vben/types'; import type { MenuRecordRaw } from '@vben/types';
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
import { import {
ArrowDown, ArrowDown,
ArrowUp, ArrowUp,
@@ -10,9 +12,10 @@ import {
} from '@vben/icons'; } from '@vben/icons';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
import { isWindowsOs } from '@vben/utils'; import { isWindowsOs } from '@vben/utils';
import { useVbenModal } from '@vben-core/popup-ui'; import { useVbenModal } from '@vben-core/popup-ui';
import { useMagicKeys, whenever } from '@vueuse/core'; import { useMagicKeys, whenever } from '@vueuse/core';
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
import SearchPanel from './search-panel.vue'; import SearchPanel from './search-panel.vue';
@@ -21,7 +24,7 @@ defineOptions({
}); });
const props = withDefaults( const props = withDefaults(
defineProps<{ enableShortcutKey?: boolean; menus: MenuRecordRaw[] }>(), defineProps<{ enableShortcutKey?: boolean; menus?: MenuRecordRaw[] }>(),
{ {
enableShortcutKey: true, enableShortcutKey: true,
menus: () => [], menus: () => [],

View File

@@ -1,21 +1,24 @@
<script setup lang="ts"> <script setup lang="ts">
import type { MenuRecordRaw } from '@vben/types'; import type { MenuRecordRaw } from '@vben/types';
import { nextTick, onMounted, ref, shallowRef, watch } from 'vue';
import { useRouter } from 'vue-router';
import { SearchX, X } from '@vben/icons'; import { SearchX, X } from '@vben/icons';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
import { mapTree, traverseTreeValues, uniqueByField } from '@vben/utils'; import { mapTree, traverseTreeValues, uniqueByField } from '@vben/utils';
import { VbenIcon, VbenScrollbar } from '@vben-core/shadcn-ui'; import { VbenIcon, VbenScrollbar } from '@vben-core/shadcn-ui';
import { isHttpUrl } from '@vben-core/shared/utils'; import { isHttpUrl } from '@vben-core/shared/utils';
import { onKeyStroke, useLocalStorage, useThrottleFn } from '@vueuse/core'; import { onKeyStroke, useLocalStorage, useThrottleFn } from '@vueuse/core';
import { nextTick, onMounted, ref, shallowRef, watch } from 'vue';
import { useRouter } from 'vue-router';
defineOptions({ defineOptions({
name: 'SearchPanel', name: 'SearchPanel',
}); });
const props = withDefaults( const props = withDefaults(
defineProps<{ keyword: string; menus: MenuRecordRaw[] }>(), defineProps<{ keyword?: string; menus?: MenuRecordRaw[] }>(),
{ {
keyword: '', keyword: '',
menus: () => [], menus: () => [],

View File

@@ -1,12 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, reactive, ref } from 'vue';
import { LockKeyhole } from '@vben/icons'; import { LockKeyhole } from '@vben/icons';
import { $t, useI18n } from '@vben/locales'; 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 { useScrollLock } from '@vben-core/composables';
import { useVbenForm, z } from '@vben-core/form-ui'; import { useVbenForm, z } from '@vben-core/form-ui';
import { VbenAvatar, VbenButton } from '@vben-core/shadcn-ui'; import { VbenAvatar, VbenButton } from '@vben-core/shadcn-ui';
import { useDateFormat, useNow } from '@vueuse/core'; import { useDateFormat, useNow } from '@vueuse/core';
import { computed, reactive, ref } from 'vue';
interface Props { interface Props {
avatar?: string; avatar?: string;
@@ -23,7 +26,7 @@ withDefaults(defineProps<Props>(), {
defineEmits<{ toLogin: [] }>(); defineEmits<{ toLogin: [] }>();
const { locale } = useI18n(); const { locale } = useI18n();
const lockStore = useLockStore(); const accessStore = useAccessStore();
const now = useNow(); const now = useNow();
const meridiem = useDateFormat(now, 'A'); const meridiem = useDateFormat(now, 'A');
@@ -32,7 +35,7 @@ const minute = useDateFormat(now, 'mm');
const date = useDateFormat(now, 'YYYY-MM-DD dddd', { locales: locale.value }); const date = useDateFormat(now, 'YYYY-MM-DD dddd', { locales: locale.value });
const showUnlockForm = ref(false); const showUnlockForm = ref(false);
const { lockScreenPassword } = storeToRefs(lockStore); const { lockScreenPassword } = storeToRefs(accessStore);
const [Form, { form, validate }] = useVbenForm( const [Form, { form, validate }] = useVbenForm(
reactive({ reactive({
@@ -63,7 +66,7 @@ async function handleSubmit() {
const { valid } = await validate(); const { valid } = await validate();
if (valid) { if (valid) {
if (validPass.value) { if (validPass.value) {
lockStore.unlockScreen(); accessStore.unlockScreen();
} else { } else {
form.setFieldError('password', $t('authentication.passwordErrorTip')); form.setFieldError('password', $t('authentication.passwordErrorTip'));
} }

View File

@@ -14,7 +14,7 @@ defineOptions({
withDefaults( withDefaults(
defineProps<{ defineProps<{
disabled?: boolean; disabled?: boolean;
items: SelectOption[]; items?: SelectOption[];
multiple?: boolean; multiple?: boolean;
onBtnClick?: (value: string) => void; onBtnClick?: (value: string) => void;
placeholder?: string; placeholder?: string;

View File

@@ -7,7 +7,7 @@ defineOptions({
name: 'PreferenceToggleItem', name: 'PreferenceToggleItem',
}); });
withDefaults(defineProps<{ disabled?: boolean; items: SelectOption[] }>(), { withDefaults(defineProps<{ disabled?: boolean; items?: SelectOption[] }>(), {
disabled: false, disabled: false,
items: () => [], items: () => [],
}); });

View File

@@ -1,13 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import type { AnyFunction } from '@vben/types';
import type { Component } from 'vue'; import type { Component } from 'vue';
import type { AnyFunction } from '@vben/types';
import { computed, useTemplateRef, watch } from 'vue';
import { useHoverToggle } from '@vben/hooks'; import { useHoverToggle } from '@vben/hooks';
import { LockKeyhole, LogOut } from '@vben/icons'; import { LockKeyhole, LogOut } from '@vben/icons';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
import { preferences, usePreferences } from '@vben/preferences'; import { preferences, usePreferences } from '@vben/preferences';
import { useLockStore } from '@vben/stores'; import { useAccessStore } from '@vben/stores';
import { isWindowsOs } from '@vben/utils'; import { isWindowsOs } from '@vben/utils';
import { useVbenModal } from '@vben-core/popup-ui'; import { useVbenModal } from '@vben-core/popup-ui';
import { import {
Badge, Badge,
@@ -21,8 +25,8 @@ import {
VbenAvatar, VbenAvatar,
VbenIcon, VbenIcon,
} from '@vben-core/shadcn-ui'; } from '@vben-core/shadcn-ui';
import { useMagicKeys, whenever } from '@vueuse/core'; import { useMagicKeys, whenever } from '@vueuse/core';
import { computed, useTemplateRef, watch } from 'vue';
import { LockScreenModal } from '../lock-screen'; import { LockScreenModal } from '../lock-screen';
@@ -78,7 +82,7 @@ const emit = defineEmits<{ logout: [] }>();
const { globalLockScreenShortcutKey, globalLogoutShortcutKey } = const { globalLockScreenShortcutKey, globalLogoutShortcutKey } =
usePreferences(); usePreferences();
const lockStore = useLockStore(); const accessStore = useAccessStore();
const [LockModal, lockModalApi] = useVbenModal({ const [LockModal, lockModalApi] = useVbenModal({
connectedComponent: LockScreenModal, connectedComponent: LockScreenModal,
}); });
@@ -129,7 +133,7 @@ function handleOpenLock() {
function handleSubmitLock(lockScreenPassword: string) { function handleSubmitLock(lockScreenPassword: string) {
lockModalApi.close(); lockModalApi.close();
lockStore.lockScreen(lockScreenPassword); accessStore.lockScreen(lockScreenPassword);
} }
function handleLogout() { function handleLogout() {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/plugins", "name": "@vben/plugins",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -24,8 +24,8 @@ export function useVbenVxeGrid(options: VxeGridProps) {
return () => h(VxeGrid, { ...props, ...attrs, api: extendedApi }, slots); return () => h(VxeGrid, { ...props, ...attrs, api: extendedApi }, slots);
}, },
{ {
inheritAttrs: false,
name: 'VbenVxeGrid', name: 'VbenVxeGrid',
inheritAttrs: false,
}, },
); );
// Add reactivity support // Add reactivity support

View File

@@ -150,7 +150,9 @@ const toolbarOptions = computed(() => {
icon: 'vxe-icon-search', icon: 'vxe-icon-search',
circle: true, circle: true,
status: showSearchForm.value ? 'primary' : undefined, status: showSearchForm.value ? 'primary' : undefined,
title: $t('common.search'), title: showSearchForm.value
? $t('common.hideSearchPanel')
: $t('common.showSearchPanel'),
}; };
// 将搜索按钮合并到用户配置的toolbarConfig.tools中 // 将搜索按钮合并到用户配置的toolbarConfig.tools中
const toolbarConfig: VxeGridPropTypes.ToolbarConfig = { const toolbarConfig: VxeGridPropTypes.ToolbarConfig = {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/request", "name": "@vben/request",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/icons", "name": "@vben/icons",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/locales", "name": "@vben/locales",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -18,5 +18,7 @@
"delete": "Delete", "delete": "Delete",
"create": "Create", "create": "Create",
"yes": "Yes", "yes": "Yes",
"no": "No" "no": "No",
"showSearchPanel": "Show search panel",
"hideSearchPanel": "Hide search panel"
} }

View File

@@ -18,5 +18,7 @@
"delete": "删除", "delete": "删除",
"create": "新增", "create": "新增",
"yes": "是", "yes": "是",
"no": "否" "no": "否",
"showSearchPanel": "显示搜索面板",
"hideSearchPanel": "隐藏搜索面板"
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/preferences", "name": "@vben/preferences",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/stores", "name": "@vben/stores",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {
@@ -25,6 +25,7 @@
"@vben-core/typings": "workspace:*", "@vben-core/typings": "workspace:*",
"pinia": "catalog:", "pinia": "catalog:",
"pinia-plugin-persistedstate": "catalog:", "pinia-plugin-persistedstate": "catalog:",
"secure-ls": "catalog:",
"vue": "catalog:", "vue": "catalog:",
"vue-router": "catalog:" "vue-router": "catalog:"
} }

View File

@@ -1,6 +1,7 @@
import type { MenuRecordRaw } from '@vben-core/typings';
import type { RouteRecordRaw } from 'vue-router'; import type { RouteRecordRaw } from 'vue-router';
import type { MenuRecordRaw } from '@vben-core/typings';
import { acceptHMRUpdate, defineStore } from 'pinia'; import { acceptHMRUpdate, defineStore } from 'pinia';
type AccessToken = null | string; type AccessToken = null | string;
@@ -26,6 +27,14 @@ interface AccessState {
* 是否已经检查过权限 * 是否已经检查过权限
*/ */
isAccessChecked: boolean; isAccessChecked: boolean;
/**
* 是否锁屏状态
*/
isLockScreen: boolean;
/**
* 锁屏密码
*/
lockScreenPassword?: string;
/** /**
* 登录是否过期 * 登录是否过期
*/ */
@@ -60,6 +69,10 @@ export const useAccessStore = defineStore('core-access', {
} }
return findMenu(this.accessMenus, path); return findMenu(this.accessMenus, path);
}, },
lockScreen(password: string) {
this.isLockScreen = true;
this.lockScreenPassword = password;
},
setAccessCodes(codes: string[]) { setAccessCodes(codes: string[]) {
this.accessCodes = codes; this.accessCodes = codes;
}, },
@@ -81,10 +94,20 @@ export const useAccessStore = defineStore('core-access', {
setRefreshToken(token: AccessToken) { setRefreshToken(token: AccessToken) {
this.refreshToken = token; this.refreshToken = token;
}, },
unlockScreen() {
this.isLockScreen = false;
this.lockScreenPassword = undefined;
},
}, },
persist: { persist: {
// 持久化 // 持久化
pick: ['accessToken', 'refreshToken', 'accessCodes'], pick: [
'accessToken',
'refreshToken',
'accessCodes',
'isLockScreen',
'lockScreenPassword',
],
}, },
state: (): AccessState => ({ state: (): AccessState => ({
accessCodes: [], accessCodes: [],
@@ -92,6 +115,8 @@ export const useAccessStore = defineStore('core-access', {
accessRoutes: [], accessRoutes: [],
accessToken: null, accessToken: null,
isAccessChecked: false, isAccessChecked: false,
isLockScreen: false,
lockScreenPassword: undefined,
loginExpired: false, loginExpired: false,
refreshToken: null, refreshToken: null,
}), }),

View File

@@ -1,4 +1,3 @@
export * from './access'; export * from './access';
export * from './lock';
export * from './tabbar'; export * from './tabbar';
export * from './user'; export * from './user';

View File

@@ -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();
});
});

View File

@@ -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,
}),
});

View File

@@ -3,6 +3,7 @@ import type { Pinia } from 'pinia';
import type { App } from 'vue'; import type { App } from 'vue';
import { createPinia } from 'pinia'; import { createPinia } from 'pinia';
import SecureLS from 'secure-ls';
let pinia: Pinia; let pinia: Pinia;
@@ -20,11 +21,27 @@ export async function initStores(app: App, options: InitStoreOptions) {
const { createPersistedState } = await import('pinia-plugin-persistedstate'); const { createPersistedState } = await import('pinia-plugin-persistedstate');
pinia = createPinia(); pinia = createPinia();
const { namespace } = options; 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( pinia.use(
createPersistedState({ createPersistedState({
// key $appName-$store.id // key $appName-$store.id
key: (storeKey) => `${namespace}-${storeKey}`, 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); app.use(pinia);

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/styles", "name": "@vben/styles",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/types", "name": "@vben/types",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/utils", "name": "@vben/utils",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -3,3 +3,6 @@ VITE_APP_TITLE=Vben Admin
# 应用命名空间用于缓存、store等功能的前缀确保隔离 # 应用命名空间用于缓存、store等功能的前缀确保隔离
VITE_APP_NAMESPACE=vben-web-play VITE_APP_NAMESPACE=vben-web-play
# 对store进行加密的密钥在将store持久化到localStorage时会使用该密钥进行加密
VITE_APP_STORE_SECURE_KEY=please-replace-me-with-your-own-key

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/playground", "name": "@vben/playground",
"version": "5.5.4", "version": "5.5.5",
"homepage": "https://vben.pro", "homepage": "https://vben.pro",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {

View File

@@ -5,9 +5,27 @@ import { useVbenDrawer } from '@vben/common-ui';
import { Input, message } from 'ant-design-vue'; import { Input, message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
const value = ref(''); const value = ref('');
const [Form] = useVbenForm({
schema: [
{
component: 'Input',
componentProps: {
placeholder: 'KeepAlive测试内部组件',
},
fieldName: 'field1',
hideLabel: true,
label: '字段1',
},
],
showDefaultActions: false,
});
const [Drawer, drawerApi] = useVbenDrawer({ const [Drawer, drawerApi] = useVbenDrawer({
destroyOnClose: false,
onCancel() { onCancel() {
drawerApi.close(); drawerApi.close();
}, },
@@ -20,7 +38,11 @@ const [Drawer, drawerApi] = useVbenDrawer({
<template> <template>
<Drawer append-to-main title="基础抽屉示例" title-tooltip="标题提示内容"> <Drawer append-to-main title="基础抽屉示例" title-tooltip="标题提示内容">
<template #extra> extra </template> <template #extra> extra </template>
本抽屉指定在内容区域打开 此弹窗指定在内容区域打开并且在关闭之后弹窗内容不会被销毁
<Input v-model="value" placeholder="KeepAlive测试" /> <Input
v-model:value="value"
placeholder="KeepAlive测试:connectedComponent"
/>
<Form />
</Drawer> </Drawer>
</template> </template>

View File

@@ -13,30 +13,30 @@ packages:
- docs - docs
- playground - playground
catalog: catalog:
'@ast-grep/napi': ^0.32.3 '@ast-grep/napi': ^0.37.0
'@changesets/changelog-github': ^0.5.1 '@changesets/changelog-github': ^0.5.1
'@changesets/cli': ^2.28.1 '@changesets/cli': ^2.29.2
'@changesets/git': ^3.0.2 '@changesets/git': ^3.0.4
'@clack/prompts': ^0.9.1 '@clack/prompts': ^0.10.1
'@commitlint/cli': ^19.8.0 '@commitlint/cli': ^19.8.0
'@commitlint/config-conventional': ^19.8.0 '@commitlint/config-conventional': ^19.8.0
'@ctrl/tinycolor': ^4.1.0 '@ctrl/tinycolor': ^4.1.0
'@eslint/js': ^9.24.0 '@eslint/js': ^9.25.1
'@faker-js/faker': ^9.6.0 '@faker-js/faker': ^9.7.0
'@iconify/json': ^2.2.324 '@iconify/json': ^2.2.332
'@iconify/tailwind': ^1.2.0 '@iconify/tailwind': ^1.2.0
'@iconify/vue': ^4.3.0 '@iconify/vue': ^4.3.0
'@intlify/core-base': ^11.1.3 '@intlify/core-base': ^11.1.3
'@intlify/unplugin-vue-i18n': ^6.0.5 '@intlify/unplugin-vue-i18n': ^6.0.8
'@jspm/generator': ^2.5.1 '@jspm/generator': ^2.5.1
'@manypkg/get-packages': ^2.2.2 '@manypkg/get-packages': ^2.2.2
'@nolebase/vitepress-plugin-git-changelog': ^2.16.0 '@nolebase/vitepress-plugin-git-changelog': ^2.16.0
'@playwright/test': ^1.51.1 '@playwright/test': ^1.52.0
'@pnpm/workspace.read-manifest': ^1000.1.3 '@pnpm/workspace.read-manifest': ^1000.1.4
'@stylistic/stylelint-plugin': ^3.1.2 '@stylistic/stylelint-plugin': ^3.1.2
'@tailwindcss/nesting': 0.0.0-insiders.565cd3e '@tailwindcss/nesting': 0.0.0-insiders.565cd3e
'@tailwindcss/typography': ^0.5.16 '@tailwindcss/typography': ^0.5.16
'@tanstack/vue-query': ^5.72.0 '@tanstack/vue-query': ^5.74.6
'@tanstack/vue-store': ^0.7.0 '@tanstack/vue-store': ^0.7.0
'@types/archiver': ^6.0.3 '@types/archiver': ^6.0.3
'@types/eslint': ^9.6.1 '@types/eslint': ^9.6.1
@@ -46,28 +46,28 @@ catalog:
'@types/lodash.get': ^4.4.9 '@types/lodash.get': ^4.4.9
'@types/lodash.isequal': ^4.5.8 '@types/lodash.isequal': ^4.5.8
'@types/lodash.set': ^4.3.9 '@types/lodash.set': ^4.3.9
'@types/node': ^22.14.0 '@types/node': ^22.15.2
'@types/nprogress': ^0.2.3 '@types/nprogress': ^0.2.3
'@types/postcss-import': ^14.0.3 '@types/postcss-import': ^14.0.3
'@types/qrcode': ^1.5.5 '@types/qrcode': ^1.5.5
'@types/qs': ^6.9.18 '@types/qs': ^6.9.18
'@types/sortablejs': ^1.15.8 '@types/sortablejs': ^1.15.8
'@typescript-eslint/eslint-plugin': ^8.29.1 '@typescript-eslint/eslint-plugin': ^8.31.0
'@typescript-eslint/parser': ^8.29.1 '@typescript-eslint/parser': ^8.31.0
'@vee-validate/zod': ^4.15.0 '@vee-validate/zod': ^4.15.0
'@vite-pwa/vitepress': ^0.5.4 '@vite-pwa/vitepress': ^1.0.0
'@vitejs/plugin-vue': ^5.2.3 '@vitejs/plugin-vue': ^5.2.3
'@vitejs/plugin-vue-jsx': ^4.1.2 '@vitejs/plugin-vue-jsx': ^4.1.2
'@vue/reactivity': ^3.5.13 '@vue/reactivity': ^3.5.13
'@vue/shared': ^3.5.13 '@vue/shared': ^3.5.13
'@vue/test-utils': ^2.4.6 '@vue/test-utils': ^2.4.6
'@vueuse/core': ^12.8.2 '@vueuse/core': ^13.1.0
'@vueuse/motion': ^2.2.6 '@vueuse/motion': ^3.0.3
'@vueuse/integrations': ^12.8.2 '@vueuse/integrations': ^13.1.0
ant-design-vue: ^4.2.6 ant-design-vue: ^4.2.6
archiver: ^7.0.1 archiver: ^7.0.1
autoprefixer: ^10.4.21 autoprefixer: ^10.4.21
axios: ^1.8.4 axios: ^1.9.0
axios-mock-adapter: ^2.1.0 axios-mock-adapter: ^2.1.0
cac: ^6.7.14 cac: ^6.7.14
chalk: ^5.4.1 chalk: ^5.4.1
@@ -85,107 +85,108 @@ catalog:
dayjs: ^1.11.13 dayjs: ^1.11.13
defu: ^6.1.4 defu: ^6.1.4
depcheck: ^1.4.7 depcheck: ^1.4.7
dotenv: ^16.4.7 dotenv: ^16.5.0
echarts: ^5.6.0 echarts: ^5.6.0
element-plus: ^2.9.7 element-plus: ^2.9.9
eslint: ^9.24.0 eslint: ^9.25.1
eslint-config-turbo: ^2.5.0 eslint-config-turbo: ^2.5.2
eslint-plugin-command: ^0.2.7 eslint-plugin-command: ^3.2.0
eslint-plugin-eslint-comments: ^3.2.0 eslint-plugin-eslint-comments: ^3.2.0
eslint-plugin-import-x: ^4.10.2 eslint-plugin-import-x: ^4.11.0
eslint-plugin-jsdoc: ^50.6.9 eslint-plugin-jsdoc: ^50.6.11
eslint-plugin-jsonc: ^2.20.0 eslint-plugin-jsonc: ^2.20.0
eslint-plugin-n: ^17.17.0 eslint-plugin-n: ^17.17.0
eslint-plugin-no-only-tests: ^3.3.0 eslint-plugin-no-only-tests: ^3.3.0
eslint-plugin-perfectionist: ^4.11.0 eslint-plugin-perfectionist: ^4.12.3
eslint-plugin-prettier: ^5.2.6 eslint-plugin-prettier: ^5.2.6
eslint-plugin-regexp: ^2.7.0 eslint-plugin-regexp: ^2.7.0
eslint-plugin-unicorn: ^56.0.1 eslint-plugin-unicorn: ^59.0.0
eslint-plugin-unused-imports: ^4.1.4 eslint-plugin-unused-imports: ^4.1.4
eslint-plugin-vitest: ^0.5.4 eslint-plugin-vitest: ^0.5.4
eslint-plugin-vue: ^9.33.0 eslint-plugin-vue: ^10.0.0
execa: ^9.5.2 execa: ^9.5.2
find-up: ^7.0.0 find-up: ^7.0.0
get-port: ^7.1.0 get-port: ^7.1.0
globals: ^15.15.0 globals: ^16.0.0
h3: ^1.15.1 h3: ^1.15.1
happy-dom: ^16.8.1 happy-dom: ^17.4.4
html-minifier-terser: ^7.2.0 html-minifier-terser: ^7.2.0
husky: ^9.1.7 husky: ^9.1.7
is-ci: ^4.1.0 is-ci: ^4.1.0
jsonc-eslint-parser: ^2.4.0 jsonc-eslint-parser: ^2.4.0
jsonwebtoken: ^9.0.2 jsonwebtoken: ^9.0.2
lint-staged: ^15.5.0 lint-staged: ^15.5.1
lodash.clonedeep: ^4.5.0 lodash.clonedeep: ^4.5.0
lodash.get: ^4.4.2 lodash.get: ^4.4.2
lodash.set: ^4.3.2 lodash.set: ^4.3.2
lodash.isequal: ^4.5.0 lodash.isequal: ^4.5.0
lucide-vue-next: ^0.469.0 lucide-vue-next: ^0.503.0
medium-zoom: ^1.1.0 medium-zoom: ^1.1.0
naive-ui: ^2.41.0 naive-ui: ^2.41.0
nitropack: ^2.11.8 nitropack: ^2.11.9
nprogress: ^0.2.0 nprogress: ^0.2.0
ora: ^8.2.0 ora: ^8.2.0
pinia: ^2.3.1 pinia: ^3.0.2
pinia-plugin-persistedstate: ^4.2.0 pinia-plugin-persistedstate: ^4.2.0
pkg-types: ^1.3.1 pkg-types: ^2.1.0
playwright: ^1.51.1 playwright: ^1.52.0
postcss: ^8.5.3 postcss: ^8.5.3
postcss-antd-fixes: ^0.2.0 postcss-antd-fixes: ^0.2.0
postcss-html: ^1.8.0 postcss-html: ^1.8.0
postcss-import: ^16.1.0 postcss-import: ^16.1.0
postcss-preset-env: ^10.1.5 postcss-preset-env: ^10.1.6
postcss-scss: ^4.0.9 postcss-scss: ^4.0.9
prettier: ^3.5.3 prettier: ^3.5.3
prettier-plugin-tailwindcss: ^0.6.11 prettier-plugin-tailwindcss: ^0.6.11
publint: ^0.2.12 publint: ^0.3.12
qrcode: ^1.5.4 qrcode: ^1.5.4
qs: ^6.14.0 qs: ^6.14.0
radix-vue: ^1.9.17 radix-vue: ^1.9.17
resolve.exports: ^2.0.3 resolve.exports: ^2.0.3
rimraf: ^6.0.1 rimraf: ^6.0.1
rollup: ^4.39.0 rollup: ^4.40.0
rollup-plugin-visualizer: ^5.14.0 rollup-plugin-visualizer: ^5.14.0
sass: ^1.86.3 sass: ^1.87.0
secure-ls: ^2.0.0
sortablejs: ^1.15.6 sortablejs: ^1.15.6
stylelint: ^16.18.0 stylelint: ^16.19.1
stylelint-config-recess-order: ^5.1.1 stylelint-config-recess-order: ^6.0.0
stylelint-config-recommended: ^14.0.1 stylelint-config-recommended: ^16.0.0
stylelint-config-recommended-scss: ^14.1.0 stylelint-config-recommended-scss: ^14.1.0
stylelint-config-recommended-vue: ^1.6.0 stylelint-config-recommended-vue: ^1.6.0
stylelint-config-standard: ^36.0.1 stylelint-config-standard: ^38.0.0
stylelint-order: ^6.0.4 stylelint-order: ^7.0.0
stylelint-prettier: ^5.0.3 stylelint-prettier: ^5.0.3
stylelint-scss: ^6.11.1 stylelint-scss: ^6.11.1
tailwind-merge: ^2.6.0 tailwind-merge: ^2.6.0
tailwindcss: ^3.4.17 tailwindcss: ^3.4.17
tailwindcss-animate: ^1.0.7 tailwindcss-animate: ^1.0.7
theme-colors: ^0.1.0 theme-colors: ^0.1.0
tippy.js: ^6.2.5 tippy.js: ^6.3.7
turbo: ^2.5.0 turbo: ^2.5.2
typescript: ^5.8.3 typescript: ^5.8.3
unbuild: ^3.5.0 unbuild: ^3.5.0
unplugin-element-plus: ^0.9.1 unplugin-element-plus: ^0.10.0
vee-validate: ^4.15.0 vee-validate: ^4.15.0
vite: ^6.2.5 vite: ^6.3.3
vite-plugin-compression: ^0.5.1 vite-plugin-compression: ^0.5.1
vite-plugin-dts: ^4.5.3 vite-plugin-dts: ^4.5.3
vite-plugin-html: ^3.2.2 vite-plugin-html: ^3.2.2
vite-plugin-lazy-import: ^1.0.7 vite-plugin-lazy-import: ^1.0.7
vite-plugin-pwa: ^0.21.2 vite-plugin-pwa: ^1.0.0
vite-plugin-vue-devtools: ^7.7.2 vite-plugin-vue-devtools: ^7.7.5
vitepress: ^1.6.3 vitepress: ^1.6.3
vitepress-plugin-group-icons: ^1.3.8 vitepress-plugin-group-icons: ^1.5.2
vitest: ^2.1.9 vitest: ^3.1.2
vue: ^3.5.13 vue: ^3.5.13
vue-eslint-parser: ^9.4.3 vue-eslint-parser: ^10.1.3
vue-i18n: ^11.1.3 vue-i18n: ^11.1.3
vue-json-viewer: ^3.0.4 vue-json-viewer: ^3.0.4
vue-router: ^4.5.0 vue-router: ^4.5.1
vue-tippy: ^6.7.0 vue-tippy: ^6.7.0
vue-tsc: 2.1.10 vue-tsc: 2.1.10
vxe-pc-ui: ^4.5.14 vxe-pc-ui: ^4.5.14
vxe-table: ^4.12.5 vxe-table: ^4.12.5
watermark-js-plus: ^1.5.8 watermark-js-plus: ^1.6.0
zod: ^3.24.2 zod: ^3.24.3
zod-defaults: ^0.1.3 zod-defaults: ^0.1.3

View File

@@ -6,7 +6,7 @@ ENV PATH="$PNPM_HOME:$PATH"
ENV NODE_OPTIONS=--max-old-space-size=8192 ENV NODE_OPTIONS=--max-old-space-size=8192
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai
RUN corepack enable RUN npm i -g corepack
WORKDIR /app WORKDIR /app

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/turbo-run", "name": "@vben/turbo-run",
"version": "5.5.4", "version": "5.5.5",
"private": true, "private": true,
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vben/vsh", "name": "@vben/vsh",
"version": "5.5.4", "version": "5.5.5",
"private": true, "private": true,
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",