代码提交

This commit is contained in:
luoshiwen 2024-07-10 11:09:08 +08:00
parent 2a297a38cd
commit 0d4dafddc3
52 changed files with 679 additions and 60 deletions

View File

@ -1,5 +1,5 @@
<script setup>
import Three from './components/Three.vue'
</script>
@ -7,16 +7,31 @@ import Three from './components/Three.vue'
<!-- <div id="three3D">
<Three />
</div> -->
<!-- 头部-->
<div class="header">
<div class="header-font">xxx部队厂房一张图</div>
</div>
<router-view></router-view>
</template>
<style scoped>
#three3D {
<style scoped lang="scss">
@import "./assets/font/font.css";
.header {
width: 100%;
height: 100%;
position: fixed;
height: vh(108);
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: 99;
font-family: pangmen;
text-shadow: 0px 0px 10px #34D1FF, 0px 3px 0px #24649A;
background-size: 100% 100%;
text-align: center;
background-image: url('@/assets/images/header.png');
&-font{
font-size: 2.75rem;
margin-top: 1rem;
}
}
</style>

6
src/assets/font/font.css Normal file
View File

@ -0,0 +1,6 @@
@font-face {
font-family:'pangmen';
src: url('pangmen.ttf'); /* 修改为你的字体文件路径 */
font-weight: normal;
font-style: normal;
}

BIN
src/assets/font/pangmen.ttf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

BIN
src/assets/images/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -4,7 +4,12 @@ import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
{
path:'/',
redirect:'/home',
redirect:'/login',
},
{
path:'/login',
name:'login',
component: () => import('@/views/login')
},
{
path:'/home',

View File

@ -11,3 +11,10 @@
padding: 0;
list-style: none;
}
#three3D {
width: 100%;
height: 100%;
position: fixed;
top: 0;
right: 0;
}

20
src/utils/getPath.js Normal file
View File

@ -0,0 +1,20 @@
// 将所有图片导入进来
const req1 = import.meta.glob("../assets/images/**", {eager: true});
const req = {...req1};
const imagesMap = {};
// 循环所有图片,将图片名设置成键,值为导入该图片的地址
for (const key in req) {
// let name = key.replace(/(\.\/images\/|\..*)/g, '')
let name = key.split("/").slice(-1)[0].split(".")[0].replace(/-/g, "");
// 抛出图片大对象后,文件页面直接引入后将图片的具体名称作为属性就能导入该图片
imagesMap[name] = req[key].default;
}
export default imagesMap

View File

