File size: 3,574 Bytes
69b897d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import router from '@/router'
import { apiClient } from '@/config/api'
export const useAuthStore = defineStore('auth', () => {
// 状态
const isLoggedIn = ref(false)
const authToken = ref(localStorage.getItem('authToken') || '')
const username = ref('')
const loginError = ref('')
const loginLoading = ref(false)
const oemSettings = ref({
siteName: 'Claude Relay Service',
siteIcon: '',
siteIconData: '',
faviconData: ''
})
const oemLoading = ref(true)
// 计算属性
const isAuthenticated = computed(() => !!authToken.value && isLoggedIn.value)
const token = computed(() => authToken.value)
const user = computed(() => ({ username: username.value }))
// 方法
async function login(credentials) {
loginLoading.value = true
loginError.value = ''
try {
const result = await apiClient.post('/web/auth/login', credentials)
if (result.success) {
authToken.value = result.token
username.value = result.username || credentials.username
isLoggedIn.value = true
localStorage.setItem('authToken', result.token)
await router.push('/dashboard')
} else {
loginError.value = result.message || '登录失败'
}
} catch (error) {
loginError.value = error.message || '登录失败,请检查用户名和密码'
} finally {
loginLoading.value = false
}
}
function logout() {
isLoggedIn.value = false
authToken.value = ''
username.value = ''
localStorage.removeItem('authToken')
router.push('/login')
}
function checkAuth() {
if (authToken.value) {
isLoggedIn.value = true
// 验证token有效性
verifyToken()
}
}
async function verifyToken() {
try {
// 获取当前用户信息
const userResult = await apiClient.get('/web/auth/user')
if (userResult.success && userResult.user) {
username.value = userResult.user.username
}
// 使用 dashboard 端点来验证 token
// 如果 token 无效,会抛出错误
const result = await apiClient.get('/admin/dashboard')
if (!result.success) {
logout()
}
} catch (error) {
// token 无效,需要重新登录
logout()
}
}
async function loadOemSettings() {
oemLoading.value = true
try {
const result = await apiClient.get('/admin/oem-settings')
if (result.success && result.data) {
oemSettings.value = { ...oemSettings.value, ...result.data }
// 设置favicon
if (result.data.siteIconData || result.data.siteIcon) {
const link = document.querySelector("link[rel*='icon']") || document.createElement('link')
link.type = 'image/x-icon'
link.rel = 'shortcut icon'
link.href = result.data.siteIconData || result.data.siteIcon
document.getElementsByTagName('head')[0].appendChild(link)
}
// 设置页面标题
if (result.data.siteName) {
document.title = `${result.data.siteName} - 管理后台`
}
}
} catch (error) {
console.error('加载OEM设置失败:', error)
} finally {
oemLoading.value = false
}
}
return {
// 状态
isLoggedIn,
authToken,
username,
loginError,
loginLoading,
oemSettings,
oemLoading,
// 计算属性
isAuthenticated,
token,
user,
// 方法
login,
logout,
checkAuth,
loadOemSettings
}
})
|