Template
1
0
mirror of https://github.com/un-pany/v3-admin-vite.git synced 2025-04-22 03:49:19 +08:00

refactor:用户鉴权与用户数据模块分离

This commit is contained in:
moke 2023-12-18 23:46:07 +08:00
parent 03928dfce5
commit eef60bde52
5 changed files with 71 additions and 57 deletions

4
.gitignore vendored
View File

@ -33,3 +33,7 @@ lerna-debug.log*
# Use the PNPM
package-lock.json
yarn.lock
# history
.history

View File

@ -1,5 +1,6 @@
import router from "@/router"
import { useUserStoreHook } from "@/store/modules/user"
import { useAuthStoreHook } from "@/store/modules/auth"
import { usePermissionStoreHook } from "@/store/modules/permission"
import { ElMessage } from "element-plus"
import { setRouteChange } from "@/hooks/useRouteListener"
@ -18,6 +19,7 @@ router.beforeEach(async (to, _from, next) => {
fixBlankPage()
NProgress.start()
const userStore = useUserStoreHook()
const authStore = useAuthStoreHook()
const permissionStore = usePermissionStoreHook()
const token = getToken()
@ -47,7 +49,7 @@ router.beforeEach(async (to, _from, next) => {
try {
if (routeSettings.async) {
// 注意:角色必须是一个数组! 例如: ['admin'] 或 ['developer', 'editor']
await userStore.getInfo()
await authStore.getInfo()
const roles = userStore.roles
// 根据角色生成可访问的 Routes可访问路由 = 常驻路由 + 有访问权限的动态路由)
permissionStore.setRoutes(roles)

38
src/store/modules/auth.ts Normal file
View File

@ -0,0 +1,38 @@
import { defineStore } from "pinia"
import { useUserStore } from "./user"
import { loginApi, getUserInfoApi } from "@/api/login"
import { setToken } from "@/utils/cache/cookies"
import { type LoginRequestData } from "@/api/login/types/login"
/**
*
*/
export const useAuthStore = defineStore("auth", () => {
const userStore = useUserStore()
/**
*
* @param {LoginRequestData} loginData -
*/
const login = async (loginData: LoginRequestData) => {
const { data } = await loginApi(loginData)
userStore.token = data.token
setToken(data.token)
await getInfo()
}
/**
*
*/
const getInfo = async () => {
const { data } = await getUserInfoApi()
userStore.username = data.username
userStore.roles = data.roles
}
return { login, getInfo }
})
export function useAuthStoreHook() {
return useAuthStore()
}

View File

@ -1,81 +1,51 @@
import { ref } from "vue"
import store from "@/store"
import { defineStore } from "pinia"
import { usePermissionStore } from "./permission"
import { useTagsViewStore } from "./tags-view"
import { useSettingsStore } from "./settings"
import { getToken, removeToken, setToken } from "@/utils/cache/cookies"
import router, { resetRouter } from "@/router"
import { loginApi, getUserInfoApi } from "@/api/login"
import { type LoginRequestData } from "@/api/login/types/login"
import { type RouteRecordRaw } from "vue-router"
import routeSettings from "@/config/route"
import { getToken, removeToken } from "@/utils/cache/cookies"
import { resetRouter } from "@/router"
/**
*
*/
export const useUserStore = defineStore("user", () => {
/** 用户的 token */
const token = ref<string>(getToken() || "")
/** 用户的角色 */
const roles = ref<string[]>([])
/** 用户名 */
const username = ref<string>("")
const permissionStore = usePermissionStore()
const tagsViewStore = useTagsViewStore()
const settingsStore = useSettingsStore()
/** 设置角色数组 */
/**
*
* @param {string[]} value -
*/
const setRoles = (value: string[]) => {
roles.value = value
}
/** 登录 */
const login = async ({ username, password, code }: LoginRequestData) => {
const { data } = await loginApi({ username, password, code })
setToken(data.token)
token.value = data.token
}
/** 获取用户详情 */
const getInfo = async () => {
const { data } = await getUserInfoApi()
username.value = data.username
// 验证返回的 roles 是否为一个非空数组,否则塞入一个没有任何作用的默认角色,防止路由守卫逻辑进入无限循环
roles.value = data.roles?.length > 0 ? data.roles : routeSettings.defaultRoles
}
/** 切换角色 */
const changeRoles = async (role: string) => {
const newToken = "token-" + role
token.value = newToken
setToken(newToken)
await getInfo()
permissionStore.setRoutes(roles.value)
resetRouter()
permissionStore.dynamicRoutes.forEach((item: RouteRecordRaw) => {
router.addRoute(item)
})
_resetTagsView()
}
/** 登出 */
/**
*
*/
const logout = () => {
removeToken()
token.value = ""
roles.value = []
resetRouter()
_resetTagsView()
}
/** 重置 Token */
/**
* token
*/
const resetToken = () => {
removeToken()
token.value = ""
roles.value = []
}
/** 重置 Visited Views 和 Cached Views */
const _resetTagsView = () => {
if (!settingsStore.cacheTagsView) {
tagsViewStore.delAllVisitedViews()
tagsViewStore.delAllCachedViews()
}
}
return { token, roles, username, setRoles, login, getInfo, changeRoles, logout, resetToken }
return { token, roles, username, setRoles, logout, resetToken }
})
/** 在 setup 外使用 */
export function useUserStoreHook() {
return useUserStore(store)
return useUserStore()
}

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import { reactive, ref } from "vue"
import { useRouter } from "vue-router"
import { useUserStore } from "@/store/modules/user"
import { useAuthStore } from "@/store/modules/auth"
import { type FormInstance, type FormRules } from "element-plus"
import { User, Lock, Key, Picture, Loading } from "@element-plus/icons-vue"
import { getLoginCodeApi } from "@/api/login"
@ -37,7 +37,7 @@ const handleLogin = () => {
loginFormRef.value?.validate((valid: boolean, fields) => {
if (valid) {
loading.value = true
useUserStore()
useAuthStore()
.login(loginFormData)
.then(() => {
router.push({ path: "/" })