| | |
| | | <script setup> |
| | | import {nextTick, onMounted, onUnmounted, ref} from 'vue'; |
| | | import {BaiduMap, BmInfoWindow, BmLabel, BmMarker} from "vue-baidu-map-3x"; |
| | | import {nextTick, onMounted, reactive, ref} from 'vue'; |
| | | import { |
| | | BaiduMap, |
| | | BmInfoWindow |
| | | } from "vue-baidu-map-3x"; |
| | | import {View, IconLayer, TextLayer} from "mapvgl"; |
| | | import mapJson from "@/assets/mapJson/map_config"; |
| | | import {FullScreen} from "@element-plus/icons-vue"; |
| | | import BoxComponent from "@/components/boxComponent.vue"; |
| | |
| | | import getRadiusBarOption from "@/components/echarts/options/radiusBar"; |
| | | import getHorizontalTechnologyOption from "@/components/echarts/options/horizontalTechnologyBar"; |
| | | import carPng from "@/assets/images/car.png"; |
| | | import outlineCarPng from "@/assets/images/outline_car.png"; |
| | | import ChartBox from "@/components/chartBox.vue"; |
| | | const isFullScreen = ref(false); |
| | | const mapStyle = ref({styleJson: mapJson}); |
| | |
| | | } |
| | | |
| | | import carPosModule from "@/views/moudle/carInfo/carPosModule"; |
| | | import CarInfoList from "@/components/carInfoList.vue"; |
| | | |
| | | const { |
| | | carPosInfo, |
| | | getCarPosList |
| | | } = carPosModule(); |
| | | |
| | | const infoWindowClose = (item) => { |
| | | item.show = false; |
| | | const infoWindow = reactive({ |
| | | show: false, |
| | | content: { |
| | | boxName: "", |
| | | boxSn: "", |
| | | lon: 0, |
| | | lat: 0, |
| | | createTime: "", |
| | | updateTime: "", |
| | | online: 0 |
| | | }, |
| | | }); |
| | | |
| | | const mapPosition = { |
| | | lng: 116.404, |
| | | lat: 39.915 |
| | | }; |
| | | const infoWindowOpen = (item) => { |
| | | item.show = true |
| | | }; |
| | | const iconLayer = ref({}); |
| | | const textLayer = ref({}); |
| | | |
| | | const handleMapReady = ({map})=>{ |
| | | let view = new View({ |
| | | map: map |
| | | }); |
| | | |
| | | textLayer.value = new TextLayer({ |
| | | enablePicked: false, |
| | | autoSelect: false, |
| | | selectedColor: '#f00', // 选中项颜色 |
| | | color: '#fff', |
| | | offset: [0, 30], |
| | | lineWidth: 3, // 文字粗细,在设置描边时才有效 |
| | | //textMaxWidth: 500, // 文字最大宽度,超过则换行 |
| | | textMaxHeight: 50, |
| | | textAlign: 'center', // 文字对齐方式,支持'center'、'left' |
| | | lineHeight: 24, |
| | | stroke: { |
| | | color: '#000' |
| | | } |
| | | }); |
| | | |
| | | view.addLayer(textLayer.value); |
| | | |
| | | iconLayer.value = new IconLayer({ |
| | | width: 40, |
| | | height: 29, |
| | | opacity: 0.8, |
| | | icon: carPng, |
| | | selectedIndex: -1, // 选中项 |
| | | enablePicked: true, // 是否可以拾取 |
| | | selectedColor: '#ff0000', // 选中项颜色 |
| | | autoSelect: true, // 根据鼠标位置来自动设置选中项 |
| | | onClick: (e)=>{ |
| | | if(e.dataIndex !== -1) { |
| | | const point = e.dataItem.geometry.coordinates; |
| | | const info = e.dataItem.properties.info; |
| | | infoWindow.show = false; |
| | | nextTick(()=>{ |
| | | infoWindow.show = true; |
| | | infoWindow.content = info; |
| | | mapPosition.lng = point[0]; |
| | | mapPosition.lat = point[1]; |
| | | }); |
| | | } |
| | | }, |
| | | }); |
| | | |
| | | view.addLayer(iconLayer.value); |
| | | searchCarPos(); |
| | | } |
| | | |
| | | const searchCarPos = async ()=>{ |
| | | const res = await getCarPosList(); |
| | | let data = res.map(item=>{ |
| | | return { |
| | | geometry: { |
| | | type: 'Point', |
| | | coordinates: [item.lon, item.lat] |
| | | }, |
| | | properties: { |
| | | icon: item.online === 1?carPng:outlineCarPng, |
| | | text: item.boxName, |
| | | info: item |
| | | } |
| | | } |
| | | }); |
| | | textLayer.value.setData(data); |
| | | iconLayer.value.setData(data); |
| | | } |
| | | |
| | | const infoWinOpen = ()=>{} |
| | | const infoWinClose = ()=>{ |
| | | infoWindow.show = false; |
| | | } |
| | | |
| | | import { |
| | | recentDaysCarModule, |
| | | totalCarNumModule |
| | | } from "@/views/moudle/carInfo/carInfoModule"; |
| | | |
| | | const { |
| | | todayCarNum, |
| | | getRecentDaysCarNum |
| | | } = recentDaysCarModule(); |
| | | |
| | | const boxGaugeOption = getGaugeOption(0, 2000, "当前在线汽车数"); |
| | | const boxBarOption = getRadiusBarOption(); |
| | | const searchRecentDaysCarNum = async ()=>{ |
| | | const data = await getRecentDaysCarNum(7); |
| | | boxBarOption.series[0].name = "在线车辆数:" |
| | | boxBarOption.series[0].data = data.map(item=>{ |
| | | return [new Date(item.date).format("MM-dd"), item.value]; |
| | | }); |
| | | boxBar.value.setOption(boxBarOption); |
| | | boxGauge.value.setOption(getGaugeOption(todayCarNum.value, 2000, "当前在线汽车数")); |
| | | } |
| | | |
| | | const { |
| | | totalCarNum, |
| | | getTotalCarNum |
| | | } = totalCarNumModule(); |
| | | |
| | | |
| | | import { |
| | | recentDaysBattModule, |
| | | totalBattNumModule |
| | | } from "@/views/moudle/battShow/battInfo" |
| | | |
| | | const battBarOption = getRadiusBarOption(); |
| | | const battGaugeOption = getGaugeOption(1, 500, "今日新增电池数"); |
| | | |
| | | const { |
| | | todayBattNum, |
| | | getRecentDaysBattNum |
| | | } = recentDaysBattModule(); |
| | | const searchRecentDaysBattNum = async ()=>{ |
| | | const data = await getRecentDaysBattNum(7); |
| | | battBarOption.series[0].name = "新增电池组数:"; |
| | | battBarOption.series[0].data = data.map(item=>{ |
| | | return [new Date(item.date).format("MM-dd"), item.value]; |
| | | }); |
| | | battBar.value.setOption(battBarOption); |
| | | battGauge.value.setOption(getGaugeOption(todayBattNum.value, 500, "今日新增电池数")); |
| | | } |
| | | |
| | | const { |
| | | totalBattNum, |
| | | getTotalBattNum |
| | | } = totalBattNumModule(); |
| | | |
| | | |
| | | import { |
| | | recentDaysVideoModule, |
| | | totalVideoNumModule |
| | | } from "@/views/moudle/videoInf/videoInf"; |
| | | |
| | | const videoGaugeOption = getGaugeOption(1, 500, "今日新增摄像头数"); |
| | | const videoBarOption = getRadiusBarOption(); |
| | | |
| | | const { |
| | | todayVideoNum, |
| | | getRecentDaysVideoNum |
| | | } = recentDaysVideoModule(); |
| | | const searchRecentDaysVideoNum = async ()=>{ |
| | | const data = await getRecentDaysVideoNum(7); |
| | | videoBarOption.series[0].name = "新增摄像头数:"; |
| | | videoBarOption.series[0].data = data.map(item=>{ |
| | | return [new Date(item.date).format("MM-dd"), item.value]; |
| | | }); |
| | | videoBar.value.setOption(videoBarOption); |
| | | videoGauge.value.setOption(getGaugeOption(todayVideoNum.value, 500, "今日新增摄像头数")); |
| | | } |
| | | |
| | | const { |
| | | totalVideoNum, |
| | | getTotalVideoNum |
| | | } = totalVideoNumModule(); |
| | | |
| | | |
| | | import { |
| | | bmsStaticAlarmModule |
| | | } from "@/views/moudle/bmsInf/bmsInf"; |
| | | |
| | | const { |
| | | getBmsStaticAlarm |
| | | } = bmsStaticAlarmModule(); |
| | | |
| | | let alarmBarOption = getHorizontalTechnologyOption(); |
| | | const searchBmsStaticAlarm = async ()=>{ |
| | | let res = await getBmsStaticAlarm(); |
| | | |
| | | alarmBarOption = getHorizontalTechnologyOption(res.map(item=>{ |
| | | return { |
| | | name: item.bmsAlarmName, |
| | | value: item.num |
| | | } |
| | | })); |
| | | alarmBar.value.setOption(alarmBarOption); |
| | | } |
| | | |
| | | /** |
| | | * 查询车辆,电池,摄像头,告警的图表数据 |
| | | */ |
| | | const searchEchartsData = ()=>{ |
| | | searchRecentDaysCarNum(); |
| | | getTotalCarNum(); |
| | | |
| | | searchRecentDaysVideoNum(); |
| | | getTotalVideoNum(); |
| | | |
| | | searchRecentDaysBattNum(); |
| | | getTotalBattNum(); |
| | | |
| | | searchBmsStaticAlarm(); |
| | | } |
| | | |
| | | onMounted(()=>{ |
| | | getCarPosList(); |
| | | |
| | | const boxGaugeOption = getGaugeOption(10, 90, "今日在线汽车数"); |
| | | boxGauge.value.setOption(boxGaugeOption); |
| | | |
| | | const boxBarOption = getRadiusBarOption(); |
| | | boxBar.value.setOption(boxBarOption); |
| | | |
| | | const videoGaugeOption = getGaugeOption(1, 500, "今日在线摄像头数"); |
| | | videoGauge.value.setOption(videoGaugeOption); |
| | | |
| | | const videoBarOption = getRadiusBarOption(); |
| | | videoBar.value.setOption(videoBarOption); |
| | | |
| | | const battGaugeOption = getGaugeOption(1, 500, "今日在线电池数"); |
| | | battGauge.value.setOption(videoGaugeOption); |
| | | battGauge.value.setOption(battGaugeOption); |
| | | battBar.value.setOption(battBarOption); |
| | | searchEchartsData(); |
| | | |
| | | const battBarOption = getRadiusBarOption(); |
| | | battBar.value.setOption(videoBarOption); |
| | | |
| | | const alarmBarOption = getHorizontalTechnologyOption(); |
| | | alarmBar.value.setOption(alarmBarOption); |
| | | }); |
| | | </script> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="baidu-map-content"> |
| | | <!-- <div class="baidu-map-tools-right" v-if="!isFullScreen">--> |
| | | <!-- <el-button type="primary" @click="changeScreenState" :icon="FullScreen" />--> |
| | | <!-- </div>--> |
| | | <div class="baidu-map-float"> |
| | | <div class="box-container"> |
| | | <div class="box-container-top"> |
| | |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <div class="box-value-wrapper"> |
| | | <div class="text-content">今日在线汽车数:</div> |
| | | <div class="text-value">0</div> |
| | | <div class="text-content">当前在线汽车数:</div> |
| | | <div class="text-value">{{todayCarNum}}</div> |
| | | </div> |
| | | <div class="box-value-wrapper"> |
| | | <div class="text-content">汽车总数:</div> |
| | | <div class="text-value">0</div> |
| | | <div class="text-value">{{totalCarNum}}</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <div class="box-value-wrapper"> |
| | | <div class="text-content">今日在线摄像头数:</div> |
| | | <div class="text-value">0</div> |
| | | <div class="text-content">今日新增摄像头数:</div> |
| | | <div class="text-value">{{todayVideoNum}}</div> |
| | | </div> |
| | | <div class="box-value-wrapper"> |
| | | <div class="text-content">摄像头总数:</div> |
| | | <div class="text-value">0</div> |
| | | <div class="text-value">{{ totalVideoNum }}</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | </el-row> |
| | | </div> |
| | | <div class="content-inner-body"> |
| | | <chart-box title="最近7天在线摄像头数"> |
| | | <chart-box title="最近7天新增摄像头数"> |
| | | <hdw-chart ref="videoBar"></hdw-chart> |
| | | </chart-box> |
| | | </div> |
| | |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <div class="box-value-wrapper"> |
| | | <div class="text-content">今日在电池数:</div> |
| | | <div class="text-value">0</div> |
| | | <div class="text-content">今日新增电池数:</div> |
| | | <div class="text-value">{{todayBattNum}}</div> |
| | | </div> |
| | | <div class="box-value-wrapper"> |
| | | <div class="text-content">电池总数:</div> |
| | | <div class="text-value">0</div> |
| | | <div class="text-value">{{totalBattNum}}</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | </el-row> |
| | | </div> |
| | | <div class="content-inner-body"> |
| | | <chart-box title="最近7天在线电池数"> |
| | | <chart-box title="最近7天新增电池数"> |
| | | <hdw-chart ref="battBar"></hdw-chart> |
| | | </chart-box> |
| | | </div> |
| | |
| | | <baidu-map |
| | | class="map-container" |
| | | ak="4GdR40xNyYI2w2XiIgYgS4TdiS3c197C" |
| | | v="3.0" type="API" |
| | | :center="{lng: 114.3202, lat: 30.59}" :zoom="15" :scroll-wheel-zoom="true" :mapStyle="mapStyle"> |
| | | <bm-marker |
| | | v-for="(item, key) in carPosInfo" :key="'key'+key" |
| | | :position="{lng: item.lon, lat: item.lat}" |
| | | :dragging="false" |
| | | @click="infoWindowOpen(item)" |
| | | :icon="{url: carPng, size: {width: 40, height: 40}}"> |
| | | <!-- <bm-info-window--> |
| | | <!-- :show="item.show"--> |
| | | <!-- :offset="{width: 0, height: -15}"--> |
| | | <!-- @close="infoWindowClose(item)"--> |
| | | <!-- @open="infoWindowOpen(item)">--> |
| | | <!-- <div class="info-list">--> |
| | | <!-- <div class="info-item">--> |
| | | <!-- <div class="info-label">车辆名称:</div>--> |
| | | <!-- <div class="info-value">{{item.boxName}}</div>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="info-item">--> |
| | | <!-- <div class="info-label">车辆识别码:</div>--> |
| | | <!-- <div class="info-value">{{item.boxSn}}</div>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="info-item">--> |
| | | <!-- <div class="info-label">创建日期:</div>--> |
| | | <!-- <div class="info-value">{{new Date(item.createTime).format("yyyy-MM-dd hh:mm:ss")}}</div>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="info-item">--> |
| | | <!-- <div class="info-label">上传日期:</div>--> |
| | | <!-- <div class="info-value">{{new Date(item.uploadTime).format("yyyy-MM-dd hh:mm:ss")}}</div>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="info-item">--> |
| | | <!-- <div class="info-label">更新日期:</div>--> |
| | | <!-- <div class="info-value">{{new Date(item.updateTime).format("yyyy-MM-dd hh:mm:ss")}}</div>--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- </bm-info-window>--> |
| | | <bm-label :content="item.boxName" :offset="{width: -12, height: 30}"></bm-label> |
| | | </bm-marker> |
| | | v="3.0" |
| | | type="WebGL" |
| | | :center="{lng: 114.3202, lat: 30.59}" |
| | | :zoom="5" |
| | | :scroll-wheel-zoom="true" |
| | | :mapStyle="mapStyle" @ready="handleMapReady"> |
| | | <bm-info-window :width="300" :position="mapPosition" title="车辆信息" :show="infoWindow.show" @close="infoWinClose" @open="infoWinOpen"> |
| | | <car-info-list :infos="infoWindow.content"></car-info-list> |
| | | </bm-info-window> |
| | | </baidu-map> |
| | | </div> |
| | | </div> |
| | |
| | | } |
| | | .hdw-chart-box { |
| | | height: 150px; |
| | | } |
| | | .info-list { |
| | | .info-item { |
| | | padding: 4px 0; |
| | | .info-label { |
| | | display: inline-block; |
| | | } |
| | | .info-value { |
| | | display: inline-block; |
| | | } |
| | | } |
| | | } |
| | | </style> |