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

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

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

  /**
   * 从数据中提取未读消息数量
   * @param {Object} data - 包含用户信息的响应数据
   * @returns {number|null} 未读消息数量,或 null 如果无法提取
   */

  const get_unread_msg_count = (data) => {
    const candidates = [
      data?.unread_msg_count,
      data?.user?.unread_msg_count,
      data?.user?.unread,
      data?.unread_msg,
      data?.unread,
    ]

    for (const value of candidates) {
      const num = Number(value)
      if (Number.isFinite(num)) return num
    }

    return null
  }

  const get_is_teacher = (data) => {
    const candidates = [
      data?.is_teacher,
      data?.user?.is_teacher,
      data?.user?.teacher,
    ]

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

    return 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 = {
          ...data.user,
          ...data.checkin
        }

        const unread = get_unread_msg_count(data)
        if (unread !== null) {
          mergedUser.unread_msg_count = unread
        }

        const is_teacher = get_is_teacher(data)
        if (is_teacher !== null) {
          mergedUser.is_teacher = is_teacher
        }

        // 更新本地存储
        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
  }
}