From fb843d41c1e186b2109bfeea73509cad2b135cdc Mon Sep 17 00:00:00 2001 From: xiaoxie <hotcoffie@163.com> Date: 星期四, 21 四月 2022 12:33:10 +0800 Subject: [PATCH] 1.重构全局页面结构,从之前每个页面独立绘制改为路由嵌套 2.全局页面样式优化,如滚动条、标题栏等 --- web_src/src/components/DeviceList.vue | 647 ++++---- web_src/src/components/StreamProxyList.vue | 209 +- web_src/src/components/setting/Media.vue | 2 web_src/src/components/ParentPlatformList.vue | 144 - web_src/src/components/PushVideoList.vue | 606 ++++---- web_src/src/components/live.vue | 77 web_src/src/components/CloudRecord.vue | 108 web_src/src/components/devicePosition.vue | 64 /dev/null | 141 - web_src/src/components/channelList.vue | 735 +++++---- web_src/src/components/setting/Web.vue | 2 web_src/src/layout/index.vue | 90 + web_src/src/components/MediaServerManger.vue | 65 web_src/src/components/control.vue | 1196 ++++++++------- web_src/src/router/index.js | 143 + web_src/src/layout/UiHeader.vue | 151 ++ web_src/src/components/CloudRecordDetail.vue | 2 web_src/src/components/setting/Sip.vue | 2 18 files changed, 2,298 insertions(+), 2,086 deletions(-) diff --git a/web_src/src/components/CloudRecord.vue b/web_src/src/components/CloudRecord.vue index 78f8a46..1d0819b 100644 --- a/web_src/src/components/CloudRecord.vue +++ b/web_src/src/components/CloudRecord.vue @@ -1,67 +1,57 @@ <template> - <div id="app"> - <el-container> - <el-header> - <uiHeader></uiHeader> - </el-header> - <el-main> - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> - <span v-if="!recordDetail" >浜戠褰曞儚</span> - <el-page-header v-if="recordDetail" @back="backToList" content="浜戠褰曞儚"> - </el-page-header> - <div style="position: absolute; right: 5rem; top: 0.3rem;"> - 鑺傜偣閫夋嫨: - <el-select size="mini" @change="chooseMediaChange" style="width: 16rem; margin-right: 1rem;" v-model="mediaServerId" placeholder="璇烽�夋嫨" :disabled="recordDetail"> - <el-option - v-for="item in mediaServerList" - :key="item.id" - :label="item.id" - :value="item.id"> - </el-option> - </el-select> - </div> - <div style="position: absolute; right: 1rem; top: 0.3rem;"> - <el-button v-if="!recordDetail" icon="el-icon-refresh-right" circle size="mini" :loading="loading" @click="getRecordList()"></el-button> - </div> - </div> - <div v-if="!recordDetail"> + <div id="app" style="width: 100%"> + <div class="page-header"> + <div class="page-title">浜戠褰曞儚</div> + <div class="page-header-btn"> + 鑺傜偣閫夋嫨: + <el-select size="mini" @change="chooseMediaChange" style="width: 16rem; margin-right: 1rem;" v-model="mediaServerId" placeholder="璇烽�夋嫨" :disabled="recordDetail"> + <el-option + v-for="item in mediaServerList" + :key="item.id" + :label="item.id" + :value="item.id"> + </el-option> + </el-select> + <el-button v-if="!recordDetail" icon="el-icon-refresh-right" circle size="mini" :loading="loading" @click="getRecordList()"></el-button> + </div> + </div> + <div v-if="!recordDetail"> - <!--璁惧鍒楄〃--> - <el-table :data="recordList" border style="width: 100%" :height="winHeight"> - <el-table-column prop="app" label="搴旂敤鍚�" align="center"> - </el-table-column> - <el-table-column prop="stream" label="娴両D" align="center"> - </el-table-column> - <el-table-column prop="time" label="鏃堕棿" align="center"> - </el-table-column> - <el-table-column label="鎿嶄綔" width="360" align="center" fixed="right"> - <template slot-scope="scope"> - <el-button-group> - <el-button size="mini" icon="el-icon-video-camera-solid" type="primary" @click="showRecordDetail(scope.row)">鏌ョ湅</el-button> -<!-- <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteRecord(scope.row)">鍒犻櫎</el-button>--> - </el-button-group> - </template> - </el-table-column> - </el-table> - <el-pagination - style="float: right" - @size-change="handleSizeChange" - @current-change="currentChange" - :current-page="currentPage" - :page-size="count" - :page-sizes="[15, 25, 35, 50]" - layout="total, sizes, prev, pager, next" - :total="total"> - </el-pagination> - </div> - <cloud-record-detail ref="cloudRecordDetail" v-if="recordDetail" :recordFile="chooseRecord" :mediaServerId="mediaServerId" :mediaServerPath="mediaServerPath" ></cloud-record-detail> - </el-main> - </el-container> - </div> + <!--璁惧鍒楄〃--> + <el-table :data="recordList" border style="width: 100%" :height="winHeight"> + <el-table-column prop="app" label="搴旂敤鍚�" align="center"> + </el-table-column> + <el-table-column prop="stream" label="娴両D" align="center"> + </el-table-column> + <el-table-column prop="time" label="鏃堕棿" align="center"> + </el-table-column> + <el-table-column label="鎿嶄綔" width="360" align="center" fixed="right"> + <template slot-scope="scope"> + <el-button-group> + <el-button size="mini" icon="el-icon-video-camera-solid" type="primary" @click="showRecordDetail(scope.row)">鏌ョ湅</el-button> + <!-- <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteRecord(scope.row)">鍒犻櫎</el-button>--> + </el-button-group> + </template> + </el-table-column> + </el-table> + <el-pagination + style="float: right" + @size-change="handleSizeChange" + @current-change="currentChange" + :current-page="currentPage" + :page-size="count" + :page-sizes="[15, 25, 35, 50]" + layout="total, sizes, prev, pager, next" + :total="total"> + </el-pagination> + </div> + <cloud-record-detail ref="cloudRecordDetail" v-if="recordDetail" :recordFile="chooseRecord" :mediaServerId="mediaServerId" :mediaServerPath="mediaServerPath" ></cloud-record-detail> + + </div> </template> <script> - import uiHeader from './UiHeader.vue' + import uiHeader from '../layout/UiHeader.vue' import cloudRecordDetail from './CloudRecordDetail.vue' import MediaServer from './service/MediaServer' export default { diff --git a/web_src/src/components/CloudRecordDetail.vue b/web_src/src/components/CloudRecordDetail.vue index bee3253..bfb81e2 100644 --- a/web_src/src/components/CloudRecordDetail.vue +++ b/web_src/src/components/CloudRecordDetail.vue @@ -104,7 +104,7 @@ <script> // TODO 鏍规嵁鏌ヨ鐨勬椂闂村垪琛ㄨ缃粦杞ㄧ殑鏈�澶у�间笌鏈�灏忓�硷紝 - import uiHeader from './UiHeader.vue' + import uiHeader from '../layout/UiHeader.vue' import player from './dialog/easyPlayer.vue' import moment from 'moment' export default { diff --git a/web_src/src/components/DeviceList.vue b/web_src/src/components/DeviceList.vue index 4f8b460..d934fe6 100644 --- a/web_src/src/components/DeviceList.vue +++ b/web_src/src/components/DeviceList.vue @@ -1,349 +1,350 @@ <template> - <div id="app"> - <el-container> - <el-header> - <uiHeader></uiHeader> - </el-header> - <el-main> - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> - <span style="font-size: 1rem; font-weight: bold;">璁惧鍒楄〃</span> - <div style="position: absolute; right: 1rem; top: 0.3rem;"> - <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading" @click="getDeviceList()"></el-button> - </div> - </div> - <!-- <devicePlayer ref="devicePlayer"></devicePlayer> --> - <!--璁惧鍒楄〃--> - <el-table :data="deviceList" border style="width: 100%;font-size: 12px;" :height="winHeight"> - <el-table-column prop="name" label="鍚嶇О" align="center"> - </el-table-column> - <el-table-column prop="deviceId" label="璁惧缂栧彿" width="180" align="center"> - </el-table-column> - <el-table-column label="鍦板潃" width="180" align="center"> - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> - <el-tag size="medium">{{ scope.row.hostAddress }}</el-tag> - </div> - </template> - </el-table-column> - <el-table-column prop="manufacturer" label="鍘傚" align="center"> - </el-table-column> - <el-table-column label="娴佷紶杈撴ā寮�" align="center" width="120"> - <template slot-scope="scope"> - <el-select size="mini" @change="transportChange(scope.row)" v-model="scope.row.streamMode" placeholder="璇烽�夋嫨"> - <el-option key="UDP" label="UDP" value="UDP"></el-option> - <el-option key="TCP-ACTIVE" label="TCP涓诲姩妯″紡" :disabled="true" value="TCP-ACTIVE"></el-option> - <el-option key="TCP-PASSIVE" label="TCP琚姩妯″紡" value="TCP-PASSIVE"></el-option> - </el-select> - </template> - </el-table-column> - <el-table-column prop="channelCount" label="閫氶亾鏁�" align="center"> - </el-table-column> - <el-table-column label="鐘舵��" width="120" align="center"> - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.online == 1">鍦ㄧ嚎</el-tag> - <el-tag size="medium" type="info" v-if="scope.row.online == 0">绂荤嚎</el-tag> - </div> - </template> - </el-table-column> - <el-table-column prop="keepaliveTime" label="鏈�杩戝績璺�" align="center" width="140"> - </el-table-column> - <el-table-column prop="registerTime" label="鏈�杩戞敞鍐�" align="center" width="140"> - </el-table-column> - <el-table-column prop="updateTime" label="鏇存柊鏃堕棿" align="center" width="140"> - </el-table-column> - <el-table-column prop="createTime" label="鍒涘缓鏃堕棿" align="center" width="140"> - </el-table-column> + <div id="app" style="width: 100%"> + <div class="page-header"> + <div class="page-title">璁惧鍒楄〃</div> + <div class="page-header-btn"> + <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading" + @click="getDeviceList()"></el-button> + </div> + </div> + <!-- <devicePlayer ref="devicePlayer"></devicePlayer> --> + <!--璁惧鍒楄〃--> + <el-table :data="deviceList" border style="width: 100%;font-size: 12px;" :height="winHeight"> + <el-table-column prop="name" label="鍚嶇О" align="center"> + </el-table-column> + <el-table-column prop="deviceId" label="璁惧缂栧彿" width="180" align="center"> + </el-table-column> + <el-table-column label="鍦板潃" width="180" align="center"> + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> + <el-tag size="medium">{{ scope.row.hostAddress }}</el-tag> + </div> + </template> + </el-table-column> + <el-table-column prop="manufacturer" label="鍘傚" align="center"> + </el-table-column> + <el-table-column label="娴佷紶杈撴ā寮�" align="center" width="120"> + <template slot-scope="scope"> + <el-select size="mini" @change="transportChange(scope.row)" v-model="scope.row.streamMode" placeholder="璇烽�夋嫨"> + <el-option key="UDP" label="UDP" value="UDP"></el-option> + <el-option key="TCP-ACTIVE" label="TCP涓诲姩妯″紡" :disabled="true" value="TCP-ACTIVE"></el-option> + <el-option key="TCP-PASSIVE" label="TCP琚姩妯″紡" value="TCP-PASSIVE"></el-option> + </el-select> + </template> + </el-table-column> + <el-table-column prop="channelCount" label="閫氶亾鏁�" align="center"> + </el-table-column> + <el-table-column label="鐘舵��" width="120" align="center"> + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> + <el-tag size="medium" v-if="scope.row.online == 1">鍦ㄧ嚎</el-tag> + <el-tag size="medium" type="info" v-if="scope.row.online == 0">绂荤嚎</el-tag> + </div> + </template> + </el-table-column> + <el-table-column prop="keepaliveTime" label="鏈�杩戝績璺�" align="center" width="140"> + </el-table-column> + <el-table-column prop="registerTime" label="鏈�杩戞敞鍐�" align="center" width="140"> + </el-table-column> + <el-table-column prop="updateTime" label="鏇存柊鏃堕棿" align="center" width="140"> + </el-table-column> + <el-table-column prop="createTime" label="鍒涘缓鏃堕棿" align="center" width="140"> + </el-table-column> - <el-table-column label="鎿嶄綔" width="450" align="center" fixed="right"> - <template slot-scope="scope"> - <el-button size="mini" v-if="scope.row.online!=0" icon="el-icon-refresh" @click="refDevice(scope.row)" @mouseover="getTooltipContent(scope.row.deviceId)">鍒锋柊</el-button> - <el-button-group> - <el-button size="mini" icon="el-icon-video-camera-solid" v-bind:disabled="scope.row.online==0" type="primary" @click="showChannelList(scope.row)">閫氶亾</el-button> - <el-button size="mini" icon="el-icon-location" v-bind:disabled="scope.row.online==0" type="primary" @click="showDevicePosition(scope.row)">瀹氫綅</el-button> - <el-button size="mini" icon="el-icon-edit" type="primary" @click="edit(scope.row)">缂栬緫</el-button> - <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteDevice(scope.row)">鍒犻櫎</el-button> - </el-button-group> - </template> - </el-table-column> - </el-table> - <el-pagination - style="float: right" - @size-change="handleSizeChange" - @current-change="currentChange" - :current-page="currentPage" - :page-size="count" - :page-sizes="[15, 25, 35, 50]" - layout="total, sizes, prev, pager, next" - :total="total"> - </el-pagination> - <deviceEdit ref="deviceEdit" ></deviceEdit> - <syncChannelProgress ref="syncChannelProgress" ></syncChannelProgress> - </el-main> - </el-container> - </div> + <el-table-column label="鎿嶄綔" width="450" align="center" fixed="right"> + <template slot-scope="scope"> + <el-button size="mini" v-if="scope.row.online!=0" icon="el-icon-refresh" @click="refDevice(scope.row)" + @mouseover="getTooltipContent(scope.row.deviceId)">鍒锋柊 + </el-button> + <el-button-group> + <el-button size="mini" icon="el-icon-video-camera-solid" v-bind:disabled="scope.row.online==0" + type="primary" @click="showChannelList(scope.row)">閫氶亾 + </el-button> + <el-button size="mini" icon="el-icon-location" v-bind:disabled="scope.row.online==0" type="primary" + @click="showDevicePosition(scope.row)">瀹氫綅 + </el-button> + <el-button size="mini" icon="el-icon-edit" type="primary" @click="edit(scope.row)">缂栬緫</el-button> + <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteDevice(scope.row)">鍒犻櫎</el-button> + </el-button-group> + </template> + </el-table-column> + </el-table> + <el-pagination + style="float: right" + @size-change="handleSizeChange" + @current-change="currentChange" + :current-page="currentPage" + :page-size="count" + :page-sizes="[15, 25, 35, 50]" + layout="total, sizes, prev, pager, next" + :total="total"> + </el-pagination> + <deviceEdit ref="deviceEdit"></deviceEdit> + <syncChannelProgress ref="syncChannelProgress"></syncChannelProgress> + </div> </template> <script> - import uiHeader from './UiHeader.vue' - import deviceEdit from './dialog/deviceEdit.vue' - import syncChannelProgress from './dialog/SyncChannelProgress.vue' - export default { - name: 'app', - components: { - uiHeader, - deviceEdit, - syncChannelProgress, - }, - data() { - return { - deviceList: [], //璁惧鍒楄〃 - currentDevice: {}, //褰撳墠鎿嶄綔璁惧瀵硅薄 +import uiHeader from '../layout/UiHeader.vue' +import deviceEdit from './dialog/deviceEdit.vue' +import syncChannelProgress from './dialog/SyncChannelProgress.vue' - videoComponentList: [], - updateLooper: 0, //鏁版嵁鍒锋柊杞鏍囧織 - currentDeviceChannelsLenth:0, - winHeight: window.innerHeight - 200, - currentPage:1, - count:15, - total:0, - getDeviceListLoading: false, - }; - }, - computed: { - getcurrentDeviceChannels: function() { - let data = this.currentDevice['channelMap']; - let channels = null; - if (data) { - channels = Object.keys(data).map(key => { - return data[key]; - }); - this.currentDeviceChannelsLenth = channels.length; - } - return channels; - } - }, - mounted() { - this.initData(); - this.updateLooper = setInterval(this.initData, 10000); - }, - destroyed() { - this.$destroy('videojs'); - clearTimeout(this.updateLooper); - }, - methods: { - initData: function() { - this.getDeviceList(); - }, - currentChange: function(val){ - this.currentPage = val; - this.getDeviceList(); - }, - handleSizeChange: function(val){ - this.count = val; - this.getDeviceList(); - }, - getDeviceList: function() { - let that = this; - this.getDeviceListLoading = true; - this.$axios({ - method: 'get', - url:`/api/device/query/devices`, - params: { - page: that.currentPage, - count: that.count - } - }).then(function (res) { - that.total = res.data.total; - that.deviceList = res.data.list; - that.getDeviceListLoading = false; - }).catch(function (error) { - console.error(error); - that.getDeviceListLoading = false; - }); +export default { + name: 'app', + components: { + uiHeader, + deviceEdit, + syncChannelProgress, + }, + data() { + return { + deviceList: [], //璁惧鍒楄〃 + currentDevice: {}, //褰撳墠鎿嶄綔璁惧瀵硅薄 - }, - deleteDevice: function(row) { - let msg = "纭畾鍒犻櫎姝よ澶囷紵" - if (row.online !== 0) { - msg = "鍦ㄧ嚎璁惧鍒犻櫎鍚庝粛鍙�氳繃娉ㄥ唽鍐嶆涓婄嚎銆�<br/>濡傞渶褰诲簳鍒犻櫎璇峰厛灏嗚澶囩绾裤��<br/><strong>纭畾鍒犻櫎姝よ澶囷紵</strong>" - } - this.$confirm(msg, '鎻愮ず', { - dangerouslyUseHTMLString : true, - confirmButtonText: '纭畾', - cancelButtonText: '鍙栨秷', - center: true, - type: 'warning' - }).then(() => { - this.$axios({ - method: 'delete', - url:`/api/device/query/devices/${row.deviceId}/delete` - }).then((res)=>{ - this.getDeviceList(); - }).catch((error) =>{ - console.error(error); - }); - }).catch(() => { - + videoComponentList: [], + updateLooper: 0, //鏁版嵁鍒锋柊杞鏍囧織 + currentDeviceChannelsLenth: 0, + winHeight: window.innerHeight - 200, + currentPage: 1, + count: 15, + total: 0, + getDeviceListLoading: false, + }; + }, + computed: { + getcurrentDeviceChannels: function () { + let data = this.currentDevice['channelMap']; + let channels = null; + if (data) { + channels = Object.keys(data).map(key => { + return data[key]; }); + this.currentDeviceChannelsLenth = channels.length; + } + return channels; + } + }, + mounted() { + this.initData(); + this.updateLooper = setInterval(this.initData, 10000); + }, + destroyed() { + this.$destroy('videojs'); + clearTimeout(this.updateLooper); + }, + methods: { + initData: function () { + this.getDeviceList(); + }, + currentChange: function (val) { + this.currentPage = val; + this.getDeviceList(); + }, + handleSizeChange: function (val) { + this.count = val; + this.getDeviceList(); + }, + getDeviceList: function () { + let that = this; + this.getDeviceListLoading = true; + this.$axios({ + method: 'get', + url: `/api/device/query/devices`, + params: { + page: that.currentPage, + count: that.count + } + }).then(function (res) { + that.total = res.data.total; + that.deviceList = res.data.list; + that.getDeviceListLoading = false; + }).catch(function (error) { + console.error(error); + that.getDeviceListLoading = false; + }); + + }, + deleteDevice: function (row) { + let msg = "纭畾鍒犻櫎姝よ澶囷紵" + if (row.online !== 0) { + msg = "鍦ㄧ嚎璁惧鍒犻櫎鍚庝粛鍙�氳繃娉ㄥ唽鍐嶆涓婄嚎銆�<br/>濡傞渶褰诲簳鍒犻櫎璇峰厛灏嗚澶囩绾裤��<br/><strong>纭畾鍒犻櫎姝よ澶囷紵</strong>" + } + this.$confirm(msg, '鎻愮ず', { + dangerouslyUseHTMLString: true, + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + center: true, + type: 'warning' + }).then(() => { + this.$axios({ + method: 'delete', + url: `/api/device/query/devices/${row.deviceId}/delete` + }).then((res) => { + this.getDeviceList(); + }).catch((error) => { + console.error(error); + }); + }).catch(() => { + + }); - }, - showChannelList: function(row) { - this.$router.push(`/channelList/${row.deviceId}/0/15/1`); - }, - showDevicePosition: function(row) { - this.$router.push(`/devicePosition/${row.deviceId}/0/15/1`); - }, + }, + showChannelList: function (row) { + this.$router.push(`/channelList/${row.deviceId}/0/15/1`); + }, + showDevicePosition: function (row) { + this.$router.push(`/devicePosition/${row.deviceId}/0/15/1`); + }, - //gb28181骞冲彴瀵规帴 - //鍒锋柊璁惧淇℃伅 - refDevice: function(itemData) { - console.log("鍒锋柊瀵瑰簲璁惧:" + itemData.deviceId); - let that = this; - this.$axios({ - method: 'post', - url: '/api/device/query/devices/' + itemData.deviceId + '/sync' - }).then((res) => { - console.log("鍒锋柊璁惧缁撴灉锛�"+JSON.stringify(res)); - if (res.data.code !==0) { - that.$message({ - showClose: true, - message: res.data.msg, - type: 'error' - }); - }else{ - // that.$message({ - // showClose: true, - // message: res.data.msg, - // type: 'success' - // }); - this.$refs.syncChannelProgress.openDialog(itemData.deviceId) - } - that.initData() - }).catch((e) => { - console.error(e) + //gb28181骞冲彴瀵规帴 + //鍒锋柊璁惧淇℃伅 + refDevice: function (itemData) { + console.log("鍒锋柊瀵瑰簲璁惧:" + itemData.deviceId); + let that = this; + this.$axios({ + method: 'post', + url: '/api/device/query/devices/' + itemData.deviceId + '/sync' + }).then((res) => { + console.log("鍒锋柊璁惧缁撴灉锛�" + JSON.stringify(res)); + if (res.data.code !== 0) { that.$message({ showClose: true, - message: e, + message: res.data.msg, type: 'error' }); - }); - - }, - - getTooltipContent: async function (deviceId){ - let result = ""; - await this.$axios({ - method: 'get', - async: false, - url:`/api/device/query/${deviceId}/sync_status/`, - }).then((res) => { - if (res.data.code == 0) { - if (res.data.data.errorMsg !== null) { - result = res.data.data.errorMsg - } else if (res.data.msg !== null) { - result = res.data.msg - } else { - result = `鍚屾涓�...[${res.data.data.current}/${res.data.data.total}]`; - } - } - }) - return result; - }, - //閫氱煡璁惧涓婁紶濯掍綋娴� - sendDevicePush: function(itemData) { - // let deviceId = this.currentDevice.deviceId; - // let channelId = itemData.channelId; - // console.log("閫氱煡璁惧鎺ㄦ祦1锛�" + deviceId + " : " + channelId); - // let that = this; - // this.$axios({ - // method: 'get', - // url: '/api/play/' + deviceId + '/' + channelId - // }).then(function(res) { - // let ssrc = res.data.ssrc; - // that.$refs.devicePlayer.play(ssrc,deviceId,channelId); - // }).catch(function(e) { - // }); - }, - transportChange: function (row) { - console.log(`淇敼浼犺緭鏂瑰紡涓� ${row.streamMode}锛�${row.deviceId} `); - let that = this; - this.$axios({ - method: 'post', - url: '/api/device/query/transport/' + row.deviceId + '/' + row.streamMode - }).then(function(res) { - - }).catch(function(e) { + } else { + // that.$message({ + // showClose: true, + // message: res.data.msg, + // type: 'success' + // }); + this.$refs.syncChannelProgress.openDialog(itemData.deviceId) + } + that.initData() + }).catch((e) => { + console.error(e) + that.$message({ + showClose: true, + message: e, + type: 'error' }); - }, - edit: function (row) { - this.$refs.deviceEdit.openDialog(row, ()=>{ - this.$refs.deviceEdit.close(); - this.$message({ - showClose: true, - message: "璁惧淇敼鎴愬姛锛岄�氶亾瀛楃闆嗗皢鍦ㄤ笅娆℃洿鏂扮敓鏁�", - type: "success", - }); - setTimeout(this.getDeviceList, 200) + }); - }) - } + }, - } - }; + getTooltipContent: async function (deviceId) { + let result = ""; + await this.$axios({ + method: 'get', + async: false, + url: `/api/device/query/${deviceId}/sync_status/`, + }).then((res) => { + if (res.data.code == 0) { + if (res.data.data.errorMsg !== null) { + result = res.data.data.errorMsg + } else if (res.data.msg !== null) { + result = res.data.msg + } else { + result = `鍚屾涓�...[${res.data.data.current}/${res.data.data.total}]`; + } + } + }) + return result; + }, + //閫氱煡璁惧涓婁紶濯掍綋娴� + sendDevicePush: function (itemData) { + // let deviceId = this.currentDevice.deviceId; + // let channelId = itemData.channelId; + // console.log("閫氱煡璁惧鎺ㄦ祦1锛�" + deviceId + " : " + channelId); + // let that = this; + // this.$axios({ + // method: 'get', + // url: '/api/play/' + deviceId + '/' + channelId + // }).then(function(res) { + // let ssrc = res.data.ssrc; + // that.$refs.devicePlayer.play(ssrc,deviceId,channelId); + // }).catch(function(e) { + // }); + }, + transportChange: function (row) { + console.log(`淇敼浼犺緭鏂瑰紡涓� ${row.streamMode}锛�${row.deviceId} `); + let that = this; + this.$axios({ + method: 'post', + url: '/api/device/query/transport/' + row.deviceId + '/' + row.streamMode + }).then(function (res) { + + }).catch(function (e) { + }); + }, + edit: function (row) { + this.$refs.deviceEdit.openDialog(row, () => { + this.$refs.deviceEdit.close(); + this.$message({ + showClose: true, + message: "璁惧淇敼鎴愬姛锛岄�氶亾瀛楃闆嗗皢鍦ㄤ笅娆℃洿鏂扮敓鏁�", + type: "success", + }); + setTimeout(this.getDeviceList, 200) + + }) + } + + } +}; </script> <style> - .videoList { - display: flex; - flex-wrap: wrap; - align-content: flex-start; - } +.videoList { + display: flex; + flex-wrap: wrap; + align-content: flex-start; +} - .video-item { - position: relative; - width: 15rem; - height: 10rem; - margin-right: 1rem; - background-color: #000000; - } +.video-item { + position: relative; + width: 15rem; + height: 10rem; + margin-right: 1rem; + background-color: #000000; +} - .video-item-img { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - margin: auto; - width: 100%; - height: 100%; - } +.video-item-img { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + width: 100%; + height: 100%; +} - .video-item-img:after { - content: ""; - display: inline-block; - position: absolute; - z-index: 2; - top: 0; - bottom: 0; - left: 0; - right: 0; - margin: auto; - width: 3rem; - height: 3rem; - background-image: url("../assets/loading.png"); - background-size: cover; - background-color: #000000; - } +.video-item-img:after { + content: ""; + display: inline-block; + position: absolute; + z-index: 2; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + width: 3rem; + height: 3rem; + background-image: url("../assets/loading.png"); + background-size: cover; + background-color: #000000; +} - .video-item-title { - position: absolute; - bottom: 0; - color: #000000; - background-color: #ffffff; - line-height: 1.5rem; - padding: 0.3rem; - width: 14.4rem; - } +.video-item-title { + position: absolute; + bottom: 0; + color: #000000; + background-color: #ffffff; + line-height: 1.5rem; + padding: 0.3rem; + width: 14.4rem; +} </style> diff --git a/web_src/src/components/MediaServerManger.vue b/web_src/src/components/MediaServerManger.vue index c412bcb..2e3eeef 100644 --- a/web_src/src/components/MediaServerManger.vue +++ b/web_src/src/components/MediaServerManger.vue @@ -1,45 +1,38 @@ <template> - <div id="mediaServerManger"> - <el-container> - <el-header> - <uiHeader></uiHeader> - </el-header> - <el-main id="msMain"> - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> - <span style="font-size: 1rem; font-weight: bold;">鑺傜偣鍒楄〃</span> - </div> - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> - <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="add">娣诲姞鑺傜偣</el-button> - </div> + <div id="mediaServerManger" style="width: 100%"> + <div class="page-header"> + <div class="page-title">鑺傜偣鍒楄〃</div> + <div class="page-header-btn"> + <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="add">娣诲姞鑺傜偣</el-button> + </div> + </div> - <el-row :gutter="12"> - <el-col :span="num" v-for="item in mediaServerList" :key="item.id"> - <el-card shadow="hover" :body-style="{ padding: '0px'}" class="server-card"> - <div class="card-img-zlm"></div> - <div style="padding: 14px;text-align: left"> - <span style="font-size: 16px">{{item.id}}</span> - <el-button v-if="!item.defaultServer" icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">缂栬緫</el-button> - <el-button v-if="item.defaultServer" icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">鏌ョ湅</el-button> - <el-button icon="el-icon-delete" style="margin-right: 10px;padding: 0;float: right;" type="text" @click="del(item)">绉婚櫎</el-button> - <div style="margin-top: 13px; line-height: 12px; "> - <span style="font-size: 14px; color: #999; margin-top: 5px; ">{{item.ip}}</span> - <span style="font-size: 14px; color: #999; margin-top: 5px; float: right;">{{item.createTime}}</span> - </div> - </div> - <i v-if="item.status" class="iconfont icon-online server-card-status-online" title="鍦ㄧ嚎"></i> - <i v-if="!item.status" class="iconfont icon-online server-card-status-offline" title="绂荤嚎"></i> - <i v-if="item.defaultServer" class="server-card-default" >榛樿</i> - </el-card> - </el-col> - </el-row> - <mediaServerEdit ref="mediaServerEdit" ></mediaServerEdit> - </el-main> - </el-container> + <el-row :gutter="12"> + <el-col :span="num" v-for="item in mediaServerList" :key="item.id"> + <el-card shadow="hover" :body-style="{ padding: '0px'}" class="server-card"> + <div class="card-img-zlm"></div> + <div style="padding: 14px;text-align: left"> + <span style="font-size: 16px">{{item.id}}</span> + <el-button v-if="!item.defaultServer" icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">缂栬緫</el-button> + <el-button v-if="item.defaultServer" icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">鏌ョ湅</el-button> + <el-button icon="el-icon-delete" style="margin-right: 10px;padding: 0;float: right;" type="text" @click="del(item)">绉婚櫎</el-button> + <div style="margin-top: 13px; line-height: 12px; "> + <span style="font-size: 14px; color: #999; margin-top: 5px; ">{{item.ip}}</span> + <span style="font-size: 14px; color: #999; margin-top: 5px; float: right;">{{item.createTime}}</span> + </div> + </div> + <i v-if="item.status" class="iconfont icon-online server-card-status-online" title="鍦ㄧ嚎"></i> + <i v-if="!item.status" class="iconfont icon-online server-card-status-offline" title="绂荤嚎"></i> + <i v-if="item.defaultServer" class="server-card-default" >榛樿</i> + </el-card> + </el-col> + </el-row> + <mediaServerEdit ref="mediaServerEdit" ></mediaServerEdit> </div> </template> <script> - import uiHeader from './UiHeader.vue' + import uiHeader from '../layout/UiHeader.vue' import MediaServer from './service/MediaServer' import mediaServerEdit from './dialog/MediaServerEdit' export default { diff --git a/web_src/src/components/ParentPlatformList.vue b/web_src/src/components/ParentPlatformList.vue index 5becea5..20a3e82 100644 --- a/web_src/src/components/ParentPlatformList.vue +++ b/web_src/src/components/ParentPlatformList.vue @@ -1,85 +1,79 @@ <template> - <div id="app"> - <el-container> - <el-header> - <uiHeader></uiHeader> - </el-header> - <el-main> - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> - <span style="font-size: 1rem; font-weight: bold;">涓婄骇骞冲彴鍒楄〃</span> - </div> - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> - <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addParentPlatform">娣诲姞</el-button> - </div> - <!--璁惧鍒楄〃--> - <el-table :data="platformList" border style="width: 100%" :height="winHeight"> - <el-table-column prop="name" label="鍚嶇О" align="center"></el-table-column> - <el-table-column prop="serverGBId" label="骞冲彴缂栧彿" width="180" align="center"></el-table-column> - <el-table-column label="鏄惁鍚敤" width="120" align="center"> - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.enable">宸插惎鐢�</el-tag> - <el-tag size="medium" type="info" v-if="!scope.row.enable">鏈惎鐢�</el-tag> - </div> - </template> - </el-table-column> - <el-table-column label="鐘舵��" width="120" align="center"> - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.status">鍦ㄧ嚎</el-tag> - <el-tag size="medium" type="info" v-if="!scope.row.status">绂荤嚎</el-tag> - </div> - </template> - </el-table-column> - <el-table-column label="鍦板潃" width="180" align="center"> - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> - <el-tag size="medium">{{ scope.row.serverIP}}:{{scope.row.serverPort }}</el-tag> - </div> - </template> - </el-table-column> - <el-table-column prop="deviceGBId" label="璁惧鍥芥爣缂栧彿" width="200" align="center"></el-table-column> - <el-table-column prop="transport" label="淇′护浼犺緭妯″紡" width="120" align="center"></el-table-column> - <el-table-column prop="channelCount" label="閫氶亾鏁�" width="120" align="center"></el-table-column> - <el-table-column label="璁㈤槄淇℃伅" width="240" align="center" fixed="right"> - <template slot-scope="scope"> - <i v-if="scope.row.alarmSubscribe" style="font-size: 20px" title="鎶ヨ璁㈤槄" class="iconfont icon-gbaojings subscribe-on " ></i> - <i v-if="!scope.row.alarmSubscribe" style="font-size: 20px" title="鎶ヨ璁㈤槄" class="iconfont icon-gbaojings subscribe-off " ></i> - <i v-if="scope.row.catalogSubscribe" title="鐩綍璁㈤槄" class="iconfont icon-gjichus subscribe-on" ></i> - <i v-if="!scope.row.catalogSubscribe" title="鐩綍璁㈤槄" class="iconfont icon-gjichus subscribe-off" ></i> - <i v-if="scope.row.mobilePositionSubscribe" title="浣嶇疆璁㈤槄" class="iconfont icon-gxunjians subscribe-on" ></i> - <i v-if="!scope.row.mobilePositionSubscribe" title="浣嶇疆璁㈤槄" class="iconfont icon-gxunjians subscribe-off" ></i> - </template> - </el-table-column> + <div id="app" style="width: 100%"> + <div class="page-header"> + <div class="page-title">涓婄骇骞冲彴鍒楄〃</div> + <div class="page-header-btn"> + <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addParentPlatform">娣诲姞</el-button> + </div> + </div> - <el-table-column label="鎿嶄綔" width="300" align="center" fixed="right"> - <template slot-scope="scope"> - <el-button size="mini" icon="el-icon-edit" @click="editPlatform(scope.row)">缂栬緫</el-button> - <el-button size="mini" icon="el-icon-share" type="primary" @click="chooseChannel(scope.row)">閫夋嫨閫氶亾</el-button> - <el-button size="mini" icon="el-icon-delete" type="danger" @click="deletePlatform(scope.row)">鍒犻櫎</el-button> - </template> - </el-table-column> - </el-table> - <el-pagination - style="float: right" - @size-change="handleSizeChange" - @current-change="currentChange" - :current-page="currentPage" - :page-size="count" - :page-sizes="[15, 25, 35, 50]" - layout="total, sizes, prev, pager, next" - :total="total"> - </el-pagination> - <platformEdit ref="platformEdit" ></platformEdit> - <chooseChannelDialog ref="chooseChannelDialog" ></chooseChannelDialog> - </el-main> - </el-container> + <!--璁惧鍒楄〃--> + <el-table :data="platformList" border style="width: 100%" :height="winHeight"> + <el-table-column prop="name" label="鍚嶇О" align="center"></el-table-column> + <el-table-column prop="serverGBId" label="骞冲彴缂栧彿" align="center"></el-table-column> + <el-table-column label="鏄惁鍚敤" width="120" align="center"> + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> + <el-tag size="medium" v-if="scope.row.enable">宸插惎鐢�</el-tag> + <el-tag size="medium" type="info" v-if="!scope.row.enable">鏈惎鐢�</el-tag> + </div> + </template> + </el-table-column> + <el-table-column label="鐘舵��" width="120" align="center"> + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> + <el-tag size="medium" v-if="scope.row.status">鍦ㄧ嚎</el-tag> + <el-tag size="medium" type="info" v-if="!scope.row.status">绂荤嚎</el-tag> + </div> + </template> + </el-table-column> + <el-table-column label="鍦板潃" width="180" align="center"> + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> + <el-tag size="medium">{{ scope.row.serverIP}}:{{scope.row.serverPort }}</el-tag> + </div> + </template> + </el-table-column> + <el-table-column prop="deviceGBId" label="璁惧鍥芥爣缂栧彿" width="200" align="center"></el-table-column> + <el-table-column prop="transport" label="淇′护浼犺緭妯″紡" width="120" align="center"></el-table-column> + <el-table-column prop="channelCount" label="閫氶亾鏁�" width="120" align="center"></el-table-column> + <el-table-column label="璁㈤槄淇℃伅" width="240" align="center" fixed="right"> + <template slot-scope="scope"> + <i v-if="scope.row.alarmSubscribe" style="font-size: 20px" title="鎶ヨ璁㈤槄" class="iconfont icon-gbaojings subscribe-on " ></i> + <i v-if="!scope.row.alarmSubscribe" style="font-size: 20px" title="鎶ヨ璁㈤槄" class="iconfont icon-gbaojings subscribe-off " ></i> + <i v-if="scope.row.catalogSubscribe" title="鐩綍璁㈤槄" class="iconfont icon-gjichus subscribe-on" ></i> + <i v-if="!scope.row.catalogSubscribe" title="鐩綍璁㈤槄" class="iconfont icon-gjichus subscribe-off" ></i> + <i v-if="scope.row.mobilePositionSubscribe" title="浣嶇疆璁㈤槄" class="iconfont icon-gxunjians subscribe-on" ></i> + <i v-if="!scope.row.mobilePositionSubscribe" title="浣嶇疆璁㈤槄" class="iconfont icon-gxunjians subscribe-off" ></i> + </template> + </el-table-column> + + <el-table-column label="鎿嶄綔" width="300" align="center" fixed="right"> + <template slot-scope="scope"> + <el-button size="mini" icon="el-icon-edit" @click="editPlatform(scope.row)">缂栬緫</el-button> + <el-button size="mini" icon="el-icon-share" type="primary" @click="chooseChannel(scope.row)">閫夋嫨閫氶亾</el-button> + <el-button size="mini" icon="el-icon-delete" type="danger" @click="deletePlatform(scope.row)">鍒犻櫎</el-button> + </template> + </el-table-column> + </el-table> + <el-pagination + style="float: right" + @size-change="handleSizeChange" + @current-change="currentChange" + :current-page="currentPage" + :page-size="count" + :page-sizes="[15, 25, 35, 50]" + layout="total, sizes, prev, pager, next" + :total="total"> + </el-pagination> + <platformEdit ref="platformEdit" ></platformEdit> + <chooseChannelDialog ref="chooseChannelDialog" ></chooseChannelDialog> </div> </template> <script> import platformEdit from './dialog/platformEdit.vue' -import uiHeader from './UiHeader.vue' +import uiHeader from '../layout/UiHeader.vue' import chooseChannelDialog from './dialog/chooseChannel.vue' export default { name: 'app', diff --git a/web_src/src/components/PushVideoList.vue b/web_src/src/components/PushVideoList.vue index 4c803da..7b5a406 100644 --- a/web_src/src/components/PushVideoList.vue +++ b/web_src/src/components/PushVideoList.vue @@ -1,18 +1,14 @@ <template> - <div id="pushVideoList"> - <el-container> - <el-header> - <uiHeader></uiHeader> - </el-header> - <el-main> - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> - <span style="font-size: 1rem; font-weight: bold;">鎺ㄦ祦鍒楄〃</span> - </div> - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> - - 鎼滅储: <el-input @input="getPushList" style="margin-right: 1rem; width: auto;" size="mini" placeholder="鍏抽敭瀛�" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input> - - 娴佸獟浣�: <el-select size="mini" @change="getPushList" style="margin-right: 1rem;" v-model="mediaServerId" placeholder="璇烽�夋嫨" default-first-option> + <div id="pushVideoList" style="width: 100%"> + <div class="page-header"> + <div class="page-title">鎺ㄦ祦鍒楄〃</div> + <div class="page-header-btn"> + 鎼滅储: + <el-input @input="getPushList" style="margin-right: 1rem; width: auto;" size="mini" placeholder="鍏抽敭瀛�" + prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input> + 娴佸獟浣�: + <el-select size="mini" @change="getPushList" style="margin-right: 1rem;" v-model="mediaServerId" + placeholder="璇烽�夋嫨" default-first-option> <el-option label="鍏ㄩ儴" value=""></el-option> <el-option v-for="item in mediaServerList" @@ -21,309 +17,327 @@ :value="item.id"> </el-option> </el-select> - 鎺ㄦ祦鐘舵��: <el-select size="mini" style="margin-right: 1rem;" @change="getPushList" v-model="pushing" placeholder="璇烽�夋嫨" default-first-option> + 鎺ㄦ祦鐘舵��: + <el-select size="mini" style="margin-right: 1rem;" @change="getPushList" v-model="pushing" placeholder="璇烽�夋嫨" + default-first-option> <el-option label="鍏ㄩ儴" value=""></el-option> <el-option label="鎺ㄦ祦杩涜涓�" value="true"></el-option> <el-option label="鎺ㄦ祦鏈繘琛�" value="false"></el-option> </el-select> - <el-button icon="el-icon-upload2" size="mini" style="margin-right: 1rem;" type="primary" @click="importChannel">閫氶亾瀵煎叆</el-button> - <el-button icon="el-icon-download" size="mini" style="margin-right: 1rem;" type="primary" > - <a style="color: #FFFFFF; text-align: center; text-decoration: none" href="/static/file/鎺ㄦ祦閫氶亾瀵煎叆.zip" download='鎺ㄦ祦閫氶亾瀵煎叆.zip' >涓嬭浇妯℃澘</a> - </el-button> - <el-button icon="el-icon-delete" size="mini" style="margin-right: 1rem;" :disabled="multipleSelection.length === 0" type="danger" @click="batchDel">鎵归噺绉婚櫎</el-button> - </div> - <devicePlayer ref="devicePlayer"></devicePlayer> - <addStreamTOGB ref="addStreamTOGB"></addStreamTOGB> - <el-table ref="pushListTable" :data="pushList" border style="width: 100%" :height="winHeight" @selection-change="handleSelectionChange" :row-key="(row)=> row.app + row.stream"> - <el-table-column align="center" type="selection" :reserve-selection="true" width="55"> - </el-table-column> - <el-table-column prop="name" label="鍚嶇О" align="center"> - </el-table-column> - <el-table-column prop="app" label="APP" align="center"> - </el-table-column> - <el-table-column prop="stream" label="娴両D" align="center"> - </el-table-column> - <el-table-column prop="gbId" label="鍥芥爣缂栫爜" width="200" align="center"> - </el-table-column> - <el-table-column prop="mediaServerId" label="娴佸獟浣�" width="200" align="center"> - </el-table-column> - <el-table-column label="寮�濮嬫椂闂�" align="center" width="200"> - <template slot-scope="scope"> - <el-button-group> - {{dateFormat(parseInt(scope.row.createStamp))}} - </el-button-group> - </template> - </el-table-column> - <el-table-column label="姝e湪鎺ㄦ祦" align="center" width="100"> - <template slot-scope="scope"> - {{(scope.row.status == false && scope.row.gbId == null) || scope.row.status ?'鏄�':'鍚�'}} - </template> - </el-table-column> + <el-button icon="el-icon-upload2" size="mini" style="margin-right: 1rem;" type="primary" @click="importChannel"> + 閫氶亾瀵煎叆 + </el-button> + <el-button icon="el-icon-download" size="mini" style="margin-right: 1rem;" type="primary"> + <a style="color: #FFFFFF; text-align: center; text-decoration: none" href="/static/file/鎺ㄦ祦閫氶亾瀵煎叆.zip" + download='鎺ㄦ祦閫氶亾瀵煎叆.zip'>涓嬭浇妯℃澘</a> + </el-button> + <el-button icon="el-icon-delete" size="mini" style="margin-right: 1rem;" + :disabled="multipleSelection.length === 0" type="danger" @click="batchDel">鎵归噺绉婚櫎 + </el-button> + </div> + </div> + <devicePlayer ref="devicePlayer"></devicePlayer> + <addStreamTOGB ref="addStreamTOGB"></addStreamTOGB> + <el-table ref="pushListTable" :data="pushList" border style="width: 100%" :height="winHeight" + @selection-change="handleSelectionChange" :row-key="(row)=> row.app + row.stream"> + <el-table-column align="center" type="selection" :reserve-selection="true" width="55"> + </el-table-column> + <el-table-column prop="name" label="鍚嶇О" align="center"> + </el-table-column> + <el-table-column prop="app" label="APP" align="center"> + </el-table-column> + <el-table-column prop="stream" label="娴両D" align="center"> + </el-table-column> + <el-table-column prop="gbId" label="鍥芥爣缂栫爜" width="200" align="center"> + </el-table-column> + <el-table-column prop="mediaServerId" label="娴佸獟浣�" width="200" align="center"> + </el-table-column> + <el-table-column label="寮�濮嬫椂闂�" align="center" width="200"> + <template slot-scope="scope"> + <el-button-group> + {{ dateFormat(parseInt(scope.row.createStamp)) }} + </el-button-group> + </template> + </el-table-column> + <el-table-column label="姝e湪鎺ㄦ祦" align="center" width="100"> + <template slot-scope="scope"> + {{ (scope.row.status == false && scope.row.gbId == null) || scope.row.status ? '鏄�' : '鍚�' }} + </template> + </el-table-column> - <el-table-column label="鎿嶄綔" width="360" align="center" fixed="right"> - <template slot-scope="scope"> - <el-button-group> - <el-button size="mini" icon="el-icon-video-play" v-if="(scope.row.status == false && scope.row.gbId == null) || scope.row.status" @click="playPush(scope.row)">鎾斁</el-button> - <el-button size="mini" icon="el-icon-delete" type="danger" @click="stopPush(scope.row)">绉婚櫎</el-button> - <el-button size="mini" icon="el-icon-position" type="primary" v-if="!!!scope.row.gbId" @click="addToGB(scope.row)">鍔犲叆鍥芥爣</el-button> - <el-button size="mini" icon="el-icon-position" type="primary" v-if="!!scope.row.gbId" @click="removeFromGB(scope.row)">绉诲嚭鍥芥爣</el-button> - </el-button-group> - </template> - </el-table-column> - </el-table> - <el-pagination - style="float: right" - @size-change="handleSizeChange" - @current-change="currentChange" - :current-page="currentPage" - :page-size="count" - :page-sizes="[15, 25, 35, 50]" - layout="total, sizes, prev, pager, next" - :total="total"> - </el-pagination> - <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit> - <importChannel ref="importChannel" ></importChannel> - </el-main> - </el-container> - </div> + <el-table-column label="鎿嶄綔" width="360" align="center" fixed="right"> + <template slot-scope="scope"> + <el-button-group> + <el-button size="mini" icon="el-icon-video-play" + v-if="(scope.row.status == false && scope.row.gbId == null) || scope.row.status" + @click="playPush(scope.row)">鎾斁 + </el-button> + <el-button size="mini" icon="el-icon-delete" type="danger" @click="stopPush(scope.row)">绉婚櫎</el-button> + <el-button size="mini" icon="el-icon-position" type="primary" v-if="!!!scope.row.gbId" + @click="addToGB(scope.row)">鍔犲叆鍥芥爣 + </el-button> + <el-button size="mini" icon="el-icon-position" type="primary" v-if="!!scope.row.gbId" + @click="removeFromGB(scope.row)">绉诲嚭鍥芥爣 + </el-button> + </el-button-group> + </template> + </el-table-column> + </el-table> + <el-pagination + style="float: right" + @size-change="handleSizeChange" + @current-change="currentChange" + :current-page="currentPage" + :page-size="count" + :page-sizes="[15, 25, 35, 50]" + layout="total, sizes, prev, pager, next" + :total="total"> + </el-pagination> + <streamProxyEdit ref="streamProxyEdit"></streamProxyEdit> + <importChannel ref="importChannel"></importChannel> + </div> </template> <script> - import streamProxyEdit from './dialog/StreamProxyEdit.vue' - import devicePlayer from './dialog/devicePlayer.vue' - import addStreamTOGB from './dialog/addStreamTOGB.vue' - import uiHeader from './UiHeader.vue' - import importChannel from './dialog/importChannel.vue' - import MediaServer from './service/MediaServer' - export default { - name: 'pushVideoList', - components: { - devicePlayer, - addStreamTOGB, - streamProxyEdit, - uiHeader, - importChannel, - }, - data() { - return { - pushList: [], //璁惧鍒楄〃 - currentPusher: {}, //褰撳墠鎿嶄綔璁惧瀵硅薄 - updateLooper: 0, //鏁版嵁鍒锋柊杞鏍囧織 - currentDeviceChannelsLenth:0, - winHeight: window.innerHeight - 250, - mediaServerObj : new MediaServer(), - currentPage:1, - count:15, - total:0, - searchSrt: "", - pushing: "", - mediaServerId: "", - mediaServerList: [], - multipleSelection: [], - getDeviceListLoading: false - }; - }, - computed: { - }, - mounted() { - this.initData(); - this.updateLooper = setInterval(this.getPushList, 2000); - }, - destroyed() { - clearTimeout(this.updateLooper); - }, - methods: { - initData: function() { - this.mediaServerObj.getOnlineMediaServerList((data)=>{ - this.mediaServerList = data.data; - }) - this.getPushList(); - }, - currentChange: function(val){ - this.currentPage = val; - this.getPushList(); - }, - handleSizeChange: function(val){ - this.count = val; - this.getPushList(); - }, - getPushList: function() { - let that = this; - this.getDeviceListLoading = true; - this.$axios({ - method: 'get', - url:`/api/push/list`, - params: { - page: that.currentPage, - count: that.count, - query: that.searchSrt, - pushing: that.pushing, - mediaServerId: that.mediaServerId, - } - }).then(function (res) { - that.total = res.data.total; - that.pushList = res.data.list; - that.getDeviceListLoading = false; - }).catch(function (error) { - console.error(error); - that.getDeviceListLoading = false; - }); - }, +import streamProxyEdit from './dialog/StreamProxyEdit.vue' +import devicePlayer from './dialog/devicePlayer.vue' +import addStreamTOGB from './dialog/addStreamTOGB.vue' +import uiHeader from '../layout/UiHeader.vue' +import importChannel from './dialog/importChannel.vue' +import MediaServer from './service/MediaServer' - playPush: function(row){ - let that = this; - this.getListLoading = true; - this.$axios({ - method: 'get', - url: '/api/media/stream_info_by_app_and_stream', - params: { - app: row.app, - stream: row.stream, - mediaServerId: row.mediaServerId - } - }).then(function (res) { - that.getListLoading = false; - that.$refs.devicePlayer.openDialog("streamPlay", null, null, { - streamInfo: res.data.data, - hasAudio: true - }); - }).catch(function (error) { - console.error(error); - that.getListLoading = false; - }); - }, - stopPush: function(row){ +export default { + name: 'pushVideoList', + components: { + devicePlayer, + addStreamTOGB, + streamProxyEdit, + uiHeader, + importChannel, + }, + data() { + return { + pushList: [], //璁惧鍒楄〃 + currentPusher: {}, //褰撳墠鎿嶄綔璁惧瀵硅薄 + updateLooper: 0, //鏁版嵁鍒锋柊杞鏍囧織 + currentDeviceChannelsLenth: 0, + winHeight: window.innerHeight - 250, + mediaServerObj: new MediaServer(), + currentPage: 1, + count: 15, + total: 0, + searchSrt: "", + pushing: "", + mediaServerId: "", + mediaServerList: [], + multipleSelection: [], + getDeviceListLoading: false + }; + }, + computed: {}, + mounted() { + this.initData(); + this.updateLooper = setInterval(this.getPushList, 2000); + }, + destroyed() { + clearTimeout(this.updateLooper); + }, + methods: { + initData: function () { + this.mediaServerObj.getOnlineMediaServerList((data) => { + this.mediaServerList = data.data; + }) + this.getPushList(); + }, + currentChange: function (val) { + this.currentPage = val; + this.getPushList(); + }, + handleSizeChange: function (val) { + this.count = val; + this.getPushList(); + }, + getPushList: function () { + let that = this; + this.getDeviceListLoading = true; + this.$axios({ + method: 'get', + url: `/api/push/list`, + params: { + page: that.currentPage, + count: that.count, + query: that.searchSrt, + pushing: that.pushing, + mediaServerId: that.mediaServerId, + } + }).then(function (res) { + that.total = res.data.total; + that.pushList = res.data.list; + that.getDeviceListLoading = false; + }).catch(function (error) { + console.error(error); + that.getDeviceListLoading = false; + }); + }, + + playPush: function (row) { + let that = this; + this.getListLoading = true; + this.$axios({ + method: 'get', + url: '/api/media/stream_info_by_app_and_stream', + params: { + app: row.app, + stream: row.stream, + mediaServerId: row.mediaServerId + } + }).then(function (res) { + that.getListLoading = false; + that.$refs.devicePlayer.openDialog("streamPlay", null, null, { + streamInfo: res.data.data, + hasAudio: true + }); + }).catch(function (error) { + console.error(error); + that.getListLoading = false; + }); + }, + stopPush: function (row) { + let that = this; + that.$axios({ + method: "post", + url: "/api/push/stop", + params: { + app: row.app, + streamId: row.stream + } + }).then((res) => { + if (res.data == "success") { + that.initData() + } + }).catch(function (error) { + console.error(error); + }); + }, + addToGB: function (row) { + this.$refs.addStreamTOGB.openDialog({ + app: row.app, + stream: row.stream, + mediaServerId: row.mediaServerId + }, this.initData); + }, + removeFromGB: function (row) { + let that = this; + that.$axios({ + method: "delete", + url: "/api/push/remove_form_gb", + data: row + }).then((res) => { + if (res.data == "success") { + that.initData() + } + }).catch(function (error) { + console.error(error); + }); + }, + dateFormat: function (/** timestamp=0 **/) { + let ts = arguments[0] || 0; + let t, y, m, d, h, i, s; + t = ts ? new Date(ts) : new Date(); + y = t.getFullYear(); + m = t.getMonth() + 1; + d = t.getDate(); + h = t.getHours(); + i = t.getMinutes(); + s = t.getSeconds(); + // 鍙牴鎹渶瑕佸湪杩欓噷瀹氫箟鏃堕棿鏍煎紡 + return y + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d) + ' ' + (h < 10 ? '0' + h : h) + ':' + (i < 10 ? '0' + i : i) + ':' + (s < 10 ? '0' + s : s); + }, + importChannel: function () { + this.$refs.importChannel.openDialog(() => { + + }) + }, + batchDel: function () { + this.$confirm(`纭畾鍒犻櫎閫変腑鐨�${this.multipleSelection.length}涓�氶亾?`, '鎻愮ず', { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' + }).then(() => { let that = this; that.$axios({ - method:"post", - url:"/api/push/stop", - params: { - app: row.app, - streamId: row.stream + method: "delete", + url: "/api/push/batchStop", + data: { + gbStreams: this.multipleSelection } - }).then((res)=>{ - if (res.data == "success") { - that.initData() - } + }).then((res) => { + this.initData(); + this.$refs.pushListTable.clearSelection(); }).catch(function (error) { console.error(error); }); - }, - addToGB: function(row){ - this.$refs.addStreamTOGB.openDialog({app: row.app, stream: row.stream, mediaServerId: row.mediaServerId}, this.initData); - }, - removeFromGB: function(row){ - let that = this; - that.$axios({ - method:"delete", - url:"/api/push/remove_form_gb", - data:row - }).then((res)=>{ - if (res.data == "success") { - that.initData() - } - }).catch(function (error) { - console.error(error); - }); - }, - dateFormat: function(/** timestamp=0 **/) { - let ts = arguments[0] || 0; - let t,y,m,d,h,i,s; - t = ts ? new Date(ts) : new Date(); - y = t.getFullYear(); - m = t.getMonth()+1; - d = t.getDate(); - h = t.getHours(); - i = t.getMinutes(); - s = t.getSeconds(); - // 鍙牴鎹渶瑕佸湪杩欓噷瀹氫箟鏃堕棿鏍煎紡 - return y+'-'+(m<10?'0'+m:m)+'-'+(d<10?'0'+d:d)+' '+(h<10?'0'+h:h)+':'+(i<10?'0'+i:i)+':'+(s<10?'0'+s:s); - }, - importChannel: function () { - this.$refs.importChannel.openDialog(()=>{ + }).catch(() => { - }) - }, - batchDel: function () { - this.$confirm(`纭畾鍒犻櫎閫変腑鐨�${this.multipleSelection.length}涓�氶亾?`, '鎻愮ず', { - confirmButtonText: '纭畾', - cancelButtonText: '鍙栨秷', - type: 'warning' - }).then(() => { - let that = this; - that.$axios({ - method:"delete", - url:"/api/push/batchStop", - data: { - gbStreams: this.multipleSelection - } - }).then((res)=>{ - this.initData(); - this.$refs.pushListTable.clearSelection(); - }).catch(function (error) { - console.error(error); - }); - }).catch(() => { - - }); - }, - handleSelectionChange: function (val) { - this.multipleSelection = val; - }, - } - }; + }); + }, + handleSelectionChange: function (val) { + this.multipleSelection = val; + }, + } +}; </script> <style> - .videoList { - display: flex; - flex-wrap: wrap; - align-content: flex-start; - } +.videoList { + display: flex; + flex-wrap: wrap; + align-content: flex-start; +} - .video-item { - position: relative; - width: 15rem; - height: 10rem; - margin-right: 1rem; - background-color: #000000; - } +.video-item { + position: relative; + width: 15rem; + height: 10rem; + margin-right: 1rem; + background-color: #000000; +} - .video-item-img { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - margin: auto; - width: 100%; - height: 100%; - } +.video-item-img { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + width: 100%; + height: 100%; +} - .video-item-img:after { - content: ""; - display: inline-block; - position: absolute; - z-index: 2; - top: 0; - bottom: 0; - left: 0; - right: 0; - margin: auto; - width: 3rem; - height: 3rem; - background-image: url("../assets/loading.png"); - background-size: cover; - background-color: #000000; - } +.video-item-img:after { + content: ""; + display: inline-block; + position: absolute; + z-index: 2; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + width: 3rem; + height: 3rem; + background-image: url("../assets/loading.png"); + background-size: cover; + background-color: #000000; +} - .video-item-title { - position: absolute; - bottom: 0; - color: #000000; - background-color: #ffffff; - line-height: 1.5rem; - padding: 0.3rem; - width: 14.4rem; - } +.video-item-title { + position: absolute; + bottom: 0; + color: #000000; + background-color: #ffffff; + line-height: 1.5rem; + padding: 0.3rem; + width: 14.4rem; +} </style> diff --git a/web_src/src/components/StreamProxyList.vue b/web_src/src/components/StreamProxyList.vue index 9ecb933..d553392 100644 --- a/web_src/src/components/StreamProxyList.vue +++ b/web_src/src/components/StreamProxyList.vue @@ -1,115 +1,108 @@ <template> - <div id="streamProxyList"> - <el-container> - <el-header> - <uiHeader></uiHeader> - </el-header> - <el-main> - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> - <span style="font-size: 1rem; font-weight: bold;">鎷夋祦浠g悊鍒楄〃</span> - </div> - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> - <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStreamProxy">娣诲姞浠g悊</el-button> - <el-button v-if="false" icon="el-icon-search" size="mini" style="margin-right: 1rem;" type="primary" @click="addOnvif">鎼滅储ONVIF</el-button> - </div> - <devicePlayer ref="devicePlayer"></devicePlayer> - <el-table :data="streamProxyList" border style="width: 100%" :height="winHeight"> - <el-table-column prop="name" label="鍚嶇О" align="center" show-overflow-tooltip/> - <el-table-column prop="app" label="娴佸簲鐢ㄥ悕" align="center" show-overflow-tooltip/> - <el-table-column prop="stream" label="娴両D" align="center" show-overflow-tooltip/> - <el-table-column label="娴佸湴鍧�" width="400" align="center" show-overflow-tooltip > - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> + <div id="streamProxyList" style="width: 100%"> + <div class="page-header"> + <div class="page-title">鎷夋祦浠g悊鍒楄〃</div> + <div class="page-header-btn"> + <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStreamProxy">娣诲姞浠g悊</el-button> + <el-button v-if="false" icon="el-icon-search" size="mini" style="margin-right: 1rem;" type="primary" @click="addOnvif">鎼滅储ONVIF</el-button> + </div> + </div> + <devicePlayer ref="devicePlayer"></devicePlayer> + <el-table :data="streamProxyList" border style="width: 100%" :height="winHeight"> + <el-table-column prop="name" label="鍚嶇О" align="center" show-overflow-tooltip/> + <el-table-column prop="app" label="娴佸簲鐢ㄥ悕" align="center" show-overflow-tooltip/> + <el-table-column prop="stream" label="娴両D" align="center" show-overflow-tooltip/> + <el-table-column label="娴佸湴鍧�" width="400" align="center" show-overflow-tooltip > + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.type == 'default'"> - <i class="cpoy-btn el-icon-document-copy" title="鐐瑰嚮鎷疯礉" v-clipboard="scope.row.url" @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></i> - {{scope.row.url}} - </el-tag> - <el-tag size="medium" v-if="scope.row.type != 'default'"> - <i class="cpoy-btn el-icon-document-copy" title="鐐瑰嚮鎷疯礉" v-clipboard="scope.row.src_url" @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></i> - {{scope.row.src_url}} - </el-tag> - </div> - </template> - </el-table-column> - <el-table-column prop="mediaServerId" label="娴佸獟浣�" width="150" align="center"></el-table-column> - <el-table-column label="绫诲瀷" width="100" align="center"> - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> - <el-tag size="medium">{{scope.row.type}}</el-tag> - </div> - </template> - </el-table-column> + <el-tag size="medium" v-if="scope.row.type == 'default'"> + <i class="cpoy-btn el-icon-document-copy" title="鐐瑰嚮鎷疯礉" v-clipboard="scope.row.url" @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></i> + {{scope.row.url}} + </el-tag> + <el-tag size="medium" v-if="scope.row.type != 'default'"> + <i class="cpoy-btn el-icon-document-copy" title="鐐瑰嚮鎷疯礉" v-clipboard="scope.row.src_url" @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></i> + {{scope.row.src_url}} + </el-tag> + </div> + </template> + </el-table-column> + <el-table-column prop="mediaServerId" label="娴佸獟浣�" width="150" align="center"></el-table-column> + <el-table-column label="绫诲瀷" width="100" align="center"> + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> + <el-tag size="medium">{{scope.row.type}}</el-tag> + </div> + </template> + </el-table-column> - <el-table-column prop="gbId" label="鍥芥爣缂栫爜" width="180" align="center" show-overflow-tooltip/> - <el-table-column label="鐘舵��" width="120" align="center"> - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.status">鍦ㄧ嚎</el-tag> - <el-tag size="medium" type="info" v-if="!scope.row.status">绂荤嚎</el-tag> - </div> - </template> - </el-table-column> - <el-table-column label="鍚敤" width="120" align="center"> - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.enable">宸插惎鐢�</el-tag> - <el-tag size="medium" type="info" v-if="!scope.row.enable">鏈惎鐢�</el-tag> - </div> - </template> - </el-table-column> - <el-table-column prop="createTime" label="鍒涘缓鏃堕棿" align="center" width="150" show-overflow-tooltip/> - <el-table-column label="杞琀LS" width="120" align="center"> - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.enable_hls">宸插惎鐢�</el-tag> - <el-tag size="medium" type="info" v-if="!scope.row.enable_hls">鏈惎鐢�</el-tag> - </div> - </template> - </el-table-column> - <el-table-column label="MP4褰曞埗" width="120" align="center"> - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.enable_mp4">宸插惎鐢�</el-tag> - <el-tag size="medium" type="info" v-if="!scope.row.enable_mp4">鏈惎鐢�</el-tag> - </div> - </template> - </el-table-column> - <el-table-column label="鏃犱汉瑙傜湅鑷姩鍒犻櫎" width="160" align="center"> - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.enable_remove_none_reader">宸插惎鐢�</el-tag> - <el-tag size="medium" type="info" v-if="!scope.row.enable_remove_none_reader">鏈惎鐢�</el-tag> - </div> - </template> - </el-table-column> + <el-table-column prop="gbId" label="鍥芥爣缂栫爜" width="180" align="center" show-overflow-tooltip/> + <el-table-column label="鐘舵��" width="120" align="center"> + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> + <el-tag size="medium" v-if="scope.row.status">鍦ㄧ嚎</el-tag> + <el-tag size="medium" type="info" v-if="!scope.row.status">绂荤嚎</el-tag> + </div> + </template> + </el-table-column> + <el-table-column label="鍚敤" width="120" align="center"> + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> + <el-tag size="medium" v-if="scope.row.enable">宸插惎鐢�</el-tag> + <el-tag size="medium" type="info" v-if="!scope.row.enable">鏈惎鐢�</el-tag> + </div> + </template> + </el-table-column> + <el-table-column prop="createTime" label="鍒涘缓鏃堕棿" align="center" width="150" show-overflow-tooltip/> + <el-table-column label="杞琀LS" width="120" align="center"> + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> + <el-tag size="medium" v-if="scope.row.enable_hls">宸插惎鐢�</el-tag> + <el-tag size="medium" type="info" v-if="!scope.row.enable_hls">鏈惎鐢�</el-tag> + </div> + </template> + </el-table-column> + <el-table-column label="MP4褰曞埗" width="120" align="center"> + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> + <el-tag size="medium" v-if="scope.row.enable_mp4">宸插惎鐢�</el-tag> + <el-tag size="medium" type="info" v-if="!scope.row.enable_mp4">鏈惎鐢�</el-tag> + </div> + </template> + </el-table-column> + <el-table-column label="鏃犱汉瑙傜湅鑷姩鍒犻櫎" width="160" align="center"> + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> + <el-tag size="medium" v-if="scope.row.enable_remove_none_reader">宸插惎鐢�</el-tag> + <el-tag size="medium" type="info" v-if="!scope.row.enable_remove_none_reader">鏈惎鐢�</el-tag> + </div> + </template> + </el-table-column> - <el-table-column label="鎿嶄綔" width="360" align="center" fixed="right"> - <template slot-scope="scope"> - <el-button-group> - <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.enable" @click="play(scope.row)">鎾斁</el-button> - <el-button size="mini" icon="el-icon-close" type="success" v-if="scope.row.enable" @click="stop(scope.row)">鍋滅敤</el-button> - <el-button size="mini" icon="el-icon-check" type="primary" :loading="startBtnLaoding" v-if="!scope.row.enable" @click="start(scope.row)">鍚敤</el-button> - <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteStreamProxy(scope.row)">鍒犻櫎</el-button> - </el-button-group> - </template> - </el-table-column> - </el-table> - <el-pagination - style="float: right" - @size-change="handleSizeChange" - @current-change="currentChange" - :current-page="currentPage" - :page-size="count" - :page-sizes="[15, 25, 35, 50]" - layout="total, sizes, prev, pager, next" - :total="total"> - </el-pagination> - <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit> - <onvifEdit ref="onvifEdit" ></onvifEdit> - </el-main> - </el-container> + <el-table-column label="鎿嶄綔" width="360" align="center" fixed="right"> + <template slot-scope="scope"> + <el-button-group> + <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.enable" @click="play(scope.row)">鎾斁</el-button> + <el-button size="mini" icon="el-icon-close" type="success" v-if="scope.row.enable" @click="stop(scope.row)">鍋滅敤</el-button> + <el-button size="mini" icon="el-icon-check" type="primary" :loading="startBtnLaoding" v-if="!scope.row.enable" @click="start(scope.row)">鍚敤</el-button> + <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteStreamProxy(scope.row)">鍒犻櫎</el-button> + </el-button-group> + </template> + </el-table-column> + </el-table> + <el-pagination + style="float: right" + @size-change="handleSizeChange" + @current-change="currentChange" + :current-page="currentPage" + :page-size="count" + :page-sizes="[15, 25, 35, 50]" + layout="total, sizes, prev, pager, next" + :total="total"> + </el-pagination> + <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit> + <onvifEdit ref="onvifEdit" ></onvifEdit> </div> </template> @@ -117,7 +110,7 @@ import streamProxyEdit from './dialog/StreamProxyEdit.vue' import onvifEdit from './dialog/onvifEdit.vue' import devicePlayer from './dialog/devicePlayer.vue' - import uiHeader from './UiHeader.vue' + import uiHeader from '../layout/UiHeader.vue' export default { name: 'streamProxyList', components: { diff --git a/web_src/src/components/UiHeader.vue b/web_src/src/components/UiHeader.vue deleted file mode 100644 index 828dda9..0000000 --- a/web_src/src/components/UiHeader.vue +++ /dev/null @@ -1,141 +0,0 @@ -<template> - <div id="UiHeader"> - <el-menu router :default-active="activeIndex" menu-trigger="click" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" mode="horizontal"> - <el-menu-item index="/">鎺у埗鍙�</el-menu-item> - <el-menu-item index="/live">瀹炴椂鐩戞帶</el-menu-item> - <el-menu-item index="/deviceList">鍥芥爣璁惧</el-menu-item> - <el-menu-item index="/pushVideoList">鎺ㄦ祦鍒楄〃</el-menu-item> - <el-menu-item index="/streamProxyList">鎷夋祦浠g悊</el-menu-item> - <el-menu-item index="/cloudRecord">浜戠褰曞儚</el-menu-item> - <el-menu-item index="/mediaServerManger">鑺傜偣绠$悊</el-menu-item> - <el-menu-item index="/parentPlatformList/15/1">鍥芥爣绾ц仈</el-menu-item> - <el-menu-item @click="openDoc">鍦ㄧ嚎鏂囨。</el-menu-item> -<!-- <el-submenu index="/setting">--> -<!-- <template slot="title">绯荤粺璁剧疆</template>--> -<!-- <el-menu-item index="/setting/web">WEB鏈嶅姟</el-menu-item>--> -<!-- <el-menu-item index="/setting/sip">鍥芥爣鏈嶅姟</el-menu-item>--> -<!-- <el-menu-item index="/setting/media">濯掍綋鏈嶅姟</el-menu-item>--> -<!-- </el-submenu>--> - <el-switch v-model="alarmNotify" active-text="鎶ヨ淇℃伅鎺ㄩ��" style="display: block float: right" @change="alarmNotifyChannge"></el-switch> -<!-- <el-menu-item style="float: right;" @click="loginout">閫�鍑�</el-menu-item>--> - <el-submenu index="" style="float: right;" > - <template slot="title">娆㈣繋锛寋{this.$cookies.get("session").username}}</template> - <el-menu-item @click="changePassword">淇敼瀵嗙爜</el-menu-item> - <el-menu-item @click="loginout">娉ㄩ攢</el-menu-item> - </el-submenu> - </el-menu> - <changePasswordDialog ref="changePasswordDialog"></changePasswordDialog> - </div> -</template> - -<script> - -import changePasswordDialog from './dialog/changePassword.vue' -export default { - name: "UiHeader", - components: { Notification, changePasswordDialog }, - data() { - return { - alarmNotify: false, - sseSource: null, - activeIndex: this.$route.path, - }; - }, - created(){ - if (this.$route.path.startsWith("/channelList")){ - this.activeIndex = "/deviceList" - } - - }, - mounted() { - window.addEventListener('beforeunload', e => this.beforeunloadHandler(e)) - // window.addEventListener('unload', e => this.unloadHandler(e)) - this.alarmNotify = this.getAlarmSwitchStatus() === "true"; - this.sseControl(); - }, - methods:{ - loginout(){ - this.$axios({ - method: 'get', - url:"/api/user/logout" - }).then((res)=> { - // 鍒犻櫎cookie锛屽洖鍒扮櫥褰曢〉闈� - this.$cookies.remove("session"); - this.$router.push('/login'); - this.sseSource.close(); - }).catch((error)=> { - console.error("鐧诲嚭澶辫触") - console.error(error) - }); - }, - changePassword(){ - this.$refs.changePasswordDialog.openDialog() - }, - openDoc(){ - console.log(process.env.BASE_API) - window.open( !!process.env.BASE_API? process.env.BASE_API + "/doc.html": "/doc.html") - }, - beforeunloadHandler() { - this.sseSource.close(); - }, - alarmNotifyChannge(){ - this.setAlarmSwitchStatus() - this.sseControl() - }, - sseControl() { - let that = this; - if (this.alarmNotify) { - console.log("鐢宠SSE鎺ㄩ�丄PI璋冪敤锛屾祻瑙堝櫒ID: " + this.$browserId); - this.sseSource = new EventSource('/api/emit?browserId=' + this.$browserId); - this.sseSource.addEventListener('message', function(evt) { - that.$notify({ - title: '鏀跺埌鎶ヨ淇℃伅', - dangerouslyUseHTMLString: true, - message: evt.data, - type: 'warning' - }); - console.log("鏀跺埌淇℃伅锛�" + evt.data); - }); - this.sseSource.addEventListener('open', function(e) { - console.log("SSE杩炴帴鎵撳紑."); - }, false); - this.sseSource.addEventListener('error', function(e) { - if (e.target.readyState == EventSource.CLOSED) { - console.log("SSE杩炴帴鍏抽棴"); - } else { - console.log(e.target.readyState); - } - }, false); - } else { - if (this.sseSource != null) { - this.sseSource.removeEventListener('open', null); - this.sseSource.removeEventListener('message', null); - this.sseSource.removeEventListener('error', null); - this.sseSource.close(); - } - - } - }, - getAlarmSwitchStatus(){ - if (localStorage.getItem("alarmSwitchStatus") == null) { - localStorage.setItem("alarmSwitchStatus", false); - } - return localStorage.getItem("alarmSwitchStatus"); - }, - setAlarmSwitchStatus(){ - localStorage.setItem("alarmSwitchStatus", this.alarmNotify); - } - }, - destroyed() { - window.removeEventListener('beforeunload', e => this.beforeunloadHandler(e)) - if (this.sseSource != null) { - this.sseSource.removeEventListener('open', null); - this.sseSource.removeEventListener('message', null); - this.sseSource.removeEventListener('error', null); - this.sseSource.close(); - } - }, - - } - -</script> diff --git a/web_src/src/components/channelList.vue b/web_src/src/components/channelList.vue index 6eae383..59a6f74 100644 --- a/web_src/src/components/channelList.vue +++ b/web_src/src/components/channelList.vue @@ -1,393 +1,406 @@ <template> -<div id="channelList"> - <el-container> - <el-header> - <uiHeader></uiHeader> - </el-header> - <el-main> - <div style="background-color: #FFFFFF; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> - <span style="font-size: 1rem; font-weight: 500; ">閫氶亾鍒楄〃({{parentChannelId ==0 ? deviceId:parentChannelId}})</span> + <div id="channelList"> + <div style="background-color: #FFFFFF; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> + <span + style="font-size: 1rem; font-weight: 500; ">閫氶亾鍒楄〃({{ parentChannelId == 0 ? deviceId : parentChannelId }})</span> - </div> - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> - <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem;" type="primary" @click="showDevice">杩斿洖</el-button> - 鎼滅储: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="鍏抽敭瀛�" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input> + </div> + <div + style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> + <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem;" type="primary" @click="showDevice"> + 杩斿洖 + </el-button> + 鎼滅储: + <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="鍏抽敭瀛�" + prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input> - 閫氶亾绫诲瀷: <el-select size="mini" @change="search" style="margin-right: 1rem;" v-model="channelType" placeholder="璇烽�夋嫨" default-first-option> - <el-option label="鍏ㄩ儴" value=""></el-option> - <el-option label="璁惧" value="false"></el-option> - <el-option label="瀛愮洰褰�" value="true"></el-option> - </el-select> - 鍦ㄧ嚎鐘舵��: <el-select size="mini" style="margin-right: 1rem;" @change="search" v-model="online" placeholder="璇烽�夋嫨" default-first-option> - <el-option label="鍏ㄩ儴" value=""></el-option> - <el-option label="鍦ㄧ嚎" value="true"></el-option> - <el-option label="绂荤嚎" value="false"></el-option> - </el-select> - <el-checkbox size="mini" style="margin-right: 1rem; float: right;" v-model="autoList" @change="autoListChange">鑷姩鍒锋柊</el-checkbox> - </div> - <devicePlayer ref="devicePlayer" v-loading="isLoging"></devicePlayer> - <!--璁惧鍒楄〃--> - <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%"> - <el-table-column prop="channelId" label="閫氶亾缂栧彿" width="200"> - </el-table-column> - <el-table-column prop="name" label="閫氶亾鍚嶇О"> - </el-table-column> - <el-table-column label="蹇収" width="80" align="center"> - <template slot-scope="scope"> - <img style="max-height: 3rem;max-width: 4rem;" - :id="scope.row.deviceId + '_' + scope.row.channelId" - :src="getSnap(scope.row)" - @error="getSnapErrorEvent($event.target.id)" - alt=""> -<!-- <el-image--> -<!-- :id="'snapImg_' + scope.row.deviceId + '_' + scope.row.channelId"--> -<!-- :src="getSnap(scope.row)"--> -<!-- @error="getSnapErrorEvent($event, scope.row)"--> -<!-- :fit="'contain'">--> -<!-- <div slot="error" class="image-slot">--> -<!-- <i class="el-icon-picture-outline"></i>--> -<!-- </div>--> -<!-- </el-image>--> - </template> - </el-table-column> - <el-table-column prop="subCount" label="瀛愯妭鐐规暟"> - </el-table-column> - <el-table-column prop="manufacture" label="鍘傚"> - </el-table-column> - <el-table-column label="浣嶇疆淇℃伅" align="center"> - <template slot-scope="scope"> - <span>{{scope.row.longitude}},{{scope.row.latitude}}</span> - </template> - </el-table-column> - <el-table-column prop="ptztypeText" label="浜戝彴绫诲瀷"/> - <el-table-column label="寮�鍚煶棰�" align="center"> - <template slot-scope="scope"> - <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF"> - </el-switch> - </template> - </el-table-column> - <el-table-column label="鐘舵��" width="180" align="center"> - <template slot-scope="scope"> - <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.status == 1">寮�鍚�</el-tag> - <el-tag size="medium" type="info" v-if="scope.row.status == 0">鍏抽棴</el-tag> - </div> - </template> - </el-table-column> + 閫氶亾绫诲瀷: + <el-select size="mini" @change="search" style="margin-right: 1rem;" v-model="channelType" placeholder="璇烽�夋嫨" + default-first-option> + <el-option label="鍏ㄩ儴" value=""></el-option> + <el-option label="璁惧" value="false"></el-option> + <el-option label="瀛愮洰褰�" value="true"></el-option> + </el-select> + 鍦ㄧ嚎鐘舵��: + <el-select size="mini" style="margin-right: 1rem;" @change="search" v-model="online" placeholder="璇烽�夋嫨" + default-first-option> + <el-option label="鍏ㄩ儴" value=""></el-option> + <el-option label="鍦ㄧ嚎" value="true"></el-option> + <el-option label="绂荤嚎" value="false"></el-option> + </el-select> + <el-checkbox size="mini" style="margin-right: 1rem; float: right;" v-model="autoList" @change="autoListChange"> + 鑷姩鍒锋柊 + </el-checkbox> + </div> + <devicePlayer ref="devicePlayer" v-loading="isLoging"></devicePlayer> + <!--璁惧鍒楄〃--> + <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%"> + <el-table-column prop="channelId" label="閫氶亾缂栧彿" width="200"> + </el-table-column> + <el-table-column prop="name" label="閫氶亾鍚嶇О"> + </el-table-column> + <el-table-column label="蹇収" width="80" align="center"> + <template slot-scope="scope"> + <img style="max-height: 3rem;max-width: 4rem;" + :id="scope.row.deviceId + '_' + scope.row.channelId" + :src="getSnap(scope.row)" + @error="getSnapErrorEvent($event.target.id)" + alt=""> + <!-- <el-image--> + <!-- :id="'snapImg_' + scope.row.deviceId + '_' + scope.row.channelId"--> + <!-- :src="getSnap(scope.row)"--> + <!-- @error="getSnapErrorEvent($event, scope.row)"--> + <!-- :fit="'contain'">--> + <!-- <div slot="error" class="image-slot">--> + <!-- <i class="el-icon-picture-outline"></i>--> + <!-- </div>--> + <!-- </el-image>--> + </template> + </el-table-column> + <el-table-column prop="subCount" label="瀛愯妭鐐规暟"> + </el-table-column> + <el-table-column prop="manufacture" label="鍘傚"> + </el-table-column> + <el-table-column label="浣嶇疆淇℃伅" align="center"> + <template slot-scope="scope"> + <span>{{ scope.row.longitude }},{{ scope.row.latitude }}</span> + </template> + </el-table-column> + <el-table-column prop="ptztypeText" label="浜戝彴绫诲瀷"/> + <el-table-column label="寮�鍚煶棰�" align="center"> + <template slot-scope="scope"> + <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF"> + </el-switch> + </template> + </el-table-column> + <el-table-column label="鐘舵��" width="180" align="center"> + <template slot-scope="scope"> + <div slot="reference" class="name-wrapper"> + <el-tag size="medium" v-if="scope.row.status == 1">寮�鍚�</el-tag> + <el-tag size="medium" type="info" v-if="scope.row.status == 0">鍏抽棴</el-tag> + </div> + </template> + </el-table-column> - <el-table-column label="鎿嶄綔" width="280" align="center" fixed="right"> - <template slot-scope="scope"> - <el-button-group> - <!-- <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">鎾斁</el-button> --> - <el-button size="mini" icon="el-icon-video-play" @click="sendDevicePush(scope.row)">鎾斁</el-button> - <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="!!scope.row.streamId" @click="stopDevicePush(scope.row)">鍋滄</el-button> - <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.subCount > 0" @click="changeSubchannel(scope.row)">鏌ョ湅</el-button> - <el-button size="mini" icon="el-icon-video-camera" type="primary" @click="queryRecords(scope.row)">璁惧褰曡薄</el-button> - <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">褰曞儚鏌ヨ</el-button> --> - </el-button-group> - </template> - </el-table-column> - </el-table> - <el-pagination style="float: right" @size-change="handleSizeChange" @current-change="currentChange" :current-page="currentPage" :page-size="count" :page-sizes="[15, 20, 30, 50]" layout="total, sizes, prev, pager, next" :total="total"> - </el-pagination> - - </el-main> - </el-container> -</div> + <el-table-column label="鎿嶄綔" width="280" align="center" fixed="right"> + <template slot-scope="scope"> + <el-button-group> + <!-- <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">鎾斁</el-button> --> + <el-button size="mini" icon="el-icon-video-play" @click="sendDevicePush(scope.row)">鎾斁</el-button> + <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="!!scope.row.streamId" + @click="stopDevicePush(scope.row)">鍋滄 + </el-button> + <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.subCount > 0" + @click="changeSubchannel(scope.row)">鏌ョ湅 + </el-button> + <el-button size="mini" icon="el-icon-video-camera" type="primary" @click="queryRecords(scope.row)">璁惧褰曡薄 + </el-button> + <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">褰曞儚鏌ヨ</el-button> --> + </el-button-group> + </template> + </el-table-column> + </el-table> + <el-pagination style="float: right" @size-change="handleSizeChange" @current-change="currentChange" + :current-page="currentPage" :page-size="count" :page-sizes="[15, 20, 30, 50]" + layout="total, sizes, prev, pager, next" :total="total"> + </el-pagination> + </div> </template> <script> import devicePlayer from './dialog/devicePlayer.vue' -import uiHeader from './UiHeader.vue' +import uiHeader from '../layout/UiHeader.vue' import moment from "moment"; + export default { - name: 'channelList', - components: { - devicePlayer, - uiHeader - }, - data() { - return { - deviceId: this.$route.params.deviceId, - parentChannelId: this.$route.params.parentChannelId, - deviceChannelList: [], - videoComponentList: [], - currentPlayerInfo: {}, //褰撳墠鎾斁瀵硅薄 - updateLooper: 0, //鏁版嵁鍒锋柊杞鏍囧織 - searchSrt: "", - channelType: "", - online: "", - winHeight: window.innerHeight - 250, - currentPage: parseInt(this.$route.params.page), - count: parseInt(this.$route.params.count), - total: 0, - beforeUrl: "/deviceList", - isLoging: false, - autoList: true, - loadSnap:{} - }; - }, + name: 'channelList', + components: { + devicePlayer, + uiHeader + }, + data() { + return { + deviceId: this.$route.params.deviceId, + parentChannelId: this.$route.params.parentChannelId, + deviceChannelList: [], + videoComponentList: [], + currentPlayerInfo: {}, //褰撳墠鎾斁瀵硅薄 + updateLooper: 0, //鏁版嵁鍒锋柊杞鏍囧織 + searchSrt: "", + channelType: "", + online: "", + winHeight: window.innerHeight - 250, + currentPage: parseInt(this.$route.params.page), + count: parseInt(this.$route.params.count), + total: 0, + beforeUrl: "/deviceList", + isLoging: false, + autoList: true, + loadSnap: {} + }; + }, - mounted() { - this.initData(); - if (this.autoList) { - this.updateLooper = setInterval(this.initData, 5000); - } - - }, - destroyed() { - this.$destroy('videojs'); - clearTimeout(this.updateLooper); - }, - methods: { - initData: function () { - if (typeof (this.parentChannelId) == "undefined" || this.parentChannelId == 0) { - this.getDeviceChannelList(); - } else { - this.showSubchannels(); - } - }, - initParam: function () { - this.deviceId = this.$route.params.deviceId; - this.parentChannelId = this.$route.params.parentChannelId; - this.currentPage = parseInt(this.$route.params.page); - this.count = parseInt(this.$route.params.count); - if (this.parentChannelId == "" || this.parentChannelId == 0) { - this.beforeUrl = "/deviceList" - } - - }, - currentChange: function (val) { - var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}` - this.$router.push(url).then(() => { - this.initParam(); - this.initData(); - }) - }, - handleSizeChange: function (val) { - var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1` - this.$router.push(url).then(() => { - this.initParam(); - this.initData(); - }) - - }, - getDeviceChannelList: function () { - let that = this; - if (typeof (this.$route.params.deviceId) == "undefined") return; - this.$axios({ - method: 'get', - url: `/api/device/query/devices/${this.$route.params.deviceId}/channels`, - params:{ - page: that.currentPage, - count: that.count, - query: that.searchSrt, - online: that.online, - channelType: that.channelType - } - }).then(function (res) { - that.total = res.data.total; - that.deviceChannelList = res.data.list; - // 闃叉鍑虹幇琛ㄦ牸閿欎綅 - that.$nextTick(() => { - that.$refs.channelListTable.doLayout(); - }) - }).catch(function (error) { - console.log(error); - }); - }, - - //閫氱煡璁惧涓婁紶濯掍綋娴� - sendDevicePush: function (itemData) { - let deviceId = this.deviceId; - this.isLoging = true; - let channelId = itemData.channelId; - console.log("閫氱煡璁惧鎺ㄦ祦1锛�" + deviceId + " : " + channelId ); - let that = this; - this.$axios({ - method: 'get', - url: '/api/play/start/' + deviceId + '/' + channelId - }).then(function (res) { - that.isLoging = false; - if (res.data.code === 0) { - - setTimeout(()=>{ - - let snapId = deviceId + "_" + channelId; - that.loadSnap[snapId] = 0; - that.getSnapErrorEvent(snapId) - },5000) - that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { - streamInfo: res.data.data, - hasAudio: itemData.hasAudio - }); - setTimeout(()=>{ - that.initData(); - },1000) - - }else { - that.$message.error(res.data.msg); - } - }).catch(function (e) {}); - }, - queryRecords: function (itemData) { - var format = moment().format("YYYY-M-D"); - let deviceId = this.deviceId; - let channelId = itemData.channelId; - this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format}) - }, - stopDevicePush: function (itemData) { - var that = this; - this.$axios({ - method: 'get', - url: '/api/play/stop/' + this.deviceId + "/" + itemData.channelId - }).then(function (res) { - that.initData(); - }).catch(function (error) { - if (error.response.status === 402) { // 宸茬粡鍋滄杩� - that.initData(); - }else { - console.log(error) - } - }); - }, - getSnap: function (row){ - return '/static/snap/' + row.deviceId + '_' + row.channelId + '.jpg' - }, - getSnapErrorEvent: function (id){ - - if (typeof (this.loadSnap[id]) != "undefined") { - console.log("涓嬭浇鎴浘" + this.loadSnap[id]) - if (this.loadSnap[id] > 5) { - delete this.loadSnap[id]; - return; - } - setTimeout(()=>{ - this.loadSnap[id] ++ - document.getElementById(id).setAttribute("src", '/static/snap/' + id + '.jpg?' + new Date().getTime()) - },1000) - - } - }, - showDevice: function () { - this.$router.push(this.beforeUrl).then(() => { - this.initParam(); - this.initData(); - }) - }, - changeSubchannel(itemData) { - this.beforeUrl = this.$router.currentRoute.path; - - var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}/${this.$router.currentRoute.params.count}/1` - this.$router.push(url).then(() => { - this.searchSrt = ""; - this.channelType = ""; - this.online = ""; - this.initParam(); - this.initData(); - }) - }, - showSubchannels: function (channelId) { - let that = this; - - this.$axios({ - method: 'get', - url:`/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`, - params: { - page: that.currentPage, - count: that.count, - query: that.searchSrt, - online: that.online, - channelType: that.channelType - } - }).then(function (res) { - that.total = res.data.total; - that.deviceChannelList = res.data.list; - // 闃叉鍑虹幇琛ㄦ牸閿欎綅 - that.$nextTick(() => { - that.$refs.channelListTable.doLayout(); - }) - }).catch(function (error) { - console.log(error); - }); - }, - search: function () { - this.currentPage = 1; - this.total = 0; - this.initData(); - }, - updateChannel: function (row) { - this.$axios({ - method: 'post', - url: `/api/device/query/channel/update/${this.deviceId}`, - params: row - }).then(function (res) { - console.log(JSON.stringify(res)); - }); - }, - autoListChange: function () { - if (this.autoList) { - this.updateLooper = setInterval(this.initData, 1500); - }else{ - window.clearInterval(this.updateLooper); - } - } - + mounted() { + this.initData(); + if (this.autoList) { + this.updateLooper = setInterval(this.initData, 5000); } + + }, + destroyed() { + this.$destroy('videojs'); + clearTimeout(this.updateLooper); + }, + methods: { + initData: function () { + if (typeof (this.parentChannelId) == "undefined" || this.parentChannelId == 0) { + this.getDeviceChannelList(); + } else { + this.showSubchannels(); + } + }, + initParam: function () { + this.deviceId = this.$route.params.deviceId; + this.parentChannelId = this.$route.params.parentChannelId; + this.currentPage = parseInt(this.$route.params.page); + this.count = parseInt(this.$route.params.count); + if (this.parentChannelId == "" || this.parentChannelId == 0) { + this.beforeUrl = "/deviceList" + } + + }, + currentChange: function (val) { + var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}` + this.$router.push(url).then(() => { + this.initParam(); + this.initData(); + }) + }, + handleSizeChange: function (val) { + var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1` + this.$router.push(url).then(() => { + this.initParam(); + this.initData(); + }) + + }, + getDeviceChannelList: function () { + let that = this; + if (typeof (this.$route.params.deviceId) == "undefined") return; + this.$axios({ + method: 'get', + url: `/api/device/query/devices/${this.$route.params.deviceId}/channels`, + params: { + page: that.currentPage, + count: that.count, + query: that.searchSrt, + online: that.online, + channelType: that.channelType + } + }).then(function (res) { + that.total = res.data.total; + that.deviceChannelList = res.data.list; + // 闃叉鍑虹幇琛ㄦ牸閿欎綅 + that.$nextTick(() => { + that.$refs.channelListTable.doLayout(); + }) + }).catch(function (error) { + console.log(error); + }); + }, + + //閫氱煡璁惧涓婁紶濯掍綋娴� + sendDevicePush: function (itemData) { + let deviceId = this.deviceId; + this.isLoging = true; + let channelId = itemData.channelId; + console.log("閫氱煡璁惧鎺ㄦ祦1锛�" + deviceId + " : " + channelId); + let that = this; + this.$axios({ + method: 'get', + url: '/api/play/start/' + deviceId + '/' + channelId + }).then(function (res) { + that.isLoging = false; + if (res.data.code === 0) { + + setTimeout(() => { + + let snapId = deviceId + "_" + channelId; + that.loadSnap[snapId] = 0; + that.getSnapErrorEvent(snapId) + }, 5000) + that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { + streamInfo: res.data.data, + hasAudio: itemData.hasAudio + }); + setTimeout(() => { + that.initData(); + }, 1000) + + } else { + that.$message.error(res.data.msg); + } + }).catch(function (e) { + }); + }, + queryRecords: function (itemData) { + var format = moment().format("YYYY-M-D"); + let deviceId = this.deviceId; + let channelId = itemData.channelId; + this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format}) + }, + stopDevicePush: function (itemData) { + var that = this; + this.$axios({ + method: 'get', + url: '/api/play/stop/' + this.deviceId + "/" + itemData.channelId + }).then(function (res) { + that.initData(); + }).catch(function (error) { + if (error.response.status === 402) { // 宸茬粡鍋滄杩� + that.initData(); + } else { + console.log(error) + } + }); + }, + getSnap: function (row) { + return '/static/snap/' + row.deviceId + '_' + row.channelId + '.jpg' + }, + getSnapErrorEvent: function (id) { + + if (typeof (this.loadSnap[id]) != "undefined") { + console.log("涓嬭浇鎴浘" + this.loadSnap[id]) + if (this.loadSnap[id] > 5) { + delete this.loadSnap[id]; + return; + } + setTimeout(() => { + this.loadSnap[id]++ + document.getElementById(id).setAttribute("src", '/static/snap/' + id + '.jpg?' + new Date().getTime()) + }, 1000) + + } + }, + showDevice: function () { + this.$router.push(this.beforeUrl).then(() => { + this.initParam(); + this.initData(); + }) + }, + changeSubchannel(itemData) { + this.beforeUrl = this.$router.currentRoute.path; + + var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}/${this.$router.currentRoute.params.count}/1` + this.$router.push(url).then(() => { + this.searchSrt = ""; + this.channelType = ""; + this.online = ""; + this.initParam(); + this.initData(); + }) + }, + showSubchannels: function (channelId) { + let that = this; + + this.$axios({ + method: 'get', + url: `/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`, + params: { + page: that.currentPage, + count: that.count, + query: that.searchSrt, + online: that.online, + channelType: that.channelType + } + }).then(function (res) { + that.total = res.data.total; + that.deviceChannelList = res.data.list; + // 闃叉鍑虹幇琛ㄦ牸閿欎綅 + that.$nextTick(() => { + that.$refs.channelListTable.doLayout(); + }) + }).catch(function (error) { + console.log(error); + }); + }, + search: function () { + this.currentPage = 1; + this.total = 0; + this.initData(); + }, + updateChannel: function (row) { + this.$axios({ + method: 'post', + url: `/api/device/query/channel/update/${this.deviceId}`, + params: row + }).then(function (res) { + console.log(JSON.stringify(res)); + }); + }, + autoListChange: function () { + if (this.autoList) { + this.updateLooper = setInterval(this.initData, 1500); + } else { + window.clearInterval(this.updateLooper); + } + } + + } }; </script> <style> .videoList { - display: flex; - flex-wrap: wrap; - align-content: flex-start; + display: flex; + flex-wrap: wrap; + align-content: flex-start; } .video-item { - position: relative; - width: 15rem; - height: 10rem; - margin-right: 1rem; - background-color: #000000; + position: relative; + width: 15rem; + height: 10rem; + margin-right: 1rem; + background-color: #000000; } .video-item-img { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - margin: auto; - width: 100%; - height: 100%; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + width: 100%; + height: 100%; } .video-item-img:after { - content: ""; - display: inline-block; - position: absolute; - z-index: 2; - top: 0; - bottom: 0; - left: 0; - right: 0; - margin: auto; - width: 3rem; - height: 3rem; - background-image: url("../assets/loading.png"); - background-size: cover; - background-color: #000000; + content: ""; + display: inline-block; + position: absolute; + z-index: 2; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + width: 3rem; + height: 3rem; + background-image: url("../assets/loading.png"); + background-size: cover; + background-color: #000000; } .video-item-title { - position: absolute; - bottom: 0; - color: #000000; - background-color: #ffffff; - line-height: 1.5rem; - padding: 0.3rem; - width: 14.4rem; + position: absolute; + bottom: 0; + color: #000000; + background-color: #ffffff; + line-height: 1.5rem; + padding: 0.3rem; + width: 14.4rem; } </style> diff --git a/web_src/src/components/control.vue b/web_src/src/components/control.vue index 742b091..a0b2834 100644 --- a/web_src/src/components/control.vue +++ b/web_src/src/components/control.vue @@ -1,584 +1,702 @@ <template> -<div id="app"> - <el-container> - <el-header> - <uiHeader></uiHeader> - </el-header> - <el-main> - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> - <span style="font-size: 1rem; font-weight: bold;">鎺у埗鍙�</span> - <div style="position: absolute; right: 17rem; top: 0.3rem;"> - 鑺傜偣閫夋嫨: <el-select size="mini" @change="chooseMediaChange" style="width: 18rem; margin-right: 8rem;" v-model="mediaServerChoose" placeholder="璇烽�夋嫨" default-first-option> - <el-option - v-for="item in mediaServerList" - :key="item.id" - :label="item.id + '( ' + item.streamIp + ' )'" - :value="item.id"> - </el-option> - </el-select> - <span >{{loadCount}}</span> - </div> - <div style="position: absolute; right: 1rem; top: 0.3rem;"> - <el-popover placement="bottom" width="900" height="300" trigger="click"> - <div style="height: 600px; overflow:auto; padding: 20px"> - <el-descriptions v-for="(value, key, index) in serverConfig" :key="key" border :column="1" style="margin-bottom: 1rem"> - <template slot="title"> - {{key}} - </template> - <el-descriptions-item v-for="(value1, key1, index1) in serverConfig[key]" :key="key1"> - <template slot="label" > - {{ getMediaKeyNameFromKey(key1) }} - </template> - {{ value1 }} - </el-descriptions-item> - </el-descriptions> - </div> - <el-button type="primary" slot="reference" size="mini" @click="getServerConfig()">濯掍綋鏈嶅姟鍣ㄩ厤缃�</el-button> - </el-popover> - <el-popover placement="bottom" width="900" height="300" trigger="click"> - <div style="height: 600px;overflow:auto; padding: 20px"> - <el-descriptions title="鍥芥爣閰嶇疆" border :column="1"> - <template slot="extra"> - <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="鐐瑰嚮鎷疯礉" v-clipboard="JSON.stringify(wvpServerConfig.sip)|| ''" @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></el-button> - </template> - <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.sip" :key="key"> - <template slot="label"> - {{ getNameFromKey(key) }} - </template> - {{ value }} - </el-descriptions-item> - </el-descriptions> + <div id="app" style="width: 100%"> + <div class="page-header"> + <div class="page-title">鎺у埗鍙�</div> + <div class="page-header-btn"> + 鑺傜偣閫夋嫨: + <el-select size="mini" @change="chooseMediaChange" style="width: 18rem; margin-right: 8rem;" + v-model="mediaServerChoose" placeholder="璇烽�夋嫨" default-first-option> + <el-option + v-for="item in mediaServerList" + :key="item.id" + :label="item.id + '( ' + item.streamIp + ' )'" + :value="item.id"> + </el-option> + </el-select> + <span>{{ loadCount }}</span> + </div> + <div class="page-header-btn"> + <el-popover placement="bottom" width="900" height="300" trigger="click"> + <div style="height: 600px; overflow:auto; padding: 20px"> + <el-descriptions v-for="(value, key, index) in serverConfig" :key="key" border :column="1" + style="margin-bottom: 1rem"> + <template slot="title"> + {{ key }} + </template> + <el-descriptions-item v-for="(value1, key1, index1) in serverConfig[key]" :key="key1"> + <template slot="label"> + {{ getMediaKeyNameFromKey(key1) }} + </template> + {{ value1 }} + </el-descriptions-item> + </el-descriptions> + </div> + <el-button type="primary" slot="reference" size="mini" @click="getServerConfig()">濯掍綋鏈嶅姟鍣ㄩ厤缃�</el-button> + </el-popover> + <el-popover placement="bottom" width="900" height="300" trigger="click"> + <div style="height: 600px;overflow:auto; padding: 20px"> + <el-descriptions title="鍥芥爣閰嶇疆" border :column="1"> + <template slot="extra"> + <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="鐐瑰嚮鎷疯礉" + v-clipboard="JSON.stringify(wvpServerConfig.sip)|| ''" + @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></el-button> + </template> + <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.sip" :key="key"> + <template slot="label"> + {{ getNameFromKey(key) }} + </template> + {{ value }} + </el-descriptions-item> + </el-descriptions> - <div style="margin-top: 1rem"> - <el-descriptions title="鍩虹閰嶇疆" border :column="1"> - <template slot="extra"> - <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="鐐瑰嚮鎷疯礉" v-clipboard="JSON.stringify(wvpServerConfig.base)|| ''" @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></el-button> - </template> - <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.base" :key="key"> - <template slot="label" > - {{ getNameFromKey(key) }} - </template> - <div v-if="key === 'interfaceAuthenticationExcludes'"> - <el-dropdown> + <div style="margin-top: 1rem"> + <el-descriptions title="鍩虹閰嶇疆" border :column="1"> + <template slot="extra"> + <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="鐐瑰嚮鎷疯礉" + v-clipboard="JSON.stringify(wvpServerConfig.base)|| ''" + @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></el-button> + </template> + <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.base" :key="key"> + <template slot="label"> + {{ getNameFromKey(key) }} + </template> + <div v-if="key === 'interfaceAuthenticationExcludes'"> + <el-dropdown> <span class="el-dropdown-link"> 鏌ョ湅<i class="el-icon-arrow-down el-icon--right"></i> </span> - <el-dropdown-menu slot="dropdown"> - <el-dropdown-item v-for="(value, key, index) in wvpServerConfig.base.interfaceAuthenticationExcludes" :key="key">{{value}}</el-dropdown-item> - </el-dropdown-menu> - </el-dropdown> - </div> - <div v-if="key !== 'interfaceAuthenticationExcludes'"> - <div v-if="value === true"> - 宸插惎鐢� - </div> - <div v-if="value === false"> - 鏈惎鐢� - </div> - <div v-if="value !== true && value !== false"> - {{ value }} - </div> - </div> + <el-dropdown-menu slot="dropdown"> + <el-dropdown-item + v-for="(value, key, index) in wvpServerConfig.base.interfaceAuthenticationExcludes" + :key="key">{{ value }} + </el-dropdown-item> + </el-dropdown-menu> + </el-dropdown> + </div> + <div v-if="key !== 'interfaceAuthenticationExcludes'"> + <div v-if="value === true"> + 宸插惎鐢� + </div> + <div v-if="value === false"> + 鏈惎鐢� + </div> + <div v-if="value !== true && value !== false"> + {{ value }} + </div> + </div> - </el-descriptions-item> - </el-descriptions> - </div> - <div style="margin-top: 1rem"> - <el-descriptions title="鐗堟湰淇℃伅" border :column="1"> - <template slot="extra"> - <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="鐐瑰嚮鎷疯礉" v-clipboard="JSON.stringify(wvpServerVersion) || ''" @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></el-button> - </template> - <el-descriptions-item v-for="(value, key, index) in wvpServerVersion" :key="key"> - <template slot="label"> - {{ getNameFromKey(key) }} - </template> - {{ value }} - </el-descriptions-item> - </el-descriptions> - - - </div> - </div> - <el-button type="primary" slot="reference" size="mini" @click="getWVPServerConfig()">淇′护鏈嶅姟鍣ㄩ厤缃�</el-button> - </el-popover> - <el-button style="margin-left: 1rem;" type="danger" size="mini" @click="reStartServer()">閲嶅惎濯掍綋鏈嶅姟鍣�</el-button> - </div> + </el-descriptions-item> + </el-descriptions> </div> - <el-row :gutter="30"> - <el-col :span="12"> - <div class="control-table" id="ThreadsLoad">table1</div> - </el-col> - <el-col :span="12"> - <div class="control-table" id="WorkThreadsLoad">table2</div> - </el-col> - </el-row> - <el-table :data="allSessionData" style="margin-top: 1rem;"> - <el-table-column prop="peer_ip" label="杩滅"></el-table-column> - <el-table-column prop="local_ip" label="鏈湴"></el-table-column> - <el-table-column prop="typeid" label="绫诲瀷"></el-table-column> - <el-table-column align="right"> - <template slot="header" slot-scope="scope"> - <el-button icon="el-icon-refresh-right" circle @click="getAllSession()"></el-button> - </template> - <template slot-scope="scope"> - <el-button @click.native.prevent="deleteRow(scope.$index, allSessionData)" type="text" size="small">绉婚櫎</el-button> - </template> - </el-table-column> - </el-table> + <div style="margin-top: 1rem"> + <el-descriptions title="鐗堟湰淇℃伅" border :column="1"> + <template slot="extra"> + <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="鐐瑰嚮鎷疯礉" + v-clipboard="JSON.stringify(wvpServerVersion) || ''" + @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></el-button> + </template> + <el-descriptions-item v-for="(value, key, index) in wvpServerVersion" :key="key"> + <template slot="label"> + {{ getNameFromKey(key) }} + </template> + {{ value }} + </el-descriptions-item> + </el-descriptions> - </el-main> - <!-- <el-footer style="position: absolute; bottom: 0; width: 100%;">ZLMediaKit-VUE_UI v1</el-footer> --> - </el-container> -</div> + </div> + </div> + <el-button type="primary" slot="reference" size="mini" @click="getWVPServerConfig()">淇′护鏈嶅姟鍣ㄩ厤缃�</el-button> + </el-popover> + <el-button style="margin-left: 1rem;" type="danger" size="mini" @click="reStartServer()">閲嶅惎濯掍綋鏈嶅姟鍣�</el-button> + </div> + </div> + <!-- <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;">--> + <!-- <span style="font-size: 1rem; font-weight: bold;">鎺у埗鍙�</span>--> + <!-- <div style="position: absolute; right: 17rem; top: 0.3rem;">--> + <!-- 鑺傜偣閫夋嫨:--> + <!-- <el-select size="mini" @change="chooseMediaChange" style="width: 18rem; margin-right: 8rem;"--> + <!-- v-model="mediaServerChoose" placeholder="璇烽�夋嫨" default-first-option>--> + <!-- <el-option--> + <!-- v-for="item in mediaServerList"--> + <!-- :key="item.id"--> + <!-- :label="item.id + '( ' + item.streamIp + ' )'"--> + <!-- :value="item.id">--> + <!-- </el-option>--> + <!-- </el-select>--> + <!-- <span>{{ loadCount }}</span>--> + <!-- </div>--> + <!-- <div style="position: absolute; right: 1rem; top: 0.3rem;">--> + <!-- <el-popover placement="bottom" width="900" height="300" trigger="click">--> + <!-- <div style="height: 600px; overflow:auto; padding: 20px">--> + <!-- <el-descriptions v-for="(value, key, index) in serverConfig" :key="key" border :column="1"--> + <!-- style="margin-bottom: 1rem">--> + <!-- <template slot="title">--> + <!-- {{ key }}--> + <!-- </template>--> + <!-- <el-descriptions-item v-for="(value1, key1, index1) in serverConfig[key]" :key="key1">--> + <!-- <template slot="label">--> + <!-- {{ getMediaKeyNameFromKey(key1) }}--> + <!-- </template>--> + <!-- {{ value1 }}--> + <!-- </el-descriptions-item>--> + <!-- </el-descriptions>--> + <!-- </div>--> + <!-- <el-button type="primary" slot="reference" size="mini" @click="getServerConfig()">濯掍綋鏈嶅姟鍣ㄩ厤缃�</el-button>--> + <!-- </el-popover>--> + <!-- <el-popover placement="bottom" width="900" height="300" trigger="click">--> + <!-- <div style="height: 600px;overflow:auto; padding: 20px">--> + <!-- <el-descriptions title="鍥芥爣閰嶇疆" border :column="1">--> + <!-- <template slot="extra">--> + <!-- <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="鐐瑰嚮鎷疯礉"--> + <!-- v-clipboard="JSON.stringify(wvpServerConfig.sip)|| ''"--> + <!-- @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></el-button>--> + <!-- </template>--> + <!-- <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.sip" :key="key">--> + <!-- <template slot="label">--> + <!-- {{ getNameFromKey(key) }}--> + <!-- </template>--> + <!-- {{ value }}--> + <!-- </el-descriptions-item>--> + <!-- </el-descriptions>--> + + <!-- <div style="margin-top: 1rem">--> + <!-- <el-descriptions title="鍩虹閰嶇疆" border :column="1">--> + <!-- <template slot="extra">--> + <!-- <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="鐐瑰嚮鎷疯礉"--> + <!-- v-clipboard="JSON.stringify(wvpServerConfig.base)|| ''"--> + <!-- @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></el-button>--> + <!-- </template>--> + <!-- <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.base" :key="key">--> + <!-- <template slot="label">--> + <!-- {{ getNameFromKey(key) }}--> + <!-- </template>--> + <!-- <div v-if="key === 'interfaceAuthenticationExcludes'">--> + <!-- <el-dropdown>--> + <!-- <span class="el-dropdown-link">--> + <!-- 鏌ョ湅<i class="el-icon-arrow-down el-icon--right"></i>--> + <!-- </span>--> + <!-- <el-dropdown-menu slot="dropdown">--> + <!-- <el-dropdown-item--> + <!-- v-for="(value, key, index) in wvpServerConfig.base.interfaceAuthenticationExcludes"--> + <!-- :key="key">{{ value }}--> + <!-- </el-dropdown-item>--> + <!-- </el-dropdown-menu>--> + <!-- </el-dropdown>--> + <!-- </div>--> + <!-- <div v-if="key !== 'interfaceAuthenticationExcludes'">--> + <!-- <div v-if="value === true">--> + <!-- 宸插惎鐢�--> + <!-- </div>--> + <!-- <div v-if="value === false">--> + <!-- 鏈惎鐢�--> + <!-- </div>--> + <!-- <div v-if="value !== true && value !== false">--> + <!-- {{ value }}--> + <!-- </div>--> + <!-- </div>--> + + <!-- </el-descriptions-item>--> + <!-- </el-descriptions>--> + <!-- </div>--> + <!-- <div style="margin-top: 1rem">--> + <!-- <el-descriptions title="鐗堟湰淇℃伅" border :column="1">--> + <!-- <template slot="extra">--> + <!-- <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="鐐瑰嚮鎷疯礉"--> + <!-- v-clipboard="JSON.stringify(wvpServerVersion) || ''"--> + <!-- @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></el-button>--> + <!-- </template>--> + <!-- <el-descriptions-item v-for="(value, key, index) in wvpServerVersion" :key="key">--> + <!-- <template slot="label">--> + <!-- {{ getNameFromKey(key) }}--> + <!-- </template>--> + <!-- {{ value }}--> + <!-- </el-descriptions-item>--> + <!-- </el-descriptions>--> + + + <!-- </div>--> + <!-- </div>--> + <!-- <el-button type="primary" slot="reference" size="mini" @click="getWVPServerConfig()">淇′护鏈嶅姟鍣ㄩ厤缃�</el-button>--> + <!-- </el-popover>--> + <!-- <el-button style="margin-left: 1rem;" type="danger" size="mini" @click="reStartServer()">閲嶅惎濯掍綋鏈嶅姟鍣�</el-button>--> + <!-- </div>--> + <!-- </div>--> + <el-row style="width: 100%"> + <el-col :span="12"> + <div class="control-table" id="ThreadsLoad" style="margin-right:10px;">table1</div> + </el-col> + <el-col :span="12"> + <div class="control-table" id="WorkThreadsLoad" style="margin-left:10px;">table2</div> + </el-col> + </el-row> + <el-table :data="allSessionData" style="margin-top: 1rem;"> + <el-table-column prop="peer_ip" label="杩滅"></el-table-column> + <el-table-column prop="local_ip" label="鏈湴"></el-table-column> + <el-table-column prop="typeid" label="绫诲瀷"></el-table-column> + <el-table-column align="right"> + <template slot="header" slot-scope="scope"> + <el-button icon="el-icon-refresh-right" circle @click="getAllSession()"></el-button> + </template> + <template slot-scope="scope"> + <el-button @click.native.prevent="deleteRow(scope.$index, allSessionData)" type="text" size="small">绉婚櫎 + </el-button> + </template> + </el-table-column> + </el-table> + </div> </template> <script> -import uiHeader from './UiHeader.vue' +import uiHeader from '../layout/UiHeader.vue' import MediaServer from './service/MediaServer' import echarts from 'echarts'; + export default { - name: 'app', - components: { - echarts, - uiHeader + name: 'app', + components: { + echarts, + uiHeader + }, + data() { + return { + tableOption: { + // legend: {}, + xAxis: {}, + yAxis: {}, + label: {}, + tooltip: {}, + dataZoom: [], + series: [] + }, + table1Option: { + // legend: {}, + xAxis: {}, + yAxis: {}, + label: {}, + tooltip: {}, + series: [] + }, + mChart: null, + mChart1: null, + charZoomStart: 0, + charZoomEnd: 100, + chartInterval: 0, //鏇存柊鍥捐〃缁熻鍥惧畾鏃朵换鍔℃爣璇� + allSessionData: [], + visible: false, + wvpVisible: false, + serverConfig: {}, + wvpServerConfig: {}, + wvpServerVersion: {}, + mediaServer: new MediaServer(), + mediaServerChoose: null, + loadCount: 0, + mediaServerList: [] + }; + }, + mounted() { + this.initTable() + this.chartInterval = setInterval(this.updateData, 3000); + this.mediaServer.getOnlineMediaServerList((data) => { + this.mediaServerList = data.data; + if (this.mediaServerList && this.mediaServerList.length > 0) { + this.mediaServerChoose = this.mediaServerList[0].id + this.loadCount = this.mediaServerList[0].count; + this.updateData(); + } + }) + }, + destroyed() { + clearInterval(this.chartInterval); //閲婃斁瀹氭椂浠诲姟 + }, + methods: { + chooseMediaChange: function (val) { + this.loadCount = 0 + this.initTable() + this.updateData(); }, - data() { - return { - tableOption: { - // legend: {}, - xAxis: {}, - yAxis: {}, - label: {}, - tooltip: {}, - dataZoom: [], - series: [] - }, - table1Option: { - // legend: {}, - xAxis: {}, - yAxis: {}, - label: {}, - tooltip: {}, - series: [] - }, - mChart: null, - mChart1: null, - charZoomStart: 0, - charZoomEnd: 100, - chartInterval: 0, //鏇存柊鍥捐〃缁熻鍥惧畾鏃朵换鍔℃爣璇� - allSessionData: [], - visible: false, - wvpVisible: false, - serverConfig: {}, - wvpServerConfig: {}, - wvpServerVersion: {}, - mediaServer : new MediaServer(), - mediaServerChoose : null, - loadCount : 0, - mediaServerList : [] - }; + updateData: function () { + this.getThreadsLoad(); + this.getLoadCount(); + this.getAllSession(); }, - mounted() { + /** + * 鑾峰彇绾跨▼鐘舵�� + */ + getThreadsLoad: function () { + let that = this; + if (that.mediaServerChoose != null) { + this.$axios({ + method: 'get', + url: '/zlm/' + that.mediaServerChoose + '/index/api/getThreadsLoad' + }).then(function (res) { + if (res.data.code == 0) { + that.tableOption.xAxis.data.push(new Date().toLocaleTimeString('chinese', { + hour12: false + })); + that.table1Option.xAxis.data.push(new Date().toLocaleTimeString('chinese', { + hour12: false + })); - this.initTable(); - this.chartInterval = setInterval(this.updateData, 3000); - this.mediaServer.getOnlineMediaServerList((data)=>{ - this.mediaServerList = data.data; - if (this.mediaServerList && this.mediaServerList.length > 0) { - this.mediaServerChoose = this.mediaServerList[0].id - this.loadCount = this.mediaServerList[0].count; - this.updateData(); - } - }) - }, - destroyed() { - clearInterval(this.chartInterval); //閲婃斁瀹氭椂浠诲姟 - }, - methods: { - chooseMediaChange: function (val) { - this.loadCount = 0 - this.initTable() - this.updateData(); - }, - updateData: function () { - this.getThreadsLoad(); - this.getLoadCount(); - this.getAllSession(); - }, - /** - * 鑾峰彇绾跨▼鐘舵�� - */ - getThreadsLoad: function () { - let that = this; - if (that.mediaServerChoose != null) { - this.$axios({ - method: 'get', - url: '/zlm/' + that.mediaServerChoose +'/index/api/getThreadsLoad' - }).then(function (res) { - if (res.data.code == 0) { - that.tableOption.xAxis.data.push(new Date().toLocaleTimeString('chinese', { - hour12: false - })); - that.table1Option.xAxis.data.push(new Date().toLocaleTimeString('chinese', { - hour12: false - })); - - for (var i = 0; i < res.data.data.length; i++) { - if (that.tableOption.series[i] === undefined) { - let data = { - data: [], - type: 'line' - }; - let data1 = { - data: [], - type: 'line' - }; - data.data.push(res.data.data[i].delay); - data1.data.push(res.data.data[i].load); - that.tableOption.series.push(data); - that.table1Option.series.push(data1); - } else { - that.tableOption.series[i].data.push(res.data.data[i].delay); - that.table1Option.series[i].data.push(res.data.data[i].load); - } - } - that.tableOption.dataZoom[0].start = that.charZoomStart; - that.tableOption.dataZoom[0].end = that.charZoomEnd; - that.table1Option.dataZoom[0].start = that.charZoomStart; - that.table1Option.dataZoom[0].end = that.charZoomEnd; - //that.myChart = echarts.init(document.getElementById('ThreadsLoad')); - that.myChart.setOption(that.tableOption, true); - // that.myChart1 = echarts.init(document.getElementById('WorkThreadsLoad')); - that.myChart1.setOption(that.table1Option, true); - } - }); - } - - }, - getLoadCount: function (){ - let that = this; - if (that.mediaServerChoose != null) { - that.mediaServer.getMediaServer(that.mediaServerChoose, (data)=>{ - if (data.code == 0) { - that.loadCount = data.data.count + for (var i = 0; i < res.data.data.length; i++) { + if (that.tableOption.series[i] === undefined) { + let data = { + data: [], + type: 'line' + }; + let data1 = { + data: [], + type: 'line' + }; + data.data.push(res.data.data[i].delay); + data1.data.push(res.data.data[i].load); + that.tableOption.series.push(data); + that.table1Option.series.push(data1); + } else { + that.tableOption.series[i].data.push(res.data.data[i].delay); + that.table1Option.series[i].data.push(res.data.data[i].load); } + } + that.tableOption.dataZoom[0].start = that.charZoomStart; + that.tableOption.dataZoom[0].end = that.charZoomEnd; + that.table1Option.dataZoom[0].start = that.charZoomStart; + that.table1Option.dataZoom[0].end = that.charZoomEnd; + //that.myChart = echarts.init(document.getElementById('ThreadsLoad')); + that.myChart.setOption(that.tableOption, true); + // that.myChart1 = echarts.init(document.getElementById('WorkThreadsLoad')); + that.myChart1.setOption(that.table1Option, true); + that.$nextTick(() => { + that.myChart.resize() + that.myChart1.resize() }) } - }, - initTable: function () { - let that = this; - this.tableOption.xAxis = { - type: 'category', - data: [], // x杞存暟鎹� - name: '鏃堕棿', // x杞村悕绉� - // x杞村悕绉版牱寮� - nameTextStyle: { - fontWeight: 300, - fontSize: 15 - } - }; - this.tableOption.yAxis = { - type: 'value', - name: '寤惰繜鐜�', // y杞村悕绉� - boundaryGap: [0, '100%'], - max: 100, - axisLabel: { - show: true, - interval: 'auto', - formatter: '{value} %' - }, - // y杞村悕绉版牱寮� - nameTextStyle: { - fontWeight: 300, - fontSize: 15 - } - }; - this.tableOption.dataZoom = [{ - show: true, - start: this.charZoomStart, - end: this.charZoomEnd - }]; - this.myChart = echarts.init(document.getElementById('ThreadsLoad')); - this.myChart.setOption(this.tableOption); - this.myChart.on('dataZoom', function (event) { - if (event.batch) { - that.charZoomStart = event.batch[0].start; - that.charZoomEnd = event.batch[0].end; - } else { - that.charZoomStart = event.start; - that.charZoomEnd = event.end; - } - }); + }); + } - this.table1Option.xAxis = { - type: 'category', - data: [], // x杞存暟鎹� - name: '鏃堕棿', // x杞村悕绉� - // x杞村悕绉版牱寮� - nameTextStyle: { - fontWeight: 300, - fontSize: 15 - } - }; - this.table1Option.yAxis = { - type: 'value', - name: '璐熻浇鐜�', // y杞村悕绉� - boundaryGap: [0, '100%'], - max: 100, - axisLabel: { - show: true, - interval: 'auto', - formatter: '{value} %' - }, - // y杞村悕绉版牱寮� - nameTextStyle: { - fontWeight: 300, - fontSize: 15 - } - }; - this.table1Option.dataZoom = [{ - show: true, - start: this.charZoomStart, - end: this.charZoomEnd - }]; - this.myChart1 = echarts.init(document.getElementById('WorkThreadsLoad')); - this.myChart1.setOption(this.table1Option); - this.myChart1.on('dataZoom', function (event) { - if (event.batch) { - that.charZoomStart = event.batch[0].start; - that.charZoomEnd = event.batch[0].end; - } else { - that.charZoomStart = event.start; - that.charZoomEnd = event.end; - } - }); - }, - - getAllSession: function () { - let that = this; - that.allSessionData = []; - this.$axios({ - method: 'get', - url: '/zlm/' + that.mediaServerChoose +'/index/api/getAllSession' - }).then(function (res) { - res.data.data.forEach(item => { - let data = { - peer_ip: item.peer_ip, - local_ip: item.local_ip, - typeid: item.typeid, - id: item.id - }; - that.allSessionData.push(data); - }); - }); - }, - getServerConfig: function () { - let that = this; - this.$axios({ - method: 'get', - url: '/zlm/' + that.mediaServerChoose +'/index/api/getServerConfig' - }).then(function (res) { - let info = res.data.data[0]; - let serverInfo = {} - for (let i = 0; i < Object.keys(info).length; i++) { - let key = Object.keys(info)[i]; - let group = key.substring(0, key.indexOf(".")) - let itemKey = key.substring(key.indexOf(".") + 1) - if (!serverInfo[group]) serverInfo[group] = {} - serverInfo[group][itemKey] = info[key] - } - - that.serverConfig = serverInfo; - that.visible = true; - }); - }, - getWVPServerConfig: function () { - let that = this; - this.$axios({ - method: 'get', - url: '/api/server/config' - }).then(function (res) { - console.log(res) - that.wvpServerConfig = res.data.data; - that.wvpVisible = true; - }); - this.$axios({ - method: 'get', - url: '/api/server/version' - }).then(function (res) { - console.log(res) - that.wvpServerVersion = res.data.data; - that.wvpVisible = true; - }); - }, - reStartServer: function () { - let that = this; - this.$confirm('姝ゆ搷浣滃皢閲嶅惎濯掍綋鏈嶅姟鍣�, 鏄惁缁х画?', '鎻愮ず', { - confirmButtonText: '纭畾', - cancelButtonText: '鍙栨秷', - type: 'warning' - }).then(() => { - let that = this; - this.$axios({ - method: 'get', - url: '/zlm/' + that.mediaServerChoose +'/index/api/restartServer' - }).then(function (res) { - that.getAllSession(); - if (res.data.code == 0) { - that.$message({ - type: 'success', - message: '鎿嶄綔瀹屾垚' - }); - } - }); - }); - }, - deleteRow: function (index, tabledata) { - let that = this; - this.$confirm('姝ゆ搷浣滃皢鏂紑璇ラ�氫俊閾捐矾, 鏄惁缁х画?', '鎻愮ず', { - confirmButtonText: '纭畾', - cancelButtonText: '鍙栨秷', - type: 'warning' - }) - .then(() => { - that.deleteSession(tabledata[index].id); - }) - .catch(() => { - console.log('id锛�' + JSON.stringify(tabledata[index])); - this.$message({ - type: 'info', - message: '宸插彇娑堝垹闄�' - }); - }); - console.log(JSON.stringify(tabledata[index])); - }, - deleteSession: function (id) { - let that = this; - this.$axios({ - method: 'get', - url: '/zlm/' + that.mediaServerChoose +'/index/api/kick_session&id=' + id - }).then(function (res) { - that.getAllSession(); - that.$message({ - type: 'success', - message: '鍒犻櫎鎴愬姛!' - }); - }); - }, - getNameFromKey: function(key) { - let nameData = { - "waitTrack": "绛夊緟缂栫爜淇℃伅", - "interfaceAuthenticationExcludes": "涓嶈繘琛岄壌鏉冪殑鎺ュ彛", - "playTimeout": "鐐规挱瓒呮椂鏃堕棿", - "autoApplyPlay": "鑷姩鐐规挱", - "recordPushLive": "鎺ㄦ祦褰曞儚", - "redisConfig": "鑷姩閰嶇疆redis", - "thirdPartyGBIdReg": "stream淇℃伅姝e垯", - "savePositionHistory": "淇濆瓨杞ㄨ抗淇℃伅", - "interfaceAuthentication": "鎺ュ彛閴存潈", - "serverId": "鏈嶅姟ID", - "logInDatebase": "鏃ュ織瀛樺偍杩涙暟鎹簱", - "seniorSdp": "鎵╁睍SDP", - "password": "瀵嗙爜", - "port": "绔彛鍙�", - "keepaliveTimeOut": "蹇冭烦瓒呮椂", - "domain": "鍥芥爣鍩�", - "ip": "IP鍦板潃", - "monitorIp": "鐩戝惉IP", - "alarm": "瀛樺偍鎶ヨ淇℃伅", - "ptzSpeed": "浜戝彴鎺у埗閫熷害", - "id": "鍥芥爣ID", - "registerTimeInterval": "娉ㄥ唽闂撮殧", - "artifactId": "妯″潡鍚嶇О", - "version": "鐗堟湰", - "project": "宸ョ▼", - "git_Revision": "GIT淇鐗堟湰", - "git_BRANCH": "GIT鍒嗘敮", - "git_URL": "GIT鍦板潃", - "build_DATE": "鏋勫缓鏃堕棿", - "create_By": "浣滆��", - "git_Revision_SHORT": "GIT淇鐗堟湰锛堢煭锛�", - "build_Jdk": "鏋勫缓鐢↗DK", - }; - console.log(key + ": " + nameData[key]) - - if (nameData[key]) { - return nameData[key] - }else { - return key; + }, + getLoadCount: function () { + let that = this; + if (that.mediaServerChoose != null) { + that.mediaServer.getMediaServer(that.mediaServerChoose, (data) => { + if (data.code == 0) { + that.loadCount = data.data.count } - }, - getMediaKeyNameFromKey: function(key) { - let nameData = { - "waitTrack": "绛夊緟缂栫爜淇℃伅", - "interfaceAuthenticationExcludes": "涓嶈繘琛岄壌鏉冪殑鎺ュ彛", - "playTimeout": "鐐规挱瓒呮椂鏃堕棿", - "autoApplyPlay": "鑷姩鐐规挱", - "recordPushLive": "鎺ㄦ祦褰曞儚", - "redisConfig": "鑷姩閰嶇疆redis", - "thirdPartyGBIdReg": "stream淇℃伅姝e垯", - "savePositionHistory": "淇濆瓨杞ㄨ抗淇℃伅", - "interfaceAuthentication": "鎺ュ彛閴存潈", - "serverId": "鏈嶅姟ID", - "logInDatebase": "鏃ュ織瀛樺偍杩涙暟鎹簱", - "seniorSdp": "鎵╁睍SDP", - "password": "瀵嗙爜", - "port": "绔彛鍙�", - "keepaliveTimeOut": "蹇冭烦瓒呮椂", - "domain": "鍥芥爣鍩�", - "ip": "IP鍦板潃", - "monitorIp": "鐩戝惉IP", - "alarm": "瀛樺偍鎶ヨ淇℃伅", - "ptzSpeed": "浜戝彴鎺у埗閫熷害", - "id": "鍥芥爣ID", - "registerTimeInterval": "娉ㄥ唽闂撮殧", - "artifactId": "妯″潡鍚嶇О", - "version": "鐗堟湰", - "project": "宸ョ▼", - "git_Revision": "GIT淇鐗堟湰", - "git_BRANCH": "GIT鍒嗘敮", - "git_URL": "GIT鍦板潃", - "build_DATE": "鏋勫缓鏃堕棿", - "create_By": "浣滆��", - "git_Revision_SHORT": "GIT淇鐗堟湰锛堢煭锛�", - "build_Jdk": "鏋勫缓鐢↗DK", - }; - console.log(key + ": " + nameData[key]) - - if (nameData[key]) { - return nameData[key] - }else { - return key; - } + }) + } + }, + initTable: function () { + let that = this; + this.tableOption.xAxis = { + type: 'category', + data: [], // x杞存暟鎹� + name: '鏃堕棿', // x杞村悕绉� + // x杞村悕绉版牱寮� + nameTextStyle: { + fontWeight: 300, + fontSize: 15 } + }; + this.tableOption.yAxis = { + type: 'value', + name: '寤惰繜鐜�', // y杞村悕绉� + boundaryGap: [0, '100%'], + max: 100, + axisLabel: { + show: true, + interval: 'auto', + formatter: '{value} %' + }, + // y杞村悕绉版牱寮� + nameTextStyle: { + fontWeight: 300, + fontSize: 15 + } + }; + this.tableOption.dataZoom = [{ + show: true, + start: this.charZoomStart, + end: this.charZoomEnd + }]; + this.myChart = echarts.init(document.getElementById('ThreadsLoad')); + this.myChart.setOption(this.tableOption); + this.myChart.on('dataZoom', function (event) { + if (event.batch) { + that.charZoomStart = event.batch[0].start; + that.charZoomEnd = event.batch[0].end; + } else { + that.charZoomStart = event.start; + that.charZoomEnd = event.end; + } + }); + + this.table1Option.xAxis = { + type: 'category', + data: [], // x杞存暟鎹� + name: '鏃堕棿', // x杞村悕绉� + // x杞村悕绉版牱寮� + nameTextStyle: { + fontWeight: 300, + fontSize: 15 + } + }; + this.table1Option.yAxis = { + type: 'value', + name: '璐熻浇鐜�', // y杞村悕绉� + boundaryGap: [0, '100%'], + max: 100, + axisLabel: { + show: true, + interval: 'auto', + formatter: '{value} %' + }, + // y杞村悕绉版牱寮� + nameTextStyle: { + fontWeight: 300, + fontSize: 15 + } + }; + this.table1Option.dataZoom = [{ + show: true, + start: this.charZoomStart, + end: this.charZoomEnd + }]; + this.myChart1 = echarts.init(document.getElementById('WorkThreadsLoad')); + this.myChart1.setOption(this.table1Option); + this.myChart1.on('dataZoom', function (event) { + if (event.batch) { + that.charZoomStart = event.batch[0].start; + that.charZoomEnd = event.batch[0].end; + } else { + that.charZoomStart = event.start; + that.charZoomEnd = event.end; + } + }); + }, + + getAllSession: function () { + let that = this; + that.allSessionData = []; + this.$axios({ + method: 'get', + url: '/zlm/' + that.mediaServerChoose + '/index/api/getAllSession' + }).then(function (res) { + res.data.data.forEach(item => { + let data = { + peer_ip: item.peer_ip, + local_ip: item.local_ip, + typeid: item.typeid, + id: item.id + }; + that.allSessionData.push(data); + }); + }); + }, + getServerConfig: function () { + let that = this; + this.$axios({ + method: 'get', + url: '/zlm/' + that.mediaServerChoose + '/index/api/getServerConfig' + }).then(function (res) { + let info = res.data.data[0]; + let serverInfo = {} + for (let i = 0; i < Object.keys(info).length; i++) { + let key = Object.keys(info)[i]; + let group = key.substring(0, key.indexOf(".")) + let itemKey = key.substring(key.indexOf(".") + 1) + if (!serverInfo[group]) serverInfo[group] = {} + serverInfo[group][itemKey] = info[key] + } + + that.serverConfig = serverInfo; + that.visible = true; + }); + }, + getWVPServerConfig: function () { + let that = this; + this.$axios({ + method: 'get', + url: '/api/server/config' + }).then(function (res) { + console.log(res) + that.wvpServerConfig = res.data.data; + that.wvpVisible = true; + }); + this.$axios({ + method: 'get', + url: '/api/server/version' + }).then(function (res) { + console.log(res) + that.wvpServerVersion = res.data.data; + that.wvpVisible = true; + }); + }, + reStartServer: function () { + let that = this; + this.$confirm('姝ゆ搷浣滃皢閲嶅惎濯掍綋鏈嶅姟鍣�, 鏄惁缁х画?', '鎻愮ず', { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' + }).then(() => { + let that = this; + this.$axios({ + method: 'get', + url: '/zlm/' + that.mediaServerChoose + '/index/api/restartServer' + }).then(function (res) { + that.getAllSession(); + if (res.data.code == 0) { + that.$message({ + type: 'success', + message: '鎿嶄綔瀹屾垚' + }); + } + }); + }); + }, + deleteRow: function (index, tabledata) { + let that = this; + this.$confirm('姝ゆ搷浣滃皢鏂紑璇ラ�氫俊閾捐矾, 鏄惁缁х画?', '鎻愮ず', { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' + }) + .then(() => { + that.deleteSession(tabledata[index].id); + }) + .catch(() => { + console.log('id锛�' + JSON.stringify(tabledata[index])); + this.$message({ + type: 'info', + message: '宸插彇娑堝垹闄�' + }); + }); + console.log(JSON.stringify(tabledata[index])); + }, + deleteSession: function (id) { + let that = this; + this.$axios({ + method: 'get', + url: '/zlm/' + that.mediaServerChoose + '/index/api/kick_session&id=' + id + }).then(function (res) { + that.getAllSession(); + that.$message({ + type: 'success', + message: '鍒犻櫎鎴愬姛!' + }); + }); + }, + getNameFromKey: function (key) { + let nameData = { + "waitTrack": "绛夊緟缂栫爜淇℃伅", + "interfaceAuthenticationExcludes": "涓嶈繘琛岄壌鏉冪殑鎺ュ彛", + "playTimeout": "鐐规挱瓒呮椂鏃堕棿", + "autoApplyPlay": "鑷姩鐐规挱", + "recordPushLive": "鎺ㄦ祦褰曞儚", + "redisConfig": "鑷姩閰嶇疆redis", + "thirdPartyGBIdReg": "stream淇℃伅姝e垯", + "savePositionHistory": "淇濆瓨杞ㄨ抗淇℃伅", + "interfaceAuthentication": "鎺ュ彛閴存潈", + "serverId": "鏈嶅姟ID", + "logInDatebase": "鏃ュ織瀛樺偍杩涙暟鎹簱", + "seniorSdp": "鎵╁睍SDP", + "password": "瀵嗙爜", + "port": "绔彛鍙�", + "keepaliveTimeOut": "蹇冭烦瓒呮椂", + "domain": "鍥芥爣鍩�", + "ip": "IP鍦板潃", + "monitorIp": "鐩戝惉IP", + "alarm": "瀛樺偍鎶ヨ淇℃伅", + "ptzSpeed": "浜戝彴鎺у埗閫熷害", + "id": "鍥芥爣ID", + "registerTimeInterval": "娉ㄥ唽闂撮殧", + "artifactId": "妯″潡鍚嶇О", + "version": "鐗堟湰", + "project": "宸ョ▼", + "git_Revision": "GIT淇鐗堟湰", + "git_BRANCH": "GIT鍒嗘敮", + "git_URL": "GIT鍦板潃", + "build_DATE": "鏋勫缓鏃堕棿", + "create_By": "浣滆��", + "git_Revision_SHORT": "GIT淇鐗堟湰锛堢煭锛�", + "build_Jdk": "鏋勫缓鐢↗DK", + }; + console.log(key + ": " + nameData[key]) + + if (nameData[key]) { + return nameData[key] + } else { + return key; + } + }, + getMediaKeyNameFromKey: function (key) { + let nameData = { + "waitTrack": "绛夊緟缂栫爜淇℃伅", + "interfaceAuthenticationExcludes": "涓嶈繘琛岄壌鏉冪殑鎺ュ彛", + "playTimeout": "鐐规挱瓒呮椂鏃堕棿", + "autoApplyPlay": "鑷姩鐐规挱", + "recordPushLive": "鎺ㄦ祦褰曞儚", + "redisConfig": "鑷姩閰嶇疆redis", + "thirdPartyGBIdReg": "stream淇℃伅姝e垯", + "savePositionHistory": "淇濆瓨杞ㄨ抗淇℃伅", + "interfaceAuthentication": "鎺ュ彛閴存潈", + "serverId": "鏈嶅姟ID", + "logInDatebase": "鏃ュ織瀛樺偍杩涙暟鎹簱", + "seniorSdp": "鎵╁睍SDP", + "password": "瀵嗙爜", + "port": "绔彛鍙�", + "keepaliveTimeOut": "蹇冭烦瓒呮椂", + "domain": "鍥芥爣鍩�", + "ip": "IP鍦板潃", + "monitorIp": "鐩戝惉IP", + "alarm": "瀛樺偍鎶ヨ淇℃伅", + "ptzSpeed": "浜戝彴鎺у埗閫熷害", + "id": "鍥芥爣ID", + "registerTimeInterval": "娉ㄥ唽闂撮殧", + "artifactId": "妯″潡鍚嶇О", + "version": "鐗堟湰", + "project": "宸ョ▼", + "git_Revision": "GIT淇鐗堟湰", + "git_BRANCH": "GIT鍒嗘敮", + "git_URL": "GIT鍦板潃", + "build_DATE": "鏋勫缓鏃堕棿", + "create_By": "浣滆��", + "git_Revision_SHORT": "GIT淇鐗堟湰锛堢煭锛�", + "build_Jdk": "鏋勫缓鐢↗DK", + }; + console.log(key + ": " + nameData[key]) + + if (nameData[key]) { + return nameData[key] + } else { + return key; + } } + } }; </script> <style> #app { - height: 100%; + height: 100%; } .control-table { - background-color: #ffffff; - height: 25rem; + background-color: #ffffff; + height: 25rem; } .table-c { - border-right: 1px solid #dcdcdc; - border-bottom: 1px solid #dcdcdc; + border-right: 1px solid #dcdcdc; + border-bottom: 1px solid #dcdcdc; } .table-c td { - border-left: 1px solid #dcdcdc; - border-top: 1px solid #dcdcdc; - padding: 0.2rem; + border-left: 1px solid #dcdcdc; + border-top: 1px solid #dcdcdc; + padding: 0.2rem; } .el-table { - width: 99.9% !important; + width: 99.9% !important; } </style> diff --git a/web_src/src/components/devicePosition.vue b/web_src/src/components/devicePosition.vue index 777b11e..0ffd5fa 100644 --- a/web_src/src/components/devicePosition.vue +++ b/web_src/src/components/devicePosition.vue @@ -1,43 +1,35 @@ <template> <div id="devicePosition" style="height: 100%"> - <el-container style="height: 100%"> - <el-header> - <uiHeader></uiHeader> - </el-header> - <el-main> - <div style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> - <span style="font-size: 1rem; font-weight: 500">璁惧瀹氫綅 ({{ parentChannelId == 0 ? deviceId : parentChannelId }})</span> - </div> - <div style="background-color: #ffffff; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left; font-size: 14px;"> - <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem" type="primary" @click="showDevice">杩斿洖</el-button> - <!-- <span class="demonstration">浠�</span> --> - <el-date-picker v-model="searchFrom" type="datetime" placeholder="閫夋嫨寮�濮嬫棩鏈熸椂闂�" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> - <el-date-picker v-model="searchTo" type="datetime" placeholder="閫夋嫨缁撴潫鏃ユ湡鏃堕棿" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> - <el-button-group> - <el-button icon="el-icon-search" size="mini" type="primary" @click="showHistoryPath">鍘嗗彶杞ㄨ抗</el-button> - <el-button icon="el-icon-search" size="mini" style="margin-right: 1rem" type="primary" @click="showLatestPosition">鏈�鏂颁綅缃�</el-button> - </el-button-group> - <el-tag style="width: 5rem; text-align: center" size="medium">杩囨湡鏃堕棿</el-tag> - <el-input-number size="mini" v-model="expired" :min="300" :controls="false" style="width: 4rem;"></el-input-number> - <el-tag style="width: 5rem; text-align: center" size="medium">涓婃姤鍛ㄦ湡</el-tag> - <el-input-number size="mini" v-model="interval" :min="1" :controls="false" style="width: 4rem;"></el-input-number> - <el-button-group> - <el-button icon="el-icon-search" size="mini" type="primary" @click="subscribeMobilePosition">浣嶇疆璁㈤槄</el-button> - <el-button icon="el-icon-search" size="mini" type="primary" @click="unSubscribeMobilePosition">鍙栨秷璁㈤槄</el-button> - </el-button-group> - <el-checkbox size="mini" style="margin-right: 1rem; float: right" v-model="autoList" @change="autoListChange" >鑷姩鍒锋柊</el-checkbox> - </div> - <div class="mapContainer" style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center; height: calc(100% - 10rem);"> - <div class="baidumap" id="allmap"></div> - </div> - </el-main> - </el-container> + <div style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> + <span style="font-size: 1rem; font-weight: 500">璁惧瀹氫綅 ({{ parentChannelId == 0 ? deviceId : parentChannelId }})</span> + </div> + <div style="background-color: #ffffff; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left; font-size: 14px;"> + <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem" type="primary" @click="showDevice">杩斿洖</el-button> + <!-- <span class="demonstration">浠�</span> --> + <el-date-picker v-model="searchFrom" type="datetime" placeholder="閫夋嫨寮�濮嬫棩鏈熸椂闂�" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> + <el-date-picker v-model="searchTo" type="datetime" placeholder="閫夋嫨缁撴潫鏃ユ湡鏃堕棿" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> + <el-button-group> + <el-button icon="el-icon-search" size="mini" type="primary" @click="showHistoryPath">鍘嗗彶杞ㄨ抗</el-button> + <el-button icon="el-icon-search" size="mini" style="margin-right: 1rem" type="primary" @click="showLatestPosition">鏈�鏂颁綅缃�</el-button> + </el-button-group> + <el-tag style="width: 5rem; text-align: center" size="medium">杩囨湡鏃堕棿</el-tag> + <el-input-number size="mini" v-model="expired" :min="300" :controls="false" style="width: 4rem;"></el-input-number> + <el-tag style="width: 5rem; text-align: center" size="medium">涓婃姤鍛ㄦ湡</el-tag> + <el-input-number size="mini" v-model="interval" :min="1" :controls="false" style="width: 4rem;"></el-input-number> + <el-button-group> + <el-button icon="el-icon-search" size="mini" type="primary" @click="subscribeMobilePosition">浣嶇疆璁㈤槄</el-button> + <el-button icon="el-icon-search" size="mini" type="primary" @click="unSubscribeMobilePosition">鍙栨秷璁㈤槄</el-button> + </el-button-group> + <el-checkbox size="mini" style="margin-right: 1rem; float: right" v-model="autoList" @change="autoListChange" >鑷姩鍒锋柊</el-checkbox> + </div> + <div class="mapContainer" style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center; height: calc(100% - 10rem);"> + <div class="baidumap" id="allmap"></div> + </div> </div> </template> <script> -import uiHeader from "./UiHeader.vue"; -import moment from "moment"; +import uiHeader from "../layout/UiHeader.vue"; import geoTools from "./GeoConvertTools.js"; export default { name: "devicePosition", @@ -173,7 +165,7 @@ let self = this; this.$axios({ method: 'get', - url:`/api/position/history/${this.deviceId}`, + url:`/api/position/history/${this.deviceId}`, params: { start: self.startTime, end: self.endTime, @@ -259,7 +251,7 @@ }, toGBString: function (dateTime) { return ( - dateTime.getFullYear() + + dateTime.getFullYear() + "-" + this.twoDigits(dateTime.getMonth() + 1) + "-" + this.twoDigits(dateTime.getDate()) + "T" + this.twoDigits(dateTime.getHours()) + diff --git a/web_src/src/components/live.vue b/web_src/src/components/live.vue index fbe5246..366672d 100644 --- a/web_src/src/components/live.vue +++ b/web_src/src/components/live.vue @@ -1,51 +1,46 @@ <template> - <div id="devicePosition" style="height: 100%"> - <el-container style="height: 100%"> - <el-header> - <uiHeader></uiHeader> - </el-header> - <el-container v-loading="loading" element-loading-text="鎷煎懡鍔犺浇涓�" style="margin: 0 20px;"> - <el-aside width="300px" style="background-color: #ffffff"> - <div style="text-align: center;padding-top: 20px;">璁惧鍒楄〃</div> - <el-menu v-loading="loading"> - <el-submenu v-for="device in deviceList" :key="device.deviceId" :index="device.deviceId" @click="sendDevicePush(item)"> - <template slot="title" > - <i class="el-icon-location-outline"></i> - {{device.name}} - </template> - <ChannelTree :device="device" @sendDevicePush="sendDevicePush"></ChannelTree> - </el-submenu> - </el-menu> - </el-aside> - <el-container> - <!-- <LivePlay></LivePlay> --> - <el-header height="40px" style="text-align: left;font-size: 17px;line-height: 40px;"> - 鍒嗗睆: - <i class="el-icon-full-screen btn" :class="{active:spilt==1}" @click="spilt=1"/> - <i class="el-icon-menu btn" :class="{active:spilt==4}" @click="spilt=4"/> - <i class="el-icon-s-grid btn" :class="{active:spilt==9}" @click="spilt=9"/> - </el-header> - <el-main> - <div style="width: 100%;height: calc( 100vh - 110px );display: flex;flex-wrap: wrap;background-color: #000;"> - <div v-for="i in spilt" :key="i" class="play-box" - :style="liveStyle" :class="{redborder:playerIdx == (i-1)}" - @click="playerIdx = (i-1)" - > - <div v-if="!videoUrl[i-1]" style="color: #ffffff;font-size: 30px;font-weight: bold;">{{i}}</div> - <player v-else :ref="'player'+i" :videoUrl="videoUrl[i-1]" fluent autoplay :height="true" - :containerId="'player'+i" @screenshot="shot" @destroy="destroy"></player> - <!-- <player v-else ref="'player'+i" :idx="'player'+i" :visible.sync="showVideoDialog" :videoUrl="videoUrl[i-1]" :height="true" :hasAudio="hasAudio" fluent autoplay live ></player> --> - </div> - </div> - </el-main> - </el-container> + <div id="devicePosition" style="height: 100%;width: 100%"> + <el-container v-loading="loading" element-loading-text="鎷煎懡鍔犺浇涓�"> + <el-aside width="300px" style="background-color: #ffffff"> + <div style="text-align: center;padding-top: 20px;">璁惧鍒楄〃</div> + <el-menu v-loading="loading"> + <el-submenu v-for="device in deviceList" :key="device.deviceId" :index="device.deviceId" @click="sendDevicePush(item)"> + <template slot="title" > + <i class="el-icon-location-outline"></i> + {{device.name}} + </template> + <ChannelTree :device="device" @sendDevicePush="sendDevicePush"></ChannelTree> + </el-submenu> + </el-menu> + </el-aside> + <el-container> + <!-- <LivePlay></LivePlay> --> + <el-header height="40px" style="text-align: left;font-size: 17px;line-height: 40px;"> + 鍒嗗睆: + <i class="el-icon-full-screen btn" :class="{active:spilt==1}" @click="spilt=1"/> + <i class="el-icon-menu btn" :class="{active:spilt==4}" @click="spilt=4"/> + <i class="el-icon-s-grid btn" :class="{active:spilt==9}" @click="spilt=9"/> + </el-header> + <el-main> + <div style="width: 100%;height: calc( 100vh - 150px );display: flex;flex-wrap: wrap;background-color: #000;"> + <div v-for="i in spilt" :key="i" class="play-box" + :style="liveStyle" :class="{redborder:playerIdx == (i-1)}" + @click="playerIdx = (i-1)" + > + <div v-if="!videoUrl[i-1]" style="color: #ffffff;font-size: 30px;font-weight: bold;">{{i}}</div> + <player v-else :ref="'player'+i" :videoUrl="videoUrl[i-1]" fluent autoplay :height="true" + :containerId="'player'+i" @screenshot="shot" @destroy="destroy"></player> + <!-- <player v-else ref="'player'+i" :idx="'player'+i" :visible.sync="showVideoDialog" :videoUrl="videoUrl[i-1]" :height="true" :hasAudio="hasAudio" fluent autoplay live ></player> --> + </div> + </div> + </el-main> </el-container> </el-container> </div> </template> <script> - import uiHeader from "./UiHeader.vue"; + import uiHeader from "../layout/UiHeader.vue"; import player from './dialog/jessibuca.vue' import ChannelTree from './channelTree.vue' diff --git a/web_src/src/components/setting/Media.vue b/web_src/src/components/setting/Media.vue index cfc4e12..0dc6c76 100644 --- a/web_src/src/components/setting/Media.vue +++ b/web_src/src/components/setting/Media.vue @@ -79,7 +79,7 @@ </template> <script> -import uiHeader from '../UiHeader.vue' +import uiHeader from '../../layout/UiHeader.vue' export default { name: "SettingForMedia", components: { diff --git a/web_src/src/components/setting/Sip.vue b/web_src/src/components/setting/Sip.vue index 3d5d8d5..4955e14 100644 --- a/web_src/src/components/setting/Sip.vue +++ b/web_src/src/components/setting/Sip.vue @@ -44,7 +44,7 @@ </template> <script> -import uiHeader from '../UiHeader.vue' +import uiHeader from '../../layout/UiHeader.vue' export default { name: "SettingForSip", components: { diff --git a/web_src/src/components/setting/Web.vue b/web_src/src/components/setting/Web.vue index 5eb853a..309d3b1 100644 --- a/web_src/src/components/setting/Web.vue +++ b/web_src/src/components/setting/Web.vue @@ -49,7 +49,7 @@ </template> <script> -import uiHeader from '../UiHeader.vue' +import uiHeader from '../../layout/UiHeader.vue' export default { name: "SettingForWeb", components: { diff --git a/web_src/src/layout/UiHeader.vue b/web_src/src/layout/UiHeader.vue new file mode 100644 index 0000000..10410bd --- /dev/null +++ b/web_src/src/layout/UiHeader.vue @@ -0,0 +1,151 @@ +<template> + <div id="UiHeader"> + <el-menu router :default-active="activeIndex" menu-trigger="click" background-color="#545c64" text-color="#fff" + active-text-color="#ffd04b" mode="horizontal"> + <el-menu-item index="/control">鎺у埗鍙�</el-menu-item> + <el-menu-item index="/live">瀹炴椂鐩戞帶</el-menu-item> + <el-menu-item index="/deviceList">鍥芥爣璁惧</el-menu-item> + <el-menu-item index="/pushVideoList">鎺ㄦ祦鍒楄〃</el-menu-item> + <el-menu-item index="/streamProxyList">鎷夋祦浠g悊</el-menu-item> + <el-menu-item index="/cloudRecord">浜戠褰曞儚</el-menu-item> + <el-menu-item index="/mediaServerManger">鑺傜偣绠$悊</el-menu-item> + <el-menu-item index="/parentPlatformList/15/1">鍥芥爣绾ц仈</el-menu-item> + <el-menu-item @click="openDoc">鍦ㄧ嚎鏂囨。</el-menu-item> + <!-- <el-submenu index="/setting">--> + <!-- <template slot="title">绯荤粺璁剧疆</template>--> + <!-- <el-menu-item index="/setting/web">WEB鏈嶅姟</el-menu-item>--> + <!-- <el-menu-item index="/setting/sip">鍥芥爣鏈嶅姟</el-menu-item>--> + <!-- <el-menu-item index="/setting/media">濯掍綋鏈嶅姟</el-menu-item>--> + <!-- </el-submenu>--> + <el-switch v-model="alarmNotify" active-text="鎶ヨ淇℃伅鎺ㄩ��" @change="alarmNotifyChannge"></el-switch> + <!-- <el-menu-item style="float: right;" @click="loginout">閫�鍑�</el-menu-item>--> + <el-submenu index="" style="float: right;"> + <template slot="title">娆㈣繋锛寋{ this.$cookies.get("session").username }}</template> + <el-menu-item @click="changePassword">淇敼瀵嗙爜</el-menu-item> + <el-menu-item @click="loginout">娉ㄩ攢</el-menu-item> + </el-submenu> + </el-menu> + <changePasswordDialog ref="changePasswordDialog"></changePasswordDialog> + </div> +</template> + +<script> + +import changePasswordDialog from '../components/dialog/changePassword.vue' + +export default { + name: "UiHeader", + components: {Notification, changePasswordDialog}, + data() { + return { + alarmNotify: false, + sseSource: null, + activeIndex: this.$route.path, + }; + }, + created() { + if (this.$route.path.startsWith("/channelList")) { + this.activeIndex = "/deviceList" + } + + }, + mounted() { + window.addEventListener('beforeunload', e => this.beforeunloadHandler(e)) + // window.addEventListener('unload', e => this.unloadHandler(e)) + this.alarmNotify = this.getAlarmSwitchStatus() === "true"; + this.sseControl(); + }, + methods: { + loginout() { + this.$axios({ + method: 'get', + url: "/api/user/logout" + }).then((res) => { + // 鍒犻櫎cookie锛屽洖鍒扮櫥褰曢〉闈� + this.$cookies.remove("session"); + this.$router.push('/login'); + this.sseSource.close(); + }).catch((error) => { + console.error("鐧诲嚭澶辫触") + console.error(error) + }); + }, + changePassword() { + this.$refs.changePasswordDialog.openDialog() + }, + openDoc() { + console.log(process.env.BASE_API) + window.open(!!process.env.BASE_API ? process.env.BASE_API + "/doc.html" : "/doc.html") + }, + beforeunloadHandler() { + this.sseSource.close(); + }, + alarmNotifyChannge() { + this.setAlarmSwitchStatus() + this.sseControl() + }, + sseControl() { + let that = this; + if (this.alarmNotify) { + console.log("鐢宠SSE鎺ㄩ�丄PI璋冪敤锛屾祻瑙堝櫒ID: " + this.$browserId); + this.sseSource = new EventSource('/api/emit?browserId=' + this.$browserId); + this.sseSource.addEventListener('message', function (evt) { + that.$notify({ + title: '鏀跺埌鎶ヨ淇℃伅', + dangerouslyUseHTMLString: true, + message: evt.data, + type: 'warning' + }); + console.log("鏀跺埌淇℃伅锛�" + evt.data); + }); + this.sseSource.addEventListener('open', function (e) { + console.log("SSE杩炴帴鎵撳紑."); + }, false); + this.sseSource.addEventListener('error', function (e) { + if (e.target.readyState == EventSource.CLOSED) { + console.log("SSE杩炴帴鍏抽棴"); + } else { + console.log(e.target.readyState); + } + }, false); + } else { + if (this.sseSource != null) { + this.sseSource.removeEventListener('open', null); + this.sseSource.removeEventListener('message', null); + this.sseSource.removeEventListener('error', null); + this.sseSource.close(); + } + + } + }, + getAlarmSwitchStatus() { + if (localStorage.getItem("alarmSwitchStatus") == null) { + localStorage.setItem("alarmSwitchStatus", false); + } + return localStorage.getItem("alarmSwitchStatus"); + }, + setAlarmSwitchStatus() { + localStorage.setItem("alarmSwitchStatus", this.alarmNotify); + } + }, + destroyed() { + window.removeEventListener('beforeunload', e => this.beforeunloadHandler(e)) + if (this.sseSource != null) { + this.sseSource.removeEventListener('open', null); + this.sseSource.removeEventListener('message', null); + this.sseSource.removeEventListener('error', null); + this.sseSource.close(); + } + }, + +} + +</script> +<style> +#UiHeader .el-switch__label { + color: white; +} +#UiHeader .el-switch__label.is-active{ + color: #409EFF; +} +</style> diff --git a/web_src/src/layout/index.vue b/web_src/src/layout/index.vue new file mode 100644 index 0000000..4fdbc72 --- /dev/null +++ b/web_src/src/layout/index.vue @@ -0,0 +1,90 @@ +<template> + <el-container style="height: 100%"> + <el-header> + <ui-header/> + </el-header> + <el-main> + <el-container> + <transition name="fade"> + <router-view></router-view> + </transition> + </el-container> + </el-main> + </el-container> +</template> + +<script> +import uiHeader from "./UiHeader.vue"; + +export default { + name: "index", + components: { + uiHeader + }, +} +</script> +<style> +/*瀹氫箟婊氬姩鏉¢珮瀹藉強鑳屾櫙 楂樺鍒嗗埆瀵瑰簲妯珫婊氬姩鏉$殑灏哄*/ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +/*瀹氫箟婊氬姩鏉¤建閬� 鍐呴槾褰�+鍦嗚*/ +::-webkit-scrollbar-track { + border-radius: 4px; + background-color: #F5F5F5; +} + +/*瀹氫箟婊戝潡 鍐呴槾褰�+鍦嗚*/ +::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: #c8c8c8; + box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); +} + +/*瀹氫箟鏍囬鏍�*/ +.page-header { + background-color: #FFFFFF; + margin-bottom: 1rem; + padding: 0.5rem; + display: flex; + justify-content: space-between; + align-items: center; +} + +.page-title { + font-weight: bold; + text-align: left; +} + +.page-header-btn { + text-align: right; +} +</style> +<style scoped> +.el-main { + margin: 0; +} + +.fade-enter { + visibility: hidden; + opacity: 0; +} + +.fade-leave-to { + display: none; +} + +.fade-enter-active, +.fade-leave-active { + transition: opacity .5s ease; +} + +.fade-enter-to, +.fade-leave { + visibility: visible; + opacity: 1; +} +</style> diff --git a/web_src/src/router/index.js b/web_src/src/router/index.js index 05bb1ae..356bc33 100644 --- a/web_src/src/router/index.js +++ b/web_src/src/router/index.js @@ -1,5 +1,6 @@ import Vue from 'vue' import VueRouter from 'vue-router' +import Layout from "../layout/index.vue" import control from '../components/control.vue' import deviceList from '../components/DeviceList.vue' @@ -32,78 +33,86 @@ routes: [ { path: '/', - component: control, - }, - { - path: '/live', - component: live, - }, - { - path: '/deviceList', - component: deviceList, - }, - { - path: '/pushVideoList', - component: pushVideoList, - }, - { - path: '/streamProxyList', - component: streamProxyList, + name: 'home', + component: Layout, + redirect: '/control', + children: [ + { + path: '/control', + component: control, + }, + { + path: '/live', + component: live, + }, + { + path: '/deviceList', + component: deviceList, + }, + { + path: '/pushVideoList', + component: pushVideoList, + }, + { + path: '/streamProxyList', + component: streamProxyList, + }, + { + path: '/channelList/:deviceId/:parentChannelId/:count/:page', + name: 'channelList', + component: channelList, + }, + { + path: '/parentPlatformList/:count/:page', + name: 'parentPlatformList', + component: parentPlatformList, + }, + { + path: '/devicePosition/:deviceId/:parentChannelId/:count/:page', + name: 'devicePosition', + component: devicePosition, + }, + { + path: '/cloudRecord', + name: 'cloudRecord', + component: cloudRecord, + }, + { + path: '/mediaServerManger', + name: 'mediaServerManger', + component: mediaServerManger, + }, + { + path: '/setting/web', + name: 'web', + component: web, + }, + { + path: '/setting/sip', + name: 'sip', + component: sip, + }, + { + path: '/setting/media', + name: 'media', + component: media, + }, + { + path: '/play/wasm/:url', + name: 'wasmPlayer', + component: wasmPlayer, + }, + { + path: '/play/rtc/:url', + name: 'rtcPlayer', + component: rtcPlayer, + }, + ] }, { path: '/login', name: '鐧诲綍', component: login, - }, - { - path: '/channelList/:deviceId/:parentChannelId/:count/:page', - name: 'channelList', - component: channelList, - }, - { - path: '/parentPlatformList/:count/:page', - name: 'parentPlatformList', - component: parentPlatformList, - }, - { - path: '/devicePosition/:deviceId/:parentChannelId/:count/:page', - name: 'devicePosition', - component: devicePosition, - }, - { - path: '/cloudRecord', - name: 'cloudRecord', - component: cloudRecord, - }, - { - path: '/mediaServerManger', - name: 'mediaServerManger', - component: mediaServerManger, - }, - { - path: '/setting/web', - name: 'web', - component: web, - }, - { - path: '/setting/sip', - name: 'sip', - component: sip, - }, - { - path: '/setting/media', - name: 'media', - component: media, - }, - { - path: '/play/wasm/:url', - name: 'wasmPlayer', - component: wasmPlayer, - }, - { - path: '/play/rtc/:url', - name: 'rtcPlayer', - component: rtcPlayer, }, ] }) -- Gitblit v1.8.0