Browse Source

增加监控视频

wangcc 2 years ago
parent
commit
267503914b

+ 1 - 0
public/index.html

@@ -16,4 +16,5 @@
     <div id="app"></div>
     <!-- built files will be auto injected -->
   </body>
+  <script src="https://web.sdk.qcloud.com/player/tcplayerlite/release/v2.4.1/TcPlayer-2.4.1.js" charset="utf-8"></script>
 </html>

+ 10 - 1
src/api/http.js

@@ -3,7 +3,7 @@
  * @Author: wangcc
  * @Date: 2023-01-09 15:07:51
  * @LastEditors: wangcc
- * @LastEditTime: 2023-01-11 17:55:28
+ * @LastEditTime: 2023-01-29 17:40:14
  * @FilePath: \parking_LargeScreen\src\api\http.js
  * @Copyright: Copyright (c) 2016~2023 by wangcc, All Rights Reserved. 
  */
@@ -73,4 +73,13 @@ export function detail(data) {
     method: 'get',
     params:data
   })
+}
+
+// 查询数据总览
+export function vehicleData(data) {
+  return request({
+    url: '/admin/screen/roadPark/vehicleData',
+    method: 'get',
+    params:data
+  })
 }

BIN
src/assets/images/mark_window_bac.png


+ 278 - 2
src/components/ParkingRate/index.vue

@@ -3,26 +3,302 @@
  * @Author: wangcc
  * @Date: 2023-01-09 11:22:53
  * @LastEditors: wangcc
- * @LastEditTime: 2023-01-11 09:27:47
+ * @LastEditTime: 2023-01-29 17:59:41
  * @FilePath: \parking_LargeScreen\src\components\ParkingRate\index.vue
  * @Copyright: Copyright (c) 2016~2023 by wangcc, All Rights Reserved. 
 -->
 <template>
   <div class="center">
+    <div class="vehicle-box">
+      <div class="vehicle-box-item">
+        <span class="vehicle-box-item-title">今日进场车 辆数(辆)</span>
+        <span class="vehicle-box-item-total">
+          <Count-to :startVal="startVal" :endVal="totalData.inVehicleCount" :duration="4000"></Count-to>
+        </span>
+      </div>
+      <div class="vehicle-box-item">
+        <span class="vehicle-box-item-title">今日出场车 辆数(辆)</span>
+        <span class="vehicle-box-item-total">
+          <Count-to :startVal="startVal" :endVal="totalData.outVehicleCount" :duration="4000"></Count-to>
+        </span>
+      </div>
+      <div class="vehicle-box-item">
+        <span class="vehicle-box-item-title">今日车位平 均使用率</span>
+        <span class="vehicle-box-item-total">
+          <!-- <Count-to :startVal="startVal" :endVal="totalData.spaceRat" :duration="4000"></Count-to> -->
+          {{totalData.spaceRat}}
+        </span>
+      </div>
+    </div>
+    <div class="vehicle-video">
+      <div class="vehicle-video-right">
+        <div class="rankTitle">
+          <h3>路段实时监控</h3>
+        </div>
+        <div class="vehicle-video-right-list">
+          <div v-if="rankOptions.length > 0">
+            <div
+              class="vehicle-video-right-list-item"
+              v-for="(item,index) in rankOptions"
+              :key="index"
+            >
+              <span class="vehicle-video-right-list-item-parkName">
+                {{item.parkName}}
+                <i class="el-icon-caret-bottom"></i>
+              </span>
+              <span
+                class="vehicle-video-right-list-item-parkVideo"
+                :class="{vactive:cur==item.id+'-'+idx}"
+                @click="tabLink(idx,item)"
+                v-for="(its,idx) in item.child"
+                :key="idx"
+              >{{its.videoName}}</span>
+            </div>
+          </div>
+          <div v-else>暂无数据</div>
+        </div>
+      </div>
+      <div class="vehicle-video-left">
+        <div v-show="videoPlayerOneRoad" id="videoPlayerCenterRoad" style="height: 100%;"></div>
+        <div class="noMore" v-if="!videoPlayerOneRoad">暂无视频</div>
+      </div>
+    </div>
+    <div class="vehicle-video">
+      <div class="vehicle-video-right">
+        <div class="rankTitle">
+          <h3>停车场实时监控</h3>
+        </div>
+        <div class="vehicle-video-right-list">
+          <div v-if="parkOptions.length > 0">
+            <div
+              class="vehicle-video-right-list-item"
+              v-for="(item,index) in parkOptions"
+              :key="index"
+            >
+              <span class="vehicle-video-right-list-item-parkName">
+                {{item.parkName}}
+                <i class="el-icon-caret-bottom"></i>
+              </span>
+              <span
+                class="vehicle-video-right-list-item-parkVideo"
+                :class="{vactive:parkCur==item.id+'-'+idx}"
+                @click="parkLink(idx,item)"
+                v-for="(its,idx) in item.child"
+                :key="idx"
+              >{{its.videoName}}</span>
+            </div>
+          </div>
+          <div v-else>暂无数据</div>
+        </div>
+      </div>
+      <div class="vehicle-video-left">
+        <div v-show="videoPlayerOnePark" id="videoPlayerCenterPark" style="height: 100%;"></div>
+        <div class="noMore" v-if="!videoPlayerOnePark">暂无视频</div>
+      </div>
+    </div>
+    <div class="vehicle-circumstance">
+      <div class="rankTitle">
+          <h3>路段停车位情况</h3>
+        </div>
+        
+    </div>
   </div>
 </template>
 
 <script>
