Kaynağa Gözat

直播

master
huxinglu 4 yıl önce
ebeveyn
işleme
0a784097d2
14 değiştirilmiş dosya ile 13055 ekleme ve 20 silme
  1. +12352
    -0
      package-lock.json
  2. BIN
      src/assets/img/command/ask-add.png
  3. BIN
      src/assets/img/command/ask-hp.png
  4. BIN
      src/assets/img/command/ask-routes.png
  5. BIN
      src/assets/img/command/ask-video.png
  6. BIN
      src/assets/img/command/search.png
  7. BIN
      src/assets/img/command/uva.png
  8. +89
    -0
      src/components/cVideo.vue
  9. +400
    -0
      src/views/command/ask/askLeft.vue
  10. +70
    -0
      src/views/command/ask/videoDialog.vue
  11. +123
    -16
      src/views/command/index.vue
  12. +1
    -1
      src/views/command/problem/assignmentDialog.vue
  13. +20
    -3
      src/views/command/problem/problemLeft.vue
  14. BIN
      static/video-js.swf

+ 12352
- 0
package-lock.json
Dosya farkı çok büyük olduğundan ihmal edildi
Dosyayı Görüntüle


BIN
src/assets/img/command/ask-add.png Dosyayı Görüntüle

Önce Sonra
Genişlik: 40  |  Yükseklik: 40  |  Boyut: 825B

BIN
src/assets/img/command/ask-hp.png Dosyayı Görüntüle

Önce Sonra
Genişlik: 244  |  Yükseklik: 64  |  Boyut: 4.6KB

BIN
src/assets/img/command/ask-routes.png Dosyayı Görüntüle

Önce Sonra
Genişlik: 242  |  Yükseklik: 62  |  Boyut: 4.8KB

BIN
src/assets/img/command/ask-video.png Dosyayı Görüntüle

Önce Sonra
Genişlik: 240  |  Yükseklik: 62  |  Boyut: 4.5KB

BIN
src/assets/img/command/search.png Dosyayı Görüntüle

Önce Sonra
Genişlik: 50  |  Yükseklik: 50  |  Boyut: 1.5KB

BIN
src/assets/img/command/uva.png Dosyayı Görüntüle

Önce Sonra
Genişlik: 148  |  Yükseklik: 148  |  Boyut: 9.0KB

+ 89
- 0
src/components/cVideo.vue Dosyayı Görüntüle

@@ -0,0 +1,89 @@
<template>
<div class="v-video">
<video-player v-if="playerOptions.sources.length>0" class="video-player vjs-custom-skin"
ref="videoPlayer"
:playsinline="true"
:options="playerOptions"
></video-player>
</div>
</template>

<script>
import {videoPlayer} from 'vue-video-player'
import 'video.js/dist/video-js.css'
import 'videojs-flash'

export default {
name: "cVideo",
data() {
return {
playerOptions: {
playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度
autoplay: false, //如果true,浏览器准备好时开始回放。
muted: false, // 默认情况下将会消除任何音频。
loop: false, // 导致视频一结束就重新开始。
preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
language: 'zh-CN',
aspectRatio: '13:6', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
techOrder: ['flash', 'html5'], // 兼容顺序
flash: {
hls: {withCredentials: false},
swf: 'static/video-js.swf' // 引入静态文件swf
},
html5: {hls: {withCredentials: false}},
sources: [],
// width: document.documentElement.clientWidth,
notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖Video.js无法播放媒体源时显示的默认信息。
controlBar: {
timeDivider: true,
durationDisplay: true,
remainingTimeDisplay: false,
fullscreenToggle: true //全屏按钮
}
}
}
},
props: {
videoUrl: {
type: String,
default() {
return '';
}
}
},
created() {
let playerOptions = JSON.parse(JSON.stringify(this.playerOptions))
playerOptions.sources.push(
{
src: this.videoUrl,
type: 'rtmp/hls'
}
)
this.playerOptions = Object.assign({}, playerOptions)
},
components: {
videoPlayer
}
}
</script>

<style lang="less">
.video-js
.vjs-big-play-button {
top: 42% !important;
left: 47% !important;
height: 1rem !important;
width: 1rem !important;
font-size: inherit;
line-height: 1rem !important;
border-radius: 50% !important;
opacity: 0.7 !important;
border: 0.02rem solid #fff !important;
background-color: #194672 !important;
}

.video-js .vjs-big-play-button .vjs-icon-placeholder:before {
font-size: 0.5rem!important;
}
</style>

+ 400
- 0
src/views/command/ask/askLeft.vue Dosyayı Görüntüle

