角色权限、RequirePermission、/me permissions 与 migration 000015; Reviewer Approve → Closed。Next:ECR-013B Contract Definition。 Co-authored-by: Cursor <cursoragent@cursor.com>
56 lines
1.3 KiB
TypeScript
56 lines
1.3 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { ref } from 'vue'
|
|
import { adminApi, getToken, setToken } from '@/api/client'
|
|
|
|
export const useAuthStore = defineStore('auth', () => {
|
|
const token = ref<string | null>(getToken())
|
|
const username = ref<string>('')
|
|
const role = ref<string>('')
|
|
const permissions = ref<string[]>([])
|
|
|
|
function applyMe(me: { username: string; role?: string; permissions?: string[] }) {
|
|
username.value = me.username
|
|
role.value = me.role || ''
|
|
permissions.value = me.permissions ?? []
|
|
}
|
|
|
|
async function login(user: string, password: string) {
|
|
const res = await adminApi.login(user, password)
|
|
setToken(res.token)
|
|
token.value = res.token
|
|
applyMe(res.admin)
|
|
}
|
|
|
|
async function hydrate() {
|
|
if (!token.value) return false
|
|
try {
|
|
const me = await adminApi.me()
|
|
applyMe(me)
|
|
return true
|
|
} catch {
|
|
setToken(null)
|
|
token.value = null
|
|
return false
|
|
}
|
|
}
|
|
|
|
async function logout() {
|
|
try {
|
|
await adminApi.logout()
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
setToken(null)
|
|
token.value = null
|
|
username.value = ''
|
|
role.value = ''
|
|
permissions.value = []
|
|
}
|
|
|
|
function can(code: string) {
|
|
return permissions.value.includes(code)
|
|
}
|
|
|
|
return { token, username, role, permissions, can, login, logout, hydrate }
|
|
})
|