Skip to content

用户管理 API

移动端用户相关的API接口,包括登录认证、用户信息管理、个人设置等功能。

📋 API 概览

接口列表

功能方法路径说明
用户登录POST/auth/login账号密码登录
短信登录POST/auth/smsLogin手机验证码登录
微信登录POST/auth/wxLogin微信授权登录
退出登录POST/auth/logout退出登录
刷新TokenPOST/auth/refresh刷新访问令牌
获取用户信息GET/system/user/profile获取当前用户信息
更新用户信息PUT/system/user/profile更新用户基本信息
修改密码PUT/system/user/updatePwd修改登录密码
绑定手机号POST/system/user/bindMobile绑定手机号码
绑定邮箱POST/system/user/bindEmail绑定邮箱地址
上传头像POST/system/user/avatar上传用户头像
获取验证码GET/system/captcha获取图形验证码
发送短信POST/system/sms/send发送短信验证码

🔐 认证相关接口

用户登录

typescript
// 账号密码登录
export interface LoginRequest {
  username: string
  password: string
  code?: string
  uuid?: string
  rememberMe?: boolean
}

export interface LoginResponse {
  access_token: string
  refresh_token: string
  expires_in: number
  user: UserInfo
}

export const login = (data: LoginRequest): Promise<ApiResponse<LoginResponse>> => {
  return http.post<LoginResponse>('/auth/login', data)
}

// 使用示例
const handleLogin = async () => {
  try {
    const response = await login({
      username: 'admin',
      password: '123456',
      code: captchaCode.value,
      uuid: captchaUuid.value
    })

    // 保存token和用户信息
    const userStore = useUserStore()
    userStore.setToken(response.data.access_token)
    userStore.setUserInfo(response.data.user)

    uni.showToast({
      title: '登录成功',
      icon: 'success'
    })

    // 跳转到首页
    uni.switchTab({
      url: '/pages/index/index'
    })
  } catch (error) {
    console.error('登录失败:', error)
  }
}

短信登录

typescript
// 短信登录
export interface SmsLoginRequest {
  mobile: string
  code: string
  smsType: 'login' | 'register' | 'resetPwd'
}

export const smsLogin = (data: SmsLoginRequest): Promise<ApiResponse<LoginResponse>> => {
  return http.post<LoginResponse>('/auth/smsLogin', data)
}

// 发送短信验证码
export interface SendSmsRequest {
  mobile: string
  smsType: 'login' | 'register' | 'resetPwd' | 'bindMobile'
  scene?: string
}

export const sendSmsCode = (data: SendSmsRequest): Promise<ApiResponse<void>> => {
  return http.post<void>('/system/sms/send', data)
}

// 使用示例
const handleSmsLogin = async () => {
  try {
    // 先发送验证码
    await sendSmsCode({
      mobile: mobile.value,
      smsType: 'login'
    })

    uni.showToast({
      title: '验证码已发送',
      icon: 'success'
    })

    // 然后进行登录
    const response = await smsLogin({
      mobile: mobile.value,
      code: smsCode.value,
      smsType: 'login'
    })

    // 处理登录成功
    handleLoginSuccess(response.data)
  } catch (error) {
    console.error('短信登录失败:', error)
  }
}

微信登录

typescript
// 微信登录
export interface WxLoginRequest {
  code: string
  encryptedData?: string
  iv?: string
  rawData?: string
  signature?: string
}

export const wxLogin = (data: WxLoginRequest): Promise<ApiResponse<LoginResponse>> => {
  return http.post<LoginResponse>('/auth/wxLogin', data)
}

// 微信授权登录流程
const handleWxLogin = async () => {
  try {
    // 微信授权登录
    const loginRes = await uni.login({
      provider: 'weixin'
    })

    if (!loginRes.code) {
      throw new Error('微信授权失败')
    }

    // 获取用户信息
    const userInfoRes = await uni.getUserInfo({
      provider: 'weixin'
    })

    // 调用登录接口
    const response = await wxLogin({
      code: loginRes.code,
      encryptedData: userInfoRes.encryptedData,
      iv: userInfoRes.iv,
      rawData: userInfoRes.rawData,
      signature: userInfoRes.signature
    })

    handleLoginSuccess(response.data)
  } catch (error) {
    console.error('微信登录失败:', error)
    uni.showToast({
      title: '微信登录失败',
      icon: 'error'
    })
  }
}

退出登录

typescript
// 退出登录
export const logout = (): Promise<ApiResponse<void>> => {
  return http.post<void>('/auth/logout')
}

// 使用示例
const handleLogout = async () => {
  try {
    await logout()

    // 清除本地数据
    const userStore = useUserStore()
    userStore.logout()

    uni.showToast({
      title: '退出成功',
      icon: 'success'
    })

    // 跳转到登录页
    uni.reLaunch({
      url: '/pages/login/login'
    })
  } catch (error) {
    console.error('退出登录失败:', error)
  }
}

Token 刷新

typescript
// 刷新Token
export interface RefreshTokenRequest {
  refresh_token: string
}

