feat: 新增userStore

This commit is contained in:
kailong321200875 2023-11-30 16:08:26 +08:00
parent 30e4214387
commit 77c962ea91
11 changed files with 125 additions and 64 deletions

View File

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

View File

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

View File

@ -1,49 +1,27 @@
<script setup lang="ts"> <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 { 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 { useDesign } from '@/hooks/web/useDesign'
import { useTagsViewStore } from '@/store/modules/tagsView'
import LockDialog from './components/LockDialog.vue' import LockDialog from './components/LockDialog.vue'
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import LockPage from './components/LockPage.vue' import LockPage from './components/LockPage.vue'
import { useLockStore } from '@/store/modules/lock' import { useLockStore } from '@/store/modules/lock'
import { useUserStore } from '@/store/modules/user'
const userStore = useUserStore()
const lockStore = useLockStore() const lockStore = useLockStore()
const getIsLock = computed(() => lockStore.getLockInfo?.isLock ?? false) const getIsLock = computed(() => lockStore.getLockInfo?.isLock ?? false)
const tagsViewStore = useTagsViewStore()
const { getPrefixCls } = useDesign() const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('user-info') const prefixCls = getPrefixCls('user-info')
const { t } = useI18n() const { t } = useI18n()
const { clear } = useStorage()
const { replace } = useRouter()
const loginOut = () => { const loginOut = () => {
ElMessageBox.confirm(t('common.loginOutMessage'), t('common.reminder'), { userStore.logoutConfirm()
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(() => {})
} }
const dialogVisible = ref<boolean>(false) const dialogVisible = ref<boolean>(false)
@ -66,7 +44,9 @@ const toDocument = () => {
alt="" alt=""
class="w-[calc(var(--logo-height)-25px)] rounded-[50%]" 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> </div>
<template #dropdown> <template #dropdown>
<ElDropdownMenu> <ElDropdownMenu>

View File

@ -12,3 +12,13 @@ export const CONTENT_TYPE = 'application/json'
* *
*/ */
export const REQUEST_TIMEOUT = 60000 export const REQUEST_TIMEOUT = 60000
/**
*
*/
export const NO_REDIRECT_WHITE_LIST = ['/login']
/**
*
*/
export const NO_RESET_WHITE_LIST = ['Redirect', 'Login', 'NoFind', 'Root']

View File

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

View File

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

View File

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

View File

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

View File

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

85
src/store/modules/user.ts Normal file
View File

@ -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)
}

View File

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