import { getStorage, setStorage, removeStorage } from '@/utils/storage'; import { loginApi, registerApi, logoutApi, forgotPasswordApi, changePasswordApi, sendCodeApi } from '@/api/modules/user'; import type { LoginParams, RegisterParams, ForgotPasswordParams, ChangePasswordParams, SendCodeParams } from '@/api/types/user'; import type { UserInfo, MenuItem, PermissionItem } from '@/stores/types/user'; import { formatMenuToElMenu, type ElMenuItem } from '@/utils/menuFormat'; // 定义用户 Store export const useUserStore = defineStore('user', () => { const router = useRouter(); // ========== 状态定义(与后端返回数据对应) ========== // 用户/菜单和权限状态 const userInfo = ref(getStorage('userInfo') || null); const token = ref(getStorage('token') || ''); const menusInfo = ref(getStorage('menusInfo') || []); const permissionsInfo = ref(getStorage('permissionsInfo') || []); // ========== 计算属性 ========== const isLoggedIn = computed(() => !!token.value); // const permissionKeys = computed(() => permissions.value.map(item => item.name)); // 格式化后的 el-menu 数据(自动更新) const sideMenu = computed(() => formatMenuToElMenu(menusInfo.value)); /** * 设置用户信息 * 作用:根据后端返回数据设置用户状态 + 本地存储 */ const setUserInfo = (set: any) => { token.value = set.user.token; userInfo.value = set.user; menusInfo.value = set.menus_info; permissionsInfo.value = set.permissions_info; // 保存到本地存储 setStorage('token', set.user.token); setStorage('userInfo', set.user); setStorage('menusInfo', set.menus_info); setStorage('permissionsInfo', set.permissions_info); console.log('用户信息保存成功'); }; /** * 清空用户信息(核心复用方法) * 作用:重置所有用户相关状态 + 清除本地存储 */ const clearUserInfo = () => { // 重置 Pinia 中的状态 token.value = ''; userInfo.value = null; menusInfo.value = []; permissionsInfo.value = []; // 清除本地存储的用户数据 removeStorage('token'); removeStorage('userInfo'); removeStorage('menusInfo'); removeStorage('permissionsInfo'); console.log('用户信息已清空'); }; /** * 登录方法 * @param params 登录参数 */ const login = async (params: LoginParams) => { try { const res = await loginApi(params); if (res.isUserNotExist) { // 用户不存在,跳转到注册页面 router.push('/user/register'); return; } setUserInfo(res); // 跳转到首页 router.push('/'); } catch (error) { console.error('登录失败', error); throw error; } }; /** * 注册方法 * @param params 登录参数 */ const register = async (params: RegisterParams) => { try { const res = await registerApi(params); //跳转登录页面 router.push('/user/login'); } catch (error) { console.error('注册失败', error); throw error; } }; /** * 退出登录 */ const logout = async () => { try { await logoutApi(); } catch (error) { console.error('退出登录接口调用失败', error); } finally { clearUserInfo(); // 跳转到登录页面 router.push('/user/login'); } }; /** * 忘记密码 */ const forgotPassword = async (params: ForgotPasswordParams) => { try { await forgotPasswordApi(params); // 跳转登录页面 router.push('/user/login'); } catch (error) { console.error('重置密码失败', error); throw error; } }; /** * 修改密码 */ const changePassword = async (params: ChangePasswordParams) => { try { await changePasswordApi(params); // 跳转登录页面 clearUserInfo(); router.push('/user/login'); } catch (error) { console.error('修改密码失败', error); throw error; } }; /** * 发送验证码 */ const sendCode = async (params: SendCodeParams) => { try { const res = await sendCodeApi(params); } catch (error) { console.error('发送验证码失败', error); throw error; } }; /** * 切换账户 */ const switchAccount = async () => { clearUserInfo(); router.push('/user/login'); }; return { // 状态 token, userInfo, menusInfo, permissionsInfo, // 计算属性 isLoggedIn, sideMenu, // 方法(箭头函数) login, register, logout, forgotPassword, changePassword, sendCode, switchAccount }; });