From 9b9a13ab36fe93153148a489436e04b12aabcdd6 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期一, 09 一月 2023 16:31:51 +0800
Subject: [PATCH] 国标录像UI重构

---
 web_src/static/css/iconfont.woff2                             |    0 
 web_src/src/components/console.vue                            |   13 
 web_src/src/components/channelList.vue                        |    4 
 web_src/src/components/dialog/devicePlayer.vue                |  291 -------------------
 web_src/src/components/GBRecordDetail.vue                     |  495 +++++++++++++++++++++++++++++++++
 src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java |    4 
 web_src/src/components/console/ConsoleResource.vue            |   12 
 web_src/src/router/index.js                                   |    6 
 web_src/static/css/iconfont.css                               |   14 
 web_src/src/components/CloudRecordDetail.vue                  |   17 +
 10 files changed, 551 insertions(+), 305 deletions(-)

diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java b/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
index 5f4ac22..d1e61c0 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
@@ -10,6 +10,7 @@
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
+import org.springframework.util.ObjectUtils;
 import org.springframework.web.filter.OncePerRequestFilter;
 
 import javax.servlet.*;
@@ -51,6 +52,9 @@
 
             LogDto logDto = new LogDto();
             logDto.setName(uriName);
+            if (ObjectUtils.isEmpty(username)) {
+                username = "";
+            }
             logDto.setUsername(username);
             logDto.setAddress(servletRequest.getRemoteAddr());
             logDto.setResult(HttpStatus.valueOf(servletResponse.getStatus()).toString());
diff --git a/web_src/src/components/CloudRecordDetail.vue b/web_src/src/components/CloudRecordDetail.vue
index 143448e..8d04eb0 100644
--- a/web_src/src/components/CloudRecordDetail.vue
+++ b/web_src/src/components/CloudRecordDetail.vue
@@ -30,7 +30,7 @@
       </el-aside>
 			<el-main style="padding: 22px">
         <div class="playBox" :style="playerStyle">
-          <player ref="recordVideoPlayer" :videoUrl="videoUrl"  fluent autoplay :height="true" ></player>
+          <player ref="recordVideoPlayer" :videoUrl="videoUrl" :height="true" style="width: 100%" ></player>
         </div>
         <div class="player-option-box" >
           <el-slider
@@ -310,7 +310,20 @@
         let h = parseInt(val/3600);
         let m = parseInt((val - h*3600)/60);
         let s = parseInt(val - h*3600 - m*60);
