feat: 完成 NestJS 后端核心底座开发 (M1-M6) 和 Ant Design Vue 前端迁移

主要更新:
1. 后端核心底座完成 (M1-M6):
   - 健康检查、指标监控、分布式锁
   - 事件总线、队列系统、事务管理
   - 安全守卫、多租户隔离、存储适配器
   - 审计日志、配置管理、多语言支持

2. 前端迁移到 Ant Design Vue:
   - 从 Element Plus 迁移到 Ant Design Vue
   - 完善 system 模块 (role/menu/dept)
   - 修复依赖和配置问题

3. 文档完善:
   - AI 开发工作流文档
   - 架构约束和开发规范
   - 项目进度跟踪

4. 其他改进:
   - 修复编译错误和类型问题
   - 完善测试用例
   - 优化项目结构
This commit is contained in:
万物街
2025-08-27 11:24:22 +08:00
parent be07b9ffec
commit 1cd5d3bdef
696 changed files with 36708 additions and 16868 deletions

View File

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

View File

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

View File

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

View File

@@ -30,7 +30,7 @@ function openWindow(url: string, options: OpenWindowOptions = {}): void {
function openRouteInNewWindow(path: string) {
const { hash, origin } = location;
const fullPath = path.startsWith('/') ? path : `/${path}`;
const url = `${origin}${hash && !fullPath.startsWith('/#') ? '/#' : ''}${fullPath}`;
const url = `${origin}${hash ? '/#' : ''}${fullPath}`;
openWindow(url, { target: '_blank' });
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -34,6 +34,17 @@ const submitButtonOptions = computed(() => {
// return !!unref(rootProps).showCollapseButton;
// });
const queryFormStyle = computed(() => {
if (!unref(rootProps).actionWrapperClass) {
return {
'grid-column': `-2 / -1`,
marginLeft: 'auto',
};
}
return {};
});
async function handleSubmit(e: Event) {
e?.preventDefault();
e?.stopPropagation();
@@ -75,59 +86,22 @@ watch(
},
);
const actionWrapperClass = computed(() => {
const props = unref(rootProps);
const actionLayout = props.actionLayout || 'rowEnd';
const actionPosition = props.actionPosition || 'right';
const cls = [
'flex',
'items-center',
'gap-3',
props.compact ? 'pb-2' : 'pb-4',
props.layout === 'vertical' ? 'self-end' : 'self-center',
props.layout === 'inline' ? '' : 'w-full',
props.actionWrapperClass,
];
switch (actionLayout) {
case 'newLine': {
cls.push('col-span-full');
break;
}
case 'rowEnd': {
cls.push('col-[-2/-1]');
break;
}
// 'inline' 不需要额外类名,保持默认
}
switch (actionPosition) {
case 'center': {
cls.push('justify-center');
break;
}
case 'left': {
cls.push('justify-start');
break;
}
default: {
// case 'right': 默认右对齐
cls.push('justify-end');
break;
}
}
return cls.join(' ');
});
defineExpose({
handleReset,
handleSubmit,
});
</script>
<template>
<div :class="cn(actionWrapperClass)">
<div
:class="
cn(
'col-span-full w-full text-right',
rootProps.compact ? 'pb-2' : 'pb-6',
rootProps.actionWrapperClass,
)
"
:style="queryFormStyle"
>
<template v-if="rootProps.actionButtonsReverse">
<!-- 提交按钮前 -->
<slot name="submit-before"></slot>
@@ -135,6 +109,7 @@ defineExpose({
<component
:is="COMPONENT_MAP.PrimaryButton"
v-if="submitButtonOptions.show"
class="ml-3"
type="button"
@click="handleSubmit"
v-bind="submitButtonOptions"
@@ -149,6 +124,7 @@ defineExpose({
<component
:is="COMPONENT_MAP.DefaultButton"
v-if="resetButtonOptions.show"
class="ml-3"
type="button"
@click="handleReset"
v-bind="resetButtonOptions"
@@ -163,6 +139,7 @@ defineExpose({
<component
:is="COMPONENT_MAP.PrimaryButton"
v-if="submitButtonOptions.show"
class="ml-3"
type="button"
@click="handleSubmit"
v-bind="submitButtonOptions"
@@ -175,9 +152,9 @@ defineExpose({
<slot name="expand-before"></slot>
<VbenExpandableArrow
class="ml-[-0.3em]"
v-if="rootProps.showCollapseButton"
v-model:model-value="collapsed"
class="ml-2"
>
<span>{{ collapsed ? $t('expand') : $t('collapse') }}</span>
</VbenExpandableArrow>

View File

@@ -59,7 +59,7 @@ const values = useFormValues();
const errors = useFieldError(fieldName);
const fieldComponentRef = useTemplateRef<HTMLInputElement>('fieldComponentRef');
const formApi = formRenderProps.form;
const compact = computed(() => formRenderProps.compact);
const compact = formRenderProps.compact;
const isInValid = computed(() => errors.value?.length > 0);
const FieldComponent = computed(() => {
@@ -295,7 +295,7 @@ onUnmounted(() => {
'form-is-required': shouldRequired,
'flex-col': isVertical,
'flex-row items-center': !isVertical,
'pb-4': !compact,
'pb-6': !compact,
'pb-2': compact,
}"
class="relative flex"
@@ -386,7 +386,7 @@ onUnmounted(() => {
</div>
<Transition name="slide-up" v-if="!compact">
<FormMessage class="absolute" />
<FormMessage class="absolute bottom-1" />
</Transition>
</div>
</FormItem>

View File

@@ -41,16 +41,6 @@ const emits = defineEmits<{
submit: [event: any];
}>();
const wrapperClass = computed(() => {
const cls = ['flex'];
if (props.layout === 'inline') {
cls.push('flex-wrap gap-x-2');
} else {
cls.push(props.compact ? 'gap-x-2' : 'gap-x-4', 'flex-col grid');
}
return cn(...cls, props.wrapperClass);
});
provideFormRenderProps(props);
const { isCalculated, keepFormItemIndex, wrapperRef } = useExpandable(props);
@@ -170,7 +160,7 @@ const computedSchema = computed(
<template>
<component :is="formComponent" v-bind="formComponentProps">
<div ref="wrapperRef" :class="wrapperClass">
<div ref="wrapperRef" :class="wrapperClass" class="grid">
<template v-for="cSchema in computedSchema" :key="cSchema.fieldName">
<!-- <div v-if="$slots[cSchema.fieldName]" :class="cSchema.formItemClass">
<slot :definition="cSchema" :name="cSchema.fieldName"> </slot>

View File

@@ -8,7 +8,7 @@ import type { ClassType, MaybeComputedRef } from '@vben-core/typings';
import type { FormApi } from './form-api';
export type FormLayout = 'horizontal' | 'inline' | 'vertical';
export type FormLayout = 'horizontal' | 'vertical';
export type BaseFormComponentType =
| 'DefaultButton'
@@ -354,15 +354,6 @@ export interface VbenFormProps<
* 操作按钮是否反转(提交按钮前置)
*/
actionButtonsReverse?: boolean;
/**
* 操作按钮组的样式
* newLine: 在新行显示。rowEnd: 在行内显示靠右对齐默认。inline: 使用grid默认样式
*/
actionLayout?: 'inline' | 'newLine' | 'rowEnd';
/**
* 操作按钮组显示位置,默认靠右显示
*/
actionPosition?: 'center' | 'left' | 'right';
/**
* 表单操作区域class
*/

View File

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

View File

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

View File

@@ -107,6 +107,7 @@ export class ModalApi {
this.store.setState((prev) => ({
...prev,
isOpen: false,
submitting: false,
}));
}
}
@@ -161,11 +162,7 @@ export class ModalApi {
}
open() {
this.store.setState((prev) => ({
...prev,
isOpen: true,
submitting: false,
}));
this.store.setState((prev) => ({ ...prev, isOpen: true }));
}
setData<T>(payload: T) {

View File

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

View File

@@ -8,7 +8,12 @@ import { computed, ref } from 'vue';
import { cn } from '@vben-core/shared/utils';
import { X } from 'lucide-vue-next';
import { DialogClose, DialogContent, useForwardPropsEmits } from 'radix-vue';
import {
DialogClose,
DialogContent,
DialogPortal,
useForwardPropsEmits,
} from 'radix-vue';
import DialogOverlay from './DialogOverlay.vue';
@@ -82,7 +87,7 @@ defineExpose({
</script>
<template>
<Teleport :to="appendTo">
<DialogPortal :to="appendTo">
<Transition name="fade">
<DialogOverlay
v-if="open && modal"
@@ -127,5 +132,5 @@ defineExpose({
<X class="h-4 w-4" />
</DialogClose>
</DialogContent>
</Teleport>
</DialogPortal>
</template>

View File

@@ -7,7 +7,7 @@ import { computed, ref } from 'vue';
import { cn } from '@vben-core/shared/utils';
import { DialogContent, useForwardPropsEmits } from 'radix-vue';
import { DialogContent, DialogPortal, useForwardPropsEmits } from 'radix-vue';
import { sheetVariants } from './sheet';
import SheetOverlay from './SheetOverlay.vue';
@@ -73,7 +73,7 @@ function onAnimationEnd(event: AnimationEvent) {
</script>
<template>
<Teleport :to="appendTo">
<DialogPortal :to="appendTo">
<Transition name="fade">
<SheetOverlay
v-if="open && modal"
@@ -103,5 +103,5 @@ function onAnimationEnd(event: AnimationEvent) {
<Cross2Icon class="h-5 w-" />
</DialogClose> -->
</DialogContent>
</Teleport>
</DialogPortal>
</template>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -29,8 +29,7 @@ function useNavigation() {
return true;
}
const route = routeMetaMap.get(path);
// 如果有外链或者设置了在新窗口打开,返回 true
return !!(route?.meta?.link || route?.meta?.openInNewWindow);
return route?.meta?.openInNewWindow ?? false;
};
const resolveHref = (path: string): string => {
@@ -40,13 +39,7 @@ function useNavigation() {
const navigation = async (path: string) => {
try {
const route = routeMetaMap.get(path);
const { openInNewWindow = false, query = {}, link } = route?.meta ?? {};
// 检查是否有外链
if (link && typeof link === 'string') {
openWindow(link, { target: '_blank' });
return;
}
const { openInNewWindow = false, query = {} } = route?.meta ?? {};
if (isHttpUrl(path)) {
openWindow(path, { target: '_blank' });

View File

@@ -98,7 +98,7 @@ async function handleEnter() {
}
const to = result[index];
if (to) {
searchHistory.value = uniqueByField([...searchHistory.value, to], 'path');
searchHistory.value.push(to);
handleClose();
await nextTick();
if (isHttpUrl(to.path)) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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