94 lines
2.5 KiB
TypeScript
94 lines
2.5 KiB
TypeScript
import { ref, computed } from 'vue'
|
||
import { defineStore } from 'pinia'
|
||
import { getUsdcBalance, formatUsdcBalance } from '@/api/user'
|
||
|
||
export interface UserInfo {
|
||
/** 用户 ID(API 可能返回 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 }
|
||
})
|