对接后端

This commit is contained in:
ovo 2024-12-06 21:54:32 +08:00
parent 9bc552cfb8
commit 8f9a6371c4
16 changed files with 140 additions and 10 deletions

1
.env.development Normal file
View File

@ -0,0 +1 @@
VITE_API_BASE_URL=http://localhost:8080/api

1
.env.production Normal file
View File

@ -0,0 +1 @@
VITE_API_BASE_URL=https://api.example.com/api

View File

@ -22,7 +22,8 @@
"video.js": "^8.5.2", "video.js": "^8.5.2",
"vue": "^3.3.4", "vue": "^3.3.4",
"vue-echarts": "^6.6.9", "vue-echarts": "^6.6.9",
"vue-router": "^4.2.5" "vue-router": "^4.2.5",
"axios": "^1.6.7"
}, },
"devDependencies": { "devDependencies": {
"@rushstack/eslint-patch": "^1.3.3", "@rushstack/eslint-patch": "^1.3.3",

4
src/api/index.ts Normal file
View File

@ -0,0 +1,4 @@
export * from './user'
export * from './activity'
export * from './community'
// ... 导出其他API模块

21
src/api/types.ts Normal file
View File

@ -0,0 +1,21 @@
// API 响应数据接口
export interface ApiResponse<T = any> {
code: number
message: string
data: T
}
// 分页请求参数接口
export interface PageParams {
page: number
pageSize: number
[key: string]: any
}
// 分页响应数据接口
export interface PageResult<T> {
list: T[]
total: number
page: number
pageSize: number
}

37
src/api/user.ts Normal file
View File

@ -0,0 +1,37 @@
import request from '@/utils/request'
import type { ApiResponse } from './types'
export interface LoginParams {
username: string
password: string
}
export interface UserInfo {
id: number
username: string
nickname: string
avatar: string
roles: string[]
}
export const userApi = {
// 登录
login(data: LoginParams) {
return request.post<ApiResponse<{ token: string }>>('/auth/login', data)
},
// 获取用户信息
getUserInfo() {
return request.get<ApiResponse<UserInfo>>('/user/info')
},
// 修改密码
changePassword(data: { oldPassword: string; newPassword: string }) {
return request.post<ApiResponse>('/user/change-password', data)
},
// 更新用户信息
updateUserInfo(data: Partial<UserInfo>) {
return request.put<ApiResponse>('/user/info', data)
}
}

View File

@ -1 +0,0 @@

74
src/utils/request.ts Normal file
View File

@ -0,0 +1,74 @@
import axios from 'axios'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { ElMessage } from 'element-plus'
import router from '@/router'
// 创建 axios 实例
const service: AxiosInstance = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL || '/api', // 从环境变量获取API基础路径
timeout: 15000, // 请求超时时间
headers: {
'Content-Type': 'application/json'
}
})
// 请求拦截器
service.interceptors.request.use(
(config: AxiosRequestConfig) => {
// 从 localStorage 获取 token
const token = localStorage.getItem('token')
if (token) {
config.headers = {
...config.headers,
Authorization: `Bearer ${token}`
}
}
return config
},
(error) => {
console.error('请求错误:', error)
return Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
(response: AxiosResponse) => {
const { code, message, data } = response.data
// 根据后端约定的状态码处理
if (code === 200) {
return data
} else {
ElMessage.error(message || '请求失败')
return Promise.reject(new Error(message || '请求失败'))
}
},
(error) => {
const { status } = error.response || {}
// 处理常见错误
switch (status) {
case 401:
ElMessage.error('登录已过期,请重新登录')
localStorage.removeItem('token')
router.push('/login')
break
case 403:
ElMessage.error('没有权限访问')
break
case 404:
ElMessage.error('请求的资源不存在')
break
case 500:
ElMessage.error('服务器错误')
break
default:
ElMessage.error('网络错误')
}
return Promise.reject(error)
}
)
export default service