-        return h + ":" + m + ":" + s
+
+        let hStr = h;
+        let mStr = m;
+        let sStr = s;
+        if (h < 10) {
+          hStr = "0" + hStr;
+        }
+        if (m < 10) {
+          mStr = "0" + mStr;s
+        }
+        if (s < 10) {
+          sStr = "0" + sStr;
+        }
+        return hStr + ":" + mStr + ":" + sStr
       },
       deleteRecord(){
 			  // TODO
diff --git a/web_src/src/components/GBRecordDetail.vue b/web_src/src/components/GBRecordDetail.vue
new file mode 100644
index 0000000..feb2443
--- /dev/null
+++ b/web_src/src/components/GBRecordDetail.vue
@@ -0,0 +1,495 @@
+<template>
+	<div style="width: 100%">
+    <div class="page-header" >
+      <div class="page-title">
+        <el-page-header @back="goBack" content="鍥芥爣褰曞儚"></el-page-header>
+      </div>
+    </div>
+		<el-container>
+      <el-aside width="300px">
+        <div class="record-list-box-box">
+          <el-date-picker size="mini" v-model="chooseDate" type="date" value-format="yyyy-MM-dd" placeholder="鏃ユ湡" @change="dateChange()"></el-date-picker>
+          <div class="record-list-box" v-loading="recordsLoading" :style="recordListStyle">
+            <ul v-if="detailFiles.length >0" class="infinite-list record-list" >
+              <li v-for="item in detailFiles" class="infinite-list-item record-list-item" >
+
+                <el-tag v-if="chooseFile != item" @click="checkedFile(item)">
+                  <i class="el-icon-video-camera"  ></i>
+                  {{ moment(item.startTime).format('HH:mm:ss')}}-{{ moment(item.endTime).format('HH:mm:ss')}}
+                </el-tag>
+                <el-tag v-if="chooseFile == item" type="danger" >
+                  <i class="el-icon-video-camera"  ></i>
+                  {{ moment(item.startTime).format('HH:mm:ss')}}-{{ moment(item.endTime).format('HH:mm:ss')}}
+                </el-tag>
+                <i style="color: #409EFF;margin-left: 5px;" class="el-icon-download" @click="downloadRecord(item)" ></i>
+              </li>
+            </ul>
+          </div>
+          <div size="mini" v-if="detailFiles.length ==0" class="record-list-no-val" >鏆傛棤鏁版嵁</div>
+        </div>
+
+      </el-aside>
+			<el-main style="padding-bottom: 10px;">
+        <div class="playBox" :style="playerStyle">
+          <player ref="recordVideoPlayer"
+                  :videoUrl="videoUrl"
+                  :error="videoError"
+                  :message="videoError"
+                  :hasAudio="hasAudio"
+                  style="max-height: 100%"
+                  fluent autoplay live ></player>
+        </div>
+        <div class="player-option-box">
+          <div>
+            <el-button-group >
+              <el-button size="mini" class="iconfont icon-zanting" title="寮�濮�" @click="gbPause()"></el-button>
+              <el-button size="mini" class="iconfont icon-kaishi" title="鏆傚仠" @click="gbPlay()"></el-button>
+              <el-dropdown size="mini" title="鎾斁鍊嶉��" style="margin-left: 1px;" @command="gbScale">
+                <el-button size="mini">
+                  鍊嶉�� <i class="el-icon-arrow-down el-icon--right"></i>
+                </el-button>
+                <el-dropdown-menu  slot="dropdown">
+                  <el-dropdown-item command="0.25">0.25鍊嶉��</el-dropdown-item>
+                  <el-dropdown-item command="0.5">0.5鍊嶉��</el-dropdown-item>
+                  <el-dropdown-item command="1.0">1鍊嶉��</el-dropdown-item>
+                  <el-dropdown-item command="2.0">2鍊嶉��</el-dropdown-item>
+                  <el-dropdown-item command="4.0">4鍊嶉��</el-dropdown-item>
+                </el-dropdown-menu>
+              </el-dropdown>
+              <el-button size="mini" class="iconfont icon-xiazai1" title="涓嬭浇閫夊畾褰曞儚" @click="downloadRecord()"></el-button>
+              <el-button v-if="sliderMIn === 0 && sliderMax === 86400" size="mini" class="iconfont icon-slider" title="鏀惧ぇ婊戝潡" @click="setSliderFit()"></el-button>
+              <el-button v-if="sliderMIn !== 0 || sliderMax !== 86400" size="mini" class="iconfont icon-slider-right" title="鎭㈠婊戝潡" @click="setSliderFit()"></el-button>
+            </el-button-group>
+          </div>
+          <el-slider
+            class="playtime-slider"
+            v-model="playTime"
+            id="playtimeSlider"
+            :disabled="detailFiles.length === 0"
+            :min="sliderMIn"
+            :max="sliderMax"
+            :range="true"
+            :format-tooltip="playTimeFormat"
+            @change="playTimeChange"
+            :marks="playTimeSliderMarks">
+          </el-slider>
+          <div class="slider-val-box">
+            <div class="slider-val" v-for="item of detailFiles" :style="'width:'  +  getDataWidth(item) + '%; left:' + getDataLeft(item) + '%'"></div>
+          </div>
+        </div>
+
+			</el-main>
+		</el-container>
+    <recordDownload ref="recordDownload"></recordDownload>
+	</div>
+</template>
+
+
+<script>
+	import uiHeader from '../layout/UiHeader.vue'
+  import player from './common/jessibuca.vue'
+  import moment  from 'moment'
+  import recordDownload from './dialog/recordDownload.vue'
+	export default {
+		name: 'app',
+		components: {
+			uiHeader, player,recordDownload
+		},
+		data() {
+			return {
+        deviceId: this.$route.params.deviceId,
+        channelId: this.$route.params.channelId,
+        recordsLoading: false,
+        sliderTime: 0,
+        seekTime: 0,
+        recordStartTime: 0,
+        streamId: "",
+        hasAudio: false,
+			  detailFiles: [],
+        chooseDate: null,
+        videoUrl: null,
+        chooseFile: null,
+        streamInfo: null,
+        app: null,
+        mediaServerId: null,
+        ssrc: null,
+
+        sliderMIn: 0,
+        sliderMax: 86400,
+        autoPlay: true,
+        taskUpdate: null,
+        tabVal: "running",
+        recordListStyle: {
+			    height: this.winHeight + "px",
+          overflow: "auto",
+          margin: "10px auto 10px auto"
+        },
+        playerStyle: {
+			    "margin": "0 auto 20px auto",
+          "height": this.winHeight + "px",
+        },
+        winHeight: window.innerHeight - 240,
+        playTime: 0,
+        playTimeSliderMarks: {
+			    0: "00:00",
+			    3600: "01:00",
+			    7200: "02:00",
+			    10800: "03:00",
+			    14400: "04:00",
+			    18000: "05:00",
+			    21600: "06:00",
+			    25200: "07:00",
+			    28800: "08:00",
+			    32400: "09:00",
+			    36000: "10:00",
+          39600: "11:00",
+			    43200: "12:00",
+			    46800: "13:00",
+			    50400: "14:00",
+			    54000: "15:00",
+			    57600: "16:00",
+			    61200: "17:00",
+			    64800: "18:00",
+			    68400: "19:00",
+          72000: "20:00",
+			    75600: "21:00",
+			    79200: "22:00",
+			    82800: "23:00",
+          86400: "24:00",
+        },
+			};
+		},
+		computed: {
+
+		},
+		mounted() {
+      this.recordListStyle.height = this.winHeight + "px";
+      this.playerStyle["height"] = this.winHeight + "px";
+      this.chooseDate = moment().format('YYYY-MM-DD')
+      this.dateChange();
+		},
+		destroyed() {
+			this.$destroy('recordVideoPlayer');
+		},
+		methods: {
+      dateChange(){
+        if (!this.chooseDate) {
+          return;
+        }
+        this.recordsLoading = true;
+        this.detailFiles = [];
+        let startTime = this.chooseDate + " 00:00:00";
+        let endTime = this.chooseDate + " 23:59:59";
+        this.$axios({
+          method: 'get',
+          url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + startTime + '&endTime=' + endTime
+        }).then((res)=>{
+          this.recordsLoading = false;
+          if(res.data.code === 0) {
+            // 澶勭悊鏃堕棿淇℃伅
+            this.detailFiles = res.data.data.recordList;
+
+          }else {
+            this.$message({
+              showClose: true,
+              message: res.data.msg,
+              type: "error",
+            });
+          }
+
+        }).catch((e)=> {
+          this.recordsLoading = false;
+          // that.videoHistory.searchHistoryResult = falsificationData.recordData;
+        });
+      },
+      moment: function (v) {
+        return moment(v)
+      },
+      videoError: function (e) {
+        console.log("鎾斁鍣ㄩ敊璇細" + JSON.stringify(e));
+      },
+      checkedFile(file){
+        this.chooseFile = file;
+			  // 寮�濮嬪洖鏀�
+        this.playRecord(file)
+
+      },
+      playRecord: function (row) {
+
+        let startTime = row.startTime
+        this.recordStartTime = row.startTime
+        this.showTimeText =  row.startTime.split(" ")[1]
+        let endTime = row.endTime
+        this.sliderTime = 0;
+        this.seekTime = new Date(endTime).getTime() - new Date(startTime).getTime();
+        if (this.streamId !== "") {
+          this.stopPlayRecord(()=> {
+            this.streamId = "";
+            this.playRecord(row);
+          })
+        } else {
+          this.$axios({
+            method: 'get',
+            url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + startTime + '&endTime=' +
+              endTime
+          }).then((res)=> {
+            if (res.data.code === 0) {
+              this.streamInfo = res.data.data;
+              this.app = this.streamInfo.app;
+              this.streamId = this.streamInfo.stream;
+              this.mediaServerId = this.streamInfo.mediaServerId;
+              this.ssrc = this.streamInfo.ssrc;
+              this.videoUrl = this.getUrlByStreamInfo();
+            }else {
+              this.$message({
+                showClose: true,
+                message: res.data.msg,
+                type: "error",
+              });
+            }
+          });
+        }
+      },
+      gbPlay(){
+        console.log('鍓嶇鎺у埗锛氭挱鏀�');
+        this.$axios({
+          method: 'get',
+          url: '/api/playback/resume/' + this.streamId
+        }).then((res)=> {
+          this.$refs[this.activePlayer].play(this.videoUrl)
+        });
+      },
+      gbPause(){
+        console.log('鍓嶇鎺у埗锛氭殏鍋�');
+        this.$axios({
+          method: 'get',
+          url: '/api/playback/pause/' + this.streamId
+        }).then(function (res) {});
+      },
+      gbScale(command){
+        console.log('鍓嶇鎺у埗锛氬�嶉�� ' + command);
+        this.$axios({
+          method: 'get',
+          url: `/api/playback/speed/${this.streamId }/${command}`
+        }).then(function (res) {});
+      },
+      downloadRecord: function (row) {
+        if (!row) {
+          let startTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + this.playTime[0]*1000).format("YYYY-MM-DD HH:mm:ss");
+          let endTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + this.playTime[1]*1000).format("YYYY-MM-DD HH:mm:ss");
+          console.log(startTimeStr);
+          console.log(endTimeStr);
+          row = {
+            startTime: startTimeStr,
+            endTime: endTimeStr
+          }
+        }
+        if (this.streamId !== "") {
+          this.stopPlayRecord(()=> {
+            this.streamId = "";
+            this.downloadRecord(row);
+          })
+        }else {
+          this.$axios({
+            method: 'get',
+            url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
+              row.endTime + '&downloadSpeed=4'
+          }).then( (res)=> {
+            if (res.data.code === 0) {
+              let streamInfo = res.data.data;
+              this.$refs.recordDownload.openDialog(this.deviceId, this.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId);
+            }else {
+              this.$message({
+                showClose: true,
+                message: res.data.msg,
+                type: "error",
+              });
+            }
+          });
+        }
+      },
+      stopDownloadRecord: function (callback) {
+        this.$refs["recordVideoPlayer"].pause();
+        this.videoUrl = '';
+        this.$axios({
+          method: 'get',
+          url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
+        }).then((res)=> {
+          if (callback) callback(res)
+        });
+      },
+      stopPlayRecord: function (callback) {
+        this.$refs["recordVideoPlayer"].pause();
+        this.videoUrl = '';
+        this.$axios({
+          method: 'get',
+          url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
+        }).then(function (res) {
+          if (callback) callback()
+        });
+      },
+      getDataWidth(item){
+        let timeForFile = this.getTimeForFile(item);
+        let result = (timeForFile[2])/((this.sliderMax - this.sliderMIn)*1000)
+        return result*100
+      },
+      getDataLeft(item){
+        let timeForFile = this.getTimeForFile(item);
+        let differenceTime = timeForFile[0].getTime() - new Date(this.chooseDate + " 00:00:00").getTime()
+        return parseFloat((differenceTime - this.sliderMIn * 1000)/((this.sliderMax - this.sliderMIn)*1000))*100   ;
+      },
+      getUrlByStreamInfo(){
+        if (location.protocol === "https:") {
+          this.videoUrl = this.streamInfo["wss_flv"]
+        }else {
+          this.videoUrl = this.streamInfo["ws_flv"]
+        }
+        return this.videoUrl;
+
+      },
+      playTimeChange(val){
+        console.log(val)
+        let maxTime = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1])[1];
+
+        let startTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + val[0]*1000).format("YYYY-MM-DD HH:mm:ss");
+        let endTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + val[1]*1000).format("YYYY-MM-DD HH:mm:ss");
+        console.log(startTimeStr);
+        console.log(endTimeStr);
+
+        this.checkedFile({
+          startTime: startTimeStr,
+          endTime: endTimeStr,
+        });
+      },
+      setSliderFit() {
+        if (this.sliderMIn === 0 && this.sliderMax === 86400) {
+          if (this.detailFiles.length > 0){
+            let timeForFile = this.getTimeForFile(this.detailFiles[0]);
+            let lastTimeForFile = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1]);
+            let timeNum = timeForFile[0].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime()
+            let lastTimeNum = lastTimeForFile[1].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime()
+
+            this.playTime = parseInt(timeNum/1000)
+            this.sliderMIn = parseInt(timeNum/1000 - timeNum/1000%(60*60))
+            this.sliderMax = parseInt(lastTimeNum/1000 - lastTimeNum/1000%(60*60)) + 60*60
+
+            this.playTime = [this.sliderMIn, this.sliderMax];
+          }
+        }else {
+          this.sliderMIn = 0;
+          this.sliderMax = 86400;
+        }
+      },
+      getTimeForFile(file){
+        let startTime = new Date(file.startTime);
+        let endTime = new Date(file.endTime);
+        return [startTime, endTime, endTime.getTime() - startTime.getTime()];
+      },
+      playTimeFormat(val){
+        let h = parseInt(val/3600);
+        let m = parseInt((val - h*3600)/60);
+        let s = parseInt(val - h*3600 - m*60);
+
+        let hStr = h;
+        let mStr = m;
+        let sStr = s;
+        if (h < 10) {
+          hStr = "0" + hStr;
+        }
+        if (m < 10) {
+          mStr = "0" + mStr;s
+        }
+        if (s < 10) {
+          sStr = "0" + sStr;
+        }
+        return hStr + ":" + mStr + ":" + sStr
+      },
+      goBack(){
+        window.history.go(-1);
+      }
+		}
+	};
+</script>
+
+<style>
+  .el-slider__runway {
+    background-color:rgba(206, 206, 206, 0.47) !important;
+  }
+  .el-slider__bar {
+    background-color: rgba(153, 153, 153, 0) !important;
+  }
+  .playtime-slider {
+    position: relative;
+    z-index: 100;
+  }
+  .data-picker-true{
+
+  }
+  .data-picker-true:after{
+    content: "";
+    position: absolute;
+    width: 4px;
+    height: 4px;
+    background-color: #606060;
+    border-radius: 4px;
+    left: 45%;
+    top: 74%;
+
+  }
+  .data-picker-false{
+
+  }
+  .slider-val-box{
+    height: 6px;
+    position: relative;
+    top: -22px;
+  }
+  .slider-val{
+    height: 6px;
+    background-color: #007CFF;
+    position: absolute;
+  }
+  .record-list-box-box{
+    width: 250px;
+    float: left;
+  }
+  .record-list-box{
+    overflow: auto;
+    width: 220px;
+    list-style: none;
+    padding: 0;
+    margin: 0;
+    margin-top: 0px;
+    padding: 1rem 0;
+    background-color: #FFF;
+    margin-top: 10px;
+  }
+  .record-list{
+    list-style: none;
+    padding: 0;
+    margin: 0;
+    background-color: #FFF;
+
+  }
+  .record-list-no-val {
+    position: absolute;
+    color: #9f9f9f;
+    top: 50%;
+    left: 110px;
+  }
+  .record-list-item{
+    padding: 0;
+    margin: 0;
+    margin: 0.5rem 0;
+    cursor: pointer;
+  }
+  .record-list-option {
+    width: 10px;
+    float: left;
+    margin-top: 39px;
+
+  }
+  .player-option-box{
+    padding: 0 20px;
+  }
+</style>
diff --git a/web_src/src/components/channelList.vue b/web_src/src/components/channelList.vue
index 136ddfe..f020f34 100644
--- a/web_src/src/components/channelList.vue
+++ b/web_src/src/components/channelList.vue
@@ -269,10 +269,10 @@
       });
     },
     queryRecords: function (itemData) {
-      var format = moment().format("yyyy-MM-DD");
       let deviceId = this.deviceId;
       let channelId = itemData.channelId;
-      this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format})
+
+      this.$router.push(`/gbRecordDetail/${deviceId}/${channelId}`)
     },
     stopDevicePush: function (itemData) {
       var that = this;
diff --git a/web_src/src/components/console.vue b/web_src/src/components/console.vue
index 6e2dd83..e192fb1 100644
--- a/web_src/src/components/console.vue
+++ b/web_src/src/components/console.vue
@@ -101,11 +101,14 @@
         window.clearTimeout(this.timer);
       }
       this.timer = setTimeout(()=>{
-        this.getSystemInfo();
-        this.getLoad();
-        this.timer = null;
-        this.loopForSystemInfo()
-        this.getResourceInfo()
+        if (this.$route.path === "/console") {
+          this.getSystemInfo();
+          this.getLoad();
+          this.timer = null;
+          this.loopForSystemInfo()
+          this.getResourceInfo()
+        }
+
       }, 2000)
     },
     getSystemInfo: function (){
diff --git a/web_src/src/components/console/ConsoleResource.vue b/web_src/src/components/console/ConsoleResource.vue
index bc307b9..3aa7771 100644
--- a/web_src/src/components/console/ConsoleResource.vue
+++ b/web_src/src/components/console/ConsoleResource.vue
@@ -1,28 +1,32 @@
 <template >
   <div id="consoleResource" style="width: 100%; height: 100%; background: #FFFFFF; text-align: center">
     <div style="width: 50%;height: 50%; float:left; ">
-      <el-progress :width="100" :stroke-width="8" type="circle" :percentage="Math.floor(deviceInfo.online/deviceInfo.total*100)" style="margin-top: 20px; font-size: 18px"></el-progress>
+      <el-progress v-if="deviceInfo.total > 0" :width="100" :stroke-width="8" type="circle" :percentage="Math.floor(deviceInfo.online/deviceInfo.total*100)" style="margin-top: 20px; font-size: 18px"></el-progress>
+      <el-progress v-if="deviceInfo.total === 0" :width="100" :stroke-width="8" type="circle" :percentage="0" style="margin-top: 20px; font-size: 18px"></el-progress>
       <div class="resourceInfo">
         璁惧鎬绘暟:{{deviceInfo.total}}<br/>
         鍦ㄧ嚎鏁�:{{deviceInfo.online}}
       </div>
     </div>
     <div style="width: 50%;height: 50%; float:left; ">
-      <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(channelInfo.online/channelInfo.total*100)" style="margin-top: 20px"></el-progress>
+      <el-progress v-if="channelInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(channelInfo.online/channelInfo.total*100)" style="margin-top: 20px"></el-progress>
+      <el-progress v-if="channelInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress>
       <div class="resourceInfo">
         閫氶亾鎬绘暟:{{channelInfo.total}}<br/>
         鍦ㄧ嚎鏁�:{{channelInfo.online}}
       </div>
     </div>
     <div style="width: 50%;height: 50%; float:left; ">
-      <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(pushInfo.online/pushInfo.total*100)" style="margin-top: 20px"></el-progress>
+      <el-progress v-if="pushInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(pushInfo.online/pushInfo.total*100)" style="margin-top: 20px"></el-progress>
+      <el-progress v-if="pushInfo.total === 0"  :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress>
       <div class="resourceInfo">
         鎺ㄦ祦鎬绘暟:{{pushInfo.total}}<br/>
         鍦ㄧ嚎鏁�:{{pushInfo.online}}
       </div>
     </div>
     <div style="width: 50%;height: 50%; float:left; ">
-      <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(proxyInfo.online/proxyInfo.total*100)" style="margin-top: 20px"></el-progress>
+      <el-progress v-if="proxyInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(proxyInfo.online/proxyInfo.total*100)" style="margin-top: 20px"></el-progress>
+      <el-progress v-if="proxyInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress>
       <div class="resourceInfo">
         鎷夋祦浠g悊鎬绘暟:{{proxyInfo.total}}<br/>
         鍦ㄧ嚎鏁�:{{proxyInfo.online}}
diff --git a/web_src/src/components/dialog/devicePlayer.vue b/web_src/src/components/dialog/devicePlayer.vue
index 9ecbb9b..e83a29c 100644
--- a/web_src/src/components/dialog/devicePlayer.vue
+++ b/web_src/src/components/dialog/devicePlayer.vue
@@ -23,11 +23,6 @@
         <div id="shared" style="text-align: right; margin-top: 1rem;">
             <el-tabs v-model="tabActiveName" @tab-click="tabHandleClick" >
                 <el-tab-pane label="瀹炴椂瑙嗛" name="media">
-                    <div style="margin-bottom: 0.5rem;">
-                        <!--		<el-button type="primary" size="small" @click="playRecord(true, '')">鎾斁</el-button>-->
-                        <!--		 <el-button type="primary" size="small" @click="startRecord()">褰曞埗</el-button>-->
-                        <!--		 <el-button type="primary" size="small" @click="stopRecord()">鍋滄褰曞埗</el-button>-->
-                    </div>
                     <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
                         <span style="width: 5rem; line-height: 2.5rem; text-align: right;">鎾斁鍦板潃锛�</span>
                         <el-input v-model="getPlayerShared.sharedUrl" :disabled="true" >
@@ -148,51 +143,6 @@
                     </div>
                 </el-tab-pane>
                 <!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->
-                <el-tab-pane label="褰曞儚鏌ヨ" name="record" v-if="showRrecord">
-                    <div style="width: 100%;">
-                      <div style="width: 100%; text-align: left">
-                        <span>褰曞儚鎺у埗</span>
-                        <el-button-group style="margin-left: 1rem;">
-                          <el-button size="mini" class="iconfont icon-zanting" title="寮�濮�" @click="gbPause()"></el-button>
-                          <el-button size="mini" class="iconfont icon-kaishi" title="鏆傚仠" @click="gbPlay()"></el-button>
-                          <el-dropdown size="mini" title="鎾斁鍊嶉��" style="margin-left: 1px;" @command="gbScale">
-                            <el-button size="mini">
-                              鍊嶉�� <i class="el-icon-arrow-down el-icon--right"></i>
-                            </el-button>
-                            <el-dropdown-menu  slot="dropdown">
-                              <el-dropdown-item command="0.25">0.25鍊嶉��</el-dropdown-item>
-                              <el-dropdown-item command="0.5">0.5鍊嶉��</el-dropdown-item>
-                              <el-dropdown-item command="1.0">1鍊嶉��</el-dropdown-item>
-                              <el-dropdown-item command="2.0">2鍊嶉��</el-dropdown-item>
-                              <el-dropdown-item command="4.0">4鍊嶉��</el-dropdown-item>
-                            </el-dropdown-menu>
-                          </el-dropdown>
-                        </el-button-group>
-                        <el-date-picker style="float: right;" size="mini" v-model="videoHistory.date" type="date" value-format="yyyy-MM-dd" placeholder="鏃ユ湡" @change="queryRecords()"></el-date-picker>
-                      </div>
-                      <div style="width: 100%; text-align: left">
-                        <span class="demonstration" style="padding: 12px 36px 12px 0;float: left;">{{showTimeText}}</span>
-                        <el-slider style="width: 80%; float:left;" v-model="sliderTime" @change="gbSeek" :show-tooltip="false"></el-slider>
-                      </div>
-                    </div>
-
-
-                    <el-table :data="videoHistory.searchHistoryResult" height="150" v-loading="recordsLoading">
-                        <el-table-column label="鍚嶇О" prop="name"></el-table-column>
-                        <el-table-column label="鏂囦欢" prop="filePath"></el-table-column>
-                        <el-table-column label="寮�濮嬫椂闂�" prop="startTime" :formatter="timeFormatter"></el-table-column>
-                        <el-table-column label="缁撴潫鏃堕棿" prop="endTime" :formatter="timeFormatter"></el-table-column>
-
-                        <el-table-column label="鎿嶄綔">
-                            <template slot-scope="scope">
-                                <el-button-group>
-                                    <el-button icon="el-icon-video-play" size="mini" @click="playRecord(scope.row)">鎾斁</el-button>
-                                    <el-button icon="el-icon-download" size="mini" @click="downloadRecord(scope.row)">涓嬭浇</el-button>
-                                </el-button-group>
-                            </template>
-                        </el-table-column>
-                    </el-table>
-                </el-tab-pane>
                 <!--閬ユ帶鐣岄潰-->
                 <el-tab-pane label="浜戝彴鎺у埗" name="control" v-if="showPtz">
                     <div style="display: flex; justify-content: left;">
@@ -286,21 +236,18 @@
             </el-tabs>
         </div>
     </el-dialog>
-    <recordDownload ref="recordDownload"></recordDownload>
 </div>
 </template>
 
 <script>
 import rtcPlayer from '../dialog/rtcPlayer.vue'
 import LivePlayer from '@liveqing/liveplayer'
-// import player from '../dialog/easyPlayer.vue'
 import jessibucaPlayer from '../common/jessibuca.vue'
-import recordDownload from '../dialog/recordDownload.vue'
 export default {
     name: 'devicePlayer',
     props: {},
     components: {
-      LivePlayer, jessibucaPlayer, rtcPlayer, recordDownload,
+      LivePlayer, jessibucaPlayer, rtcPlayer,
     },
     computed: {
         getPlayerShared: function () {
@@ -328,10 +275,6 @@
               livePlayer : ["ws_flv", "wss_flv"],
               webRTC: ["rtc", "rtcs"],
             },
-            videoHistory: {
-                date: '',
-                searchHistoryResult: [] //濯掍綋娴佸巻鍙茶褰曟悳绱㈢粨鏋�
-            },
             showVideoDialog: false,
             streamId: '',
             app : '',
@@ -357,7 +300,6 @@
             tracks: [],
             coverPlaying:false,
             tracksLoading: false,
-            recordPlay: "",
             showPtz: true,
             showRrecord: true,
             tracksNotLoaded: false,
@@ -418,11 +360,6 @@
                 case "media":
                     this.play(param.streamInfo, param.hasAudio)
                     break;
-                case "record":
-                    this.showVideoDialog = true;
-                    this.videoHistory.date = param.date;
-                    this.queryRecords()
-                    break;
                 case "streamPlay":
                     this.tabActiveName = "media";
                     this.showRrecord = false;
@@ -432,9 +369,6 @@
                 case "control":
                     break;
             }
-        },
-        timeAxisSelTime: function (val) {
-            console.log(val)
         },
         play: function (streamInfo, hasAudio) {
             this.streamInfo = streamInfo;
@@ -531,10 +465,6 @@
               this.convertStop();
             }
             this.convertKey = ''
-            if (this.recordPlay != '') {
-              this.stopPlayRecord();
-            }
-            this.recordPlay = ''
         },
 
         copySharedInfo: function (data) {
@@ -558,137 +488,6 @@
                     });
                 }
             );
