This commit is contained in:
dap 2024-10-17 13:36:03 +08:00
commit 70e7d6a131
54 changed files with 357 additions and 319 deletions

View File

@ -1,2 +0,0 @@
export * from './form';
export * from './vxe-table';

View File

@ -45,14 +45,14 @@ async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
async function loadDayjsLocale(lang: SupportedLanguagesType) { async function loadDayjsLocale(lang: SupportedLanguagesType) {
let locale; let locale;
switch (lang) { switch (lang) {
case 'zh-CN': {
locale = await import('dayjs/locale/zh-cn');
break;
}
case 'en-US': { case 'en-US': {
locale = await import('dayjs/locale/en'); locale = await import('dayjs/locale/en');
break; break;
} }
case 'zh-CN': {
locale = await import('dayjs/locale/zh-cn');
break;
}
// 默认使用英语 // 默认使用英语
default: { default: {
locale = await import('dayjs/locale/en'); locale = await import('dayjs/locale/en');
@ -71,14 +71,14 @@ async function loadDayjsLocale(lang: SupportedLanguagesType) {
*/ */
async function loadAntdLocale(lang: SupportedLanguagesType) { async function loadAntdLocale(lang: SupportedLanguagesType) {
switch (lang) { switch (lang) {
case 'zh-CN': {
antdLocale.value = antdDefaultLocale;
break;
}
case 'en-US': { case 'en-US': {
antdLocale.value = antdEnLocale; antdLocale.value = antdEnLocale;
break; break;
} }
case 'zh-CN': {
antdLocale.value = antdDefaultLocale;
break;
}
} }
} }

View File

@ -1,2 +0,0 @@
export * from './form';
export * from './vxe-table';

View File

@ -45,14 +45,14 @@ async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
async function loadDayjsLocale(lang: SupportedLanguagesType) { async function loadDayjsLocale(lang: SupportedLanguagesType) {
let locale; let locale;
switch (lang) { switch (lang) {
case 'zh-CN': {
locale = await import('dayjs/locale/zh-cn');
break;
}
case 'en-US': { case 'en-US': {
locale = await import('dayjs/locale/en'); locale = await import('dayjs/locale/en');
break; break;
} }
case 'zh-CN': {
locale = await import('dayjs/locale/zh-cn');
break;
}
// 默认使用英语 // 默认使用英语
default: { default: {
locale = await import('dayjs/locale/en'); locale = await import('dayjs/locale/en');
@ -71,14 +71,14 @@ async function loadDayjsLocale(lang: SupportedLanguagesType) {
*/ */
async function loadElementLocale(lang: SupportedLanguagesType) { async function loadElementLocale(lang: SupportedLanguagesType) {
switch (lang) { switch (lang) {
case 'zh-CN': {
elementLocale.value = defaultLocale;
break;
}
case 'en-US': { case 'en-US': {
elementLocale.value = enLocale; elementLocale.value = enLocale;
break; break;
} }
case 'zh-CN': {
elementLocale.value = defaultLocale;
break;
}
} }
} }

View File

@ -1,3 +0,0 @@
export * from './form';
export * from './naive';
export * from './vxe-table';

View File

@ -12,7 +12,7 @@ import {
} from '@vben/request'; } from '@vben/request';
import { useAccessStore } from '@vben/stores'; import { useAccessStore } from '@vben/stores';
import { message } from '#/adapter'; import { message } from '#/adapter/naive';
import { useAuthStore } from '#/store'; import { useAuthStore } from '#/store';
import { refreshTokenApi } from './core'; import { refreshTokenApi } from './core';

View File

@ -6,7 +6,7 @@ import type {
import { generateAccessible } from '@vben/access'; import { generateAccessible } from '@vben/access';
import { preferences } from '@vben/preferences'; import { preferences } from '@vben/preferences';
import { message } from '#/adapter'; import { message } from '#/adapter/naive';
import { getAllMenusApi } from '#/api'; import { getAllMenusApi } from '#/api';
import { BasicLayout, IFrameView } from '#/layouts'; import { BasicLayout, IFrameView } from '#/layouts';
import { $t } from '#/locales'; import { $t } from '#/locales';

View File

@ -9,7 +9,7 @@ import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { notification } from '#/adapter'; import { notification } from '#/adapter/naive';
import { getAccessCodesApi, getUserInfoApi, loginApi, logoutApi } from '#/api'; import { getAccessCodesApi, getUserInfoApi, loginApi, logoutApi } from '#/api';
import { $t } from '#/locales'; import { $t } from '#/locales';

View File

@ -1,3 +1,4 @@
import '@vben/styles';
import './variables.css'; import './variables.css';
import './base.css'; import './base.css';
import '@vben/styles';

View File

@ -258,7 +258,7 @@ _注意_ 需要指定 `dependencies` 的 `triggerFields` 属性,设置由谁
```vue ```vue
<script setup lang="ts"> <script setup lang="ts">
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
// Form 为弹窗组件 // Form 为弹窗组件
// formApi 为弹窗的方法 // formApi 为弹窗的方法
@ -475,7 +475,7 @@ rules的值可以是一个字符串也可以是一个zod的schema。
rules也支持 zod 的 schema可以进行更复杂的校验zod 的使用请查看 [zod文档](https://zod.dev/)。 rules也支持 zod 的 schema可以进行更复杂的校验zod 的使用请查看 [zod文档](https://zod.dev/)。
```ts ```ts
import { z } from '#/adapter'; import { z } from '#/adapter/form';
// 基础类型 // 基础类型
{ {

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { Button, message, Space } from 'ant-design-vue'; import { Button, message, Space } from 'ant-design-vue';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
const [BaseForm, formApi] = useVbenForm({ const [BaseForm, formApi] = useVbenForm({
// //
@ -81,6 +81,97 @@ function handleClick(
| 'updateSubmitButton', | 'updateSubmitButton',
) { ) {
switch (action) { switch (action) {
case 'batchAddSchema': {
formApi.setState((prev) => {
const currentSchema = prev?.schema ?? [];
const newSchema = [];
for (let i = 0; i < 2; i++) {
newSchema.push({
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: `field${i}${Date.now()}`,
label: `field+`,
});
}
return {
schema: [...currentSchema, ...newSchema],
};
});
break;
}
case 'batchDeleteSchema': {
formApi.setState((prev) => {
const currentSchema = prev?.schema ?? [];
return {
schema: currentSchema.slice(0, -2),
};
});
break;
}
case 'disabled': {
formApi.setState({ commonConfig: { disabled: true } });
break;
}
case 'hiddenAction': {
formApi.setState({ showDefaultActions: false });
break;
}
case 'hiddenResetButton': {
formApi.setState({ resetButtonOptions: { show: false } });
break;
}
case 'hiddenSubmitButton': {
formApi.setState({ submitButtonOptions: { show: false } });
break;
}
case 'labelWidth': {
formApi.setState({
commonConfig: {
labelWidth: 150,
},
});
break;
}
case 'resetDisabled': {
formApi.setState({ commonConfig: { disabled: false } });
break;
}
case 'resetLabelWidth': {
formApi.setState({
commonConfig: {
labelWidth: 100,
},
});
break;
}
case 'showAction': {
formApi.setState({ showDefaultActions: true });
break;
}
case 'showResetButton': {
formApi.setState({ resetButtonOptions: { show: true } });
break;
}
case 'showSubmitButton': {
formApi.setState({ submitButtonOptions: { show: true } });
break;
}
case 'updateActionAlign': {
formApi.setState({
// class
actionWrapperClass: 'text-center',
});
break;
}
case 'updateResetButton': {
formApi.setState({
resetButtonOptions: { disabled: true },
});
break;
}
case 'updateSchema': { case 'updateSchema': {
formApi.updateSchema([ formApi.updateSchema([
{ {
@ -106,103 +197,12 @@ function handleClick(
message.success('字段 `fieldOptions` 下拉选项更新成功。'); message.success('字段 `fieldOptions` 下拉选项更新成功。');
break; break;
} }
case 'labelWidth': {
formApi.setState({
commonConfig: {
labelWidth: 150,
},
});
break;
}
case 'resetLabelWidth': {
formApi.setState({
commonConfig: {
labelWidth: 100,
},
});
break;
}
case 'disabled': {
formApi.setState({ commonConfig: { disabled: true } });
break;
}
case 'resetDisabled': {
formApi.setState({ commonConfig: { disabled: false } });
break;
}
case 'hiddenAction': {
formApi.setState({ showDefaultActions: false });
break;
}
case 'showAction': {
formApi.setState({ showDefaultActions: true });
break;
}
case 'hiddenResetButton': {
formApi.setState({ resetButtonOptions: { show: false } });
break;
}
case 'showResetButton': {
formApi.setState({ resetButtonOptions: { show: true } });
break;
}
case 'hiddenSubmitButton': {
formApi.setState({ submitButtonOptions: { show: false } });
break;
}
case 'showSubmitButton': {
formApi.setState({ submitButtonOptions: { show: true } });
break;
}
case 'updateResetButton': {
formApi.setState({
resetButtonOptions: { disabled: true },
});
break;
}
case 'updateSubmitButton': { case 'updateSubmitButton': {
formApi.setState({ formApi.setState({
submitButtonOptions: { loading: true }, submitButtonOptions: { loading: true },
}); });
break; break;
} }
case 'updateActionAlign': {
formApi.setState({
// class
actionWrapperClass: 'text-center',
});
break;
}
case 'batchAddSchema': {
formApi.setState((prev) => {
const currentSchema = prev?.schema ?? [];
const newSchema = [];
for (let i = 0; i < 2; i++) {
newSchema.push({
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: `field${i}${Date.now()}`,
label: `field+`,
});
}
return {
schema: [...currentSchema, ...newSchema],
};
});
break;
}
case 'batchDeleteSchema': {
formApi.setState((prev) => {
const currentSchema = prev?.schema ?? [];
return {
schema: currentSchema.slice(0, -2),
};
});
break;
}
} }
} }
</script> </script>

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
const [BaseForm] = useVbenForm({ const [BaseForm] = useVbenForm({
// //

View File

@ -3,7 +3,7 @@ import { h } from 'vue';
import { Input, message } from 'ant-design-vue'; import { Input, message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
const [Form] = useVbenForm({ const [Form] = useVbenForm({
// //

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
const [Form] = useVbenForm({ const [Form] = useVbenForm({
// //

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
const [QueryForm] = useVbenForm({ const [QueryForm] = useVbenForm({
// //

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { useVbenForm, z } from '#/adapter'; import { useVbenForm, z } from '#/adapter/form';
const [Form] = useVbenForm({ const [Form] = useVbenForm({
// //

View File

@ -105,6 +105,7 @@ const customConfig: Linter.Config[] = [
], ],
}, },
}, },
{ {
// 不能引入@vben/*里面的包 // 不能引入@vben/*里面的包
files: [ files: [

View File

@ -28,7 +28,7 @@
"build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 turbo build", "build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 turbo build",
"build:analyze": "turbo build:analyze", "build:analyze": "turbo build:analyze",
"build:antd": "pnpm run build --filter=@vben/web-antd", "build:antd": "pnpm run build --filter=@vben/web-antd",
"build:docker": "./build-local-docker-image.sh", "build:docker": "./scripts/deploy/build-local-docker-image.sh",
"build:docs": "pnpm run build --filter=@vben/docs", "build:docs": "pnpm run build --filter=@vben/docs",
"build:ele": "pnpm run build --filter=@vben/web-ele", "build:ele": "pnpm run build --filter=@vben/web-ele",
"build:naive": "pnpm run build --filter=@vben/web-naive", "build:naive": "pnpm run build --filter=@vben/web-naive",

View File

@ -1,7 +1,8 @@
import './design-tokens';
import './css/global.css'; import './css/global.css';
import './css/transition.css'; import './css/transition.css';
import './css/nprogress.css'; import './css/nprogress.css';
import './css/ui.css'; import './css/ui.css';
import './design-tokens';
export {}; export {};

View File

@ -93,7 +93,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
"mode": "dark", "mode": "dark",
"radius": "0.5", "radius": "0.5",
"semiDarkHeader": false, "semiDarkHeader": false,
"semiDarkSidebar": true, "semiDarkSidebar": false,
}, },
"transition": { "transition": {
"enable": true, "enable": true,

View File

@ -82,7 +82,6 @@ const defaultPreferences: Preferences = {
showIcon: true, showIcon: true,
showMaximize: true, showMaximize: true,
showMore: true, showMore: true,
styleType: 'chrome', styleType: 'chrome',
}, },
theme: { theme: {
@ -94,7 +93,7 @@ const defaultPreferences: Preferences = {
mode: 'auto', mode: 'auto',
radius: '0.5', radius: '0.5',
semiDarkHeader: false, semiDarkHeader: false,
semiDarkSidebar: true, semiDarkSidebar: false,
}, },
transition: { transition: {
enable: true, enable: true,

View File

@ -18,7 +18,7 @@ function updateCSSVariables(preferences: Preferences) {
const theme = preferences?.theme ?? {}; const theme = preferences?.theme ?? {};
const { builtinType, colorPrimary, mode, radius } = theme; const { builtinType, mode, radius } = theme;
// html 设置 dark 类 // html 设置 dark 类
if (Reflect.has(theme, 'mode')) { if (Reflect.has(theme, 'mode')) {
@ -58,7 +58,7 @@ function updateCSSVariables(preferences: Preferences) {
Reflect.has(theme, 'colorSuccess') || Reflect.has(theme, 'colorSuccess') ||
Reflect.has(theme, 'colorWarning') Reflect.has(theme, 'colorWarning')
) { ) {
preferences.theme.colorPrimary = builtinTypeColorPrimary || colorPrimary; // preferences.theme.colorPrimary = builtinTypeColorPrimary || colorPrimary;
updateMainColorVariables(preferences); updateMainColorVariables(preferences);
} }

View File

@ -83,6 +83,9 @@ watch(
" "
:style="queryFormStyle" :style="queryFormStyle"
> >
<!-- 重置按钮前 -->
<slot name="reset-before"></slot>
<component <component
:is="COMPONENT_MAP.DefaultButton" :is="COMPONENT_MAP.DefaultButton"
v-if="resetButtonOptions.show" v-if="resetButtonOptions.show"
@ -94,6 +97,9 @@ watch(
{{ resetButtonOptions.content }} {{ resetButtonOptions.content }}
</component> </component>
<!-- 提交按钮前 -->
<slot name="submit-before"></slot>
<component <component
:is="COMPONENT_MAP.PrimaryButton" :is="COMPONENT_MAP.PrimaryButton"
v-if="submitButtonOptions.show" v-if="submitButtonOptions.show"
@ -104,6 +110,9 @@ watch(
{{ submitButtonOptions.content }} {{ submitButtonOptions.content }}
</component> </component>
<!-- 展开按钮前 -->
<slot name="expand-before"></slot>
<VbenExpandableArrow <VbenExpandableArrow
v-if="rootProps.showCollapseButton" v-if="rootProps.showCollapseButton"
v-model:model-value="collapsed" v-model:model-value="collapsed"
@ -111,5 +120,8 @@ watch(
> >
<span>{{ collapsed ? $t('expand') : $t('collapse') }}</span> <span>{{ collapsed ? $t('expand') : $t('collapse') }}</span>
</VbenExpandableArrow> </VbenExpandableArrow>
<!-- 展开按钮后 -->
<slot name="expand-after"></slot>
</div> </div>
</template> </template>

View File

@ -58,7 +58,20 @@ const handleUpdateCollapsed = (value: boolean) => {
v-if="forward.showDefaultActions" v-if="forward.showDefaultActions"
:model-value="state.collapsed" :model-value="state.collapsed"
@update:model-value="handleUpdateCollapsed" @update:model-value="handleUpdateCollapsed"
/> >
<template #reset-before="resetSlotProps">
<slot name="reset-before" v-bind="resetSlotProps"></slot>
</template>
<template #submit-before="submitSlotProps">
<slot name="submit-before" v-bind="submitSlotProps"></slot>
</template>
<template #expand-before="expandBeforeSlotProps">
<slot name="expand-before" v-bind="expandBeforeSlotProps"></slot>
</template>
<template #expand-after="expandAfterSlotProps">
<slot name="expand-after" v-bind="expandAfterSlotProps"></slot>
</template>
</FormActions>
</slot> </slot>
</template> </template>
</Form> </Form>

View File

@ -53,6 +53,10 @@ async function generateRoutes(
let resultRoutes: RouteRecordRaw[] = routes; let resultRoutes: RouteRecordRaw[] = routes;
switch (mode) { switch (mode) {
case 'backend': {
resultRoutes = await generateRoutesByBackend(options);
break;
}
case 'frontend': { case 'frontend': {
resultRoutes = await generateRoutesByFrontend( resultRoutes = await generateRoutesByFrontend(
routes, routes,
@ -61,10 +65,6 @@ async function generateRoutes(
); );
break; break;
} }
case 'backend': {
resultRoutes = await generateRoutesByBackend(options);
break;
}
} }
/** /**

View File

@ -3,6 +3,8 @@ import type { ToolbarType } from './types';
import { computed } from 'vue'; import { computed } from 'vue';
import { preferences } from '@vben/preferences';
import { import {
AuthenticationColorToggle, AuthenticationColorToggle,
AuthenticationLayoutToggle, AuthenticationLayoutToggle,
@ -41,7 +43,7 @@ const showTheme = computed(() => props.toolbarList.includes('theme'));
<AuthenticationLayoutToggle v-if="showLayout" /> <AuthenticationLayoutToggle v-if="showLayout" />
</div> </div>
<!-- Always show Language and Theme toggles --> <!-- Always show Language and Theme toggles -->
<LanguageToggle v-if="showLanguage" /> <LanguageToggle v-if="showLanguage && preferences.widget.languageToggle" />
<ThemeToggle v-if="showTheme" /> <ThemeToggle v-if="showTheme && preferences.widget.themeToggle" />
</div> </div>
</template> </template>

View File

@ -13,10 +13,11 @@ defineOptions({
name: 'AuthenticationColorToggle', name: 'AuthenticationColorToggle',
}); });
function handleUpdate(value: BuiltinThemeType) { function handleUpdate(colorPrimary: string, type: BuiltinThemeType) {
updatePreferences({ updatePreferences({
theme: { theme: {
builtinType: value, colorPrimary,
builtinType: type,
}, },
}); });
} }
@ -30,7 +31,7 @@ function handleUpdate(value: BuiltinThemeType) {
<template v-for="preset in COLOR_PRESETS" :key="preset.color"> <template v-for="preset in COLOR_PRESETS" :key="preset.color">
<VbenIconButton <VbenIconButton
class="flex-center flex-shrink-0" class="flex-center flex-shrink-0"
@click="handleUpdate(preset.type)" @click="handleUpdate(preset.color, preset.type)"
> >
<div <div
:style="{ backgroundColor: preset.color }" :style="{ backgroundColor: preset.color }"

View File

@ -31,11 +31,30 @@ const builtinThemePresets = computed(() => {
function typeView(name: BuiltinThemeType) { function typeView(name: BuiltinThemeType) {
switch (name) { switch (name) {
case 'custom': {
return $t('preferences.theme.builtin.custom');
}
case 'deep-blue': {
return $t('preferences.theme.builtin.deepBlue');
}
case 'deep-green': {
return $t('preferences.theme.builtin.deepGreen');
}
case 'default': { case 'default': {
return $t('preferences.theme.builtin.default'); return $t('preferences.theme.builtin.default');
} }
case 'violet': { case 'gray': {
return $t('preferences.theme.builtin.violet'); return $t('preferences.theme.builtin.gray');
}
case 'green': {
return $t('preferences.theme.builtin.green');
}
case 'neutral': {
return $t('preferences.theme.builtin.neutral');
}
case 'orange': {
return $t('preferences.theme.builtin.orange');
} }
case 'pink': { case 'pink': {
return $t('preferences.theme.builtin.pink'); return $t('preferences.theme.builtin.pink');
@ -46,18 +65,11 @@ function typeView(name: BuiltinThemeType) {
case 'sky-blue': { case 'sky-blue': {
return $t('preferences.theme.builtin.skyBlue'); return $t('preferences.theme.builtin.skyBlue');
} }
case 'deep-blue': { case 'slate': {
return $t('preferences.theme.builtin.deepBlue'); return $t('preferences.theme.builtin.slate');
} }
case 'violet': {
case 'green': { return $t('preferences.theme.builtin.violet');
return $t('preferences.theme.builtin.green');
}
case 'deep-green': {
return $t('preferences.theme.builtin.deepGreen');
}
case 'orange': {
return $t('preferences.theme.builtin.orange');
} }
case 'yellow': { case 'yellow': {
return $t('preferences.theme.builtin.yellow'); return $t('preferences.theme.builtin.yellow');
@ -65,18 +77,6 @@ function typeView(name: BuiltinThemeType) {
case 'zinc': { case 'zinc': {
return $t('preferences.theme.builtin.zinc'); return $t('preferences.theme.builtin.zinc');
} }
case 'neutral': {
return $t('preferences.theme.builtin.neutral');
}
case 'slate': {
return $t('preferences.theme.builtin.slate');
}
case 'gray': {
return $t('preferences.theme.builtin.gray');
}
case 'custom': {
return $t('preferences.theme.builtin.custom');
}
} }
} }

View File

@ -37,14 +37,14 @@ function activeClass(theme: string): string[] {
function nameView(name: string) { function nameView(name: string) {
switch (name) { switch (name) {
case 'light': { case 'auto': {
return $t('preferences.theme.light'); return $t('preferences.followSystem');
} }
case 'dark': { case 'dark': {
return $t('preferences.theme.dark'); return $t('preferences.theme.dark');
} }
case 'auto': { case 'light': {
return $t('preferences.followSystem'); return $t('preferences.theme.light');
} }
} }
} }

View File

@ -277,6 +277,18 @@ onMounted(() => {
v-bind="slotProps" v-bind="slotProps"
></slot> ></slot>
</template> </template>
<template #reset-before="slotProps">
<slot name="reset-before" v-bind="slotProps"></slot>
</template>
<template #submit-before="slotProps">
<slot name="submit-before" v-bind="slotProps"></slot>
</template>
<template #expand-before="slotProps">
<slot name="expand-before" v-bind="slotProps"></slot>
</template>
<template #expand-after="slotProps">
<slot name="expand-after" v-bind="slotProps"></slot>
</template>
</Form> </Form>
</slot> </slot>
<div <div

View File

@ -306,7 +306,9 @@ export const useTabbarStore = defineStore('core-tabbar', {
(item) => getTabPath(item) === getTabPath(tab), (item) => getTabPath(item) === getTabPath(tab),
); );
if (index !== -1) { if (index !== -1) {
const oldTab = this.tabs[index];
tab.meta.affixTab = true; tab.meta.affixTab = true;
tab.meta.title = oldTab?.meta?.title as string;
// this.addTab(tab); // this.addTab(tab);
this.tabs.splice(index, 1, tab); this.tabs.splice(index, 1, tab);
} }
@ -411,7 +413,9 @@ export const useTabbarStore = defineStore('core-tabbar', {
); );
if (index !== -1) { if (index !== -1) {
const oldTab = this.tabs[index];
tab.meta.affixTab = false; tab.meta.affixTab = false;
tab.meta.title = oldTab?.meta?.title as string;
// this.addTab(tab); // this.addTab(tab);
this.tabs.splice(index, 1, tab); this.tabs.splice(index, 1, tab);
} }

View File

@ -1,2 +0,0 @@
export * from './form';
export * from './vxe-table';

View File

@ -45,14 +45,14 @@ async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
async function loadDayjsLocale(lang: SupportedLanguagesType) { async function loadDayjsLocale(lang: SupportedLanguagesType) {
let locale; let locale;
switch (lang) { switch (lang) {
case 'zh-CN': {
locale = await import('dayjs/locale/zh-cn');
break;
}
case 'en-US': { case 'en-US': {
locale = await import('dayjs/locale/en'); locale = await import('dayjs/locale/en');
break; break;
} }
case 'zh-CN': {
locale = await import('dayjs/locale/zh-cn');
break;
}
// 默认使用英语 // 默认使用英语
default: { default: {
locale = await import('dayjs/locale/en'); locale = await import('dayjs/locale/en');
@ -71,14 +71,14 @@ async function loadDayjsLocale(lang: SupportedLanguagesType) {
*/ */
async function loadAntdLocale(lang: SupportedLanguagesType) { async function loadAntdLocale(lang: SupportedLanguagesType) {
switch (lang) { switch (lang) {
case 'zh-CN': {
antdLocale.value = antdDefaultLocale;
break;
}
case 'en-US': { case 'en-US': {
antdLocale.value = antdEnLocale; antdLocale.value = antdEnLocale;
break; break;
} }
case 'zh-CN': {
antdLocale.value = antdDefaultLocale;
break;
}
} }
} }

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useVbenDrawer } from '@vben/common-ui'; import { useVbenDrawer } from '@vben/common-ui';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
defineOptions({ defineOptions({
name: 'FormDrawerDemo', name: 'FormDrawerDemo',

View File

@ -3,7 +3,7 @@ import { Page } from '@vben/common-ui';
import { Button, Card, message, Space } from 'ant-design-vue'; import { Button, Card, message, Space } from 'ant-design-vue';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
const [BaseForm, formApi] = useVbenForm({ const [BaseForm, formApi] = useVbenForm({
// //
@ -92,6 +92,97 @@ function handleClick(
| 'updateSubmitButton', | 'updateSubmitButton',
) { ) {
switch (action) { switch (action) {
case 'batchAddSchema': {
formApi.setState((prev) => {
const currentSchema = prev?.schema ?? [];
const newSchema = [];
for (let i = 0; i < 3; i++) {
newSchema.push({
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: `field${i}${Date.now()}`,
label: `field+`,
});
}
return {
schema: [...currentSchema, ...newSchema],
};
});
break;
}
case 'batchDeleteSchema': {
formApi.setState((prev) => {
const currentSchema = prev?.schema ?? [];
return {
schema: currentSchema.slice(0, -3),
};
});
break;
}
case 'disabled': {
formApi.setState({ commonConfig: { disabled: true } });
break;
}
case 'hiddenAction': {
formApi.setState({ showDefaultActions: false });
break;
}
case 'hiddenResetButton': {
formApi.setState({ resetButtonOptions: { show: false } });
break;
}
case 'hiddenSubmitButton': {
formApi.setState({ submitButtonOptions: { show: false } });
break;
}
case 'labelWidth': {
formApi.setState({
commonConfig: {
labelWidth: 150,
},
});
break;
}
case 'resetDisabled': {
formApi.setState({ commonConfig: { disabled: false } });
break;
}
case 'resetLabelWidth': {
formApi.setState({
commonConfig: {
labelWidth: 100,
},
});
break;
}
case 'showAction': {
formApi.setState({ showDefaultActions: true });
break;
}
case 'showResetButton': {
formApi.setState({ resetButtonOptions: { show: true } });
break;
}
case 'showSubmitButton': {
formApi.setState({ submitButtonOptions: { show: true } });
break;
}
case 'updateActionAlign': {
formApi.setState({
// class
actionWrapperClass: 'text-center',
});
break;
}
case 'updateResetButton': {
formApi.setState({
resetButtonOptions: { disabled: true },
});
break;
}
case 'updateSchema': { case 'updateSchema': {
formApi.updateSchema([ formApi.updateSchema([
{ {
@ -117,103 +208,12 @@ function handleClick(
message.success('字段 `fieldOptions` 下拉选项更新成功。'); message.success('字段 `fieldOptions` 下拉选项更新成功。');
break; break;
} }
case 'labelWidth': {
formApi.setState({
commonConfig: {
labelWidth: 150,
},
});
break;
}
case 'resetLabelWidth': {
formApi.setState({
commonConfig: {
labelWidth: 100,
},
});
break;
}
case 'disabled': {
formApi.setState({ commonConfig: { disabled: true } });
break;
}
case 'resetDisabled': {
formApi.setState({ commonConfig: { disabled: false } });
break;
}
case 'hiddenAction': {
formApi.setState({ showDefaultActions: false });
break;
}
case 'showAction': {
formApi.setState({ showDefaultActions: true });
break;
}
case 'hiddenResetButton': {
formApi.setState({ resetButtonOptions: { show: false } });
break;
}
case 'showResetButton': {
formApi.setState({ resetButtonOptions: { show: true } });
break;
}
case 'hiddenSubmitButton': {
formApi.setState({ submitButtonOptions: { show: false } });
break;
}
case 'showSubmitButton': {
formApi.setState({ submitButtonOptions: { show: true } });
break;
}
case 'updateResetButton': {
formApi.setState({
resetButtonOptions: { disabled: true },
});
break;
}
case 'updateSubmitButton': { case 'updateSubmitButton': {
formApi.setState({ formApi.setState({
submitButtonOptions: { loading: true }, submitButtonOptions: { loading: true },
}); });
break; break;
} }
case 'updateActionAlign': {
formApi.setState({
// class
actionWrapperClass: 'text-center',
});
break;
}
case 'batchAddSchema': {
formApi.setState((prev) => {
const currentSchema = prev?.schema ?? [];
const newSchema = [];
for (let i = 0; i < 3; i++) {
newSchema.push({
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: `field${i}${Date.now()}`,
label: `field+`,
});
}
return {
schema: [...currentSchema, ...newSchema],
};
});
break;
}
case 'batchDeleteSchema': {
formApi.setState((prev) => {
const currentSchema = prev?.schema ?? [];
return {
schema: currentSchema.slice(0, -3),
};
});
break;
}
} }
} }
</script> </script>

View File

@ -4,7 +4,7 @@ import { Page } from '@vben/common-ui';
import { Button, Card, message } from 'ant-design-vue'; import { Button, Card, message } from 'ant-design-vue';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
import DocButton from '../doc-button.vue'; import DocButton from '../doc-button.vue';

View File

@ -5,7 +5,7 @@ import { Page } from '@vben/common-ui';
import { Card, Input, message } from 'ant-design-vue'; import { Card, Input, message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
const [Form] = useVbenForm({ const [Form] = useVbenForm({
// //

View File

@ -3,7 +3,7 @@ import { Page } from '@vben/common-ui';
import { Button, Card, message } from 'ant-design-vue'; import { Button, Card, message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
const [Form, formApi] = useVbenForm({ const [Form, formApi] = useVbenForm({
// //

View File

@ -5,7 +5,7 @@ import { Page } from '@vben/common-ui';
import { Button, Card, message, Step, Steps, Switch } from 'ant-design-vue'; import { Button, Card, message, Step, Steps, Switch } from 'ant-design-vue';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
const currentTab = ref(0); const currentTab = ref(0);
function onFirstSubmit(values: Record<string, any>) { function onFirstSubmit(values: Record<string, any>) {

View File

@ -3,7 +3,7 @@ import { Page } from '@vben/common-ui';
import { Card, message } from 'ant-design-vue'; import { Card, message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
const [QueryForm] = useVbenForm({ const [QueryForm] = useVbenForm({
// //

View File

@ -3,7 +3,7 @@ import { Page } from '@vben/common-ui';
import { Button, Card, message } from 'ant-design-vue'; import { Button, Card, message } from 'ant-design-vue';
import { useVbenForm, z } from '#/adapter'; import { useVbenForm, z } from '#/adapter/form';
const [Form, formApi] = useVbenForm({ const [Form, formApi] = useVbenForm({
// //

View File

@ -3,7 +3,7 @@ import { useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter'; import { useVbenForm } from '#/adapter/form';
defineOptions({ defineOptions({
name: 'FormModelDemo', name: 'FormModelDemo',

View File

@ -1,11 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VxeGridListeners, VxeGridProps } from '#/adapter'; import type { VxeGridListeners, VxeGridProps } from '#/adapter/vxe-table';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { Button, message } from 'ant-design-vue'; import { Button, message } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
import DocButton from '../doc-button.vue'; import DocButton from '../doc-button.vue';
import { MOCK_TABLE_DATA } from './table-data'; import { MOCK_TABLE_DATA } from './table-data';

View File

@ -1,11 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VxeGridProps } from '#/adapter'; import type { VxeGridProps } from '#/adapter/vxe-table';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { Button, Image, Switch, Tag } from 'ant-design-vue'; import { Button, Image, Switch, Tag } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getExampleTableApi } from '#/api'; import { getExampleTableApi } from '#/api';
interface RowType { interface RowType {

View File

@ -1,9 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VxeGridProps } from '#/adapter'; import type { VxeGridProps } from '#/adapter/vxe-table';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { useVbenVxeGrid } from '#/adapter'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getExampleTableApi } from '#/api'; import { getExampleTableApi } from '#/api';
interface RowType { interface RowType {

View File

@ -1,11 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VxeGridProps } from '#/adapter'; import type { VxeGridProps } from '#/adapter/vxe-table';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { Button, message } from 'ant-design-vue'; import { Button, message } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getExampleTableApi } from '#/api'; import { getExampleTableApi } from '#/api';
interface RowType { interface RowType {

View File

@ -1,11 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VxeGridProps } from '#/adapter'; import type { VxeGridProps } from '#/adapter/vxe-table';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue'; import { Button } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getExampleTableApi } from '#/api'; import { getExampleTableApi } from '#/api';
interface RowType { interface RowType {

View File

@ -1,11 +1,12 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VbenFormProps, VxeGridProps } from '#/adapter'; import type { VbenFormProps } from '#/adapter/form';
import type { VxeGridProps } from '#/adapter/vxe-table';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getExampleTableApi } from '#/api'; import { getExampleTableApi } from '#/api';
interface RowType { interface RowType {

View File

@ -1,11 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VxeGridProps } from '#/adapter'; import type { VxeGridProps } from '#/adapter/vxe-table';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue'; import { Button } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getExampleTableApi } from '#/api'; import { getExampleTableApi } from '#/api';
interface RowType { interface RowType {

View File

@ -1,11 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VxeGridProps } from '#/adapter'; import type { VxeGridProps } from '#/adapter/vxe-table';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue'; import { Button } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { MOCK_TREE_TABLE_DATA } from './table-data'; import { MOCK_TREE_TABLE_DATA } from './table-data';

View File

@ -1,11 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VxeGridProps } from '#/adapter'; import type { VxeGridProps } from '#/adapter/vxe-table';
import { onMounted } from 'vue'; import { onMounted } from 'vue';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { useVbenVxeGrid } from '#/adapter'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
interface RowType { interface RowType {
id: number; id: number;

View File

@ -22,15 +22,15 @@ catalog:
'@ctrl/tinycolor': ^4.1.0 '@ctrl/tinycolor': ^4.1.0
'@eslint/js': ^9.12.0 '@eslint/js': ^9.12.0
'@faker-js/faker': ^9.0.3 '@faker-js/faker': ^9.0.3
'@iconify/json': ^2.2.259 '@iconify/json': ^2.2.260
'@iconify/tailwind': ^1.1.3 '@iconify/tailwind': ^1.1.3
'@iconify/vue': ^4.1.2 '@iconify/vue': ^4.1.2
'@intlify/core-base': ^10.0.4 '@intlify/core-base': ^10.0.4
'@intlify/unplugin-vue-i18n': ^5.2.0 '@intlify/unplugin-vue-i18n': ^5.2.0
'@jspm/generator': ^2.3.1 '@jspm/generator': ^2.4.1
'@manypkg/get-packages': ^2.2.2 '@manypkg/get-packages': ^2.2.2
'@nolebase/vitepress-plugin-git-changelog': ^2.6.1 '@nolebase/vitepress-plugin-git-changelog': ^2.6.1
'@playwright/test': ^1.48.0 '@playwright/test': ^1.48.1
'@pnpm/workspace.read-manifest': ^2.2.1 '@pnpm/workspace.read-manifest': ^2.2.1
'@stylistic/stylelint-plugin': ^3.1.1 '@stylistic/stylelint-plugin': ^3.1.1
'@tailwindcss/nesting': 0.0.0-insiders.565cd3e '@tailwindcss/nesting': 0.0.0-insiders.565cd3e
@ -48,8 +48,8 @@ catalog:
'@types/postcss-import': ^14.0.3 '@types/postcss-import': ^14.0.3
'@types/qrcode': ^1.5.5 '@types/qrcode': ^1.5.5
'@types/sortablejs': ^1.15.8 '@types/sortablejs': ^1.15.8
'@typescript-eslint/eslint-plugin': ^8.8.1 '@typescript-eslint/eslint-plugin': ^8.9.0
'@typescript-eslint/parser': ^8.8.1 '@typescript-eslint/parser': ^8.9.0
'@vee-validate/zod': ^4.13.2 '@vee-validate/zod': ^4.13.2
'@vite-pwa/vitepress': ^0.5.3 '@vite-pwa/vitepress': ^0.5.3
'@vitejs/plugin-vue': ^5.1.4 '@vitejs/plugin-vue': ^5.1.4
@ -73,7 +73,7 @@ catalog:
commitlint-plugin-function-rules: ^4.0.0 commitlint-plugin-function-rules: ^4.0.0
consola: ^3.2.3 consola: ^3.2.3
cross-env: ^7.0.3 cross-env: ^7.0.3
cspell: ^8.15.1 cspell: ^8.15.2
cssnano: ^7.0.6 cssnano: ^7.0.6
cz-git: ^1.10.1 cz-git: ^1.10.1
czg: ^1.10.1 czg: ^1.10.1
@ -88,11 +88,11 @@ catalog:
eslint-plugin-command: ^0.2.6 eslint-plugin-command: ^0.2.6
eslint-plugin-eslint-comments: ^3.2.0 eslint-plugin-eslint-comments: ^3.2.0
eslint-plugin-import-x: ^4.3.1 eslint-plugin-import-x: ^4.3.1
eslint-plugin-jsdoc: ^50.3.2 eslint-plugin-jsdoc: ^50.4.1
eslint-plugin-jsonc: ^2.16.0 eslint-plugin-jsonc: ^2.16.0
eslint-plugin-n: ^17.11.1 eslint-plugin-n: ^17.11.1
eslint-plugin-no-only-tests: ^3.3.0 eslint-plugin-no-only-tests: ^3.3.0
eslint-plugin-perfectionist: ^3.8.0 eslint-plugin-perfectionist: ^3.9.0
eslint-plugin-prettier: ^5.2.1 eslint-plugin-prettier: ^5.2.1
eslint-plugin-regexp: ^2.6.0 eslint-plugin-regexp: ^2.6.0
eslint-plugin-unicorn: ^56.0.0 eslint-plugin-unicorn: ^56.0.0
@ -112,7 +112,7 @@ catalog:
jsonwebtoken: ^9.0.2 jsonwebtoken: ^9.0.2
lint-staged: ^15.2.10 lint-staged: ^15.2.10
lodash.clonedeep: ^4.5.0 lodash.clonedeep: ^4.5.0
lucide-vue-next: ^0.452.0 lucide-vue-next: ^0.453.0
medium-zoom: ^1.1.0 medium-zoom: ^1.1.0
naive-ui: ^2.40.1 naive-ui: ^2.40.1
nanoid: ^5.0.7 nanoid: ^5.0.7
@ -122,7 +122,7 @@ catalog:
pinia: 2.2.2 pinia: 2.2.2
pinia-plugin-persistedstate: ^4.1.1 pinia-plugin-persistedstate: ^4.1.1
pkg-types: ^1.2.1 pkg-types: ^1.2.1
playwright: ^1.48.0 playwright: ^1.48.1
postcss: ^8.4.47 postcss: ^8.4.47
postcss-antd-fixes: ^0.2.0 postcss-antd-fixes: ^0.2.0
postcss-html: ^1.7.0 postcss-html: ^1.7.0
@ -149,8 +149,8 @@ catalog:
stylelint-order: ^6.0.4 stylelint-order: ^6.0.4
stylelint-prettier: ^5.0.2 stylelint-prettier: ^5.0.2
stylelint-scss: ^6.7.0 stylelint-scss: ^6.7.0
tailwind-merge: ^2.5.3 tailwind-merge: ^2.5.4
tailwindcss: ^3.4.13 tailwindcss: ^3.4.14
tailwindcss-animate: ^1.0.7 tailwindcss-animate: ^1.0.7
theme-colors: ^0.1.0 theme-colors: ^0.1.0
turbo: ^2.1.3 turbo: ^2.1.3
@ -158,7 +158,7 @@ catalog:
unbuild: ^2.0.0 unbuild: ^2.0.0
unplugin-element-plus: ^0.8.0 unplugin-element-plus: ^0.8.0
vee-validate: ^4.13.2 vee-validate: ^4.13.2
vite: ^5.4.8 vite: ^5.4.9
vite-plugin-compression: ^0.5.1 vite-plugin-compression: ^0.5.1
vite-plugin-dts: 4.2.1 vite-plugin-dts: 4.2.1
vite-plugin-html: ^3.2.2 vite-plugin-html: ^3.2.2
@ -167,14 +167,14 @@ catalog:
vite-plugin-pwa: ^0.20.5 vite-plugin-pwa: ^0.20.5
vite-plugin-vue-devtools: ^7.4.6 vite-plugin-vue-devtools: ^7.4.6
vitepress: ^1.4.1 vitepress: ^1.4.1
vitepress-plugin-group-icons: ^1.2.4 vitepress-plugin-group-icons: ^1.3.0
vitest: ^2.1.2 vitest: ^2.1.3
vue: ^3.5.12 vue: ^3.5.12
vue-eslint-parser: ^9.4.3 vue-eslint-parser: ^9.4.3
vue-i18n: ^10.0.4 vue-i18n: ^10.0.4
vue-router: ^4.4.5 vue-router: ^4.4.5
vue-tsc: ^2.1.6 vue-tsc: ^2.1.6
vxe-pc-ui: ^4.2.19 vxe-pc-ui: ^4.2.20
vxe-table: ^4.7.86 vxe-table: ^4.7.86
watermark-js-plus: ^1.5.7 watermark-js-plus: ^1.5.7
zod: ^3.23.8 zod: ^3.23.8

View File

@ -18,12 +18,12 @@ RUN pnpm run build
RUN echo "Builder Success 🎉" RUN echo "Builder Success 🎉"
FROM nginx:stable-alpine as production FROM nginx:stable-alpine AS production
RUN echo "types { application/javascript js mjs; }" > /etc/nginx/conf.d/mjs.conf RUN echo "types { application/javascript js mjs; }" > /etc/nginx/conf.d/mjs.conf
COPY --from=builder /app/playground/dist /usr/share/nginx/html COPY --from=builder /app/playground/dist /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/nginx.conf COPY --from=builder /app/scripts/deploy/nginx.conf /etc/nginx/nginx.conf
EXPOSE 8080 EXPOSE 8080

View File

@ -24,7 +24,7 @@ function install_dependencies() {
function build_image() { function build_image() {
# build docker # build docker
docker build . -f Dockerfile -t ${IMAGE_NAME} || ERROR="build_image failed" docker build ../../ -f Dockerfile -t ${IMAGE_NAME} || ERROR="build_image failed"
} }
function log_message() { function log_message() {