代码提交
27
src/App.vue
|
@ -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>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
@font-face {
|
||||
font-family:'pangmen';
|
||||
src: url('pangmen.ttf'); /* 修改为你的字体文件路径 */
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 548 B |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 1.0 MiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 396 B |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 339 B |
After Width: | Height: | Size: 1.3 KiB |
|
@ -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',
|
||||
|
|
|
@ -11,3 +11,10 @@
|
|||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
#three3D {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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>
|
|
@ -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>
|