@@ -0,0 +1,400 @@
<template>
<div v-loading="searchLoading" class="ask-left">
<div>
<img src="../../../assets/img/command/head-ask.png"/>
<div>
<img src="../../../assets/img/command/ask-add.png">
<div>新建任务</div>
</div>
</div>
<div>
<div :class="activeType==1?'check-type':''" @click="activeTypeClick(1)">
<div>
<div></div>
<div>正在执行</div>
</div>
<div>24</div>
<div v-show="activeType==1"></div>
</div>
<div :class="activeType==2?'check-type':''" @click="activeTypeClick(2)">
<div>
<div></div>
<div>已执行</div>
</div>
<div>19</div>
<div v-show="activeType==2"></div>
</div>
</div>
<div>
<el-input placeholder="请输入河流" v-model="searchValue">
</el-input>
<div>
<img @click="search" src="../../../assets/img/command/search.png">
</div>
</div>
<div>
<div :key="index" v-for="(item,index) in dataList">
<div>
<div>
<div>澧水河</div>
<div>江宁</div>
</div>
<div>2020-04-22</div>
</div>
<div>秦淮河河东-秦淮河北</div>
<div>
<div>
<div :class="activeType==2?'isCheck':''"></div>
<div>{{activeType?'在执行':'已执行'}}</div>
</div>
<div>
<img @click="routesClick" src="../../../assets/img/command/ask-routes.png"/>
<img @click="videoClick" v-if="activeType==1" src="../../../assets/img/command/ask-video.png"/>
<img v-if="activeType==2" src="../../../assets/img/command/ask-hp.png"/>
</div>
</div>
</div>
</div>
<div v-show="dataList.length>0">
<el-pagination
background
:pager-count="5"
layout="prev, pager, next"
:total="100">
</el-pagination>
</div>
<videoDialog @dialogClose="visible=false" v-if="visible" :visible="visible" ></videoDialog>
</div>
</template>

<script>
import {mapGetters} from "vuex";
import videoDialog from './videoDialog'

export default {
name: "ask-left",
data() {
return {
searchLoading: false,
searchValue: '',
activeType: 1,
visible: false,
dataList: [{}, {}, {}, {}],
}
},
computed: {
...mapGetters(["fontSize"])
},
components: {videoDialog},
watch: {
driverId() {
if (this.driverId) {
this.searchValue= this.driverId
this.search()
}
}
},
props: {
driverId: {
type: String,
default() {
return ''
}
}
},
mounted() {
this.search()
},
methods: {
activeTypeClick(activeType) {
this.activeType = activeType
this.searchValue = ''
this.search()
},
showProblemDetail(item) {
this.$emit('showProblemDetail', {id: 1, driverId: 27})
},
routesClick(){
this.$emit('routesClick', 296)
},
videoClick(){
this.$emit('askClear',this.driverId)
this.visible=true
},
search() {
let me = this
this.dataList=[]
this.searchLoading = true
me.$emit('askClear',me.driverId)
setTimeout(function () {
me.dataList=[{},{},{},{}]
me.searchLoading = false
}, 2000)
}
},
}
</script>

