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>
|