diff --git a/ruoyi-ui-next/src/stores/modules/user.ts b/ruoyi-ui-next/src/stores/modules/user.ts index 6e180aa..1da5150 100644 --- a/ruoyi-ui-next/src/stores/modules/user.ts +++ b/ruoyi-ui-next/src/stores/modules/user.ts @@ -1,13 +1,88 @@ import { defineStore } from 'pinia' import { ref } from 'vue' -import { getToken, setToken, removeToken } from '@/utils/auth' import axios from 'axios' +import { ElMessage } from 'element-plus' +import { getToken, setToken, removeToken } from '@/utils/auth' const apiClient = axios.create({ baseURL: import.meta.env.VITE_APP_BASE_API || '/dev-api', timeout: 60000, + headers: { + 'Content-Type': 'application/json;charset=utf-8', + }, }) +// 请求拦截器:自动注入 Token +apiClient.interceptors.request.use( + (config) => { + const token = getToken() + if (token) { + config.headers['Authorization'] = `Bearer ${token}` + } + return config + }, + (error) => { + return Promise.reject(error) + } +) + +// 响应拦截器:统一处理 AjaxResult 格式 +apiClient.interceptors.response.use( + (response) => { + const res = response.data + + // 二进制数据直接返回 + if (res instanceof Blob || response.config.responseType === 'blob') { + return res + } + + const { code, msg, data } = res + + if (code === 200) { + // 返回完整响应对象,保留顶层字段(如 token) + return res + } else if (code === 401) { + ElMessage.error(msg || '登录状态已过期,请重新登录') + removeToken() + window.location.href = '/login' + return Promise.reject(new Error(msg || '登录已过期')) + } else if (code === 500) { + ElMessage.error(msg || '系统内部错误') + return Promise.reject(new Error(msg || '系统内部错误')) + } else { + ElMessage.error(msg || '请求失败') + return Promise.reject(new Error(msg || '请求失败')) + } + }, + (error) => { + let message = '网络异常' + if (error.response) { + switch (error.response.status) { + case 401: + message = '未授权,请重新登录' + break + case 403: + message = '拒绝访问' + break + case 404: + message = '请求地址不存在' + break + case 500: + message = '服务器内部错误' + break + default: + message = `连接错误 ${error.response.status}` + } + } else if (error.code === 'ECONNABORTED') { + message = '请求超时' + } else { + message = error.message || '网络异常' + } + ElMessage.error(message) + return Promise.reject(error) + } +) + export interface UserInfo { userId: number userName: string @@ -24,19 +99,27 @@ export const useUserStore = defineStore('user', () => { const permissions = ref([]) async function login(username: string, password: string, code?: string, uuid?: string) { - const { data } = await apiClient.post('/login', { username, password, code, uuid }) - setToken(data.token) - token.value = data.token - return data + const res = await apiClient.post('/login', { username, password, code, uuid }) + const tokenValue = res.token + if (!tokenValue) { + throw new Error('登录失败,未获取到 token') + } + setToken(tokenValue) + token.value = tokenValue + return res } async function getInfo() { - const { data } = await apiClient.get('/getInfo') + const res = await apiClient.get('/getInfo') + const data = res.data || {} const user = data.user + if (!user) { + throw new Error('获取用户信息失败') + } userInfo.value = user - roles.value = user.roles || [] - permissions.value = user.permissions || [] - return data + roles.value = user.roles || data.roles || [] + permissions.value = user.permissions || data.permissions || [] + return res } async function logout() {