-        },
-
-        queryRecords: function () {
-            if (!this.videoHistory.date) {
-                return;
-            }
-            this.recordsLoading = true;
-            this.videoHistory.searchHistoryResult = [];
-            let that = this;
-            var startTime = this.videoHistory.date + " 00:00:00";
-            var endTime = this.videoHistory.date + " 23:59:59";
-            this.$axios({
-                method: 'get',
-                url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + startTime + '&endTime=' + endTime
-            }).then(function (res) {
-                console.log(res)
-                that.recordsLoading = false;
-                if(res.data.code === 0) {
-                  // 澶勭悊鏃堕棿淇℃伅
-                  that.videoHistory.searchHistoryResult = res.data.data.recordList;
-                }else {
-                  this.$message({
-                    showClose: true,
-                    message: res.data.msg,
-                    type: "error",
-                  });
-                }
-
-            }).catch(function (e) {
-                console.log(e.message);
-                // that.videoHistory.searchHistoryResult = falsificationData.recordData;
-            });
-
-        },
-        onTimeChange: function (video) {
-            // this.queryRecords()
-        },
-        playRecord: function (row) {
-            let that = this;
-
-            let startTime = row.startTime
-            this.recordStartTime = row.startTime
-            this.showTimeText =  row.startTime.split(" ")[1]
-            let endtime = row.endTime
-            this.sliderTime = 0;
-            this.seekTime = new Date(endtime).getTime() - new Date(startTime).getTime();
-            console.log(this.seekTime)
-            if (that.streamId != "") {
-                that.stopPlayRecord(function () {
-                    that.streamId = "";
-                    that.playRecord(row);
-                })
-            } else {
-                this.$axios({
-                    method: 'get',
-                    url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
-                        row.endTime
-                }).then(function (res) {
-                  if (res.data.code === 0) {
-                    that.streamInfo = res.data.data;
-                    that.app = that.streamInfo.app;
-                    that.streamId = that.streamInfo.stream;
-                    that.mediaServerId = that.streamInfo.mediaServerId;
-                    that.ssrc = that.streamInfo.ssrc;
-                    that.videoUrl = that.getUrlByStreamInfo();
-                  }else {
-                    that.$message({
-                      showClose: true,
-                      message: res.data.msg,
-                      type: "error",
-                    });
-                  }
-                  that.recordPlay = true;
-                });
-            }
-        },
-        stopPlayRecord: function (callback) {
-          this.$refs[this.activePlayer].pause();
-            this.videoUrl = '';
-            this.$axios({
-                method: 'get',
-                url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
-            }).then(function (res) {
-                if (callback) callback()
-            });
-        },
-        downloadRecord: function (row) {
-            let that = this;
-            if (that.streamId != "") {
-                that.stopDownloadRecord(function (res) {
-                  if (res.code == 0) {
-                    that.streamId = "";
-                    that.downloadRecord(row);
-                  }else {
-                    this.$message({
-                      showClose: true,
-                      message: res.data.msg,
-                      type: "error",
-                    });
-                  }
-
-                })
-            } else {
-                this.$axios({
-                    method: 'get',
-                    url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
-                        row.endTime + '&downloadSpeed=4'
-                }).then(function (res) {
-                  if (res.data.code == 0) {
-                    let streamInfo = res.data.data;
-                    that.recordPlay = false;
-                    that.$refs.recordDownload.openDialog(that.deviceId, that.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId);
-                  }else {
-                    that.$message({
-                      showClose: true,
-                      message: res.data.msg,
-                      type: "error",
-                    });
-                  }
-                });
-            }
-        },
-        stopDownloadRecord: function (callback) {
-            this.$refs[this.activePlayer].pause();
-            this.videoUrl = '';
-            this.$axios({
-                method: 'get',
-                url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
-            }).then((res)=> {
-                if (callback) callback(res)
-            });
         },
         ptzCamera: function (command) {
             console.log('浜戝彴鎺у埗锛�' + command);
@@ -728,52 +527,6 @@
                 url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '&parameter1=' + groupNum + '&parameter2=' + parameter + '&combindCode2=0'
             }).then(function (res) {});
         },
