CMVR-IOT-UI/src/views/inspection/cockpit/components/MapOverview.vue

342 lines
10 KiB
Vue
Raw Normal View History

2026-05-25 09:10:10 +08:00
<template>
<div class="page-container">
<div class="left-container">
<div class="robot-container">
<div class="robot-state">机器人状态</div>
<div class="robot-info" v-for="item, index in 2">
<div class="title-box">
<div><SvgIcon name="bot" :color="index === 0 ? '#00D4FF' : '#FFB300'" /></div>
<div class="title">巡检机器人#{{ index }}</div>
<div class="state" :class="robotState">在线</div>
</div>
<div class="info-box">
<div class="item-box">
<div class="item-title">编号</div>
<div class="item-detail">RB-2024-001</div>
</div>
<div class="item-box">
<div class="item-title">当前任务</div>
<div class="item-detail">厂区A-定时巡检</div>
</div>
<div class="item-box">
<div class="item-title">电量</div>
<div class="item-detail">78%</div>
</div>
<div class="item-box">
<div class="item-title">速度</div>
<div class="item-detail">0.8m/s</div>
</div>
</div>
</div>
</div>
<div class="split-line"></div>
<div class="task-container">
<div class="container-title">当前任务</div>
<div class="task-box" v-for="item, index in 2">
<div class="title">巡检机器人#{{ index }}</div>
<div class="task-info">
<div>执行中</div>
<div>厂区A定时巡检</div>
</div>
</div>
</div>
</div>
<div class="map-container">
<div class="title-container">
<div class="title">
<SvgIcon name="map" color='#00D4FF' />
<span>实时地图 工厂园区</span>
</div>
<div class="map-controller">
<div class="btn-container">
2026-05-29 13:54:45 +08:00
<SvgIcon name="zoom-in" color='#00D4FF' :size="16" @click="zoomCanvas(true)" />
2026-05-25 09:10:10 +08:00
</div>
<div class="btn-container">
2026-05-29 13:54:45 +08:00
<SvgIcon name="zoom-out" color='#00D4FF' :size="16" @click="zoomCanvas(false)" />
2026-05-25 09:10:10 +08:00
</div>
<div class="btn-container">
2026-05-29 13:54:45 +08:00
<SvgIcon name="locate-fixed" color='#00D4FF' :size="16" @click="centerCanvasView" />
2026-05-25 09:10:10 +08:00
</div>
</div>
</div>
<div class="map-box">
2026-05-29 13:54:45 +08:00
<MapCanvas ref="mapCanvasRef" />
2026-05-25 09:10:10 +08:00
</div>
</div>
<div class="right-container">
2026-06-12 17:27:59 +08:00
<!-- <div class="sensor-container">
2026-05-25 09:10:10 +08:00
<div class="sensor-title">传感器数据</div>
2026-06-12 17:27:59 +08:00
</div> -->
<!-- <div class="split-line"></div> -->
2026-05-25 09:10:10 +08:00
<div class="alarm-container">
<div class="container-title">告警记录</div>
<div class="alarm-box" v-for="item, index in 2">
<div class="title">#01 检测到异常噪声</div>
<div class="alarm-info">14:28:33 厂区A 东侧走廊</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import SvgIcon from "@/components/SvgIcon";
import MapCanvas from "./MapCanvas.vue";
import { onMounted, onUnmounted } from "vue";
2026-06-12 17:27:59 +08:00
console.log('sss', import.meta.env.VITE_INSPECTION_TYPE)
2026-05-25 09:10:10 +08:00
const robotState = ref('online')
2026-05-29 13:54:45 +08:00
const mapCanvasRef = ref(null)
2026-05-25 09:10:10 +08:00
2026-05-29 13:54:45 +08:00
const zoomCanvas = (isZoomIn) => {
if (mapCanvasRef.value) {
mapCanvasRef.value.zoomCanvas(isZoomIn);
}
}
const centerCanvasView = () => {
if (mapCanvasRef.value) {
mapCanvasRef.value.centerCanvasView();
}
}
2026-05-25 09:10:10 +08:00
</script>
<style lang="scss">
.page-container {
height: 100%;
width: 100%;
display: flex;
.left-container {
width: 300px;
height: 100%;
padding: 16px;
.robot-container {
max-height: 50%;
overflow-y: auto;
.robot-state {
color: #fff;
font-size: 16px;
font-weight: bold;
margin-bottom: 16px;
}
.robot-info {
width: 268px;
height: 148px;
background: #0F1E38;
border-radius: 10px;
// border: 1px solid #00D4FF;
padding: 16px;
margin-bottom: 16px;
.title-box {
display: flex;
justify-content: space-between;
margin-bottom: 12px;
.title {
color: #fff;
font-size: 14px;
font-family: Inter;
font-weight: bold;
}
.state {
font-size: 12px;
border-radius: 12px;
padding: 0 8px;
display: flex;
align-items: center;
justify-content: center;
}
.online {
background: #0f83;
color: #0f8;
}
}
.info-box {
.item-box {
display: flex;
justify-content: space-between;
margin: 6px 0;
.item-title {
color: #89B;
font-size: 12px;
}
.item-detail {
color: #e0e8f0;
font-size: 12px;
}
}
}
}
.robot-info.last-child {
margin-bottom: 0;
}
}
.split-line {
width: 100%;
height: 1px;
margin: 16px 0;
background: #1E3A5F;
}
.task-container {
max-height: 50%;
overflow-y: auto;
.container-title {
color: #fff;
font-size: 16px;
font-weight: bold;
margin-bottom: 16px;
}
.task-box {
height: 72px;
background: #0F1E38;
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
.title {
color: #fff;
text-align: center;
font-size: 14px;
font-family: Inter;
font-weight: bold;
}
.task-info {
display: flex;
justify-content: space-between;
align-items: center;
margin: 10px 0;
font-size: 12px;
color: #E0E8F0;
}
}
}
}
.map-container {
flex: 1;
border: 1px solid #1E3A5F;
border-top: 0;
.title-container {
height: 52px;
padding: 0 16px;
display: flex;
align-items: center;
justify-content: space-between;
.title {
color: #fff;
font-size: 16px;
font-weight: bold;
display: flex;
align-items: center;
gap: 12px;
}
.map-controller {
display: flex;
align-items: center;
gap: 12px;
.btn-container {
width: 32px;
height: 32px;
border-radius: 8px;
background: #1E3A5F;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid transparent;
&:hover {
border-color: #00D4FF;
cursor: pointer;
}
}
}
}
.map-box {
height: calc(100% - 52px);
}
}
.right-container {
width: 280px;
height: 100%;
padding: 16px;
.sensor-container {
max-height: 50%;
height: 45%;
overflow-y: auto;
.sensor-title {
color: #fff;
font-size: 16px;
font-weight: bold;
margin-bottom: 16px;
}
}
.split-line {
width: 100%;
height: 1px;
margin: 16px 0;
background: #1E3A5F;
}
.alarm-container {
max-height: 50%;
overflow-y: auto;
.container-title {
color: #fff;
font-size: 16px;
font-weight: bold;
margin-bottom: 16px;
}
.alarm-box {
height: 72px;
background: #0F1E38;
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
.title {
color: #FF6B6B;
font-size: 14px;
font-family: Inter;
font-weight: bold;
}
.alarm-info {
margin: 10px 0;
font-size: 12px;
color: #8899BB;
}
}
}
}
}
</style>