+import CountTo from 'vue-count-to';
+import { vehicleData } from '@/api/http';
 export default {
   name: '',
+  components: { CountTo },
   data() {
     return {
       value: '',
-      options: []
+      cur: 0,
+      parkCur: 0,
+      playerRoadUrl: '',
+      playerUrl: '',
+      startVal: 0,
+      videoPlayerOnePark: null,
+      videoPlayerOneRoad: null,
+      rankOptions: [],
+      parkOptions: [],
+      totalData: {}
     };
+  },
+  mounted() {
+    this.videoPlayerPark();
+    this.videoPlayerRoad();
+  },
+  created() {
+    this.getVehicleData()
+  },
+  destroyed() {
+    // 页面销毁,同时也销毁 TcPlayer
+    if (this.videoPlayerOnePark) {
+      this.videoPlayerOnePark.destroy();
+    }
+    if (this.videoPlayerOneRoad) {
+      this.videoPlayerOneRoad.destroy();
+    }
+  },
+  methods: {
+    tabLink(e, item) {
+      this.cur = item.id + '-' + e;
+    },
+    parkLink(e, item) {
+      this.parkCur = item.id + '-' + e;
+    },
+    // 查询数据总览
+    async getVehicleData() {
+      let { data, code } = await vehicleData();
+      if (code == 200) {
+        console.log(data);
+        this.totalData = data;
+      }
+    },
+    // 道路视频监控
+    videoPlayerRoad() {
+      this.videoPlayerOneRoad = new TcPlayer('videoPlayerCenterRoad', {
+        m3u8: this.playerRoadUrl,
+        autoplay: true, //iOS下safari浏览器,以及大部分移动端浏览器是不开放视频自动播放这个能力的
+        // "coverpic": img,
+        width: '100%', //视频的显示宽度,请尽量使用视频分辨率宽度
+        height: '100%', //视频的显示高度,请尽量使用视频分辨率高度
+        remember: 1,
+        controls: 'none'
+      });
+    },
+    // 停车场视频监控
+    videoPlayerPark() {
+      this.videoPlayerOnePark = new TcPlayer('videoPlayerCenterPark', {
+        m3u8: this.playerUrl,
+        autoplay: true, //iOS下safari浏览器,以及大部分移动端浏览器是不开放视频自动播放这个能力的
+        // "coverpic": img,
+        width: '100%', //视频的显示宽度,请尽量使用视频分辨率宽度
+        height: '100%', //视频的显示高度,请尽量使用视频分辨率高度
+        remember: 1,
+        controls: 'none'
+      });
+    }
   }
 };
 </script>
 
 <style  lang='scss' scoped>
