|
|
@@ -0,0 +1,356 @@
|
|
|
+<template>
|
|
|
+ <div class="battle-warp">
|
|
|
+ <div class="map-card-wrap map">
|
|
|
+ <div class="map-card-wrap__info map">
|
|
|
+ <div class="item-header" style="padding: 3px 15px;border-color: #dddddd;">
|
|
|
+ <div class="text-bold">{{ queryTruckInfo.carNumber }}<span class="text-normal">({{ queryTruckInfo.linked === 1 ? '其他' : '自营' }})</span></div>
|
|
|
+ <div><span class="color-blue">{{ truckInfo.uploadTime || '-' }}</span></div>
|
|
|
+ </div>
|
|
|
+ <div class="label item-info__user" style="padding-left: 0;margin: 10px 15px;padding-bottom: 10px;border-bottom: 1px solid #f3f4f5;display: flex;justify-content: space-between;align-items: center;" v-if="truckInfo.hasOwnProperty('truckDriverList') && truckInfo.truckDriverList.length > 0">
|
|
|
+ <div class="driver-wrap" style="width: 85%;">
|
|
|
+ <div v-for="(driver, driverIndex) in truckInfo.truckDriverList" :key="driverIndex" class="driver-list">{{ driver.driverName }}</div>
|
|
|
+ </div>
|
|
|
+ <div><van-icon :name="showStatus ? 'arrow-down' : 'arrow-up'" @click="showStatus = !showStatus" /></div>
|
|
|
+ </div>
|
|
|
+ <van-row v-if="showStatus" class="map-card-wrap__info-box" :gutter="3" type="flex" justify="space-around">
|
|
|
+ <van-col :span="6" class="item" v-for="(item, index) of cardList" :key="index">
|
|
|
+ <div class="name">{{ item.name }}</div>
|
|
|
+ <div class="value">{{ item.value }} <span class="unit">{{ item.unit }}</span></div>
|
|
|
+ </van-col>
|
|
|
+ </van-row>
|
|
|
+ <template v-else>
|
|
|
+ <div class="list-wrap__item truck">
|
|
|
+ <div class="map-card-wrap__info-box">
|
|
|
+ <div class="item">
|
|
|
+ <div class="name">今日里程</div>
|
|
|
+ <div class="value">{{ truckInfo.mileage.toFixed(0) }} <span class="unit">公里</span></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="item-info">
|
|
|
+ <div class="label speed">
|
|
|
+ <span>{{ truckInfo.speed || '-' }}</span>公里/小时
|
|
|
+ <span class="status" :class="'status__' + truckInfo.speedStatus">{{ truckStatusList[truckInfo.speedStatus] }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="label local">{{ truckInfo.currAddress || '-' }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="list-wrap__item truck">
|
|
|
+ <div class="map-card-wrap__info-box">
|
|
|
+ <div class="item">
|
|
|
+ <div class="name">今日耗能</div>
|
|
|
+ <div class="value">{{ truckInfo.consumption }} <span class="unit">公斤</span></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="volume">剩余气量:{{ truckInfo.filterPercent > 0 ? `${truckInfo.filterPercent}%` : '无' }}</div>
|
|
|
+ <div class="map-card-wrap__info-box">
|
|
|
+ <div class="item">
|
|
|
+ <div class="name">今日减碳</div>
|
|
|
+ <div class="value">{{ truckInfo.carbon }} <span class="unit">公斤</span></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="footer-trail-wrap">
|
|
|
+ <div>回放时段</div>
|
|
|
+ <div class="back-time-list">
|
|
|
+ <van-tag :color="timeStatus === 9 ? '#2979ff' : '#ffffff'" :text-color="timeStatus === 9 ? '#ffffff' : '#868b9a'" size="large" @click="timeEvent(9)">自定义</van-tag>
|
|
|
+ <van-tag :color="timeStatus === 1 ? '#2979ff' : '#ffffff'" :text-color="timeStatus === 1 ? '#ffffff' : '#868b9a'" size="large" @click="timeEvent(1)">近1天</van-tag>
|
|
|
+ <van-tag :color="timeStatus === 2 ? '#2979ff' : '#ffffff'" :text-color="timeStatus === 2 ? '#ffffff' : '#868b9a'" size="large" @click="timeEvent(2)">近3天</van-tag>
|
|
|
+ <van-tag :color="timeStatus === 3 ? '#2979ff' : '#ffffff'" :text-color="timeStatus === 3 ? '#ffffff' : '#868b9a'" size="large" @click="timeEvent(3)">近7天</van-tag>
|
|
|
+ </div>
|
|
|
+ <div class="back-info-wrap">
|
|
|
+ <div class="data-info">
|
|
|
+ <div>总里程 {{ truckTrialInfo.mileage }}公里</div>
|
|
|
+ <div>总能耗 {{ truckTrialInfo.consumption }}公斤</div>
|
|
|
+ <div>总减碳 {{ truckTrialInfo.carbon }}公斤</div>
|
|
|
+ </div>
|
|
|
+ <div style="width: 100%;padding: 30px 0 10px;">
|
|
|
+ <van-slider v-model="backValue" bar-height="4px" disabled>
|
|
|
+ <template #button>
|
|
|
+ <div class="slider-custom-button"> </div>
|
|
|
+ </template>
|
|
|
+ </van-slider>
|
|
|
+ </div>
|
|
|
+ <div class="back-time">
|
|
|
+ <div>{{ datatime.startTime }}</div>
|
|
|
+ <div @click="playTrailEvent()"><van-image width="28px" height="28px" fit="contain" :src="requestImages()"/></div>
|
|
|
+ <div>{{ datatime.endTime }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <el-bmap vid="bmap" :min-zoom="8" :max-zoom="20" :zoom="zoom" :center="center" :bmap-manager="bmapManager" class="bm-view" :style="mapStyle" :events="events"></el-bmap>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import 'vue-bmap-gl/dist/style.css'
|
|
|
+import axios from 'axios'
|
|
|
+import { BMapManager } from 'vue-bmap-gl'
|
|
|
+import { $gasdataTruckInfo, $gasdataTruckTrajectory } from '@/service/gasdata'
|
|
|
+import { formatDate } from '@/utils/tools'
|
|
|
+// import { transformFromWGSToGCJ, transformFromGCJToBaidu } from '@/utils/wscoordinate'
|
|
|
+export default {
|
|
|
+ name: 'battle',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ backValue: 0,
|
|
|
+ timeStatus: 1,
|
|
|
+ showStatus: true,
|
|
|
+ playStatus: 1,
|
|
|
+ datatime: {
|
|
|
+ startTime: formatDate((new Date().getTime() - 86400000), 'yyyy-MM-dd hh:mm:ss'),
|
|
|
+ endTime: formatDate(new Date().getTime(), 'yyyy-MM-dd hh:mm:ss')
|
|
|
+ },
|
|
|
+ truckInfo: {},
|
|
|
+ truckTrialInfo: {},
|
|
|
+ queryTruckInfo: this.$route.query,
|
|
|
+ bmapManager: new BMapManager(),
|
|
|
+ map: null,
|
|
|
+ mapStyle: {
|
|
|
+ width: '100%',
|
|
|
+ height: '100%'
|
|
|
+ },
|
|
|
+ center: [this.$route.query.lng, this.$route.query.lat],
|
|
|
+ zoom: 10,
|
|
|
+ events: {
|
|
|
+ init: (map) => {
|
|
|
+ this.map = map
|
|
|
+ this.initTrailData()
|
|
|
+ // this.startDemo(o)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ timer: null,
|
|
|
+ mapHeight: 400,
|
|
|
+ cardList: [{
|
|
|
+ name: '今日里程',
|
|
|
+ value: '0',
|
|
|
+ unit: '公里'
|
|
|
+ }, {
|
|
|
+ name: '今日耗能',
|
|
|
+ value: '0',
|
|
|
+ unit: '公斤'
|
|
|
+ }, {
|
|
|
+ name: '今日减碳',
|
|
|
+ value: '0',
|
|
|
+ unit: '公斤'
|
|
|
+ }],
|
|
|
+ truckStatusList: {
|
|
|
+ 0: '行驶中',
|
|
|
+ 1: '静止中',
|
|
|
+ 2: '离线中'
|
|
|
+ },
|
|
|
+ lushu: null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {},
|
|
|
+ computed: {},
|
|
|
+ created() {
|
|
|
+ this.dragendPointer()
|
|
|
+ // this.truckTrailInfo()
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ // 重置地图高度
|
|
|
+ this.mapHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
|
|
|
+ },
|
|
|
+ beforeDestroy() {},
|
|
|
+ methods: {
|
|
|
+ initData() {
|
|
|
+ let loaded = false
|
|
|
+ try {
|
|
|
+ loaded = (BMapGLLib && BMapGLLib.Lushu)
|
|
|
+ } catch (err) {
|
|
|
+ loaded = false
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!loaded) {
|
|
|
+ console.log('BMapGLLib.Lushu loading!')
|
|
|
+ const lushu = document.createElement('script')
|
|
|
+ lushu.type = 'text/javascript'
|
|
|
+ lushu.src = 'https://mapopen.bj.bcebos.com/github/BMapGLLib/Lushu/src/Lushu.min.js'
|
|
|
+ document.body.appendChild(lushu)
|
|
|
+ const trackAnimation = document.createElement('script')
|
|
|
+ trackAnimation.type = 'text/javascript'
|
|
|
+ trackAnimation.src = 'https://mapopen.bj.bcebos.com/github/BMapGLLib/TrackAnimation/src/TrackAnimation.min.js'
|
|
|
+ document.body.appendChild(trackAnimation)
|
|
|
+ } else {
|
|
|
+ console.log('BMapGLLib.Lushu is loaded!')
|
|
|
+ }
|
|
|
+ },
|
|
|
+ timeEvent(type) {
|
|
|
+ this.timeStatus = Number(type)
|
|
|
+
|
|
|
+ if (this.timeStatus === 1) {
|
|
|
+ this.datatime = {
|
|
|
+ startTime: formatDate((new Date().getTime() - 86400000), 'yyyy-MM-dd hh:mm:ss'),
|
|
|
+ endTime: formatDate(new Date().getTime(), 'yyyy-MM-dd hh:mm:ss')
|
|
|
+ }
|
|
|
+ } if (this.timeStatus === 2) {
|
|
|
+ this.datatime = {
|
|
|
+ startTime: formatDate((new Date().getTime() - 3 * 86400000), 'yyyy-MM-dd hh:mm:ss'),
|
|
|
+ endTime: formatDate(new Date().getTime(), 'yyyy-MM-dd hh:mm:ss')
|
|
|
+ }
|
|
|
+ } if (this.timeStatus === 3) {
|
|
|
+ this.datatime = {
|
|
|
+ startTime: formatDate((new Date().getTime() - 7 * 86400000), 'yyyy-MM-dd hh:mm:ss'),
|
|
|
+ endTime: formatDate(new Date().getTime(), 'yyyy-MM-dd hh:mm:ss')
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.initTrailData()
|
|
|
+ },
|
|
|
+ requestImages () {
|
|
|
+ if (this.playStatus === 1) {
|
|
|
+ return require('@/assets/images/home/play.png')
|
|
|
+ } else {
|
|
|
+ return require('@/assets/images/home/stop.png')
|
|
|
+ }
|
|
|
+ },
|
|
|
+ playTrailEvent() {
|
|
|
+ if (this.playStatus === 1) {
|
|
|
+ this.playStatus = 2
|
|
|
+ this.lushu.start()
|
|
|
+ } else {
|
|
|
+ this.playStatus = 1
|
|
|
+ this.lushu.pause()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async initTrailData() {
|
|
|
+ this.initData()
|
|
|
+ const truckInfo = await this.truckTrailInfo()
|
|
|
+ const arrPois = truckInfo.points || []
|
|
|
+
|
|
|
+ const len = arrPois.length - 1
|
|
|
+ // const beginPoint = transformFromWGSToGCJ(arrPois[0].lat, arrPois[0].lng)
|
|
|
+ // const endPoint = transformFromWGSToGCJ(arrPois[len].lat, arrPois[len].lng)
|
|
|
+ // const baiduBeginPoint = transformFromGCJToBaidu(beginPoint.latitude, beginPoint.longitude)
|
|
|
+ // const baiduEndPoint = transformFromGCJToBaidu(endPoint.latitude, endPoint.longitude)
|
|
|
+ // console.log(baiduBeginPoint, baiduEndPoint)
|
|
|
+
|
|
|
+ var start = new BMapGL.Point(arrPois[0].lng, arrPois[0].lat)
|
|
|
+ var end = new BMapGL.Point(arrPois[len].lng, arrPois[len].lat)
|
|
|
+ var drv = new BMapGL.DrivingRoute(this.map, {
|
|
|
+ onSearchComplete: (res) => {
|
|
|
+ if (drv.getStatus() == BMAP_STATUS_SUCCESS) {
|
|
|
+ this.map.clearOverlays()
|
|
|
+ // 增加起点和终点坐标
|
|
|
+ this.map.addOverlay(new BMapGL.Marker(start, {
|
|
|
+ offset: new BMapGL.Size(0, -12),
|
|
|
+ icon: new BMapGL.Icon(require('@/assets/images/home/begin@2x.png'), new BMapGL.Size(20, 26))
|
|
|
+ }))
|
|
|
+ this.map.addOverlay(new BMapGL.Marker(end, {
|
|
|
+ offset: new BMapGL.Size(0, -12),
|
|
|
+ icon: new BMapGL.Icon(require('@/assets/images/home/end@2x.png'), new BMapGL.Size(20, 26))
|
|
|
+ }))
|
|
|
+
|
|
|
+ this.map.addOverlay(new BMapGL.Polyline(arrPois, { strokeColor: '#43bf91', strokeOpacity: 1 }))
|
|
|
+ this.map.setViewport(arrPois)
|
|
|
+
|
|
|
+ this.lushu = new BMapGLLib.LuShu(this.map, arrPois, {
|
|
|
+ defaultContent: '', // 覆盖物中的内容 "从天安门到百度大厦"
|
|
|
+ autoView: true, // 是否开启自动视野调整,如果开启那么路书在运动过程中会根据视野自动调整
|
|
|
+ icon: new BMapGL.Icon(require('@/assets/images/home/red@2x.png'), new BMapGL.Size(15, 15), { anchor: new BMapGL.Size(10, 10) }),
|
|
|
+ speed: 10, // 覆盖物移动速度,单位米/秒
|
|
|
+ enableRotation: true // 是否设置marker随着道路的走向进行旋转
|
|
|
+ // landmarkPois: [
|
|
|
+ // { lng: 116.314782, lat: 39.913508, html: '加油站', pauseTime: 2 },
|
|
|
+ // { lng: 116.315391, lat: 39.964429, html: '高速公路收费<div><img src="//map.baidu.com/img/logo-map.gif"/></div>', pauseTime: 3 },
|
|
|
+ // { lng: 116.381476, lat: 39.974073, html: '肯德基早餐', pauseTime: 2 }
|
|
|
+ // ]
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ drv.search(start, end)
|
|
|
+ },
|
|
|
+ async queryCurrAddress(location) {
|
|
|
+ const data = await axios.post(process.env.VUE_APP_BAIDU_URL + '?output=json&ak=Zvd6FzmertUwjhZih5Zfq0D8uTUhvqsH&coordtype=wgs84ll&location=' + location).then(response => {
|
|
|
+ return response.data
|
|
|
+ })
|
|
|
+
|
|
|
+ if (data.hasOwnProperty('result')) {
|
|
|
+ return data.result.addressComponent
|
|
|
+ } else {
|
|
|
+ return '-'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ angle(start, end) {
|
|
|
+ // 通过 a、b 确定角度所处的象限
|
|
|
+ const a = start[0] - end[0]
|
|
|
+ const b = start[1] - end[1]
|
|
|
+ // eslint-disable-next-line camelcase
|
|
|
+ const a_c = Math.abs(a)
|
|
|
+ // eslint-disable-next-line camelcase
|
|
|
+ const b_c = Math.abs(b)
|
|
|
+ // 获取得三角形的斜边 Math.hypot();
|
|
|
+ const c = Math.hypot(a_c, b_c)
|
|
|
+ // 计算弧度
|
|
|
+ // eslint-disable-next-line camelcase
|
|
|
+ const radina = Math.acos(a_c / c)
|
|
|
+ // 计算角度
|
|
|
+ let angleVal = Math.floor(radina * 180 / Math.PI)
|
|
|
+ // 处理最终需要旋转的角度
|
|
|
+ if (a > 0) {
|
|
|
+ // 第二、三象限
|
|
|
+ if (b > 0) {
|
|
|
+ // 三
|
|
|
+ angleVal = 90 + 90 - angleVal
|
|
|
+ } else {
|
|
|
+ angleVal = -180 + angleVal
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 一、四象限
|
|
|
+ if (b > 0) {
|
|
|
+ // 四
|
|
|
+ // eslint-disable-next-line no-self-assign
|
|
|
+ angleVal = angleVal
|
|
|
+ } else {
|
|
|
+ // 一
|
|
|
+ angleVal = -angleVal
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return angleVal
|
|
|
+ },
|
|
|
+ async truckTrailInfo() {
|
|
|
+ const params = {
|
|
|
+ carNumber: this.queryTruckInfo.carNumber,
|
|
|
+ days: (this.timeStatus === 9 ? 0 : this.timeStatus),
|
|
|
+ startTime: this.datatime.startTime,
|
|
|
+ endTime: this.datatime.endTime
|
|
|
+ }
|
|
|
+ const data = await $gasdataTruckTrajectory(params).then(response => {
|
|
|
+ return response
|
|
|
+ })
|
|
|
+ this.truckTrialInfo = data
|
|
|
+
|
|
|
+ return data
|
|
|
+ },
|
|
|
+ dragendPointer() {
|
|
|
+ const params = {
|
|
|
+ carNumber: this.queryTruckInfo.carNumber
|
|
|
+ }
|
|
|
+
|
|
|
+ this.markers = []
|
|
|
+ $gasdataTruckInfo(params).then(async response => {
|
|
|
+ this.truckInfo = response
|
|
|
+ // 统计数据
|
|
|
+ this.cardList[0].value = response.mileage.toFixed(0)
|
|
|
+ this.cardList[1].value = response.consumption
|
|
|
+ this.cardList[2].value = response.carbon
|
|
|
+
|
|
|
+ // 根据金纬度获取地理位置信息
|
|
|
+ const addressInfo = await this.queryCurrAddress(response.lat + ',' + response.lng)
|
|
|
+ const currAddress = addressInfo.province + addressInfo.city + addressInfo.district + addressInfo.street
|
|
|
+
|
|
|
+ if (response.hasOwnProperty('currAddress')) {
|
|
|
+ response.currAddress = currAddress
|
|
|
+ } else {
|
|
|
+ this.$set(response, 'currAddress', currAddress)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|