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:
parent
03928dfce5
commit
eef60bde52
4
.gitignore
vendored
4
.gitignore
vendored
@ -33,3 +33,7 @@ lerna-debug.log*
|
||||
# Use the PNPM
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
|
||||
# history
|
||||
|
||||
.history
|
||||
|
@ -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
38
src/store/modules/auth.ts
Normal 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()
|
||||
}
|
@ -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()
|
||||
}
|
||||
|
@ -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: "/" })
|
||||
|
Loading…
x
Reference in New Issue
Block a user