init: initial commit
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import { create } from 'zustand'
|
||||
|
||||
interface AppState {
|
||||
sidebarOpen: boolean
|
||||
mobileMenuOpen: boolean
|
||||
toggleSidebar: () => void
|
||||
setMobileMenu: (open: boolean) => void
|
||||
}
|
||||
|
||||
export const useAppStore = create<AppState>((set) => ({
|
||||
sidebarOpen: true,
|
||||
mobileMenuOpen: false,
|
||||
toggleSidebar: () => set(s => ({ sidebarOpen: !s.sidebarOpen })),
|
||||
setMobileMenu: (open) => set({ mobileMenuOpen: open }),
|
||||
}))
|
||||
@@ -0,0 +1,78 @@
|
||||
import { create } from 'zustand'
|
||||
import type { SystemUser, SystemMenu } from '@/api/system'
|
||||
import { getUserMenuTree } from '@/api/systemCrud'
|
||||
import { logout as apiLogout } from '@/api/system'
|
||||
|
||||
const TOKEN_KEY = 'token'
|
||||
const USER_KEY = 'user'
|
||||
|
||||
interface AuthState {
|
||||
user: SystemUser | null
|
||||
token: string | null
|
||||
isAuthenticated: boolean
|
||||
menus: SystemMenu[]
|
||||
permissions: string[]
|
||||
login: (user: SystemUser, token: string) => void
|
||||
logout: () => Promise<void>
|
||||
refreshMenus: () => Promise<void>
|
||||
hasPermission: (permission: string) => boolean
|
||||
}
|
||||
|
||||
function extractPermissions(menus: SystemMenu[]): string[] {
|
||||
const perms: string[] = []
|
||||
const traverse = (m: SystemMenu) => {
|
||||
if (m.permission) perms.push(m.permission)
|
||||
m.children?.forEach(traverse)
|
||||
}
|
||||
menus.forEach(traverse)
|
||||
return perms
|
||||
}
|
||||
|
||||
function getStoredAuth() {
|
||||
try {
|
||||
const token = localStorage.getItem(TOKEN_KEY)
|
||||
const userStr = localStorage.getItem(USER_KEY)
|
||||
if (token && userStr) {
|
||||
return { user: JSON.parse(userStr) as SystemUser, token, isAuthenticated: true }
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
return { user: null, token: null, isAuthenticated: false }
|
||||
}
|
||||
|
||||
const initial = getStoredAuth()
|
||||
|
||||
export const useAuthStore = create<AuthState>((set, get) => ({
|
||||
user: initial.user,
|
||||
token: initial.token,
|
||||
isAuthenticated: initial.isAuthenticated,
|
||||
menus: [],
|
||||
permissions: [],
|
||||
|
||||
login: (user, token) => {
|
||||
localStorage.setItem(TOKEN_KEY, token)
|
||||
localStorage.setItem(USER_KEY, JSON.stringify(user))
|
||||
set({ user, token, isAuthenticated: true, menus: [], permissions: [] })
|
||||
},
|
||||
|
||||
logout: async () => {
|
||||
try { await apiLogout() } catch { /* ignore */ }
|
||||
localStorage.removeItem(TOKEN_KEY)
|
||||
localStorage.removeItem(USER_KEY)
|
||||
set({ user: null, token: null, isAuthenticated: false, menus: [], permissions: [] })
|
||||
},
|
||||
|
||||
refreshMenus: async () => {
|
||||
if (!get().isAuthenticated) return
|
||||
try {
|
||||
const res = await getUserMenuTree()
|
||||
const menus = res.data || []
|
||||
set({ menus, permissions: extractPermissions(menus) })
|
||||
} catch (e) { console.error('获取菜单失败:', e) }
|
||||
},
|
||||
|
||||
hasPermission: (permission) => {
|
||||
const { user, permissions } = get()
|
||||
if (user?.account === 'admin') return true
|
||||
return permissions.includes(permission)
|
||||
},
|
||||
}))
|
||||
Reference in New Issue
Block a user