import { toast } from 'sonner' import { create } from 'zustand' import { getSysUserInfo, logout } from '@/api' import { getExpandedMenus, sleep } from '@/lib' import type { SysUserInfo } from '@/schemas' const IS_LOGIN_KEY = 'is_login' interface Store { token: string | null tokenExp: string | null userInfo: SysUserInfo | null expandedMenus: number[] isLogin: boolean setToken: (token: string | null, tokenExp?: string | null) => void logout: () => void init: () => Promise toggleMenu: (id: number) => void } const isLoginPage = () => { return typeof window !== 'undefined' && window.location.pathname === '/login' } const getIsLogin = () => { return typeof window !== 'undefined' && localStorage.getItem(IS_LOGIN_KEY) === 'true' } const setLoginFlag = (isLogin: boolean) => { if (isLogin) { localStorage.setItem(IS_LOGIN_KEY, 'true') } else { localStorage.removeItem(IS_LOGIN_KEY) } } export const useStore = create((set) => { return { token: null, tokenExp: null, userInfo: null, expandedMenus: [], isLogin: getIsLogin(), setToken: (token, tokenExp = null) => { setLoginFlag(Boolean(token)) set({ token, tokenExp }) }, logout: async () => { try { await logout() } catch (error) { console.error(error) toast.error('退出登录失败,请稍后重试', { richColors: true }) return } set({ token: null, tokenExp: null, userInfo: null, isLogin: false }) setLoginFlag(false) location.replace('/login') }, init: async () => { if (isLoginPage()) { return } try { const [{ data }] = await Promise.all([getSysUserInfo(), sleep(500)]) set({ userInfo: data, expandedMenus: getExpandedMenus(data.menus), }) } catch (error) { console.error(error) set({ userInfo: null, expandedMenus: [], }) } }, toggleMenu: (id: number) => { set((state) => { const expandedMenus = state.expandedMenus.includes(id) ? state.expandedMenus.filter((item) => item !== id) : [...state.expandedMenus, id] return { expandedMenus } }) }, } })