<style lang="less">
.ask-left {
position: absolute;
top: 1.25rem;
width: 4.27rem;
background-color: rgba(0, 0, 0, 0.6);
height: 100%;
padding-left: 0.26rem;
padding-right: 0.27rem;


> div:first-child {
margin-top: 0.1rem;
width: 100%;
height: 0.47rem;
display: flex;
align-items: center;
justify-content: space-between;

> img {
width: 1.33rem;
height: 100%;
}

> div:last-child {
display: flex;
align-items: center;

> img {
width: 0.2rem;
height: 0.2rem;
}

> div {
font-family: PingFangSC-Regular;
font-size: 0.16rem;
color: #FFFFFF;
line-height: 0.22rem;
margin-left: 0.152rem;
}
}
}

> div:nth-child(2) {
margin-top: 0.075rem;
display: flex;
justify-content: space-between;

> div {
opacity: 0.83;
width: 2rem;
position: relative;
background: rgba(86, 244, 248, 0.10);
font-family: PingFangSC-Medium;
color: #FFFFFF;
border-radius: 0.02rem;
cursor: pointer;
position: relative;

> div:first-child {
margin-left: 0.21rem;
margin-top: 0.04rem;
display: flex;
align-items: center;

> div:first-child {
width: 0.08rem;
height: 0.08rem;
background: #0DFE9E;
border: 0.04rem solid #0a583e;
border-radius: 50%;
}

> div:last-child {
margin-left: 0.13rem;
font-size: 0.16rem;
line-height: 0.22rem;
}
}

> div:nth-child(2) {
text-align: center;
font-size: 0.41rem;
line-height: 0.57rem;
margin-top: 0.093rem;
margin-bottom: 0.065em;
}

> div:last-child {
position: absolute;
width: 100%;
bottom: 0rem;
height: 0.065rem;
background: #276D70;
}
}

> div:last-child {
> div:first-child {
> div:first-child {
background: #FF0056;
border: 0.04rem solid #53102C;
}
}
}

.check-type {
opacity: 1 !important;
}
}

> div:nth-child(3) {
position: relative;
margin-top: 0.202rem;
display: flex;

.el-input__inner {
border: none;
background-color: #3D3D3D;
color: #FFFFFF;
font-family: PingFangSC-Regular;
font-size: 0.16rem;
height: 0.36rem;
line-height: 0.36rem;
opacity: 1;
}

> div:last-child {
position: absolute;
right: 0.1rem;
top: -0.63rem;
width: 0.23rem;
height: 0.23rem;

> img {
width: 100%;
}

.el-icon-loading {
font-size: 0.2rem;
color: #ffffff;
}
}
}

> div:nth-child(4) {
>div{
margin-top: 0.24rem;
font-family: PingFangSC-Regular;
color: #FFFFFF;
font-size: 0.14rem;
>div:first-child{
display: flex;
justify-content: space-between;
align-items: center;
line-height: 0.25rem;
>div:first-child{
display: flex;
align-items: center;
>div:first-child{
font-family: PingFangSC-Medium;
font-size: 0.18rem;
margin-right: 0.135rem;
}
}
}
>div:nth-child(2){
width: 100%;
line-height: 0.2rem;
margin-top: 0.1rem;
overflow: hidden;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
white-space: nowrap;
}
>div:last-child{
display: flex;
justify-content: space-between;
align-items: center;
line-height: 0.3rem;
margin-top: 0.133rem;
>div:first-child{
display: flex;
align-items: center;
>div:first-child{
width: 0.077rem;
height: 0.077rem;
border-radius: 50%;
background: rgba(102,102,102,0.34);
border: 0.02rem solid #0DFE9E;
margin-right: 0.07rem;
}
.isCheck{
border: 0.02rem solid #FF0056!important;
}
}
>div:last-child{
display: flex;
>img{
width: 1.2rem;
height: 0.3rem;
}
>img:last-child{
margin-left: 0.3rem;
}
}
}
}
}

> div:last-child {
text-align: center;
}

.el-pagination {
margin-top: 0.33rem;
color: #C4C4C4;;
font-weight: 700;
font-size: 0.14rem;
}

.el-pagination.is-background .btn-prev, .el-pagination.is-background .el-pager li {
margin: 0 0.05rem;
background-color: #26262A;
color: #96969A;
min-width: 0.36rem !important;
border-radius: 0.02rem;
border: 0.01rem solid #343434;
font-size: 0.14rem;
}

.el-pagination.is-background .btn-next {
margin: 0 0.05rem;
background-color: #26262A;
color: #96969A;
min-width: 0.36rem;
border-radius: 0.02rem;
border: 0.01rem solid #343434;
font-size: 0.14rem;
}

.el-pagination button {
line-height: 0.36rem;
height: 0.36rem;
}

.el-pager li {
line-height: 0.36rem;
height: 0.36rem;
}

.el-pager .more::before {
line-height: 0.36rem;
}

.el-pagination.is-background .el-pager li:not(.disabled).active {
background-color: #4F4F53;
color: #FFFFFF;
}

}

</style>

+ 70
- 0
src/views/command/ask/videoDialog.vue Dosyayı Görüntüle

@@ -0,0 +1,70 @@
<template>
<el-dialog top="10vh" :before-close="dialogClose" class="videoDialog" title="澧水河——2020.04.25" :visible.sync="visible">
<c-video videoUrl="rtmp://58.200.131.2:1935/livetv/hunantv"></c-video>
</el-dialog>
</template>

<script>
import {mapGetters} from "vuex";
import cVideo from '@/components/cVideo'
import $ from 'jquery'

export default {
name: "videoDialog",
data() {
return {
top: this.$root.$options.filters.filterPx(2, this.fontSize)
}
},
props: {
visible: {
type: Boolean,
default() {
return false
}
}
},
computed: {
...mapGetters(["fontSize"])
},
components:{cVideo},
mounted(){
},
methods: {
dialogClose() {
this.$emit('dialogClose')
},
}
}
</script>