export const refreshToken = (data: RefreshTokenRequest): Promise<ApiResponse<LoginResponse>> => {
  return http.post<LoginResponse>('/auth/refresh', data)
}

// 自动刷新Token
export const autoRefreshToken = async (): Promise<boolean> => {
  try {
    const userStore = useUserStore()
    const refreshToken = userStore.refreshToken

    if (!refreshToken) {
      return false
    }

    const response = await refreshToken({
      refresh_token: refreshToken
    })

    // 更新token
    userStore.setToken(response.data.access_token)
    userStore.setRefreshToken(response.data.refresh_token)

    return true
  } catch (error) {
    console.error('Token刷新失败:', error)
    return false
  }
}

👤 用户信息管理

获取用户信息

typescript
// 用户信息接口
export interface UserInfo {
  id: number
  username: string
  nickname: string
  avatar?: string
  email?: string
  mobile?: string
  sex: '0' | '1' | '2' // 0未知 1男 2女
  birthday?: string
  province?: string
  city?: string
  address?: string
  signature?: string
  status: '0' | '1' // 0正常 1停用
  createTime: string
  loginTime?: string
  loginIp?: string
  roles?: Role[]
  permissions?: string[]
}

export const getUserProfile = (): Promise<ApiResponse<UserInfo>> => {
  return http.get<UserInfo>('/system/user/profile')
}

// 使用示例
const loadUserProfile = async () => {
  try {
    const response = await getUserProfile()
    const userStore = useUserStore()
    userStore.setUserInfo(response.data)
    return response.data
  } catch (error) {
    console.error('获取用户信息失败:', error)
  }
}

更新用户信息

typescript
// 更新用户信息
export interface UpdateUserRequest {
  nickname?: string
  email?: string
  mobile?: string
  sex?: '0' | '1' | '2'
  birthday?: string
  province?: string
  city?: string
  address?: string
  signature?: string
}

export const updateUserProfile = (data: UpdateUserRequest): Promise<ApiResponse<void>> => {
  return http.put<void>('/system/user/profile', data)
}

// 使用示例
const handleUpdateProfile = async (updateData: UpdateUserRequest) => {
  try {
    await updateUserProfile(updateData)

    uni.showToast({
      title: '更新成功',
      icon: 'success'
    })

    // 重新获取用户信息
    await loadUserProfile()
  } catch (error) {
    console.error('更新用户信息失败:', error)
  }
}

修改密码

typescript
// 修改密码
export interface UpdatePasswordRequest {
  oldPassword: string
  newPassword: string
  confirmPassword: string
}

export const updatePassword = (data: UpdatePasswordRequest): Promise<ApiResponse<void>> => {
  return http.put<void>('/system/user/updatePwd', data)
}

// 使用示例
const handleUpdatePassword = async (passwordData: UpdatePasswordRequest) => {
  try {
    if (passwordData.newPassword !== passwordData.confirmPassword) {
      uni.showToast({
        title: '两次密码输入不一致',
        icon: 'error'
      })
      return
    }

    await updatePassword(passwordData)

    uni.showToast({
      title: '密码修改成功',
      icon: 'success'
    })

    // 修改密码后重新登录
    handleLogout()
  } catch (error) {
    console.error('修改密码失败:', error)
  }
}

绑定手机号

typescript
// 绑定手机号
export interface BindMobileRequest {
  mobile: string
  code: string
  password?: string
}

export const bindMobile = (data: BindMobileRequest): Promise<ApiResponse<void>> => {
  return http.post<void>('/system/user/bindMobile', data)
}

// 使用示例
const handleBindMobile = async () => {
  try {
    // 先发送验证码
    await sendSmsCode({
      mobile: mobile.value,
      smsType: 'bindMobile'
    })

    // 绑定手机号
    await bindMobile({
      mobile: mobile.value,
      code: smsCode.value,
      password: password.value
    })

    uni.showToast({
      title: '手机号绑定成功',
      icon: 'success'
    })

    // 更新用户信息
    await loadUserProfile()
  } catch (error) {
    console.error('绑定手机号失败:', error)
  }
}

绑定邮箱

typescript
// 绑定邮箱
export interface BindEmailRequest {
  email: string
  code: string
  password?: string
}

export const bindEmail = (data: BindEmailRequest): Promise<ApiResponse<void>> => {
  return http.post<void>('/system/user/bindEmail', data)
}

// 发送邮箱验证码
export interface SendEmailCodeRequest {
  email: string
  emailType: 'bind' | 'unbind' | 'resetPwd'
}

export const sendEmailCode = (data: SendEmailCodeRequest): Promise<ApiResponse<void>> => {
  return http.post<void>('/system/email/send', data)
}

上传头像

typescript
// 上传头像
export const uploadAvatar = (filePath: string): Promise<ApiResponse<string>> => {
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: `${import.meta.env.VITE_APP_BASE_API}/system/user/avatar`,
      filePath,
      name: 'file',
      header: {
        'Authorization': `Bearer ${useUserStore().token}`
      },
      success: (res) => {
        const data = JSON.parse(res.data)
        if (data.code === 200) {
          resolve(data)
        } else {
          reject(new Error(data.msg))
        }
      },
      fail: reject
    })
  })
}

