|
|
@@ -0,0 +1,408 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <div id="loseTimeSpan"
|
|
|
+ style="width:700px"
|
|
|
+ class="loseTimeSpan">
|
|
|
+ <i v-for="(item,index) in checkSpan"
|
|
|
+ :key="index + 'x'"
|
|
|
+ :style="{width:item.width + 'px',left:item.start + 'px'}"
|
|
|
+ :title="'检查模版' + item.st + '~' + item.et"></i>
|
|
|
+ <i v-for="(item,index) in loseSpan"
|
|
|
+ :key="index + 'y'"
|
|
|
+ class="lose"
|
|
|
+ :style="{width:item.width + 'px',left:item.start + 'px'}"
|
|
|
+ :title="'录像丢失' + item.st + '~' + item.et"></i>
|
|
|
+ <i v-for="(item,index) in warnSpan"
|
|
|
+ :key="index + 'z'"
|
|
|
+ class="warn"
|
|
|
+ :style="{width:item.width + 'px',left:item.start + 'px'}"
|
|
|
+ :title="'无录像计划' + item.st + '~' + item.et"></i>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import axios from 'axios'
|
|
|
+export default {
|
|
|
+ name: "Login",
|
|
|
+ data () {
|
|
|
+ return {
|
|
|
+ DAY_SECOND: 86400,
|
|
|
+ rowData: this.data,
|
|
|
+ checkSpan: [],
|
|
|
+ loseSpan: [],
|
|
|
+ warnSpan: [],
|
|
|
+ widthrem:this.rems
|
|
|
+ }
|
|
|
+ },
|
|
|
+ props:{
|
|
|
+ data:{
|
|
|
+ },
|
|
|
+ rems:{
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ data(rowData) {
|
|
|
+ if(!rowData) return;
|
|
|
+ this.rowData=rowData;
|
|
|
+ let data = this.renderVideoRuler();
|
|
|
+ this.checkSpan = data.checkSpan;
|
|
|
+ this.loseSpan = data.loseSpan;
|
|
|
+ this.warnSpan = data.warnSpan;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ //计算录像模版长度
|
|
|
+ calculateCheckSpanUI (spans = [], widthPx) {
|
|
|
+ const tmpTemplates = [];
|
|
|
+ const tmpSpans = [];
|
|
|
+ spans.forEach((item) => {
|
|
|
+ const st = this.datestr2number(item.st);
|
|
|
+ const et = this.datestr2number(item.et);
|
|
|
+
|
|
|
+ //转换为秒数
|
|
|
+ tmpTemplates.push({
|
|
|
+ st: st,
|
|
|
+ et: et
|
|
|
+ })
|
|
|
+
|
|
|
+ //计算宽度
|
|
|
+ let width = widthPx * ((et - st) / this.DAY_SECOND);
|
|
|
+
|
|
|
+ if (width < 1) {
|
|
|
+ width = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ //计算开始位置
|
|
|
+ let start = widthPx * (st / this.DAY_SECOND);
|
|
|
+
|
|
|
+
|
|
|
+ tmpSpans.push({
|
|
|
+ width: width,
|
|
|
+ start: start,
|
|
|
+ st: item.st,
|
|
|
+ et: item.et,
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ return {
|
|
|
+ templates: tmpTemplates,
|
|
|
+ spans: tmpSpans
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //计算丢失数据的信息
|
|
|
+ calculateWarnSpanUI (spans = [], widthPx) {
|
|
|
+ let warnSpans = [];
|
|
|
+ // console.log(spans)
|
|
|
+ if (spans.length > 0) {
|
|
|
+ let flag = "00:00:00";
|
|
|
+ spans.forEach((item, index) => {
|
|
|
+ if (index==0&&item.st > flag) {
|
|
|
+ const st = this.datestr2number(flag) + 1;
|
|
|
+ const et = this.datestr2number(item.st) - 1;
|
|
|
+
|
|
|
+ //计算宽度
|
|
|
+ let width = widthPx * ((et - st) / this.DAY_SECOND);
|
|
|
+ if (width < 1) {
|
|
|
+ width = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ //计算开始位置
|
|
|
+ let start = widthPx * (st / this.DAY_SECOND);
|
|
|
+
|
|
|
+ warnSpans.push({
|
|
|
+ width: width,
|
|
|
+ start: start,
|
|
|
+ st: flag,
|
|
|
+ et: item.st
|
|
|
+ })
|
|
|
+ }else if(index>0&&item.st > spans[index-1].et){
|
|
|
+ const st = this.datestr2number(spans[index-1].et) + 1;
|
|
|
+ const et = this.datestr2number(item.st) - 1;
|
|
|
+
|
|
|
+ //计算宽度
|
|
|
+ let width = widthPx * ((et - st) / this.DAY_SECOND);
|
|
|
+ if (width < 1) {
|
|
|
+ width = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ //计算开始位置
|
|
|
+ let start = widthPx * (st / this.DAY_SECOND);
|
|
|
+
|
|
|
+ warnSpans.push({
|
|
|
+ width: width,
|
|
|
+ start: start,
|
|
|
+ st: spans[index-1].et,
|
|
|
+ et: item.st
|
|
|
+ })
|
|
|
+ }else {
|
|
|
+ flag
|
|
|
+ }
|
|
|
+
|
|
|
+ if (index + 1 === spans.length && item.et !== "23:59:59") {
|
|
|
+ const st = this.datestr2number(item.et) + 1;
|
|
|
+ const et = this.datestr2number("23:59:59");
|
|
|
+
|
|
|
+ //计算宽度
|
|
|
+ let width = widthPx * ((et - st) / this.DAY_SECOND);
|
|
|
+ if (width < 1) {
|
|
|
+ width = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ let start = widthPx * (st / this.DAY_SECOND);
|
|
|
+
|
|
|
+ warnSpans.push({
|
|
|
+ width: width,
|
|
|
+ start: start,
|
|
|
+ st: item.et,
|
|
|
+ et: "24:00:00"
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ spans: warnSpans
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ //判断指定的丢失片段是否存在模版范围之中
|
|
|
+ judgeLoseSpan (checkSpanTemplate = [], st, et) {
|
|
|
+ let flag = false;
|
|
|
+ checkSpanTemplate.forEach((val) => {
|
|
|
+ if (st >= val.st && et <= val.et) {
|
|
|
+ flag = true;
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return flag;
|
|
|
+ },
|
|
|
+ //计算丢失录像
|
|
|
+ calculateLoseSpanUI (spans = [], checkSpanTemplate = [], widthPx) {
|
|
|
+
|
|
|
+ //计算每个span的边界
|
|
|
+ const tmpSpans = [], tmpWarnSpan = [];
|
|
|
+
|
|
|
+ if(spans.length===0)
|
|
|
+ {
|
|
|
+ return {
|
|
|
+ spans: tmpSpans,
|
|
|
+ warnSpans: tmpWarnSpan
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //将检测模版和丢失片段都按照开始日期升序排序
|
|
|
+ checkSpanTemplate.sort(function (a, b) {
|
|
|
+ return a.st - b.st;
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ spans.sort(function (a, b) {
|
|
|
+ let datestr2number = (dateStr) => {
|
|
|
+ if (typeof dateStr !== "string") {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ const arr = dateStr.split(":");
|
|
|
+ if (arr.length !== 3) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return (Number.parseInt(arr[0]) * 3600) + (Number.parseInt(arr[1]) * 60) + (Number.parseInt(arr[2]));
|
|
|
+ }
|
|
|
+
|
|
|
+ return datestr2number(a.st) - datestr2number(b.st);
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // let test = new Array();
|
|
|
+ // test.push(spans[1]);
|
|
|
+ // console.log(test);
|
|
|
+ spans.forEach((item) => {
|
|
|
+ let st = this.datestr2number(item.st);
|
|
|
+ let et = this.datestr2number(item.et);
|
|
|
+
|
|
|
+ if ((et - st) <= 5) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断丢失时间段是否在录像计划的范围内
|
|
|
+ const normalFlag = this.judgeLoseSpan(checkSpanTemplate, st, et);
|
|
|
+ // console.log('是否越界' + normalFlag)
|
|
|
+ if (!normalFlag) {
|
|
|
+ //异常丢失日期,超越了边界,去掉超过检查模版的边缘
|
|
|
+ //找到第一个复核丢失片段的检查模版
|
|
|
+ let checkSpan = undefined;
|
|
|
+ for (let i = 0; i < checkSpanTemplate.length; i++) {
|
|
|
+ const val = checkSpanTemplate[i];
|
|
|
+ if (!checkSpan && st <= val.st) {
|
|
|
+ checkSpan = val;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // console.log('是否赋值' + JSON.stringify(checkSpan));
|
|
|
+
|
|
|
+
|
|
|
+ if (!checkSpan) {
|
|
|
+ //没有匹配到模版,重新使用ET匹配
|
|
|
+ for (let i = (checkSpanTemplate.length - 1); i >= 0; i--) {
|
|
|
+ const val = checkSpanTemplate[i];
|
|
|
+ if (!checkSpan && et >= val.et) {
|
|
|
+ checkSpan = val;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (!!checkSpan) {
|
|
|
+ let warnSt = 0, warnEt = 0;//告警录像
|
|
|
+ let loseSt = 0, loseEt = 0;//丢失录像
|
|
|
+
|
|
|
+ if (st < checkSpan.st) {
|
|
|
+ //左边越界
|
|
|
+ warnSt = st;
|
|
|
+ warnEt = checkSpan.st;
|
|
|
+ loseSt = checkSpan.st;
|
|
|
+ loseEt = et;
|
|
|
+ } else {
|
|
|
+ //右边越界
|
|
|
+ loseSt = st;
|
|
|
+ loseEt = checkSpan.et;
|
|
|
+ warnSt = checkSpan.et;
|
|
|
+ warnEt = et;
|
|
|
+ }
|
|
|
+
|
|
|
+ let width_1 = widthPx * ((warnEt - warnSt) / this.DAY_SECOND);
|
|
|
+
|
|
|
+ if (width_1 < 1) {
|
|
|
+ width_1 = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ tmpWarnSpan.push({
|
|
|
+ width: width_1,
|
|
|
+ start: widthPx * (warnSt / this.DAY_SECOND),
|
|
|
+ st: this.number2datestr(warnSt),
|
|
|
+ et: this.number2datestr(warnEt)
|
|
|
+ });
|
|
|
+
|
|
|
+ let width_2 = widthPx * ((loseEt - loseSt) / this.DAY_SECOND);
|
|
|
+ if (width_2 < 1) {
|
|
|
+ width_2 = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ tmpSpans.push({
|
|
|
+ width: width_2,
|
|
|
+ start: widthPx * (loseSt / this.DAY_SECOND),
|
|
|
+ st: this.number2datestr(loseSt),
|
|
|
+ et: this.number2datestr(loseEt)
|
|
|
+ })
|
|
|
+
|
|
|
+ return;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ //正常片段
|
|
|
+ let width = widthPx * ((et - st) / this.DAY_SECOND);
|
|
|
+ if (width < 1) {
|
|
|
+ width = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ tmpSpans.push({
|
|
|
+ width: width,
|
|
|
+ start: widthPx * (st / this.DAY_SECOND),
|
|
|
+ st: item.st,
|
|
|
+ et: item.et
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ return {
|
|
|
+ spans: tmpSpans,
|
|
|
+ warnSpans: tmpWarnSpan
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ renderVideoRuler () {
|
|
|
+ if(!this.rowData) return ;
|
|
|
+ this.rowData.checkSpan=JSON.parse(this.rowData.checkSpan)
|
|
|
+ this.rowData.loseSpan=JSON.parse(this.rowData.loseSpan)
|
|
|
+ const checkSpan = this.calculateCheckSpanUI(this.rowData.checkSpan, this.widthrem);
|
|
|
+ const loseSpan = this.calculateLoseSpanUI(this.rowData.loseSpan, checkSpan.templates, this.widthrem);
|
|
|
+ const warnSpan = this.calculateWarnSpanUI(this.rowData.checkSpan, this.widthrem);
|
|
|
+ // debugger
|
|
|
+ return {
|
|
|
+ //存放检测模版气质时间得秒数
|
|
|
+ checkSpanTemplate: checkSpan.templates,
|
|
|
+ //检测模版数据
|
|
|
+ checkSpan: checkSpan.spans,
|
|
|
+ //录像丢失数据
|
|
|
+ loseSpan: loseSpan.spans,
|
|
|
+ //无录像计划的数据
|
|
|
+ warnSpan: warnSpan.spans
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ number2datestr (senconds) {
|
|
|
+ const hour = Math.floor((senconds % this.DAY_SECOND) / 3600);
|
|
|
+ const minute = Math.floor((senconds % 3600) / 60);
|
|
|
+ const second = senconds % 60;
|
|
|
+ return (hour < 10 ? '0' : '') + hour + ":" +
|
|
|
+ (minute < 10 ? '0' : '') + minute + ":" +
|
|
|
+ (second < 10 ? '0' : '') + second;
|
|
|
+ },
|
|
|
+ datestr2number (dateStr) {
|
|
|
+ if (typeof dateStr !== "string") {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ const arr = dateStr.split(":");
|
|
|
+ if (arr.length !== 3) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return (Number.parseInt(arr[0]) * 3600) + (Number.parseInt(arr[1]) * 60) + (Number.parseInt(arr[2]));
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted () {
|
|
|
+ let data = this.renderVideoRuler();
|
|
|
+ if(!data) return;
|
|
|
+ this.checkSpan = data.checkSpan;
|
|
|
+ this.loseSpan = data.loseSpan;
|
|
|
+ this.warnSpan = data.warnSpan;
|
|
|
+ },
|
|
|
+ beforeDestroy () {
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style>
|
|
|
+.loseTimeSpan {
|
|
|
+ background: transparent;
|
|
|
+ height: 20px;
|
|
|
+ overflow: hidden;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+.loseTimeSpan i {
|
|
|
+ cursor: pointer;
|
|
|
+ margin: 0px;
|
|
|
+ padding: 0px;
|
|
|
+ display: inline-block;
|
|
|
+ z-index: 5;
|
|
|
+ position: absolute;
|
|
|
+ height: 100%;
|
|
|
+ background: #51ca65;
|
|
|
+}
|
|
|
+.loseTimeSpan .lose {
|
|
|
+ z-index: 20;
|
|
|
+ background: #f5a623;
|
|
|
+}
|
|
|
+.loseTimeSpan .warn {
|
|
|
+ z-index: 4;
|
|
|
+ background: #e0e0e0;
|
|
|
+}
|
|
|
+</style>
|