<style lang="less">
.videoDialog {
.el-dialog {
background-color: inherit;
width: 13rem;
/*height: 7.547rem;*/
margin: 0;
margin-left: 5.8rem;

.el-dialog__header {
background-color: inherit !important;
padding: 0.2rem !important;
font-family: PingFangSC-Medium;
font-size: 0.18rem;
color: #FFFFFF;
}

.el-dialog__body {
padding: 0rem;
height: 100%;
width: 100%;
}

.tech-theme .banner {
display: none;
}

}
}
</style>

+ 123
- 16
src/views/command/index.vue Dosyayı Görüntüle

@@ -85,8 +85,11 @@
</div>
<dateLeft v-if="activeType=='date'&&finshMap"></dateLeft>
<dateRight v-if="activeType=='date'&&finshMap"></dateRight>
<problemLeft @problemClear="problemClear" @problemSearch="problemSearch" @showProblemDetail="showProblemDetail"
<problemLeft :driverId="driverId" @fillMarker="fillMarker" @problemClear="problemClear"
@problemSearch="problemSearch" @showProblemDetail="showProblemDetail"
v-if="activeType=='problem'&&finshMap"></problemLeft>
<askLeft @routesClick="routesClick" @askClear="askClear" :driverId="driverId"
v-if="activeType=='ask'&&finshMap"></askLeft>
</div>
</template>

