useUserInfo.js 3.81 KB
/**
 * 用户信息获取 composable
 * 提供统一的用户信息获取逻辑
 *
 * @Date: 2026-01-18
 * @Description: 统一获取用户信息,处理缓存和错误
 */

import { ref } from 'vue'
import { getUserInfoAPI } from '@/api/users'

/**
 * 构建当前用户对象
 * @param {Object} data - 包含用户信息的响应数据
 * @returns {Object|null} 合并后的当前用户对象,或 null 如果无法构建
 */

export const build_current_user = (data) => {
  if (!data || typeof data !== 'object') return null

  const merged_user = {
    ...(data.user && typeof data.user === 'object' ? data.user : {}),
    ...(data.checkin && typeof data.checkin === 'object' ? data.checkin : {}),
  }

  const unread_candidates = [
    data?.unread_msg_count,
    data?.user?.unread_msg_count,
    data?.user?.unread,
    data?.unread_msg,
    data?.unread,
  ]

  for (const value of unread_candidates) {
    const num = Number(value)
    if (Number.isFinite(num)) {
      merged_user.unread_msg_count = num
      break
    }
  }

  const teacher_candidates = [
    data?.is_teacher,
    data?.user?.is_teacher,
    data?.user?.teacher,
  ]

  for (const value of teacher_candidates) {
    if (value === null || value === undefined) continue
    if (value === true || value === 'true') {
      merged_user.is_teacher = 1
      break
    }
    if (value === false || value === 'false') {
      merged_user.is_teacher = 0
      break
    }
    const num = Number(value)
    if (Number.isFinite(num)) {
      merged_user.is_teacher = num ? 1 : 0
      break
    }
  }

  return merged_user
}

/**
 * @function useUserInfo
 * @description 提供用户信息获取功能
 * @returns {Object} 包含用户信息状态和方法的对象
 */
export function useUserInfo() {
  // 用户信息状态
  const userInfo = ref(null)
  const loading = ref(false)
  const error = ref(null)

  /**
   * 刷新用户信息
   * @returns {Promise<Object>} 用户信息对象
   * @throws {Error} 获取失败时抛出错误
   */
  const refreshUserInfo = async () => {
    loading.value = true
    error.value = null

    try {
      const { code, data, msg } = await getUserInfoAPI()

      if (code === 1) {
        userInfo.value = data
        const mergedUser = build_current_user(data)

        // 更新本地存储
        if (mergedUser) {
          localStorage.setItem('currentUser', JSON.stringify(mergedUser))
        }

        loading.value = false
        return mergedUser
      } else {
        throw new Error(msg || '获取用户信息失败')
      }
    } catch (err) {
      error.value = err.message || '获取用户信息失败'
      loading.value = false
      throw err
    }
  }

  /**
   * 从本地存储获取用户信息(不发起网络请求)
   * @returns {Object|null} 用户信息对象,如果不存在则返回 null
   */
  const getUserInfoFromLocal = () => {
    try {
      const savedUser = localStorage.getItem('currentUser')
      return savedUser ? JSON.parse(savedUser) : null
    } catch (err) {
      console.error('解析本地用户信息失败:', err)
      return null
    }
  }

  /**
   * 清除本地用户信息
   */
  const clearUserInfo = () => {
    userInfo.value = null
    localStorage.removeItem('currentUser')
  }

  /**
   * 初始化用户信息(优先从本地存储,必要时刷新)
   * @param {boolean} [forceRefresh=false] - 是否强制刷新,忽略本地缓存
   * @returns {Promise<Object|null>} 用户信息对象
   */
  const initUserInfo = async (forceRefresh = false) => {
    if (!forceRefresh) {
      const localUser = getUserInfoFromLocal()
      if (localUser) {
        userInfo.value = localUser
        return localUser
      }
    }

    return await refreshUserInfo()
  }

  return {
    userInfo,
    loading,
    error,
    refreshUserInfo,
    getUserInfoFromLocal,
    clearUserInfo,
    initUserInfo
  }
}