index.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import { unref, nextTick } from 'vue';
  2. import { defineStore } from 'pinia';
  3. import { REFRESH_TOKEN_COUNT } from '@/config';
  4. import { router } from '@/router';
  5. import type { AdminLoginParams } from '@/service';
  6. import { fetchLogin, fetchUserInfo, fetchStudentLogin } from '@/service';
  7. import { useRouterPush } from '@/composables';
  8. import { localStg } from '@/utils';
  9. import { useTabStore } from '../tab';
  10. import { useRouteStore } from '../route';
  11. import { getToken, getUserInfo, clearAuthStorage } from './helpers';
  12. interface AuthState {
  13. /** 用户信息 */
  14. userInfo: Auth.UserInfo;
  15. /** 用户token */
  16. token: string;
  17. /** 登录的加载状态 */
  18. loginLoading: boolean;
  19. }
  20. export const useAuthStore = defineStore('auth-store', {
  21. state: (): AuthState => ({
  22. userInfo: getUserInfo(),
  23. token: getToken() as string,
  24. loginLoading: false
  25. }),
  26. getters: {
  27. /** 是否登录 */
  28. isLogin(state) {
  29. return Boolean(state.token);
  30. }
  31. },
  32. actions: {
  33. /** 重置auth状态 */
  34. resetAuthStore() {
  35. const { toLogin } = useRouterPush(false);
  36. const { resetTabStore } = useTabStore();
  37. const { resetRouteStore } = useRouteStore();
  38. const route = unref(router.currentRoute);
  39. clearAuthStorage();
  40. REFRESH_TOKEN_COUNT.length = 0;
  41. this.$reset();
  42. if (route.meta.requiresAuth) {
  43. toLogin();
  44. }
  45. nextTick(() => {
  46. resetTabStore();
  47. resetRouteStore();
  48. });
  49. },
  50. /**
  51. * 处理登录后成功或失败的逻辑
  52. * @param backendToken - 返回的token
  53. */
  54. async handleActionAfterLogin(backendToken: ApiAuth.Token) {
  55. const route = useRouteStore();
  56. const { toLoginRedirect } = useRouterPush(false);
  57. const loginSuccess = await this.loginByToken(backendToken);
  58. if (loginSuccess) {
  59. await route.initAuthRoute();
  60. // 跳转登录后的地址
  61. toLoginRedirect();
  62. // 登录成功弹出欢迎提示
  63. if (route.isInitAuthRoute) {
  64. window.$notification?.success({
  65. title: '登录成功!',
  66. content: `欢迎回来,${this.userInfo.username}!`,
  67. duration: 3000
  68. });
  69. }
  70. return;
  71. }
  72. // 不成功则重置状态
  73. this.resetAuthStore();
  74. },
  75. /**
  76. * 根据token进行登录
  77. * @param backendToken - 返回的token
  78. */
  79. async loginByToken(backendToken: ApiAuth.Token) {
  80. let successFlag = false;
  81. // 先把token存储到缓存中(后面接口的请求头需要token)
  82. const { token, refreshToken } = backendToken;
  83. localStg.set('token', token);
  84. localStg.set('refreshToken', refreshToken);
  85. // 获取用户信息
  86. const { data } = await fetchUserInfo();
  87. if (data) {
  88. // 成功后把用户信息存储到缓存中
  89. localStg.set('userInfo', data as Auth.UserInfo);
  90. // 更新状态
  91. this.userInfo = data as Auth.UserInfo;
  92. this.token = token;
  93. successFlag = true;
  94. }
  95. return successFlag;
  96. },
  97. async studentLogin(params: AdminLoginParams) {
  98. this.loginLoading = true;
  99. const { data, status, code } = await fetchStudentLogin(params);
  100. if (status && code === 200) {
  101. await this.handleActionAfterLogin(data as ApiAuth.Token);
  102. return true;
  103. }
  104. this.loginLoading = false;
  105. return false;
  106. },
  107. /**
  108. * 登录
  109. * @param userName - 用户名
  110. * @param password - 密码
  111. */
  112. async login(params: AdminLoginParams) {
  113. this.loginLoading = true;
  114. const { code, status, data } = await fetchLogin(params);
  115. if (status && code === 200) {
  116. await this.handleActionAfterLogin(data as ApiAuth.Token);
  117. return true;
  118. }
  119. this.loginLoading = false;
  120. return false;
  121. }
  122. }
  123. });