feat: 新增userStore
This commit is contained in:
parent
30e4214387
commit
77c962ea91
|
@ -8,5 +8,4 @@ export interface UserType {
|
||||||
password: string
|
password: string
|
||||||
role: string
|
role: string
|
||||||
roleId: string
|
roleId: string
|
||||||
permissions: string | string[]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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']
|
||||||
|
|
|
@ -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}`) // 否则全部重定向到登录页
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
|
||||||
},
|
},
|
||||||
|
|
|
@ -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 = () => {
|
||||||
|
|
|
@ -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)
|
||||||
: []
|
: []
|
||||||
},
|
},
|
||||||
|
|
|
@ -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,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(() => {})
|
||||||
|
|
Loading…
Reference in New Issue