浏览代码

feat: 新增userStore

kailong321200875 1 年之前
父节点
当前提交
77c962ea91

+ 0 - 1
src/api/login/types.ts

@@ -8,5 +8,4 @@ export interface UserType {
   password: string
   role: string
   roleId: string
-  permissions: string | string[]
 }

+ 3 - 8
src/axios/config.ts

@@ -1,12 +1,8 @@
 import { AxiosResponse, AxiosRequestHeaders, InternalAxiosRequestConfig } from './types'
 import { ElMessage } from 'element-plus'
 import qs from 'qs'
-import router from '@/router'
 import { SUCCESS_CODE } from '@/constants'
-
-import { useStorage } from '@/hooks/web/useStorage'
-
-const { clear } = useStorage()
+import { useUserStoreWithOut } from '@/store/modules/user'
 
 const defaultRequestInterceptors = (config: InternalAxiosRequestConfig) => {
   if (
@@ -40,9 +36,8 @@ const defaultResponseInterceptors = (response: AxiosResponse) => {
   } else {
     ElMessage.error(response?.data?.message)
     if (response?.data?.code === 401) {
-      // token过期
-      clear()
-      router.push('/login')
+      const userStore = useUserStoreWithOut()
+      userStore.logout()
     }
   }
 }

+ 8 - 28
src/components/UserInfo/src/UserInfo.vue

@@ -1,49 +1,27 @@
 <script setup lang="ts">
-import { ElDropdown, ElDropdownMenu, ElDropdownItem, ElMessageBox } from 'element-plus'
+import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus'
 import { useI18n } from '@/hooks/web/useI18n'
-import { useStorage } from '@/hooks/web/useStorage'
-import { resetRouter } from '@/router'
-import { useRouter } from 'vue-router'
-import { loginOutApi } from '@/api/login'
 import { useDesign } from '@/hooks/web/useDesign'
-import { useTagsViewStore } from '@/store/modules/tagsView'
 import LockDialog from './components/LockDialog.vue'
 import { ref, computed } from 'vue'
 import LockPage from './components/LockPage.vue'
 import { useLockStore } from '@/store/modules/lock'
+import { useUserStore } from '@/store/modules/user'
+
+const userStore = useUserStore()
 
 const lockStore = useLockStore()
 
 const getIsLock = computed(() => lockStore.getLockInfo?.isLock ?? false)
 
-const tagsViewStore = useTagsViewStore()
-
 const { getPrefixCls } = useDesign()
 
 const prefixCls = getPrefixCls('user-info')
 
 const { t } = useI18n()
 
-const { clear } = useStorage()
-
-const { replace } = useRouter()
-
 const loginOut = () => {
-  ElMessageBox.confirm(t('common.loginOutMessage'), t('common.reminder'), {
-    confirmButtonText: t('common.ok'),
-    cancelButtonText: t('common.cancel'),
-    type: 'warning'
-  })
-    .then(async () => {
-      const res = await loginOutApi().catch(() => {})
-      if (res) {
-        clear()
-        tagsViewStore.delAllViews()
-        resetRouter() // 重置静态路由表
-        replace('/login')
-      }
-    })
-    .catch(() => {})
+  userStore.logoutConfirm()
 }
 
 const dialogVisible = ref<boolean>(false)
@@ -66,7 +44,9 @@ const toDocument = () => {
         alt=""
         class="w-[calc(var(--logo-height)-25px)] rounded-[50%]"
       />
-      <span class="<lg:hidden text-14px pl-[5px] text-[var(--top-header-text-color)]">Archer</span>
+      <span class="<lg:hidden text-14px pl-[5px] text-[var(--top-header-text-color)]">{{
+        userStore.getUserInfo?.username
+      }}</span>
     </div>
     <template #dropdown>
       <ElDropdownMenu>

+ 10 - 0
src/constants/index.ts

@@ -12,3 +12,13 @@ export const CONTENT_TYPE = 'application/json'
  * 请求超时时间
  */
 export const REQUEST_TIMEOUT = 60000
+
+/**
+ * 不重定向白名单
+ */
+export const NO_REDIRECT_WHITE_LIST = ['/login']
+
+/**
+ * 不重置路由白名单
+ */
+export const NO_RESET_WHITE_LIST = ['Redirect', 'Login', 'NoFind', 'Root']

+ 6 - 8
src/permission.ts

@@ -1,26 +1,24 @@
 import router from './router'
 import { useAppStoreWithOut } from '@/store/modules/app'
-import { useStorage } from '@/hooks/web/useStorage'
 import type { RouteRecordRaw } from 'vue-router'
 import { useTitle } from '@/hooks/web/useTitle'
 import { useNProgress } from '@/hooks/web/useNProgress'
 import { usePermissionStoreWithOut } from '@/store/modules/permission'
 import { usePageLoading } from '@/hooks/web/usePageLoading'
-
-const { getStorage } = useStorage()
+import { NO_REDIRECT_WHITE_LIST } from '@/constants'
+import { useUserStoreWithOut } from '@/store/modules/user'
 
 const { start, done } = useNProgress()
 
 const { loadStart, loadDone } = usePageLoading()
 
-const whiteList = ['/login'] // 不重定向白名单
-
 router.beforeEach(async (to, from, next) => {
   start()
   loadStart()
   const permissionStore = usePermissionStoreWithOut()
   const appStore = useAppStoreWithOut()
-  if (getStorage(appStore.getUserInfo)) {
+  const userStore = useUserStoreWithOut()
+  if (userStore.getUserInfo) {
     if (to.path === '/login') {
       next({ path: '/' })
     } else {
@@ -30,7 +28,7 @@ router.beforeEach(async (to, from, next) => {
       }
 
       // 开发者可根据实际情况进行修改
-      const roleRouters = getStorage('roleRouters') || []
+      const roleRouters = userStore.getRoleRouters || []
 
       // 是否使用动态路由
       if (appStore.getDynamicRouter) {
@@ -51,7 +49,7 @@ router.beforeEach(async (to, from, next) => {
       next(nextData)
     }
   } else {
-    if (whiteList.indexOf(to.path) !== -1) {
+    if (NO_REDIRECT_WHITE_LIST.indexOf(to.path) !== -1) {
       next()
     } else {
       next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页

+ 2 - 2
src/router/index.ts

@@ -3,6 +3,7 @@ import type { RouteRecordRaw } from 'vue-router'
 import type { App } from 'vue'
 import { Layout, getParentLayout } from '@/utils/routerHelper'
 import { useI18n } from '@/hooks/web/useI18n'
+import { NO_RESET_WHITE_LIST } from '@/constants'
 
 const { t } = useI18n()
 
@@ -690,10 +691,9 @@ const router = createRouter({
 })
 
 export const resetRouter = (): void => {
-  const resetWhiteNameList = ['Redirect', 'Login', 'NoFind', 'Root']
   router.getRoutes().forEach((route) => {
     const { name } = route
-    if (name && !resetWhiteNameList.includes(name as string)) {
+    if (name && !NO_RESET_WHITE_LIST.includes(name as string)) {
       router.hasRoute(name) && router.removeRoute(name)
     }
   })

+ 0 - 5
src/store/modules/app.ts

@@ -22,7 +22,6 @@ interface AppState {
   pageLoading: boolean
   layout: LayoutType
   title: string
-  userInfo: string
   isDark: boolean
   currentSize: ComponentSize
   sizeMap: ComponentSize[]
@@ -35,7 +34,6 @@ interface AppState {
 export const useAppStore = defineStore('app', {
   state: (): AppState => {
     return {
-      userInfo: 'userInfo', // 登录信息存储字段-建议每个项目换一个字段,避免与其它项目冲突
       sizeMap: ['default', 'large', 'small'],
       mobile: false, // 是否是移动端
       title: import.meta.env.VITE_APP_TITLE, // 标题
@@ -151,9 +149,6 @@ export const useAppStore = defineStore('app', {
     getTitle(): string {
       return this.title
     },
-    getUserInfo(): string {
-      return this.userInfo
-    },
     getIsDark(): boolean {
       return this.isDark
     },

+ 3 - 1
src/store/modules/permission.ts

@@ -77,7 +77,9 @@ export const usePermissionStore = defineStore('permission', {
       this.menuTabRouters = routers
     }
   },
-  persist: false
+  persist: {
+    paths: ['routers', 'addRouters', 'menuTabRouters']
+  }
 })
 
 export const usePermissionStoreWithOut = () => {

+ 3 - 6
src/store/modules/tagsView.ts

@@ -4,10 +4,7 @@ import { getRawRoute } from '@/utils/routerHelper'
 import { defineStore } from 'pinia'
 import { store } from '../index'
 import { findIndex } from '@/utils'
-import { useStorage } from '@/hooks/web/useStorage'
-import { useAppStoreWithOut } from './app'
-
-const { getStorage } = useStorage()
+import { useUserStoreWithOut } from './user'
 
 export interface TagsViewState {
   visitedViews: RouteLocationNormalizedLoaded[]
@@ -93,10 +90,10 @@ export const useTagsViewStore = defineStore('tagsView', {
     },
     // 删除所有tag
     delAllVisitedViews() {
-      const appStore = useAppStoreWithOut()
+      const userStore = useUserStoreWithOut()
 
       // const affixTags = this.visitedViews.filter((tag) => tag.meta.affix)
-      this.visitedViews = getStorage(appStore.getUserInfo)
+      this.visitedViews = userStore.getUserInfo
         ? this.visitedViews.filter((tag) => tag?.meta?.affix)
         : []
     },

+ 85 - 0
src/store/modules/user.ts

@@ -0,0 +1,85 @@
+import { defineStore } from 'pinia'
+import { store } from '../index'
+import { UserType } from '@/api/login/types'
+import { ElMessageBox } from 'element-plus'
+import { useI18n } from '@/hooks/web/useI18n'
+import { loginOutApi } from '@/api/login'
+import { useTagsViewStore } from './tagsView'
+import router from '@/router'
+
+interface UserState {
+  userInfo?: UserType
+  tokenKey: string
+  token: string
+  roleRouters?: string[] | AppCustomRouteRecordRaw[]
+}
+
+export const useUserStore = defineStore('user', {
+  state: (): UserState => {
+    return {
+      userInfo: undefined,
+      tokenKey: 'Token',
+      token: '',
+      roleRouters: undefined
+    }
+  },
+  getters: {
+    getTokenKey(): string {
+      return this.tokenKey
+    },
+    getToken(): string {
+      return this.token
+    },
+    getUserInfo(): UserType | undefined {
+      return this.userInfo
+    },
+    getRoleRouters(): string[] | AppCustomRouteRecordRaw[] | undefined {
+      return this.roleRouters
+    }
+  },
+  actions: {
+    setTokenKey(tokenKey: string) {
+      this.tokenKey = tokenKey
+    },
+    setToken(token: string) {
+      this.token = token
+    },
+    setUserInfo(userInfo?: UserType) {
+      this.userInfo = userInfo
+    },
+    setRoleRouters(roleRouters: string[] | AppCustomRouteRecordRaw[]) {
+      this.roleRouters = roleRouters
+    },
+    logoutConfirm() {
+      const { t } = useI18n()
+      ElMessageBox.confirm(t('common.loginOutMessage'), t('common.reminder'), {
+        confirmButtonText: t('common.ok'),
+        cancelButtonText: t('common.cancel'),
+        type: 'warning'
+      })
+        .then(async () => {
+          const res = await loginOutApi().catch(() => {})
+          if (res) {
+            this.reset()
+          }
+        })
+        .catch(() => {})
+    },
+    reset() {
+      const tagsViewStore = useTagsViewStore()
+      tagsViewStore.delAllViews()
+      this.setToken('')
+      this.setUserInfo(undefined)
+      this.setRoleRouters([])
+      router.replace('/login')
+    },
+    logout() {
+      this.reset()
+    }
+  },
+  persist: true
+})
+
+export const useUserStoreWithOut = () => {
+  return useUserStore(store)
+}

+ 5 - 5
src/views/Login/components/LoginForm.vue

@@ -5,7 +5,6 @@ import { useI18n } from '@/hooks/web/useI18n'
 import { ElButton, ElCheckbox, ElLink } from 'element-plus'
 import { useForm } from '@/hooks/web/useForm'
 import { loginApi, getTestRoleApi, getAdminRoleApi } from '@/api/login'
-import { useStorage } from '@/hooks/web/useStorage'
 import { useAppStore } from '@/store/modules/app'
 import { usePermissionStore } from '@/store/modules/permission'
 import { useRouter } from 'vue-router'
@@ -13,6 +12,7 @@ import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router'
 import { UserType } from '@/api/login/types'
 import { useValidator } from '@/hooks/web/useValidator'
 import { Icon } from '@/components/Icon'
+import { useUserStore } from '@/store/modules/user'
 
 const { required } = useValidator()
 
@@ -20,12 +20,12 @@ const emit = defineEmits(['to-register'])
 
 const appStore = useAppStore()
 
+const userStore = useUserStore()
+
 const permissionStore = usePermissionStore()
 
 const { currentRoute, addRoute, push } = useRouter()
 
-const { setStorage } = useStorage()
-
 const { t } = useI18n()
 
 const rules = {
@@ -215,7 +215,7 @@ const signIn = async () => {
         const res = await loginApi(formData)
 
         if (res) {
-          setStorage(appStore.getUserInfo, res.data)
+          userStore.setUserInfo(res.data)
           // 是否使用动态路由
           if (appStore.getDynamicRouter) {
             getRole()
@@ -247,7 +247,7 @@ const getRole = async () => {
       : await getTestRoleApi(params)
   if (res) {
     const routers = res.data || []
-    setStorage('roleRouters', routers)
+    userStore.setRoleRouters(routers)
     appStore.getDynamicRouter && appStore.getServerDynamicRouter
       ? await permissionStore.generateRoutes('server', routers).catch(() => {})
       : await permissionStore.generateRoutes('frontEnd', routers).catch(() => {})