import type { GetUserInfoModel, UserInfo } from '@vben/types';
|
|
import type { AuthApi } from '#/api';
|
|
import { h, ref } from 'vue';
|
import { useRouter } from 'vue-router';
|
|
import { useMessage } from '@jnpf/hooks';
|
import { encryptByMd5, formatToDateTime } from '@jnpf/utils';
|
|
import { LOGIN_PATH } from '@vben/constants';
|
import { preferences, updatePreferences } from '@vben/preferences';
|
import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';
|
|
import { notification } from 'ant-design-vue';
|
import { cloneDeep } from 'lodash-es';
|
import { defineStore } from 'pinia';
|
|
import { getUserInfoApi, loginApi, logoutApi, unlockApi } from '#/api';
|
import { $t, initLocale } from '#/locales';
|
import { defaultPreferencesConfig } from '#/utils/constants';
|
import { getRealJnpfAppEnCode } from '#/utils/jnpf';
|
|
import { useBaseStore } from './base';
|
|
export const useAuthStore = defineStore('auth', () => {
|
const accessStore = useAccessStore();
|
const userStore = useUserStore();
|
const baseStore = useBaseStore();
|
const router = useRouter();
|
|
const loginLoading = ref(false);
|
|
/**
|
* 异步处理登录操作
|
* Asynchronously handle the login process
|
* @param params 登录表单数据
|
*/
|
async function authLogin(params: AuthApi.LoginParams) {
|
const loginRequestParams: AuthApi.LoginParams = { ...params };
|
// 异步处理用户登录操作并获取 accessToken
|
let userInfo: null | UserInfo = null;
|
try {
|
loginLoading.value = true;
|
const res = await loginApi(loginRequestParams);
|
const { token: accessToken } = res.data;
|
|
// 如果成功获取到 accessToken
|
if (accessToken) {
|
accessStore.setAccessToken(accessToken);
|
|
userInfo = await fetchUserInfo();
|
if (!userInfo) return;
|
userStore.setUserInfo(userInfo);
|
|
if (accessStore.loginExpired) {
|
accessStore.setLoginExpired(false);
|
}
|
|
if (userInfo?.prevLogin === 1) {
|
notification?.destroy();
|
notification.open({
|
message: $t('sys.login.lastLoginInfo'),
|
description: () =>
|
h('div', { class: 'pt-[10px]' }, [
|
h('p', null, `时间: ${formatToDateTime(userInfo?.prevLoginTime)}`),
|
h('p', null, `地点: ${userInfo?.prevLoginIPAddressName || ''}`),
|
h('p', null, `IP: ${userInfo?.prevLoginIPAddress || ''}`),
|
]),
|
placement: 'bottomRight',
|
style: { width: '300px' },
|
});
|
}
|
}
|
} finally {
|
loginLoading.value = false;
|
}
|
|
return userInfo;
|
}
|
|
async function logout(redirect: boolean = true) {
|
try {
|
if (accessStore.accessToken) {
|
const res = await logoutApi();
|
// 单点登录退出登录
|
if (res?.data?.ssoLogoutApiUrl) {
|
const iframe: any = document.createElement('IFRAME');
|
iframe.setAttribute('style', 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;');
|
iframe.src = res?.data.ssoLogoutApiUrl;
|
iframe.addEventListener('load', () => {
|
iframe.remove();
|
});
|
document.body.append(iframe);
|
}
|
}
|
} catch {
|
// 不做任何处理
|
}
|
|
resetAllStores();
|
accessStore.setLoginExpired(false);
|
if (router.currentRoute.value.path === LOGIN_PATH) return;
|
|
// 回登陆页带上当前路由地址
|
await router.replace({
|
path: LOGIN_PATH,
|
query: redirect
|
? {
|
redirect: encodeURIComponent(router.currentRoute.value.fullPath),
|
}
|
: {},
|
});
|
}
|
|
async function fetchUserInfo() {
|
const res = await getUserInfoApi();
|
if (!res) return null;
|
const { userInfo, sysConfigInfo, menuList = [], permissionList = [] } = res.data as GetUserInfoModel;
|
initLocale(preferences.app.locale);
|
handleUpdatePreferences(userInfo);
|
|
baseStore.setSysConfig(sysConfigInfo);
|
userStore.setUserInfo(userInfo);
|
accessStore.setBackMenus(menuList);
|
accessStore.setPermissionList(permissionList);
|
return userInfo;
|
}
|
|
// 更新偏好配置
|
function handleUpdatePreferences(userInfo) {
|
const appEnCode = getRealJnpfAppEnCode();
|
let preferenceJson: any = cloneDeep(defaultPreferencesConfig);
|
try {
|
if (userInfo.preferenceJson) preferenceJson = JSON.parse(userInfo.preferenceJson);
|
} catch {
|
preferenceJson = cloneDeep(defaultPreferencesConfig);
|
}
|
if (!appEnCode) preferenceJson.app.layout = 'mixed-nav';
|
if (appEnCode && ['teamwork', 'workFlow'].includes(appEnCode)) preferenceJson.app.layout = 'sidebar-nav';
|
updatePreferences(preferenceJson);
|
}
|
|
function confirmLoginOut() {
|
const { createConfirm } = useMessage();
|
createConfirm({
|
iconType: 'warning',
|
title: () => h('span', $t('sys.app.logoutTip')),
|
content: () => h('span', $t('sys.app.logoutMessage')),
|
onOk: async () => {
|
await logout(false);
|
},
|
});
|
}
|
// 锁屏解锁
|
async function unLock(password) {
|
const userStore = useUserStore();
|
try {
|
const account = userStore.getUserInfo?.userAccount;
|
const res = await unlockApi({
|
account,
|
password: encryptByMd5(password),
|
});
|
return res;
|
} catch {
|
return false;
|
}
|
}
|
function goForbidden() {
|
router.replace('/forbidden');
|
}
|
|
function $reset() {
|
loginLoading.value = false;
|
}
|
|
return {
|
$reset,
|
authLogin,
|
fetchUserInfo,
|
loginLoading,
|
logout,
|
confirmLoginOut,
|
unLock,
|
goForbidden,
|
};
|
});
|