前端types修改

This commit is contained in:
2025-10-06 16:49:12 +08:00
parent b2e275f52b
commit 8d0185b35a
16 changed files with 1081 additions and 50 deletions

View File

@@ -0,0 +1,71 @@
/**
* @description 认证相关API
* @author yslg
* @since 2025-10-06
*/
import { api } from './index';
import type { LoginParam, LoginDomain } from '@/types';
/**
* 认证API服务
*/
export const authApi = {
/**
* 用户登录
* @param loginParam 登录参数
* @returns Promise<LoginDomain>
*/
async login(loginParam: LoginParam): Promise<LoginDomain> {
const response = await api.post<LoginDomain>('/auth/login', loginParam);
return response.data.data!;
},
/**
* 用户登出
* @returns Promise<string>
*/
async logout(): Promise<string> {
const response = await api.post<string>('/auth/logout');
return response.data.data!;
},
/**
* 获取验证码
* @returns Promise<{captchaId: string, captchaImage: string}>
*/
async getCaptcha(): Promise<{ captchaId: string; captchaImage: string }> {
const response = await api.get<{ captchaId: string; captchaImage: string }>('/auth/captcha');
return response.data.data!;
},
/**
* 刷新Token
* @returns Promise<string>
*/
async refreshToken(): Promise<string> {
const response = await api.post<string>('/auth/refresh-token');
return response.data.data!;
},
/**
* 发送手机验证码
* @param phone 手机号
* @returns Promise<boolean>
*/
async sendSmsCode(phone: string): Promise<boolean> {
const response = await api.post<boolean>('/auth/send-sms-code', { phone });
return response.data.data!;
},
/**
* 发送邮箱验证码
* @param email 邮箱
* @returns Promise<boolean>
*/
async sendEmailCode(email: string): Promise<boolean> {
const response = await api.post<boolean>('/auth/send-email-code', { email });
return response.data.data!;
}
};

View File

