<template>
<el-config-provider :locale="language">
<div class="h-100 flex-column level-0">
<router-view />
<Dialog ref="timeoutRef" class="timeout" :config="timeoutConfig" @close="timeoutHandle">
<template #other>
<div class="timeout-container">
<div class="icon">
<el-icon :size="24"><IconError /></el-icon>
</div>
<div class="content">
<h3>{{ traduction('COMMON_ERROR') }}</h3>
<p>{{ timeoutMessage }}</p>
</div>
</div>
</template>
</Dialog>
<el-tooltip
v-model:visible="tooltipVisible"
:content="tooltipContent"
placement="top"
trigger="hover"
virtual-triggering
:virtual-ref="tooltipTriggerRef"
trigger-keys
/>
</div>
<div id="customizedHomepage"></div>
</el-config-provider>
</template>
<script setup lang="ts">
import useStore from '@/stores';
import zhCn from 'element-plus/es/locale/lang/zh-cn';
import en from 'element-plus/es/locale/lang/en';
import fr from 'element-plus/es/locale/lang/fr';
import ja from 'element-plus/es/locale/lang/ja';
import ru from 'element-plus/es/locale/lang/ru';
import $http, { IbmcHttp } from '@/utils/http-service';
import { onMounted, reactive, ref, watch } from 'vue';
import { getStoreData, setStoreData } from './utils/composition';
import { traduction } from './utils/language';
import { IconError } from '@computing/opendesign-icons';
import { useRouter } from 'vue-router';
import { RouterChangeReason } from './model/base-enum';
import { UI_RESET_SESSIONS, UI_RESET_LOGINOUT } from './api/api';
import { clearCurrentLoginInfo } from './utils/common-service';
import { authorizeGuard } from './apps/app-bmc/guard/authorize.guard';
import {
getBrowserType,
isIE11,
isSafari,
urlReplace,
escapeHeader,
updateLocalLoginCount
} from './utils/utils';
import { ROUTER_BASE } from '@/model/router-utils';
import { tooltipVisible, tooltipContent, tooltipTriggerRef } from '@/directive/mouseEventDirective';
const store = useStore();
const router = useRouter();
const timeoutRef = ref();
const timeoutMessage = ref('');
const allowHttpDelete = getStoreData('loct', 'allowHttpDelete');
const timeoutConfig = reactive({
title: traduction('COMMON_INFORMATION'),
content: '',
closeIcon: false,
cancelButton: {
hide: true
}
});
let language: any = zhCn;
const localeKey = getStoreData('loct', 'locale');
switch (localeKey) {
case 'en': {
language = en;
break;
}
case 'ja': {
language = ja;
break;
}
case 'ru': {
language = ru;
break;
}
case 'fr': {
language = fr;
break;
}
default: {
language = zhCn;
}
}
function timeoutHandle() {
timeoutRef.value.hide();
IbmcHttp.errorCount = 0;
router.push('/login');
setTimeout(() => {
self.location.reload();
}, 1000);
}
onMounted(() => {
watch(
() => store.state.event.error401,
newVal => {
const path = router.currentRoute.value.fullPath;
if (
getStoreData('glob', 'isTimeOut') ||
path.indexOf('login') > -1 ||
path === '' ||
path === '/'
) {
return;
}
clearCurrentLoginInfo();
setStoreData('glob', 'isTimeOut', true);
timeoutMessage.value = newVal.replace(/\d/g, '');
timeoutRef.value.show();
}
);
* 路由跳转错误,主要包括以下几种,
* 1. 用户未登录, (跳转到登录页)
* 2. 路由路径不存在 (已登录时,跳转到首页,未登录时跳转到登录页)
* 3. 用户无权限访问路由 (跳转到登录页,若已经登录,则注销会话)
*/
watch(
() => store.state.event.routeChangeError,
newVal => {
const val = newVal.replace(/(\.|\d)/g, '');
switch (val) {
case RouterChangeReason.notLogin:
router.push('/login');
break;
case RouterChangeReason.invalid:
router.push('/navigate/home');
break;
case RouterChangeReason.noPermission: {
const rn = getStoreData('loct', 'rn');
if (rn) {
const request = allowHttpDelete
? $http.delete(urlReplace(UI_RESET_LOGINOUT, { sid: rn }))
: $http.post(UI_RESET_SESSIONS, { RequestMethod: 'DELETE', SessionId: rn });
request.finally(() => {
clearCurrentLoginInfo();
});
}
setTimeout(() => router.push('/login'), 1000);
break;
}
default:
router.push('/navigate/home');
break;
}
}
);
router.beforeEach((to, from, next) => {
if (self.location.pathname !== ROUTER_BASE) {
self.location.pathname = ROUTER_BASE || '/';
}
const position = to.fullPath.lastIndexOf('navigate');
if (position > -1 && !to.fullPath.includes('login') && position !== 1) {
self.location.hash = '#/' + to.fullPath.slice(position);
}
const result = authorizeGuard(to);
if (result) {
next();
}
});
document.addEventListener('click', sendActived);
* tab页切换时,触发刷新操作, 登录页直接进入到Home
* visibilitychange事件触发的场景
* 1.页面刷新 2.tab页切换 3.tab页关闭 4.浏览器关闭
*/
document.addEventListener('visibilitychange', () => {
const path = router?.currentRoute?.value?.fullPath;
if (path?.indexOf('kvm_h5') > -1 || path?.indexOf('videoPlayer') > -1) {
return;
}
const loct = localStorage.getItem('loct');
const loctJson = loct ? JSON.parse(loct) : null;
if (loctJson) {
const rn = getStoreData('loct', 'rn');
if (rn === loctJson.rn) {
return;
}
self.location.reload();
}
});
let tabsCount = JSON.parse(localStorage.getItem('tabs') || '0');
const tabValid = sessionStorage.getItem('tabIsValid');
if (tabValid) {
tabsCount++;
localStorage.setItem('tabs', JSON.stringify(tabsCount));
}
window.addEventListener('beforeunload', () => {
let tabIsValidUnload = JSON.parse(sessionStorage.getItem('tabIsValid') || 'null');
if (tabIsValidUnload) {
let tabsUnload = JSON.parse(localStorage.getItem('tabs') || '0');
tabsUnload--;
localStorage.setItem('tabs', JSON.stringify(tabsUnload));
}
const isValid = sessionStorage.getItem('tabIsValid');
if (isValid) {
const tabIsValid = JSON.parse(isValid);
if (!tabIsValid) {
return;
}
}
if (isIE11() || isSafari()) {
sendDeactive();
} else {
const tabs = JSON.parse(localStorage.getItem('tabs') as string);
if (tabs !== null && tabs <= 0) {
sendDeactive();
}
}
});
function sendDeactive(): void {
const browser = getBrowserType();
if (isIE11() || browser.browser === 'firefox') {
const xml = new XMLHttpRequest();
const data = JSON.stringify({ Mode: 'Deactivate' });
xml.open('POST', '/UI/Rest/KeepAlive', false);
xml.withCredentials = true;
xml.setRequestHeader('From', 'WebUI');
xml.setRequestHeader('Content-Type', 'application/json');
xml.setRequestHeader('X-CSRF-Token', escapeHeader(getStoreData('loct', 'to')));
xml.send(data);
} else {
$http.keepAlive('Deactivate');
}
}
function sendActived() {
const path = router.currentRoute.value.fullPath;
if (path.indexOf('login') === -1 && path.indexOf('kvm_h5') === -1) {
$http.keepAlive('Activate');
}
}
});
</script>
<style scoped lang="scss">
:deep(.timeout-container) {
display: flex;
.content {
margin-left: 16px;
h3 {
font-size: 16px;
line-height: 24px;
color: var(--o-text-color-primary);
}
p {
margin-top: 16px;
}
}
}
</style>