-        formatTooltip: function (val) {
-            var h = parseInt(val / 60);
-            var hStr = h < 10 ? ("0" + h) : h;
-            var s = val % 60;
-            var sStr = s < 10 ? ("0" + s) : s;
-            return h + ":" + sStr;
-        },
-        timeFormatter: function (row, column, cellValue, index) {
-            return cellValue.split(" ")[1];
-        },
-        mergeTime: function (timeArray) {
-            var resultArray = [];
-            for (let i = 0; i < timeArray.length; i++) {
-                var startTime = new Date(timeArray[i].startTime);
-                var endTime = new Date(timeArray[i].endTime);
-                if (i == 0) {
-                    resultArray[0] = {
-                        startTime: startTime,
-                        endTime: endTime
-                    }
-                }
-                for (let j = 0; j < resultArray.length; j++) {
-                    if (startTime > resultArray[j].endTime) { // 鍚堝苟
-                        if (startTime - resultArray[j].endTime <= 1000) {
-                            resultArray[j].endTime = endTime;
-                        } else {
-                            resultArray[resultArray.length] = {
-                                startTime: startTime,
-                                endTime: endTime
-                            }
-                        }
-                    } else if (resultArray[j].startTime > endTime) { // 鍚堝苟
-                        if (resultArray[j].startTime - endTime <= 1000) {
-                            resultArray[j].startTime = startTime;
-                        } else {
-                            resultArray[resultArray.length] = {
-                                startTime: startTime,
-                                endTime: endTime
-                            }
-                        }
-                    }
-                }
-            }
-            console.log(resultArray)
-            return resultArray;
-        },
         copyUrl: function (dropdownItem){
             console.log(dropdownItem)
             this.$copyText(dropdownItem).then((e)=> {
@@ -782,47 +535,7 @@
 
             })
         },