@@ -1,50 +1,249 @@
import axios, { AxiosRequestConfig } from "axios";
import { ElLoading } from "element-plus";
import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from "axios";
import { ElLoading, ElMessage } from "element-plus";
import type { ResultDomain } from "@/types";
/**
* 扩展AxiosRequestConfig以支持自定义配置
*/
interface CustomAxiosRequestConfig extends AxiosRequestConfig {
/** 是否显示加载动画 */
showLoading?: boolean;
/** 是否显示错误提示 */
showError?: boolean;
/** 是否需要token */
requiresAuth?: boolean;
}
/**
* Token管理
*/
export const TokenManager = {
/** 获取token */
getToken(): string | null {
return localStorage.getItem('token');
},
/** 设置token */
setToken(token: string): void {
localStorage.setItem('token', token);
},
/** 移除token */
removeToken(): void {
localStorage.removeItem('token');
},
/** 检查是否有token */
hasToken(): boolean {
return !!this.getToken();
}
};
/**
* 创建axios实例
*/
const request = axios.create({
baseURL: "/api",
baseURL: import.meta.env.VITE_API_BASE_URL || "/api",
timeout: 30000,
headers: {
'Content-Type': 'application/json;charset=UTF-8',
}
})
});
let loadingInstance: ReturnType<typeof ElLoading.service> | null = null;
request.interceptors.request.use(config => {
if (config.showLoading) {
loadingInstance = ElLoading.service({
lock: true,
text: "加载中...",
background: "rgba(0, 0, 0, 0.7)",
});
/**
* 请求拦截器
*/
request.interceptors.request.use(
(config: CustomAxiosRequestConfig) => {
// 显示加载动画
if (config.showLoading !== false) {
loadingInstance = ElLoading.service({
lock: true,
text: "加载中...",
background: "rgba(0, 0, 0, 0.7)",
});
}
// 添加token
const token = TokenManager.getToken();
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error: AxiosError) => {
if (loadingInstance) {
loadingInstance.close();
loadingInstance = null;
}
return Promise.reject(error);
}
return config;
});
);
request.interceptors.response.use(response => {
if (loadingInstance) {
loadingInstance.close();
loadingInstance = null;
/**
* 响应拦截器
*/
request.interceptors.response.use(
(response: AxiosResponse<ResultDomain<any>>) => {
// 关闭加载动画
if (loadingInstance) {
loadingInstance.close();
loadingInstance = null;
}
const result = response.data;
// 检查是否为ResultDomain格式
if (result && typeof result === 'object' && 'code' in result) {
// 检查登录状态
if (result.login === false) {
ElMessage.error(result.message || '请先登录');
TokenManager.removeToken();
// 跳转到登录页
window.location.href = '/login';
return Promise.reject(new Error('未登录'));
}
// 检查权限
if (result.auth === false) {
ElMessage.error(result.message || '没有权限访问');
return Promise.reject(new Error('无权限'));
}
// 检查业务逻辑是否成功
if (!result.success) {
const config = response.config as CustomAxiosRequestConfig;
if (config.showError !== false) {
ElMessage.error(result.message || '操作失败');
}
return Promise.reject(new Error(result.message || '操作失败'));
}
// 返回成功的数据
return response;
}
// 非ResultDomain格式直接返回
return response;
},
(error: AxiosError<ResultDomain<any>>) => {
// 关闭加载动画
if (loadingInstance) {
loadingInstance.close();
loadingInstance = null;
}
const config = error.config as CustomAxiosRequestConfig;
// 处理HTTP错误
if (error.response) {
const { status, data } = error.response;
switch (status) {
case 401:
ElMessage.error('认证失败,请重新登录');
TokenManager.removeToken();
window.location.href = '/login';
break;
case 403:
ElMessage.error('没有权限访问该资源');
break;
case 404:
ElMessage.error('请求的资源不存在');
break;
case 500:
ElMessage.error(data?.message || '服务器内部错误');
break;
default:
if (config?.showError !== false) {
ElMessage.error(data?.message || '请求失败');
}
}
} else if (error.request) {
// 请求已发送但没有收到响应
ElMessage.error('网络错误,请检查网络连接');
} else {
// 其他错误
if (config?.showError !== false) {
ElMessage.error(error.message || '请求失败');
}
}
return Promise.reject(error);
}
return response;
});
);
/**
* API封装
*/
export const api = {
get: function(url: string, config = {} as AxiosRequestConfig) { return request.get(url, config) },
post: function(url: string, data = {}, config = {} as AxiosRequestConfig) { return request.post(url, data, config) },
put: function(url: string, data = {}, config = {} as AxiosRequestConfig) { return request.put(url, data, config) },
delete: function(url: string, config = {} as AxiosRequestConfig) { return request.delete(url, config) },
upload: function(url: string, formData: FormData, config = {} as AxiosRequestConfig) {
return request.post(url, formData, {
/**
* GET请求
*/
get<T = any>(url: string, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<ResultDomain<T>>> {
return request.get<ResultDomain<T>>(url, config);
},
/**
* POST请求
*/
post<T = any>(url: string, data?: any, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<ResultDomain<T>>> {
return request.post<ResultDomain<T>>(url, data, config);
},
/**
* PUT请求
*/
put<T = any>(url: string, data?: any, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<ResultDomain<T>>> {
return request.put<ResultDomain<T>>(url, data, config);
},
/**
* DELETE请求
*/
delete<T = any>(url: string, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<ResultDomain<T>>> {
return request.delete<ResultDomain<T>>(url, config);
},
/**
* PATCH请求
*/
patch<T = any>(url: string, data?: any, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<ResultDomain<T>>> {
return request.patch<ResultDomain<T>>(url, data, config);
},
/**
* 文件上传
*/
upload<T = any>(url: string, formData: FormData, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<ResultDomain<T>>> {
return request.post<ResultDomain<T>>(url, formData, {
...config,
headers: {
'Content-Type': 'multipart/form-data',
...(config.headers as Record<string, string>)
...(config?.headers as Record<string, string>)
}
})
});
},
/**
* 文件下载
*/
download(url: string, filename?: string, config?: CustomAxiosRequestConfig): Promise<void> {
return request.get(url, {
...config,
responseType: 'blob'
}).then((response) => {
const blob = new Blob([response.data]);
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = filename || 'download';
link.click();
window.URL.revokeObjectURL(link.href);
});
}
}
};
export default request;

View File

@@ -0,0 +1,92 @@
/**
* @description 菜单相关API
* @author yslg
* @since 2025-10-06
*/
import { api } from './index';
import type { SysMenu, MenuTreeNode } from '@/types';
/**
* 菜单API服务
*/
export const menuApi = {
/**
* 获取当前用户的菜单树
* @returns Promise<MenuTreeNode[]>
*/
async getCurrentUserMenuTree(): Promise<MenuTreeNode[]> {
const response = await api.get<SysMenu>('/menu/user-tree');
return response.data.dataList! as MenuTreeNode[];
},
/**
* 获取所有菜单列表
* @returns Promise<SysMenu[]>
*/
async getMenuList(): Promise<SysMenu[]> {
const response = await api.get<SysMenu>('/menu/list');
return response.data.dataList!;
},
/**
* 获取菜单树
* @returns Promise<MenuTreeNode[]>
*/
async getMenuTree(): Promise<MenuTreeNode[]> {
const response = await api.get<SysMenu>('/menu/tree');
return response.data.dataList! as MenuTreeNode[];
},
/**
* 根据ID获取菜单
* @param menuId 菜单ID
* @returns Promise<SysMenu>
*/
async getMenuById(menuId: string): Promise<SysMenu> {
const response = await api.get<SysMenu>(`/menu/${menuId}`);
return response.data.data!;
},
/**
* 创建菜单
* @param menu 菜单信息
* @returns Promise<string> 返回菜单ID
*/
async createMenu(menu: SysMenu): Promise<string> {
const response = await api.post<string>('/menu', menu);
return response.data.data!;
},
/**
* 更新菜单
* @param menuId 菜单ID
* @param menu 菜单信息
* @returns Promise<boolean>
*/
async updateMenu(menuId: string, menu: SysMenu): Promise<boolean> {
const response = await api.put<boolean>(`/menu/${menuId}`, menu);
return response.data.data!;
},
/**
* 删除菜单
* @param menuId 菜单ID
* @returns Promise<boolean>
*/
async deleteMenu(menuId: string): Promise<boolean> {
const response = await api.delete<boolean>(`/menu/${menuId}`);
return response.data.data!;
},
/**
* 获取子菜单列表
* @param parentId 父菜单ID
* @returns Promise<SysMenu[]>
*/
async getChildMenus(parentId: string): Promise<SysMenu[]> {
const response = await api.get<SysMenu>(`/menu/children/${parentId}`);
return response.data.dataList!;
}
};

View File

@@ -0,0 +1,153 @@
/**
* @description 用户相关API
* @author yslg
* @since 2025-10-06
*/
import { api } from './index';
import type { SysUser, SysUserInfo, UserVO, PageDomain, PageParam } from '@/types';
/**
* 用户API服务
*/
export const userApi = {
/**
* 获取当前用户信息
* @returns Promise<UserVO>
*/
async getCurrentUser(): Promise<UserVO> {
const response = await api.get<UserVO>('/user/current');
return response.data.data!;
},
/**
* 更新当前用户信息
* @param user 用户信息
* @returns Promise<boolean>
*/
async updateCurrentUser(user: SysUser): Promise<boolean> {
const response = await api.put<boolean>('/user/current', user);
return response.data.data!;
},
/**
* 更新用户详细信息
* @param userInfo 用户详细信息
* @returns Promise<boolean>
*/
async updateUserInfo(userInfo: SysUserInfo): Promise<boolean> {
const response = await api.put<boolean>('/user/info', userInfo);
return response.data.data!;
},
/**
* 修改密码
* @param oldPassword 旧密码
* @param newPassword 新密码
* @returns Promise<boolean>
*/
async changePassword(oldPassword: string, newPassword: string): Promise<boolean> {
const response = await api.post<boolean>('/user/change-password', {
oldPassword,
newPassword
});
return response.data.data!;
},
/**
* 获取用户列表(分页)
* @param pageParam 分页参数
* @returns Promise<PageDomain<SysUser>>
*/
async getUserList(pageParam: PageParam): Promise<PageDomain<SysUser>> {
const response = await api.get<SysUser>('/user/list', {
params: pageParam
});
return response.data.pageDomain!;
},
/**
* 根据ID获取用户
* @param userId 用户ID
* @returns Promise<SysUser>
*/
async getUserById(userId: string): Promise<SysUser> {
const response = await api.get<SysUser>(`/user/${userId}`);
return response.data.data!;
},
/**
* 创建用户
* @param user 用户信息
* @returns Promise<string> 返回用户ID
*/
async createUser(user: SysUser): Promise<string> {
const response = await api.post<string>('/user', user);
return response.data.data!;
},
/**
* 更新用户
* @param userId 用户ID
* @param user 用户信息
* @returns Promise<boolean>
*/
async updateUser(userId: string, user: SysUser): Promise<boolean> {
const response = await api.put<boolean>(`/user/${userId}`, user);
return response.data.data!;
},
/**
* 删除用户
* @param userId 用户ID
* @returns Promise<boolean>
*/
async deleteUser(userId: string): Promise<boolean> {
const response = await api.delete<boolean>(`/user/${userId}`);
return response.data.data!;
},
/**
* 批量删除用户
* @param userIds 用户ID列表
* @returns Promise<boolean>
*/
async batchDeleteUsers(userIds: string[]): Promise<boolean> {
const response = await api.post<boolean>('/user/batch-delete', { userIds });
return response.data.data!;
},
/**
* 启用/禁用用户
* @param userId 用户ID
* @param status 状态 0-启用 1-禁用
* @returns Promise<boolean>
*/
async changeUserStatus(userId: string, status: number): Promise<boolean> {
const response = await api.patch<boolean>(`/user/${userId}/status`, { status });
return response.data.data!;
},
/**
* 重置用户密码
* @param userId 用户ID
* @returns Promise<string> 返回新密码
*/
async resetPassword(userId: string): Promise<string> {
const response = await api.post<string>(`/user/${userId}/reset-password`);
return response.data.data!;
},
/**
* 上传用户头像
* @param file 文件
* @returns Promise<string> 返回头像URL
*/
async uploadAvatar(file: File): Promise<string> {
const formData = new FormData();
formData.append('file', file);
const response = await api.upload<string>('/user/avatar', formData);
return response.data.data!;
}
};