157 lines
3.9 KiB
JavaScript
157 lines
3.9 KiB
JavaScript
|
|
import { defineStore } from 'pinia'
|
|||
|
|
import { ref, computed } from 'vue'
|
|||
|
|
import { useRouter } from 'vue-router'
|
|||
|
|
import * as authApi from '@/api/auth'
|
|||
|
|
|
|||
|
|
// ==================== 认证状态管理 ====================
|
|||
|
|
|
|||
|
|
export const useAuthStore = defineStore('auth', () => {
|
|||
|
|
// ==================== 状态 ====================
|
|||
|
|
|
|||
|
|
// 当前用户信息
|
|||
|
|
const currentUser = ref(
|
|||
|
|
JSON.parse(localStorage.getItem('user') || 'null')
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 认证令牌
|
|||
|
|
const token = ref(localStorage.getItem('token') || '')
|
|||
|
|
|
|||
|
|
// ==================== 计算属性(Getters) ====================
|
|||
|
|
|
|||
|
|
// 是否已登录
|
|||
|
|
const isLoggedIn = computed(() => !!token.value)
|
|||
|
|
|
|||
|
|
// 是否为管理员
|
|||
|
|
const isAdmin = computed(() => {
|
|||
|
|
if (!currentUser.value) return false
|
|||
|
|
return (
|
|||
|
|
currentUser.value.role === 'admin' ||
|
|||
|
|
currentUser.value.isAdmin === true
|
|||
|
|
)
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 用户名称(优先显示姓名,其次用户名)
|
|||
|
|
const userName = computed(() => {
|
|||
|
|
if (!currentUser.value) return ''
|
|||
|
|
return currentUser.value.name || currentUser.value.username || ''
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 用户所属组别
|
|||
|
|
const userGroup = computed(() => {
|
|||
|
|
return currentUser.value?.group || ''
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// ==================== 私有辅助方法 ====================
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 持久化存储 token 和用户信息到 localStorage
|
|||
|
|
*/
|
|||
|
|
function persistAuth(tokenValue, userData) {
|
|||
|
|
token.value = tokenValue
|
|||
|
|
currentUser.value = userData
|
|||
|
|
localStorage.setItem('token', tokenValue)
|
|||
|
|
localStorage.setItem('user', JSON.stringify(userData))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 清除本地存储的认证信息
|
|||
|
|
*/
|
|||
|
|
function clearAuth() {
|
|||
|
|
token.value = ''
|
|||
|
|
currentUser.value = null
|
|||
|
|
localStorage.removeItem('token')
|
|||
|
|
localStorage.removeItem('user')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ==================== 操作方法(Actions) ====================
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 参赛者登录(身份证号 + 密码)
|
|||
|
|
* @param {string} idNumber - 身份证号
|
|||
|
|
* @param {string} password - 密码
|
|||
|
|
* @returns {Promise<object>} 用户信息
|
|||
|
|
*/
|
|||
|
|
async function login(phone, password) {
|
|||
|
|
const result = await authApi.login(phone, password)
|
|||
|
|
// 后端应返回 { token, user }
|
|||
|
|
persistAuth(result.token, result.user)
|
|||
|
|
return result.user
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 管理员登录
|
|||
|
|
* @param {string} username - 管理员用户名
|
|||
|
|
* @param {string} password - 密码
|
|||
|
|
* @returns {Promise<object>} 管理员信息
|
|||
|
|
*/
|
|||
|
|
async function adminLogin(username, password) {
|
|||
|
|
const result = await authApi.adminLogin(username, password)
|
|||
|
|
// 后端应返回 { token, user }
|
|||
|
|
persistAuth(result.token, result.user)
|
|||
|
|
return result.user
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 激活账号(设置密码)
|
|||
|
|
* @param {object} data - { phone, password, smsCode }
|
|||
|
|
* @returns {Promise}
|
|||
|
|
*/
|
|||
|
|
async function activate(data) {
|
|||
|
|
const result = await authApi.activate(data)
|
|||
|
|
// 激活成功后自动登录
|
|||
|
|
if (result.token && result.user) {
|
|||
|
|
persistAuth(result.token, result.user)
|
|||
|
|
}
|
|||
|
|
return result
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 退出登录
|
|||
|
|
*/
|
|||
|
|
async function logout() {
|
|||
|
|
try {
|
|||
|
|
// 尝试通知后端登出
|
|||
|
|
await authApi.logout()
|
|||
|
|
} catch (e) {
|
|||
|
|
// 即使后端请求失败,也清除本地状态
|
|||
|
|
console.warn('登出请求失败,仍将清除本地状态', e)
|
|||
|
|
}
|
|||
|
|
clearAuth()
|
|||
|
|
// 跳转到登录页
|
|||
|
|
window.location.href = '/login'
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 从服务端获取最新用户信息
|
|||
|
|
* @returns {Promise<object>} 用户信息
|
|||
|
|
*/
|
|||
|
|
async function fetchCurrentUser() {
|
|||
|
|
const user = await authApi.getCurrentUser()
|
|||
|
|
currentUser.value = user
|
|||
|
|
localStorage.setItem('user', JSON.stringify(user))
|
|||
|
|
return user
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ==================== 导出 ====================
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
// 状态
|
|||
|
|
currentUser,
|
|||
|
|
token,
|
|||
|
|
// 计算属性
|
|||
|
|
isLoggedIn,
|
|||
|
|
isAdmin,
|
|||
|
|
userName,
|
|||
|
|
userGroup,
|
|||
|
|
// 操作
|
|||
|
|
login,
|
|||
|
|
adminLogin,
|
|||
|
|
activate,
|
|||
|
|
logout,
|
|||
|
|
fetchCurrentUser,
|
|||
|
|
// 工具方法
|
|||
|
|
clearAuth,
|
|||
|
|
persistAuth,
|
|||
|
|
}
|
|||
|
|
})
|