-        gbPlay(){
-          console.log('鍓嶇鎺у埗锛氭挱鏀�');
-          this.$axios({
-            method: 'get',
-            url: '/api/playback/resume/' + this.streamId
-          }).then((res)=> {
-            this.$refs[this.activePlayer].play(this.videoUrl)
-          });
-        },
-        gbPause(){
-          console.log('鍓嶇鎺у埗锛氭殏鍋�');
-          this.$axios({
-            method: 'get',
-            url: '/api/playback/pause/' + this.streamId
-          }).then(function (res) {});
-        },
-        gbScale(command){
-          console.log('鍓嶇鎺у埗锛氬�嶉�� ' + command);
-          this.$axios({
-            method: 'get',
-            url: `/api/playback/speed/${this.streamId }/${command}`
-          }).then(function (res) {});
-        },
-        gbSeek(val){
-          console.log('鍓嶇鎺у埗锛歴eek ');
-          console.log(this.seekTime);
-          console.log(this.sliderTime);
-          let showTime = new Date(new Date(this.recordStartTime).getTime() + this.seekTime * val / 100)
-          let hour = showTime.getHours();
-          let minutes = showTime.getMinutes();
-          let seconds = showTime.getSeconds();
-          this.showTimeText = (hour < 10?("0" + hour):hour) + ":" + (minutes<10?("0" + minutes):minutes) + ":" + (seconds<10?("0" + seconds):seconds)
-          this.$axios({
-            method: 'get',
-            url: `/api/playback/seek/${this.streamId }/` + Math.floor(this.seekTime * val / 100000)
-          }).then( (res)=> {
-            setTimeout(()=>{
-              this.$refs[this.activePlayer].play(this.videoUrl)
-            }, 600)
-          });
-        },
+
 
 
     }
