企业微信视频回放
This commit is contained in:
		| @@ -1,19 +1,67 @@ | |||||||
| <template> | <template> | ||||||
|   <div class="slw"> |   <div class="slw"> | ||||||
|     <iframe v-if="isShow" :id="id" style="width: 100%; height: 100%;" :src="`https://cdn.cunwuyun.cn/jssdk/slw/index.html?isMobile=1&url=${src}`"></iframe> |     <iframe v-if="isShow" :id="iframeId" style="width: 100%; height: 100%;" :src="`https://cdn.cunwuyun.cn/slw2.0/index.html?url=${src}`"></iframe> | ||||||
|  |     <div class="slw-bottom" v-if="isShowBar"> | ||||||
|  |       <Timeline class="Timeline" v-if="times.length" :times="times" @replay="onReplay" :isLiveing="isLiveing" ref="timeline" :style="{width: width}"></Timeline> | ||||||
|  |       <div class="action-bar"> | ||||||
|  |         <div class="left"> | ||||||
|  |           <div class="left-btns"> | ||||||
|  |             <img | ||||||
|  |               :src="isPause ? 'https://cdn.cunwuyun.cn/slw2.0/images/play.png' : 'https://cdn.cunwuyun.cn/slw2.0/images/pause.png'" | ||||||
|  |               @click="changePlayStatus"> | ||||||
|  |           </div> | ||||||
|  |           <div | ||||||
|  |             class="volume" | ||||||
|  |             @mouseleave.stop="isShowVolume = false"> | ||||||
|  |             <img  | ||||||
|  |               @mouseenter.stop="isShowVolume = true" | ||||||
|  |               src="https://cdn.cunwuyun.cn/slw2.0/images/sound.png"> | ||||||
|  |             <div class="volume-slider" :class="[isShowVolume ? 'active' : '']"> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |           <div class="play-status"> | ||||||
|  |             <div class="live" v-if="isLiveing"> | ||||||
|  |               <span class="label"></span> | ||||||
|  |               <i>直播中</i> | ||||||
|  |               <em>{{ date }}</em> | ||||||
|  |             </div> | ||||||
|  |             <div v-else class="back-btn" @click="backLiveing">回到直播</div> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="right"> | ||||||
|  |           <img src="https://cdn.cunwuyun.cn/slw2.0/images/date.png" @click="isShowDate = true"> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
|  |   import Timeline from './components/Timeline' | ||||||
|   export default { |   export default { | ||||||
|     props: ['src'], |     props: ['id'], | ||||||
|  |  | ||||||
|     name: 'slwVideo', |     name: 'slwVideo', | ||||||
|  |  | ||||||
|  |     components: { | ||||||
|  |       Timeline | ||||||
|  |     }, | ||||||
|  |  | ||||||
|     data () { |     data () { | ||||||
|       return { |       return { | ||||||
|         isShow: true, |         isShow: true, | ||||||
|         id: `video-${new Date().getTime()}` |         iframeId: `video-${new Date().getTime()}`, | ||||||
|  |         liveingUrl: '', | ||||||
|  |         replayUrl: '', | ||||||
|  |         times: [], | ||||||
|  |         isPause: false, | ||||||
|  |         isShowVolume: false, | ||||||
|  |         isShowBar: true, | ||||||
|  |         date: '', | ||||||
|  |         form: { | ||||||
|  |           date: '' | ||||||
|  |         }, | ||||||
|  |         isLiveing: true | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
| @@ -33,53 +81,302 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     mounted () { |     computed: { | ||||||
|       window.addEventListener('message', e => { |       src () { | ||||||
|         if (e.data.type && e.data.name === 'fullscreen') { |         if (this.isLiveing) { | ||||||
|           this.requestFullScreen(document.getElementById(this.id)) |           return this.liveingUrl | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!e.data.type && e.data.name === 'fullscreen') { |         return this.replayUrl | ||||||
|           this.exitFullscreen() |       } | ||||||
|         } |     }, | ||||||
|       }, false) |  | ||||||
|  |     mounted () { | ||||||
|  |       this.form.date = this.$dayjs(new Date()).format('YYYY-MM-DD') | ||||||
|  |       this.date = this.$dayjs(new Date()).format('YYYY-MM-DD') | ||||||
|  |       this.getSlwPlaybackTime() | ||||||
|  |       this.width = document.querySelector(`.slw`).offsetWidth + 'px' | ||||||
|  |  | ||||||
|  |       if (this.id) { | ||||||
|  |         this.getLiveingUrl() | ||||||
|  |       } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     methods: { |     methods: { | ||||||
|       exitFullscreen () { |       backLiveing () { | ||||||
|         if (document.exitFullscreen) { |         this.getLiveingUrl() | ||||||
|           document.exitFullscreen() |  | ||||||
|         } else if (document.msExitFullscreen) { |  | ||||||
|           document.msExitFullscreen() |  | ||||||
|         } else if (document.mozCancelFullScreen) { |  | ||||||
|           document.mozCancelFullScreen() |  | ||||||
|         } else if (document.webkitExitFullscreen) { |  | ||||||
|           document.webkitExitFullscreen() |  | ||||||
|         } |  | ||||||
|       }, |       }, | ||||||
|  |  | ||||||
|       requestFullScreen (element) { |       onReplay (e) { | ||||||
|         var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen; |         this.isLoading = true | ||||||
|         if (requestMethod) { |         this.$http.post(`/app/appzyvideoequipment/getSlwPlaybackUrl`, null, { | ||||||
|           requestMethod.call(element); |           params: { | ||||||
|         } else if (typeof window.ActiveXObject !== 'undefined') { |             ids: this.id, | ||||||
|           var wscript = new ActiveXObject('WScript.Shell') |             startTime: `${this.form.date} ${e}`, | ||||||
|           if (wscript !== null) { |             endTime: this.form.date + ` ${Number(e.substr(0, 2)) + 6 > 9 ? Number(e.substr(0, 2)) + 6 : '0' + (Number(e.substr(0, 2)) + 6)}:00:00`, | ||||||
|             wscript.SendKeys('{F11}') |             nvrCodes: '' | ||||||
|           } |           } | ||||||
|         } |         }).then(res => { | ||||||
|       } |           if (res.code == 0) { | ||||||
|  |             if (res.data && res.data.length) { | ||||||
|  |               this.replayUrl = res.data[0].playbackUrl | ||||||
|  |               this.isLiveing = false | ||||||
|  |             } | ||||||
|  |             this.isLoading = false | ||||||
|  |           } | ||||||
|  |         }).catch(() => { | ||||||
|  |           this.isLoading = false | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       getLiveingUrl () { | ||||||
|  |         this.isLoading = true | ||||||
|  |         this.$http.post(`/app/appzyvideoequipment/getWebSdkUrl?deviceId=${this.id}`).then(res => { | ||||||
|  |           if (res.data) { | ||||||
|  |             this.liveingUrl = res.data | ||||||
|  |             this.isLiveing = true | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           this.isLoading = false | ||||||
|  |         }).catch(() => { | ||||||
|  |           this.isLoading = false | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       getSlwPlaybackTime () { | ||||||
|  |         this.isLoading = true | ||||||
|  |         this.$http.post(`/app/appzyvideoequipment/getSlwPlaybackTime`, null, { | ||||||
|  |           params: { | ||||||
|  |             ids: this.id, | ||||||
|  |             startTime: this.date + ' 00:00:00', | ||||||
|  |             endTime: this.date + ' 23:59:59', | ||||||
|  |           } | ||||||
|  |         }).then(res => { | ||||||
|  |           if (res.code == 0) { | ||||||
|  |             if (res.data && res.data.length) { | ||||||
|  |               const times = res.data[0].times | ||||||
|  |  | ||||||
|  |               this.times = times.map(item => { | ||||||
|  |                 const startTime = (item.startTime - new Date(this.date + ' 00:00:00').getTime()) / 1000 | ||||||
|  |                 const endTime = (item.endTime - new Date(this.date + ' 00:00:00').getTime()) / 1000 | ||||||
|  |  | ||||||
|  |                 return { | ||||||
|  |                   startTime: Number(startTime.toFixed(0)), | ||||||
|  |                   endTime: Number(endTime.toFixed(0)) | ||||||
|  |                 } | ||||||
|  |               }).sort((a, b) => { | ||||||
|  |                 return a.startTime - b.startTime | ||||||
|  |               }) | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             this.isLoading = false | ||||||
|  |           } | ||||||
|  |         }).catch(() => { | ||||||
|  |           this.isLoading = false | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       onVolume (e) { | ||||||
|  |         const v = (e / 100).toFixed(1) | ||||||
|  |         const subPage = document.querySelector(`#${this.iframeId}`).contentWindow | ||||||
|  |         subPage.postMessage({ | ||||||
|  |           type: 'volume', | ||||||
|  |           value: Number(v) | ||||||
|  |         }, '*') | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       changePlayStatus () { | ||||||
|  |         const subPage = document.querySelector(`#${this.iframeId}`).contentWindow | ||||||
|  |         subPage.postMessage({ | ||||||
|  |           type: 'play', | ||||||
|  |           value: this.isPause | ||||||
|  |         }, '*') | ||||||
|  |          | ||||||
|  |         this.isPause = !this.isPause | ||||||
|  |       }, | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
|   .slw { |   .slw { | ||||||
|  |     position: relative; | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     height: 100%; |     height: 100%; | ||||||
|  |  | ||||||
|  |     * { | ||||||
|  |       box-sizing: border-box; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     iframe { |     iframe { | ||||||
|       border: none; |       border: none; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     .slw-bottom { | ||||||
|  |       position: absolute; | ||||||
|  |       bottom: 0; | ||||||
|  |       left: 0; | ||||||
|  |       z-index: 1; | ||||||
|  |       width: 100%; | ||||||
|  |       transition: all ease-in-out 0.5s; | ||||||
|  |  | ||||||
|  |       .action-bar { | ||||||
|  |         display: flex; | ||||||
|  |         align-items: center; | ||||||
|  |         justify-content: space-between; | ||||||
|  |         width: 100%; | ||||||
|  |         height: 40px; | ||||||
|  |         padding: 0 16px; | ||||||
|  |         background: rgba(0, 0, 0, 0.8); | ||||||
|  |  | ||||||
|  |         .left { | ||||||
|  |           display: flex; | ||||||
|  |           align-items: center; | ||||||
|  |  | ||||||
|  |           .play-status { | ||||||
|  |             display: flex; | ||||||
|  |             align-items: center; | ||||||
|  |             margin-left: 12px; | ||||||
|  |  | ||||||
|  |             em { | ||||||
|  |               margin-left: 12px; | ||||||
|  |               font-style: normal; | ||||||
|  |               color: #fff; | ||||||
|  |               font-size: 12px; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             .back-btn { | ||||||
|  |               padding: 4px 10px; | ||||||
|  |               border-radius: 6px; | ||||||
|  |               color: #ddd; | ||||||
|  |               font-size: 12px; | ||||||
|  |               cursor: pointer; | ||||||
|  |               background: #343747; | ||||||
|  |  | ||||||
|  |               &:hover { | ||||||
|  |                 opacity: 0.6; | ||||||
|  |               } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             .live { | ||||||
|  |               display: flex; | ||||||
|  |               align-items: center; | ||||||
|  |               padding: 2px 5px; | ||||||
|  |               color: rgba(0,255,0,.8); | ||||||
|  |  | ||||||
|  |               i { | ||||||
|  |                 font-size: 12px; | ||||||
|  |                 font-style: normal; | ||||||
|  |               } | ||||||
|  |  | ||||||
|  |               .label { | ||||||
|  |                 width: 6px; | ||||||
|  |                 height: 6px; | ||||||
|  |                 margin-right: 12px; | ||||||
|  |                 background: rgba(0,255,0,.8); | ||||||
|  |                 border-radius: 50%; | ||||||
|  |                 position: relative; | ||||||
|  |  | ||||||
|  |                 &:after { | ||||||
|  |                   content: ""; | ||||||
|  |                   width: 12px; | ||||||
|  |                   height: 12px; | ||||||
|  |                   position: absolute; | ||||||
|  |                   left: 50%; | ||||||
|  |                   top: 50%; | ||||||
|  |                   -webkit-transform: translate(-50%,-50%); | ||||||
|  |                   transform: translate(-50%,-50%); | ||||||
|  |                   border-radius: 50%; | ||||||
|  |                   border: 4px solid rgba(0,255,0,.2); | ||||||
|  |                 } | ||||||
|  |               } | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           .volume { | ||||||
|  |             display: flex; | ||||||
|  |             align-items: center; | ||||||
|  |             position: relative; | ||||||
|  |             height: 100%; | ||||||
|  |  | ||||||
|  |             .volume-slider { | ||||||
|  |               display: none; | ||||||
|  |               position: absolute; | ||||||
|  |               bottom: 15px; | ||||||
|  |               left: 50%; | ||||||
|  |               z-index: -1; | ||||||
|  |               opacity: 0; | ||||||
|  |               padding: 20px 0 10px; | ||||||
|  |               background-color: rgba(0, 0,0,.8); | ||||||
|  |               transform: translate(-50%, 0); | ||||||
|  |               transition: all ease 0.3s; | ||||||
|  |  | ||||||
|  |               &.active { | ||||||
|  |                 display: block; | ||||||
|  |                 z-index: 1; | ||||||
|  |                 opacity: 1; | ||||||
|  |               } | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           img { | ||||||
|  |             cursor: pointer; | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           .left-btns { | ||||||
|  |             display: flex; | ||||||
|  |             align-items: center; | ||||||
|  |             margin-right: 10px; | ||||||
|  |  | ||||||
|  |             span { | ||||||
|  |               flex: 1; | ||||||
|  |               height: 100%; | ||||||
|  |               line-height: 24px; | ||||||
|  |               background: #222838; | ||||||
|  |               color: #c9c9c9; | ||||||
|  |               font-size: 12px; | ||||||
|  |               cursor: pointer; | ||||||
|  |  | ||||||
|  |               &.active { | ||||||
|  |                 color: #fff; | ||||||
|  |                 background: linear-gradient(180deg, #28B2EB 0%, #193D91 100%); | ||||||
|  |               } | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .right { | ||||||
|  |           color: #c9c9c9; | ||||||
|  |           font-size: 12px; | ||||||
|  |  | ||||||
|  |           span { | ||||||
|  |             margin-right: 32px; | ||||||
|  |             cursor: pointer; | ||||||
|  |  | ||||||
|  |             &:hover { | ||||||
|  |               opacity: 0.6; | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           img { | ||||||
|  |             margin-right: 16px; | ||||||
|  |             cursor: pointer; | ||||||
|  |  | ||||||
|  |             &:last-child { | ||||||
|  |               margin-right: 0; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             &:hover { | ||||||
|  |               opacity: 0.6; | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         & > div { | ||||||
|  |           display: flex; | ||||||
|  |           align-items: center; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| </style> | </style> | ||||||
							
								
								
									
										289
									
								
								src/apps/AppIntelligentSecurity/components/Timeline.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										289
									
								
								src/apps/AppIntelligentSecurity/components/Timeline.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,289 @@ | |||||||
|  | <template> | ||||||
|  |   <div :class="wrapper" class="canvas" v-if="isInit"> | ||||||
|  |     <canvas | ||||||
|  |       class="canvas" | ||||||
|  |       :id="id" | ||||||
|  |       @click="onClick" | ||||||
|  |       :canvas-id="id" | ||||||
|  |       :style="{height: '52px'}" | ||||||
|  |       v-if="canvasWidth" | ||||||
|  |       :width="canvasWidth" | ||||||
|  |       height="52"> | ||||||
|  |     </canvas> | ||||||
|  |     <img | ||||||
|  |       class="drag-img" | ||||||
|  |       :style="{left: x + 'px'}" | ||||||
|  |       src="https://cdn.cunwuyun.cn/slw2.0/images/drag.png" /> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  |   export default { | ||||||
|  |     props: ['isLiveing', 'times'], | ||||||
|  |  | ||||||
|  |     data () { | ||||||
|  |       return { | ||||||
|  |         ctx: null, | ||||||
|  |         canvasWidth: '', | ||||||
|  |         canvasHeight: '', | ||||||
|  |         scale: 4, | ||||||
|  |         time: '', | ||||||
|  |         left: 0, | ||||||
|  |         x: 0, | ||||||
|  |         ratioW: '', | ||||||
|  |         isHide: true, | ||||||
|  |         isInit: false, | ||||||
|  |         isChoose: false, | ||||||
|  |         wrapper: `canvas-${new Date().getTime()}`, | ||||||
|  |         id: `timeline-${new Date().getTime()}`, | ||||||
|  |         timer: null | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     watch: { | ||||||
|  |       isLiveing () { | ||||||
|  |         this.countdown() | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       times: { | ||||||
|  |         deep: true, | ||||||
|  |         handler (v) { | ||||||
|  |           if (v.length && this.ctx) { | ||||||
|  |             this.init() | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     mounted () { | ||||||
|  |       this.$nextTick(() => { | ||||||
|  |         this.init() | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     destroyed () { | ||||||
|  |       clearInterval(this.timer) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     methods: { | ||||||
|  |       onMousemove (e) { | ||||||
|  |         const canvasInfo = document.querySelector(`#${this.id}`).getBoundingClientRect() | ||||||
|  |         const seconds = 24 * 60 * 60 | ||||||
|  |  | ||||||
|  |         if (e.clientY - canvasInfo.top < 29) { | ||||||
|  |           const x = e.clientX - canvasInfo.left | ||||||
|  |           const unit = seconds / this.canvasWidth * x | ||||||
|  |           this.left = x | ||||||
|  |           this.time = this.secTotime(unit) | ||||||
|  |           this.isHide = false | ||||||
|  |  | ||||||
|  |           if (!this.isChoose) return | ||||||
|  |           this.x = e.clientX - canvasInfo.left - 4 | ||||||
|  |           this.ratioW = this.x / this.canvasWidth | ||||||
|  |         } else { | ||||||
|  |           this.isHide = true | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       onClick (e) { | ||||||
|  |         this.x = e.target.x | ||||||
|  |         clearInterval(this.timer) | ||||||
|  |         this.timer = null | ||||||
|  |         const time = this.secTotime((24 * 60 * 60) / this.canvasWidth * this.x) | ||||||
|  |         this.$emit('replay', time) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       onDragDown () { | ||||||
|  |         this.isChoose = true | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       onMouseUp () { | ||||||
|  |         if (!this.isChoose) return | ||||||
|  |  | ||||||
|  |         clearInterval(this.timer) | ||||||
|  |         this.timer = null | ||||||
|  |         this.isChoose = false | ||||||
|  |         const time = this.secTotime((24 * 60 * 60) / this.canvasWidth * this.x) | ||||||
|  |         this.$emit('replay', time) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       secTotime (s) { | ||||||
|  |         let second = parseInt(s) | ||||||
|  |         let minute = 0 | ||||||
|  |         let hour = 0 | ||||||
|  |         if (second > 60) { | ||||||
|  |           minute = parseInt(second / 60) | ||||||
|  |           second = parseInt(second % 60) | ||||||
|  |           if (minute > 60) { | ||||||
|  |             hour = parseInt(minute / 60) | ||||||
|  |             minute = parseInt(minute % 60) | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         hour = `${parseInt(hour) > 9 ? parseInt(hour) : '0' + parseInt(hour)}` | ||||||
|  |         minute = `${parseInt(minute) > 9 ? parseInt(minute) : '0' + parseInt(minute)}` | ||||||
|  |         second = `${parseInt(second) > 9 ? parseInt(second) : '0' + parseInt(second)}` | ||||||
|  |         return `${hour}:${minute}:${second}` | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       init () { | ||||||
|  |         if (this.timer) { | ||||||
|  |           clearInterval(this.timer) | ||||||
|  |           this.timer = null | ||||||
|  |         } | ||||||
|  |            | ||||||
|  |         this.ratioW = this.x / this.canvasWidth | ||||||
|  |         this.$nextTick(() => { | ||||||
|  |           this.isInit = true | ||||||
|  |           this.$nextTick(() => { | ||||||
|  |             this.canvasWidth = document.querySelector(`.${this.wrapper}`).offsetWidth | ||||||
|  |             this.canvasHeight = document.querySelector(`.${this.wrapper}`).offsetHeight | ||||||
|  |  | ||||||
|  |             this.$nextTick(() => { | ||||||
|  |               const el = document.querySelector(`#${this.id}`) | ||||||
|  |               this.ctx = uni.createCanvasContext(`${this.id}`) | ||||||
|  |               // this.ctx.width  = document.querySelector('.canvas').offsetWidth | ||||||
|  |               // this.ctx.height  = document.querySelector('.canvas').offsetHeight | ||||||
|  |  | ||||||
|  |               if (this.x > 0) { | ||||||
|  |                 this.x = this.ratioW * this.canvasWidth | ||||||
|  |               } else { | ||||||
|  |                 this.initNowTime() | ||||||
|  |               } | ||||||
|  |  | ||||||
|  |               this.renderTimeLine() | ||||||
|  |               this.renderPlayback() | ||||||
|  |  | ||||||
|  |               this.countdown() | ||||||
|  |             }) | ||||||
|  |           }) | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       countdown () { | ||||||
|  |         this.timer = setInterval(() => { | ||||||
|  |           if (this.isLiveing) { | ||||||
|  |             this.initNowTime() | ||||||
|  |           } else { | ||||||
|  |             this.x = this.x + this.canvasWidth / (24 * 60 * 60) | ||||||
|  |           } | ||||||
|  |         }, 1000) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       initNowTime () { | ||||||
|  |         const date = new Date() | ||||||
|  |         const seconds = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds() | ||||||
|  |  | ||||||
|  |         this.x = this.canvasWidth / (24 * 60 * 60) * seconds | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       drawLine(ctx, options) { | ||||||
|  |         const { beginX, beginY, endX, endY, lineColor, lineWidth } = options | ||||||
|  |         ctx.beginPath() | ||||||
|  |         ctx.lineWidth = lineWidth | ||||||
|  |         ctx.moveTo(beginX, beginY) | ||||||
|  |         ctx.lineTo(endX, endY) | ||||||
|  |         ctx.strokeStyle = lineColor | ||||||
|  |         ctx.stroke() | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       renderPlayback () { | ||||||
|  |         const ctx = this.ctx | ||||||
|  |         const unit = this.canvasWidth / (24 * 60 * 60) | ||||||
|  |         this.times.forEach(item => { | ||||||
|  |           this.drawLine(ctx, { | ||||||
|  |             beginX: item.startTime * unit, | ||||||
|  |             beginY: 28, | ||||||
|  |             endX: item.startTime * unit, | ||||||
|  |             endY: 0, | ||||||
|  |             lineColor: 'rgba(0, 156, 255, 1)', | ||||||
|  |             lineWidth: item.endTime * unit - item.startTime * unit | ||||||
|  |           }) | ||||||
|  |         }) | ||||||
|  |         ctx.draw() | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       renderTimeLine () { | ||||||
|  |         const ctx = this.ctx | ||||||
|  |         ctx.fillStyle = 'rgba(51, 60, 83, 0.8)' | ||||||
|  |         ctx.fillRect(0, 0, this.canvasWidth, 28) | ||||||
|  |         ctx.fillStyle = 'rgba(32, 40, 61, 0.8)' | ||||||
|  |         ctx.fillRect(0, 28, this.canvasWidth, 24) | ||||||
|  |  | ||||||
|  |          | ||||||
|  |         ctx.fillStyle = '#fff' | ||||||
|  |         ctx.font = '12px Arial' | ||||||
|  |         const w = this.canvasWidth / 24  | ||||||
|  |  | ||||||
|  |         for (let i = 1; i < 25; i ++) { | ||||||
|  |           this.drawLine(ctx, { | ||||||
|  |             beginX: i * w, | ||||||
|  |             beginY: 28, | ||||||
|  |             endX: i * w, | ||||||
|  |             endY: i % this.scale === 0 ? 16 : 20, | ||||||
|  |             lineColor: i % this.scale === 0 ? 'red' : '#000', | ||||||
|  |             lineWidth: i % this.scale === 0 ? 1 : 1 | ||||||
|  |           }) | ||||||
|  |  | ||||||
|  |           if (i % this.scale === 0) { | ||||||
|  |             const text = (i < 10 ? '0' + i : i) + ': 00' | ||||||
|  |             const textWidth = ctx.measureText(text).width | ||||||
|  |             if (i === 24) { | ||||||
|  |               ctx.fillText(text, i * w - textWidth, 44) | ||||||
|  |             } else { | ||||||
|  |               ctx.fillText(text, i * w - textWidth / 2, 44) | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  |   .canvas { | ||||||
|  |     position: relative; | ||||||
|  |     width: 100%; | ||||||
|  |  | ||||||
|  |     .drag-img { | ||||||
|  |       position: absolute; | ||||||
|  |       left: 0; | ||||||
|  |       top: 0; | ||||||
|  |       z-index: 1; | ||||||
|  |       user-select: none; | ||||||
|  |       cursor: e-resize; | ||||||
|  |       -webkit-user-drag: none; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .time-scale { | ||||||
|  |       display: flex; | ||||||
|  |       position: absolute; | ||||||
|  |       align-items: center; | ||||||
|  |       justify-content: center; | ||||||
|  |       left: 0; | ||||||
|  |       bottom: 0; | ||||||
|  |       z-index: 1; | ||||||
|  |       user-select: none; | ||||||
|  |       width: 12px; | ||||||
|  |       height: 24px; | ||||||
|  |  | ||||||
|  |       span { | ||||||
|  |         width: 2px; | ||||||
|  |         height: 24px; | ||||||
|  |         background: rgba(255, 255, 255, 0.8); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .time { | ||||||
|  |       position: absolute; | ||||||
|  |       bottom: 22px; | ||||||
|  |       left: 0; | ||||||
|  |       z-index: 1; | ||||||
|  |       padding: 2px 4px; | ||||||
|  |       font-size: 12px; | ||||||
|  |       color: #fff; | ||||||
|  |       background: rgba(0, 0, 0, 1); | ||||||
|  |       transform: translate(-50%, 100%); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </style> | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| <template> | <template> | ||||||
|   <section class="monitorDetail"> |   <section class="monitorDetail"> | ||||||
|     <div class="videoBox"> |     <div class="videoBox"> | ||||||
|       <SlwVideo :src="videoUrl" :style="style"></SlwVideo> |       <SlwVideo :id="id" :style="style"></SlwVideo> | ||||||
|     </div> |     </div> | ||||||
|   </section> |   </section> | ||||||
| </template> | </template> | ||||||
| @@ -14,7 +14,8 @@ export default { | |||||||
|     return { |     return { | ||||||
|       style: {}, |       style: {}, | ||||||
|       videoUrl: '', |       videoUrl: '', | ||||||
|       monitor: {} |       monitor: {}, | ||||||
|  |       id: '' | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
| @@ -61,7 +62,8 @@ export default { | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   onLoad(params) { |   onLoad(params) { | ||||||
|     this.getDetail(params.id) |     this.id = params.id | ||||||
|  |     // this.getDetail(params.id) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|   | |||||||
| @@ -111,7 +111,7 @@ export default { | |||||||
|       this.$http.post(`/app/appzyvideoequipment/getAreaEquipment?areaId=${this.areaId}`).then(res => { |       this.$http.post(`/app/appzyvideoequipment/getAreaEquipment?areaId=${this.areaId}`).then(res => { | ||||||
|         if (res?.data) { |         if (res?.data) { | ||||||
|           this.list = res.data.list |           this.list = res.data.list | ||||||
|           this.count = res.data.count |           this.count = res.data.count || 0 | ||||||
|           this.onlineRate = (this.count.online / this.count.sum).toFixed(2) |           this.onlineRate = (this.count.online / this.count.sum).toFixed(2) | ||||||
|           this.offlineRate = (1 - this.onlineRate).toFixed(2) |           this.offlineRate = (1 - this.onlineRate).toFixed(2) | ||||||
|           this.initEchart() |           this.initEchart() | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								src/main.js
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								src/main.js
									
									
									
									
									
								
							| @@ -5,6 +5,7 @@ import axios from './common/axios'; | |||||||
| import utils from './common/util'; | import utils from './common/util'; | ||||||
| import ui from 'uview-ui' | import ui from 'uview-ui' | ||||||
| import VConsole from 'vconsole' | import VConsole from 'vconsole' | ||||||
|  | import dayjs from 'dayjs' | ||||||
|  |  | ||||||
| const loading = title => { | const loading = title => { | ||||||
|   uni.showLoading({ |   uni.showLoading({ | ||||||
| @@ -23,6 +24,7 @@ Vue.use(ui) | |||||||
| Vue.config.productionTip = false; | Vue.config.productionTip = false; | ||||||
| //初始化接口工具类 | //初始化接口工具类 | ||||||
| Vue.prototype.$http = axios; | Vue.prototype.$http = axios; | ||||||
|  | Vue.prototype.$dayjs = dayjs | ||||||
| Vue.prototype.$cdn = 'https://cdn.cunwuyun.cn/dvcp/h5/'; | Vue.prototype.$cdn = 'https://cdn.cunwuyun.cn/dvcp/h5/'; | ||||||
| Object.keys(utils).map((e) => (Vue.prototype['$' + e] = utils[e])); | Object.keys(utils).map((e) => (Vue.prototype['$' + e] = utils[e])); | ||||||
| utils.dict.init({instance: axios}) | utils.dict.init({instance: axios}) | ||||||
| @@ -32,20 +34,20 @@ const app = new Vue({ | |||||||
|   store, |   store, | ||||||
|   ...App |   ...App | ||||||
| }); | }); | ||||||
| app.$mount(); | // app.$mount(); | ||||||
| // store.dispatch("agentSign").then(config => { | store.dispatch("agentSign").then(config => { | ||||||
| //   const init = (c = 0) => { |   const init = (c = 0) => { | ||||||
| //     if (config) { |     if (config) { | ||||||
| //       store.commit("getConfig", {...config, latlng: [config.lat, config.lng]}) |       store.commit("getConfig", {...config, latlng: [config.lat, config.lng]}) | ||||||
| //       app.$mount(); |       app.$mount(); | ||||||
| //     } else { |     } else { | ||||||
| //       if (c < 5) { |       if (c < 5) { | ||||||
| //         setTimeout(() => { |         setTimeout(() => { | ||||||
| //           init(++c) |           init(++c) | ||||||
| //         }, 300) |         }, 300) | ||||||
| //       } |       } | ||||||
| //     } |     } | ||||||
| //   } |   } | ||||||
| //   init() |   init() | ||||||
| // }) | }) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user