+.center {
+  position: absolute;
+  overflow: hidden;
+  top: 67px;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 1002;
+  color: #fff;
+  padding: 0 20px 20px 20px;
+}
+.vehicle-box {
+  display: flex;
+  height: 84px;
+  align-items: center;
+  justify-content: flex-start;
+  &-item {
+    width: 230px;
+    margin-right: 80px;
+    &-title {
+      width: 70px;
+      display: inline-block;
+      font-size: 14px;
+    }
+    &-total {
+      font-size: 44px;
+      font-weight: 600;
+      margin-left: 20px;
+    }
+  }
+}
+.vehicle-video {
+  background: linear-gradient(90deg, #293446 0%, rgba(41, 52, 70, 0.2) 100%);
+  backdrop-filter: blur(10px);
+  width: 890px;
+  height: 520px;
+  float: left;
+  overflow: hidden;
+  padding: 20px;
+  margin-left: 10px;
+  &-right {
+    float: left;
+    width: 160px;
+    margin-right: 20px;
+    .rankTitle {
+      text-align: left;
+      // padding-left: 20px;
+      font-size: 16px;
+      color: #ffffff;
+      /* line-height: 22px; */
+      margin-bottom: 12px;
+      display: flex;
+      height: 22px;
+      align-items: center;
+    }
+    .rankTitle::before {
+      content: '';
+      width: 16px;
+      height: 15px;
+      display: inline-block;
+      background-image: url('@/assets/images/check.png');
+      background-size: 100% 100%;
+      margin-right: 10px;
+    }
+    &-list {
+      width: 100%;
+      text-align: center;
+      &-item {
+        display: flex;
+        flex-direction: column;
+        span {
+          line-height: 30px;
+          margin-bottom: 6px;
+          cursor: pointer;
+        }
+        &-parkName {
+          font-size: 16px;
+        }
+        &-parkVideo {
+          font-size: 14px;
+          background-color: rgba(255, 255, 255, 0.15);
+          border: 1px solid rgba(255, 255, 255, 0.15);
+        }
+        .vactive {
+          color: #1dd4ff;
+          background: linear-gradient(
+            180deg,
+            rgba(42, 215, 255, 0) 0%,
+            rgba(29, 212, 255, 0.6) 46%,
+            rgba(42, 214, 255, 0) 100%
+          );
+          border: 1px solid;
+          border-image: linear-gradient(
+              90deg,
+              rgba(84, 237, 255, 0.16),
+              rgba(29, 212, 255, 1),
+              rgba(42, 215, 255, 0.16)
+            )
+            1 1;
+        }
+      }
+    }
+  }
+  &-left {
+    width: 700px;
+    float: right;
+    height: 100%;
+  }
+}
+.noMore {
+  display: flex;
+  height: 100%;
+  justify-content: center;
+  align-items: center;
+}
 </style>

+ 24 - 13
src/components/Receivables/PercenTage.vue

@@ -3,7 +3,7 @@
  * @Author: wangcc
  * @Date: 2023-01-11 14:19:56
  * @LastEditors: wangcc
- * @LastEditTime: 2023-01-28 17:33:30
+ * @LastEditTime: 2023-01-29 13:45:15
  * @FilePath: \parking_LargeScreen\src\components\Receivables\PercenTage.vue
  * @Copyright: Copyright (c) 2016~2023 by wangcc, All Rights Reserved. 
 -->
@@ -40,17 +40,18 @@ export default {
           { value: 30, name: '无感支付' }
         ]
       },
-      payData:{
-        0:'现金支付',
-        1:'微信支付', 
-        3:'快捷支付', 
-        4:'聚合支付', 
-        6:'无感支付', 
-        99:'其他'
+      payData: {
+        0: '现金支付',
+        1: '微信支付',
+        3: '快捷支付',
+        4: '聚合支付',
+        6: '无感支付',
+        99: '其他'
       },
       searchFrom: {
         isRoad: '1'
-      }
+      },
+      setTime: ''
     };
   },
   created() {
@@ -64,18 +65,28 @@ export default {
       }
     }
   },
