refactor: ♻️ userStore 代码重构优化

Former-commit-id: ef31b8420a48a91dd2449d62fb615941d528bf24
This commit is contained in:
郝先瑞
2023-09-11 18:20:03 +08:00
parent 7fcf66c8d0
commit 18daf33f9d
8 changed files with 32 additions and 44 deletions

View File

@@ -2,9 +2,10 @@
* 登录用户信息 * 登录用户信息
*/ */
export interface UserInfo { export interface UserInfo {
userId: number; userId?: number;
nickname: string; username?: string;
avatar: string; nickname?: string;
avatar?: string;
roles: string[]; roles: string[];
perms: string[]; perms: string[];
} }

View File

@@ -7,7 +7,7 @@ import { Directive, DirectiveBinding } from "vue";
export const hasPerm: Directive = { export const hasPerm: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) { mounted(el: HTMLElement, binding: DirectiveBinding) {
// 「超级管理员」拥有所有的按钮权限 // 「超级管理员」拥有所有的按钮权限
const { roles, perms } = useUserStoreHook(); const { roles, perms } = useUserStoreHook().user;
if (roles.includes("ROOT")) { if (roles.includes("ROOT")) {
return true; return true;
} }
@@ -40,7 +40,7 @@ export const hasRole: Directive = {
if (value) { if (value) {
const requiredRoles = value; // DOM绑定需要的角色编码 const requiredRoles = value; // DOM绑定需要的角色编码
const { roles } = useUserStoreHook(); const { roles } = useUserStoreHook().user;
const hasRole = roles.some((perm) => { const hasRole = roles.some((perm) => {
return requiredRoles.includes(perm); return requiredRoles.includes(perm);
}); });

View File

@@ -16,7 +16,7 @@
<!-- 用户头像 --> <!-- 用户头像 -->
<el-dropdown trigger="click"> <el-dropdown trigger="click">
<div class="avatar-container"> <div class="avatar-container">
<img :src="userStore.avatar + '?imageView2/1/w/80/h/80'" /> <img :src="userStore.user.avatar + '?imageView2/1/w/80/h/80'" />
<i-ep-caret-bottom class="w-3 h-3" /> <i-ep-caret-bottom class="w-3 h-3" />
</div> </div>
<template #dropdown> <template #dropdown>

View File

@@ -22,7 +22,7 @@ router.beforeEach(async (to, from, next) => {
NProgress.done(); NProgress.done();
} else { } else {
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
const hasRoles = userStore.roles && userStore.roles.length > 0; const hasRoles = userStore.user.roles && userStore.user.roles.length > 0;
if (hasRoles) { if (hasRoles) {
// 未匹配到任何路由跳转404 // 未匹配到任何路由跳转404
if (to.matched.length === 0) { if (to.matched.length === 0) {
@@ -40,7 +40,7 @@ router.beforeEach(async (to, from, next) => {
next({ ...to, replace: true }); next({ ...to, replace: true });
} catch (error) { } catch (error) {
// 移除 token 并跳转登录页 // 移除 token 并跳转登录页
await userStore.resetToken(); await userStore.resetStore();
next(`/login?redirect=${to.path}`); next(`/login?redirect=${to.path}`);
NProgress.done(); NProgress.done();
} }

View File

@@ -1,4 +1,4 @@
import { RouteRecordRaw, useRouter } from "vue-router"; import { RouteRecordRaw } from "vue-router";
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { constantRoutes } from "@/router"; import { constantRoutes } from "@/router";
import { store } from "@/store"; import { store } from "@/store";

View File

@@ -11,16 +11,15 @@ import { UserInfo } from "@/api/user/types";
import { useStorage } from "@vueuse/core"; import { useStorage } from "@vueuse/core";
export const useUserStore = defineStore("user", () => { export const useUserStore = defineStore("user", () => {
// state const user: UserInfo = {
const userId = ref(); roles: [],
perms: [],
};
const token = useStorage("accessToken", ""); const token = useStorage("accessToken", "");
const nickname = ref("");
const avatar = ref("");
const roles = ref<Array<string>>([]); // 用户角色编码集合 → 判断路由权限
const perms = ref<Array<string>>([]); // 用户权限编码集合 → 判断按钮权限
/** /**
* 登录调用 * 登录
* *
* @param {LoginData} * @param {LoginData}
* @returns * @returns
@@ -45,16 +44,14 @@ export const useUserStore = defineStore("user", () => {
getUserInfo() getUserInfo()
.then(({ data }) => { .then(({ data }) => {
if (!data) { if (!data) {
return reject("Verification failed, please Login again."); reject("Verification failed, please Login again.");
return;
} }
if (!data.roles || data.roles.length <= 0) { if (!data.roles || data.roles.length <= 0) {
reject("getUserInfo: roles must be a non-null array!"); reject("getUserInfo: roles must be a non-null array!");
return;
} }
userId.value = data.userId; Object.assign(user, { ...data });
nickname.value = data.nickname;
avatar.value = data.avatar;
roles.value = data.roles;
perms.value = data.perms;
resolve(data); resolve(data);
}) })
.catch((error) => { .catch((error) => {
@@ -68,8 +65,7 @@ export const useUserStore = defineStore("user", () => {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
logoutApi() logoutApi()
.then(() => { .then(() => {
resetRouter(); resetStore();
resetToken();
location.reload(); // 清空路由 location.reload(); // 清空路由
resolve(); resolve();
}) })
@@ -79,28 +75,19 @@ export const useUserStore = defineStore("user", () => {
}); });
} }
// 重置 /** 清空缓存 */
function resetToken() { function resetStore() {
resetRouter();
token.value = ""; token.value = "";
nickname.value = ""; Object.assign(user, { roles: [], perms: [] });
avatar.value = "";
roles.value = [];
perms.value = [];
} }
return { return {
token, token,
nickname, user,
avatar,
roles,
perms,
login, login,
getInfo, getInfo,
logout, logout,
resetToken, resetStore,
/**
* 当前登录用户ID
*/
userId,
}; };
}); });

View File

@@ -74,10 +74,10 @@ orderCount.value = 2000;
<div class="flex items-center"> <div class="flex items-center">
<img <img
class="user-avatar" class="user-avatar"
:src="userStore.avatar + '?imageView2/1/w/80/h/80'" :src="userStore.user.avatar + '?imageView2/1/w/80/h/80'"
/> />
<span class="ml-[10px] text-[16px]"> <span class="ml-[10px] text-[16px]">
{{ userStore.nickname }} {{ userStore.user.nickname }}
</span> </span>
</div> </div>

View File

@@ -15,12 +15,12 @@ import { storeToRefs } from "pinia";
const emit = defineEmits(["change"]); const emit = defineEmits(["change"]);
const store = storeToRefs(useUserStoreHook()); const store = storeToRefs(useUserStoreHook());
const { roles } = store; const { roles } = store.user.value;
const switchRoles = computed({ const switchRoles = computed({
get: () => roles.value[0], get: () => roles[0],
set: (val) => { set: (val) => {
roles.value = [val]; Object.assign(roles, [val]);
emit("change"); emit("change");
}, },
}); });