28 KiB
Yudao UI Admin Vben - 项目结构与开发指南
专注于 web-antd 项目 - 基于 Vue 3 + Vite + Ant Design Vue 的后台管理系统
📋 目录
🏗️ 项目架构
整体结构
本项目采用 Monorepo 架构,使用 pnpm workspace 管理多个包:
yudao-ui-admin-vben/
├── apps/ # 应用层
│ ├── web-antd/ # Ant Design Vue 版本 (主要使用)
│ ├── web-ele/ # Element Plus 版本
│ ├── web-naive/ # Naive UI 版本
│ └── web-tdesign/ # TDesign 版本
├── packages/ # 公共包
│ ├── @core/ # 核心包
│ ├── effects/ # 业务效果包
│ ├── locales/ # 国际化
│ ├── stores/ # 状态管理
│ └── ... # 其他工具包
├── internal/ # 内部工具
│ ├── vite-config/ # Vite 配置
│ ├── tailwind-config/ # Tailwind 配置
│ └── lint-configs/ # 代码规范配置
└── docs/ # 文档站点
技术栈
| 技术 | 版本 | 说明 |
|---|---|---|
| Vue | 3.x | 渐进式 JavaScript 框架 |
| Vite | 5.x | 下一代前端构建工具 |
| TypeScript | 5.x | 类型安全 |
| Ant Design Vue | 4.x | UI 组件库 |
| Pinia | 2.x | 状态管理 |
| Vue Router | 4.x | 路由管理 |
| Tailwind CSS | 3.x | 原子化 CSS |
| VueUse | 10.x | Vue Composition API 工具集 |
📁 目录结构详解
apps/web-antd/ - 主应用目录
apps/web-antd/
├── public/ # 静态资源
│ ├── favicon.ico # 网站图标
│ ├── login-illustration.svg # 登录页插图
│ ├── images/ # 图片资源
│ ├── static/ # 静态文件
│ └── tinymce/ # 富文本编辑器资源
│
├── src/
│ ├── adapter/ # 适配器层
│ │ ├── component.ts # 组件适配器 (全局组件注册)
│ │ ├── form.ts # 表单适配器
│ │ └── vxe-table.ts # 表格适配器
│ │
│ ├── api/ # API 接口层 (201 个文件)
│ │ ├── core/ # 核心接口 (登录、权限等)
│ │ ├── system/ # 系统管理
│ │ ├── infra/ # 基础设施
│ │ ├── bpm/ # 工作流
│ │ ├── mall/ # 商城
│ │ ├── mp/ # 公众号
│ │ ├── pay/ # 支付
│ │ ├── ai/ # AI 相关
│ │ ├── iot/ # 物联网
│ │ └── erp/ # ERP
│ │
│ ├── assets/ # 资源文件
│ │ ├── images/ # 图片
│ │ └── svg/ # SVG 图标
│ │
│ ├── components/ # 业务组件 (54 个文件)
│ │ ├── Bpmnjs/ # 工作流设计器
│ │ ├── Button/ # 按钮组件
│ │ ├── ContentWrap/ # 内容包裹器
│ │ ├── Crontab/ # 定时任务配置
│ │ ├── Dialog/ # 对话框
│ │ ├── Editor/ # 编辑器
│ │ ├── Form/ # 表单
│ │ ├── Icon/ # 图标
│ │ ├── ImageViewer/ # 图片查看器
│ │ ├── InputNumber/ # 数字输入框
│ │ ├── JsonEditor/ # JSON 编辑器
│ │ ├── Search/ # 搜索
│ │ ├── SimpleProcessDesignerV2/ # 流程设计器 V2
│ │ ├── Table/ # 表格
│ │ ├── UploadFile/ # 文件上传
│ │ └── UploadImg/ # 图片上传
│ │
│ ├── layouts/ # 布局组件
│ │ ├── auth.vue # 登录页布局 (自定义)
│ │ ├── auth-original.vue # 原始登录页布局 (备份)
│ │ ├── basic.vue # 基础布局
│ │ └── index.ts # 导出
│ │
│ ├── locales/ # 本地化
│ │ ├── langs/ # 语言包
│ │ │ ├── en-US.json # 英文
│ │ │ └── zh-CN.json # 中文
│ │ └── index.ts
│ │
│ ├── plugins/ # 插件
│ │ └── form-create.ts # 表单构建器插件
│ │
│ ├── router/ # 路由配置
│ │ ├── guard.ts # 路由守卫
│ │ ├── index.ts # 路由实例
│ │ └── routes/ # 路由定义
│ │ ├── core.ts # 核心路由 (登录、404等)
│ │ └── modules/ # 业务路由模块
│ │
│ ├── store/ # 状态管理 (Pinia)
│ │ ├── index.ts
│ │ ├── modules/
│ │ │ ├── auth.ts # 认证状态
│ │ │ ├── dict.ts # 字典状态
│ │ │ └── tenant.ts # 租户状态
│ │
│ ├── utils/ # 工具函数
│ │ ├── dict.ts # 字典工具
│ │ ├── tree.ts # 树形数据工具
│ │ └── ...
│ │
│ ├── views/ # 页面视图 (1233 个文件)
│ │ ├── _core/ # 核心页面
│ │ │ ├── authentication/ # 认证相关
│ │ │ │ ├── login.vue # 登录页
│ │ │ │ ├── code-login.vue # 验证码登录
│ │ │ │ ├── qrcode-login.vue # 二维码登录
│ │ │ │ └── forget-password.vue # 忘记密码
│ │ │ ├── profile/ # 个人中心
│ │ │ └── ...
│ │ ├── system/ # 系统管理
│ │ ├── bpm/ # 工作流
│ │ ├── mall/ # 商城
│ │ ├── mp/ # 公众号
│ │ ├── pay/ # 支付
│ │ ├── ai/ # AI
│ │ ├── iot/ # 物联网
│ │ └── erp/ # ERP
│ │
│ ├── app.vue # 根组件
│ ├── bootstrap.ts # 应用启动配置
│ ├── main.ts # 应用入口
│ └── preferences.ts # 偏好设置
│
├── index.html # HTML 模板
├── vite.config.mts # Vite 配置
├── tsconfig.json # TypeScript 配置
├── tailwind.config.mjs # Tailwind 配置
├── package.json # 依赖管理
└── LOGIN_LAYOUT_README.md # 登录布局文档
🧩 通用组件库
packages/@core/ - 核心组件包
1. shadcn-ui (packages/@core/ui-kit/shadcn-ui)
基于 shadcn/ui 的 Vue 组件库,提供高质量的基础 UI 组件:
// 导入方式
import {
VbenButton,
VbenInput,
VbenModal,
VbenToast,
VbenDropdown,
VbenSelect,
VbenPinInput, // 验证码输入框
VbenLoading,
VbenSpinner,
// ... 更多组件
} from '@vben-core/shadcn-ui';
常用组件:
- 按钮类:
VbenButton,VbenIconButton - 输入类:
VbenInput,VbenInputPassword,VbenPinInput - 选择类:
VbenSelect,VbenDropdown,VbenCheckbox,VbenRadio - 反馈类:
VbenModal,VbenToast,VbenAlert,VbenLoading - 布局类:
VbenCard,VbenTabs,VbenCollapse
2. form-ui (packages/@core/ui-kit/form-ui)
强大的表单构建器:
import { useVbenForm, VbenFormSchema } from '@vben-core/form-ui';
// 表单配置示例
const formSchema: VbenFormSchema[] = [
{
component: 'VbenInput',
fieldName: 'username',
label: '用户名',
rules: z.string().min(1, { message: '请输入用户名' }),
},
{
component: 'VbenInputPassword',
fieldName: 'password',
label: '密码',
rules: z.string().min(6, { message: '密码至少6位' }),
},
];
const [Form, formApi] = useVbenForm({ schema: formSchema });
3. menu-ui (packages/@core/ui-kit/menu-ui)
菜单组件,支持多级菜单、收缩展开等:
import { VbenMenu } from '@vben-core/menu-ui';
4. layout-ui (packages/@core/ui-kit/layout-ui)
布局组件(Header, Sidebar, Content, Footer):
import { BasicLayout, LayoutHeader, LayoutSidebar } from '@vben-core/layout-ui';
5. popup-ui (packages/@core/ui-kit/popup-ui)
弹窗、抽屉组件:
import { VbenModal, VbenDrawer } from '@vben-core/popup-ui';
packages/effects/ - 业务效果包
1. layouts (packages/effects/layouts)
布局组件和小部件:
import {
// 布局组件
AuthPageLayout, // 认证页布局
LoginIllustration, // 登录插图 (自定义新增)
// 小部件
ThemeToggle, // 主题切换
LanguageToggle, // 语言切换
ColorToggle, // 颜色选择器
LayoutToggle, // 布局切换
UserDropdown, // 用户下拉菜单
Breadcrumb, // 面包屑
GlobalSearch, // 全局搜索
LockScreen, // 锁屏
Notification, // 通知
} from '@vben/layouts';
目录结构:
packages/effects/layouts/src/
├── authentication/ # 认证相关
│ ├── authentication.vue # 认证页布局
│ ├── icons/
│ │ ├── login-illustration.vue # 登录插图组件
│ │ └── slogan.vue # Logo/标语组件
│ └── index.ts # 导出
├── basic/ # 基础布局
├── widgets/ # 小部件
│ ├── theme-toggle.vue
│ ├── language-toggle.vue
│ ├── color-toggle.vue # 颜色选择器 (已修改)
│ └── ...
└── index.ts
2. common-ui (packages/effects/common-ui)
通用 UI 组件:
import {
// 认证组件
AuthenticationLogin, // 登录表单
AuthenticationCodeLogin, // 验证码登录
AuthenticationForgetPassword, // 忘记密码
AuthenticationRegister, // 注册
// 其他通用组件
Page, // 页面容器
DocAlert, // 文档提醒
Description, // 描述列表
Ellipsis, // 文本省略
Iframe, // 内嵌页面
// ...
} from '@vben/common-ui';
3. hooks (packages/effects/hooks)
业务相关的 Composition API 钩子:
import {
useWatermark, // 水印
useTabs, // 标签页管理
useContentHeight, // 内容高度自适应
isTenantEnable, // 租户功能是否启用
} from '@vben/hooks';
4. access (packages/effects/access)
权限控制:
import { useAccess } from '@vben/access';
// 权限检查
const { hasAccessByRoles, hasAccessByCodes } = useAccess();
// 指令方式
<button v-access="'system:user:create'">创建用户</button>
packages/其他包
locales - 国际化
import { $t, setupI18n } from '@vben/locales';
// 使用翻译
$t('authentication.login');
$t('authentication.username');
语言包位置:
- 中文:
packages/locales/src/langs/zh-CN/*.json - 英文:
packages/locales/src/langs/en-US/*.json
stores - 状态管理
import {
useUserStore, // 用户信息
useAccessStore, // 权限信息
useTabsStore, // 标签页
useAppStore, // 应用配置
} from '@vben/stores';
const userStore = useUserStore();
await userStore.fetchUserInfo();
preferences - 偏好设置
import {
preferences, // 偏好设置对象
updatePreferences, // 更新偏好设置
usePreferences, // 响应式偏好设置
} from '@vben/preferences';
// 读取
const isDark = preferences.theme.mode === 'dark';
// 更新
updatePreferences({
theme: {
colorPrimary: '#FFA00A',
builtinType: 'amber',
},
});
utils - 工具函数
import {
// 路由工具
mapTree,
resetRoutes,
// 通用工具
formatDate,
formatDateTime,
openWindow,
// 验证器
isEmail,
isPhone,
isUrl,
} from '@vben/utils';
constants - 常量定义
import {
// 核心常量
LOGIN_PATH,
VBEN_DOC_URL,
// 业务枚举
DictEnum,
SystemEnum,
BpmEnum,
// ...
} from '@vben/constants';
⚙️ 配置文件说明
1. Vite 配置 (vite.config.mts)
import { defineConfig } from '@vben/vite-config';
export default defineConfig(async () => {
return {
application: {},
vite: {
server: {
proxy: {
'/admin-api': {
target: 'http://localhost:48080/admin-api',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/admin-api/, ''),
},
},
},
},
};
});
2. TypeScript 配置 (tsconfig.json)
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@vben/tsconfig/web-app.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"#/*": ["./src/*"]
},
"allowJs": true
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}
路径别名:
#/*→./src/*(应用内部)@vben/*→packages/*(公共包)
3. Tailwind 配置 (tailwind.config.mjs)
import { defineConfig } from '@vben/tailwind-config';
export default defineConfig({
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
// 自定义配置...
});
4. 环境变量 (.env.*)
# .env.development
VITE_APP_TITLE=芋道管理系统
VITE_APP_BASE_API=/admin-api
VITE_APP_NAMESPACE=vben-web-antd
🎨 主题定制
1. 新增主题色
文件: packages/@core/preferences/src/constants.ts
const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [
{
color: 'hsl(37 100% 52%)', // #FFA00A
type: 'amber',
},
// ... 其他颜色
];
export const COLOR_PRESETS = [...BUILT_IN_THEME_PRESETS].slice(0, 8);
类型定义: packages/@core/base/typings/src/app.d.ts
type BuiltinThemeType =
| 'amber' // 新增
| 'default'
| 'orange'
| 'red'
// ...
| (Record<never, never> & string);
默认主题: packages/@core/preferences/src/config.ts
const defaultPreferences: Preferences = {
theme: {
builtinType: 'amber', // 默认主题类型
colorPrimary: 'hsl(37 100% 52%)', // 主色调
mode: 'dark', // 暗色模式
radius: '0.5', // 圆角
},
// ...
};
2. Loading 页面定制
文件: internal/vite-config/src/plugins/inject-app-loading/default-loading.html
<style data-app-loading="inject-css">
/* 主题色 */
.loader::after {
background: hsl(var(--primary, 37 100% 52%)); /* 橙色 #FFA00A */
}
/* 标题样式 */
.title {
font-weight: 600 !important;
font-family:
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
}
</style>
注意: 修改后需要重启开发服务器才能生效!
🔐 登录布局定制
自定义登录页
文件: apps/web-antd/src/layouts/auth.vue
主要特性:
- ✅ 橙色渐变背景 (
rgb(218,125,68)→#FFA00A) - ✅ 浮动插图动画(左侧)
- ✅ 表单卡片居右
- ✅ 支持 Light/Dark 主题
- ✅ 响应式布局
- ✅ 快速过渡动画
组件引用:
import { LanguageToggle, LoginIllustration, ThemeToggle } from '@vben/layouts';
详细文档: 参见 apps/web-antd/LOGIN_LAYOUT_README.md
登录页面
文件: apps/web-antd/src/views/_core/authentication/login.vue
功能:
- 用户名/密码登录
- 图形验证码
- 记住密码
- 第三方登录(手机、二维码)
表单配置示例:
const formSchema = computed((): VbenFormSchema[] => [
{
component: 'VbenInput',
fieldName: 'username',
label: $t('authentication.username'),
rules: z.string().min(1),
},
{
component: 'VbenInputPassword',
fieldName: 'password',
label: $t('authentication.password'),
rules: z.string().min(1),
},
// ...
]);
验证码登录/忘记密码
文件:
apps/web-antd/src/views/_core/authentication/code-login.vueapps/web-antd/src/views/_core/authentication/forget-password.vue
验证码组件 (VbenPinInput):
- ✅ 验证码长度: 6 位
- ✅ 发送前验证手机号
- ✅ 倒计时 60 秒
- ✅ 失败自动清除倒计时
修复: packages/@core/ui-kit/shadcn-ui/src/components/pin-input/input.vue
async function handleSend(e: Event) {
try {
e?.preventDefault();
// ✅ 先验证手机号
await handleSendCode();
// ✅ 验证成功后才开始倒计时
countdown.value = maxTime;
startCountdown();
} catch (error) {
// ✅ 失败清除倒计时
countdown.value = 0;
clearTimeout(timer.value);
}
}
🛠️ 开发调试指南
启动项目
# 安装依赖
pnpm install
# 启动开发服务器
pnpm dev
# 或者只启动 web-antd
pnpm --filter @vben/web-antd dev
构建项目
# 构建所有应用
pnpm build
# 只构建 web-antd
pnpm --filter @vben/web-antd build
代码规范
# ESLint 检查
pnpm lint
# 格式化代码
pnpm format
# 类型检查
pnpm typecheck
常用命令
# 清理所有 node_modules
pnpm clean
# 清理并重新安装
pnpm clean && pnpm install
# 查看依赖树
pnpm list --depth 0
# 更新依赖
pnpm update
调试技巧
1. Vue DevTools
安装 Vue DevTools 浏览器扩展,可以查看:
- 组件树
- Pinia 状态
- 路由信息
- 性能分析
2. 网络请求调试
打开浏览器开发者工具 Network 面板:
- 查看 API 请求/响应
- 检查请求头/响应头
- 查看接口耗时
3. 控制台调试
// 在组件中使用 console
console.log('当前路由:', router.currentRoute.value);
console.log('用户信息:', userStore.userInfo);
console.log('权限列表:', accessStore.accessCodes);
4. 断点调试
在 VS Code 中配置 .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}/apps/web-antd"
}
]
}
5. 性能分析
使用 Vue DevTools Performance 功能:
- 记录组件渲染时间
- 查找性能瓶颈
- 优化重渲染
📝 本次会话修改记录
1. 主题色定制 (#FFA00A - 橙色)
文件: packages/@core/preferences/src/constants.ts
// 新增 amber 主题色
const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [
{
color: 'hsl(37 100% 52%)', // #FFA00A
type: 'amber',
},
// ...
];
export const COLOR_PRESETS = [...BUILT_IN_THEME_PRESETS].slice(0, 8); // 7→8
文件: packages/@core/base/typings/src/app.d.ts
type BuiltinThemeType =
| 'amber' // ← 新增
| 'default';
// ...
文件: packages/@core/preferences/src/config.ts
const defaultPreferences: Preferences = {
theme: {
builtinType: 'amber', // ← 设为默认
colorPrimary: 'hsl(37 100% 52%)', // ← 设为默认
// ...
},
};
2. 登录布局重构
文件: apps/web-antd/src/layouts/auth.vue
完全重构,新增功能:
- ✅ 橙色渐变背景 (从
rgb(218,125,68)到#FFA00A) - ✅ 浮动插图组件 (左侧,带动画)
- ✅ 白色 Logo 文字,带阴影
- ✅ 表单卡片右对齐,垂直居中
- ✅ 快速过渡动画 (0.2s/0.15s)
- ✅ 响应式布局
- ✅ 保留原有 Toolbar (主题、语言切换)
关键代码:
<template>
<div class="relative flex h-screen w-full overflow-hidden font-sans">
<!-- 橙色渐变背景 -->
<div
class="to-[#FFA00A]/8 absolute inset-0 bg-gradient-to-r from-[rgb(218,125,68)] via-[#FFA00A]/30"
>
<!-- 浮动插图 -->
<div
class="absolute -left-[5%] top-1/2 hidden h-[48rem] w-[65%] -translate-y-1/2 lg:block"
>
<LoginIllustration :alt="appName" />
</div>
</div>
<!-- Logo - 白色字体 -->
<div class="absolute left-4 top-4">
<img :src="logo" :alt="appName" />
<span
class="text-xl font-semibold text-white drop-shadow-[0_2px_4px_rgba(0,0,0,0.3)]"
>
{{ appName }}
</span>
</div>
<!-- 登录卡片 - 右侧居中 -->
<div class="flex w-full flex-1 items-center justify-end">
<div class="w-full md:w-[480px] lg:mr-[10%]">
<div class="rounded-[2.5rem] p-8">
<RouterView />
</div>
</div>
</div>
</div>
</template>
<style scoped>
/* 快速过渡动画 */
.fade-enter-active {
transition:
opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1),
transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
</style>
备份文件: apps/web-antd/src/layouts/auth-original.vue
保留了原始布局,可随时切换回去。
3. 登录插图组件
文件: packages/effects/layouts/src/authentication/icons/login-illustration.vue
新建组件:
<script setup lang="ts">
defineOptions({
name: 'LoginIllustration',
});
defineProps<{
alt?: string;
}>();
</script>
<template>
<div class="login-illustration-container">
<img
src="/login-illustration.svg"
:alt="alt || 'Login Illustration'"
class="w-full animate-float opacity-40"
/>
</div>
</template>
<style scoped>
.login-illustration-container img {
transform: scale(1.2);
animation: float-smooth 3s ease-in-out 0ms infinite;
}
@keyframes float-smooth {
0%,
100% {
transform: scale(1.2) translateY(0);
}
50% {
transform: scale(1.2) translateY(-15px);
}
}
</style>
文件: packages/effects/layouts/src/authentication/index.ts
export { default as AuthPageLayout } from './authentication.vue';
export { default as LoginIllustration } from './icons/login-illustration.vue'; // ← 新增导出
export * from './types';
静态资源: apps/web-antd/public/login-illustration.svg
插图 SVG 文件放置在 public 目录。
4. 登录页优化
文件: apps/web-antd/src/views/_core/authentication/login.vue
修改内容:
- ✅ 移除内部标题,使用组件默认标题
- ✅ 新增"其他登录方式"分隔线
- ✅ 图标按钮样式统一
- ✅ 手机登录 + 二维码登录(微信已注释)
- ✅ 多语言支持
其他登录方式:
<template>
<div class="mt-8">
<!-- 分隔线 -->
<div class="relative mb-6 flex justify-center text-xs">
<span class="relative z-10 bg-background px-3">
{{ $t('authentication.otherLoginMethods') }}
</span>
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t"></div>
</div>
</div>
<!-- 登录按钮 -->
<div class="flex justify-center gap-8">
<!-- 手机登录 -->
<button
class="flex size-12 items-center justify-center rounded-2xl border bg-slate-50 transition-all hover:scale-110 hover:shadow-md"
@click="$router.push('/auth/code-login')"
>
<svg><!-- 手机图标 --></svg>
</button>
<!-- 二维码登录 -->
<button
class="flex size-12 items-center justify-center rounded-2xl border bg-slate-50 transition-all hover:scale-110 hover:shadow-md"
@click="$router.push('/auth/qrcode-login')"
>
<svg><!-- 二维码图标 --></svg>
</button>
<!-- 微信登录 (已注释) -->
<!-- <button ...>...</button> -->
</div>
</div>
</template>
5. 验证码功能修复
文件: packages/@core/ui-kit/shadcn-ui/src/components/pin-input/input.vue
问题: 点击"发送验证码"后立即开始倒计时,即使手机号验证失败。
修复: 先验证手机号,成功后才开始倒计时。
async function handleSend(e: Event) {
try {
e?.preventDefault();
// ✅ 先执行验证码发送逻辑(包含手机号验证)
await handleSendCode();
// ✅ 只有成功后才开始倒计时
countdown.value = maxTime;
startCountdown();
} catch (error) {
console.error('Failed to send code:', error);
// ✅ 如果发送失败,确保倒计时停止
countdown.value = 0;
clearTimeout(timer.value);
emit('sendError', error);
}
}
文件: apps/web-antd/src/views/_core/authentication/forget-password.vue
文件: apps/web-antd/src/views/_core/authentication/code-login.vue
修改: 验证码长度从 4 位改为 6 位。
const CODE_LENGTH = 6; // 4 → 6
6. 国际化新增
文件: packages/locales/src/langs/zh-CN/authentication.json
{
"otherLoginMethods": "或使用以下方式登录",
"contactSupport": "遇到问题?",
"support": "联系支持"
}
文件: packages/locales/src/langs/en-US/authentication.json
{
"otherLoginMethods": "Or sign in with",
"contactSupport": "Need help?",
"support": "Contact Support"
}
7. Loading 页面优化
文件: internal/vite-config/src/plugins/inject-app-loading/default-loading.html
问题:
- Loading 动画颜色先蓝后橙(闪烁)
- 标题字体粗细变化
修复:
<style data-app-loading="inject-css">
/* 修改主题色回退值为橙色 */
.loader::before {
background: hsl(var(--primary, 37 100% 52%) / 50%); /* 蓝色 → 橙色 */
}
.loader::after {
background: hsl(var(--primary, 37 100% 52%)); /* 蓝色 → 橙色 */
}
/* 锁定标题样式 */
.title {
font-weight: 600 !important;
font-family:
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
color: rgb(0 0 0 / 85%) !important;
}
.dark .title {
color: #fff !important;
}
</style>
注意: 修改后需要重启开发服务器才能生效!
📚 相关文档
🔍 快速查找
我要修改...
| 需求 | 文件位置 |
|---|---|
| 登录页布局 | apps/web-antd/src/layouts/auth.vue |
| 登录表单 | apps/web-antd/src/views/_core/authentication/login.vue |
| 验证码登录 | apps/web-antd/src/views/_core/authentication/code-login.vue |
| 忘记密码 | apps/web-antd/src/views/_core/authentication/forget-password.vue |
| 主题色 | packages/@core/preferences/src/constants.ts |
| Loading 页面 | internal/vite-config/src/plugins/inject-app-loading/default-loading.html |
| 国际化 | packages/locales/src/langs/zh-CN/*.json |
| 路由配置 | apps/web-antd/src/router/routes/ |
| API 接口 | apps/web-antd/src/api/ |
| 全局组件 | apps/web-antd/src/components/ |
| 工具函数 | apps/web-antd/src/utils/ |
| 状态管理 | apps/web-antd/src/store/ |
常见问题
Q: 如何切换回原始登录布局?
A: 修改路由配置,将 auth.vue 改为 auth-original.vue。
Q: 如何添加新的主题色?
A: 参见 主题定制 章节。
Q: 修改 Loading 页面后不生效?
A: 必须重启开发服务器 (Ctrl+C 然后 pnpm dev)。
Q: 如何自定义登录插图?
A: 替换 apps/web-antd/public/login-illustration.svg 文件。
Q: 验证码长度如何修改?
A: 修改对应页面的 CODE_LENGTH 常量。