chen.cheng 7 сар өмнө
parent
commit
181951a168

+ 1 - 1
ruoyi-ui/deploy.sh

@@ -37,7 +37,7 @@ fi
 # 更新版本号
 NEXT_VERSION="${CURRENT_MAJOR}.${CURRENT_MINOR}"
 echo $NEXT_VERSION > $VERSION_FILE
-echo -e "\e[1;34;42m版本号:" $NEXT_VERSION "\e[0m"
+echo  -e "\e[1;34;42m版本号:" $NEXT_VERSION " 日期:$(date +"%Y-%m-%d %H:%M:%S")" "\e[0m"
 # 用户选择执行的步骤
 echo "请选择要执行的步骤(输入数字):"
 echo "1. 编译bd-app项目"

+ 2 - 1
ruoyi-ui/package.json

@@ -63,7 +63,8 @@
     "vue-json-editor": "^1.4.3",
     "vue-meta": "2.4.0",
     "vue-router": "3.4.9",
-    "vuedraggable": "2.24.3",
+    "vue-video-player": "^5.0.1",
+    "vuedraggable": "^2.24.3",
     "vuex": "3.6.0"
   },
   "devDependencies": {

+ 55 - 0
ruoyi-ui/src/main.js

@@ -38,6 +38,14 @@ import VueMeta from 'vue-meta'
 // 字典数据组件
 import DictData from '@/components/DictData'
 
+import VideoPlayer from 'vue-video-player'
+
+import 'video.js/dist/video-js.css'
+
+import 'vue-video-player/src/custom-theme.css'
+
+Vue.use(VideoPlayer)
+
 // 全局方法挂载
 Vue.prototype.getDicts = getDicts
 Vue.prototype.getConfigKey = getConfigKey
@@ -57,7 +65,54 @@ Vue.component('Editor', Editor)
 Vue.component('FileUpload', FileUpload)
 Vue.component('ImageUpload', ImageUpload)
 Vue.component('ImagePreview', ImagePreview)
+Vue.directive('drag', (el) => {
+  const oDiv = el // 当前元素
+  const minTop = oDiv.getAttribute('drag-min-top')
+  const ifMoveSizeArea = 20
+  oDiv.onmousedown = e => {
+    let target = oDiv
+    while (window.getComputedStyle(target).position !== 'absolute' && target !== document.body) {
+      target = target.parentElement
+    }
 
+    document.onselectstart = () => {
+      return false
+    }
+    if (!target.getAttribute('init_x')) {
+      target.setAttribute('init_x', target.offsetLeft)
+      target.setAttribute('init_y', target.offsetTop)
+    }
+
+    const initX = parseInt(target.getAttribute('init_x'))
+    const initY = parseInt(target.getAttribute('init_y'))
+
+    // 鼠标按下,计算当前元素距离可视区的距离
+    const disX = e.clientX - target.offsetLeft
+    const disY = e.clientY - target.offsetTop
+    document.onmousemove = e => {
+      // 通过事件委托,计算移动的距离
+      // 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
+      const l = e.clientX - disX
+      const t = e.clientY - disY
+      const { marginTop: mt, marginLeft: ml } = window.getComputedStyle(target)
+      // 计算移动当前元素的位置,并且给该元素样式中的left和top值赋值
+      target.style.left = l - parseInt(ml) + 'px'
+      target.style.top = (t < minTop ? minTop : t) - parseInt(mt) + 'px'
+      if (Math.abs(l - initX) > ifMoveSizeArea || Math.abs(t - initY) > ifMoveSizeArea) {
+        target.setAttribute('dragged', '')
+      } else {
+        target.removeAttribute('dragged')
+      }
+    }
+    document.onmouseup = e => {
+      document.onmousemove = null
+      document.onmouseup = null
+      document.onselectstart = null
+    }
+    // return false不加的话可能导致黏连,拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
+    return false
+  }
+})
 Vue.use(directive)
 Vue.use(plugins)
 Vue.use(VueMeta)

+ 112 - 106
ruoyi-ui/src/views/bd/roomlocation/roommap/index.vue

@@ -1,35 +1,38 @@
 <template>
   <el-dialog
-      title="室内定位融合"
-      :visible.sync="centerDialogVisible"
-      width="70vw"
-      @closed="onDialogClose"
-      @opened="play"
-      center>
-    <div style="width: 100%;height: 70vh;">
-      <bd-map :loaded="loaded" map-id="room-map" />
+    title="室内定位融合"
+    :visible.sync="centerDialogVisible"
+    width="70vw"
+    @closed="onDialogClose"
+    @opened="play"
+    center>
+    <div style="width: 100%;height: 70vh;position: relative">
+      <bd-map :loaded="loaded" map-id="room-map"/>
+      <video-p ref="videoP"/>
       <socket-message
-          v-if="centerDialogVisible"
-          :key="`device_uwb001`" :onMessage="onMessage"
-          :ws="`/ws/point/uwb001`"></socket-message>
+        v-if="centerDialogVisible"
+        :key="`device_uwb001`" :onMessage="onMessage"
+        :ws="`/ws/point/uwb001`"></socket-message>
     </div>
-
   </el-dialog>
 </template>
 
 <script>
 
-import { pushDevcLocation } from '@/api/bd/fenceInfo';
+import {listFenceInfo, pushDevcLocation} from '@/api/bd/fenceInfo';
 import SocketMessage from '@/components/WebsocketMessage/index.vue';
 import BdMap from '@/views/bd/map/index.vue';
 import maphandle from '@/views/bd/map/maphandle';
 import position from '@/views/bd/realtimeLocation/icon/position.png';
 import dayjs from 'dayjs';
+import VideoP from "@/views/bd/roomlocation/roommap/video/video.vue";
+// import {uuid} from "@/utils";
 
 export default {
   name: 'room-map',
   mixins: [maphandle],
   components: {
+    VideoP,
     BdMap,
     SocketMessage,
   },
@@ -39,18 +42,19 @@ export default {
       locationMarkers: {},
       mapIns: null,
       playInterval: null,
+      fencePolyLayer: null,
     };
   },
   // 组件卸载前清空图层信息
   beforeDestroy() {
-    this.markLayer && window.map.removeLayersById('markerLayer');
+    this.markLayer && this.mapIns.removeLayersById('markerLayer');
+    this.fencePolyLayer && this.fencePolyLayer.cust.clearLayer()
     this.playInterval && clearInterval(this.playInterval);
   },
   created() {
 
   },
   mounted() {
-
   },
   methods: {
     dayjs,
@@ -68,7 +72,9 @@ export default {
       map.addCustomLayers(this.markLayer);
       this.mapIns = map;
       map.setPitch(0);
-      map.setCenter([118.86895,32.01326]);
+      map.setCenter([118.86895, 32.01326]);
+      this.fencePolyLayer = this.createLayer(map);
+      this.getFenceList();
     },
     show() {
       this.centerDialogVisible = true;
@@ -80,23 +86,60 @@ export default {
         deviceId,
       } = data;
       const marker = new BDLayers.Lib.Overlays.MarkerImg(
-          `marker${deviceId}`,
-          [longitude, latitude],
-          {
-            imgurl: position,
-            iconSize: [25, 30],
-            symbol: {
-              'textName': 'm4',
-              'textSize': 14,
-              'markerFile': position,
-              'markerHorizontalAlignment': 'middle', // left, middle(默认), right
-              'markerVerticalAlignment': 'middle', // top, middle, bottom(默认)
-            },
+        `marker${deviceId}`,
+        [longitude, latitude],
+        {
+          imgurl: position,
+          iconSize: [25, 30],
+          symbol: {
+            'textName': 'm4',
+            'textSize': 14,
+            'markerFile': position,
+            'markerHorizontalAlignment': 'middle', // left, middle(默认), right
+            'markerVerticalAlignment': 'middle', // top, middle, bottom(默认)
           },
+        },
       );
       this.markLayer.addMarker(marker);
       return marker;
     },
+    async getFenceList() {
+      const {rows} = await listFenceInfo({
+        pageNum: 1,
+        pageSize: 10,
+        fenceType: 2,
+      });
+      if (!rows || rows.length < 1) {
+        return;
+      }
+      const result = [];
+      rows.forEach(item => {
+        const {
+          id,
+          defenceName,
+          poly,
+        } = item;
+        const polygon = this.drawPoly({
+          name: defenceName,
+          coordinates: this.polygonToCoordinates(poly),
+          symbol: {
+            lineColor: 'rgba(241,0,23,0.49)',
+            lineWidth: 2,
+            polygonFill: 'rgba(241,0,23,0.49)',
+            polygonOpacity: 0.4,
+          },
+          bizAttr: {
+            id,
+            name: defenceName,
+          },
+        }, this.fencePolyLayer);
+        result.push({
+          id,
+          name: defenceName,
+          polygon,
+        });
+      });
+    },
     onMessage(a) {
       const data = JSON.parse(a.data);
       const {
@@ -109,7 +152,7 @@ export default {
         this.locationMarkers[deviceId] = this.addMarker(data);
         return;
       }
-      this.locationMarkers[deviceId].moveMarker([longitude, latitude], 2000, false);
+      this.locationMarkers[deviceId].moveMarker([longitude, latitude], 1500, false);
     },
     play() {
       if (!this.mapIns) {
@@ -117,91 +160,54 @@ export default {
       }
       this.mapIns.setZoom(22)
       const gps = [
-        [118.869125003231, 32.0132579193923],
-        [118.869114609672, 32.0132582036815],
-        [118.869115950776, 32.013238303438],
-        [118.869116286052, 32.0132195403474],
-        [118.869116286052, 32.0132144231402],
-        [118.869113939119, 32.0132064630396],
-        [118.869105557216, 32.0132021986996],
-        [118.869093822552, 32.0132021986996],
-        [118.869086111201, 32.0132021986996],
-        [118.869077394021, 32.0132021986996],
-        [118.869073370708, 32.0132021986996],
-        [118.869070688499, 32.0132044730143],
-        [118.869070353223, 32.013218118901],
-        [118.869070353223, 32.0132323333641],
-        [118.869071359051, 32.0132479692711],
-        [118.869069012118, 32.0132536550547],
-        [118.869064988805, 32.0132579193923],
-        [118.869048224998, 32.0132570665248],
-        [118.869028778983, 32.0132570665248],
-        [118.869008327139, 32.0132525178981],
-        [118.868998939408, 32.0132579193923],
-        [118.868995586647, 32.0132604779947],
-        [118.868992233885, 32.0132604779947],
-        [118.868991228057, 32.0132621837296],
-        [118.868982510878, 32.0132601937055],
-        [118.868976140631, 32.0132601937055],
-        [118.868968764556, 32.0132607622839],
-        [118.868963735414, 32.0132607622839],
-        [118.868965411795, 32.0132525178981],
-        [118.868965747071, 32.0132394405949],
-        [118.868965747071, 32.0132334705211],
-        [118.868966082347, 32.0132127174044],
-        [118.868965747071, 32.0132036201463],
-        [118.868976811183, 32.0132002086742],
-        [118.868985193087, 32.0132056101716],
-        [118.868987204743, 32.0132175503224],
-        [118.86898485781, 32.0132354605458],
-        [118.868985528363, 32.0132402934625],
-        [118.868999274684, 32.0132445578007],
-        [118.869013021005, 32.0132439892223],
-        [118.869029784811, 32.0132454106683],
-        [118.869033472849, 32.0132431363547],
-        [118.869036155058, 32.0132391563057],
-        [118.869036155058, 32.0132320490749],
-        [118.869037160886, 32.0132215303724],
-        [118.869035484506, 32.0132067473289],
-        [118.869035484506, 32.0132002086742],
-        [118.86902039708, 32.0131987872275],
-        [118.869002962721, 32.0131993558062],
-        [118.868989551676, 32.0131993558062],
-        [118.868975805355, 32.0131982186489],
-        [118.86896239431, 32.0131976500702],
-        [118.868952336026, 32.0131976500702],
-        [118.868940266086, 32.0131996400956],
-        [118.868936913324, 32.0131996400956],
-        [118.868934231115, 32.0131996400956],
-        [118.868921155346, 32.0131999243849],
-        [118.868917132033, 32.0132010615423],
-        [118.868910091234, 32.013200777253],
-        [118.868910091234, 32.0132138545616],
-        [118.868909085406, 32.0132272161577],
-        [118.868909755958, 32.0132391563057],
-        [118.868910091234, 32.0132488221386],
-        [118.868910761786, 32.013257350814],
-        [118.868909755958, 32.0132636051754],
-        [118.868942277742, 32.0132627523079],
-        [118.868973123146, 32.0132644580428],
-        [118.869001621617, 32.0132638894645],
-        [118.869058618558, 32.0132636051754],
-        [118.869081082059, 32.0132624680188],
-        [118.869094157828, 32.0132624680188],
-        [118.869112933291, 32.0132624680188],
-        [118.869124332679, 32.0132604779947],
-        [118.869125003231, 32.0132579193923],
-      ];
+        [118.868928794571, 32.0132512031322],
+        [118.868928459294, 32.0132364200935],
+        [118.868929129847, 32.0132159512668],
+        [118.868929129847, 32.0132108340593],
+        [118.868968021877, 32.0132017368011],
+        [118.868968021877, 32.0132185098704],
+        [118.868967016049, 32.0132259013915],
+        [118.868966680773, 32.0132313028872],
+        [118.868967016049, 32.0132440959023],
+        [118.86897908599, 32.0132523402889],
+        [118.868979756542, 32.0132458016376],
+        [118.868983444579, 32.0132352829366],
+        [118.868990820654, 32.0132375572504],
+        [118.868992497035, 32.0132440959023],
+        [118.869004566975, 32.0132483602403],
+        [118.869005572804, 32.013257457494],
+        [118.8690266952, 32.0132577417831],
+        [118.869029712685, 32.0132577417831],
+        [118.869031724342, 32.0132577417831],
+        [118.869032394894, 32.0132625746988],
+        [118.868924100705, 32.0132523402889]
+      ]
       let i = 0;
       this.playInterval && clearInterval(this.playInterval);
       this.playInterval = setInterval(() => {
+        if (i === 0) {
+          this.$refs.videoP.play();
+        }
         pushDevcLocation({
           devcKey: 'uwb001',
           lat: gps[i][1],
           lng: gps[i][0],
         });
-        if (i === gps.length - 1) {
-          i = 0;
+        // this.onMessage({
+        //       data: JSON.stringify({
+        //         latitude: gps[i][1],
+        //         longitude: gps[i][0],
+        //         deviceId: 'uwb001',
+        //       })
+        //     }
+        // );
+        // var marker = new BDLayers.Lib.Overlays.MarkerIcon(`marker${uuid()}`, gps[i], {
+        //   iconSize: 45,
+        //   iconColor: 'red',
+        //   labelText: `${i}`
+        // });
+        // marker.getMarker().addTo(this.mapIns.map);
+        if (i === gps.length - 2) {
           return;
         }
         i++;

+ 13 - 0
ruoyi-ui/src/views/bd/roomlocation/roommap/video/index.scss

@@ -0,0 +1,13 @@
+.drag-video-container {
+  position: absolute;
+  border-radius: 10px;
+  top: 0px;
+  .video-title {
+    height: 30px;
+    width: 100%;
+    background: #fefefe;
+    padding: 0 15px;
+    line-height: 30px;
+    cursor: move;
+  }
+}

BIN
ruoyi-ui/src/views/bd/roomlocation/roommap/video/output.mp4


BIN
ruoyi-ui/src/views/bd/roomlocation/roommap/video/roomlocation.mp4


+ 129 - 0
ruoyi-ui/src/views/bd/roomlocation/roommap/video/video.vue

@@ -0,0 +1,129 @@
+<template>
+  <div v-drag class="drag-video-container">
+    <div class="video-title" style="">
+      西南角展厅监控
+    </div>
+    <video-player
+      style="width: 600px;height: 300px;"
+      ref="videoPlayer"
+      class="player-video"
+      :playsinline="false"
+      :options="playOptions"
+      @ready="onPlayerReady"
+      @play="onPlayerPlay($event)"
+      @pause="onPlayerPause($event)"
+      @ended="onPlayerEnd($event)"
+      @waiting="onPlayerWaiting($event)"
+      @playing="onPlayerPlaying($event)"
+      @loadeddata="onPlayerLoadeddata($event)"
+      @timeupdate="onPlayerTimeupdate($event)"
+      @statechanged="playerStateChanged($event)"
+    />
+  </div>
+</template>
+
+<script>
+
+export default {
+  name: "video-p",
+  props: {
+    path: {  // 传入的地址
+      type: String,
+      default: "",
+    },
+    lastTime: {  // 传入的上次播放位置
+      type: Number,
+      default: 0,
+    },
+  },
+  data() {
+    return {
+      playedTime: this.lastTime,
+      currentTime: 0,
+      maxTime: 0,
+      playOptions: {
+        height: "100px",
+        width: "200px",
+        playbackRates: [0.5], // 可选的播放速度
+        autoplay: false, // 如果为true,浏览器准备好时开始回放
+        muted: false, // 默认情况下静音播放
+        loop: false, // 是否视频一结束就重新开始
+        preload: "auto", // 建议浏览器在<video>加载元素后是否应该开始下载视频数据,auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
+        language: "zh-CN",
+        aspectRatio: "16:9", // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值,值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
+        fluid: true, // 当true时,Video.js player将拥有流体大小,换句话说,它将按比例缩放以适应其容器
+        sources: [
+          {
+            type: "video/mp4", // 类型
+            src: require("./output.mp4"), // url地址,在使用本地的资源时,需要用require()引入,否则控制台会报错
+          },
+        ],
+        notSupportedMessage: "此视频暂无法播放,请稍后再试", // 允许覆盖Video.js无法播放媒体源时显示的默认信息
+        controlBar: {
+          currentTimeDisplay: true,
+          progressControl: true,  // 是否显示进度条
+          playbackRateMenuButton: true, // 是否显示调整播放倍速按钮
+          timeDivider: true, // 当前时间和持续时间的分隔符
+          durationDisplay: true, // 显示持续时间
+          remainingTimeDisplay: true, // 是否显示剩余时间功能
+          fullscreenToggle: true, // 是否显示全屏按钮
+        },
+      },
+    };
+  },
+  computed: {},
+  mounted() {
+  },
+  methods: {
+    update() {
+
+    },
+    // 准备好了
+    onPlayerReady() {
+      console.log("准备好了");
+    },
+    // 视频播放
+    onPlayerPlay(player) {
+
+    },
+    // 视频暂停的
+    onPlayerPause(player) {
+
+    },
+    // 视频播放完
+    onPlayerEnd(player) {
+
+    },
+    // DOM元素上的readyState更改导致播放停止
+    onPlayerWaiting(player) {
+
+    },
+    // 视频已开始播放
+    onPlayerPlaying(player) {
+
+    },
+    // 当播放器在当前播放位置下载数据时触发
+    onPlayerLoadeddata(player) {
+
+    },
+    // 当前播放位置发生变化时触发
+    onPlayerTimeupdate(player) {
+
+    },
+    //播放状态改变
+    playerStateChanged(playerCurrentState) {
+      console.log("播放状态变化了");
+      console.log(playerCurrentState);
+    },
+    // 手动暂停视频的播放
+    pause() {
+      // 视频播放器的方法调用,要使用this.$refs.videoPlayer.player这个对象去调用
+      this.$refs.videoPlayer.player.pause()
+    },
+    play() {
+      this.$refs.videoPlayer.player.play()
+    },
+  },
+};
+</script>
+<style lang="scss" src="./index.scss"/>

+ 1 - 1
ruoyi-ui/version

@@ -1 +1 @@
-2.2
+3.0