feat:"完成页面接口的对接"

This commit is contained in:
2026-01-29 17:58:19 +08:00
parent 2774a539bf
commit 2b69da3c15
98 changed files with 9504 additions and 592 deletions

View File

@@ -0,0 +1,139 @@
# 登录接口逻辑说明
## 问题描述
原先的实现中,登录失败时后端会抛出 `UnauthorizedException`HTTP 401前端响应拦截器收到 401 后会自动清空 token 并跳转到登录页,这在登录页面本身会造成逻辑混乱。
## 解决方案
### 1. 后端修改 (`后端/src/auth/auth.controller.ts`)
**修改前**
```typescript
async login(@Body() loginDto: LoginDto): Promise<any> {
const result = await this.authService.login(loginDto);
return { code: 0, message: 'success', data: result };
}
```
- 如果 auth.service 抛出 `UnauthorizedException`,会直接返回 HTTP 401 状态码
**修改后**
```typescript
async login(@Body() loginDto: LoginDto): Promise<any> {
try {
const result = await this.authService.login(loginDto);
return {
code: 0,
message: '登录成功',
data: result,
};
} catch (error) {
// 登录失败返回统一格式,不抛出 HTTP 异常
return {
code: 401,
message: error.message || '用户名或密码错误',
data: null,
};
}
}
```
**关键变化**
- ✅ HTTP 状态码始终为 200
- ✅ 通过响应体的 `code` 字段区分成功0和失败401
- ✅ 错误信息通过 `message` 字段返回
### 2. 前端修改 (`管理后台/src/utils/request.ts`)
**修改前**
```typescript
if (res.code !== 0 && res.code !== 200) {
ElMessage.error(res.message || '请求失败')
if (res.code === 401) {
const userStore = useUserStore()
userStore.logout()
router.push('/login')
}
return Promise.reject(new Error(res.message || '请求失败'))
}
```
- 所有 401 都会跳转登录页
**修改后**
```typescript
if (res.code !== 0 && res.code !== 200) {
const isLoginRequest = response.config.url?.includes('/auth/login')
if (res.code === 401 && !isLoginRequest) {
ElMessage.error('登录已过期,请重新登录')
const userStore = useUserStore()
userStore.logout()
router.push('/login')
} else if (!isLoginRequest) {
ElMessage.error(res.message || '请求失败')
}
return Promise.reject(new Error(res.message || '请求失败'))
}
```
**关键变化**
- ✅ 区分登录请求和其他请求
- ✅ 登录接口的 401 不会触发自动跳转
- ✅ 登录接口的错误消息不在拦截器中显示(由登录页面处理)
### 3. 前端登录页面 (`管理后台/src/views/login/index.vue`)
保持原有的错误处理逻辑:
```typescript
try {
await userStore.login(loginForm.username, loginForm.password)
ElMessage.success('登录成功')
router.push('/')
} catch (error: any) {
const errorMessage = error.message || '登录失败,请检查用户名和密码'
ElMessage.error(errorMessage)
}
```
**关键点**
- ✅ 登录页面自己处理并显示错误信息
- ✅ 错误消息来自后端返回的 `message` 字段
## 最终效果
### 登录成功
```
请求: POST /api/auth/login
响应: { code: 0, message: '登录成功', data: { user: {...}, access_token: '...', refresh_token: '...' } }
结果: 显示"登录成功",跳转到首页
```
### 登录失败(用户名或密码错误)
```
请求: POST /api/auth/login
响应: { code: 401, message: '用户名或密码错误', data: null }
结果: 显示"用户名或密码错误",停留在登录页
```
### 登录失败(账户被禁用)
```
请求: POST /api/auth/login
响应: { code: 401, message: '账户已被禁用,请联系管理员', data: null }
结果: 显示"账户已被禁用,请联系管理员",停留在登录页
```
### 其他接口 Token 过期
```
请求: GET /api/case/list
响应: { code: 401, message: 'Unauthorized', data: null }
结果: 显示"登录已过期,请重新登录",清空 token跳转到登录页
```
## 总结
这个修改确保了:
1. **登录接口**:失败时返回友好的错误信息,不会触发自动跳转
2. **其他接口**Token 过期时自动清理状态并跳转到登录页
3. **用户体验**:错误提示清晰准确,不会出现重复提示或循环跳转