Files
sionrui/frontend/hooks/web/useUserInfo.js
2025-11-12 22:45:29 +08:00

151 lines
3.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 用户信息 Hook
* 封装获取用户信息的逻辑,可在各个应用中复用
*
* 使用方式:
* import { useUserInfo } from '@gold/hooks/web/useUserInfo'
*
* const { fetchUserInfo, loading, error } = useUserInfo()
* await fetchUserInfo()
*/
import { ref } from 'vue'
import axios from 'axios'
import { API_BASE } from '@gold/config/api'
// 获取 token 的工具函数(需要从应用层传入或使用全局配置)
let getTokenFn = null
/**
* 设置获取 token 的函数
* @param {Function} fn - 获取 token 的函数
*/
export function setTokenGetter(fn) {
getTokenFn = fn
}
/**
* 获取 Authorization Header
* @returns {string}
*/
function getAuthHeader() {
if (getTokenFn) {
const token = getTokenFn()
return token ? `Bearer ${token}` : ''
}
// 如果没有设置 token getter尝试从常见位置获取
try {
// 尝试从 sessionStorage 获取
const manualToken = sessionStorage.getItem('DEV_MANUAL_TOKEN')
if (manualToken) {
return `Bearer ${manualToken}`
}
} catch (e) {
// 忽略错误
}
return ''
}
/**
* 用户信息 Hook
* @param {Object} options - 配置选项
* @param {string} options.baseUrl - API 基础 URL可选默认使用 APP_MEMBER
* @param {Function} options.getToken - 获取 token 的函数(可选)
* @returns {Object} { fetchUserInfo, loading, error, userInfo }
*/
export function useUserInfo(options = {}) {
const loading = ref(false)
const error = ref(null)
const userInfo = ref(null)
// 如果传入了 getToken 函数,设置它
if (options.getToken) {
setTokenGetter(options.getToken)
}
// 确定 API 基础路径
const baseUrl = options.baseUrl || API_BASE.APP_MEMBER
const apiUrl = `${baseUrl}/user/get`
/**
* 获取用户信息
* @returns {Promise<Object>} 用户信息对象
*/
async function fetchUserInfo() {
loading.value = true
error.value = null
try {
const authHeader = getAuthHeader()
const headers = {
'Content-Type': 'application/json',
}
if (authHeader) {
headers.Authorization = authHeader
}
// 获取 tenant-id从环境变量或默认值
const tenantId =
(typeof import.meta !== 'undefined' && import.meta.env?.VITE_TENANT_ID) ||
(typeof process !== 'undefined' && process.env?.VITE_TENANT_ID) ||
'1'
if (tenantId) {
headers['tenant-id'] = tenantId
}
const response = await axios.get(apiUrl, { headers })
// 处理响应数据(根据后端返回格式调整)
// 后端通常返回 { code: 0, data: {...}, msg: '...' } 格式
let data = null
if (response.data) {
// 如果响应有 code 字段,说明是标准格式
if (typeof response.data.code === 'number') {
// code 为 0 或 200 表示成功
if (response.data.code === 0 || response.data.code === 200) {
data = response.data.data || response.data
} else {
throw new Error(response.data.msg || response.data.message || '获取用户信息失败')
}
} else {
// 没有 code 字段,直接使用 data
data = response.data.data || response.data
}
}
if (data) {
userInfo.value = data
return data
} else {
throw new Error('获取用户信息失败:响应数据为空')
}
} catch (err) {
error.value = err
console.error('获取用户信息失败:', err)
throw err
} finally {
loading.value = false
}
}
return {
fetchUserInfo,
loading,
error,
userInfo,
}
}
/**
* 便捷函数:直接获取用户信息(不返回响应式状态)
* @param {Object} options - 配置选项
* @returns {Promise<Object>} 用户信息对象
*/
export async function getUserInfo(options = {}) {
const { fetchUserInfo } = useUserInfo(options)
return await fetchUserInfo()
}