75 lines
2.5 KiB
TypeScript
75 lines
2.5 KiB
TypeScript
/**
|
||||
|
|
* 管理端登录状态(跨页面共享单例)。
|
|||
|
|
*
|
|||
|
|
* 参数配置页与 Worker 管理页共用同一份 token(localStorage 的 cm_admin_token),
|
|||
|
|
* 在任一页面登录后另一页面无需重复登录。抽成模块级单例而非 Pinia store,
|
|||
|
|
* 避免为这点状态引入额外样板。
|
|||
|
|
*/
|
|||
|
|
import { computed, ref } from 'vue'
|
|||
|
|
import { ElMessage } from 'element-plus'
|
|||
|
|
import { login, parseJwt, TOKEN_KEY, type AuthUser } from '@/api/workerAdmin'
|
|||
|
|
|
|||
|
|
const token = ref(localStorage.getItem(TOKEN_KEY) || '')
|
|||
|
|
const currentUser = ref<AuthUser | null>(null)
|
|||
|
|
const username = ref('')
|
|||
|
|
const password = ref('')
|
|||
|
|
const logging = ref(false)
|
|||
|
|
|
|||
|
|
/** 从持久化 token 恢复身份(进入页面时调用;权限校验仍以后端为准) */
|
|||
|
|
export function restoreAuth(): AuthUser | null {
|
|||
|
|
const t = token.value.trim()
|
|||
|
|
currentUser.value = t ? parseJwt(t) : null
|
|||
|
|
return currentUser.value
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function useAdminAuth() {
|
|||
|
|
const isLoggedIn = computed(() => !!token.value.trim())
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 登录并领取管理 Token。
|
|||
|
|
* @returns 登录成功时的用户信息;失败返回 null(已弹出提示)。
|
|||
|
|
*/
|
|||
|
|
const doLogin = async (): Promise<AuthUser | null> => {
|
|||
|
|
const name = username.value.trim()
|
|||
|
|
if (!name || !password.value) {
|
|||
|
|
ElMessage.warning('请输入用户名和密码')
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
logging.value = true
|
|||
|
|
try {
|
|||
|
|
const data = await login(name, password.value)
|
|||
|
|
// 后端登录失败仍返回 HTTP 200,仅 result=fail + 空 token
|
|||
|
|
if (data.result !== 'success' || !data.token) {
|
|||
|
|
ElMessage.error(`登录失败:${data.message || '用户名或密码错误'}`)
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
token.value = data.token
|
|||
|
|
localStorage.setItem(TOKEN_KEY, data.token)
|
|||
|
|
username.value = ''
|
|||
|
|
password.value = ''
|
|||
|
|
const info = parseJwt(data.token)
|
|||
|
|
currentUser.value = info
|
|||
|
|
ElMessage.success(`登录成功:${(info?.username || '').trim() || '未知用户'}`)
|
|||
|
|
if (!info?.is_superuser) {
|
|||
|
|
ElMessage.error('权限不足:仅超级管理员可管理配置,操作将被拒绝')
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
return info
|
|||
|
|
} catch (e: any) {
|
|||
|
|
ElMessage.error(`登录失败:${e.message}`)
|
|||
|
|
return null
|
|||
|
|
} finally {
|
|||
|
|
logging.value = false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const logout = () => {
|
|||
|
|
localStorage.removeItem(TOKEN_KEY)
|
|||
|
|
token.value = ''
|
|||
|
|
currentUser.value = null
|
|||
|
|
ElMessage.success('已退出登录')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return { token, currentUser, username, password, logging, isLoggedIn, doLogin, logout }
|
|||
|
|
}
|