Files
DjangoAdmin_Flask_EleVue/ui/src/components/Lockscreen/Lockscreen.vue
T
DjangoAdmin DevandClaude 15f2a5e097 chore: 基线提交(重构前代码快照)
- git 初始化 + .gitignore 补全(根 .env / logs / instance / __pycache__ 等)
- 修复 utils/.gitignore 误将整个 utils/ 源码层忽略的问题,补入全部工具源码(含 ip2region.xdb)
- 含后端全部代码:application / extensions / utils / config / migrations
- 含前端 ui/(后续整体迁走)
- 不含根 .env(含密钥,本地保留)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-07 12:12:06 +08:00

273 lines
6.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div
:class="{ onLockLogin: showLogin }"
class="lockscreen"
@keyup="onLockLogin(true)"
@mousedown.stop
@contextmenu.prevent
>
<template v-if="!showLogin">
<div class="lock-box">
<div class="lock">
<span class="lock-icon" title="解锁屏幕" @click="onLockLogin(true)">
<el-icon class="el-input__icon">
<lock-outlined />
</el-icon>
</span>
</div>
</div>
<!--充电-->
<recharge
:battery="battery"
:battery-status="batteryStatus"
:calc-discharging-time="calcDischargingTime"
:calc-charging-time="calcChargingTime"
/>
<div class="local-time">
<div class="time">{{ hour }}:{{ minute }}</div>
<div class="date">{{ month }}月{{ day }}号,星期{{ week }}</div>
</div>
<div class="computer-status">
<span :class="{ offline: !online }" class="network">
<wifi-outlined class="network" />
</span>
<api-outlined />
</div>
</template>
<!--登录-->
<template v-if="showLogin">
<div class="login-box">
<el-avatar :size="128">
<el-icon class="el-input__icon" :size="50">
<user-outlined />
</el-icon>
</el-avatar>
<div class="username">{{ loginParams.username }}</div>
<el-input
type="password"
autofocus
show-password
v-model="loginParams.password"
@keyup.enter="onLogin"
placeholder="请输入登录密码"
>
<template #suffix>
<el-icon class="el-input__icon" @click="onLogin" style="cursor: pointer">
<LoadingOutlined v-if="loginLoading" />
<arrow-right-outlined v-else />
</el-icon>
</template>
</el-input>
<div class="flex w-full" v-if="isLoginError">
<span class="text-red-500">{{ errorMsg }}</span>
</div>
<div class="flex justify-around w-full mt-1">
<div><a @click="showLogin = false">返回</a></div>
<div><a @click="goLogin">重新登录</a></div>
<div><a @click="onLogin">进入系统</a></div>
</div>
</div>
</template>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { ResultEnum } from '@/enums/httpEnum';
import { Recharge } from './index';
import {
LockOutlined,
LoadingOutlined,
UserOutlined,
ApiOutlined,
ArrowRightOutlined,
WifiOutlined,
} from '@vicons/antd';
import { useRouter, useRoute } from 'vue-router';
import { useOnline } from '@/hooks/useOnline';
import { useTime } from '@/hooks/useTime';
import { useBattery } from '@/hooks/useBattery';
import { useLockscreenStore } from '@/store/modules/lockscreen';
import { useUserStore } from '@/store/modules/user';
const useLockscreen = useLockscreenStore();
const userStore = useUserStore();
// 获取时间
const { month, day, hour, minute, week } = useTime();
const { online } = useOnline();
const router = useRouter();
const route = useRoute();
const { battery, batteryStatus, calcDischargingTime, calcChargingTime } = useBattery();
const userInfo: object = userStore.getUserInfo || {};
const username = userInfo['username'] || '';
const showLogin = ref(false);
const loginLoading = ref(false);
const isLoginError = ref(false);
const errorMsg = ref('密码错误');
const loginParams = ref({
username: username || '',
password: '',
});
// 解锁登录
const onLockLogin = (value: boolean) => (showLogin.value = value);
// 登录
const onLogin = async () => {
if (!loginParams.value.password.trim()) {
return;
}
const params = {
isLock: true,
...loginParams.value,
};
loginLoading.value = true;
const { code, message } = await userStore.login(params);
if (code === ResultEnum.SUCCESS) {
onLockLogin(false);
useLockscreen.setLock(false);
} else {
errorMsg.value = message;
isLoginError.value = true;
}
loginLoading.value = false;
};
//重新登录
const goLogin = () => {
onLockLogin(false);
useLockscreen.setLock(false);
router.replace({
path: '/login',
query: {
redirect: route.fullPath,
},
});
};
</script>
<style lang="scss" scoped>
.lockscreen {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
background: #000;
color: white;
overflow: hidden;
z-index: 9999;
&.onLockLogin {
background-color: rgba(25, 28, 34, 0.88);
backdrop-filter: blur(7px);
}
.login-box {
position: absolute;
top: 45%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
> * {
margin-bottom: 14px;
}
.username {
font-size: 30px;
}
}
.lock-box {
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
font-size: 34px;
z-index: 100;
.tips {
color: white;
cursor: text;
}
.lock {
display: flex;
justify-content: center;
.lock-icon {
cursor: pointer;
.anticon-unlock {
display: none;
}
&:hover .anticon-unlock {
display: initial;
}
&:hover .anticon-lock {
display: none;
}
}
}
}
.local-time {
position: absolute;
bottom: 60px;
left: 60px;
font-family: helvetica;
.time {
font-size: 70px;
}
.date {
font-size: 40px;
}
}
.computer-status {
position: absolute;
bottom: 60px;
right: 60px;
font-size: 24px;
> * {
margin-left: 14px;
}
.network {
position: relative;
&.offline::before {
content: '';
position: absolute;
left: 50%;
top: 50%;
width: 2px;
height: 28px;
transform: translate(-50%, -50%) rotate(45deg);
background-color: red;
z-index: 10;
}
}
}
}
</style>