2025-12-19 13:49:21 +08:00
|
|
|
|
# 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/ # 文档站点
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
2025-12-19 13:54:09 +08:00
|
|
|
|
| 技术 | 版本 | 说明 |
|
|
|
|
|
|
| -------------- | ---- | -------------------------- |
|
|
|
|
|
|
| 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 工具集 |
|
2025-12-19 13:49:21 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 📁 目录结构详解
|
|
|
|
|
|
|
|
|
|
|
|
### 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 组件:
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
// 导入方式
|
|
|
|
|
|
import {
|
|
|
|
|
|
VbenButton,
|
|
|
|
|
|
VbenInput,
|
|
|
|
|
|
VbenModal,
|
|
|
|
|
|
VbenToast,
|
|
|
|
|
|
VbenDropdown,
|
|
|
|
|
|
VbenSelect,
|
2025-12-19 13:54:09 +08:00
|
|
|
|
VbenPinInput, // 验证码输入框
|
2025-12-19 13:49:21 +08:00
|
|
|
|
VbenLoading,
|
|
|
|
|
|
VbenSpinner,
|
|
|
|
|
|
// ... 更多组件
|
|
|
|
|
|
} from '@vben-core/shadcn-ui';
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**常用组件**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- **按钮类**: `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`)
|
|
|
|
|
|
|
|
|
|
|
|
强大的表单构建器:
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
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`)
|
|
|
|
|
|
|
|
|
|
|
|
菜单组件,支持多级菜单、收缩展开等:
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
import { VbenMenu } from '@vben-core/menu-ui';
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 4. layout-ui (`packages/@core/ui-kit/layout-ui`)
|
|
|
|
|
|
|
|
|
|
|
|
布局组件(Header, Sidebar, Content, Footer):
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
import { BasicLayout, LayoutHeader, LayoutSidebar } from '@vben-core/layout-ui';
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 5. popup-ui (`packages/@core/ui-kit/popup-ui`)
|
|
|
|
|
|
|
|
|
|
|
|
弹窗、抽屉组件:
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
import { VbenModal, VbenDrawer } from '@vben-core/popup-ui';
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### packages/effects/ - 业务效果包
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. layouts (`packages/effects/layouts`)
|
|
|
|
|
|
|
|
|
|
|
|
布局组件和小部件:
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
import {
|
|
|
|
|
|
// 布局组件
|
2025-12-19 13:54:09 +08:00
|
|
|
|
AuthPageLayout, // 认证页布局
|
|
|
|
|
|
LoginIllustration, // 登录插图 (自定义新增)
|
|
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
// 小部件
|
2025-12-19 13:54:09 +08:00
|
|
|
|
ThemeToggle, // 主题切换
|
|
|
|
|
|
LanguageToggle, // 语言切换
|
|
|
|
|
|
ColorToggle, // 颜色选择器
|
|
|
|
|
|
LayoutToggle, // 布局切换
|
|
|
|
|
|
UserDropdown, // 用户下拉菜单
|
|
|
|
|
|
Breadcrumb, // 面包屑
|
|
|
|
|
|
GlobalSearch, // 全局搜索
|
|
|
|
|
|
LockScreen, // 锁屏
|
|
|
|
|
|
Notification, // 通知
|
2025-12-19 13:49:21 +08:00
|
|
|
|
} from '@vben/layouts';
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**目录结构**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```
|
|
|
|
|
|
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 组件:
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
import {
|
|
|
|
|
|
// 认证组件
|
2025-12-19 13:54:09 +08:00
|
|
|
|
AuthenticationLogin, // 登录表单
|
|
|
|
|
|
AuthenticationCodeLogin, // 验证码登录
|
2025-12-19 13:49:21 +08:00
|
|
|
|
AuthenticationForgetPassword, // 忘记密码
|
2025-12-19 13:54:09 +08:00
|
|
|
|
AuthenticationRegister, // 注册
|
|
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
// 其他通用组件
|
2025-12-19 13:54:09 +08:00
|
|
|
|
Page, // 页面容器
|
|
|
|
|
|
DocAlert, // 文档提醒
|
|
|
|
|
|
Description, // 描述列表
|
|
|
|
|
|
Ellipsis, // 文本省略
|
|
|
|
|
|
Iframe, // 内嵌页面
|
2025-12-19 13:49:21 +08:00
|
|
|
|
// ...
|
|
|
|
|
|
} from '@vben/common-ui';
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. hooks (`packages/effects/hooks`)
|
|
|
|
|
|
|
|
|
|
|
|
业务相关的 Composition API 钩子:
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
import {
|
2025-12-19 13:54:09 +08:00
|
|
|
|
useWatermark, // 水印
|
|
|
|
|
|
useTabs, // 标签页管理
|
|
|
|
|
|
useContentHeight, // 内容高度自适应
|
|
|
|
|
|
isTenantEnable, // 租户功能是否启用
|
2025-12-19 13:49:21 +08:00
|
|
|
|
} from '@vben/hooks';
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 4. access (`packages/effects/access`)
|
|
|
|
|
|
|
|
|
|
|
|
权限控制:
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
import { useAccess } from '@vben/access';
|
|
|
|
|
|
|
|
|
|
|
|
// 权限检查
|
|
|
|
|
|
const { hasAccessByRoles, hasAccessByCodes } = useAccess();
|
|
|
|
|
|
|
|
|
|
|
|
// 指令方式
|
|
|
|
|
|
<button v-access="'system:user:create'">创建用户</button>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### packages/其他包
|
|
|
|
|
|
|
|
|
|
|
|
#### locales - 国际化
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
import { $t, setupI18n } from '@vben/locales';
|
|
|
|
|
|
|
|
|
|
|
|
// 使用翻译
|
|
|
|
|
|
$t('authentication.login');
|
|
|
|
|
|
$t('authentication.username');
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**语言包位置**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- 中文: `packages/locales/src/langs/zh-CN/*.json`
|
|
|
|
|
|
- 英文: `packages/locales/src/langs/en-US/*.json`
|
|
|
|
|
|
|
|
|
|
|
|
#### stores - 状态管理
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
import {
|
2025-12-19 13:54:09 +08:00
|
|
|
|
useUserStore, // 用户信息
|
|
|
|
|
|
useAccessStore, // 权限信息
|
|
|
|
|
|
useTabsStore, // 标签页
|
|
|
|
|
|
useAppStore, // 应用配置
|
2025-12-19 13:49:21 +08:00
|
|
|
|
} from '@vben/stores';
|
|
|
|
|
|
|
|
|
|
|
|
const userStore = useUserStore();
|
|
|
|
|
|
await userStore.fetchUserInfo();
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### preferences - 偏好设置
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
import {
|
2025-12-19 13:54:09 +08:00
|
|
|
|
preferences, // 偏好设置对象
|
|
|
|
|
|
updatePreferences, // 更新偏好设置
|
|
|
|
|
|
usePreferences, // 响应式偏好设置
|
2025-12-19 13:49:21 +08:00
|
|
|
|
} from '@vben/preferences';
|
|
|
|
|
|
|
|
|
|
|
|
// 读取
|
|
|
|
|
|
const isDark = preferences.theme.mode === 'dark';
|
|
|
|
|
|
|
|
|
|
|
|
// 更新
|
|
|
|
|
|
updatePreferences({
|
|
|
|
|
|
theme: {
|
|
|
|
|
|
colorPrimary: '#FFA00A',
|
|
|
|
|
|
builtinType: 'amber',
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### utils - 工具函数
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
import {
|
|
|
|
|
|
// 路由工具
|
|
|
|
|
|
mapTree,
|
|
|
|
|
|
resetRoutes,
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
// 通用工具
|
|
|
|
|
|
formatDate,
|
|
|
|
|
|
formatDateTime,
|
|
|
|
|
|
openWindow,
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
// 验证器
|
|
|
|
|
|
isEmail,
|
|
|
|
|
|
isPhone,
|
|
|
|
|
|
isUrl,
|
|
|
|
|
|
} from '@vben/utils';
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### constants - 常量定义
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
import {
|
|
|
|
|
|
// 核心常量
|
|
|
|
|
|
LOGIN_PATH,
|
|
|
|
|
|
VBEN_DOC_URL,
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
// 业务枚举
|
|
|
|
|
|
DictEnum,
|
|
|
|
|
|
SystemEnum,
|
|
|
|
|
|
BpmEnum,
|
|
|
|
|
|
// ...
|
|
|
|
|
|
} from '@vben/constants';
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## ⚙️ 配置文件说明
|
|
|
|
|
|
|
|
|
|
|
|
### 1. Vite 配置 (`vite.config.mts`)
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
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`)
|
|
|
|
|
|
|
|
|
|
|
|
```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"]
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**路径别名**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- `#/*` → `./src/*` (应用内部)
|
|
|
|
|
|
- `@vben/*` → `packages/*` (公共包)
|
|
|
|
|
|
|
|
|
|
|
|
### 3. Tailwind 配置 (`tailwind.config.mjs`)
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
import { defineConfig } from '@vben/tailwind-config';
|
|
|
|
|
|
|
|
|
|
|
|
export default defineConfig({
|
|
|
|
|
|
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
|
|
|
|
|
|
// 自定义配置...
|
|
|
|
|
|
});
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 环境变量 (`.env.*`)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# .env.development
|
|
|
|
|
|
VITE_APP_TITLE=芋道管理系统
|
|
|
|
|
|
VITE_APP_BASE_API=/admin-api
|
|
|
|
|
|
VITE_APP_NAMESPACE=vben-web-antd
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🎨 主题定制
|
|
|
|
|
|
|
|
|
|
|
|
### 1. 新增主题色
|
|
|
|
|
|
|
|
|
|
|
|
**文件**: `packages/@core/preferences/src/constants.ts`
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [
|
|
|
|
|
|
{
|
2025-12-19 13:54:09 +08:00
|
|
|
|
color: 'hsl(37 100% 52%)', // #FFA00A
|
2025-12-19 13:49:21 +08:00
|
|
|
|
type: 'amber',
|
|
|
|
|
|
},
|
|
|
|
|
|
// ... 其他颜色
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
export const COLOR_PRESETS = [...BUILT_IN_THEME_PRESETS].slice(0, 8);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**类型定义**: `packages/@core/base/typings/src/app.d.ts`
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
type BuiltinThemeType =
|
2025-12-19 13:54:09 +08:00
|
|
|
|
| 'amber' // 新增
|
2025-12-19 13:49:21 +08:00
|
|
|
|
| 'default'
|
|
|
|
|
|
| 'orange'
|
|
|
|
|
|
| 'red'
|
|
|
|
|
|
// ...
|
|
|
|
|
|
| (Record<never, never> & string);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**默认主题**: `packages/@core/preferences/src/config.ts`
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
const defaultPreferences: Preferences = {
|
|
|
|
|
|
theme: {
|
2025-12-19 13:54:09 +08:00
|
|
|
|
builtinType: 'amber', // 默认主题类型
|
2025-12-19 13:49:21 +08:00
|
|
|
|
colorPrimary: 'hsl(37 100% 52%)', // 主色调
|
2025-12-19 13:54:09 +08:00
|
|
|
|
mode: 'dark', // 暗色模式
|
|
|
|
|
|
radius: '0.5', // 圆角
|
2025-12-19 13:49:21 +08:00
|
|
|
|
},
|
|
|
|
|
|
// ...
|
|
|
|
|
|
};
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2. Loading 页面定制
|
|
|
|
|
|
|
|
|
|
|
|
**文件**: `internal/vite-config/src/plugins/inject-app-loading/default-loading.html`
|
|
|
|
|
|
|
|
|
|
|
|
```html
|
|
|
|
|
|
<style data-app-loading="inject-css">
|
|
|
|
|
|
/* 主题色 */
|
|
|
|
|
|
.loader::after {
|
|
|
|
|
|
background: hsl(var(--primary, 37 100% 52%)); /* 橙色 #FFA00A */
|
|
|
|
|
|
}
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
/* 标题样式 */
|
|
|
|
|
|
.title {
|
|
|
|
|
|
font-weight: 600 !important;
|
2025-12-19 13:54:09 +08:00
|
|
|
|
font-family:
|
|
|
|
|
|
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
|
2025-12-19 13:49:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
</style>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**注意**: 修改后需要**重启开发服务器**才能生效!
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🔐 登录布局定制
|
|
|
|
|
|
|
|
|
|
|
|
### 自定义登录页
|
|
|
|
|
|
|
|
|
|
|
|
**文件**: `apps/web-antd/src/layouts/auth.vue`
|
|
|
|
|
|
|
|
|
|
|
|
**主要特性**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- ✅ 橙色渐变背景 (`rgb(218,125,68)` → `#FFA00A`)
|
|
|
|
|
|
- ✅ 浮动插图动画(左侧)
|
|
|
|
|
|
- ✅ 表单卡片居右
|
|
|
|
|
|
- ✅ 支持 Light/Dark 主题
|
|
|
|
|
|
- ✅ 响应式布局
|
|
|
|
|
|
- ✅ 快速过渡动画
|
|
|
|
|
|
|
|
|
|
|
|
**组件引用**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```typescript
|
2025-12-19 13:54:09 +08:00
|
|
|
|
import { LanguageToggle, LoginIllustration, ThemeToggle } from '@vben/layouts';
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**详细文档**: 参见 `apps/web-antd/LOGIN_LAYOUT_README.md`
|
|
|
|
|
|
|
|
|
|
|
|
### 登录页面
|
|
|
|
|
|
|
|
|
|
|
|
**文件**: `apps/web-antd/src/views/_core/authentication/login.vue`
|
|
|
|
|
|
|
|
|
|
|
|
**功能**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- 用户名/密码登录
|
|
|
|
|
|
- 图形验证码
|
|
|
|
|
|
- 记住密码
|
|
|
|
|
|
- 第三方登录(手机、二维码)
|
|
|
|
|
|
|
|
|
|
|
|
**表单配置示例**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```typescript
|
|
|
|
|
|
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),
|
|
|
|
|
|
},
|
|
|
|
|
|
// ...
|
|
|
|
|
|
]);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 验证码登录/忘记密码
|
|
|
|
|
|
|
|
|
|
|
|
**文件**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- `apps/web-antd/src/views/_core/authentication/code-login.vue`
|
|
|
|
|
|
- `apps/web-antd/src/views/_core/authentication/forget-password.vue`
|
|
|
|
|
|
|
|
|
|
|
|
**验证码组件** (`VbenPinInput`):
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- ✅ 验证码长度: 6 位
|
|
|
|
|
|
- ✅ 发送前验证手机号
|
|
|
|
|
|
- ✅ 倒计时 60 秒
|
|
|
|
|
|
- ✅ 失败自动清除倒计时
|
|
|
|
|
|
|
|
|
|
|
|
**修复**: `packages/@core/ui-kit/shadcn-ui/src/components/pin-input/input.vue`
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```typescript
|
|
|
|
|
|
async function handleSend(e: Event) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
e?.preventDefault();
|
|
|
|
|
|
// ✅ 先验证手机号
|
|
|
|
|
|
await handleSendCode();
|
|
|
|
|
|
// ✅ 验证成功后才开始倒计时
|
|
|
|
|
|
countdown.value = maxTime;
|
|
|
|
|
|
startCountdown();
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
// ✅ 失败清除倒计时
|
|
|
|
|
|
countdown.value = 0;
|
|
|
|
|
|
clearTimeout(timer.value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🛠️ 开发调试指南
|
|
|
|
|
|
|
|
|
|
|
|
### 启动项目
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 安装依赖
|
|
|
|
|
|
pnpm install
|
|
|
|
|
|
|
|
|
|
|
|
# 启动开发服务器
|
|
|
|
|
|
pnpm dev
|
|
|
|
|
|
|
|
|
|
|
|
# 或者只启动 web-antd
|
|
|
|
|
|
pnpm --filter @vben/web-antd dev
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 构建项目
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 构建所有应用
|
|
|
|
|
|
pnpm build
|
|
|
|
|
|
|
|
|
|
|
|
# 只构建 web-antd
|
|
|
|
|
|
pnpm --filter @vben/web-antd build
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 代码规范
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# ESLint 检查
|
|
|
|
|
|
pnpm lint
|
|
|
|
|
|
|
|
|
|
|
|
# 格式化代码
|
|
|
|
|
|
pnpm format
|
|
|
|
|
|
|
|
|
|
|
|
# 类型检查
|
|
|
|
|
|
pnpm typecheck
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 常用命令
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 清理所有 node_modules
|
|
|
|
|
|
pnpm clean
|
|
|
|
|
|
|
|
|
|
|
|
# 清理并重新安装
|
|
|
|
|
|
pnpm clean && pnpm install
|
|
|
|
|
|
|
|
|
|
|
|
# 查看依赖树
|
|
|
|
|
|
pnpm list --depth 0
|
|
|
|
|
|
|
|
|
|
|
|
# 更新依赖
|
|
|
|
|
|
pnpm update
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 调试技巧
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. Vue DevTools
|
|
|
|
|
|
|
|
|
|
|
|
安装 Vue DevTools 浏览器扩展,可以查看:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- 组件树
|
|
|
|
|
|
- Pinia 状态
|
|
|
|
|
|
- 路由信息
|
|
|
|
|
|
- 性能分析
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 网络请求调试
|
|
|
|
|
|
|
|
|
|
|
|
打开浏览器开发者工具 Network 面板:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- 查看 API 请求/响应
|
|
|
|
|
|
- 检查请求头/响应头
|
|
|
|
|
|
- 查看接口耗时
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. 控制台调试
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
// 在组件中使用 console
|
|
|
|
|
|
console.log('当前路由:', router.currentRoute.value);
|
|
|
|
|
|
console.log('用户信息:', userStore.userInfo);
|
|
|
|
|
|
console.log('权限列表:', accessStore.accessCodes);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 4. 断点调试
|
|
|
|
|
|
|
|
|
|
|
|
在 VS Code 中配置 `.vscode/launch.json`:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```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 功能:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- 记录组件渲染时间
|
|
|
|
|
|
- 查找性能瓶颈
|
|
|
|
|
|
- 优化重渲染
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 📝 本次会话修改记录
|
|
|
|
|
|
|
|
|
|
|
|
### 1. 主题色定制 (#FFA00A - 橙色)
|
|
|
|
|
|
|
|
|
|
|
|
#### 文件: `packages/@core/preferences/src/constants.ts`
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```typescript
|
|
|
|
|
|
// 新增 amber 主题色
|
|
|
|
|
|
const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [
|
|
|
|
|
|
{
|
2025-12-19 13:54:09 +08:00
|
|
|
|
color: 'hsl(37 100% 52%)', // #FFA00A
|
2025-12-19 13:49:21 +08:00
|
|
|
|
type: 'amber',
|
|
|
|
|
|
},
|
|
|
|
|
|
// ...
|
|
|
|
|
|
];
|
|
|
|
|
|
export const COLOR_PRESETS = [...BUILT_IN_THEME_PRESETS].slice(0, 8); // 7→8
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 文件: `packages/@core/base/typings/src/app.d.ts`
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```typescript
|
|
|
|
|
|
type BuiltinThemeType =
|
2025-12-19 13:54:09 +08:00
|
|
|
|
| 'amber' // ← 新增
|
|
|
|
|
|
| 'default';
|
|
|
|
|
|
// ...
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 文件: `packages/@core/preferences/src/config.ts`
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```typescript
|
|
|
|
|
|
const defaultPreferences: Preferences = {
|
|
|
|
|
|
theme: {
|
2025-12-19 13:54:09 +08:00
|
|
|
|
builtinType: 'amber', // ← 设为默认
|
2025-12-19 13:49:21 +08:00
|
|
|
|
colorPrimary: 'hsl(37 100% 52%)', // ← 设为默认
|
|
|
|
|
|
// ...
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 登录布局重构
|
|
|
|
|
|
|
|
|
|
|
|
#### 文件: `apps/web-antd/src/layouts/auth.vue`
|
|
|
|
|
|
|
|
|
|
|
|
**完全重构,新增功能**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- ✅ 橙色渐变背景 (从 `rgb(218,125,68)` 到 `#FFA00A`)
|
|
|
|
|
|
- ✅ 浮动插图组件 (左侧,带动画)
|
|
|
|
|
|
- ✅ 白色 Logo 文字,带阴影
|
|
|
|
|
|
- ✅ 表单卡片右对齐,垂直居中
|
|
|
|
|
|
- ✅ 快速过渡动画 (0.2s/0.15s)
|
|
|
|
|
|
- ✅ 响应式布局
|
|
|
|
|
|
- ✅ 保留原有 Toolbar (主题、语言切换)
|
|
|
|
|
|
|
|
|
|
|
|
**关键代码**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```vue
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<div class="relative flex h-screen w-full overflow-hidden font-sans">
|
|
|
|
|
|
<!-- 橙色渐变背景 -->
|
2025-12-19 13:54:09 +08:00
|
|
|
|
<div
|
|
|
|
|
|
class="to-[#FFA00A]/8 absolute inset-0 bg-gradient-to-r from-[rgb(218,125,68)] via-[#FFA00A]/30"
|
|
|
|
|
|
>
|
2025-12-19 13:49:21 +08:00
|
|
|
|
<!-- 浮动插图 -->
|
2025-12-19 13:54:09 +08:00
|
|
|
|
<div
|
|
|
|
|
|
class="absolute -left-[5%] top-1/2 hidden h-[48rem] w-[65%] -translate-y-1/2 lg:block"
|
|
|
|
|
|
>
|
2025-12-19 13:49:21 +08:00
|
|
|
|
<LoginIllustration :alt="appName" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
<!-- Logo - 白色字体 -->
|
|
|
|
|
|
<div class="absolute left-4 top-4">
|
|
|
|
|
|
<img :src="logo" :alt="appName" />
|
2025-12-19 13:54:09 +08:00
|
|
|
|
<span
|
|
|
|
|
|
class="text-xl font-semibold text-white drop-shadow-[0_2px_4px_rgba(0,0,0,0.3)]"
|
|
|
|
|
|
>
|
2025-12-19 13:49:21 +08:00
|
|
|
|
{{ appName }}
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</div>
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
<!-- 登录卡片 - 右侧居中 -->
|
|
|
|
|
|
<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`
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
保留了原始布局,可随时切换回去。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 登录插图组件
|
|
|
|
|
|
|
|
|
|
|
|
#### 文件: `packages/effects/layouts/src/authentication/icons/login-illustration.vue`
|
|
|
|
|
|
|
|
|
|
|
|
**新建组件**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```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'"
|
2025-12-19 13:54:09 +08:00
|
|
|
|
class="w-full animate-float opacity-40"
|
2025-12-19 13:49:21 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.login-illustration-container img {
|
|
|
|
|
|
transform: scale(1.2);
|
|
|
|
|
|
animation: float-smooth 3s ease-in-out 0ms infinite;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@keyframes float-smooth {
|
2025-12-19 13:54:09 +08:00
|
|
|
|
0%,
|
|
|
|
|
|
100% {
|
2025-12-19 13:49:21 +08:00
|
|
|
|
transform: scale(1.2) translateY(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
50% {
|
|
|
|
|
|
transform: scale(1.2) translateY(-15px);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 文件: `packages/effects/layouts/src/authentication/index.ts`
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```typescript
|
|
|
|
|
|
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`
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
插图 SVG 文件放置在 public 目录。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 登录页优化
|
|
|
|
|
|
|
|
|
|
|
|
#### 文件: `apps/web-antd/src/views/_core/authentication/login.vue`
|
|
|
|
|
|
|
|
|
|
|
|
**修改内容**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- ✅ 移除内部标题,使用组件默认标题
|
|
|
|
|
|
- ✅ 新增"其他登录方式"分隔线
|
|
|
|
|
|
- ✅ 图标按钮样式统一
|
|
|
|
|
|
- ✅ 手机登录 + 二维码登录(微信已注释)
|
|
|
|
|
|
- ✅ 多语言支持
|
|
|
|
|
|
|
|
|
|
|
|
**其他登录方式**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```vue
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<div class="mt-8">
|
|
|
|
|
|
<!-- 分隔线 -->
|
|
|
|
|
|
<div class="relative mb-6 flex justify-center text-xs">
|
2025-12-19 13:54:09 +08:00
|
|
|
|
<span class="relative z-10 bg-background px-3">
|
2025-12-19 13:49:21 +08:00
|
|
|
|
{{ $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
|
2025-12-19 13:54:09 +08:00
|
|
|
|
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')"
|
|
|
|
|
|
>
|
2025-12-19 13:49:21 +08:00
|
|
|
|
<svg><!-- 手机图标 --></svg>
|
|
|
|
|
|
</button>
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
<!-- 二维码登录 -->
|
|
|
|
|
|
<button
|
2025-12-19 13:54:09 +08:00
|
|
|
|
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')"
|
|
|
|
|
|
>
|
2025-12-19 13:49:21 +08:00
|
|
|
|
<svg><!-- 二维码图标 --></svg>
|
|
|
|
|
|
</button>
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
<!-- 微信登录 (已注释) -->
|
|
|
|
|
|
<!-- <button ...>...</button> -->
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### 5. 验证码功能修复
|
|
|
|
|
|
|
|
|
|
|
|
#### 文件: `packages/@core/ui-kit/shadcn-ui/src/components/pin-input/input.vue`
|
|
|
|
|
|
|
|
|
|
|
|
**问题**: 点击"发送验证码"后立即开始倒计时,即使手机号验证失败。
|
|
|
|
|
|
|
|
|
|
|
|
**修复**: 先验证手机号,成功后才开始倒计时。
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
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`
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
#### 文件: `apps/web-antd/src/views/_core/authentication/code-login.vue`
|
|
|
|
|
|
|
|
|
|
|
|
**修改**: 验证码长度从 4 位改为 6 位。
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
2025-12-19 13:54:09 +08:00
|
|
|
|
const CODE_LENGTH = 6; // 4 → 6
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### 6. 国际化新增
|
|
|
|
|
|
|
|
|
|
|
|
#### 文件: `packages/locales/src/langs/zh-CN/authentication.json`
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"otherLoginMethods": "或使用以下方式登录",
|
|
|
|
|
|
"contactSupport": "遇到问题?",
|
|
|
|
|
|
"support": "联系支持"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 文件: `packages/locales/src/langs/en-US/authentication.json`
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```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`
|
|
|
|
|
|
|
2025-12-19 13:54:09 +08:00
|
|
|
|
**问题**:
|
|
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
- Loading 动画颜色先蓝后橙(闪烁)
|
|
|
|
|
|
- 标题字体粗细变化
|
|
|
|
|
|
|
|
|
|
|
|
**修复**:
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
```html
|
|
|
|
|
|
<style data-app-loading="inject-css">
|
|
|
|
|
|
/* 修改主题色回退值为橙色 */
|
|
|
|
|
|
.loader::before {
|
|
|
|
|
|
background: hsl(var(--primary, 37 100% 52%) / 50%); /* 蓝色 → 橙色 */
|
|
|
|
|
|
}
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
.loader::after {
|
|
|
|
|
|
background: hsl(var(--primary, 37 100% 52%)); /* 蓝色 → 橙色 */
|
|
|
|
|
|
}
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
/* 锁定标题样式 */
|
|
|
|
|
|
.title {
|
|
|
|
|
|
font-weight: 600 !important;
|
2025-12-19 13:54:09 +08:00
|
|
|
|
font-family:
|
|
|
|
|
|
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
|
2025-12-19 13:49:21 +08:00
|
|
|
|
color: rgb(0 0 0 / 85%) !important;
|
|
|
|
|
|
}
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
.dark .title {
|
|
|
|
|
|
color: #fff !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**注意**: 修改后需要**重启开发服务器**才能生效!
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 📚 相关文档
|
|
|
|
|
|
|
|
|
|
|
|
- [登录布局详细说明](./LOGIN_LAYOUT_README.md)
|
|
|
|
|
|
- [项目官方文档](https://doc.vben.pro)
|
|
|
|
|
|
- [Vite 文档](https://vitejs.dev)
|
|
|
|
|
|
- [Vue 3 文档](https://vuejs.org)
|
|
|
|
|
|
- [Ant Design Vue 文档](https://antdv.com)
|
|
|
|
|
|
- [Tailwind CSS 文档](https://tailwindcss.com)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🔍 快速查找
|
|
|
|
|
|
|
|
|
|
|
|
### 我要修改...
|
|
|
|
|
|
|
|
|
|
|
|
| 需求 | 文件位置 |
|
2025-12-19 13:54:09 +08:00
|
|
|
|
| --- | --- |
|
2025-12-19 13:49:21 +08:00
|
|
|
|
| **登录页布局** | `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: 如何切换回原始登录布局?
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
A: 修改路由配置,将 `auth.vue` 改为 `auth-original.vue`。
|
|
|
|
|
|
|
|
|
|
|
|
#### Q: 如何添加新的主题色?
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
A: 参见 [主题定制](#主题定制) 章节。
|
|
|
|
|
|
|
|
|
|
|
|
#### Q: 修改 Loading 页面后不生效?
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
A: 必须重启开发服务器 (`Ctrl+C` 然后 `pnpm dev`)。
|
|
|
|
|
|
|
|
|
|
|
|
#### Q: 如何自定义登录插图?
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
A: 替换 `apps/web-antd/public/login-illustration.svg` 文件。
|
|
|
|
|
|
|
|
|
|
|
|
#### Q: 验证码长度如何修改?
|
2025-12-19 13:54:09 +08:00
|
|
|
|
|
2025-12-19 13:49:21 +08:00
|
|
|
|
A: 修改对应页面的 `CODE_LENGTH` 常量。
|
|
|
|
|
|
|
|
|
|
|
|
---
|