@ -1,9 +1,17 @@
<template>
<!-- 头部-->
<div class="header">
<!-- 侧边栏显隐-->
<div class="aside">
<ul class="aside-ul">
<li class="aside-li" v-for="(item,index) in asideList" @click="toggleDevice(index)">
<img :src="deviceIndex===index?item.select:item.default" alt="" srcset="">
<img class="aside-li-msg" v-if="deviceIndex===index" :src="item.rightImg" alt="" srcset="">
</li>
</ul>
</div>
<div id="three3D">
<Three />
</div>
<div class="container">
<div class="container-left">
<div class="container-left-box">
@ -11,24 +19,95 @@
<div class="public-title">
<span class="font">报警列表</span>
<span class="more">
查看更多
</span>
</div>
<div class="alarmList">
<section class="regional">
<section class="regional" v-for="item in alarmList.regional">
<div class="alarmList-type">
区域入侵
</div>
<div class="alarmList-regional">
<div style="width: 2.75rem; height:2.75rem;display: flex;align-items: center">
<el-image style="width: 2.75rem; height: 2.75rem" :src="cameraUrl" fit="cover" />
</div>
<div class="alarmList-regional-msg">
<div>
<i class="drop"></i>
<span>位置</span>
<span>{{item.address}}</span>
</div>
<div>
<i class="drop"></i>
<span>时间</span>
<span>{{item.date}}</span>
</div>
</div>
</div>
</section>
<section>
<section class="humidity" v-for="item in alarmList.humidity">
<div class="alarmList-type">
温湿度告警
</div>
<div class="alarmList-content">
<div>
<i class="drop"></i>
<span>当前温度</span>
<span>{{item.humidity}}</span>
</div>
<div>
<i class="drop"></i>
<span>报警温度</span>
<span>{{item.alarmHumidity}}</span>
</div>
<div>
<i class="drop"></i>
<span>位置</span>
<span>{{item.address}}</span>
</div>
<div>
<i class="drop"></i>
<span>时间</span>
<span>{{item.date}}</span>
</div>
</div>
</section>
<section>
<section class="urgent" v-for="item in alarmList.urgent">
<div class="alarmList-type">
紧急告警
</div>
<div class="alarmList-content">
<div>
<i class="drop"></i>
<span>当前温度</span>
<span>{{item.humidity}}</span>
</div>
<div>
<i class="drop"></i>
<span>报警温度</span>
<span>{{item.alarmHumidity}}</span>
</div>
<div>
<i class="drop"></i>
<span>位置</span>
<span>{{item.address}}</span>
</div>
<div>
<i class="drop"></i>
<span>时间</span>
<span>{{item.date}}</span>
</div>
</div>
</section>
</div>
<div class="public-title">
<span class="font">钥匙柜状态总览</span>
<span class="more">
取还记录
<span class="record-icon">
</span>
</div>
<!-- 钥匙柜数据 -->
@ -39,10 +118,43 @@
<span>{{item}}</span>
</li>
</ul>
<section v-for="(item,index) in keywordList" class="keyword-item" :class="'keyword-item'+index">
<section v-for="(item,index) in keywordList" class="keyword-item" :class="'keyword-item-state'+item.keyState">
<span>{{item.keyCapturing}}号锁位</span>
<span class="position">{{item.position}}</span>
</section>
</div>
<!-- 门禁进入实况-->
<div class="access-title">
<span>门禁进入实况</span>
</div>
<div class="access-control">
<el-collapse v-model="activeNames">
<el-collapse-item :title="item.doorName" :name="item.doorName" v-for="item in doorNames">
<el-timeline>
<el-timeline-item v-for="(activity, index) in item.data" :key="index">
<p style="display: flex;justify-content: space-between">
<span v-if="activity.inAndOutType"
style="margin-left: 0.5rem">
{{ activity.personName
}}
<span style="margin-left: 0.5rem;color: rgba(233, 244, 255, 0.60)">{{
activity.inAndOutType == -1
? "出库房"
: activity.inAndOutType == 1
? "进入库房"
: "未知"
}}</span>
</span>
<span style="color: rgba(0, 221, 255, 1);font-size: .75rem">{{ activity.eventTime }}</span>
</p>
<!-- <div class="enterImg">-->
<!-- <img :src="'https://192.168.3.3:443' + activity.picUri" alt="" />-->
<!-- </div>-->
</el-timeline-item>
</el-timeline>
</el-collapse-item>
</el-collapse>
</div>
</div>
</div>
<div class="container-right">
@ -51,7 +163,7 @@
<div class="public-title">
<span class="font">排班表</span>
<span class="more">
查看更多
</span>
</div>
<div class="schedule-date">
@ -98,12 +210,64 @@
</div>
<!-- 底部-->
<div class="footer">
<ul class="footer-ul">
<li class="footer-ul-li" v-for="(item,index) in footerList">
<img :src="item.default" alt="">
</li>
</ul>
</div>
</template>
<script setup>
import getPath from "@/utils/getPath.js";
import Three from '@/components/Three.vue'
import {ref} from 'vue'
import cameraUrl from '@/assets/images/camera.png'
//
const asideList = ref([
{
default:getPath.store,
select:getPath.storeSelect,
rightImg:getPath.storePrompt,
},
{
default:getPath.monitorPoint,
select:getPath.monitorPointSelect,
rightImg:getPath.monitorPointPrompt,
},
{
default:getPath.alarmHost,
select:getPath.alarmHostSelect,
rightImg:getPath.alarmHostPrompt,
},
{
default:getPath.water,
select:getPath.waterSelect,
rightImg:getPath.waterPrompt,
},
{
default:getPath.smoke,
select:getPath.smokeSelect,
rightImg:getPath.smokePrompt,
},
{
default:getPath.humidity,
select:getPath.humiditySelect,
rightImg:getPath.humidityPrompt,
},
{
default:getPath.accessControl,
select:getPath.accessControlSelect,
rightImg:getPath.accessControlPrompt,
},
])
//
const footerList = ref([
{default:getPath.home,select:getPath.homeSelect},
{default:getPath.record,select:getPath.recordSelect},
{default:getPath.guns,select:getPath.gunsSelect},
{default:getPath.monitor,select:getPath.monitorSelect},
{default:getPath.operation,select:getPath.operationSelect}
])
//
const alarmList = ref({
regional:[
@ -135,56 +299,72 @@ const keywordState = ref(['在位','不在位'])
const keywordList = ref([
{
keyCapturing: "1",
keyState: "在位",
keyState: "1",
},
{
keyCapturing: "2",
keyState: "在位",
keyState: "1",
},
{
keyCapturing: "3",
keyState: "在位",
keyState: "1",
},
{
keyCapturing: "4",
keyState: "在位",
keyState: "1",
},
{
keyCapturing: "5",
keyState: "不在位",
keyState: "0",
position: "李柳柳取走",
},
{
keyCapturing: "6",
keyState: "不在位",
keyState: "0",
position: "李柳柳取走",
},
{
keyCapturing: "7",
keyState: "不在位",
keyState: "0",
position: "李柳柳取走",
},
{
keyCapturing: "8",
keyState: "在位",
keyState: "1",
},
{
keyCapturing: "9",
keyState: "在位",
keyState: "1",
},
{
keyCapturing: "10",
keyState: "在位",
keyState: "1",
},
{
keyCapturing: "11",
keyState: "在位",
keyState: "1",
},
{
keyCapturing: "12",
keyState: "在位",
keyState: "1",
},
]);
//
const activeNames = ref([])
const doorNames = ref([
{
doorName:'1号仓库',
data:[
{personName:'张集网',eventTime:'12:27',inAndOutType:-1},{personName:'张集网',eventTime:'12:27',inAndOutType:-1},{personName:'张集网',eventTime:'12:27',inAndOutType:-1}
]
},
{
doorName:'2号仓库',
data:[
{personName:'张集网',eventTime:'12:27',inAndOutType:-1},{personName:'张集网',eventTime:'12:27',inAndOutType:-1}
]
}
])
//
const schedule = ref({
date:'2022-07-08',
@ -311,48 +491,85 @@ function getRowColor({ row }) {
// return "state3";
// }
}
const deviceIndex = ref(0)
// three
function toggleDevice(index){
deviceIndex.value = index
}
</script>
<style lang="scss" scoped>
.header {
width: 100%;
height: vh(108);
position: absolute;
top: 0;
left: 0;
background-size: 100% 100%;
background-image: url('@/assets/images/header.png');
.aside{
//height: vh(380);
width: vw(44);
position: fixed;
bottom: 81px;
left:vh(270);
z-index:99;
&-li{
width: 100%;
position: relative;
margin-bottom: .6rem;
&-msg{
position: absolute;
left: 107%;
top: 7%;
}
}
}
//
.drop{
margin-right: 0.5rem;
width: 0.8rem;
display: inline-block;
height: 0.8rem;
background-image: url('@/assets/images/drop.png');
}
.container {
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
&-left, &-right {
padding-top: vw(104);
width: vw(380);
height: 100%;
position: relative;
&-box {
width: 100%;
height: 100%;
}
}
//
.public-title{
.public-title,.access-title{
height:vh(40);
width: 100%;
width: 108%;
position: relative;
right: 4%;
display: flex;
justify-content: space-between;
padding-left: 3.5rem;
padding-right: 1rem;
align-items: center;
box-sizing: border-box;
background-image: url('@/assets/images/title-box.png');
span:nth-child(1){
//font-size: 1.625rem;
font-family: pangmen;
font-size: 1.625rem;
}
.more,.record-icon{
background-image: url('@/assets/images/checkMore.png');
background-size: 100% 100%;
width: 4.25rem;
height: 1.5rem;
}
.record-icon{
background-image: url('@/assets/images/record-icon.png');
}
}
.access-title{
margin-top: 0.5rem;
background-image: url('@/assets/images/door-title.png');
}
&-left {
background-image: url('@/assets/images/left-mask.png');
@ -361,15 +578,56 @@ function getRowColor({ row }) {
//
.alarmList{
width: 100%;
height: vh(318);
height: vh(364);
margin-bottom: 1rem;
display: flex;
flex-wrap: wrap;
align-content: space-evenly;
&-type{
margin-top: .75rem;
margin-left: 1.3rem;
color: rgba(255, 255, 255, 1);
}
//湿
&-content{
display: flex;
flex-wrap: wrap;
padding-left: .7rem;
align-items: center;
box-sizing: border-box;
align-content: space-evenly;
font-size: 0.875rem;
height: 70%;
color:rgba(189, 220, 248, 1);
}
&-content>div:nth-child(2n-1){
width: 40%;
}
&-content>div>span:nth-of-type(1){
color: rgba(88, 174, 247, 1);
}
section{
width: 100%;
height: 30%;
background-image: url('@/assets/images/alarm-item.png');
}
//
&-regional{
align-items: center;
display: flex;
font-size: 0.875rem;
color:rgba(189, 220, 248, 1);
padding-left: .7rem;
height: 70%;
&-msg{
height: 100%;
margin-left: .75rem;
display: flex;
flex-wrap: wrap;
align-content: space-evenly;
}
}
}
//
.keyword{
@ -417,12 +675,38 @@ function getRowColor({ row }) {
background-image: url('@/assets/images/has-bg.png');
background-size: 100% 100%;
margin-right: .45rem;
position: relative;
.position{
top: 0;
position: absolute;
left: 50%;
white-space: nowrap;
font-size: .625rem;
transform: translate(-50%);
}
&-state1{
background-image: url('@/assets/images/has-bg.png');
color: rgba(0, 237, 197, 1);
}
&-state0{
color: rgba(255, 255, 255, 1);
background-image: url('@/assets/images/noHas-bg.png');
}
}
&-item:nth-of-type(4n){
margin-right: 0;
}
}
//
.access-control{
margin-top: 1rem;
height: vh(175);
overflow-y: scroll;
}
.access-control::-webkit-scrollbar{
display: none;
}
}
&-right {
@ -431,13 +715,6 @@ function getRowColor({ row }) {
background-size: 100% 100%;
.schedule-date{
.drop{
margin-right: 0.5rem;
width: 0.8rem;
display: inline-block;
height: 0.8rem;
background-image: url('@/assets/images/drop.png');
}
display: flex;
flex-wrap: wrap;
align-content: space-between;
@ -446,7 +723,7 @@ function getRowColor({ row }) {
background-image: url('@/assets/images/schedule-date.png');
width: 100%;
height: vh(80);
margin:.5rem 0;
margin:1rem 0;
}
.schedule-person{
&-item{
@ -465,17 +742,35 @@ function getRowColor({ row }) {
}
.footer {
width: 100%;
height: vh(26);
position: absolute;
bottom: 0;
background-image: url('@/assets/images/bottom.png');
justify-content: center;
&-ul{
width: vw(800);
display: flex;
position: absolute;
top: -100%;
left: 50%;
transform: translate(-50%);
&-li{
margin-left: -1.25rem;
cursor: pointer;
}
&-li:nth-child(1){
margin-left: 0;
}
}
}
//线
.patrol-line{
height: vh(540);
width: 100%;
margin-top: 1.1rem;
margin-top: 1rem;
.qiu-icon {
display: inline-block;
width: 0.5rem;
@ -539,4 +834,72 @@ function getRowColor({ row }) {
:deep(.el-table td.el-table__cell) {
border-color: transparent;
}
//
:deep(.el-collapse-item__header){
height: 1.75rem;
padding-left: 0.625rem;
font-size: 1rem;
box-sizing: border-box;
border: none;
background-color: transparent;
color: rgba(233, 244, 255, 1);
background-image: url('@/assets/images/door-device.png');
}
:deep(.el-collapse-item__content){
background-color: transparent;
border: none !important;
font-size: 1rem;
padding-bottom: 0;
}
:deep(.el-collapse-item__wrap){
background-color: transparent;
border: none;
}
:deep(.el-collapse){
border: none;
//border-color: unset;
}
:deep(.el-timeline-item__wrapper) {
padding-left: 0.8rem;
}
:deep(.el-timeline) {
padding-left: 0.3rem;
box-sizing: border-box;
padding-top: 0.5rem;
}
:deep(.el-timeline-item) {
padding-bottom: 0.4rem;
}
:deep(.el-timeline-item__content) {
color:rgba(233, 244, 255, 1);
font-size: 0.875rem;
padding:0 1rem;
//background-image: url('@/assets/images/timeline.png');
//background-size: 100% 100%;
box-sizing: border-box;
}
:deep(.el-timeline-item__node--normal) {
width: 0.75rem;
height: 0.75rem;
left: 1px;
top: .3rem;
background-color: transparent;
background-image: url('@/assets/images/round-icon.png');
}
:deep(.el-timeline-item__tail) {
//border-color: #0a6594;
border:1px dashed #fff;
height: 59%;
top: 1.1rem;
left: 6px;
}
</style>

203
src/views/login.vue Normal file
View File

@ -0,0 +1,203 @@
<script setup>
import { ElMessage } from 'element-plus'
import {ref,reactive,onMounted} from 'vue'
import {useRouter} from "vue-router";
const ruleForm = reactive({
user:'',
password:''
})
const router = useRouter()
const rules = reactive({
//
user: [{ required: true, message: "请输入用户名", trigger: "blur" }],
password: [{ required: true, message: "请输入密码", trigger: "blur" }],
});
const ruleFormRef = ref()
const passwordCheck = ref(false)
function submitForm(elForm){
if(!elForm) return
elForm.validate((valid)=>{
if(valid){
if(passwordCheck.value){
localStorage.setItem('loginInfo',JSON.stringify(ruleForm))
}else{
localStorage.setItem('loginInfo',JSON.stringify({}))
}
ElMessage({
message:'登录成功',
type:"success"
})
router.push('/home')
}else{
ElMessage({
message:'登录失败',
type:"error"
})
}
})
}
//
function checkSavePassword(){
let loginInfo = localStorage.getItem('loginInfo')
console.log(loginInfo,'xxxxxxxxxxxx')
if(loginInfo!==null&&Object.keys(loginInfo).length > 2){
console.log(loginInfo)
ruleForm.user = JSON.parse(loginInfo).user
ruleForm.password = JSON.parse(loginInfo).password
passwordCheck.value = true
}else{
passwordCheck.value = false
}
}
onMounted(()=>{
//
checkSavePassword()
})
</script>
<template>
<div class="login-bg">
<div class="login-form">
<div class="login-form-title">
欢迎登录
</div>
<el-form
ref="ruleFormRef"
:model="ruleForm"
status-icon
class="demo-ruleForm"
:rules="rules"
>
<el-form-item prop="user">
<el-input v-model="ruleForm.user" type="text" placeholder="请输入用户名" >
<!-- <template #prepend>-->
<!-- <div class="user-icon">-->
<!-- </div>-->
<!-- </template>-->
<template #prefix>
<i class="user-icon"></i>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="ruleForm.password"
type="password"
placeholder="请输入密码"
>
<!-- <template #prepend>-->
<!-- <div class="password-icon">-->
<!-- </div>-->
<!-- </template>-->
<template #prefix>
<i class="password-icon"></i>
</template>
</el-input>
</el-form-item>
<el-form-item>
<div>
<el-checkbox v-model="passwordCheck" label="保存密码" />
</div>
<div class="submit" @click="submitForm(ruleFormRef)">
</div>
</el-form-item>
</el-form>
</div>
</div>
</template>
<style scoped lang="scss">
//
.submit{
cursor: pointer;
background-image: url('@/assets/images/submit.png');
width: 100%;
height: 100%;
background-size: 100% 100%;
}
.login-bg{
width: 100%;
height: 100%;
background-image: url('@/assets/images/login-bg.png');
background-size: 100% 100%;
}
.user-icon,.password-icon{
width: 100%;
display: block;
height: 100%;
background-size: 100% 100%;
}
:deep(.el-input__prefix){
width: 15%;
height: 100%;
}
.user-icon{
background-image: url('@/assets/images/user.png');
}
.password-icon{
background-image: url('@/assets/images/password.png');
}
:deep(.el-input__prefix-inner){
width: 100%;
height: 100%;
}
:deep(.el-input__wrapper){
background-color: transparent;
padding-left: 1px;
box-shadow: 0 0 0 0px var(--el-input-border-color,var(--el-border-color)) inset;
cursor: default;
}
.el-input__inner{
cursor: default !important;
}
:deep(.el-input){
width: 100%;
height: 100%;
background-image: url('@/assets/images/el-input.png');
background-size: 100% 100%;
}
:deep(.el-checkbox__label){
color: rgba(233, 244, 255, 1);
}
:deep(.el-form-item) {
height: 13%;
}
:deep(.el-form) {
width: 100%;
height: 100%;
}
.login-form{
width: vw(600);
height: vh(400);
padding: 0 6.25rem;
box-sizing: border-box;
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
margin: auto;
background-image: url('@/assets/images/login-form.png');
background-size: 100% 100%;
&-title{
letter-spacing: 3px;
text-shadow: 0px 0px 7px #129DFF;
font-size: 1.875rem;
font-weight: 400;
font-family: pangmen;
text-align: center;
margin:3.125rem 0 2.25rem 0;
}
}
</style>