康来智慧冷链系统 - 前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

231 lines
6.3 KiB

<template>
<div
:class="prefixCls"
class="fixed inset-0 flex h-screen w-screen bg-black items-center justify-center"
>
<!--解锁区域-->
<div
v-show="showDate"
:class="`${prefixCls}__unlock`"
class="absolute top-0 left-1/2 flex pt-5 h-16 items-center justify-center sm:text-md xl:text-xl text-white flex-col cursor-pointer transform translate-x-1/2"
@click="handleShowForm(false)"
>
<LockOutlined/>
<span>{{ t('sys.lock.unlock') }}</span>
</div>
<!--锁屏时间区域-->
<div class="flex w-screen h-screen justify-center items-center">
<div :class="`${prefixCls}__hour`" class="relative mr-5 md:mr-20 w-2/5 h-2/5 md:h-4/5">
<span>{{ hour }}</span>
<span v-show="showDate" class="meridiem absolute left-5 top-5 text-md xl:text-xl">
{{ meridiem }}
</span>
</div>
<div :class="`${prefixCls}__minute w-2/5 h-2/5 md:h-4/5 `">
<span>{{ minute }}</span>
</div>
</div>
<!--锁屏登录区域-->
<transition name="fade-slide">
<div v-show="!showDate" :class="`${prefixCls}-entry`">
<div :class="`${prefixCls}-entry-content`">
<div :class="`${prefixCls}-entry__header enter-x`">
<img :src="userInfo.avatar || defaultAvatar" :class="`${prefixCls}-entry__header-img`">
<p :class="`${prefixCls}-entry__header-name`">
{{ userInfo.nickName }}
</p>
</div>
<InputPassword
v-model:value="password"
:placeholder="t('sys.lock.placeholder')"
class="enter-x"
/>
<span v-if="errMsg" :class="`${prefixCls}-entry__err-msg enter-x`">
{{ t('sys.lock.alert') }}
</span>
<div :class="`${prefixCls}-entry__footer enter-x`">
<a-button
type="link"
size="small"
class="mt-2 mr-2 enter-x"
:disabled="loading"
@click="handleShowForm(true)"
>{{ t('common.back') }}</a-button>
<a-button
type="link"
size="small"
class="mt-2 mr-2 enter-x"
:disabled="loading"
@click="goLogin"
>{{ t('sys.lock.backToLogin') }}</a-button>
<a-button
type="link"
size="small"
class="mt-2"
:loading="loading"
@click="unLock()"
>{{ t('sys.lock.entry') }}</a-button>
</div>
</div>
</div>
</transition>
<!--锁屏登录时间区域-->
<div class="absolute bottom-5 w-full text-gray-300 xl:text-xl 2xl:text-3xl text-center enter-y">
<div v-show="!showDate" class="text-5xl mb-4 enter-x">
{{ hour }}:{{ minute }}
<span class="text-3xl">{{ meridiem }}</span>
</div>
<div class="text-2xl"> {{ year }}/{{ month }}/{{ day }} {{ week }} </div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import { Input } from 'ant-design-vue';
import { useUserStore } from '/@/store/modules/user';
import { useLockStore } from '/@/store/modules/lock';
import { useI18n } from '/@/hooks/web/useI18n';
import { useNow } from './useNow';
import { useDesign } from '/@/hooks/web/useDesign';
import { LockOutlined } from '@ant-design/icons-vue';
import { UserVo } from '/@/api/platform/core/entity/user';
import defaultAvatar from '/@/assets/images/defaultAvatar.svg';
const InputPassword = Input.Password;
const password = ref('');
const loading = ref(false);
const errMsg = ref(false);
const showDate = ref(true);
const { prefixCls } = useDesign('lock-page');
const lockStore = useLockStore();
const userStore = useUserStore();
const { hour, month, minute, meridiem, year, day, week } = useNow(true);
const { t } = useI18n();
const userInfo = computed<UserVo>(() => {
return userStore.getUserInfo || {};
});
/** 解锁 */
async function unLock() {
if (!password.value) return;
let pwd = password.value;
try {
loading.value = true;
const res = await lockStore.unLock(pwd);
errMsg.value = !res;
} finally {
loading.value = false;
}
}
/** 跳转登陆页面 */
function goLogin() {
userStore.logout(true);
lockStore.resetLockInfo();
}
/** 处理显示锁屏登录区域 */
function handleShowForm(show = false) {
showDate.value = show;
}
</script>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-lock-page';
.@{prefix-cls} {
z-index: @lock-page-z-index;
&__unlock {
transform: translate(-50%, 0);
}
&__hour,
&__minute {
display: flex;
font-weight: 700;
color: #bababa;
background-color: #141313;
border-radius: 30px;
justify-content: center;
align-items: center;
@media screen and (max-width: @screen-md) {
span:not(.meridiem) {
font-size: 160px;
}
}
@media screen and (min-width: @screen-md) {
span:not(.meridiem) {
font-size: 160px;
}
}
@media screen and (max-width: @screen-sm) {
span:not(.meridiem) {
font-size: 90px;
}
}
@media screen and (min-width: @screen-lg) {
span:not(.meridiem) {
font-size: 220px;
}
}
@media screen and (min-width: @screen-xl) {
span:not(.meridiem) {
font-size: 260px;
}
}
@media screen and (min-width: @screen-2xl) {
span:not(.meridiem) {
font-size: 320px;
}
}
}
&-entry {
position: absolute;
top: 0;
left: 0;
display: flex;
width: 100%;
height: 100%;
background-color: rgb(0 0 0 / 50%);
backdrop-filter: blur(8px);
justify-content: center;
align-items: center;
&-content {
width: 260px;
}
&__header {
text-align: center;
&-img {
width: 70px;
margin: 0 auto;
border-radius: 50%;
}
&-name {
margin-top: 5px;
font-weight: 500;
color: #bababa;
}
}
&__err-msg {
display: inline-block;
margin-top: 10px;
color: @error-color;
}
&__footer {
display: flex;
justify-content: space-between;
}
}
}
</style>