Files
nl-tcm-agent-admin/src/stores/user.js
2026-08-15 12:52:39 +08:00

73 lines
2.8 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.
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { notification } from 'ant-design-vue'
import { loginApi, refreshApi, profileApi } from '@/api/auth'
import { TOKEN_KEY } from '@/api/request'
const USER_KEY = 'agent_admin_user'
const EXPIRE_KEY = 'agent_admin_expire'
// 用户会话 store登录 / 登出 / 会话校验 / 静默续签
export const useUserStore = defineStore('user', () => {
const token = ref(localStorage.getItem(TOKEN_KEY) || '')
const user = ref(safeParse(localStorage.getItem(USER_KEY)))
const expireAt = ref(Number(localStorage.getItem(EXPIRE_KEY) || 0))
const isAuthenticated = computed(() => !!token.value)
function safeParse(s) {
try { return s ? JSON.parse(s) : null } catch { return null }
}
// 登录:成功后落 localStorage 并返回,失败抛错由登录页展示(含 shake 动效)
async function login({ username, password, captcha }) {
const res = await loginApi({ username, password, captcha })
const d = res.data
token.value = d.token
user.value = { nick_name: d.nick_name, role_name: d.role_name, role: d.role }
expireAt.value = d.expire_at || 0
localStorage.setItem(TOKEN_KEY, d.token)
localStorage.setItem(USER_KEY, JSON.stringify(user.value))
localStorage.setItem(EXPIRE_KEY, String(expireAt.value))
notification.success({ message: '登录成功', description: `欢迎回来,${d.nick_name}` })
return d
}
// 会话校验:启动时调 profiletoken 失效会走 401 全局跳转
async function checkSession() {
if (!token.value) return false
try {
const res = await profileApi()
user.value = { ...user.value, ...res.data }
return true
} catch {
return false
}
}
// 静默续签:剩余有效期 < 24h 时换新 tokenAdminLayout 定时驱动)
async function maybeRefresh() {
if (!token.value || !expireAt.value) return
const remain = expireAt.value - Math.floor(Date.now() / 1000)
if (remain > 24 * 3600 || remain <= 0) return
try {
const res = await refreshApi()
token.value = res.data.token
expireAt.value = res.data.expire_at || 0
localStorage.setItem(TOKEN_KEY, token.value)
localStorage.setItem(EXPIRE_KEY, String(expireAt.value))
} catch { /* 续签失败不打扰用户,到期自然走 401 */ }
}
function logout() {
token.value = ''
user.value = null
expireAt.value = 0
localStorage.removeItem(TOKEN_KEY)
localStorage.removeItem(USER_KEY)
localStorage.removeItem(EXPIRE_KEY)
}
return { token, user, expireAt, isAuthenticated, login, logout, checkSession, maybeRefresh }
})