223 lines
5.5 KiB
Vue
223 lines
5.5 KiB
Vue
<script setup lang="ts">
|
|
import { ref, toRaw, onMounted, onUnmounted } from 'vue';
|
|
import useI18n from '@/hooks/useI18n';
|
|
import { message } from 'ant-design-vue/lib';
|
|
import { getToken } from '@/plugins/auth-token';
|
|
import useUserStore from '@/store/modules/user';
|
|
import useLockedStore from '@/store/modules/locked';
|
|
import { getConfigKey } from '@/api/system/config';
|
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
|
import { useRouter } from 'vue-router';
|
|
import { computed } from 'vue';
|
|
const lockedStore = useLockedStore();
|
|
const userStore = useUserStore();
|
|
const router = useRouter();
|
|
const { t } = useI18n();
|
|
|
|
const password = ref('');
|
|
/**设置定时器ID */
|
|
let timeoutDuration = 10 * 60 * 1000; // 设置超时时间为10分钟,单位为毫秒
|
|
let timeoutId: any = null;
|
|
|
|
// 超时锁屏
|
|
function resetTimeout() {
|
|
if (timeoutId) {
|
|
clearTimeout(timeoutId);
|
|
}
|
|
timeoutId = setTimeout(() => {
|
|
lockedStore.fnLock('lock');
|
|
}, timeoutDuration);
|
|
}
|
|
|
|
/**解锁 */
|
|
function handleUnlock() {
|
|
let lockFrom: any = {};
|
|
lockFrom.username = userStore.userName;
|
|
lockFrom.password = password.value;
|
|
userStore.fnLogin(toRaw(lockFrom)).then(res => {
|
|
if (res.code === RESULT_CODE_SUCCESS) {
|
|
message.success(t('components.LockScreen.validSucc'), 3);
|
|
password.value = '';
|
|
lockedStore.fnLock('none');
|
|
} else {
|
|
message.error(t('components.LockScreen.validError'), 3);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**返回登录界面 */
|
|
function backLogin() {
|
|
lockedStore.fnLock('none');
|
|
userStore.fnLogOut().finally(() => router.push({ name: 'Login' }));
|
|
}
|
|
|
|
const isLocked = computed(() => lockedStore.type !== 'none');
|
|
|
|
onMounted(() => {
|
|
getConfigKey('sys.lockTime')
|
|
.then(res => {
|
|
if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
|
lockedStore.lockTimeout = res.data;
|
|
timeoutDuration = res.data * 1000;
|
|
}
|
|
})
|
|
.finally(() => {
|
|
if (timeoutDuration !== 0) {
|
|
resetTimeout();
|
|
// 监听用户的操作,重置超时时间
|
|
window.addEventListener('mousemove', resetTimeout);
|
|
window.addEventListener('keydown', resetTimeout);
|
|
}
|
|
// 本地锁定同时是登录状态
|
|
if (lockedStore.type === 'lock' && getToken()) {
|
|
lockedStore.fnLock('lock');
|
|
} else if (lockedStore.type === 'reload') {
|
|
lockedStore.relaodWait();
|
|
}
|
|
});
|
|
});
|
|
|
|
/**组件实例被卸载之后调用 */
|
|
onUnmounted(() => {
|
|
if (timeoutId) {
|
|
clearTimeout(timeoutId);
|
|
}
|
|
});
|
|
</script>
|
|
<template>
|
|
<a-modal
|
|
v-model:visible="isLocked"
|
|
get-container="#app"
|
|
:footer="null"
|
|
:zIndex="1008"
|
|
:closable="false"
|
|
:keyboard="false"
|
|
:centered="true"
|
|
:maskClosable="false"
|
|
:maskStyle="{
|
|
backdropFilter: 'blur(10px)',
|
|
WebkitBackdropFilter: 'blur(10px)',
|
|
}"
|
|
wrapClassName="lock-screen"
|
|
:wrap-style="{
|
|
background: 'rgba(0, 0, 0, 0.85)',
|
|
}"
|
|
>
|
|
<!-- 锁屏-登录 -->
|
|
<div class="lock-screen_login" v-if="lockedStore.type === 'lock'">
|
|
<div class="lock-screen_login-user">
|
|
<a-avatar
|
|
shape="circle"
|
|
:size="100"
|
|
:src="userStore.getAvatar"
|
|
:alt="userStore.userName"
|
|
></a-avatar>
|
|
<span class="nick">
|
|
{{ userStore.nickName }}
|
|
</span>
|
|
</div>
|
|
<div class="lock-screen_login-from">
|
|
<a-input-group compact>
|
|
<a-input
|
|
type="password"
|
|
v-model:value="password"
|
|
:placeholder="t('components.LockScreen.inputPlacePwd')"
|
|
:maxlength="32"
|
|
style="width: calc(100% - 50px)"
|
|
@keyup.enter="handleUnlock"
|
|
/>
|
|
<a-button type="primary" @click="handleUnlock">
|
|
<LoginOutlined />
|
|
</a-button>
|
|
</a-input-group>
|
|
<a-button type="text" class="logout" @click="backLogin">
|
|
{{ t('components.LockScreen.backLogin') }}
|
|
</a-button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 锁屏-OMC重启升级 -->
|
|
<div class="lock-screen_reload" v-if="lockedStore.type === 'reload'">
|
|
<LoadingOutlined style="font-size: 56px" />
|
|
<div class="text">
|
|
{{ t('components.LockScreen.backReload') }}
|
|
</div>
|
|
<div class="desc">
|
|
{{ t('components.LockScreen.backReload2') }}
|
|
</div>
|
|
</div>
|
|
</a-modal>
|
|
</template>
|
|
|
|
<style lang="less" scoped>
|
|
.lock-screen_login {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background-color: transparent;
|
|
|
|
&-user {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
.nick {
|
|
font-size: 28px;
|
|
max-width: 164px;
|
|
white-space: nowrap;
|
|
text-align: start;
|
|
text-overflow: ellipsis;
|
|
overflow: hidden;
|
|
color: #fff;
|
|
}
|
|
}
|
|
|
|
&-from {
|
|
display: flex;
|
|
flex-flow: column;
|
|
width: 256px;
|
|
margin-top: 30px;
|
|
|
|
.logout {
|
|
margin-top: 8px;
|
|
color: rgba(255, 255, 255, 0.85);
|
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
|
|
&:hover {
|
|
color: var(--ant-primary-color);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.lock-screen_reload {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background-color: transparent;
|
|
|
|
color: #fff;
|
|
|
|
& .text {
|
|
font-size: 24px;
|
|
font-weight: bold;
|
|
letter-spacing: 4px;
|
|
margin-top: 24px;
|
|
}
|
|
& .desc {
|
|
margin-top: 8px;
|
|
font-size: 16px;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<style lang="less">
|
|
.lock-screen {
|
|
.ant-modal-content {
|
|
background-color: transparent;
|
|
box-shadow: none;
|
|
}
|
|
}
|
|
</style>
|