Files
nl-tcm-agent-admin/src/stores/user.js

73 lines
2.8 KiB
JavaScript
Raw Normal View History

2025-05-15 21:24:56 +08:00
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
2026-08-15 12:52:39 +08:00
import { notification } from 'ant-design-vue'
import { loginApi, refreshApi, profileApi } from '@/api/auth'
import { TOKEN_KEY } from '@/api/request'
2025-05-15 21:24:56 +08:00
2026-08-15 12:52:39 +08:00
const USER_KEY = 'agent_admin_user'
const EXPIRE_KEY = 'agent_admin_expire'
// 用户会话 store登录 / 登出 / 会话校验 / 静默续签
2025-05-15 21:24:56 +08:00
export const useUserStore = defineStore('user', () => {
2026-08-15 12:52:39 +08:00
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 }
}
2025-05-15 21:24:56 +08:00
2026-08-15 12:52:39 +08:00
// 登录:成功后落 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
2025-05-15 21:24:56 +08:00
}
2026-08-15 12:52:39 +08:00
// 会话校验:启动时调 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 */ }
}
2025-05-15 21:24:56 +08:00
2026-08-15 12:52:39 +08:00
function logout() {
token.value = ''
user.value = null
expireAt.value = 0
localStorage.removeItem(TOKEN_KEY)
localStorage.removeItem(USER_KEY)
localStorage.removeItem(EXPIRE_KEY)
}
2025-05-15 21:24:56 +08:00
2026-08-15 12:52:39 +08:00
return { token, user, expireAt, isAuthenticated, login, logout, checkSession, maybeRefresh }
})