+  mounted() {
+    let _this = this;
+    this.setTime = setInterval(function () {
+      _this.getPaySource();
+    }, 30000);
+  },
+
   methods: {
+    clearTime() {
+      clearInterval(this.setTime);
+    },
     async getPaySource() {
       this.hackReset = false;
       let { code, data } = await paysource(this.searchFrom);
       if (code == 200) {
         this.hackReset = true;
-        this.echartsData.pieData = data.itemList.map(item =>{
+        this.echartsData.pieData = data.itemList.map((item) => {
           let pieData = {};
           pieData.value = item.amt;
-          pieData.name = this.payData[item.paySource]
-          return pieData
-        })
+          pieData.name = this.payData[item.paySource];
+          return pieData;
+        });
       }
     }
   }

+ 5 - 2
src/components/Receivables/Receivables.vue

@@ -3,7 +3,7 @@
  * @Author: wangcc
  * @Date: 2023-01-09 11:20:54
  * @LastEditors: wangcc
- * @LastEditTime: 2023-01-28 13:40:30
+ * @LastEditTime: 2023-01-29 13:52:53
  * @FilePath: \parking_LargeScreen\src\components\Receivables\Receivables.vue
  * @Copyright: Copyright (c) 2016~2023 by wangcc, All Rights Reserved. 
 -->
@@ -81,7 +81,7 @@ export default {
       countName: '路段数量(个)',
       searchFrom: {
         isRoad: '1'
-      }
+      },
     };
   },
   created() {
@@ -101,6 +101,9 @@ export default {
         this.getAmtVehicle()
       }
     }
+  },
+   mounted() {
+
   },
   methods: {
     async getTotalData() {

+ 18 - 7
src/components/Receivables/analyse.vue

@@ -3,7 +3,7 @@
  * @Author: wangcc
  * @Date: 2023-01-11 15:28:30
  * @LastEditors: wangcc
- * @LastEditTime: 2023-01-28 14:38:21
+ * @LastEditTime: 2023-01-29 13:57:40
  * @FilePath: \parking_LargeScreen\src\components\Receivables\analyse.vue
  * @Copyright: Copyright (c) 2016~2023 by wangcc, All Rights Reserved. 
 -->
@@ -36,25 +36,36 @@ export default {
         xData: [],
         yData: []
       },
-      hackReset:false,
+      hackReset: false,
       searchFrom: {
         isRoad: '1'
-      }
+      },
+      setTime: ''
     };
   },
   created() {
     this.getIncome();
   },
+
   watch: {
     '$store.state.addr.isRoad': {
       handler(val) {
         this.searchFrom.isRoad = val;
         this.getIncome();
-      },
-
+      }
     }
   },