// 选择并上传头像
const handleChooseAvatar = async () => {
  try {
    const chooseImageRes = await uni.chooseImage({
      count: 1,
      sizeType: ['compressed'],
      sourceType: ['album', 'camera']
    })

    const filePath = chooseImageRes.tempFilePaths[0]

    uni.showLoading({
      title: '上传中...'
    })

    const response = await uploadAvatar(filePath)

    uni.hideLoading()

    // 更新用户头像
    await updateUserProfile({
      avatar: response.data
    })

    uni.showToast({
      title: '头像更新成功',
      icon: 'success'
    })
  } catch (error) {
    uni.hideLoading()
    console.error('上传头像失败:', error)
    uni.showToast({
      title: '上传失败',
      icon: 'error'
    })
  }
}

🔒 验证码相关接口

图形验证码

typescript
// 获取图形验证码
export interface CaptchaResponse {
  uuid: string
  img: string
  enabled: boolean
}

export const getCaptcha = (): Promise<ApiResponse<CaptchaResponse>> => {
  return http.get<CaptchaResponse>('/system/captcha')
}

// 使用示例
const loadCaptcha = async () => {
  try {
    const response = await getCaptcha()
    captchaUuid.value = response.data.uuid
    captchaImg.value = response.data.img
    captchaEnabled.value = response.data.enabled
  } catch (error) {
    console.error('获取验证码失败:', error)
  }
}

短信验证码

typescript
// 验证短信验证码
export interface VerifySmsRequest {
  mobile: string
  code: string
  smsType: string
}

export const verifySmsCode = (data: VerifySmsRequest): Promise<ApiResponse<boolean>> => {
  return http.post<boolean>('/system/sms/verify', data)
}

// 获取短信发送记录
export const getSmsRecords = (mobile: string): Promise<ApiResponse<SmsRecord[]>> => {
  return http.get<SmsRecord[]>(`/system/sms/records/${mobile}`)
}

export interface SmsRecord {
  id: number
  mobile: string
  code: string
  smsType: string
  status: '0' | '1' // 0未使用 1已使用
  expireTime: string
  createTime: string
}

🔧 工具函数

登录状态检查

typescript
// 检查登录状态
export const checkLoginStatus = (): boolean => {
  const userStore = useUserStore()
  return !!userStore.token && !!userStore.userInfo
}

// 需要登录的页面守卫
export const requireLogin = () => {
  if (!checkLoginStatus()) {
    uni.showModal({
      title: '提示',
      content: '请先登录',
      showCancel: false,
      success: () => {
        uni.reLaunch({
          url: '/pages/login/login'
        })
      }
    })
    return false
  }
  return true
}

Token 有效性检查

typescript
// 检查Token是否即将过期
export const isTokenExpiringSoon = (expiresIn: number, threshold = 5 * 60 * 1000): boolean => {
  return expiresIn < threshold
}

// 自动刷新Token的组合函数
export function useTokenRefresh() {
  const userStore = useUserStore()
  let refreshTimer: number | null = null

  const startAutoRefresh = (expiresIn: number) => {
    if (refreshTimer) {
      clearTimeout(refreshTimer)
    }

    // 在token过期前5分钟自动刷新
    const refreshTime = Math.max(expiresIn - 5 * 60 * 1000, 0)

    refreshTimer = setTimeout(async () => {
      const success = await autoRefreshToken()
      if (success) {
        // 继续下一次自动刷新
        startAutoRefresh(userStore.expiresIn)
      } else {
        // 刷新失败,跳转登录页
        handleLogout()
      }
    }, refreshTime)
  }

  const stopAutoRefresh = () => {
    if (refreshTimer) {
      clearTimeout(refreshTimer)
      refreshTimer = null
    }
  }

  onUnmounted(() => {
    stopAutoRefresh()
  })

  return {
    startAutoRefresh,
    stopAutoRefresh
  }
}

用户权限检查

typescript
// 检查用户权限
export const hasPermission = (permission: string): boolean => {
  const userStore = useUserStore()
  return userStore.permissions.includes(permission) || userStore.permissions.includes('*:*:*')
}

// 检查用户角色
export const hasRole = (role: string): boolean => {
  const userStore = useUserStore()
  return userStore.roles.some(r => r.roleKey === role) || userStore.roles.some(r => r.roleKey === 'admin')
}

// 权限指令
export const vPermission = {
  mounted(el: HTMLElement, binding: any) {
    const permission = binding.value
    if (!hasPermission(permission)) {
      el.style.display = 'none'
    }
  },
  updated(el: HTMLElement, binding: any) {
    const permission = binding.value
    if (!hasPermission(permission)) {
      el.style.display = 'none'
    } else {
      el.style.display = ''
    }
  }
}

用户管理API为移动端提供了完整的用户认证和信息管理功能,支持多种登录方式和安全验证机制。