94 lines
2.5 KiB
TypeScript
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.

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import { getUsdcBalance, formatUsdcBalance } from '@/api/user'
export interface UserInfo {
/** 用户 IDAPI 可能返回 id 或 ID */
id?: number | string
ID?: number
headerImg?: string
nickName?: string
userName?: string
[key: string]: unknown
}
const STORAGE_KEY = 'poly-user'
function loadStored(): { token: string; user: UserInfo } | null {
try {
const raw = localStorage.getItem(STORAGE_KEY)
if (!raw) return null
return JSON.parse(raw) as { token: string; user: UserInfo }
} catch {
return null
}
}
function saveToStorage(token: string, user: UserInfo) {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify({ token, user }))
} catch {
//
}
}
function clearStorage() {
try {
localStorage.removeItem(STORAGE_KEY)
} catch {
//
}
}
export const useUserStore = defineStore('user', () => {
const stored = loadStored()
const token = ref<string>(stored?.token ?? '')
const user = ref<UserInfo | null>(stored?.user ?? null)
const isLoggedIn = computed(() => !!token.value && !!user.value)
const avatarUrl = computed(() => user.value?.headerImg ?? '')
/** 钱包余额显示,如 "0.00",可从接口更新 */
const balance = ref<string>('0.00')
function setUser(loginData: { token?: string; user?: UserInfo }) {
const t = loginData.token ?? ''
const u = loginData.user ?? null
token.value = t
user.value = u
if (t && u) saveToStorage(t, u)
else clearStorage()
}
function logout() {
token.value = ''
user.value = null
clearStorage()
}
/** 鉴权请求头x-token 与 x-user-id未登录时返回 undefined */
function getAuthHeaders(): Record<string, string> | undefined {
if (!token.value || !user.value) return undefined
const uid = user.value.id ?? user.value.ID
return {
'x-token': token.value,
...(uid != null && uid !== '' && { 'x-user-id': String(uid) }),
}
}
/** 请求 USDC 余额需已登录amount/available 除以 1000000 后更新余额显示 */
async function fetchUsdcBalance() {
const headers = getAuthHeaders()
if (!headers) return
try {
const res = await getUsdcBalance(headers)
if (res.code === 0 && res.data) {
balance.value = formatUsdcBalance(res.data.available)
}
} catch (e) {
console.error('[fetchUsdcBalance] 请求失败:', e)
}
}
return { token, user, isLoggedIn, avatarUrl, balance, setUser, logout, getAuthHeaders, fetchUsdcBalance }
})