@@ -96,6 +99,7 @@
import dateLeft from './date/dateLeft'
import dateRight from './date/dateRight'
import problemLeft from './problem/problemLeft'
import askLeft from './ask/askLeft'
import {mapGetters} from "vuex";
import api from '@/api/main/index'
import driver from 'static/driver.json'
@@ -105,14 +109,16 @@
name: "command-container",
data() {
return {
driverId: '',
InfoWindow: null,
mapType: 1,
loading: false,
activeType: "problem",
activeType: "ask",
map: {},
center: {},
barHeight: document.body.clientHeight > 1050 ? 2.42 : 2.06,
nameMarkList: [],
routersMarker:[],
polygonList: [],
driverList: [],
markerList: [],
@@ -145,8 +151,76 @@
computed: {
...mapGetters(["fontSize"])
},
components: {dateLeft, dateRight, problemLeft, problemDetailWin},
components: {dateLeft, dateRight, problemLeft, problemDetailWin, askLeft},
methods: {
routesClick(driverId) {
this.clearRoutersMarker()
this.checkDriver(driverId)
const {data} = driver
let child = data.find(item => item.id == driverId)
if (child&&child.mapInfo&&child.mapInfo.length>0) {
this.initRouters(child)
} else {
this.$notify.error({
title: '错误',
message: '没有找到飞行路线'
});
}
},
initRouters(child) {
let path = child.mapInfo
let point = new AMap.LngLat(path[0].x, path[0].y)
let me = this
let image = require('../../assets/img/command/uva.png')
let icon = new AMap.Icon({
// 图标尺寸
size: new AMap.Size(60, 60),
// 图标的取图地址
image: image,
// 图标所用图片大小
imageSize: new AMap.Size(60, 60),
});
let pathList = []
for (let i = 0, l = path.length; i < l; i++) {
pathList.push(
new AMap.LngLat(path[i].x, path[i].y)
)
}
let marker = new AMap.Marker({
map: me.map,
position: point,
icon: icon,
offset: new AMap.Pixel(-30, -30),
autoRotation: true,
angle: -90,
});
// 绘制轨迹
let polyline = new AMap.Polyline({
map: me.map,
path: pathList,
showDir: true,
strokeColor: "#FFEF5D", //线颜色
// strokeOpacity: 1, //线透明度
strokeWeight: 6, //线宽
// strokeStyle: "solid" //线样式
});

let passedPolyline = new AMap.Polyline({
map: me.map,
// path: lineArr,
strokeColor: "#AF5", //线颜色
// strokeOpacity: 1, //线透明度
strokeWeight: 6, //线宽
// strokeStyle: "solid" //线样式
})

marker.on('moving', function (e) {
passedPolyline.setPath(e.passedPath);
});

marker.moveAlong(pathList, 6000);
this.routersMarker=[marker,passedPolyline,polyline]
},
hideMarker() {
this.markerList.map(item => {
item.hide()
@@ -162,20 +236,46 @@
this.InfoWindow.close()
}
},
clearRoutersMarker(){
if (this.routersMarker.length > 0) {
this.routersMarker.map(item => {
this.map.remove(item)
})
this.routersMarker=[]
}
},
clearMarker() {
if (this.markerList.length > 0) {
this.markerList.map(item => {
this.map.remove(item)
})
this.markerList=[]
}
},
problemClear() {
fillMarker() {
this.fillDriver()
this.clearMarker()
this.closeInfoWin()
this.map.setFitView(this.polygonList)
},
closeInfoWindow(){
askClear(driverId) {
if (!driverId) {
this.fillMarker()
}
this.driverId=''
this.clearRoutersMarker()
this.map.setFitView(this.polygonList)
},
problemClear(driverId) {
if (driverId) {
this.checkDriver(driverId)
} else {
this.fillMarker()
}
this.driverId=''
this.clearMarker()
this.map.setFitView(this.polygonList)
},
closeInfoWindow() {
this.closeInfoWin()
this.fillDriver()
},
@@ -225,7 +325,7 @@
marker.setMap(this.map)
return marker
},
checkDriver(dirverId){
checkDriver(dirverId) {
this.driverList.map(item => {
if (item.check) {
item.check = false
@@ -243,17 +343,17 @@
}
})
},
showProblemDetail(child){
showProblemDetail(child) {
this.closeInfoWin()
this.map.setFitView(this.polygonList)
let me=this
let me = this
setTimeout(function () {
let marker = me.markerList.find(item=>item.childData.id==child.id)
if(marker){
let marker = me.markerList.find(item => item.childData.id == child.id)
if (marker) {
me.InfoWindow.open(me.map, marker.getPosition());
}
me.checkDriver(child.dirverId)
},500)
}, 500)
},
getMarkerDetail(marker) {
this.InfoWindow.open(this.map, marker.getPosition());
@@ -293,7 +393,9 @@
polygons.name = item.name
polygons.id = item.id
polygons.on('click', function () {
me.driverId = this.id
me.checkDriver(this.id)
me.clearRoutersMarker()
me.closeInfoWin()
})
this.map.add(polygons)
@@ -321,14 +423,13 @@
})
}
})
this.driverId = ''
},
typeLick(type) {
this.activeType = type;
this.fillDriver()
this.closeInfoWin()
this.clearMarker()
this.problemClear()
this.clearRoutersMarker()
this.markerList = []
this.map.setFitView(this.polygonList)
},
addBound() {
let me = this;
@@ -375,6 +476,10 @@
width: 100%;
height: 100%;

.el-loading-mask {
background-color: inherit;
}

.problem-marker {
position: absolute;
bottom: 0.3rem;
@@ -685,10 +790,12 @@
color: #C0C4CC;
line-height: 0.3rem;
}

.el-select .el-input .el-select__caret {
color: #ffffff;
font-size: 0.12rem;
}

.el-input__icon {
line-height: 0.3rem
}

+ 1
- 1
src/views/command/problem/assignmentDialog.vue Dosyayı Görüntüle

@@ -27,7 +27,7 @@
<div class="foot-btn">
<div @click="dialogClose">取消</div>
<div @click="submit">
<span v-show="!submitLoading">指派任务</span>
<span v-show="!submitLoading">指派</span>
<i v-show="submitLoading" class="el-icon-loading"></i>
</div>
</div>

+ 20
- 3
src/views/command/problem/problemLeft.vue Dosyayı Görüntüle

@@ -26,7 +26,7 @@
</el-select>
</el-form-item>
<el-form-item label="河湖名称:">
<el-select v-model="ruleForm.hu" placeholder="" clearable>
<el-select v-model="ruleForm.driverId" placeholder="" clearable>
<el-option
v-for="item in huList"
:key="item.value"
@@ -97,7 +97,7 @@
searchLoading:false,
ruleForm: {
date: '',
driver: ''
driverId: ''
},
dataList:[{},{},{},{}],
driverList: [],
@@ -114,11 +114,28 @@
...mapGetters(["fontSize"])
},
components: {assignmentDialog},
watch:{
driverId(){
if(this.driverId){
this.ruleForm.driverId=this.driverId
this.search()
}
}
},
props:{
driverId:{
type:String,
default(){
return ''
}
}
},
mounted(){
this.search()
},
methods: {
assignment(){
this.$emit('fillMarker')
this.visible=true
},
showProblemDetail(item){
@@ -137,7 +154,7 @@
{id:6,lng:119.038507,lat:31.605114,type:2,dirverId:209},
{id:7,lng:119.038507,lat:31.325114,type:3,dirverId:216},
]
this.$emit('problemClear')
this.$emit('problemClear',this.ruleForm.driverId)
let me=this
setTimeout(function () {
me.dataList=[{},{},{},{}]

BIN
static/video-js.swf Dosyayı Görüntüle


Yükleniyor…
İptal
Kaydet