mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-10-14 13:06:51 +00:00
- web/vite.config.ts:生产判据由 `mode === "prod"`(恒 false)改为 `production || prod`, 压缩/去 console/剔除 vue-devtools 插件真正生效;同时修正 terser `comments: true` (是「保留全部注释」,与注释文字相反)为 `"some"`,保留 @license 等版权声明 - app 刷新令牌:改为发送 JSON 字符串(后端为 Body(str)),与 web 端已知可用实现一致, 修掉移动端 token 过期必然 422 强制登出 - app 上传:路径补 /common(真实路径 /api/v1/common/file/upload),并改走统一 http 层的 wd-upload upload-method 钩子,Authorization 由 http 层注入,不再页面自拼 URL - app 生产 WS:ws://localhost:5180/ws → wss://service.fastapiadmin.com;开发 WS 指向本机 - app 开发接口地址:改为 http://127.0.0.1:8001,与 web 端开发策略一致 复核证据(队长独立执行):web/app type-check 均 exit 0;build:prod 与 build:h5 均 exit 0; 生产包内第一方 console 特征串 9/9 全部 0 命中(剩余 5 处 console 为字符串文案或 第三方 typeof 守卫,非可执行调用);H5 产物内 localhost:5180 命中 0、wss 域名命中 1、 裸 /file/upload 命中 0、/common/file/upload 命中 1。
341 lines
8.2 KiB
TypeScript
341 lines
8.2 KiB
TypeScript
import { http } from '@/http'
|
||
|
||
const USER_BASE_URL = '/system/user'
|
||
|
||
/**
|
||
* 用户管理 API
|
||
* 与 web 端 module_system/user.ts 对齐(完整字段定义)
|
||
*/
|
||
const UserAPI = {
|
||
/**
|
||
* 个人中心用户信息
|
||
*
|
||
* @returns 登录用户昵称、头像信息,包括角色和权限
|
||
*/
|
||
getCurrentUserInfo(): Promise<UserInfo> {
|
||
return http.Get(`${USER_BASE_URL}/current/info`)
|
||
},
|
||
|
||
/**
|
||
* 当前用户头像上传
|
||
*
|
||
* 路径必须是 `/common/file/upload`:后端 `FileRouter` 自身前缀是 `/file`,但挂在
|
||
* `/common` 域下(`backend/app/api/v1/routers.py:63`),配合 `VITE_APP_BASE_API=/api/v1`
|
||
* 得到 `/api/v1/common/file/upload`;`upload_type` 是 Query 参数、文件字段名约定为 `file`
|
||
* (`backend/app/modules/common/file/controller.py:18-31`)。
|
||
* 旧实现写成 `/file/upload`,后端无此路由 → 404。
|
||
*
|
||
* 走统一 http 层(`requestType: 'upload'`):请求头由 http 层 `beforeRequest` 统一注入
|
||
* `Authorization`(该接口要求 `module_common:file:upload` 权限),失败复用全局错误处理,
|
||
* 调用方无需自己拼 URL 与请求头。
|
||
*
|
||
* @param body 上传参数
|
||
* @param body.filePath 本地临时文件路径(uni.chooseImage 选择结果)
|
||
* @param body.name 上传字段名,后端约定为 file
|
||
* @returns uni.uploadFile 成功回调结果(statusCode + data 响应体字符串,需调用方解析)
|
||
*/
|
||
uploadCurrentUserAvatar(body: { filePath: string, name?: string }): Promise<UniApp.UploadFileSuccessCallbackResult> {
|
||
return http.Post('/common/file/upload?upload_type=avatar', body, { requestType: 'upload' })
|
||
},
|
||
|
||
/**
|
||
* 修改个人中心用户信息
|
||
*
|
||
* @param body
|
||
* @returns 修改后的用户信息
|
||
*/
|
||
updateCurrentUserInfo(body: UserProfileForm): Promise<UserInfo> {
|
||
return http.Put(`${USER_BASE_URL}/current/info/update`, body)
|
||
},
|
||
|
||
/**
|
||
* 修改个人中心用户密码
|
||
*
|
||
* @param body
|
||
* @returns 修改后的用户信息
|
||
*/
|
||
changeCurrentUserPassword(body: PasswordChangeForm): Promise<void> {
|
||
return http.Put(`${USER_BASE_URL}/password/change`, body)
|
||
},
|
||
|
||
/**
|
||
* 注册用户(公开接口)
|
||
*
|
||
* @param body 注册参数
|
||
* @param body.username 用户名(字母开头,3-32 位)
|
||
* @param body.password 密码(6-128 位)
|
||
* @param body.name 昵称(可选)
|
||
* @returns 注册结果
|
||
*/
|
||
registerUser(body: RegisterForm): Promise<void> {
|
||
return http.Post(`${USER_BASE_URL}/register`, body, { meta: { ignoreAuth: true } })
|
||
},
|
||
|
||
/**
|
||
* 忘记密码(公开接口)
|
||
*
|
||
* @param body 重置参数
|
||
* @param body.username 用户名(字母开头,3-32 位)
|
||
* @param body.new_password 新密码(6-128 位)
|
||
* @returns 重置结果
|
||
*/
|
||
forgetPassword(body: ForgetPasswordForm): Promise<void> {
|
||
return http.Post(`${USER_BASE_URL}/password/forget`, body, { meta: { ignoreAuth: true } })
|
||
},
|
||
|
||
/**
|
||
* 重置用户密码
|
||
*
|
||
* @param id 用户ID
|
||
* @param body 新密码
|
||
* @param body.password 新密码
|
||
*/
|
||
resetPassword(id: number, body: { password: string }): Promise<void> {
|
||
return http.Put(`${USER_BASE_URL}/password/reset/${id}`, body)
|
||
},
|
||
|
||
/**
|
||
* 批量修改用户状态
|
||
*
|
||
* @param body 批量操作参数
|
||
* @param body.ids 用户ID列表
|
||
* @param body.status 目标状态
|
||
*/
|
||
batchStatus(body: BatchSetStatus): Promise<void> {
|
||
return http.Patch(`${USER_BASE_URL}/status/batch`, body)
|
||
},
|
||
|
||
/**
|
||
* 导出用户
|
||
*
|
||
* @param params 导出参数
|
||
*/
|
||
exportUsers(params?: Record<string, any>): Promise<unknown> {
|
||
return http.Post(`${USER_BASE_URL}/export`, params)
|
||
},
|
||
|
||
/**
|
||
* 获取用户导入模板
|
||
*/
|
||
getImportTemplate(): Promise<unknown> {
|
||
return http.Get(`${USER_BASE_URL}/import/template`)
|
||
},
|
||
|
||
/**
|
||
* 导入用户数据
|
||
*
|
||
* @param body 导入数据
|
||
*/
|
||
importData(body: Record<string, any>): Promise<void> {
|
||
return http.Post(`${USER_BASE_URL}/import/data`, body)
|
||
},
|
||
|
||
/**
|
||
* 获取用户分页列表
|
||
*
|
||
* @param queryParams 查询参数
|
||
*/
|
||
getUserPage(queryParams: UserPageQuery): Promise<PageResult<UserInfo>> {
|
||
return http.Get(`${USER_BASE_URL}/list`, queryParams)
|
||
},
|
||
|
||
/**
|
||
* 获取用户表单详情
|
||
*
|
||
* @param userId 用户ID
|
||
* @returns 用户表单详情
|
||
*/
|
||
getUserDetail(userId: number): Promise<UserForm> {
|
||
return http.Get(`${USER_BASE_URL}/detail/${userId}`)
|
||
},
|
||
|
||
/**
|
||
* 添加用户
|
||
*
|
||
* @param body 用户表单数据
|
||
*/
|
||
addUser(body: UserForm): Promise<void> {
|
||
return http.Post(`${USER_BASE_URL}/create`, body)
|
||
},
|
||
|
||
/**
|
||
* 修改用户
|
||
*
|
||
* @param body 用户表单数据
|
||
*/
|
||
updateUser(body: UserForm): Promise<void> {
|
||
return http.Put(`${USER_BASE_URL}/update/${body.id}`, body)
|
||
},
|
||
|
||
/**
|
||
* 删除用户
|
||
*
|
||
* @param ids 用户ID数组
|
||
*/
|
||
deleteUser(ids: number[]): Promise<void> {
|
||
return http.Delete(`${USER_BASE_URL}/delete`, ids)
|
||
},
|
||
}
|
||
|
||
export default UserAPI
|
||
|
||
/* 忘记密码申请(与后端 UserForgetPasswordSchema 一致:仅用户名,后端不会直接改密) */
|
||
export interface ForgetPasswordForm {
|
||
username: string
|
||
}
|
||
|
||
/* 注册表单 */
|
||
export interface RegisterForm {
|
||
username: string
|
||
password: string
|
||
name?: string
|
||
}
|
||
|
||
/* 分页查询表单 */
|
||
export interface UserPageQuery extends PageQuery {
|
||
username?: string
|
||
name?: string
|
||
mobile?: string
|
||
email?: string
|
||
dept_id?: number
|
||
status?: number
|
||
start_time?: string
|
||
end_time?: string
|
||
}
|
||
|
||
/* 搜索选择器数据类型 */
|
||
export interface searchSelectDataType {
|
||
name?: string
|
||
status?: number
|
||
}
|
||
|
||
/* 用户表单 */
|
||
export interface UserForm extends BaseFormType {
|
||
username?: string
|
||
name?: string
|
||
dept_id?: number
|
||
dept_name?: string
|
||
role_ids?: number[]
|
||
role_names?: string[]
|
||
position_ids?: number[]
|
||
position_names?: string[]
|
||
password?: string
|
||
gender?: number
|
||
email?: string
|
||
mobile?: string
|
||
avatar?: string
|
||
is_superuser?: boolean
|
||
status?: number
|
||
description?: string
|
||
}
|
||
|
||
/* 登录用户信息 */
|
||
export interface UserInfo extends BaseType {
|
||
username?: string
|
||
name?: string
|
||
avatar?: string
|
||
email?: string
|
||
mobile?: string
|
||
gender?: string
|
||
password?: string
|
||
menus?: MenuTable[]
|
||
dept?: deptTreeType
|
||
dept_id?: deptTreeType['id']
|
||
dept_name?: deptTreeType['name']
|
||
roles?: roleSelectorType[]
|
||
role_names?: roleSelectorType['name'][]
|
||
role_ids?: roleSelectorType['id'][]
|
||
positions?: positionSelectorType[]
|
||
position_names?: positionSelectorType['name'][]
|
||
position_ids?: positionSelectorType['id'][]
|
||
is_superuser?: boolean
|
||
last_login?: string
|
||
gitee_login?: string
|
||
github_login?: string
|
||
wx_login?: string
|
||
qq_login?: string
|
||
status?: number
|
||
description?: string
|
||
}
|
||
|
||
/* 菜单表 */
|
||
export interface MenuTable extends BaseType {
|
||
name?: string
|
||
type?: number
|
||
icon?: string
|
||
order?: number
|
||
permission?: string
|
||
route_name?: string
|
||
route_path?: string
|
||
component_path?: string
|
||
redirect?: string
|
||
parent_id?: number
|
||
parent_name?: string
|
||
keep_alive?: boolean
|
||
hidden?: boolean
|
||
always_show?: boolean
|
||
title?: string
|
||
params?: { key: string, value: string }[]
|
||
affix?: boolean
|
||
status?: number
|
||
description?: string
|
||
children?: MenuTable[]
|
||
}
|
||
|
||
/* 部门树 */
|
||
export interface deptTreeType {
|
||
id?: number
|
||
name?: string
|
||
parent_id?: number
|
||
children?: deptTreeType[]
|
||
}
|
||
|
||
/* 角色选择器 */
|
||
export interface roleSelectorType {
|
||
id?: number
|
||
name?: string
|
||
status?: number
|
||
description?: string
|
||
}
|
||
|
||
/* 职位选择器 */
|
||
export interface positionSelectorType {
|
||
id?: number
|
||
name?: string
|
||
status?: number
|
||
description?: string
|
||
}
|
||
|
||
/* 个人中心用户信息表单 */
|
||
export interface UserProfileForm extends BaseFormType {
|
||
name?: string
|
||
gender?: string
|
||
mobile?: string
|
||
email?: string
|
||
username?: string
|
||
dept_name?: string
|
||
positions?: positionSelectorType[]
|
||
roles?: roleSelectorType[]
|
||
avatar?: string
|
||
created_time?: string
|
||
}
|
||
|
||
/* 修改密码表单 */
|
||
export interface PasswordChangeForm {
|
||
old_password: string
|
||
new_password: string
|
||
confirm_password: string
|
||
}
|
||
|
||
/* 重置密码表单 */
|
||
export interface ResetPasswordForm {
|
||
id: number
|
||
password: string
|
||
}
|
||
|
||
/* 批量设置状态 */
|
||
export interface BatchSetStatus {
|
||
ids: number[]
|
||
status: number
|
||
}
|