313 lines
6.5 KiB
Markdown
313 lines
6.5 KiB
Markdown
# 管理后台前端开发指南
|
|
|
|
## 项目概述
|
|
|
|
情绪博物馆管理后台是一个基于 Vue 3 + TypeScript + Element Plus 的现代化管理系统,用于管理系统的管理员、用户和数据。
|
|
|
|
## 快速开始
|
|
|
|
### 1. 安装依赖
|
|
|
|
```bash
|
|
cd web-admin
|
|
npm install
|
|
```
|
|
|
|
### 2. 启动开发服务器
|
|
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
访问 http://localhost:5174
|
|
|
|
### 3. 登录系统
|
|
|
|
使用默认账号登录:
|
|
- 账号: admin
|
|
- 密码: admin123
|
|
|
|
## 项目结构
|
|
|
|
```
|
|
web-admin/
|
|
├── src/
|
|
│ ├── api/ # API接口定义
|
|
│ │ ├── admin.ts # 管理员API
|
|
│ │ ├── auth.ts # 认证API
|
|
│ │ └── user.ts # 用户API
|
|
│ ├── layouts/ # 布局组件
|
|
│ │ └── Layout.vue # 主布局
|
|
│ ├── router/ # 路由配置
|
|
│ │ └── index.ts # 路由定义
|
|
│ ├── stores/ # 状态管理
|
|
│ │ ├── index.ts # Pinia实例
|
|
│ │ └── admin.ts # 管理员状态
|
|
│ ├── types/ # TypeScript类型
|
|
│ │ ├── admin.ts # 管理员类型
|
|
│ │ ├── common.ts # 通用类型
|
|
│ │ ├── env.d.ts # 环境变量类型
|
|
│ │ └── user.ts # 用户类型
|
|
│ ├── utils/ # 工具函数
|
|
│ │ ├── request.ts # Axios封装
|
|
│ │ ├── storage.ts # 本地存储
|
|
│ │ └── validate.ts # 表单验证
|
|
│ ├── views/ # 页面组件
|
|
│ │ ├── admin/ # 管理员管理
|
|
│ │ │ └── AdminList.vue
|
|
│ │ ├── user/ # 用户管理
|
|
│ │ │ └── UserList.vue
|
|
│ │ ├── Dashboard.vue # 仪表盘
|
|
│ │ ├── Login.vue # 登录页
|
|
│ │ └── NotFound.vue # 404页面
|
|
│ ├── App.vue # 根组件
|
|
│ └── main.ts # 入口文件
|
|
├── .env.development # 开发环境配置
|
|
├── .env.production # 生产环境配置
|
|
├── index.html # HTML模板
|
|
├── package.json # 项目配置
|
|
├── tsconfig.json # TypeScript配置
|
|
└── vite.config.ts # Vite配置
|
|
```
|
|
|
|
## 核心功能
|
|
|
|
### 1. 登录认证
|
|
|
|
登录流程:
|
|
1. 用户输入账号密码
|
|
2. 调用登录API
|
|
3. 保存Token到localStorage
|
|
4. 保存管理员信息到Pinia
|
|
5. 跳转到仪表盘
|
|
|
|
代码示例:
|
|
```typescript
|
|
// stores/admin.ts
|
|
const login = async (loginForm: AdminLoginRequest) => {
|
|
const res = await loginApi(loginForm)
|
|
token.value = res.data.accessToken
|
|
adminInfo.value = res.data.adminInfo
|
|
localStorage.setItem('adminToken', res.data.accessToken)
|
|
router.push('/')
|
|
}
|
|
```
|
|
|
|
### 2. 路由守卫
|
|
|
|
所有路由都需要登录才能访问(除了登录页):
|
|
|
|
```typescript
|
|
// router/index.ts
|
|
router.beforeEach((to, from, next) => {
|
|
const token = localStorage.getItem('adminToken')
|
|
|
|
if (to.path === '/login') {
|
|
if (token) {
|
|
next('/')
|
|
} else {
|
|
next()
|
|
}
|
|
} else {
|
|
if (token) {
|
|
next()
|
|
} else {
|
|
next('/login')
|
|
}
|
|
}
|
|
})
|
|
```
|
|
|
|
### 3. API请求拦截
|
|
|
|
自动添加Token到请求头:
|
|
|
|
```typescript
|
|
// utils/request.ts
|
|
service.interceptors.request.use((config) => {
|
|
const token = localStorage.getItem('adminToken')
|
|
if (token) {
|
|
config.headers.Authorization = `Bearer ${token}`
|
|
}
|
|
return config
|
|
})
|
|
```
|
|
|
|
### 4. 响应拦截
|
|
|
|
统一处理错误:
|
|
|
|
```typescript
|
|
service.interceptors.response.use(
|
|
(response) => {
|
|
const res = response.data
|
|
if (res.code !== 200) {
|
|
ElMessage.error(res.message)
|
|
if (res.code === 401) {
|
|
router.push('/login')
|
|
}
|
|
return Promise.reject(new Error(res.message))
|
|
}
|
|
return res
|
|
},
|
|
(error) => {
|
|
// 错误处理
|
|
}
|
|
)
|
|
```
|
|
|
|
## 开发规范
|
|
|
|
### 1. 命名规范
|
|
|
|
- 组件名:PascalCase (如 AdminList.vue)
|
|
- 文件名:kebab-case (如 admin-list.ts)
|
|
- 变量名:camelCase (如 adminInfo)
|
|
- 常量名:UPPER_CASE (如 API_BASE_URL)
|
|
|
|
### 2. 类型定义
|
|
|
|
所有API接口都应该有类型定义:
|
|
|
|
```typescript
|
|
// types/admin.ts
|
|
export interface Admin {
|
|
id: string
|
|
account: string
|
|
username: string
|
|
// ...
|
|
}
|
|
|
|
export interface AdminPageRequest {
|
|
current: number
|
|
size: number
|
|
// ...
|
|
}
|
|
```
|
|
|
|
### 3. API调用
|
|
|
|
使用封装的request工具:
|
|
|
|
```typescript
|
|
// api/admin.ts
|
|
export function getAdminPage(params: AdminPageRequest) {
|
|
return request<ApiResponse<PageResult<Admin>>>({
|
|
url: '/admin/page',
|
|
method: 'get',
|
|
params
|
|
})
|
|
}
|
|
```
|
|
|
|
### 4. 状态管理
|
|
|
|
使用Pinia进行状态管理:
|
|
|
|
```typescript
|
|
// stores/admin.ts
|
|
export const useAdminStore = defineStore('admin', () => {
|
|
const token = ref<string>('')
|
|
const adminInfo = ref<Admin | null>(null)
|
|
|
|
const login = async (loginForm: AdminLoginRequest) => {
|
|
// ...
|
|
}
|
|
|
|
return { token, adminInfo, login }
|
|
})
|
|
```
|
|
|
|
## 常见问题
|
|
|
|
### 1. Token过期处理
|
|
|
|
Token过期时会自动跳转到登录页,用户需要重新登录。
|
|
|
|
### 2. 跨域问题
|
|
|
|
开发环境通过Vite代理解决:
|
|
|
|
```typescript
|
|
// vite.config.ts
|
|
server: {
|
|
proxy: {
|
|
'/api': {
|
|
target: 'http://localhost:8080',
|
|
changeOrigin: true
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. 构建优化
|
|
|
|
生产环境构建时会自动进行代码分割和压缩:
|
|
|
|
```bash
|
|
npm run build
|
|
```
|
|
|
|
## 部署
|
|
|
|
### 1. 构建
|
|
|
|
```bash
|
|
npm run build
|
|
```
|
|
|
|
### 2. Nginx配置
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
server_name admin.emotion-museum.com;
|
|
|
|
root /var/www/web-admin/dist;
|
|
index index.html;
|
|
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
|
|
location /api {
|
|
proxy_pass http://localhost:8080;
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. 环境变量
|
|
|
|
生产环境需要配置正确的API地址:
|
|
|
|
```
|
|
VITE_APP_BASE_API=https://api.emotion-museum.com
|
|
```
|
|
|
|
## 扩展功能
|
|
|
|
### 添加新页面
|
|
|
|
1. 在 `views` 目录创建新组件
|
|
2. 在 `router/index.ts` 添加路由
|
|
3. 在布局组件的菜单中添加入口
|
|
|
|
### 添加新API
|
|
|
|
1. 在 `types` 目录定义类型
|
|
2. 在 `api` 目录创建API函数
|
|
3. 在组件中调用API
|
|
|
|
### 添加新状态
|
|
|
|
1. 在 `stores` 目录创建新的store
|
|
2. 在组件中使用store
|
|
|
|
## 技术支持
|
|
|
|
如有问题,请查看:
|
|
- [Vue 3 文档](https://cn.vuejs.org/)
|
|
- [Element Plus 文档](https://element-plus.org/)
|
|
- [TypeScript 文档](https://www.typescriptlang.org/)
|
|
- [Vite 文档](https://cn.vitejs.dev/)
|