Files
dy/frontend/src/stores/auth.js
T
2026-08-07 17:51:57 +08:00

189 lines
5.5 KiB
JavaScript

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import api from '../api'
import { MENU_ITEMS, menuAccessible } from '../config/menus'
export const useAuthStore = defineStore('auth', () => {
const token = ref(localStorage.getItem('kefu_token') || '')
const user = ref(JSON.parse(localStorage.getItem('kefu_user') || 'null'))
const isLoggedIn = computed(() => !!token.value)
const permissions = computed(() => {
const list = user.value?.permissions
return Array.isArray(list) ? list : []
})
const permissionSet = computed(() => new Set(permissions.value))
const isAdmin = computed(() => {
if (typeof user.value?.is_admin === 'boolean') return user.value.is_admin
return user.value?.role === 'admin'
})
const hasPermission = (code) => {
if (!code) return true
if (isAdmin.value) return true
if (permissionSet.value.has(code)) return true
// Legacy accounts.write covers all granular account write buttons.
if (
code.startsWith('accounts.') &&
code !== 'accounts.write' &&
permissionSet.value.has('accounts.write')
) {
return true
}
return false
}
const canWrite = computed(() =>
hasPermission('accounts.write') ||
hasPermission('accounts.create') ||
hasPermission('accounts.update') ||
hasPermission('accounts.delete') ||
hasPermission('accounts.start') ||
hasPermission('accounts.stop') ||
hasPermission('accounts.cookie')
)
const canCreateAccounts = computed(() => hasPermission('accounts.create'))
const canUpdateAccounts = computed(() => hasPermission('accounts.update'))
const canDeleteAccounts = computed(() => hasPermission('accounts.delete'))
const canStartAccounts = computed(() => hasPermission('accounts.start'))
const canStopAccounts = computed(() => hasPermission('accounts.stop'))
const canManageCookies = computed(() => hasPermission('accounts.cookie'))
const canWriteMessages = computed(() => hasPermission('messages.write'))
const canWriteRules = computed(() => hasPermission('rules.write'))
const canWriteLinkCards = computed(() => hasPermission('link_cards.write'))
const canClearSystemLogs = computed(() => hasPermission('system_logs.clear'))
const canManageUsers = computed(() => hasPermission('users.manage'))
const canManageRoles = computed(() => hasPermission('roles.manage'))
const canManagePayments = computed(() => hasPermission('payments.manage'))
const canManageSettings = computed(() => hasPermission('settings.manage'))
const canManageDatabase = computed(() => hasPermission('settings.database'))
const canCreateOrders = computed(() => hasPermission('orders.create'))
const hasGlobalDataScope = computed(
() => isAdmin.value || hasPermission('data.scope_all')
)
const isViewer = computed(
() =>
!canWrite.value &&
!canWriteMessages.value &&
!canWriteRules.value &&
!isAdmin.value
)
const roleLabel = computed(
() => user.value?.role_label || user.value?.role || ''
)
const visibleMenus = computed(() =>
MENU_ITEMS.filter((item) => menuAccessible(item, hasPermission)).map((item) => ({
...item,
title: isAdmin.value && item.adminTitle ? item.adminTitle : item.title
}))
)
const setSession = (accessToken, userData) => {
token.value = accessToken
user.value = userData
localStorage.setItem('kefu_token', accessToken)
localStorage.setItem('kefu_user', JSON.stringify(userData))
}
const clearSession = () => {
token.value = ''
user.value = null
localStorage.removeItem('kefu_token')
localStorage.removeItem('kefu_user')
}
const login = async (username, password) => {
const res = await api.post('/auth/login', { username, password })
const accessToken = res.data.access_token
const me = await api.get('/auth/me', {
headers: { Authorization: `Bearer ${accessToken}` }
})
setSession(accessToken, me.data)
return me.data
}
const register = async (payload) => {
const res = await api.post('/auth/register', payload)
return res.data
}
const verifyEmail = async (verifyToken) => {
const res = await api.post('/auth/verify-email', { token: verifyToken })
return res.data
}
const resendVerification = async (payload) => {
const res = await api.post('/auth/resend-verification', payload)
return res.data
}
const forgotPassword = async (payload) => {
const res = await api.post('/auth/forgot-password', payload)
return res.data
}
const resetPassword = async (resetToken, password) => {
const res = await api.post('/auth/reset-password', {
token: resetToken,
password
})
return res.data
}
const fetchMe = async () => {
if (!token.value) return null
const res = await api.get('/auth/me')
user.value = res.data
localStorage.setItem('kefu_user', JSON.stringify(res.data))
return res.data
}
const logout = () => {
clearSession()
}
return {
token,
user,
isLoggedIn,
permissions,
isAdmin,
canWrite,
canCreateAccounts,
canUpdateAccounts,
canDeleteAccounts,
canStartAccounts,
canStopAccounts,
canManageCookies,
canWriteMessages,
canWriteRules,
canWriteLinkCards,
canClearSystemLogs,
canManageUsers,
canManageRoles,
canManagePayments,
canManageSettings,
canManageDatabase,
canCreateOrders,
hasGlobalDataScope,
isViewer,
roleLabel,
visibleMenus,
hasPermission,
login,
register,
verifyEmail,
resendVerification,
forgotPassword,
resetPassword,
fetchMe,
logout,
clearSession
}
})