add:群控电梯系统

This commit is contained in:
zhaohy
2024-08-06 15:44:21 +08:00
parent 243aea92bb
commit 16f3865dbd
14 changed files with 523 additions and 34 deletions

View File

@@ -1,44 +1,143 @@
<template>
<div class="map-box">
<div class="map">
<liftInfo v-for="(item, index) in liftBox" :key="index" :liftInfo="item" />
</div>
<div class="left-box">
<liftInfo
v-for="(item, index) in liftBox"
:key="index"
:liftInfo="item"
@click="clickLift(item)" />
<a-drawer
v-model:visible="visible"
class="left-item"
:width="600"
:forceRender="preload"
placement="right"
:body-style="{
backgroundColor: 'rgba(0, 0, 0, 1)',
overflow: 'hidden',
position: 'relative',
}"
:closable="false"
id="drawer"
:maskStyle="{ 'background-color': 'rgba(0, 0, 0,0.5)' }">
<a-tabs :activeKey="'1'">
<a-tab-pane key="1" tab="日志">
<liftPage ref="leftPage" @clickDrawer="clickDrawer" />
</a-tab-pane>
</a-tabs>
</a-drawer>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import liftInfo from './liftInfo.vue';
import liftPage from './liftPage.vue';
// 请求
// 初始化 ===========================================================
//弹窗
const visible = ref(false);
// 预加载flag获得分区数据后预加载抽屉防止获取ref报错
const preload = ref(false);
//选择的电梯
const selctLeft = ref({});
// table页面 ref
const leftPage = ref(null);
// 初始化 ===========================================================
onMounted(() => {});
// tab页部分 ========================================================
const liftBox = ref([
{
name: '办公区域扶梯A',
name: '1站台西侧扶梯',
workState: 1,
faultState: 2,
direction: 1,
type: 2,
isLeft: true,
styleText: { left: '245px', bottom: '230px' },
styleText: { left: '10%', bottom: '33%' },
},
{
name: '办公区域扶梯B',
name: '2站台西侧扶梯',
workState: 1,
faultState: 2,
direction: 1,
type: 2,
isLeft: true,
styleText: { left: '3%', bottom: '52%' },
},
{
name: '2站台东侧扶梯',
workState: 1,
faultState: 2,
direction: 1,
type: 2,
isLeft: true,
styleText: { left: '48%', bottom: '69%' },
},
{
name: '1站台东侧扶梯',
workState: 1,
faultState: 2,
direction: 1,
type: 2,
isLeft: true,
styleText: { left: '65%', bottom: '62%' },
},
{
name: '办公东区扶梯',
workState: 1,
faultState: 2,
direction: 1,
type: 2,
isLeft: true,
styleText: { left: '78%', bottom: '42%' },
},
{
name: '办公西区扶梯',
workState: 1,
faultState: 2,
direction: 1,
type: 2,
isLeft: true,
styleText: { left: '15%', bottom: '15%' },
},
{
name: '1站台直梯',
workState: 0,
faultState: 3,
direction: 0,
type: 1,
isLeft: false,
styleText: { left: '700px', bottom: '360px' },
styleText: { left: '35%', bottom: '50%' },
},
{
name: '2站台直梯',
workState: 0,
faultState: 3,
direction: 0,
type: 1,
isLeft: false,
styleText: { left: '52%', bottom: '52%' },
},
]);
//点击获取详情
const clickLift = (item: any) => {
visible.value = true;
console.log(item, '获取详细日志');
selctLeft.value = item;
setTimeout(() => {
leftPage.value.toggle(selctLeft.value);
}, 100);
// 开始预加载
preload.value = true;
};
const clickDrawer = () => {
visible.value = false;
};
</script>
<style lang="less" scoped>
.map-box {
.left-box {
// 颜色变量,用于区别颜色
// 正常 - 开启 - 上行 -下行
--on: #0dffa4;
@@ -56,10 +155,24 @@
--size: 40px;
width: 100%;
height: 100%;
.map {
width: 1280px;
height: 720px;
background-image: url(../image/bg.jpg);
}
position: relative;
border-radius: 4px;
background-image: url(../image/bg.jpg);
background-size: 100% 100%;
background-repeat: no-repeat;
overflow: hidden;
}
:deep(.ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn) {
color: white !important;
}
:deep(.ant-tabs-ink-bar) {
background: linear-gradient(180deg, rgba(86, 221, 253, 1) 0%, rgba(25, 176, 255, 1) 100%);
}
:deep(.ant-tabs-tabpane) {
color: white;
padding: 20px 20px 0px 20px;
width: 100%;
height: 950px;
overflow: hidden;
}
</style>

View File

@@ -26,26 +26,73 @@
</div>
</div>
<!-- 是否故障 -->
<!-- 维修故障告警 -->
<div class="item">
<div class="item-box">
<div class="icon">
<div class="icon-item">
<img src="../image/liftState/lift-normal.svg" alt="" />
<img
:src="
{ '0': stateNormal, '1': stateRepair, '2': stateFault, '3': stateAlarm }[3]
"
alt="" />
</div>
</div>
</div>
<div class="item-text">开启</div>
<div
class="item-text"
:style="{
color: {
'0': 'rgba(0, 255, 210, 1)', //正常
'1': 'rgba(255, 188, 70, 1)', //维修
'2': 'rgba(255, 118, 54, 1)', //故障
'3': 'rgba(243, 97, 99, 1)', //告警
}[3],
}"
>{{ { '0': '正常', '1': '维修', '2': '故障', '3': '告警' }[3] }}</div
>
</div>
<!-- 如何运行 -->
<!-- 上行 下行 暂停 急停 未知 -->
<div class="item">
<div class="item-box">
<div class="icon">
<div class="icon-item">
<img src="../image/liftState/lift-normal.svg" alt="" />
<img
:src="
{
'0': liftNormal,
'1': liftNormal,
'2': liftPause,
'3': liftStop,
'4': liftUnknown,
}[2]
"
alt="" />
</div>
</div>
</div>
<div class="item-text">开启</div>
<div
class="item-text"
:style="{
color: {
'0': 'rgba(0, 255, 210, 1)', //上行
'1': 'rgba(0, 255, 210, 1)', //下行
'2': 'rgba(255, 188, 70, 1)', //暂停
'3': 'rgba(243, 97, 99, 1)', //急停
'4': 'rgba(167, 66, 255, 1)', //未知
}[2],
}"
>{{
{
'0': '上行', //上行
'1': '下行', //下行
'2': '暂停', //暂停
'3': '急停', //急停
'4': '未知', //未知
}[2]
}}</div
>
</div>
</div>
</div>
@@ -56,6 +103,15 @@
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
//图片
import stateRepair from '../image/liftState/state-repair.svg'; //维修
import stateFault from '../image/liftState/state-fault.svg'; //故障
import stateAlarm from '../image/liftState/state-alarm.svg'; //告警
import stateNormal from '../image/liftState/state-normal.svg'; //正常
import liftNormal from '../image/liftState/lift-normal.svg'; //上下行
import liftStop from '../image/liftState/lift-stop.svg'; //急停
import liftUnknown from '../image/liftState/lift-unknown.svg'; //未知
import liftPause from '../image/liftState/lift-pause.svg'; //暂停
// 请求
@@ -118,8 +174,8 @@
.info-box {
// 字体颜色变量
--text: rgb(20, 255, 255);
width: 250px;
height: 130px;
width: 224.54px;
height: 110px;
display: flex;
gap: 5px;
flex-direction: column;
@@ -138,8 +194,9 @@
.dot {
display: inline-block;
width: 2px;
height: 16px;
height: 12px;
vertical-align: middle;
margin-top: -4px;
background: var(--text);
}
// 标题
@@ -165,22 +222,22 @@
justify-content: center;
// border: 1px solid red;
.icon {
width: 55px;
height: 55px;
width: 45px;
height: 45px;
background-image: url(../image/box.svg);
background-size: 130% 130%;
background-repeat: no-repeat;
background-position: left -8px top -8px;
background-position: left -6.5px top -3px;
// border: 1px solid red;
position: relative;
.icon-item {
position: absolute;
width: 20px;
height: 20px;
left: 0;
width: 16px;
height: 16px;
left: 1px;
right: 0;
bottom: 0;
top: 0;
top: -1px;
margin: auto;
img {
width: 100%;
@@ -190,6 +247,7 @@
}
}
.item-text {
margin-top: 2px;
height: 20px;
text-align: center;
font-size: 12px;

View File

@@ -0,0 +1,279 @@
<template>
<div style="width: 100%; height: 100%; overflow: hidden">
<div style="width: 100%; height: 50px; display: flex">
<img
v-if="selctLeft.type == 1"
style="width: 42px; height: 42px; margin-left: -6px"
src="../image/liftState/straightLadder.png"
alt="" />
<img
v-else-if="selctLeft.type == 2"
style="width: 42px; height: 42px; margin-left: -6px"
src="../image/liftState/escalator.png"
alt="" />
<div style="margin-left: 6px; font-size: 20px; line-height: 28px">
{{ selctLeft.name }}
</div>
</div>
<!-- 左侧抽屉的关闭按钮 -->
<div class="drawer-box-out" @click="clickDrawer()">
<DoubleRightOutlined class="drawer-icon" style="color: white" />
</div>
<div style="width: 100%; height: calc(100% - 50px); display: flex; position: relative">
<a-table
style="width: 100%"
:columns="column"
:data-source="dataSource"
:pagination="pagination">
<template #bodyCell="{ record, column }">
<template v-if="column.dataIndex === 'switch'">
<a-tag
style="background-color: rgba(0, 0, 0, 0.5); width: 50px"
:style="{
border: {
'0': '1px solid rgba(0, 255, 210, 1)', //2
'1': '1px solid rgba(191, 205, 226, 1)', //关闭
}[record.switch],
color: {
'0': 'rgba(0, 255, 210, 1)', //正常
'1': 'rgba(191, 205, 226, 1)', //关闭
}[record.switch],
}"
>{{ { '0': '开启', '1': '关闭' }[record.switch] }}</a-tag
>
</template>
<template v-if="column.dataIndex === 'state'">
<a-tag
style="background-color: rgba(0, 0, 0, 0.5); width: 50px"
:style="{
border: {
'0': '1px solid rgba(0, 255, 210, 1)', //正常
'1': '1px solid rgba(255, 188, 70, 1)', //维修
'2': '1px solid rgba(255, 118, 54, 1)', //故障
'3': '1px solid rgba(243, 97, 99, 1)', //告警
}[record.state],
color: {
'0': 'rgba(0, 255, 210, 1)', //正常
'1': 'rgba(255, 188, 70, 1)', //维修
'2': 'rgba(255, 118, 54, 1)', //故障
'3': 'rgba(243, 97, 99, 1)', //告警
}[record.state],
}"
>{{ { '0': '正常', '1': '维修', '2': '故障', '3': '告警' }[record.state] }}</a-tag
>
</template>
<template v-if="column.dataIndex === 'lift'">
<a-tag
style="background-color: rgba(0, 0, 0, 0.5); width: 50px"
:style="{
border: {
'0': '1px solid rgba(0, 255, 210, 1)', //上行
'1': '1px solid rgba(0, 255, 210, 1)', //下行
'2': '1px solid rgba(255, 188, 70, 1)', //暂停
'3': '1px solid rgba(243, 97, 99, 1)', //急停
'4': '1px solid rgba(167, 66, 255, 1)', //未知
}[record.lift],
color: {
'0': 'rgba(0, 255, 210, 1)', //上行
'1': 'rgba(0, 255, 210, 1)', //下行
'2': 'rgba(255, 188, 70, 1)', //暂停
'3': 'rgba(243, 97, 99, 1)', //急停
'4': 'rgba(167, 66, 255, 1)', //未知
}[record.lift],
}"
>{{
{
'0': '上行', //上行
'1': '下行', //下行
'2': '暂停', //暂停
'3': '急停', //急停
'4': '未知', //未知
}[record.lift]
}}</a-tag
>
</template>
</template>
</a-table>
</div>
</div>
</template>
<script setup lang="ts">
import { DoubleRightOutlined } from '@ant-design/icons-vue';
import { ref } from 'vue';
const emit = defineEmits(['clickDrawer']);
const selctLeft = ref({});
// 改变页码
const handleChangePage = (current: number, pageSize: number) => {
pagination.value.current = current;
pagination.value.pageSize = pageSize;
};
const dataSource = ref([
{ time: '2022-03-01 10:00:00', state: '0', switch: '0', lift: 1 },
{ time: '2022-03-01 10:00:00', state: '1', switch: 0, lift: 2 },
{ time: '2022-03-01 10:00:00', state: '2', switch: 0, lift: 1 },
{ time: '2022-03-01 10:00:00', state: '3', switch: 0, lift: 0 },
{ time: '2022-03-01 10:00:00', state: '1', switch: 0, lift: 1 },
{ time: '2022-03-01 10:00:00', state: '3', switch: 0, lift: 3 },
{ time: '2022-03-01 10:00:00', state: '2', switch: 0, lift: 1 },
{ time: '2022-03-01 10:00:00', state: '0', switch: 0, lift: 4 },
{ time: '2022-03-01 10:00:00', state: '1', switch: 0, lift: 1 },
{ time: '2022-03-01 10:00:00', state: '3', switch: 0, lift: 1 },
{ time: '2022-03-01 10:00:00', state: '2', switch: 0, lift: 1 },
{ time: '2022-03-01 10:00:00', state: '2', switch: 0, lift: 0 },
{ time: '2022-03-01 10:00:00', state: '1', switch: 0, lift: 1 },
{ time: '2022-03-01 10:00:00', state: '3', switch: 0, lift: 3 },
{ time: '2022-03-01 10:00:00', state: '1', switch: 0, lift: 1 },
{ time: '2022-03-01 10:00:00', state: '0', switch: 0, lift: 4 },
{ time: '2022-03-01 10:00:00', state: '2', switch: 0, lift: 1 },
{ time: '2022-03-01 10:00:00', state: '1', switch: 0, lift: 2 },
{ time: '2022-03-01 10:00:00', state: '2', switch: 0, lift: 1 },
]);
const pagination = ref({
total: dataSource.value.length,
size: 'small',
current: 1,
pageSize: 10,
showQuickJumper: false,
showLessItems: false,
showSizeChanger: false,
responsive: true,
showTotal: (total: number, range: any) => (total && range ? `` : ''), //显示第${range[0]}到${range[1]}条记录,共 ${total} 条记录
onChange: handleChangePage,
});
const column = [
{
title: '执行时间',
dataIndex: 'time',
key: 'time',
width: 140,
},
{
title: '开关',
dataIndex: 'switch',
key: 'switch',
width: 80,
},
{
title: '状态',
dataIndex: 'state',
key: 'state',
width: 80,
},
{
title: '模式',
dataIndex: 'lift',
key: 'lift',
width: 80,
},
];
const toggle = (data: any) => {
pagination.value.current = 1;
selctLeft.value = data;
};
const clickDrawer = () => {
emit('clickDrawer');
};
defineExpose({
toggle,
});
</script>
<style scoped lang="less">
:deep(.ant-table-thead > tr) {
height: 30px !important;
}
:deep(.ant-table-tbody > tr) {
height: 30px !important;
}
:deep(.ant-table-thead > tr > th) {
background-color: #1a2230;
border: 1px solid rgba(163, 192, 243, 0.8);
color: white;
text-align: center;
font-weight: normal !important;
padding: 12px !important;
}
:deep(.ant-table-tbody > tr > td) {
background-color: rgba(0, 0, 0, 0.9) !important;
color: white;
border: 1px solid rgba(163, 192, 243, 0.8);
text-align: center;
padding: 12px !important;
}
:deep(.ant-table-row:hover td) {
background: rgba(0, 0, 0, 0.9) !important;
cursor: pointer;
}
:deep(.ant-tabs-tab-btn) {
font-size: 20px;
font-weight: bold;
color: #fff !important;
}
//分页
:deep(.ant-pagination-item) {
background-color: rgba(0, 0, 0, 1) !important;
border: 1px solid rgba(147, 200, 243, 1) !important;
border-radius: 2px !important;
margin: 0 8px !important;
}
:deep(.ant-pagination-item a) {
color: rgba(12, 140, 246, 1) !important;
}
:deep(.ant-pagination-item-active) {
border-radius: 2px !important;
background: rgba(12, 140, 246, 1) !important;
}
:deep(.ant-pagination-item-active a) {
color: white !important;
}
:deep(.ant-pagination-prev) {
background-color: rgba(0, 0, 0, 1) !important;
border: 1px solid rgba(147, 200, 243, 1) !important;
}
:deep(.ant-pagination-next) {
background-color: rgba(0, 0, 0, 1) !important;
border: 1px solid rgba(147, 200, 243, 1) !important;
}
:deep(.anticon) {
color: rgba(12, 140, 246, 1) !important;
}
:deep(.ant-table-pagination) {
display: flex;
position: absolute;
bottom: 0;
right: 0;
}
:deep(.ant-spin-container) {
height: 100% !important;
}
:deep(.ant-spin-nested-loading) {
height: 100% !important;
}
//分页 在右边 取消
// :deep(.ant-table-pagination-right) {
// justify-content: normal !important;
// }
// 抽屉关闭按钮
.drawer-box-out {
width: 24px;
height: 24px;
border-radius: 2px;
position: absolute;
right: 576px;
z-index: 2;
top: 50%;
margin: auto;
background: #268aff;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
border-radius: 0 8px 8px 0;
color: white;
}
:deep(.anticon) {
color: #fff !important;
}
</style>