From 2b1f7a47394363e95deb4dfa0f1c67d41e747f7f Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期三, 01 二月 2023 10:56:40 +0800
Subject: [PATCH] Merge branch 'wvp-28181-2.0' into fix-269

---
 web_src/src/components/GBRecordDetail.vue |  513 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 513 insertions(+), 0 deletions(-)

diff --git a/web_src/src/components/GBRecordDetail.vue b/web_src/src/components/GBRecordDetail.vue
new file mode 100644
index 0000000..6fe29a8
--- /dev/null
+++ b/web_src/src/components/GBRecordDetail.vue
@@ -0,0 +1,513 @@
+<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-time-picker
+                size="mini"
+                is-range
+                align="left"
+                v-model="timeRange"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                range-separator="鑷�"
+                start-placeholder="寮�濮嬫椂闂�"
+                end-placeholder="缁撴潫鏃堕棿"
+                @change="timePickerChange"
+                placeholder="閫夋嫨鏃堕棿鑼冨洿">
+              </el-time-picker>
+            </el-button-group>
+
+            <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="鎾斁鍊嶉��"  @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,
+        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: null,
+        timeRange: null,
+        startTime: null,
+        endTime: null,
+        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.setTime(this.chooseDate + " 00:00:00", this.chooseDate + " 23:59:59");
+        this.recordsLoading = true;
+        this.detailFiles = [];
+        this.$axios({
+          method: 'get',
+          url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' + this.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)
+      },
+      setTime: function (startTime, endTime){
+        this.startTime = startTime;
+        this.endTime = endTime;
+        let start = (new Date(this.startTime).getTime() - new Date(this.chooseDate + " 00:00:00").getTime())/1000;
+        let end = (new Date(this.endTime).getTime() - new Date(this.chooseDate + " 00:00:00").getTime())/1000;
+        console.log(start)
+        console.log(end)
+        this.playTime = [start, end];
+        this.timeRange = [startTime, endTime];
+      },
+      videoError: function (e) {
+        console.log("鎾斁鍣ㄩ敊璇細" + JSON.stringify(e));
+      },
+      checkedFile(file){
+        this.chooseFile = file;
+        this.setTime(file.startTime, file.endTime);
+			  // 寮�濮嬪洖鏀�
+        this.playRecord()
+      },
+      playRecord: function () {
+
+        if (this.streamId !== "") {
+          this.stopPlayRecord(()=> {
+            this.streamId = "";
+            this.playRecord();
+          })
+        } else {
+          this.$axios({
+            method: 'get',
+            url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' +
+              this.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["recordVideoPlayer"].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;
+
+      },
+      timePickerChange: function (val){
+        this.setTime(val[0], val[1])
+      },
+      playTimeChange(val){
+        console.log(val)
+
+        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");
+
+        this.setTime(startTimeStr, endTimeStr)
+
+        this.playRecord();
+      },
+      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>

--
Gitblit v1.8.0