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' import { handleRouter, setRouter } from '@/router/handleRouter.ts' // 定义用户 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 const btnAuth = (set.permissions_info || []) .map((item: any) => item.code) .filter((item: any) => item) // 保存到本地存储 setStorage('token', set.user.token) setStorage('userInfo', set.user) setStorage('menusInfo', set.menus_info) setStorage('permissionsInfo', set.permissions_info) setStorage('btnAuth', btnAuth) setRouter() } /** * 清空用户信息(核心复用方法) * 作用:重置所有用户相关状态 + 清除本地存储 */ const clearUserInfo = () => { // 重置 Pinia 中的状态 token.value = '' userInfo.value = null menusInfo.value = [] permissionsInfo.value = [] // 清除本地存储的用户数据 removeStorage('token') removeStorage('userInfo') removeStorage('menusInfo') removeStorage('permissionsInfo') removeStorage('device_no') 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) // 跳转到首页 if (res.user.real_check !== 1) { router.push('/') } else { router.push('/realName') } } 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 (params: { device_no: string }) => { try { await logoutApi(params) } 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') } /** * 更新用户信息 * @param data 要更新的用户信息 */ const updateUserInfo = (data: Partial) => { if (userInfo.value) { // 合并更新用户信息 userInfo.value = { ...userInfo.value, ...data } // 更新本地存储 setStorage('userInfo', userInfo.value) } } return { // 状态 token, userInfo, menusInfo, permissionsInfo, // 计算属性 isLoggedIn, sideMenu, // 方法(箭头函数) login, setUserInfo, register, logout, forgotPassword, changePassword, sendCode, switchAccount, updateUserInfo, clearUserInfo, } })