From b3c0a05a3e0dc37155e6dc9992713f1624b15985 Mon Sep 17 00:00:00 2001 From: gaoziman <2942894660@qq.com> Date: Tue, 18 Nov 2025 20:46:02 +0800 Subject: [PATCH] =?UTF-8?q?feat(API=E5=B1=82):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=AE=8C=E6=95=B4=E7=9A=84=20API=20=E6=8E=A5=E5=8F=A3=E5=B0=81?= =?UTF-8?q?=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增用户认证接口(auth.ts):登录、注册、获取用户信息 - 新增用户管理接口(user.ts):增删改查、批量操作 - 实现完整的请求/响应类型定义 - 统一错误处理和响应格式 --- src/api/auth.ts | 117 +++++++++++++++++++++ src/api/user.ts | 274 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 391 insertions(+) create mode 100644 src/api/auth.ts create mode 100644 src/api/user.ts diff --git a/src/api/auth.ts b/src/api/auth.ts new file mode 100644 index 0000000..81820f9 --- /dev/null +++ b/src/api/auth.ts @@ -0,0 +1,117 @@ +/** + * 认证相关 API + * @description 封装登录、注册、登出、获取用户信息等认证接口 + */ + +import request from '@/utils/request'; +import type { R } from '@/types/api'; +import type { + LoginReq, + LoginResp, + RegisterReq, + UserInfoResp, +} from '@/types/auth'; + +// ==================== 认证 API 路径 ==================== + +const AUTH_API = { + /** 登录 */ + LOGIN: '/auth/login', + /** 注册 */ + REGISTER: '/auth/register', + /** 登出 */ + LOGOUT: '/auth/logout', + /** 获取用户信息 */ + USER_INFO: '/auth/user/info', +}; + +// ==================== 认证 API 函数 ==================== + +/** + * 用户登录 + * @param data - 登录请求参数 + * @returns 登录响应数据 + * @example + * ```typescript + * const result = await login({ + * account: 'admin', + * password: 'admin123' + * }); + * + * if (result.code === 0) { + * const { token, userId, username, nickname, role } = result.data; + * // 存储 token 和用户信息 + * setToken(token); + * setUserInfo({ userId, username, nickname, role }); + * } + * ``` + */ +export function login(data: LoginReq): Promise> { + return request.post(AUTH_API.LOGIN, data); +} + +/** + * 用户注册 + * @param data - 注册请求参数 + * @returns 注册响应 + * @example + * ```typescript + * const result = await register({ + * username: 'testuser', + * password: 'Test@123', + * confirmPassword: 'Test@123', + * email: 'test@leocoder.cn', + * phone: '13800138001', + * nickname: '测试用户' + * }); + * + * if (result.code === 0) { + * Message.success('注册成功,请登录'); + * // 跳转到登录页 + * history.push('/login'); + * } + * ``` + */ +export function register(data: RegisterReq): Promise> { + return request.post(AUTH_API.REGISTER, data); +} + +/** + * 用户登出 + * @returns 登出响应 + * @example + * ```typescript + * const result = await logout(); + * + * if (result.code === 0) { + * // 清除本地存储 + * clearAuthInfo(); + * // 跳转到登录页 + * window.location.href = '/login'; + * } + * ``` + */ +export function logout(): Promise> { + return request.post(AUTH_API.LOGOUT); +} + +/** + * 获取当前用户信息 + * @returns 用户信息响应 + * @example + * ```typescript + * const result = await getUserInfo(); + * + * if (result.code === 0) { + * const userInfo = result.data; + * // 更新 Redux Store + * dispatch({ + * type: 'update-userInfo', + * payload: { userInfo } + * }); + * } + * ``` + */ +export function getUserInfo(): Promise> { + return request.get(AUTH_API.USER_INFO); +} diff --git a/src/api/user.ts b/src/api/user.ts new file mode 100644 index 0000000..9eb2c99 --- /dev/null +++ b/src/api/user.ts @@ -0,0 +1,274 @@ +/** + * 用户管理相关 API + * @description 封装用户管理的 CRUD 接口 + */ + +import request from '@/utils/request'; +import type { R, PageResp } from '@/types/api'; +import type { + UserQuery, + UserResp, + UserReq, + BatchDeleteReq, + ResetPasswordReq, + UpdateProfileReq, +} from '@/types/user'; + +// ==================== 用户管理 API 路径 ==================== + +const USER_API = { + /** 分页查询用户 */ + PAGE: '/system/user', + /** 获取用户详情 */ + GET: (id: number) => `/system/user/${id}`, + /** 创建用户 */ + CREATE: '/system/user', + /** 更新用户 */ + UPDATE: (id: number) => `/system/user/${id}`, + /** 删除用户 */ + DELETE: (id: number) => `/system/user/${id}`, + /** 批量删除用户(DELETE /system/user,携带 ids 数组) */ + BATCH_DELETE: '/system/user', + /** 导出用户 */ + EXPORT: '/system/user/export', + /** 重置用户密码 */ + RESET_PASSWORD: '/system/user/password/reset', + /** 修改个人信息 */ + UPDATE_PROFILE: '/system/user/profile', + /** 上传头像 */ + UPLOAD_AVATAR: '/system/user/avatar', +}; + +// ==================== 用户管理 API 函数 ==================== + +/** + * 分页查询用户列表 + * @param params - 查询参数 + * @returns 分页用户列表 + * @example + * ```typescript + * const result = await getUserPage({ + * current: 1, + * size: 10, + * username: 'admin', + * role: 'ADMIN', + * status: 1 + * }); + * + * if (result.code === 0) { + * const { list, total } = result.data; + * setTableData(list); + * setPagination({ ...pagination, total }); + * } + * ``` + */ +export function getUserPage(params: UserQuery): Promise>> { + return request.get>(USER_API.PAGE, { params }); +} + +/** + * 获取用户详情 + * @param id - 用户ID + * @returns 用户详情 + * @example + * ```typescript + * const result = await getUserDetail(1); + * + * if (result.code === 0) { + * const userDetail = result.data; + * form.setFieldsValue(userDetail); + * } + * ``` + */ +export function getUserDetail(id: number): Promise> { + return request.get(USER_API.GET(id)); +} + +/** + * 创建用户 + * @param data - 用户数据 + * @returns 新创建用户的ID + * @example + * ```typescript + * const result = await createUser({ + * username: 'testuser', + * role: 'USER', + * password: 'Test@123', + * email: 'test@leocoder.cn', + * phone: '13800138001', + * nickname: '测试用户', + * status: 1 + * }); + * + * if (result.code === 0) { + * Message.success('用户创建成功'); + * fetchData(); // 刷新列表 + * } + * ``` + */ +export function createUser(data: UserReq): Promise> { + return request.post(USER_API.CREATE, data); +} + +/** + * 更新用户 + * @param id - 用户ID + * @param data - 用户数据 + * @returns 更新响应 + * @example + * ```typescript + * const result = await updateUser(1, { + * username: 'updateduser', + * role: 'USER', + * email: 'updated@leocoder.cn', + * phone: '13800138003', + * nickname: '更新后的昵称', + * status: 1 + * }); + * + * if (result.code === 0) { + * Message.success('用户更新成功'); + * fetchData(); // 刷新列表 + * } + * ``` + */ +export function updateUser(id: number, data: UserReq): Promise> { + return request.put(USER_API.UPDATE(id), data); +} + +/** + * 删除用户 + * @param id - 用户ID + * @returns 删除响应 + * @example + * ```typescript + * await Modal.confirm({ + * title: '确认删除', + * content: '确定要删除该用户吗?此操作不可恢复。' + * }); + * + * const result = await deleteUser(1); + * + * if (result.code === 0) { + * Message.success('删除成功'); + * fetchData(); // 刷新列表 + * } + * ``` + */ +export function deleteUser(id: number): Promise> { + return request.delete(USER_API.DELETE(id)); +} + +/** + * 批量删除用户 + * @param ids - 用户ID列表 + * @returns 删除响应 + * @example + * ```typescript + * await Modal.confirm({ + * title: '批量删除确认', + * content: `确定要删除选中的 ${ids.length} 个用户吗?` + * }); + * + * const result = await batchDeleteUsers([1, 2, 3, 4, 5]); + * + * if (result.code === 0) { + * Message.success('批量删除成功'); + * setSelectedRowKeys([]); // 清空选择 + * fetchData(); // 刷新列表 + * } + * ``` + */ +export function batchDeleteUsers(ids: number[]): Promise> { + return request.delete(USER_API.BATCH_DELETE, { + data: { ids }, + }); +} + +/** + * 管理员重置用户密码 + * @param data - 重置密码参数 + */ +export function resetUserPassword(data: ResetPasswordReq): Promise> { + return request.put(USER_API.RESET_PASSWORD, data); +} + +/** + * 导出用户数据 + * @param params - 查询参数(用于筛选要导出的数据) + * @returns Blob 数据流 + * @example + * ```typescript + * const response = await exportUsers({ + * username: 'admin', + * role: 'ADMIN', + * status: 1 + * }); + * + * // 创建下载链接 + * const url = window.URL.createObjectURL(new Blob([response.data])); + * const link = document.createElement('a'); + * link.href = url; + * link.setAttribute('download', `用户列表_${new Date().getTime()}.xlsx`); + * document.body.appendChild(link); + * link.click(); + * link.remove(); + * + * Message.success('导出成功'); + * ``` + */ +export function exportUsers(params: UserQuery): Promise { + return request.post(USER_API.EXPORT, params, { + responseType: 'blob', // 重要:指定响应类型为 blob + }); +} + +/** + * 修改个人信息 + * @param data - 个人信息数据 + * @returns 更新响应 + * @example + * ```typescript + * const result = await updateProfile({ + * nickname: 'Leo哥', + * email: 'leo@example.com', + * phone: '13800138000' + * }); + * + * if (result.code === 0) { + * Message.success('个人信息修改成功'); + * // 重新获取用户信息 + * fetchUserInfo(); + * } + * ``` + */ +export function updateProfile(data: UpdateProfileReq): Promise> { + return request.put(USER_API.UPDATE_PROFILE, data); +} + +/** + * 上传头像 + * @param file - 头像文件 + * @returns 头像URL + * @example + * ```typescript + * const formData = new FormData(); + * formData.append('avatar', file); + * + * const result = await uploadAvatar(formData); + * + * if (result.code === 0) { + * const avatarUrl = result.data; + * Message.success('头像上传成功'); + * // 更新个人信息中的头像字段 + * await updateProfile({ avatar: avatarUrl }); + * } + * ``` + */ +export function uploadAvatar(formData: FormData): Promise> { + return request.put(USER_API.UPLOAD_AVATAR, formData, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + }); +}