diff --git a/web_src/src/router/index.js b/web_src/src/router/index.js
index 4844d64..23c0a82 100644
--- a/web_src/src/router/index.js
+++ b/web_src/src/router/index.js
@@ -5,6 +5,7 @@
 import console from '../components/console.vue'
 import deviceList from '../components/DeviceList.vue'
 import channelList from '../components/channelList.vue'
+import gbRecordDetail from '../components/GBRecordDetail.vue'
 import pushVideoList from '../components/PushVideoList.vue'
 import streamProxyList from '../components/StreamProxyList.vue'
 import map from '../components/map.vue'
@@ -65,6 +66,11 @@
           component: channelList,
         },
         {
+          path: '/gbRecordDetail/:deviceId/:channelId/',
+          name: 'gbRecordDetail',
+          component: gbRecordDetail,
+        },
+        {
           path: '/parentPlatformList/:count/:page',
           name: 'parentPlatformList',
           component: parentPlatformList,
diff --git a/web_src/static/css/iconfont.css b/web_src/static/css/iconfont.css
index a09b98e..4636a73 100644
--- a/web_src/static/css/iconfont.css
+++ b/web_src/static/css/iconfont.css
@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 1291092 */
-  src: url('iconfont.woff2?t=1655453611360') format('woff2'),
-       url('iconfont.woff?t=1655453611360') format('woff'),
-       url('iconfont.ttf?t=1655453611360') format('truetype');
+  src: url('iconfont.woff2?t=1673251105600') format('woff2'),
+       url('iconfont.woff?t=1673251105600') format('woff'),
+       url('iconfont.ttf?t=1673251105600') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,14 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-slider:before {
+  content: "\e7e0";
+}
+
+.icon-slider-right:before {
+  content: "\ea19";
+}
+
 .icon-list:before {
   content: "\e7de";
 }
diff --git a/web_src/static/css/iconfont.woff2 b/web_src/static/css/iconfont.woff2
index c2fdf69..f1cb24c 100644
--- a/web_src/static/css/iconfont.woff2
+++ b/web_src/static/css/iconfont.woff2
Binary files differ

--
Gitblit v1.8.0