+  mounted() {
+    let _this = this;
+    this.setTime = setInterval(function () {
+      _this.getIncome();
+    }, 30000);
+  },
+
   methods: {
+    clearTime() {
+      clearInterval(this.setTime);
+    },
     getTimeAnalysis() {
       this.echartsData.xData = this.echartsData.barRData.map((item) => {
         return item.time;
@@ -68,8 +79,8 @@ export default {
       income(this.searchFrom).then((res) => {
         if (res.code == 200) {
           this.hackReset = true;
-          this.echartsData.barRData = res.data.map(item =>{
-            let data = {}
+          this.echartsData.barRData = res.data.map((item) => {
+            let data = {};
             data.time = item.payTime;
             data.num = item.realAmount;
             return data;

+ 52 - 4
src/components/map.vue

@@ -3,7 +3,7 @@
  * @Author: wangcc
  * @Date: 2023-01-09 11:19:36
  * @LastEditors: wangcc
- * @LastEditTime: 2023-01-28 18:01:02
+ * @LastEditTime: 2023-01-29 11:36:38
  * @FilePath: \parking_LargeScreen\src\components\map.vue
  * @Copyright: Copyright (c) 2016~2023 by wangcc, All Rights Reserved. 
 -->
@@ -42,6 +42,7 @@ export default {
         this.searchFrom.isRoad = val;
         this.markerData.setMap(null);
         this.getRoadParkList();
+        this.infoWindow.close();
       }
     }
   },
@@ -120,15 +121,16 @@ export default {
         _this.infoWindow = new TMap.InfoWindow({
           map: this.map,
           position: new TMap.LatLng(39.984104, 116.307503),
-          offset: { x: 0, y: -60 } //设置信息窗相对position偏移像素
+          offset: { x: 0, y: -20 } //设置信息窗相对position偏移像素
         });
         _this.infoWindow.close();
         this.markerData.on('click', function (evt) {
           //设置infoWindow
-          infoWindow.open(); //打开信息窗
-          infoWindow.setPosition(evt.geometry.position); //设置信息窗位置
+          _this.infoWindow.open(); //打开信息窗
+          _this.infoWindow.setPosition(evt.geometry.position); //设置信息窗位置
           console.log(evt.geometry.roadNo);
           _this.getDetail(evt.geometry.roadNo);
+          _this.map.panTo(evt.geometry.position, { duration: 2000 });
           // infoWindow.setContent(evt.toString()); //设置信息窗内容
         });
       }
@@ -137,6 +139,29 @@ export default {
       detail({ roadNo: roadNo }).then((res) => {
         if (res.code == 200) {
           console.log(res);
+          let data = res.data;
+          let html =
+            '<div class="label-box" id="'+data.roadNo+'">' +
+            '<h3 class="label-box-title">' +
+            data.roadName +
+            '</h3>' +
+            '<div class="label-box-content"><p><span>车位数:</span>' +
+            data.totalSpaceCount +
+            '</p>' +
+            '<p><span>今日实收</span>:' +
+            data.realAmount +
+            '</p>' +
+            '<p><span>今日停车次数</span>:' +
+            data.realAmount +
+            '</p></div>';
+          ('</div>');
+          this.infoWindow.setContent(html);
+          let parent = document.getElementById(data.roadNo).parentNode
+          parent.style.backgroundColor = 'transparent';
+          parent.setAttribute('id', 'first'+ data.roadNo);
+          let bother =
+            document.getElementById('first'+ data.roadNo).nextElementSibling;
+          bother.style.display = 'none';
         }
       });
     }
@@ -169,4 +194,27 @@ export default {
 ::v-deep .amap-copyright {
   opacity: 0 !important; //去掉高德的版本号
 }
+::v-deep .label-box {
+  background-image: url('../assets/images/mark_window_bac.png');
+  width: 211px;
+  height: 137px;
+  color: #fff;
+  background-size: 100% 100%;
+  &-title {
+    text-align: left;
+    line-height: 28px;
+    padding-left: 30px;
+  }
+  &-content {
+    padding: 15px 10px;
+    text-align: left;
+    p {
+      line-height: 25px;
+      font-weight: 600;
+      span {
+        font-weight: 400;
+      }
+    }
+  }
+}
 </style>

+ 1 - 1
src/components/topNav.vue

@@ -3,7 +3,7 @@
  * @Author: wangcc
  * @Date: 2023-01-09 11:20:03
  * @LastEditors: wangcc
- * @LastEditTime: 2023-01-11 16:49:06
+ * @LastEditTime: 2023-01-29 15:44:29
  * @FilePath: \parking_LargeScreen\src\components\topNav.vue
  * @Copyright: Copyright (c) 2016~2023 by wangcc, All Rights Reserved. 
 -->

+ 53 - 0
src/components/video/vueVideoPlayer.vue

@@ -0,0 +1,53 @@
+<!--
+ * @Description: vueVideoPlayer
+ * @Author: wangcc
+ * @Date: 2023-01-29 16:29:30
+ * @LastEditors: wangcc
+ * @LastEditTime: 2023-01-29 17:31:02
+ * @FilePath: \parking_LargeScreen\src\components\video\vueVideoPlayer.vue
+ * @Copyright: Copyright (c) 2016~2023 by wangcc, All Rights Reserved. 
+-->
+<template>
+  <div style="height: 100%;">
+    <div id="videoPlayerCenter" style="height: 100%;"></div>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    videoPlayerUrl: String
+  },
+  data() {
+    return {
+      videoPlayerOne: null
+    };
+  },
+  mounted() {
+    this.videoPlayer();
+  },
+  destroyed() {
+    // 页面销毁,同时也销毁 TcPlayer
+    if (this.videoPlayerOne) {
+      this.videoPlayerOne.destroy();
+    }
+  },
+  methods: {
+    videoPlayer() {
+      this.videoPlayerOne = new TcPlayer('videoPlayerCenter', {
+        // m3u8: 'https://1500005692.vod2.myqcloud.com/43843706vodtranscq1500005692/62656d94387702300542496289/v.f100240.m3u8', //请替换成实际可用的播放地址
+        m3u8: this.videoPlayerUrl,
+        autoplay: true, //iOS下safari浏览器,以及大部分移动端浏览器是不开放视频自动播放这个能力的
+        // "coverpic": img,
+        width: '100%', //视频的显示宽度,请尽量使用视频分辨率宽度
+        height: '100%', //视频的显示高度,请尽量使用视频分辨率高度
+        remember: 1,
+        controls: 'none'
+      });
+    }
+  }
+};
+</script>
+
+<style  lang='scss' scoped>
+</style>

+ 0 - 1
src/main.js

@@ -9,7 +9,6 @@ import { Select, Option, Input, Table, TableColumn,Dialog } from 'element-ui';
 import VScaleScreen from 'v-scale-screen'
 import * as echarts from 'echarts';
 
-
 Vue.use(VScaleScreen)
 Vue.use(Select);
 Vue.use(Option);

+ 12 - 4
src/views/screenIndex/index.vue

@@ -3,7 +3,7 @@
  * @Author: wangcc
  * @Date: 2023-01-09 11:18:33
  * @LastEditors: wangcc
- * @LastEditTime: 2023-01-11 17:17:10
+ * @LastEditTime: 2023-01-29 17:09:42
  * @FilePath: \parking_LargeScreen\src\views\screenIndex\index.vue
  * @Copyright: Copyright (c) 2016~2023 by wangcc, All Rights Reserved. 
 -->
@@ -15,8 +15,9 @@
         <tab-label v-if="tabType == 1"></tab-label>
         <Receivables v-if="tabType == 1"></Receivables>
         <ranking v-if="tabType == 1"></ranking>
-        <percen-tage v-if="tabType == 1"></percen-tage>
-        <analyse v-if="tabType == 1"></analyse>
+        <percen-tage ref="PercenTage" v-if="tabType == 1"></percen-tage>
+        <analyse ref="analyse" v-if="tabType == 1"></analyse>
+        <Parking-rate v-if="tabType != 1"></Parking-rate>
     </v-scale-screen>
   </div>
 </template>
@@ -30,6 +31,7 @@ import Receivables from '@/components/Receivables/Receivables.vue';
 import ranking from '@/components/Receivables/ranking.vue';
 import PercenTage from '@/components/Receivables/PercenTage.vue';
 import analyse from '@/components/Receivables/analyse';
+import ParkingRate from '@/components/ParkingRate/index.vue'
 export default {
   name: '',
   components: {
@@ -39,7 +41,8 @@ export default {
     Receivables,
     ranking,
     PercenTage,
-    analyse
+    analyse,
+    ParkingRate
   },
   data() {
     return {
@@ -53,7 +56,12 @@ export default {
   watch: {},
   methods: {
     tabCheck(item) {
+      console.log(item);
       this.tabType = item.id;
+      if (item.id !=1) {
+        this.$refs.PercenTage.clearTime();
+        this.$refs.analyse.clearTime();
+      }
     },
   }
 };