Commit fb843d41c1e186b2109bfeea73509cad2b135cdc
1 parent
3def634a
1.重构全局页面结构,从之前每个页面独立绘制改为路由嵌套
2.全局页面样式优化,如滚动条、标题栏等
Showing
17 changed files
with
2249 additions
and
2037 deletions
web_src/src/components/CloudRecord.vue
| 1 | 1 | <template> |
| 2 | - <div id="app"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span v-if="!recordDetail" >云端录像</span> | |
| 10 | - <el-page-header v-if="recordDetail" @back="backToList" content="云端录像"> | |
| 11 | - </el-page-header> | |
| 12 | - <div style="position: absolute; right: 5rem; top: 0.3rem;"> | |
| 13 | - 节点选择: | |
| 14 | - <el-select size="mini" @change="chooseMediaChange" style="width: 16rem; margin-right: 1rem;" v-model="mediaServerId" placeholder="请选择" :disabled="recordDetail"> | |
| 15 | - <el-option | |
| 16 | - v-for="item in mediaServerList" | |
| 17 | - :key="item.id" | |
| 18 | - :label="item.id" | |
| 19 | - :value="item.id"> | |
| 20 | - </el-option> | |
| 21 | - </el-select> | |
| 22 | - </div> | |
| 23 | - <div style="position: absolute; right: 1rem; top: 0.3rem;"> | |
| 24 | - <el-button v-if="!recordDetail" icon="el-icon-refresh-right" circle size="mini" :loading="loading" @click="getRecordList()"></el-button> | |
| 25 | - </div> | |
| 26 | - </div> | |
| 27 | - <div v-if="!recordDetail"> | |
| 2 | + <div id="app" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">云端录像</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + 节点选择: | |
| 7 | + <el-select size="mini" @change="chooseMediaChange" style="width: 16rem; margin-right: 1rem;" v-model="mediaServerId" placeholder="请选择" :disabled="recordDetail"> | |
| 8 | + <el-option | |
| 9 | + v-for="item in mediaServerList" | |
| 10 | + :key="item.id" | |
| 11 | + :label="item.id" | |
| 12 | + :value="item.id"> | |
| 13 | + </el-option> | |
| 14 | + </el-select> | |
| 15 | + <el-button v-if="!recordDetail" icon="el-icon-refresh-right" circle size="mini" :loading="loading" @click="getRecordList()"></el-button> | |
| 16 | + </div> | |
| 17 | + </div> | |
| 18 | + <div v-if="!recordDetail"> | |
| 28 | 19 | |
| 29 | - <!--设备列表--> | |
| 30 | - <el-table :data="recordList" border style="width: 100%" :height="winHeight"> | |
| 31 | - <el-table-column prop="app" label="应用名" align="center"> | |
| 32 | - </el-table-column> | |
| 33 | - <el-table-column prop="stream" label="流ID" align="center"> | |
| 34 | - </el-table-column> | |
| 35 | - <el-table-column prop="time" label="时间" align="center"> | |
| 36 | - </el-table-column> | |
| 37 | - <el-table-column label="操作" width="360" align="center" fixed="right"> | |
| 38 | - <template slot-scope="scope"> | |
| 39 | - <el-button-group> | |
| 40 | - <el-button size="mini" icon="el-icon-video-camera-solid" type="primary" @click="showRecordDetail(scope.row)">查看</el-button> | |
| 41 | -<!-- <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteRecord(scope.row)">删除</el-button>--> | |
| 42 | - </el-button-group> | |
| 43 | - </template> | |
| 44 | - </el-table-column> | |
| 45 | - </el-table> | |
| 46 | - <el-pagination | |
| 47 | - style="float: right" | |
| 48 | - @size-change="handleSizeChange" | |
| 49 | - @current-change="currentChange" | |
| 50 | - :current-page="currentPage" | |
| 51 | - :page-size="count" | |
| 52 | - :page-sizes="[15, 25, 35, 50]" | |
| 53 | - layout="total, sizes, prev, pager, next" | |
| 54 | - :total="total"> | |
| 55 | - </el-pagination> | |
| 56 | - </div> | |
| 57 | - <cloud-record-detail ref="cloudRecordDetail" v-if="recordDetail" :recordFile="chooseRecord" :mediaServerId="mediaServerId" :mediaServerPath="mediaServerPath" ></cloud-record-detail> | |
| 58 | - </el-main> | |
| 59 | - </el-container> | |
| 60 | - </div> | |
| 20 | + <!--设备列表--> | |
| 21 | + <el-table :data="recordList" border style="width: 100%" :height="winHeight"> | |
| 22 | + <el-table-column prop="app" label="应用名" align="center"> | |
| 23 | + </el-table-column> | |
| 24 | + <el-table-column prop="stream" label="流ID" align="center"> | |
| 25 | + </el-table-column> | |
| 26 | + <el-table-column prop="time" label="时间" align="center"> | |
| 27 | + </el-table-column> | |
| 28 | + <el-table-column label="操作" width="360" align="center" fixed="right"> | |
| 29 | + <template slot-scope="scope"> | |
| 30 | + <el-button-group> | |
| 31 | + <el-button size="mini" icon="el-icon-video-camera-solid" type="primary" @click="showRecordDetail(scope.row)">查看</el-button> | |
| 32 | + <!-- <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteRecord(scope.row)">删除</el-button>--> | |
| 33 | + </el-button-group> | |
| 34 | + </template> | |
| 35 | + </el-table-column> | |
| 36 | + </el-table> | |
| 37 | + <el-pagination | |
| 38 | + style="float: right" | |
| 39 | + @size-change="handleSizeChange" | |
| 40 | + @current-change="currentChange" | |
| 41 | + :current-page="currentPage" | |
| 42 | + :page-size="count" | |
| 43 | + :page-sizes="[15, 25, 35, 50]" | |
| 44 | + layout="total, sizes, prev, pager, next" | |
| 45 | + :total="total"> | |
| 46 | + </el-pagination> | |
| 47 | + </div> | |
| 48 | + <cloud-record-detail ref="cloudRecordDetail" v-if="recordDetail" :recordFile="chooseRecord" :mediaServerId="mediaServerId" :mediaServerPath="mediaServerPath" ></cloud-record-detail> | |
| 49 | + | |
| 50 | + </div> | |
| 61 | 51 | </template> |
| 62 | 52 | |
| 63 | 53 | <script> |
| 64 | - import uiHeader from './UiHeader.vue' | |
| 54 | + import uiHeader from '../layout/UiHeader.vue' | |
| 65 | 55 | import cloudRecordDetail from './CloudRecordDetail.vue' |
| 66 | 56 | import MediaServer from './service/MediaServer' |
| 67 | 57 | export default { | ... | ... |
web_src/src/components/CloudRecordDetail.vue
| ... | ... | @@ -104,7 +104,7 @@ |
| 104 | 104 | |
| 105 | 105 | <script> |
| 106 | 106 | // TODO 根据查询的时间列表设置滑轨的最大值与最小值, |
| 107 | - import uiHeader from './UiHeader.vue' | |
| 107 | + import uiHeader from '../layout/UiHeader.vue' | |
| 108 | 108 | import player from './dialog/easyPlayer.vue' |
| 109 | 109 | import moment from 'moment' |
| 110 | 110 | export default { | ... | ... |
web_src/src/components/DeviceList.vue
| 1 | 1 | <template> |
| 2 | - <div id="app"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">设备列表</span> | |
| 10 | - <div style="position: absolute; right: 1rem; top: 0.3rem;"> | |
| 11 | - <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading" @click="getDeviceList()"></el-button> | |
| 12 | - </div> | |
| 13 | - </div> | |
| 14 | - <!-- <devicePlayer ref="devicePlayer"></devicePlayer> --> | |
| 15 | - <!--设备列表--> | |
| 16 | - <el-table :data="deviceList" border style="width: 100%;font-size: 12px;" :height="winHeight"> | |
| 17 | - <el-table-column prop="name" label="名称" align="center"> | |
| 18 | - </el-table-column> | |
| 19 | - <el-table-column prop="deviceId" label="设备编号" width="180" align="center"> | |
| 20 | - </el-table-column> | |
| 21 | - <el-table-column label="地址" width="180" align="center"> | |
| 22 | - <template slot-scope="scope"> | |
| 23 | - <div slot="reference" class="name-wrapper"> | |
| 24 | - <el-tag size="medium">{{ scope.row.hostAddress }}</el-tag> | |
| 25 | - </div> | |
| 26 | - </template> | |
| 27 | - </el-table-column> | |
| 28 | - <el-table-column prop="manufacturer" label="厂家" align="center"> | |
| 29 | - </el-table-column> | |
| 30 | - <el-table-column label="流传输模式" align="center" width="120"> | |
| 31 | - <template slot-scope="scope"> | |
| 32 | - <el-select size="mini" @change="transportChange(scope.row)" v-model="scope.row.streamMode" placeholder="请选择"> | |
| 33 | - <el-option key="UDP" label="UDP" value="UDP"></el-option> | |
| 34 | - <el-option key="TCP-ACTIVE" label="TCP主动模式" :disabled="true" value="TCP-ACTIVE"></el-option> | |
| 35 | - <el-option key="TCP-PASSIVE" label="TCP被动模式" value="TCP-PASSIVE"></el-option> | |
| 36 | - </el-select> | |
| 37 | - </template> | |
| 38 | - </el-table-column> | |
| 39 | - <el-table-column prop="channelCount" label="通道数" align="center"> | |
| 40 | - </el-table-column> | |
| 41 | - <el-table-column label="状态" width="120" align="center"> | |
| 42 | - <template slot-scope="scope"> | |
| 43 | - <div slot="reference" class="name-wrapper"> | |
| 44 | - <el-tag size="medium" v-if="scope.row.online == 1">在线</el-tag> | |
| 45 | - <el-tag size="medium" type="info" v-if="scope.row.online == 0">离线</el-tag> | |
| 46 | - </div> | |
| 47 | - </template> | |
| 48 | - </el-table-column> | |
| 49 | - <el-table-column prop="keepaliveTime" label="最近心跳" align="center" width="140"> | |
| 50 | - </el-table-column> | |
| 51 | - <el-table-column prop="registerTime" label="最近注册" align="center" width="140"> | |
| 52 | - </el-table-column> | |
| 53 | - <el-table-column prop="updateTime" label="更新时间" align="center" width="140"> | |
| 54 | - </el-table-column> | |
| 55 | - <el-table-column prop="createTime" label="创建时间" align="center" width="140"> | |
| 56 | - </el-table-column> | |
| 2 | + <div id="app" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">设备列表</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading" | |
| 7 | + @click="getDeviceList()"></el-button> | |
| 8 | + </div> | |
| 9 | + </div> | |
| 10 | + <!-- <devicePlayer ref="devicePlayer"></devicePlayer> --> | |
| 11 | + <!--设备列表--> | |
| 12 | + <el-table :data="deviceList" border style="width: 100%;font-size: 12px;" :height="winHeight"> | |
| 13 | + <el-table-column prop="name" label="名称" align="center"> | |
| 14 | + </el-table-column> | |
| 15 | + <el-table-column prop="deviceId" label="设备编号" width="180" align="center"> | |
| 16 | + </el-table-column> | |
| 17 | + <el-table-column label="地址" width="180" align="center"> | |
| 18 | + <template slot-scope="scope"> | |
| 19 | + <div slot="reference" class="name-wrapper"> | |
| 20 | + <el-tag size="medium">{{ scope.row.hostAddress }}</el-tag> | |
| 21 | + </div> | |
| 22 | + </template> | |
| 23 | + </el-table-column> | |
| 24 | + <el-table-column prop="manufacturer" label="厂家" align="center"> | |
| 25 | + </el-table-column> | |
| 26 | + <el-table-column label="流传输模式" align="center" width="120"> | |
| 27 | + <template slot-scope="scope"> | |
| 28 | + <el-select size="mini" @change="transportChange(scope.row)" v-model="scope.row.streamMode" placeholder="请选择"> | |
| 29 | + <el-option key="UDP" label="UDP" value="UDP"></el-option> | |
| 30 | + <el-option key="TCP-ACTIVE" label="TCP主动模式" :disabled="true" value="TCP-ACTIVE"></el-option> | |
| 31 | + <el-option key="TCP-PASSIVE" label="TCP被动模式" value="TCP-PASSIVE"></el-option> | |
| 32 | + </el-select> | |
| 33 | + </template> | |
| 34 | + </el-table-column> | |
| 35 | + <el-table-column prop="channelCount" label="通道数" align="center"> | |
| 36 | + </el-table-column> | |
| 37 | + <el-table-column label="状态" width="120" align="center"> | |
| 38 | + <template slot-scope="scope"> | |
| 39 | + <div slot="reference" class="name-wrapper"> | |
| 40 | + <el-tag size="medium" v-if="scope.row.online == 1">在线</el-tag> | |
| 41 | + <el-tag size="medium" type="info" v-if="scope.row.online == 0">离线</el-tag> | |
| 42 | + </div> | |
| 43 | + </template> | |
| 44 | + </el-table-column> | |
| 45 | + <el-table-column prop="keepaliveTime" label="最近心跳" align="center" width="140"> | |
| 46 | + </el-table-column> | |
| 47 | + <el-table-column prop="registerTime" label="最近注册" align="center" width="140"> | |
| 48 | + </el-table-column> | |
| 49 | + <el-table-column prop="updateTime" label="更新时间" align="center" width="140"> | |
| 50 | + </el-table-column> | |
| 51 | + <el-table-column prop="createTime" label="创建时间" align="center" width="140"> | |
| 52 | + </el-table-column> | |
| 57 | 53 | |
| 58 | - <el-table-column label="操作" width="450" align="center" fixed="right"> | |
| 59 | - <template slot-scope="scope"> | |
| 60 | - <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> | |
| 61 | - <el-button-group> | |
| 62 | - <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> | |
| 63 | - <el-button size="mini" icon="el-icon-location" v-bind:disabled="scope.row.online==0" type="primary" @click="showDevicePosition(scope.row)">定位</el-button> | |
| 64 | - <el-button size="mini" icon="el-icon-edit" type="primary" @click="edit(scope.row)">编辑</el-button> | |
| 65 | - <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteDevice(scope.row)">删除</el-button> | |
| 66 | - </el-button-group> | |
| 67 | - </template> | |
| 68 | - </el-table-column> | |
| 69 | - </el-table> | |
| 70 | - <el-pagination | |
| 71 | - style="float: right" | |
| 72 | - @size-change="handleSizeChange" | |
| 73 | - @current-change="currentChange" | |
| 74 | - :current-page="currentPage" | |
| 75 | - :page-size="count" | |
| 76 | - :page-sizes="[15, 25, 35, 50]" | |
| 77 | - layout="total, sizes, prev, pager, next" | |
| 78 | - :total="total"> | |
| 79 | - </el-pagination> | |
| 80 | - <deviceEdit ref="deviceEdit" ></deviceEdit> | |
| 81 | - <syncChannelProgress ref="syncChannelProgress" ></syncChannelProgress> | |
| 82 | - </el-main> | |
| 83 | - </el-container> | |
| 84 | - </div> | |
| 54 | + <el-table-column label="操作" width="450" align="center" fixed="right"> | |
| 55 | + <template slot-scope="scope"> | |
| 56 | + <el-button size="mini" v-if="scope.row.online!=0" icon="el-icon-refresh" @click="refDevice(scope.row)" | |
| 57 | + @mouseover="getTooltipContent(scope.row.deviceId)">刷新 | |
| 58 | + </el-button> | |
| 59 | + <el-button-group> | |
| 60 | + <el-button size="mini" icon="el-icon-video-camera-solid" v-bind:disabled="scope.row.online==0" | |
| 61 | + type="primary" @click="showChannelList(scope.row)">通道 | |
| 62 | + </el-button> | |
| 63 | + <el-button size="mini" icon="el-icon-location" v-bind:disabled="scope.row.online==0" type="primary" | |
| 64 | + @click="showDevicePosition(scope.row)">定位 | |
| 65 | + </el-button> | |
| 66 | + <el-button size="mini" icon="el-icon-edit" type="primary" @click="edit(scope.row)">编辑</el-button> | |
| 67 | + <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteDevice(scope.row)">删除</el-button> | |
| 68 | + </el-button-group> | |
| 69 | + </template> | |
| 70 | + </el-table-column> | |
| 71 | + </el-table> | |
| 72 | + <el-pagination | |
| 73 | + style="float: right" | |
| 74 | + @size-change="handleSizeChange" | |
| 75 | + @current-change="currentChange" | |
| 76 | + :current-page="currentPage" | |
| 77 | + :page-size="count" | |
| 78 | + :page-sizes="[15, 25, 35, 50]" | |
| 79 | + layout="total, sizes, prev, pager, next" | |
| 80 | + :total="total"> | |
| 81 | + </el-pagination> | |
| 82 | + <deviceEdit ref="deviceEdit"></deviceEdit> | |
| 83 | + <syncChannelProgress ref="syncChannelProgress"></syncChannelProgress> | |
| 84 | + </div> | |
| 85 | 85 | </template> |
| 86 | 86 | |
| 87 | 87 | <script> |
| 88 | - import uiHeader from './UiHeader.vue' | |
| 89 | - import deviceEdit from './dialog/deviceEdit.vue' | |
| 90 | - import syncChannelProgress from './dialog/SyncChannelProgress.vue' | |
| 91 | - export default { | |
| 92 | - name: 'app', | |
| 93 | - components: { | |
| 94 | - uiHeader, | |
| 95 | - deviceEdit, | |
| 96 | - syncChannelProgress, | |
| 97 | - }, | |
| 98 | - data() { | |
| 99 | - return { | |
| 100 | - deviceList: [], //设备列表 | |
| 101 | - currentDevice: {}, //当前操作设备对象 | |
| 88 | +import uiHeader from '../layout/UiHeader.vue' | |
| 89 | +import deviceEdit from './dialog/deviceEdit.vue' | |
| 90 | +import syncChannelProgress from './dialog/SyncChannelProgress.vue' | |
| 102 | 91 | |
| 103 | - videoComponentList: [], | |
| 104 | - updateLooper: 0, //数据刷新轮训标志 | |
| 105 | - currentDeviceChannelsLenth:0, | |
| 106 | - winHeight: window.innerHeight - 200, | |
| 107 | - currentPage:1, | |
| 108 | - count:15, | |
| 109 | - total:0, | |
| 110 | - getDeviceListLoading: false, | |
| 111 | - }; | |
| 112 | - }, | |
| 113 | - computed: { | |
| 114 | - getcurrentDeviceChannels: function() { | |
| 115 | - let data = this.currentDevice['channelMap']; | |
| 116 | - let channels = null; | |
| 117 | - if (data) { | |
| 118 | - channels = Object.keys(data).map(key => { | |
| 119 | - return data[key]; | |
| 120 | - }); | |
| 121 | - this.currentDeviceChannelsLenth = channels.length; | |
| 122 | - } | |
| 123 | - return channels; | |
| 124 | - } | |
| 125 | - }, | |
| 126 | - mounted() { | |
| 127 | - this.initData(); | |
| 128 | - this.updateLooper = setInterval(this.initData, 10000); | |
| 129 | - }, | |
| 130 | - destroyed() { | |
| 131 | - this.$destroy('videojs'); | |
| 132 | - clearTimeout(this.updateLooper); | |
| 133 | - }, | |
| 134 | - methods: { | |
| 135 | - initData: function() { | |
| 136 | - this.getDeviceList(); | |
| 137 | - }, | |
| 138 | - currentChange: function(val){ | |
| 139 | - this.currentPage = val; | |
| 140 | - this.getDeviceList(); | |
| 141 | - }, | |
| 142 | - handleSizeChange: function(val){ | |
| 143 | - this.count = val; | |
| 144 | - this.getDeviceList(); | |
| 145 | - }, | |
| 146 | - getDeviceList: function() { | |
| 147 | - let that = this; | |
| 148 | - this.getDeviceListLoading = true; | |
| 149 | - this.$axios({ | |
| 150 | - method: 'get', | |
| 151 | - url:`/api/device/query/devices`, | |
| 152 | - params: { | |
| 153 | - page: that.currentPage, | |
| 154 | - count: that.count | |
| 155 | - } | |
| 156 | - }).then(function (res) { | |
| 157 | - that.total = res.data.total; | |
| 158 | - that.deviceList = res.data.list; | |
| 159 | - that.getDeviceListLoading = false; | |
| 160 | - }).catch(function (error) { | |
| 161 | - console.error(error); | |
| 162 | - that.getDeviceListLoading = false; | |
| 163 | - }); | |
| 92 | +export default { | |
| 93 | + name: 'app', | |
| 94 | + components: { | |
| 95 | + uiHeader, | |
| 96 | + deviceEdit, | |
| 97 | + syncChannelProgress, | |
| 98 | + }, | |
| 99 | + data() { | |
| 100 | + return { | |
| 101 | + deviceList: [], //设备列表 | |
| 102 | + currentDevice: {}, //当前操作设备对象 | |
| 164 | 103 | |
| 165 | - }, | |
| 166 | - deleteDevice: function(row) { | |
| 167 | - let msg = "确定删除此设备?" | |
| 168 | - if (row.online !== 0) { | |
| 169 | - msg = "在线设备删除后仍可通过注册再次上线。<br/>如需彻底删除请先将设备离线。<br/><strong>确定删除此设备?</strong>" | |
| 104 | + videoComponentList: [], | |
| 105 | + updateLooper: 0, //数据刷新轮训标志 | |
| 106 | + currentDeviceChannelsLenth: 0, | |
| 107 | + winHeight: window.innerHeight - 200, | |
| 108 | + currentPage: 1, | |
| 109 | + count: 15, | |
| 110 | + total: 0, | |
| 111 | + getDeviceListLoading: false, | |
| 112 | + }; | |
| 113 | + }, | |
| 114 | + computed: { | |
| 115 | + getcurrentDeviceChannels: function () { | |
| 116 | + let data = this.currentDevice['channelMap']; | |
| 117 | + let channels = null; | |
| 118 | + if (data) { | |
| 119 | + channels = Object.keys(data).map(key => { | |
| 120 | + return data[key]; | |
| 121 | + }); | |
| 122 | + this.currentDeviceChannelsLenth = channels.length; | |
| 123 | + } | |
| 124 | + return channels; | |
| 125 | + } | |
| 126 | + }, | |
| 127 | + mounted() { | |
| 128 | + this.initData(); | |
| 129 | + this.updateLooper = setInterval(this.initData, 10000); | |
| 130 | + }, | |
| 131 | + destroyed() { | |
| 132 | + this.$destroy('videojs'); | |
| 133 | + clearTimeout(this.updateLooper); | |
| 134 | + }, | |
| 135 | + methods: { | |
| 136 | + initData: function () { | |
| 137 | + this.getDeviceList(); | |
| 138 | + }, | |
| 139 | + currentChange: function (val) { | |
| 140 | + this.currentPage = val; | |
| 141 | + this.getDeviceList(); | |
| 142 | + }, | |
| 143 | + handleSizeChange: function (val) { | |
| 144 | + this.count = val; | |
| 145 | + this.getDeviceList(); | |
| 146 | + }, | |
| 147 | + getDeviceList: function () { | |
| 148 | + let that = this; | |
| 149 | + this.getDeviceListLoading = true; | |
| 150 | + this.$axios({ | |
| 151 | + method: 'get', | |
| 152 | + url: `/api/device/query/devices`, | |
| 153 | + params: { | |
| 154 | + page: that.currentPage, | |
| 155 | + count: that.count | |
| 170 | 156 | } |
| 171 | - this.$confirm(msg, '提示', { | |
| 172 | - dangerouslyUseHTMLString : true, | |
| 173 | - confirmButtonText: '确定', | |
| 174 | - cancelButtonText: '取消', | |
| 175 | - center: true, | |
| 176 | - type: 'warning' | |
| 177 | - }).then(() => { | |
| 178 | - this.$axios({ | |
| 179 | - method: 'delete', | |
| 180 | - url:`/api/device/query/devices/${row.deviceId}/delete` | |
| 181 | - }).then((res)=>{ | |
| 182 | - this.getDeviceList(); | |
| 183 | - }).catch((error) =>{ | |
| 184 | - console.error(error); | |
| 185 | - }); | |
| 186 | - }).catch(() => { | |
| 157 | + }).then(function (res) { | |
| 158 | + that.total = res.data.total; | |
| 159 | + that.deviceList = res.data.list; | |
| 160 | + that.getDeviceListLoading = false; | |
| 161 | + }).catch(function (error) { | |
| 162 | + console.error(error); | |
| 163 | + that.getDeviceListLoading = false; | |
| 164 | + }); | |
| 187 | 165 | |
| 166 | + }, | |
| 167 | + deleteDevice: function (row) { | |
| 168 | + let msg = "确定删除此设备?" | |
| 169 | + if (row.online !== 0) { | |
| 170 | + msg = "在线设备删除后仍可通过注册再次上线。<br/>如需彻底删除请先将设备离线。<br/><strong>确定删除此设备?</strong>" | |
| 171 | + } | |
| 172 | + this.$confirm(msg, '提示', { | |
| 173 | + dangerouslyUseHTMLString: true, | |
| 174 | + confirmButtonText: '确定', | |
| 175 | + cancelButtonText: '取消', | |
| 176 | + center: true, | |
| 177 | + type: 'warning' | |
| 178 | + }).then(() => { | |
| 179 | + this.$axios({ | |
| 180 | + method: 'delete', | |
| 181 | + url: `/api/device/query/devices/${row.deviceId}/delete` | |
| 182 | + }).then((res) => { | |
| 183 | + this.getDeviceList(); | |
| 184 | + }).catch((error) => { | |
| 185 | + console.error(error); | |
| 188 | 186 | }); |
| 187 | + }).catch(() => { | |
| 188 | + | |
| 189 | + }); | |
| 189 | 190 | |
| 190 | 191 | |
| 191 | - }, | |
| 192 | - showChannelList: function(row) { | |
| 193 | - this.$router.push(`/channelList/${row.deviceId}/0/15/1`); | |
| 194 | - }, | |
| 195 | - showDevicePosition: function(row) { | |
| 196 | - this.$router.push(`/devicePosition/${row.deviceId}/0/15/1`); | |
| 197 | - }, | |
| 192 | + }, | |
| 193 | + showChannelList: function (row) { | |
| 194 | + this.$router.push(`/channelList/${row.deviceId}/0/15/1`); | |
| 195 | + }, | |
| 196 | + showDevicePosition: function (row) { | |
| 197 | + this.$router.push(`/devicePosition/${row.deviceId}/0/15/1`); | |
| 198 | + }, | |
| 198 | 199 | |
| 199 | - //gb28181平台对接 | |
| 200 | - //刷新设备信息 | |
| 201 | - refDevice: function(itemData) { | |
| 202 | - console.log("刷新对应设备:" + itemData.deviceId); | |
| 203 | - let that = this; | |
| 204 | - this.$axios({ | |
| 205 | - method: 'post', | |
| 206 | - url: '/api/device/query/devices/' + itemData.deviceId + '/sync' | |
| 207 | - }).then((res) => { | |
| 208 | - console.log("刷新设备结果:"+JSON.stringify(res)); | |
| 209 | - if (res.data.code !==0) { | |
| 210 | - that.$message({ | |
| 211 | - showClose: true, | |
| 212 | - message: res.data.msg, | |
| 213 | - type: 'error' | |
| 214 | - }); | |
| 215 | - }else{ | |
| 216 | - // that.$message({ | |
| 217 | - // showClose: true, | |
| 218 | - // message: res.data.msg, | |
| 219 | - // type: 'success' | |
| 220 | - // }); | |
| 221 | - this.$refs.syncChannelProgress.openDialog(itemData.deviceId) | |
| 222 | - } | |
| 223 | - that.initData() | |
| 224 | - }).catch((e) => { | |
| 225 | - console.error(e) | |
| 200 | + //gb28181平台对接 | |
| 201 | + //刷新设备信息 | |
| 202 | + refDevice: function (itemData) { | |
| 203 | + console.log("刷新对应设备:" + itemData.deviceId); | |
| 204 | + let that = this; | |
| 205 | + this.$axios({ | |
| 206 | + method: 'post', | |
| 207 | + url: '/api/device/query/devices/' + itemData.deviceId + '/sync' | |
| 208 | + }).then((res) => { | |
| 209 | + console.log("刷新设备结果:" + JSON.stringify(res)); | |
| 210 | + if (res.data.code !== 0) { | |
| 226 | 211 | that.$message({ |
| 227 | 212 | showClose: true, |
| 228 | - message: e, | |
| 213 | + message: res.data.msg, | |
| 229 | 214 | type: 'error' |
| 230 | 215 | }); |
| 231 | - }); | |
| 216 | + } else { | |
| 217 | + // that.$message({ | |
| 218 | + // showClose: true, | |
| 219 | + // message: res.data.msg, | |
| 220 | + // type: 'success' | |
| 221 | + // }); | |
| 222 | + this.$refs.syncChannelProgress.openDialog(itemData.deviceId) | |
| 223 | + } | |
| 224 | + that.initData() | |
| 225 | + }).catch((e) => { | |
| 226 | + console.error(e) | |
| 227 | + that.$message({ | |
| 228 | + showClose: true, | |
| 229 | + message: e, | |
| 230 | + type: 'error' | |
| 231 | + }); | |
| 232 | + }); | |
| 232 | 233 | |
| 233 | - }, | |
| 234 | + }, | |
| 234 | 235 | |
| 235 | - getTooltipContent: async function (deviceId){ | |
| 236 | - let result = ""; | |
| 237 | - await this.$axios({ | |
| 238 | - method: 'get', | |
| 239 | - async: false, | |
| 240 | - url:`/api/device/query/${deviceId}/sync_status/`, | |
| 241 | - }).then((res) => { | |
| 242 | - if (res.data.code == 0) { | |
| 243 | - if (res.data.data.errorMsg !== null) { | |
| 244 | - result = res.data.data.errorMsg | |
| 245 | - } else if (res.data.msg !== null) { | |
| 246 | - result = res.data.msg | |
| 247 | - } else { | |
| 248 | - result = `同步中...[${res.data.data.current}/${res.data.data.total}]`; | |
| 249 | - } | |
| 250 | - } | |
| 251 | - }) | |
| 252 | - return result; | |
| 253 | - }, | |
| 254 | - //通知设备上传媒体流 | |
| 255 | - sendDevicePush: function(itemData) { | |
| 256 | - // let deviceId = this.currentDevice.deviceId; | |
| 257 | - // let channelId = itemData.channelId; | |
| 258 | - // console.log("通知设备推流1:" + deviceId + " : " + channelId); | |
| 259 | - // let that = this; | |
| 260 | - // this.$axios({ | |
| 261 | - // method: 'get', | |
| 262 | - // url: '/api/play/' + deviceId + '/' + channelId | |
| 263 | - // }).then(function(res) { | |
| 264 | - // let ssrc = res.data.ssrc; | |
| 265 | - // that.$refs.devicePlayer.play(ssrc,deviceId,channelId); | |
| 266 | - // }).catch(function(e) { | |
| 267 | - // }); | |
| 268 | - }, | |
| 269 | - transportChange: function (row) { | |
| 270 | - console.log(`修改传输方式为 ${row.streamMode}:${row.deviceId} `); | |
| 271 | - let that = this; | |
| 272 | - this.$axios({ | |
| 273 | - method: 'post', | |
| 274 | - url: '/api/device/query/transport/' + row.deviceId + '/' + row.streamMode | |
| 275 | - }).then(function(res) { | |
| 236 | + getTooltipContent: async function (deviceId) { | |
| 237 | + let result = ""; | |
| 238 | + await this.$axios({ | |
| 239 | + method: 'get', | |
| 240 | + async: false, | |
| 241 | + url: `/api/device/query/${deviceId}/sync_status/`, | |
| 242 | + }).then((res) => { | |
| 243 | + if (res.data.code == 0) { | |
| 244 | + if (res.data.data.errorMsg !== null) { | |
| 245 | + result = res.data.data.errorMsg | |
| 246 | + } else if (res.data.msg !== null) { | |
| 247 | + result = res.data.msg | |
| 248 | + } else { | |
| 249 | + result = `同步中...[${res.data.data.current}/${res.data.data.total}]`; | |
| 250 | + } | |
| 251 | + } | |
| 252 | + }) | |
| 253 | + return result; | |
| 254 | + }, | |
| 255 | + //通知设备上传媒体流 | |
| 256 | + sendDevicePush: function (itemData) { | |
| 257 | + // let deviceId = this.currentDevice.deviceId; | |
| 258 | + // let channelId = itemData.channelId; | |
| 259 | + // console.log("通知设备推流1:" + deviceId + " : " + channelId); | |
| 260 | + // let that = this; | |
| 261 | + // this.$axios({ | |
| 262 | + // method: 'get', | |
| 263 | + // url: '/api/play/' + deviceId + '/' + channelId | |
| 264 | + // }).then(function(res) { | |
| 265 | + // let ssrc = res.data.ssrc; | |
| 266 | + // that.$refs.devicePlayer.play(ssrc,deviceId,channelId); | |
| 267 | + // }).catch(function(e) { | |
| 268 | + // }); | |
| 269 | + }, | |
| 270 | + transportChange: function (row) { | |
| 271 | + console.log(`修改传输方式为 ${row.streamMode}:${row.deviceId} `); | |
| 272 | + let that = this; | |
| 273 | + this.$axios({ | |
| 274 | + method: 'post', | |
| 275 | + url: '/api/device/query/transport/' + row.deviceId + '/' + row.streamMode | |
| 276 | + }).then(function (res) { | |
| 276 | 277 | |
| 277 | - }).catch(function(e) { | |
| 278 | + }).catch(function (e) { | |
| 279 | + }); | |
| 280 | + }, | |
| 281 | + edit: function (row) { | |
| 282 | + this.$refs.deviceEdit.openDialog(row, () => { | |
| 283 | + this.$refs.deviceEdit.close(); | |
| 284 | + this.$message({ | |
| 285 | + showClose: true, | |
| 286 | + message: "设备修改成功,通道字符集将在下次更新生效", | |
| 287 | + type: "success", | |
| 278 | 288 | }); |
| 279 | - }, | |
| 280 | - edit: function (row) { | |
| 281 | - this.$refs.deviceEdit.openDialog(row, ()=>{ | |
| 282 | - this.$refs.deviceEdit.close(); | |
| 283 | - this.$message({ | |
| 284 | - showClose: true, | |
| 285 | - message: "设备修改成功,通道字符集将在下次更新生效", | |
| 286 | - type: "success", | |
| 287 | - }); | |
| 288 | - setTimeout(this.getDeviceList, 200) | |
| 289 | + setTimeout(this.getDeviceList, 200) | |
| 289 | 290 | |
| 290 | - }) | |
| 291 | - } | |
| 291 | + }) | |
| 292 | + } | |
| 292 | 293 | |
| 293 | - } | |
| 294 | - }; | |
| 294 | + } | |
| 295 | +}; | |
| 295 | 296 | </script> |
| 296 | 297 | |
| 297 | 298 | <style> |
| 298 | - .videoList { | |
| 299 | - display: flex; | |
| 300 | - flex-wrap: wrap; | |
| 301 | - align-content: flex-start; | |
| 302 | - } | |
| 299 | +.videoList { | |
| 300 | + display: flex; | |
| 301 | + flex-wrap: wrap; | |
| 302 | + align-content: flex-start; | |
| 303 | +} | |
| 303 | 304 | |
| 304 | - .video-item { | |
| 305 | - position: relative; | |
| 306 | - width: 15rem; | |
| 307 | - height: 10rem; | |
| 308 | - margin-right: 1rem; | |
| 309 | - background-color: #000000; | |
| 310 | - } | |
| 305 | +.video-item { | |
| 306 | + position: relative; | |
| 307 | + width: 15rem; | |
| 308 | + height: 10rem; | |
| 309 | + margin-right: 1rem; | |
| 310 | + background-color: #000000; | |
| 311 | +} | |
| 311 | 312 | |
| 312 | - .video-item-img { | |
| 313 | - position: absolute; | |
| 314 | - top: 0; | |
| 315 | - bottom: 0; | |
| 316 | - left: 0; | |
| 317 | - right: 0; | |
| 318 | - margin: auto; | |
| 319 | - width: 100%; | |
| 320 | - height: 100%; | |
| 321 | - } | |
| 313 | +.video-item-img { | |
| 314 | + position: absolute; | |
| 315 | + top: 0; | |
| 316 | + bottom: 0; | |
| 317 | + left: 0; | |
| 318 | + right: 0; | |
| 319 | + margin: auto; | |
| 320 | + width: 100%; | |
| 321 | + height: 100%; | |
| 322 | +} | |
| 322 | 323 | |
| 323 | - .video-item-img:after { | |
| 324 | - content: ""; | |
| 325 | - display: inline-block; | |
| 326 | - position: absolute; | |
| 327 | - z-index: 2; | |
| 328 | - top: 0; | |
| 329 | - bottom: 0; | |
| 330 | - left: 0; | |
| 331 | - right: 0; | |
| 332 | - margin: auto; | |
| 333 | - width: 3rem; | |
| 334 | - height: 3rem; | |
| 335 | - background-image: url("../assets/loading.png"); | |
| 336 | - background-size: cover; | |
| 337 | - background-color: #000000; | |
| 338 | - } | |
| 324 | +.video-item-img:after { | |
| 325 | + content: ""; | |
| 326 | + display: inline-block; | |
| 327 | + position: absolute; | |
| 328 | + z-index: 2; | |
| 329 | + top: 0; | |
| 330 | + bottom: 0; | |
| 331 | + left: 0; | |
| 332 | + right: 0; | |
| 333 | + margin: auto; | |
| 334 | + width: 3rem; | |
| 335 | + height: 3rem; | |
| 336 | + background-image: url("../assets/loading.png"); | |
| 337 | + background-size: cover; | |
| 338 | + background-color: #000000; | |
| 339 | +} | |
| 339 | 340 | |
| 340 | - .video-item-title { | |
| 341 | - position: absolute; | |
| 342 | - bottom: 0; | |
| 343 | - color: #000000; | |
| 344 | - background-color: #ffffff; | |
| 345 | - line-height: 1.5rem; | |
| 346 | - padding: 0.3rem; | |
| 347 | - width: 14.4rem; | |
| 348 | - } | |
| 341 | +.video-item-title { | |
| 342 | + position: absolute; | |
| 343 | + bottom: 0; | |
| 344 | + color: #000000; | |
| 345 | + background-color: #ffffff; | |
| 346 | + line-height: 1.5rem; | |
| 347 | + padding: 0.3rem; | |
| 348 | + width: 14.4rem; | |
| 349 | +} | |
| 349 | 350 | </style> | ... | ... |
web_src/src/components/MediaServerManger.vue
| 1 | 1 | <template> |
| 2 | - <div id="mediaServerManger"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main id="msMain"> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">节点列表</span> | |
| 10 | - </div> | |
| 11 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> | |
| 12 | - <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="add">添加节点</el-button> | |
| 13 | - </div> | |
| 2 | + <div id="mediaServerManger" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">节点列表</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="add">添加节点</el-button> | |
| 7 | + </div> | |
| 8 | + </div> | |
| 14 | 9 | |
| 15 | - <el-row :gutter="12"> | |
| 16 | - <el-col :span="num" v-for="item in mediaServerList" :key="item.id"> | |
| 17 | - <el-card shadow="hover" :body-style="{ padding: '0px'}" class="server-card"> | |
| 18 | - <div class="card-img-zlm"></div> | |
| 19 | - <div style="padding: 14px;text-align: left"> | |
| 20 | - <span style="font-size: 16px">{{item.id}}</span> | |
| 21 | - <el-button v-if="!item.defaultServer" icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">编辑</el-button> | |
| 22 | - <el-button v-if="item.defaultServer" icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">查看</el-button> | |
| 23 | - <el-button icon="el-icon-delete" style="margin-right: 10px;padding: 0;float: right;" type="text" @click="del(item)">移除</el-button> | |
| 24 | - <div style="margin-top: 13px; line-height: 12px; "> | |
| 25 | - <span style="font-size: 14px; color: #999; margin-top: 5px; ">{{item.ip}}</span> | |
| 26 | - <span style="font-size: 14px; color: #999; margin-top: 5px; float: right;">{{item.createTime}}</span> | |
| 27 | - </div> | |
| 28 | - </div> | |
| 29 | - <i v-if="item.status" class="iconfont icon-online server-card-status-online" title="在线"></i> | |
| 30 | - <i v-if="!item.status" class="iconfont icon-online server-card-status-offline" title="离线"></i> | |
| 31 | - <i v-if="item.defaultServer" class="server-card-default" >默认</i> | |
| 32 | - </el-card> | |
| 33 | - </el-col> | |
| 34 | - </el-row> | |
| 35 | - <mediaServerEdit ref="mediaServerEdit" ></mediaServerEdit> | |
| 36 | - </el-main> | |
| 37 | - </el-container> | |
| 10 | + <el-row :gutter="12"> | |
| 11 | + <el-col :span="num" v-for="item in mediaServerList" :key="item.id"> | |
| 12 | + <el-card shadow="hover" :body-style="{ padding: '0px'}" class="server-card"> | |
| 13 | + <div class="card-img-zlm"></div> | |
| 14 | + <div style="padding: 14px;text-align: left"> | |
| 15 | + <span style="font-size: 16px">{{item.id}}</span> | |
| 16 | + <el-button v-if="!item.defaultServer" icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">编辑</el-button> | |
| 17 | + <el-button v-if="item.defaultServer" icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">查看</el-button> | |
| 18 | + <el-button icon="el-icon-delete" style="margin-right: 10px;padding: 0;float: right;" type="text" @click="del(item)">移除</el-button> | |
| 19 | + <div style="margin-top: 13px; line-height: 12px; "> | |
| 20 | + <span style="font-size: 14px; color: #999; margin-top: 5px; ">{{item.ip}}</span> | |
| 21 | + <span style="font-size: 14px; color: #999; margin-top: 5px; float: right;">{{item.createTime}}</span> | |
| 22 | + </div> | |
| 23 | + </div> | |
| 24 | + <i v-if="item.status" class="iconfont icon-online server-card-status-online" title="在线"></i> | |
| 25 | + <i v-if="!item.status" class="iconfont icon-online server-card-status-offline" title="离线"></i> | |
| 26 | + <i v-if="item.defaultServer" class="server-card-default" >默认</i> | |
| 27 | + </el-card> | |
| 28 | + </el-col> | |
| 29 | + </el-row> | |
| 30 | + <mediaServerEdit ref="mediaServerEdit" ></mediaServerEdit> | |
| 38 | 31 | </div> |
| 39 | 32 | </template> |
| 40 | 33 | |
| 41 | 34 | <script> |
| 42 | - import uiHeader from './UiHeader.vue' | |
| 35 | + import uiHeader from '../layout/UiHeader.vue' | |
| 43 | 36 | import MediaServer from './service/MediaServer' |
| 44 | 37 | import mediaServerEdit from './dialog/MediaServerEdit' |
| 45 | 38 | export default { | ... | ... |
web_src/src/components/ParentPlatformList.vue
| 1 | 1 | <template> |
| 2 | - <div id="app"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">上级平台列表</span> | |
| 10 | - </div> | |
| 11 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> | |
| 12 | - <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addParentPlatform">添加</el-button> | |
| 13 | - </div> | |
| 14 | - <!--设备列表--> | |
| 15 | - <el-table :data="platformList" border style="width: 100%" :height="winHeight"> | |
| 16 | - <el-table-column prop="name" label="名称" align="center"></el-table-column> | |
| 17 | - <el-table-column prop="serverGBId" label="平台编号" width="180" align="center"></el-table-column> | |
| 18 | - <el-table-column label="是否启用" width="120" align="center"> | |
| 19 | - <template slot-scope="scope"> | |
| 20 | - <div slot="reference" class="name-wrapper"> | |
| 21 | - <el-tag size="medium" v-if="scope.row.enable">已启用</el-tag> | |
| 22 | - <el-tag size="medium" type="info" v-if="!scope.row.enable">未启用</el-tag> | |
| 23 | - </div> | |
| 24 | - </template> | |
| 25 | - </el-table-column> | |
| 26 | - <el-table-column label="状态" width="120" align="center"> | |
| 27 | - <template slot-scope="scope"> | |
| 28 | - <div slot="reference" class="name-wrapper"> | |
| 29 | - <el-tag size="medium" v-if="scope.row.status">在线</el-tag> | |
| 30 | - <el-tag size="medium" type="info" v-if="!scope.row.status">离线</el-tag> | |
| 31 | - </div> | |
| 32 | - </template> | |
| 33 | - </el-table-column> | |
| 34 | - <el-table-column label="地址" width="180" align="center"> | |
| 35 | - <template slot-scope="scope"> | |
| 36 | - <div slot="reference" class="name-wrapper"> | |
| 37 | - <el-tag size="medium">{{ scope.row.serverIP}}:{{scope.row.serverPort }}</el-tag> | |
| 38 | - </div> | |
| 39 | - </template> | |
| 40 | - </el-table-column> | |
| 41 | - <el-table-column prop="deviceGBId" label="设备国标编号" width="200" align="center"></el-table-column> | |
| 42 | - <el-table-column prop="transport" label="信令传输模式" width="120" align="center"></el-table-column> | |
| 43 | - <el-table-column prop="channelCount" label="通道数" width="120" align="center"></el-table-column> | |
| 44 | - <el-table-column label="订阅信息" width="240" align="center" fixed="right"> | |
| 45 | - <template slot-scope="scope"> | |
| 46 | - <i v-if="scope.row.alarmSubscribe" style="font-size: 20px" title="报警订阅" class="iconfont icon-gbaojings subscribe-on " ></i> | |
| 47 | - <i v-if="!scope.row.alarmSubscribe" style="font-size: 20px" title="报警订阅" class="iconfont icon-gbaojings subscribe-off " ></i> | |
| 48 | - <i v-if="scope.row.catalogSubscribe" title="目录订阅" class="iconfont icon-gjichus subscribe-on" ></i> | |
| 49 | - <i v-if="!scope.row.catalogSubscribe" title="目录订阅" class="iconfont icon-gjichus subscribe-off" ></i> | |
| 50 | - <i v-if="scope.row.mobilePositionSubscribe" title="位置订阅" class="iconfont icon-gxunjians subscribe-on" ></i> | |
| 51 | - <i v-if="!scope.row.mobilePositionSubscribe" title="位置订阅" class="iconfont icon-gxunjians subscribe-off" ></i> | |
| 52 | - </template> | |
| 53 | - </el-table-column> | |
| 2 | + <div id="app" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">上级平台列表</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addParentPlatform">添加</el-button> | |
| 7 | + </div> | |
| 8 | + </div> | |
| 54 | 9 | |
| 55 | - <el-table-column label="操作" width="300" align="center" fixed="right"> | |
| 56 | - <template slot-scope="scope"> | |
| 57 | - <el-button size="mini" icon="el-icon-edit" @click="editPlatform(scope.row)">编辑</el-button> | |
| 58 | - <el-button size="mini" icon="el-icon-share" type="primary" @click="chooseChannel(scope.row)">选择通道</el-button> | |
| 59 | - <el-button size="mini" icon="el-icon-delete" type="danger" @click="deletePlatform(scope.row)">删除</el-button> | |
| 60 | - </template> | |
| 61 | - </el-table-column> | |
| 62 | - </el-table> | |
| 63 | - <el-pagination | |
| 64 | - style="float: right" | |
| 65 | - @size-change="handleSizeChange" | |
| 66 | - @current-change="currentChange" | |
| 67 | - :current-page="currentPage" | |
| 68 | - :page-size="count" | |
| 69 | - :page-sizes="[15, 25, 35, 50]" | |
| 70 | - layout="total, sizes, prev, pager, next" | |
| 71 | - :total="total"> | |
| 72 | - </el-pagination> | |
| 73 | - <platformEdit ref="platformEdit" ></platformEdit> | |
| 74 | - <chooseChannelDialog ref="chooseChannelDialog" ></chooseChannelDialog> | |
| 75 | - </el-main> | |
| 76 | - </el-container> | |
| 10 | + <!--设备列表--> | |
| 11 | + <el-table :data="platformList" border style="width: 100%" :height="winHeight"> | |
| 12 | + <el-table-column prop="name" label="名称" align="center"></el-table-column> | |
| 13 | + <el-table-column prop="serverGBId" label="平台编号" align="center"></el-table-column> | |
| 14 | + <el-table-column label="是否启用" width="120" align="center"> | |
| 15 | + <template slot-scope="scope"> | |
| 16 | + <div slot="reference" class="name-wrapper"> | |
| 17 | + <el-tag size="medium" v-if="scope.row.enable">已启用</el-tag> | |
| 18 | + <el-tag size="medium" type="info" v-if="!scope.row.enable">未启用</el-tag> | |
| 19 | + </div> | |
| 20 | + </template> | |
| 21 | + </el-table-column> | |
| 22 | + <el-table-column label="状态" width="120" align="center"> | |
| 23 | + <template slot-scope="scope"> | |
| 24 | + <div slot="reference" class="name-wrapper"> | |
| 25 | + <el-tag size="medium" v-if="scope.row.status">在线</el-tag> | |
| 26 | + <el-tag size="medium" type="info" v-if="!scope.row.status">离线</el-tag> | |
| 27 | + </div> | |
| 28 | + </template> | |
| 29 | + </el-table-column> | |
| 30 | + <el-table-column label="地址" width="180" align="center"> | |
| 31 | + <template slot-scope="scope"> | |
| 32 | + <div slot="reference" class="name-wrapper"> | |
| 33 | + <el-tag size="medium">{{ scope.row.serverIP}}:{{scope.row.serverPort }}</el-tag> | |
| 34 | + </div> | |
| 35 | + </template> | |
| 36 | + </el-table-column> | |
| 37 | + <el-table-column prop="deviceGBId" label="设备国标编号" width="200" align="center"></el-table-column> | |
| 38 | + <el-table-column prop="transport" label="信令传输模式" width="120" align="center"></el-table-column> | |
| 39 | + <el-table-column prop="channelCount" label="通道数" width="120" align="center"></el-table-column> | |
| 40 | + <el-table-column label="订阅信息" width="240" align="center" fixed="right"> | |
| 41 | + <template slot-scope="scope"> | |
| 42 | + <i v-if="scope.row.alarmSubscribe" style="font-size: 20px" title="报警订阅" class="iconfont icon-gbaojings subscribe-on " ></i> | |
| 43 | + <i v-if="!scope.row.alarmSubscribe" style="font-size: 20px" title="报警订阅" class="iconfont icon-gbaojings subscribe-off " ></i> | |
| 44 | + <i v-if="scope.row.catalogSubscribe" title="目录订阅" class="iconfont icon-gjichus subscribe-on" ></i> | |
| 45 | + <i v-if="!scope.row.catalogSubscribe" title="目录订阅" class="iconfont icon-gjichus subscribe-off" ></i> | |
| 46 | + <i v-if="scope.row.mobilePositionSubscribe" title="位置订阅" class="iconfont icon-gxunjians subscribe-on" ></i> | |
| 47 | + <i v-if="!scope.row.mobilePositionSubscribe" title="位置订阅" class="iconfont icon-gxunjians subscribe-off" ></i> | |
| 48 | + </template> | |
| 49 | + </el-table-column> | |
| 50 | + | |
| 51 | + <el-table-column label="操作" width="300" align="center" fixed="right"> | |
| 52 | + <template slot-scope="scope"> | |
| 53 | + <el-button size="mini" icon="el-icon-edit" @click="editPlatform(scope.row)">编辑</el-button> | |
| 54 | + <el-button size="mini" icon="el-icon-share" type="primary" @click="chooseChannel(scope.row)">选择通道</el-button> | |
| 55 | + <el-button size="mini" icon="el-icon-delete" type="danger" @click="deletePlatform(scope.row)">删除</el-button> | |
| 56 | + </template> | |
| 57 | + </el-table-column> | |
| 58 | + </el-table> | |
| 59 | + <el-pagination | |
| 60 | + style="float: right" | |
| 61 | + @size-change="handleSizeChange" | |
| 62 | + @current-change="currentChange" | |
| 63 | + :current-page="currentPage" | |
| 64 | + :page-size="count" | |
| 65 | + :page-sizes="[15, 25, 35, 50]" | |
| 66 | + layout="total, sizes, prev, pager, next" | |
| 67 | + :total="total"> | |
| 68 | + </el-pagination> | |
| 69 | + <platformEdit ref="platformEdit" ></platformEdit> | |
| 70 | + <chooseChannelDialog ref="chooseChannelDialog" ></chooseChannelDialog> | |
| 77 | 71 | </div> |
| 78 | 72 | </template> |
| 79 | 73 | |
| 80 | 74 | <script> |
| 81 | 75 | import platformEdit from './dialog/platformEdit.vue' |
| 82 | -import uiHeader from './UiHeader.vue' | |
| 76 | +import uiHeader from '../layout/UiHeader.vue' | |
| 83 | 77 | import chooseChannelDialog from './dialog/chooseChannel.vue' |
| 84 | 78 | export default { |
| 85 | 79 | name: 'app', | ... | ... |
web_src/src/components/PushVideoList.vue
| 1 | 1 | <template> |
| 2 | - <div id="pushVideoList"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">推流列表</span> | |
| 10 | - </div> | |
| 11 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> | |
| 12 | - | |
| 13 | - 搜索: <el-input @input="getPushList" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input> | |
| 14 | - | |
| 15 | - 流媒体: <el-select size="mini" @change="getPushList" style="margin-right: 1rem;" v-model="mediaServerId" placeholder="请选择" default-first-option> | |
| 2 | + <div id="pushVideoList" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">推流列表</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + 搜索: | |
| 7 | + <el-input @input="getPushList" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" | |
| 8 | + prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input> | |
| 9 | + 流媒体: | |
| 10 | + <el-select size="mini" @change="getPushList" style="margin-right: 1rem;" v-model="mediaServerId" | |
| 11 | + placeholder="请选择" default-first-option> | |
| 16 | 12 | <el-option label="全部" value=""></el-option> |
| 17 | 13 | <el-option |
| 18 | 14 | v-for="item in mediaServerList" |
| ... | ... | @@ -21,309 +17,327 @@ |
| 21 | 17 | :value="item.id"> |
| 22 | 18 | </el-option> |
| 23 | 19 | </el-select> |
| 24 | - 推流状态: <el-select size="mini" style="margin-right: 1rem;" @change="getPushList" v-model="pushing" placeholder="请选择" default-first-option> | |
| 20 | + 推流状态: | |
| 21 | + <el-select size="mini" style="margin-right: 1rem;" @change="getPushList" v-model="pushing" placeholder="请选择" | |
| 22 | + default-first-option> | |
| 25 | 23 | <el-option label="全部" value=""></el-option> |
| 26 | 24 | <el-option label="推流进行中" value="true"></el-option> |
| 27 | 25 | <el-option label="推流未进行" value="false"></el-option> |
| 28 | 26 | </el-select> |
| 29 | - <el-button icon="el-icon-upload2" size="mini" style="margin-right: 1rem;" type="primary" @click="importChannel">通道导入</el-button> | |
| 30 | - <el-button icon="el-icon-download" size="mini" style="margin-right: 1rem;" type="primary" > | |
| 31 | - <a style="color: #FFFFFF; text-align: center; text-decoration: none" href="/static/file/推流通道导入.zip" download='推流通道导入.zip' >下载模板</a> | |
| 32 | - </el-button> | |
| 33 | - <el-button icon="el-icon-delete" size="mini" style="margin-right: 1rem;" :disabled="multipleSelection.length === 0" type="danger" @click="batchDel">批量移除</el-button> | |
| 34 | - </div> | |
| 35 | - <devicePlayer ref="devicePlayer"></devicePlayer> | |
| 36 | - <addStreamTOGB ref="addStreamTOGB"></addStreamTOGB> | |
| 37 | - <el-table ref="pushListTable" :data="pushList" border style="width: 100%" :height="winHeight" @selection-change="handleSelectionChange" :row-key="(row)=> row.app + row.stream"> | |
| 38 | - <el-table-column align="center" type="selection" :reserve-selection="true" width="55"> | |
| 39 | - </el-table-column> | |
| 40 | - <el-table-column prop="name" label="名称" align="center"> | |
| 41 | - </el-table-column> | |
| 42 | - <el-table-column prop="app" label="APP" align="center"> | |
| 43 | - </el-table-column> | |
| 44 | - <el-table-column prop="stream" label="流ID" align="center"> | |
| 45 | - </el-table-column> | |
| 46 | - <el-table-column prop="gbId" label="国标编码" width="200" align="center"> | |
| 47 | - </el-table-column> | |
| 48 | - <el-table-column prop="mediaServerId" label="流媒体" width="200" align="center"> | |
| 49 | - </el-table-column> | |
| 50 | - <el-table-column label="开始时间" align="center" width="200"> | |
| 51 | - <template slot-scope="scope"> | |
| 52 | - <el-button-group> | |
| 53 | - {{dateFormat(parseInt(scope.row.createStamp))}} | |
| 54 | - </el-button-group> | |
| 55 | - </template> | |
| 56 | - </el-table-column> | |
| 57 | - <el-table-column label="正在推流" align="center" width="100"> | |
| 58 | - <template slot-scope="scope"> | |
| 59 | - {{(scope.row.status == false && scope.row.gbId == null) || scope.row.status ?'是':'否'}} | |
| 60 | - </template> | |
| 61 | - </el-table-column> | |
| 27 | + <el-button icon="el-icon-upload2" size="mini" style="margin-right: 1rem;" type="primary" @click="importChannel"> | |
| 28 | + 通道导入 | |
| 29 | + </el-button> | |
| 30 | + <el-button icon="el-icon-download" size="mini" style="margin-right: 1rem;" type="primary"> | |
| 31 | + <a style="color: #FFFFFF; text-align: center; text-decoration: none" href="/static/file/推流通道导入.zip" | |
| 32 | + download='推流通道导入.zip'>下载模板</a> | |
| 33 | + </el-button> | |
| 34 | + <el-button icon="el-icon-delete" size="mini" style="margin-right: 1rem;" | |
| 35 | + :disabled="multipleSelection.length === 0" type="danger" @click="batchDel">批量移除 | |
| 36 | + </el-button> | |
| 37 | + </div> | |
| 38 | + </div> | |
| 39 | + <devicePlayer ref="devicePlayer"></devicePlayer> | |
| 40 | + <addStreamTOGB ref="addStreamTOGB"></addStreamTOGB> | |
| 41 | + <el-table ref="pushListTable" :data="pushList" border style="width: 100%" :height="winHeight" | |
| 42 | + @selection-change="handleSelectionChange" :row-key="(row)=> row.app + row.stream"> | |
| 43 | + <el-table-column align="center" type="selection" :reserve-selection="true" width="55"> | |
| 44 | + </el-table-column> | |
| 45 | + <el-table-column prop="name" label="名称" align="center"> | |
| 46 | + </el-table-column> | |
| 47 | + <el-table-column prop="app" label="APP" align="center"> | |
| 48 | + </el-table-column> | |
| 49 | + <el-table-column prop="stream" label="流ID" align="center"> | |
| 50 | + </el-table-column> | |
| 51 | + <el-table-column prop="gbId" label="国标编码" width="200" align="center"> | |
| 52 | + </el-table-column> | |
| 53 | + <el-table-column prop="mediaServerId" label="流媒体" width="200" align="center"> | |
| 54 | + </el-table-column> | |
| 55 | + <el-table-column label="开始时间" align="center" width="200"> | |
| 56 | + <template slot-scope="scope"> | |
| 57 | + <el-button-group> | |
| 58 | + {{ dateFormat(parseInt(scope.row.createStamp)) }} | |
| 59 | + </el-button-group> | |
| 60 | + </template> | |
| 61 | + </el-table-column> | |
| 62 | + <el-table-column label="正在推流" align="center" width="100"> | |
| 63 | + <template slot-scope="scope"> | |
| 64 | + {{ (scope.row.status == false && scope.row.gbId == null) || scope.row.status ? '是' : '否' }} | |
| 65 | + </template> | |
| 66 | + </el-table-column> | |
| 62 | 67 | |
| 63 | - <el-table-column label="操作" width="360" align="center" fixed="right"> | |
| 64 | - <template slot-scope="scope"> | |
| 65 | - <el-button-group> | |
| 66 | - <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> | |
| 67 | - <el-button size="mini" icon="el-icon-delete" type="danger" @click="stopPush(scope.row)">移除</el-button> | |
| 68 | - <el-button size="mini" icon="el-icon-position" type="primary" v-if="!!!scope.row.gbId" @click="addToGB(scope.row)">加入国标</el-button> | |
| 69 | - <el-button size="mini" icon="el-icon-position" type="primary" v-if="!!scope.row.gbId" @click="removeFromGB(scope.row)">移出国标</el-button> | |
| 70 | - </el-button-group> | |
| 71 | - </template> | |
| 72 | - </el-table-column> | |
| 73 | - </el-table> | |
| 74 | - <el-pagination | |
| 75 | - style="float: right" | |
| 76 | - @size-change="handleSizeChange" | |
| 77 | - @current-change="currentChange" | |
| 78 | - :current-page="currentPage" | |
| 79 | - :page-size="count" | |
| 80 | - :page-sizes="[15, 25, 35, 50]" | |
| 81 | - layout="total, sizes, prev, pager, next" | |
| 82 | - :total="total"> | |
| 83 | - </el-pagination> | |
| 84 | - <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit> | |
| 85 | - <importChannel ref="importChannel" ></importChannel> | |
| 86 | - </el-main> | |
| 87 | - </el-container> | |
| 88 | - </div> | |
| 68 | + <el-table-column label="操作" width="360" align="center" fixed="right"> | |
| 69 | + <template slot-scope="scope"> | |
| 70 | + <el-button-group> | |
| 71 | + <el-button size="mini" icon="el-icon-video-play" | |
| 72 | + v-if="(scope.row.status == false && scope.row.gbId == null) || scope.row.status" | |
| 73 | + @click="playPush(scope.row)">播放 | |
| 74 | + </el-button> | |
| 75 | + <el-button size="mini" icon="el-icon-delete" type="danger" @click="stopPush(scope.row)">移除</el-button> | |
| 76 | + <el-button size="mini" icon="el-icon-position" type="primary" v-if="!!!scope.row.gbId" | |
| 77 | + @click="addToGB(scope.row)">加入国标 | |
| 78 | + </el-button> | |
| 79 | + <el-button size="mini" icon="el-icon-position" type="primary" v-if="!!scope.row.gbId" | |
| 80 | + @click="removeFromGB(scope.row)">移出国标 | |
| 81 | + </el-button> | |
| 82 | + </el-button-group> | |
| 83 | + </template> | |
| 84 | + </el-table-column> | |
| 85 | + </el-table> | |
| 86 | + <el-pagination | |
| 87 | + style="float: right" | |
| 88 | + @size-change="handleSizeChange" | |
| 89 | + @current-change="currentChange" | |
| 90 | + :current-page="currentPage" | |
| 91 | + :page-size="count" | |
| 92 | + :page-sizes="[15, 25, 35, 50]" | |
| 93 | + layout="total, sizes, prev, pager, next" | |
| 94 | + :total="total"> | |
| 95 | + </el-pagination> | |
| 96 | + <streamProxyEdit ref="streamProxyEdit"></streamProxyEdit> | |
| 97 | + <importChannel ref="importChannel"></importChannel> | |
| 98 | + </div> | |
| 89 | 99 | </template> |
| 90 | 100 | |
| 91 | 101 | <script> |
| 92 | - import streamProxyEdit from './dialog/StreamProxyEdit.vue' | |
| 93 | - import devicePlayer from './dialog/devicePlayer.vue' | |
| 94 | - import addStreamTOGB from './dialog/addStreamTOGB.vue' | |
| 95 | - import uiHeader from './UiHeader.vue' | |
| 96 | - import importChannel from './dialog/importChannel.vue' | |
| 97 | - import MediaServer from './service/MediaServer' | |
| 98 | - export default { | |
| 99 | - name: 'pushVideoList', | |
| 100 | - components: { | |
| 101 | - devicePlayer, | |
| 102 | - addStreamTOGB, | |
| 103 | - streamProxyEdit, | |
| 104 | - uiHeader, | |
| 105 | - importChannel, | |
| 106 | - }, | |
| 107 | - data() { | |
| 108 | - return { | |
| 109 | - pushList: [], //设备列表 | |
| 110 | - currentPusher: {}, //当前操作设备对象 | |
| 111 | - updateLooper: 0, //数据刷新轮训标志 | |
| 112 | - currentDeviceChannelsLenth:0, | |
| 113 | - winHeight: window.innerHeight - 250, | |
| 114 | - mediaServerObj : new MediaServer(), | |
| 115 | - currentPage:1, | |
| 116 | - count:15, | |
| 117 | - total:0, | |
| 118 | - searchSrt: "", | |
| 119 | - pushing: "", | |
| 120 | - mediaServerId: "", | |
| 121 | - mediaServerList: [], | |
| 122 | - multipleSelection: [], | |
| 123 | - getDeviceListLoading: false | |
| 124 | - }; | |
| 125 | - }, | |
| 126 | - computed: { | |
| 127 | - }, | |
| 128 | - mounted() { | |
| 129 | - this.initData(); | |
| 130 | - this.updateLooper = setInterval(this.getPushList, 2000); | |
| 131 | - }, | |
| 132 | - destroyed() { | |
| 133 | - clearTimeout(this.updateLooper); | |
| 134 | - }, | |
| 135 | - methods: { | |
| 136 | - initData: function() { | |
| 137 | - this.mediaServerObj.getOnlineMediaServerList((data)=>{ | |
| 138 | - this.mediaServerList = data.data; | |
| 139 | - }) | |
| 140 | - this.getPushList(); | |
| 141 | - }, | |
| 142 | - currentChange: function(val){ | |
| 143 | - this.currentPage = val; | |
| 144 | - this.getPushList(); | |
| 145 | - }, | |
| 146 | - handleSizeChange: function(val){ | |
| 147 | - this.count = val; | |
| 148 | - this.getPushList(); | |
| 149 | - }, | |
| 150 | - getPushList: function() { | |
| 151 | - let that = this; | |
| 152 | - this.getDeviceListLoading = true; | |
| 153 | - this.$axios({ | |
| 154 | - method: 'get', | |
| 155 | - url:`/api/push/list`, | |
| 156 | - params: { | |
| 157 | - page: that.currentPage, | |
| 158 | - count: that.count, | |
| 159 | - query: that.searchSrt, | |
| 160 | - pushing: that.pushing, | |
| 161 | - mediaServerId: that.mediaServerId, | |
| 162 | - } | |
| 163 | - }).then(function (res) { | |
| 164 | - that.total = res.data.total; | |
| 165 | - that.pushList = res.data.list; | |
| 166 | - that.getDeviceListLoading = false; | |
| 167 | - }).catch(function (error) { | |
| 168 | - console.error(error); | |
| 169 | - that.getDeviceListLoading = false; | |
| 170 | - }); | |
| 171 | - }, | |
| 102 | +import streamProxyEdit from './dialog/StreamProxyEdit.vue' | |
| 103 | +import devicePlayer from './dialog/devicePlayer.vue' | |
| 104 | +import addStreamTOGB from './dialog/addStreamTOGB.vue' | |
| 105 | +import uiHeader from '../layout/UiHeader.vue' | |
| 106 | +import importChannel from './dialog/importChannel.vue' | |
| 107 | +import MediaServer from './service/MediaServer' | |
| 108 | + | |
| 109 | +export default { | |
| 110 | + name: 'pushVideoList', | |
| 111 | + components: { | |
| 112 | + devicePlayer, | |
| 113 | + addStreamTOGB, | |
| 114 | + streamProxyEdit, | |
| 115 | + uiHeader, | |
| 116 | + importChannel, | |
| 117 | + }, | |
| 118 | + data() { | |
| 119 | + return { | |
| 120 | + pushList: [], //设备列表 | |
| 121 | + currentPusher: {}, //当前操作设备对象 | |
| 122 | + updateLooper: 0, //数据刷新轮训标志 | |
| 123 | + currentDeviceChannelsLenth: 0, | |
| 124 | + winHeight: window.innerHeight - 250, | |
| 125 | + mediaServerObj: new MediaServer(), | |
| 126 | + currentPage: 1, | |
| 127 | + count: 15, | |
| 128 | + total: 0, | |
| 129 | + searchSrt: "", | |
| 130 | + pushing: "", | |
| 131 | + mediaServerId: "", | |
| 132 | + mediaServerList: [], | |
| 133 | + multipleSelection: [], | |
| 134 | + getDeviceListLoading: false | |
| 135 | + }; | |
| 136 | + }, | |
| 137 | + computed: {}, | |
| 138 | + mounted() { | |
| 139 | + this.initData(); | |
| 140 | + this.updateLooper = setInterval(this.getPushList, 2000); | |
| 141 | + }, | |
| 142 | + destroyed() { | |
| 143 | + clearTimeout(this.updateLooper); | |
| 144 | + }, | |
| 145 | + methods: { | |
| 146 | + initData: function () { | |
| 147 | + this.mediaServerObj.getOnlineMediaServerList((data) => { | |
| 148 | + this.mediaServerList = data.data; | |
| 149 | + }) | |
| 150 | + this.getPushList(); | |
| 151 | + }, | |
| 152 | + currentChange: function (val) { | |
| 153 | + this.currentPage = val; | |
| 154 | + this.getPushList(); | |
| 155 | + }, | |
| 156 | + handleSizeChange: function (val) { | |
| 157 | + this.count = val; | |
| 158 | + this.getPushList(); | |
| 159 | + }, | |
| 160 | + getPushList: function () { | |
| 161 | + let that = this; | |
| 162 | + this.getDeviceListLoading = true; | |
| 163 | + this.$axios({ | |
| 164 | + method: 'get', | |
| 165 | + url: `/api/push/list`, | |
| 166 | + params: { | |
| 167 | + page: that.currentPage, | |
| 168 | + count: that.count, | |
| 169 | + query: that.searchSrt, | |
| 170 | + pushing: that.pushing, | |
| 171 | + mediaServerId: that.mediaServerId, | |
| 172 | + } | |
| 173 | + }).then(function (res) { | |
| 174 | + that.total = res.data.total; | |
| 175 | + that.pushList = res.data.list; | |
| 176 | + that.getDeviceListLoading = false; | |
| 177 | + }).catch(function (error) { | |
| 178 | + console.error(error); | |
| 179 | + that.getDeviceListLoading = false; | |
| 180 | + }); | |
| 181 | + }, | |
| 172 | 182 | |
| 173 | - playPush: function(row){ | |
| 174 | - let that = this; | |
| 175 | - this.getListLoading = true; | |
| 176 | - this.$axios({ | |
| 177 | - method: 'get', | |
| 178 | - url: '/api/media/stream_info_by_app_and_stream', | |
| 179 | - params: { | |
| 180 | - app: row.app, | |
| 181 | - stream: row.stream, | |
| 182 | - mediaServerId: row.mediaServerId | |
| 183 | - } | |
| 184 | - }).then(function (res) { | |
| 185 | - that.getListLoading = false; | |
| 186 | - that.$refs.devicePlayer.openDialog("streamPlay", null, null, { | |
| 187 | - streamInfo: res.data.data, | |
| 188 | - hasAudio: true | |
| 189 | - }); | |
| 190 | - }).catch(function (error) { | |
| 191 | - console.error(error); | |
| 192 | - that.getListLoading = false; | |
| 193 | - }); | |
| 194 | - }, | |
| 195 | - stopPush: function(row){ | |
| 183 | + playPush: function (row) { | |
| 184 | + let that = this; | |
| 185 | + this.getListLoading = true; | |
| 186 | + this.$axios({ | |
| 187 | + method: 'get', | |
| 188 | + url: '/api/media/stream_info_by_app_and_stream', | |
| 189 | + params: { | |
| 190 | + app: row.app, | |
| 191 | + stream: row.stream, | |
| 192 | + mediaServerId: row.mediaServerId | |
| 193 | + } | |
| 194 | + }).then(function (res) { | |
| 195 | + that.getListLoading = false; | |
| 196 | + that.$refs.devicePlayer.openDialog("streamPlay", null, null, { | |
| 197 | + streamInfo: res.data.data, | |
| 198 | + hasAudio: true | |
| 199 | + }); | |
| 200 | + }).catch(function (error) { | |
| 201 | + console.error(error); | |
| 202 | + that.getListLoading = false; | |
| 203 | + }); | |
| 204 | + }, | |
| 205 | + stopPush: function (row) { | |
| 206 | + let that = this; | |
| 207 | + that.$axios({ | |
| 208 | + method: "post", | |
| 209 | + url: "/api/push/stop", | |
| 210 | + params: { | |
| 211 | + app: row.app, | |
| 212 | + streamId: row.stream | |
| 213 | + } | |
| 214 | + }).then((res) => { | |
| 215 | + if (res.data == "success") { | |
| 216 | + that.initData() | |
| 217 | + } | |
| 218 | + }).catch(function (error) { | |
| 219 | + console.error(error); | |
| 220 | + }); | |
| 221 | + }, | |
| 222 | + addToGB: function (row) { | |
| 223 | + this.$refs.addStreamTOGB.openDialog({ | |
| 224 | + app: row.app, | |
| 225 | + stream: row.stream, | |
| 226 | + mediaServerId: row.mediaServerId | |
| 227 | + }, this.initData); | |
| 228 | + }, | |
| 229 | + removeFromGB: function (row) { | |
| 230 | + let that = this; | |
| 231 | + that.$axios({ | |
| 232 | + method: "delete", | |
| 233 | + url: "/api/push/remove_form_gb", | |
| 234 | + data: row | |
| 235 | + }).then((res) => { | |
| 236 | + if (res.data == "success") { | |
| 237 | + that.initData() | |
| 238 | + } | |
| 239 | + }).catch(function (error) { | |
| 240 | + console.error(error); | |
| 241 | + }); | |
| 242 | + }, | |
| 243 | + dateFormat: function (/** timestamp=0 **/) { | |
| 244 | + let ts = arguments[0] || 0; | |
| 245 | + let t, y, m, d, h, i, s; | |
| 246 | + t = ts ? new Date(ts) : new Date(); | |
| 247 | + y = t.getFullYear(); | |
| 248 | + m = t.getMonth() + 1; | |
| 249 | + d = t.getDate(); | |
| 250 | + h = t.getHours(); | |
| 251 | + i = t.getMinutes(); | |
| 252 | + s = t.getSeconds(); | |
| 253 | + // 可根据需要在这里定义时间格式 | |
| 254 | + 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); | |
| 255 | + }, | |
| 256 | + importChannel: function () { | |
| 257 | + this.$refs.importChannel.openDialog(() => { | |
| 258 | + | |
| 259 | + }) | |
| 260 | + }, | |
| 261 | + batchDel: function () { | |
| 262 | + this.$confirm(`确定删除选中的${this.multipleSelection.length}个通道?`, '提示', { | |
| 263 | + confirmButtonText: '确定', | |
| 264 | + cancelButtonText: '取消', | |
| 265 | + type: 'warning' | |
| 266 | + }).then(() => { | |
| 196 | 267 | let that = this; |
| 197 | 268 | that.$axios({ |
| 198 | - method:"post", | |
| 199 | - url:"/api/push/stop", | |
| 200 | - params: { | |
| 201 | - app: row.app, | |
| 202 | - streamId: row.stream | |
| 203 | - } | |
| 204 | - }).then((res)=>{ | |
| 205 | - if (res.data == "success") { | |
| 206 | - that.initData() | |
| 269 | + method: "delete", | |
| 270 | + url: "/api/push/batchStop", | |
| 271 | + data: { | |
| 272 | + gbStreams: this.multipleSelection | |
| 207 | 273 | } |
| 274 | + }).then((res) => { | |
| 275 | + this.initData(); | |
| 276 | + this.$refs.pushListTable.clearSelection(); | |
| 208 | 277 | }).catch(function (error) { |
| 209 | 278 | console.error(error); |
| 210 | 279 | }); |
| 211 | - }, | |
| 212 | - addToGB: function(row){ | |
| 213 | - this.$refs.addStreamTOGB.openDialog({app: row.app, stream: row.stream, mediaServerId: row.mediaServerId}, this.initData); | |
| 214 | - }, | |
| 215 | - removeFromGB: function(row){ | |
| 216 | - let that = this; | |
| 217 | - that.$axios({ | |
| 218 | - method:"delete", | |
| 219 | - url:"/api/push/remove_form_gb", | |
| 220 | - data:row | |
| 221 | - }).then((res)=>{ | |
| 222 | - if (res.data == "success") { | |
| 223 | - that.initData() | |
| 224 | - } | |
| 225 | - }).catch(function (error) { | |
| 226 | - console.error(error); | |
| 227 | - }); | |
| 228 | - }, | |
| 229 | - dateFormat: function(/** timestamp=0 **/) { | |
| 230 | - let ts = arguments[0] || 0; | |
| 231 | - let t,y,m,d,h,i,s; | |
| 232 | - t = ts ? new Date(ts) : new Date(); | |
| 233 | - y = t.getFullYear(); | |
| 234 | - m = t.getMonth()+1; | |
| 235 | - d = t.getDate(); | |
| 236 | - h = t.getHours(); | |
| 237 | - i = t.getMinutes(); | |
| 238 | - s = t.getSeconds(); | |
| 239 | - // 可根据需要在这里定义时间格式 | |
| 240 | - 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); | |
| 241 | - }, | |
| 242 | - importChannel: function () { | |
| 243 | - this.$refs.importChannel.openDialog(()=>{ | |
| 280 | + }).catch(() => { | |
| 244 | 281 | |
| 245 | - }) | |
| 246 | - }, | |
| 247 | - batchDel: function () { | |
| 248 | - this.$confirm(`确定删除选中的${this.multipleSelection.length}个通道?`, '提示', { | |
| 249 | - confirmButtonText: '确定', | |
| 250 | - cancelButtonText: '取消', | |
| 251 | - type: 'warning' | |
| 252 | - }).then(() => { | |
| 253 | - let that = this; | |
| 254 | - that.$axios({ | |
| 255 | - method:"delete", | |
| 256 | - url:"/api/push/batchStop", | |
| 257 | - data: { | |
| 258 | - gbStreams: this.multipleSelection | |
| 259 | - } | |
| 260 | - }).then((res)=>{ | |
| 261 | - this.initData(); | |
| 262 | - this.$refs.pushListTable.clearSelection(); | |
| 263 | - }).catch(function (error) { | |
| 264 | - console.error(error); | |
| 265 | - }); | |
| 266 | - }).catch(() => { | |
| 267 | - | |
| 268 | - }); | |
| 269 | - }, | |
| 270 | - handleSelectionChange: function (val) { | |
| 271 | - this.multipleSelection = val; | |
| 272 | - }, | |
| 273 | - } | |
| 274 | - }; | |
| 282 | + }); | |
| 283 | + }, | |
| 284 | + handleSelectionChange: function (val) { | |
| 285 | + this.multipleSelection = val; | |
| 286 | + }, | |
| 287 | + } | |
| 288 | +}; | |
| 275 | 289 | </script> |
| 276 | 290 | |
| 277 | 291 | <style> |
| 278 | - .videoList { | |
| 279 | - display: flex; | |
| 280 | - flex-wrap: wrap; | |
| 281 | - align-content: flex-start; | |
| 282 | - } | |
| 292 | +.videoList { | |
| 293 | + display: flex; | |
| 294 | + flex-wrap: wrap; | |
| 295 | + align-content: flex-start; | |
| 296 | +} | |
| 283 | 297 | |
| 284 | - .video-item { | |
| 285 | - position: relative; | |
| 286 | - width: 15rem; | |
| 287 | - height: 10rem; | |
| 288 | - margin-right: 1rem; | |
| 289 | - background-color: #000000; | |
| 290 | - } | |
| 298 | +.video-item { | |
| 299 | + position: relative; | |
| 300 | + width: 15rem; | |
| 301 | + height: 10rem; | |
| 302 | + margin-right: 1rem; | |
| 303 | + background-color: #000000; | |
| 304 | +} | |
| 291 | 305 | |
| 292 | - .video-item-img { | |
| 293 | - position: absolute; | |
| 294 | - top: 0; | |
| 295 | - bottom: 0; | |
| 296 | - left: 0; | |
| 297 | - right: 0; | |
| 298 | - margin: auto; | |
| 299 | - width: 100%; | |
| 300 | - height: 100%; | |
| 301 | - } | |
| 306 | +.video-item-img { | |
| 307 | + position: absolute; | |
| 308 | + top: 0; | |
| 309 | + bottom: 0; | |
| 310 | + left: 0; | |
| 311 | + right: 0; | |
| 312 | + margin: auto; | |
| 313 | + width: 100%; | |
| 314 | + height: 100%; | |
| 315 | +} | |
| 302 | 316 | |
| 303 | - .video-item-img:after { | |
| 304 | - content: ""; | |
| 305 | - display: inline-block; | |
| 306 | - position: absolute; | |
| 307 | - z-index: 2; | |
| 308 | - top: 0; | |
| 309 | - bottom: 0; | |
| 310 | - left: 0; | |
| 311 | - right: 0; | |
| 312 | - margin: auto; | |
| 313 | - width: 3rem; | |
| 314 | - height: 3rem; | |
| 315 | - background-image: url("../assets/loading.png"); | |
| 316 | - background-size: cover; | |
| 317 | - background-color: #000000; | |
| 318 | - } | |
| 317 | +.video-item-img:after { | |
| 318 | + content: ""; | |
| 319 | + display: inline-block; | |
| 320 | + position: absolute; | |
| 321 | + z-index: 2; | |
| 322 | + top: 0; | |
| 323 | + bottom: 0; | |
| 324 | + left: 0; | |
| 325 | + right: 0; | |
| 326 | + margin: auto; | |
| 327 | + width: 3rem; | |
| 328 | + height: 3rem; | |
| 329 | + background-image: url("../assets/loading.png"); | |
| 330 | + background-size: cover; | |
| 331 | + background-color: #000000; | |
| 332 | +} | |
| 319 | 333 | |
| 320 | - .video-item-title { | |
| 321 | - position: absolute; | |
| 322 | - bottom: 0; | |
| 323 | - color: #000000; | |
| 324 | - background-color: #ffffff; | |
| 325 | - line-height: 1.5rem; | |
| 326 | - padding: 0.3rem; | |
| 327 | - width: 14.4rem; | |
| 328 | - } | |
| 334 | +.video-item-title { | |
| 335 | + position: absolute; | |
| 336 | + bottom: 0; | |
| 337 | + color: #000000; | |
| 338 | + background-color: #ffffff; | |
| 339 | + line-height: 1.5rem; | |
| 340 | + padding: 0.3rem; | |
| 341 | + width: 14.4rem; | |
| 342 | +} | |
| 329 | 343 | </style> | ... | ... |
web_src/src/components/StreamProxyList.vue
| 1 | 1 | <template> |
| 2 | - <div id="streamProxyList"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">拉流代理列表</span> | |
| 10 | - </div> | |
| 11 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> | |
| 12 | - <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStreamProxy">添加代理</el-button> | |
| 13 | - <el-button v-if="false" icon="el-icon-search" size="mini" style="margin-right: 1rem;" type="primary" @click="addOnvif">搜索ONVIF</el-button> | |
| 14 | - </div> | |
| 15 | - <devicePlayer ref="devicePlayer"></devicePlayer> | |
| 16 | - <el-table :data="streamProxyList" border style="width: 100%" :height="winHeight"> | |
| 17 | - <el-table-column prop="name" label="名称" align="center" show-overflow-tooltip/> | |
| 18 | - <el-table-column prop="app" label="流应用名" align="center" show-overflow-tooltip/> | |
| 19 | - <el-table-column prop="stream" label="流ID" align="center" show-overflow-tooltip/> | |
| 20 | - <el-table-column label="流地址" width="400" align="center" show-overflow-tooltip > | |
| 21 | - <template slot-scope="scope"> | |
| 22 | - <div slot="reference" class="name-wrapper"> | |
| 2 | + <div id="streamProxyList" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">拉流代理列表</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStreamProxy">添加代理</el-button> | |
| 7 | + <el-button v-if="false" icon="el-icon-search" size="mini" style="margin-right: 1rem;" type="primary" @click="addOnvif">搜索ONVIF</el-button> | |
| 8 | + </div> | |
| 9 | + </div> | |
| 10 | + <devicePlayer ref="devicePlayer"></devicePlayer> | |
| 11 | + <el-table :data="streamProxyList" border style="width: 100%" :height="winHeight"> | |
| 12 | + <el-table-column prop="name" label="名称" align="center" show-overflow-tooltip/> | |
| 13 | + <el-table-column prop="app" label="流应用名" align="center" show-overflow-tooltip/> | |
| 14 | + <el-table-column prop="stream" label="流ID" align="center" show-overflow-tooltip/> | |
| 15 | + <el-table-column label="流地址" width="400" align="center" show-overflow-tooltip > | |
| 16 | + <template slot-scope="scope"> | |
| 17 | + <div slot="reference" class="name-wrapper"> | |
| 23 | 18 | |
| 24 | - <el-tag size="medium" v-if="scope.row.type == 'default'"> | |
| 25 | - <i class="cpoy-btn el-icon-document-copy" title="点击拷贝" v-clipboard="scope.row.url" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i> | |
| 26 | - {{scope.row.url}} | |
| 27 | - </el-tag> | |
| 28 | - <el-tag size="medium" v-if="scope.row.type != 'default'"> | |
| 29 | - <i class="cpoy-btn el-icon-document-copy" title="点击拷贝" v-clipboard="scope.row.src_url" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i> | |
| 30 | - {{scope.row.src_url}} | |
| 31 | - </el-tag> | |
| 32 | - </div> | |
| 33 | - </template> | |
| 34 | - </el-table-column> | |
| 35 | - <el-table-column prop="mediaServerId" label="流媒体" width="150" align="center"></el-table-column> | |
| 36 | - <el-table-column label="类型" width="100" align="center"> | |
| 37 | - <template slot-scope="scope"> | |
| 38 | - <div slot="reference" class="name-wrapper"> | |
| 39 | - <el-tag size="medium">{{scope.row.type}}</el-tag> | |
| 40 | - </div> | |
| 41 | - </template> | |
| 42 | - </el-table-column> | |
| 19 | + <el-tag size="medium" v-if="scope.row.type == 'default'"> | |
| 20 | + <i class="cpoy-btn el-icon-document-copy" title="点击拷贝" v-clipboard="scope.row.url" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i> | |
| 21 | + {{scope.row.url}} | |
| 22 | + </el-tag> | |
| 23 | + <el-tag size="medium" v-if="scope.row.type != 'default'"> | |
| 24 | + <i class="cpoy-btn el-icon-document-copy" title="点击拷贝" v-clipboard="scope.row.src_url" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i> | |
| 25 | + {{scope.row.src_url}} | |
| 26 | + </el-tag> | |
| 27 | + </div> | |
| 28 | + </template> | |
| 29 | + </el-table-column> | |
| 30 | + <el-table-column prop="mediaServerId" label="流媒体" width="150" align="center"></el-table-column> | |
| 31 | + <el-table-column label="类型" width="100" align="center"> | |
| 32 | + <template slot-scope="scope"> | |
| 33 | + <div slot="reference" class="name-wrapper"> | |
| 34 | + <el-tag size="medium">{{scope.row.type}}</el-tag> | |
| 35 | + </div> | |
| 36 | + </template> | |
| 37 | + </el-table-column> | |
| 43 | 38 | |
| 44 | - <el-table-column prop="gbId" label="国标编码" width="180" align="center" show-overflow-tooltip/> | |
| 45 | - <el-table-column label="状态" width="120" align="center"> | |
| 46 | - <template slot-scope="scope"> | |
| 47 | - <div slot="reference" class="name-wrapper"> | |
| 48 | - <el-tag size="medium" v-if="scope.row.status">在线</el-tag> | |
| 49 | - <el-tag size="medium" type="info" v-if="!scope.row.status">离线</el-tag> | |
| 50 | - </div> | |
| 51 | - </template> | |
| 52 | - </el-table-column> | |
| 53 | - <el-table-column label="启用" width="120" align="center"> | |
| 54 | - <template slot-scope="scope"> | |
| 55 | - <div slot="reference" class="name-wrapper"> | |
| 56 | - <el-tag size="medium" v-if="scope.row.enable">已启用</el-tag> | |
| 57 | - <el-tag size="medium" type="info" v-if="!scope.row.enable">未启用</el-tag> | |
| 58 | - </div> | |
| 59 | - </template> | |
| 60 | - </el-table-column> | |
| 61 | - <el-table-column prop="createTime" label="创建时间" align="center" width="150" show-overflow-tooltip/> | |
| 62 | - <el-table-column label="转HLS" width="120" align="center"> | |
| 63 | - <template slot-scope="scope"> | |
| 64 | - <div slot="reference" class="name-wrapper"> | |
| 65 | - <el-tag size="medium" v-if="scope.row.enable_hls">已启用</el-tag> | |
| 66 | - <el-tag size="medium" type="info" v-if="!scope.row.enable_hls">未启用</el-tag> | |
| 67 | - </div> | |
| 68 | - </template> | |
| 69 | - </el-table-column> | |
| 70 | - <el-table-column label="MP4录制" width="120" align="center"> | |
| 71 | - <template slot-scope="scope"> | |
| 72 | - <div slot="reference" class="name-wrapper"> | |
| 73 | - <el-tag size="medium" v-if="scope.row.enable_mp4">已启用</el-tag> | |
| 74 | - <el-tag size="medium" type="info" v-if="!scope.row.enable_mp4">未启用</el-tag> | |
| 75 | - </div> | |
| 76 | - </template> | |
| 77 | - </el-table-column> | |
| 78 | - <el-table-column label="无人观看自动删除" width="160" align="center"> | |
| 79 | - <template slot-scope="scope"> | |
| 80 | - <div slot="reference" class="name-wrapper"> | |
| 81 | - <el-tag size="medium" v-if="scope.row.enable_remove_none_reader">已启用</el-tag> | |
| 82 | - <el-tag size="medium" type="info" v-if="!scope.row.enable_remove_none_reader">未启用</el-tag> | |
| 83 | - </div> | |
| 84 | - </template> | |
| 85 | - </el-table-column> | |
| 39 | + <el-table-column prop="gbId" label="国标编码" width="180" align="center" show-overflow-tooltip/> | |
| 40 | + <el-table-column label="状态" width="120" align="center"> | |
| 41 | + <template slot-scope="scope"> | |
| 42 | + <div slot="reference" class="name-wrapper"> | |
| 43 | + <el-tag size="medium" v-if="scope.row.status">在线</el-tag> | |
| 44 | + <el-tag size="medium" type="info" v-if="!scope.row.status">离线</el-tag> | |
| 45 | + </div> | |
| 46 | + </template> | |
| 47 | + </el-table-column> | |
| 48 | + <el-table-column label="启用" width="120" align="center"> | |
| 49 | + <template slot-scope="scope"> | |
| 50 | + <div slot="reference" class="name-wrapper"> | |
| 51 | + <el-tag size="medium" v-if="scope.row.enable">已启用</el-tag> | |
| 52 | + <el-tag size="medium" type="info" v-if="!scope.row.enable">未启用</el-tag> | |
| 53 | + </div> | |
| 54 | + </template> | |
| 55 | + </el-table-column> | |
| 56 | + <el-table-column prop="createTime" label="创建时间" align="center" width="150" show-overflow-tooltip/> | |
| 57 | + <el-table-column label="转HLS" width="120" align="center"> | |
| 58 | + <template slot-scope="scope"> | |
| 59 | + <div slot="reference" class="name-wrapper"> | |
| 60 | + <el-tag size="medium" v-if="scope.row.enable_hls">已启用</el-tag> | |
| 61 | + <el-tag size="medium" type="info" v-if="!scope.row.enable_hls">未启用</el-tag> | |
| 62 | + </div> | |
| 63 | + </template> | |
| 64 | + </el-table-column> | |
| 65 | + <el-table-column label="MP4录制" width="120" align="center"> | |
| 66 | + <template slot-scope="scope"> | |
| 67 | + <div slot="reference" class="name-wrapper"> | |
| 68 | + <el-tag size="medium" v-if="scope.row.enable_mp4">已启用</el-tag> | |
| 69 | + <el-tag size="medium" type="info" v-if="!scope.row.enable_mp4">未启用</el-tag> | |
| 70 | + </div> | |
| 71 | + </template> | |
| 72 | + </el-table-column> | |
| 73 | + <el-table-column label="无人观看自动删除" width="160" align="center"> | |
| 74 | + <template slot-scope="scope"> | |
| 75 | + <div slot="reference" class="name-wrapper"> | |
| 76 | + <el-tag size="medium" v-if="scope.row.enable_remove_none_reader">已启用</el-tag> | |
| 77 | + <el-tag size="medium" type="info" v-if="!scope.row.enable_remove_none_reader">未启用</el-tag> | |
| 78 | + </div> | |
| 79 | + </template> | |
| 80 | + </el-table-column> | |
| 86 | 81 | |
| 87 | 82 | |
| 88 | - <el-table-column label="操作" width="360" align="center" fixed="right"> | |
| 89 | - <template slot-scope="scope"> | |
| 90 | - <el-button-group> | |
| 91 | - <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.enable" @click="play(scope.row)">播放</el-button> | |
| 92 | - <el-button size="mini" icon="el-icon-close" type="success" v-if="scope.row.enable" @click="stop(scope.row)">停用</el-button> | |
| 93 | - <el-button size="mini" icon="el-icon-check" type="primary" :loading="startBtnLaoding" v-if="!scope.row.enable" @click="start(scope.row)">启用</el-button> | |
| 94 | - <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteStreamProxy(scope.row)">删除</el-button> | |
| 95 | - </el-button-group> | |
| 96 | - </template> | |
| 97 | - </el-table-column> | |
| 98 | - </el-table> | |
| 99 | - <el-pagination | |
| 100 | - style="float: right" | |
| 101 | - @size-change="handleSizeChange" | |
| 102 | - @current-change="currentChange" | |
| 103 | - :current-page="currentPage" | |
| 104 | - :page-size="count" | |
| 105 | - :page-sizes="[15, 25, 35, 50]" | |
| 106 | - layout="total, sizes, prev, pager, next" | |
| 107 | - :total="total"> | |
| 108 | - </el-pagination> | |
| 109 | - <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit> | |
| 110 | - <onvifEdit ref="onvifEdit" ></onvifEdit> | |
| 111 | - </el-main> | |
| 112 | - </el-container> | |
| 83 | + <el-table-column label="操作" width="360" align="center" fixed="right"> | |
| 84 | + <template slot-scope="scope"> | |
| 85 | + <el-button-group> | |
| 86 | + <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.enable" @click="play(scope.row)">播放</el-button> | |
| 87 | + <el-button size="mini" icon="el-icon-close" type="success" v-if="scope.row.enable" @click="stop(scope.row)">停用</el-button> | |
| 88 | + <el-button size="mini" icon="el-icon-check" type="primary" :loading="startBtnLaoding" v-if="!scope.row.enable" @click="start(scope.row)">启用</el-button> | |
| 89 | + <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteStreamProxy(scope.row)">删除</el-button> | |
| 90 | + </el-button-group> | |
| 91 | + </template> | |
| 92 | + </el-table-column> | |
| 93 | + </el-table> | |
| 94 | + <el-pagination | |
| 95 | + style="float: right" | |
| 96 | + @size-change="handleSizeChange" | |
| 97 | + @current-change="currentChange" | |
| 98 | + :current-page="currentPage" | |
| 99 | + :page-size="count" | |
| 100 | + :page-sizes="[15, 25, 35, 50]" | |
| 101 | + layout="total, sizes, prev, pager, next" | |
| 102 | + :total="total"> | |
| 103 | + </el-pagination> | |
| 104 | + <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit> | |
| 105 | + <onvifEdit ref="onvifEdit" ></onvifEdit> | |
| 113 | 106 | </div> |
| 114 | 107 | </template> |
| 115 | 108 | |
| ... | ... | @@ -117,7 +110,7 @@ |
| 117 | 110 | import streamProxyEdit from './dialog/StreamProxyEdit.vue' |
| 118 | 111 | import onvifEdit from './dialog/onvifEdit.vue' |
| 119 | 112 | import devicePlayer from './dialog/devicePlayer.vue' |
| 120 | - import uiHeader from './UiHeader.vue' | |
| 113 | + import uiHeader from '../layout/UiHeader.vue' | |
| 121 | 114 | export default { |
| 122 | 115 | name: 'streamProxyList', |
| 123 | 116 | components: { | ... | ... |
web_src/src/components/channelList.vue
| 1 | 1 | <template> |
| 2 | -<div id="channelList"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: 500; ">通道列表({{parentChannelId ==0 ? deviceId:parentChannelId}})</span> | |
| 2 | + <div id="channelList"> | |
| 3 | + <div style="background-color: #FFFFFF; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> | |
| 4 | + <span | |
| 5 | + style="font-size: 1rem; font-weight: 500; ">通道列表({{ parentChannelId == 0 ? deviceId : parentChannelId }})</span> | |
| 10 | 6 | |
| 11 | - </div> | |
| 12 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> | |
| 13 | - <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem;" type="primary" @click="showDevice">返回</el-button> | |
| 14 | - 搜索: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input> | |
| 7 | + </div> | |
| 8 | + <div | |
| 9 | + style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> | |
| 10 | + <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem;" type="primary" @click="showDevice"> | |
| 11 | + 返回 | |
| 12 | + </el-button> | |
| 13 | + 搜索: | |
| 14 | + <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" | |
| 15 | + prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input> | |
| 15 | 16 | |
| 16 | - 通道类型: <el-select size="mini" @change="search" style="margin-right: 1rem;" v-model="channelType" placeholder="请选择" default-first-option> | |
| 17 | - <el-option label="全部" value=""></el-option> | |
| 18 | - <el-option label="设备" value="false"></el-option> | |
| 19 | - <el-option label="子目录" value="true"></el-option> | |
| 20 | - </el-select> | |
| 21 | - 在线状态: <el-select size="mini" style="margin-right: 1rem;" @change="search" v-model="online" placeholder="请选择" default-first-option> | |
| 22 | - <el-option label="全部" value=""></el-option> | |
| 23 | - <el-option label="在线" value="true"></el-option> | |
| 24 | - <el-option label="离线" value="false"></el-option> | |
| 25 | - </el-select> | |
| 26 | - <el-checkbox size="mini" style="margin-right: 1rem; float: right;" v-model="autoList" @change="autoListChange">自动刷新</el-checkbox> | |
| 27 | - </div> | |
| 28 | - <devicePlayer ref="devicePlayer" v-loading="isLoging"></devicePlayer> | |
| 29 | - <!--设备列表--> | |
| 30 | - <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%"> | |
| 31 | - <el-table-column prop="channelId" label="通道编号" width="200"> | |
| 32 | - </el-table-column> | |
| 33 | - <el-table-column prop="name" label="通道名称"> | |
| 34 | - </el-table-column> | |
| 35 | - <el-table-column label="快照" width="80" align="center"> | |
| 36 | - <template slot-scope="scope"> | |
| 37 | - <img style="max-height: 3rem;max-width: 4rem;" | |
| 38 | - :id="scope.row.deviceId + '_' + scope.row.channelId" | |
| 39 | - :src="getSnap(scope.row)" | |
| 40 | - @error="getSnapErrorEvent($event.target.id)" | |
| 41 | - alt=""> | |
| 42 | -<!-- <el-image--> | |
| 43 | -<!-- :id="'snapImg_' + scope.row.deviceId + '_' + scope.row.channelId"--> | |
| 44 | -<!-- :src="getSnap(scope.row)"--> | |
| 45 | -<!-- @error="getSnapErrorEvent($event, scope.row)"--> | |
| 46 | -<!-- :fit="'contain'">--> | |
| 47 | -<!-- <div slot="error" class="image-slot">--> | |
| 48 | -<!-- <i class="el-icon-picture-outline"></i>--> | |
| 49 | -<!-- </div>--> | |
| 50 | -<!-- </el-image>--> | |
| 51 | - </template> | |
| 52 | - </el-table-column> | |
| 53 | - <el-table-column prop="subCount" label="子节点数"> | |
| 54 | - </el-table-column> | |
| 55 | - <el-table-column prop="manufacture" label="厂家"> | |
| 56 | - </el-table-column> | |
| 57 | - <el-table-column label="位置信息" align="center"> | |
| 58 | - <template slot-scope="scope"> | |
| 59 | - <span>{{scope.row.longitude}},{{scope.row.latitude}}</span> | |
| 60 | - </template> | |
| 61 | - </el-table-column> | |
| 62 | - <el-table-column prop="ptztypeText" label="云台类型"/> | |
| 63 | - <el-table-column label="开启音频" align="center"> | |
| 64 | - <template slot-scope="scope"> | |
| 65 | - <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF"> | |
| 66 | - </el-switch> | |
| 67 | - </template> | |
| 68 | - </el-table-column> | |
| 69 | - <el-table-column label="状态" width="180" align="center"> | |
| 70 | - <template slot-scope="scope"> | |
| 71 | - <div slot="reference" class="name-wrapper"> | |
| 72 | - <el-tag size="medium" v-if="scope.row.status == 1">开启</el-tag> | |
| 73 | - <el-tag size="medium" type="info" v-if="scope.row.status == 0">关闭</el-tag> | |
| 74 | - </div> | |
| 75 | - </template> | |
| 76 | - </el-table-column> | |
| 17 | + 通道类型: | |
| 18 | + <el-select size="mini" @change="search" style="margin-right: 1rem;" v-model="channelType" placeholder="请选择" | |
| 19 | + default-first-option> | |
| 20 | + <el-option label="全部" value=""></el-option> | |
| 21 | + <el-option label="设备" value="false"></el-option> | |
| 22 | + <el-option label="子目录" value="true"></el-option> | |
| 23 | + </el-select> | |
| 24 | + 在线状态: | |
| 25 | + <el-select size="mini" style="margin-right: 1rem;" @change="search" v-model="online" placeholder="请选择" | |
| 26 | + default-first-option> | |
| 27 | + <el-option label="全部" value=""></el-option> | |
| 28 | + <el-option label="在线" value="true"></el-option> | |
| 29 | + <el-option label="离线" value="false"></el-option> | |
| 30 | + </el-select> | |
| 31 | + <el-checkbox size="mini" style="margin-right: 1rem; float: right;" v-model="autoList" @change="autoListChange"> | |
| 32 | + 自动刷新 | |
| 33 | + </el-checkbox> | |
| 34 | + </div> | |
| 35 | + <devicePlayer ref="devicePlayer" v-loading="isLoging"></devicePlayer> | |
| 36 | + <!--设备列表--> | |
| 37 | + <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%"> | |
| 38 | + <el-table-column prop="channelId" label="通道编号" width="200"> | |
| 39 | + </el-table-column> | |
| 40 | + <el-table-column prop="name" label="通道名称"> | |
| 41 | + </el-table-column> | |
| 42 | + <el-table-column label="快照" width="80" align="center"> | |
| 43 | + <template slot-scope="scope"> | |
| 44 | + <img style="max-height: 3rem;max-width: 4rem;" | |
| 45 | + :id="scope.row.deviceId + '_' + scope.row.channelId" | |
| 46 | + :src="getSnap(scope.row)" | |
| 47 | + @error="getSnapErrorEvent($event.target.id)" | |
| 48 | + alt=""> | |
| 49 | + <!-- <el-image--> | |
| 50 | + <!-- :id="'snapImg_' + scope.row.deviceId + '_' + scope.row.channelId"--> | |
| 51 | + <!-- :src="getSnap(scope.row)"--> | |
| 52 | + <!-- @error="getSnapErrorEvent($event, scope.row)"--> | |
| 53 | + <!-- :fit="'contain'">--> | |
| 54 | + <!-- <div slot="error" class="image-slot">--> | |
| 55 | + <!-- <i class="el-icon-picture-outline"></i>--> | |
| 56 | + <!-- </div>--> | |
| 57 | + <!-- </el-image>--> | |
| 58 | + </template> | |
| 59 | + </el-table-column> | |
| 60 | + <el-table-column prop="subCount" label="子节点数"> | |
| 61 | + </el-table-column> | |
| 62 | + <el-table-column prop="manufacture" label="厂家"> | |
| 63 | + </el-table-column> | |
| 64 | + <el-table-column label="位置信息" align="center"> | |
| 65 | + <template slot-scope="scope"> | |
| 66 | + <span>{{ scope.row.longitude }},{{ scope.row.latitude }}</span> | |
| 67 | + </template> | |
| 68 | + </el-table-column> | |
| 69 | + <el-table-column prop="ptztypeText" label="云台类型"/> | |
| 70 | + <el-table-column label="开启音频" align="center"> | |
| 71 | + <template slot-scope="scope"> | |
| 72 | + <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF"> | |
| 73 | + </el-switch> | |
| 74 | + </template> | |
| 75 | + </el-table-column> | |
| 76 | + <el-table-column label="状态" width="180" align="center"> | |
| 77 | + <template slot-scope="scope"> | |
| 78 | + <div slot="reference" class="name-wrapper"> | |
| 79 | + <el-tag size="medium" v-if="scope.row.status == 1">开启</el-tag> | |
| 80 | + <el-tag size="medium" type="info" v-if="scope.row.status == 0">关闭</el-tag> | |
| 81 | + </div> | |
| 82 | + </template> | |
| 83 | + </el-table-column> | |
| 77 | 84 | |
| 78 | 85 | |
| 79 | - <el-table-column label="操作" width="280" align="center" fixed="right"> | |
| 80 | - <template slot-scope="scope"> | |
| 81 | - <el-button-group> | |
| 82 | - <!-- <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">播放</el-button> --> | |
| 83 | - <el-button size="mini" icon="el-icon-video-play" @click="sendDevicePush(scope.row)">播放</el-button> | |
| 84 | - <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="!!scope.row.streamId" @click="stopDevicePush(scope.row)">停止</el-button> | |
| 85 | - <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.subCount > 0" @click="changeSubchannel(scope.row)">查看</el-button> | |
| 86 | - <el-button size="mini" icon="el-icon-video-camera" type="primary" @click="queryRecords(scope.row)">设备录象</el-button> | |
| 87 | - <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">录像查询</el-button> --> | |
| 88 | - </el-button-group> | |
| 89 | - </template> | |
| 90 | - </el-table-column> | |
| 91 | - </el-table> | |
| 92 | - <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"> | |
| 93 | - </el-pagination> | |
| 94 | - | |
| 95 | - </el-main> | |
| 96 | - </el-container> | |
| 97 | -</div> | |
| 86 | + <el-table-column label="操作" width="280" align="center" fixed="right"> | |
| 87 | + <template slot-scope="scope"> | |
| 88 | + <el-button-group> | |
| 89 | + <!-- <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">播放</el-button> --> | |
| 90 | + <el-button size="mini" icon="el-icon-video-play" @click="sendDevicePush(scope.row)">播放</el-button> | |
| 91 | + <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="!!scope.row.streamId" | |
| 92 | + @click="stopDevicePush(scope.row)">停止 | |
| 93 | + </el-button> | |
| 94 | + <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.subCount > 0" | |
| 95 | + @click="changeSubchannel(scope.row)">查看 | |
| 96 | + </el-button> | |
| 97 | + <el-button size="mini" icon="el-icon-video-camera" type="primary" @click="queryRecords(scope.row)">设备录象 | |
| 98 | + </el-button> | |
| 99 | + <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">录像查询</el-button> --> | |
| 100 | + </el-button-group> | |
| 101 | + </template> | |
| 102 | + </el-table-column> | |
| 103 | + </el-table> | |
| 104 | + <el-pagination style="float: right" @size-change="handleSizeChange" @current-change="currentChange" | |
| 105 | + :current-page="currentPage" :page-size="count" :page-sizes="[15, 20, 30, 50]" | |
| 106 | + layout="total, sizes, prev, pager, next" :total="total"> | |
| 107 | + </el-pagination> | |
| 108 | + </div> | |
| 98 | 109 | </template> |
| 99 | 110 | |
| 100 | 111 | <script> |
| 101 | 112 | import devicePlayer from './dialog/devicePlayer.vue' |
| 102 | -import uiHeader from './UiHeader.vue' | |
| 113 | +import uiHeader from '../layout/UiHeader.vue' | |
| 103 | 114 | import moment from "moment"; |
| 115 | + | |
| 104 | 116 | export default { |
| 105 | - name: 'channelList', | |
| 106 | - components: { | |
| 107 | - devicePlayer, | |
| 108 | - uiHeader | |
| 109 | - }, | |
| 110 | - data() { | |
| 111 | - return { | |
| 112 | - deviceId: this.$route.params.deviceId, | |
| 113 | - parentChannelId: this.$route.params.parentChannelId, | |
| 114 | - deviceChannelList: [], | |
| 115 | - videoComponentList: [], | |
| 116 | - currentPlayerInfo: {}, //当前播放对象 | |
| 117 | - updateLooper: 0, //数据刷新轮训标志 | |
| 118 | - searchSrt: "", | |
| 119 | - channelType: "", | |
| 120 | - online: "", | |
| 121 | - winHeight: window.innerHeight - 250, | |
| 122 | - currentPage: parseInt(this.$route.params.page), | |
| 123 | - count: parseInt(this.$route.params.count), | |
| 124 | - total: 0, | |
| 125 | - beforeUrl: "/deviceList", | |
| 126 | - isLoging: false, | |
| 127 | - autoList: true, | |
| 128 | - loadSnap:{} | |
| 129 | - }; | |
| 117 | + name: 'channelList', | |
| 118 | + components: { | |
| 119 | + devicePlayer, | |
| 120 | + uiHeader | |
| 121 | + }, | |
| 122 | + data() { | |
| 123 | + return { | |
| 124 | + deviceId: this.$route.params.deviceId, | |
| 125 | + parentChannelId: this.$route.params.parentChannelId, | |
| 126 | + deviceChannelList: [], | |
| 127 | + videoComponentList: [], | |
| 128 | + currentPlayerInfo: {}, //当前播放对象 | |
| 129 | + updateLooper: 0, //数据刷新轮训标志 | |
| 130 | + searchSrt: "", | |
| 131 | + channelType: "", | |
| 132 | + online: "", | |
| 133 | + winHeight: window.innerHeight - 250, | |
| 134 | + currentPage: parseInt(this.$route.params.page), | |
| 135 | + count: parseInt(this.$route.params.count), | |
| 136 | + total: 0, | |
| 137 | + beforeUrl: "/deviceList", | |
| 138 | + isLoging: false, | |
| 139 | + autoList: true, | |
| 140 | + loadSnap: {} | |
| 141 | + }; | |
| 142 | + }, | |
| 143 | + | |
| 144 | + mounted() { | |
| 145 | + this.initData(); | |
| 146 | + if (this.autoList) { | |
| 147 | + this.updateLooper = setInterval(this.initData, 5000); | |
| 148 | + } | |
| 149 | + | |
| 150 | + }, | |
| 151 | + destroyed() { | |
| 152 | + this.$destroy('videojs'); | |
| 153 | + clearTimeout(this.updateLooper); | |
| 154 | + }, | |
| 155 | + methods: { | |
| 156 | + initData: function () { | |
| 157 | + if (typeof (this.parentChannelId) == "undefined" || this.parentChannelId == 0) { | |
| 158 | + this.getDeviceChannelList(); | |
| 159 | + } else { | |
| 160 | + this.showSubchannels(); | |
| 161 | + } | |
| 130 | 162 | }, |
| 163 | + initParam: function () { | |
| 164 | + this.deviceId = this.$route.params.deviceId; | |
| 165 | + this.parentChannelId = this.$route.params.parentChannelId; | |
| 166 | + this.currentPage = parseInt(this.$route.params.page); | |
| 167 | + this.count = parseInt(this.$route.params.count); | |
| 168 | + if (this.parentChannelId == "" || this.parentChannelId == 0) { | |
| 169 | + this.beforeUrl = "/deviceList" | |
| 170 | + } | |
| 131 | 171 | |
| 132 | - mounted() { | |
| 172 | + }, | |
| 173 | + currentChange: function (val) { | |
| 174 | + var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}` | |
| 175 | + this.$router.push(url).then(() => { | |
| 176 | + this.initParam(); | |
| 133 | 177 | this.initData(); |
| 134 | - if (this.autoList) { | |
| 135 | - this.updateLooper = setInterval(this.initData, 5000); | |
| 136 | - } | |
| 178 | + }) | |
| 179 | + }, | |
| 180 | + handleSizeChange: function (val) { | |
| 181 | + var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1` | |
| 182 | + this.$router.push(url).then(() => { | |
| 183 | + this.initParam(); | |
| 184 | + this.initData(); | |
| 185 | + }) | |
| 137 | 186 | |
| 138 | 187 | }, |
| 139 | - destroyed() { | |
| 140 | - this.$destroy('videojs'); | |
| 141 | - clearTimeout(this.updateLooper); | |
| 188 | + getDeviceChannelList: function () { | |
| 189 | + let that = this; | |
| 190 | + if (typeof (this.$route.params.deviceId) == "undefined") return; | |
| 191 | + this.$axios({ | |
| 192 | + method: 'get', | |
| 193 | + url: `/api/device/query/devices/${this.$route.params.deviceId}/channels`, | |
| 194 | + params: { | |
| 195 | + page: that.currentPage, | |
| 196 | + count: that.count, | |
| 197 | + query: that.searchSrt, | |
| 198 | + online: that.online, | |
| 199 | + channelType: that.channelType | |
| 200 | + } | |
| 201 | + }).then(function (res) { | |
| 202 | + that.total = res.data.total; | |
| 203 | + that.deviceChannelList = res.data.list; | |
| 204 | + // 防止出现表格错位 | |
| 205 | + that.$nextTick(() => { | |
| 206 | + that.$refs.channelListTable.doLayout(); | |
| 207 | + }) | |
| 208 | + }).catch(function (error) { | |
| 209 | + console.log(error); | |
| 210 | + }); | |
| 142 | 211 | }, |
| 143 | - methods: { | |
| 144 | - initData: function () { | |
| 145 | - if (typeof (this.parentChannelId) == "undefined" || this.parentChannelId == 0) { | |
| 146 | - this.getDeviceChannelList(); | |
| 147 | - } else { | |
| 148 | - this.showSubchannels(); | |
| 149 | - } | |
| 150 | - }, | |
| 151 | - initParam: function () { | |
| 152 | - this.deviceId = this.$route.params.deviceId; | |
| 153 | - this.parentChannelId = this.$route.params.parentChannelId; | |
| 154 | - this.currentPage = parseInt(this.$route.params.page); | |
| 155 | - this.count = parseInt(this.$route.params.count); | |
| 156 | - if (this.parentChannelId == "" || this.parentChannelId == 0) { | |
| 157 | - this.beforeUrl = "/deviceList" | |
| 158 | - } | |
| 159 | - | |
| 160 | - }, | |
| 161 | - currentChange: function (val) { | |
| 162 | - var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}` | |
| 163 | - this.$router.push(url).then(() => { | |
| 164 | - this.initParam(); | |
| 165 | - this.initData(); | |
| 166 | - }) | |
| 167 | - }, | |
| 168 | - handleSizeChange: function (val) { | |
| 169 | - var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1` | |
| 170 | - this.$router.push(url).then(() => { | |
| 171 | - this.initParam(); | |
| 172 | - this.initData(); | |
| 173 | - }) | |
| 174 | 212 | |
| 175 | - }, | |
| 176 | - getDeviceChannelList: function () { | |
| 177 | - let that = this; | |
| 178 | - if (typeof (this.$route.params.deviceId) == "undefined") return; | |
| 179 | - this.$axios({ | |
| 180 | - method: 'get', | |
| 181 | - url: `/api/device/query/devices/${this.$route.params.deviceId}/channels`, | |
| 182 | - params:{ | |
| 183 | - page: that.currentPage, | |
| 184 | - count: that.count, | |
| 185 | - query: that.searchSrt, | |
| 186 | - online: that.online, | |
| 187 | - channelType: that.channelType | |
| 188 | - } | |
| 189 | - }).then(function (res) { | |
| 190 | - that.total = res.data.total; | |
| 191 | - that.deviceChannelList = res.data.list; | |
| 192 | - // 防止出现表格错位 | |
| 193 | - that.$nextTick(() => { | |
| 194 | - that.$refs.channelListTable.doLayout(); | |
| 195 | - }) | |
| 196 | - }).catch(function (error) { | |
| 197 | - console.log(error); | |
| 198 | - }); | |
| 199 | - }, | |
| 213 | + //通知设备上传媒体流 | |
| 214 | + sendDevicePush: function (itemData) { | |
| 215 | + let deviceId = this.deviceId; | |
| 216 | + this.isLoging = true; | |
| 217 | + let channelId = itemData.channelId; | |
| 218 | + console.log("通知设备推流1:" + deviceId + " : " + channelId); | |
| 219 | + let that = this; | |
| 220 | + this.$axios({ | |
| 221 | + method: 'get', | |
| 222 | + url: '/api/play/start/' + deviceId + '/' + channelId | |
| 223 | + }).then(function (res) { | |
| 224 | + that.isLoging = false; | |
| 225 | + if (res.data.code === 0) { | |
| 200 | 226 | |
| 201 | - //通知设备上传媒体流 | |
| 202 | - sendDevicePush: function (itemData) { | |
| 203 | - let deviceId = this.deviceId; | |
| 204 | - this.isLoging = true; | |
| 205 | - let channelId = itemData.channelId; | |
| 206 | - console.log("通知设备推流1:" + deviceId + " : " + channelId ); | |
| 207 | - let that = this; | |
| 208 | - this.$axios({ | |
| 209 | - method: 'get', | |
| 210 | - url: '/api/play/start/' + deviceId + '/' + channelId | |
| 211 | - }).then(function (res) { | |
| 212 | - that.isLoging = false; | |
| 213 | - if (res.data.code === 0) { | |
| 227 | + setTimeout(() => { | |
| 214 | 228 | |
| 215 | - setTimeout(()=>{ | |
| 229 | + let snapId = deviceId + "_" + channelId; | |
| 230 | + that.loadSnap[snapId] = 0; | |
| 231 | + that.getSnapErrorEvent(snapId) | |
| 232 | + }, 5000) | |
| 233 | + that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { | |
| 234 | + streamInfo: res.data.data, | |
| 235 | + hasAudio: itemData.hasAudio | |
| 236 | + }); | |
| 237 | + setTimeout(() => { | |
| 238 | + that.initData(); | |
| 239 | + }, 1000) | |
| 216 | 240 | |
| 217 | - let snapId = deviceId + "_" + channelId; | |
| 218 | - that.loadSnap[snapId] = 0; | |
| 219 | - that.getSnapErrorEvent(snapId) | |
| 220 | - },5000) | |
| 221 | - that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { | |
| 222 | - streamInfo: res.data.data, | |
| 223 | - hasAudio: itemData.hasAudio | |
| 224 | - }); | |
| 225 | - setTimeout(()=>{ | |
| 226 | - that.initData(); | |
| 227 | - },1000) | |
| 228 | - | |
| 229 | - }else { | |
| 230 | - that.$message.error(res.data.msg); | |
| 231 | - } | |
| 232 | - }).catch(function (e) {}); | |
| 233 | - }, | |
| 234 | - queryRecords: function (itemData) { | |
| 235 | - var format = moment().format("YYYY-M-D"); | |
| 236 | - let deviceId = this.deviceId; | |
| 237 | - let channelId = itemData.channelId; | |
| 238 | - this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format}) | |
| 239 | - }, | |
| 240 | - stopDevicePush: function (itemData) { | |
| 241 | - var that = this; | |
| 242 | - this.$axios({ | |
| 243 | - method: 'get', | |
| 244 | - url: '/api/play/stop/' + this.deviceId + "/" + itemData.channelId | |
| 245 | - }).then(function (res) { | |
| 246 | - that.initData(); | |
| 247 | - }).catch(function (error) { | |
| 248 | - if (error.response.status === 402) { // 已经停止过 | |
| 249 | - that.initData(); | |
| 250 | - }else { | |
| 251 | - console.log(error) | |
| 252 | - } | |
| 253 | - }); | |
| 254 | - }, | |
| 255 | - getSnap: function (row){ | |
| 256 | - return '/static/snap/' + row.deviceId + '_' + row.channelId + '.jpg' | |
| 257 | - }, | |
| 258 | - getSnapErrorEvent: function (id){ | |
| 241 | + } else { | |
| 242 | + that.$message.error(res.data.msg); | |
| 243 | + } | |
| 244 | + }).catch(function (e) { | |
| 245 | + }); | |
| 246 | + }, | |
| 247 | + queryRecords: function (itemData) { | |
| 248 | + var format = moment().format("YYYY-M-D"); | |
| 249 | + let deviceId = this.deviceId; | |
| 250 | + let channelId = itemData.channelId; | |
| 251 | + this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format}) | |
| 252 | + }, | |
| 253 | + stopDevicePush: function (itemData) { | |
| 254 | + var that = this; | |
| 255 | + this.$axios({ | |
| 256 | + method: 'get', | |
| 257 | + url: '/api/play/stop/' + this.deviceId + "/" + itemData.channelId | |
| 258 | + }).then(function (res) { | |
| 259 | + that.initData(); | |
| 260 | + }).catch(function (error) { | |
| 261 | + if (error.response.status === 402) { // 已经停止过 | |
| 262 | + that.initData(); | |
| 263 | + } else { | |
| 264 | + console.log(error) | |
| 265 | + } | |
| 266 | + }); | |
| 267 | + }, | |
| 268 | + getSnap: function (row) { | |
| 269 | + return '/static/snap/' + row.deviceId + '_' + row.channelId + '.jpg' | |
| 270 | + }, | |
| 271 | + getSnapErrorEvent: function (id) { | |
| 259 | 272 | |
| 260 | - if (typeof (this.loadSnap[id]) != "undefined") { | |
| 261 | - console.log("下载截图" + this.loadSnap[id]) | |
| 262 | - if (this.loadSnap[id] > 5) { | |
| 263 | - delete this.loadSnap[id]; | |
| 264 | - return; | |
| 265 | - } | |
| 266 | - setTimeout(()=>{ | |
| 267 | - this.loadSnap[id] ++ | |
| 268 | - document.getElementById(id).setAttribute("src", '/static/snap/' + id + '.jpg?' + new Date().getTime()) | |
| 269 | - },1000) | |
| 273 | + if (typeof (this.loadSnap[id]) != "undefined") { | |
| 274 | + console.log("下载截图" + this.loadSnap[id]) | |
| 275 | + if (this.loadSnap[id] > 5) { | |
| 276 | + delete this.loadSnap[id]; | |
| 277 | + return; | |
| 278 | + } | |
| 279 | + setTimeout(() => { | |
| 280 | + this.loadSnap[id]++ | |
| 281 | + document.getElementById(id).setAttribute("src", '/static/snap/' + id + '.jpg?' + new Date().getTime()) | |
| 282 | + }, 1000) | |
| 270 | 283 | |
| 271 | - } | |
| 272 | - }, | |
| 273 | - showDevice: function () { | |
| 274 | - this.$router.push(this.beforeUrl).then(() => { | |
| 275 | - this.initParam(); | |
| 276 | - this.initData(); | |
| 277 | - }) | |
| 278 | - }, | |
| 279 | - changeSubchannel(itemData) { | |
| 280 | - this.beforeUrl = this.$router.currentRoute.path; | |
| 284 | + } | |
| 285 | + }, | |
| 286 | + showDevice: function () { | |
| 287 | + this.$router.push(this.beforeUrl).then(() => { | |
| 288 | + this.initParam(); | |
| 289 | + this.initData(); | |
| 290 | + }) | |
| 291 | + }, | |
| 292 | + changeSubchannel(itemData) { | |
| 293 | + this.beforeUrl = this.$router.currentRoute.path; | |
| 281 | 294 | |
| 282 | - var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}/${this.$router.currentRoute.params.count}/1` | |
| 283 | - this.$router.push(url).then(() => { | |
| 284 | - this.searchSrt = ""; | |
| 285 | - this.channelType = ""; | |
| 286 | - this.online = ""; | |
| 287 | - this.initParam(); | |
| 288 | - this.initData(); | |
| 289 | - }) | |
| 290 | - }, | |
| 291 | - showSubchannels: function (channelId) { | |
| 292 | - let that = this; | |
| 295 | + var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}/${this.$router.currentRoute.params.count}/1` | |
| 296 | + this.$router.push(url).then(() => { | |
| 297 | + this.searchSrt = ""; | |
| 298 | + this.channelType = ""; | |
| 299 | + this.online = ""; | |
| 300 | + this.initParam(); | |
| 301 | + this.initData(); | |
| 302 | + }) | |
| 303 | + }, | |
| 304 | + showSubchannels: function (channelId) { | |
| 305 | + let that = this; | |
| 293 | 306 | |
| 294 | - this.$axios({ | |
| 295 | - method: 'get', | |
| 296 | - url:`/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`, | |
| 297 | - params: { | |
| 298 | - page: that.currentPage, | |
| 299 | - count: that.count, | |
| 300 | - query: that.searchSrt, | |
| 301 | - online: that.online, | |
| 302 | - channelType: that.channelType | |
| 303 | - } | |
| 304 | - }).then(function (res) { | |
| 305 | - that.total = res.data.total; | |
| 306 | - that.deviceChannelList = res.data.list; | |
| 307 | - // 防止出现表格错位 | |
| 308 | - that.$nextTick(() => { | |
| 309 | - that.$refs.channelListTable.doLayout(); | |
| 310 | - }) | |
| 311 | - }).catch(function (error) { | |
| 312 | - console.log(error); | |
| 313 | - }); | |
| 314 | - }, | |
| 315 | - search: function () { | |
| 316 | - this.currentPage = 1; | |
| 317 | - this.total = 0; | |
| 318 | - this.initData(); | |
| 319 | - }, | |
| 320 | - updateChannel: function (row) { | |
| 321 | - this.$axios({ | |
| 322 | - method: 'post', | |
| 323 | - url: `/api/device/query/channel/update/${this.deviceId}`, | |
| 324 | - params: row | |
| 325 | - }).then(function (res) { | |
| 326 | - console.log(JSON.stringify(res)); | |
| 327 | - }); | |
| 328 | - }, | |
| 329 | - autoListChange: function () { | |
| 330 | - if (this.autoList) { | |
| 331 | - this.updateLooper = setInterval(this.initData, 1500); | |
| 332 | - }else{ | |
| 333 | - window.clearInterval(this.updateLooper); | |
| 334 | - } | |
| 307 | + this.$axios({ | |
| 308 | + method: 'get', | |
| 309 | + url: `/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`, | |
| 310 | + params: { | |
| 311 | + page: that.currentPage, | |
| 312 | + count: that.count, | |
| 313 | + query: that.searchSrt, | |
| 314 | + online: that.online, | |
| 315 | + channelType: that.channelType | |
| 335 | 316 | } |
| 336 | - | |
| 317 | + }).then(function (res) { | |
| 318 | + that.total = res.data.total; | |
| 319 | + that.deviceChannelList = res.data.list; | |
| 320 | + // 防止出现表格错位 | |
| 321 | + that.$nextTick(() => { | |
| 322 | + that.$refs.channelListTable.doLayout(); | |
| 323 | + }) | |
| 324 | + }).catch(function (error) { | |
| 325 | + console.log(error); | |
| 326 | + }); | |
| 327 | + }, | |
| 328 | + search: function () { | |
| 329 | + this.currentPage = 1; | |
| 330 | + this.total = 0; | |
| 331 | + this.initData(); | |
| 332 | + }, | |
| 333 | + updateChannel: function (row) { | |
| 334 | + this.$axios({ | |
| 335 | + method: 'post', | |
| 336 | + url: `/api/device/query/channel/update/${this.deviceId}`, | |
| 337 | + params: row | |
| 338 | + }).then(function (res) { | |
| 339 | + console.log(JSON.stringify(res)); | |
| 340 | + }); | |
| 341 | + }, | |
| 342 | + autoListChange: function () { | |
| 343 | + if (this.autoList) { | |
| 344 | + this.updateLooper = setInterval(this.initData, 1500); | |
| 345 | + } else { | |
| 346 | + window.clearInterval(this.updateLooper); | |
| 347 | + } | |
| 337 | 348 | } |
| 349 | + | |
| 350 | + } | |
| 338 | 351 | }; |
| 339 | 352 | </script> |
| 340 | 353 | |
| 341 | 354 | <style> |
| 342 | 355 | .videoList { |
| 343 | - display: flex; | |
| 344 | - flex-wrap: wrap; | |
| 345 | - align-content: flex-start; | |
| 356 | + display: flex; | |
| 357 | + flex-wrap: wrap; | |
| 358 | + align-content: flex-start; | |
| 346 | 359 | } |
| 347 | 360 | |
| 348 | 361 | .video-item { |
| 349 | - position: relative; | |
| 350 | - width: 15rem; | |
| 351 | - height: 10rem; | |
| 352 | - margin-right: 1rem; | |
| 353 | - background-color: #000000; | |
| 362 | + position: relative; | |
| 363 | + width: 15rem; | |
| 364 | + height: 10rem; | |
| 365 | + margin-right: 1rem; | |
| 366 | + background-color: #000000; | |
| 354 | 367 | } |
| 355 | 368 | |
| 356 | 369 | .video-item-img { |
| 357 | - position: absolute; | |
| 358 | - top: 0; | |
| 359 | - bottom: 0; | |
| 360 | - left: 0; | |
| 361 | - right: 0; | |
| 362 | - margin: auto; | |
| 363 | - width: 100%; | |
| 364 | - height: 100%; | |
| 370 | + position: absolute; | |
| 371 | + top: 0; | |
| 372 | + bottom: 0; | |
| 373 | + left: 0; | |
| 374 | + right: 0; | |
| 375 | + margin: auto; | |
| 376 | + width: 100%; | |
| 377 | + height: 100%; | |
| 365 | 378 | } |
| 366 | 379 | |
| 367 | 380 | .video-item-img:after { |
| 368 | - content: ""; | |
| 369 | - display: inline-block; | |
| 370 | - position: absolute; | |
| 371 | - z-index: 2; | |
| 372 | - top: 0; | |
| 373 | - bottom: 0; | |
| 374 | - left: 0; | |
| 375 | - right: 0; | |
| 376 | - margin: auto; | |
| 377 | - width: 3rem; | |
| 378 | - height: 3rem; | |
| 379 | - background-image: url("../assets/loading.png"); | |
| 380 | - background-size: cover; | |
| 381 | - background-color: #000000; | |
| 381 | + content: ""; | |
| 382 | + display: inline-block; | |
| 383 | + position: absolute; | |
| 384 | + z-index: 2; | |
| 385 | + top: 0; | |
| 386 | + bottom: 0; | |
| 387 | + left: 0; | |
| 388 | + right: 0; | |
| 389 | + margin: auto; | |
| 390 | + width: 3rem; | |
| 391 | + height: 3rem; | |
| 392 | + background-image: url("../assets/loading.png"); | |
| 393 | + background-size: cover; | |
| 394 | + background-color: #000000; | |
| 382 | 395 | } |
| 383 | 396 | |
| 384 | 397 | .video-item-title { |
| 385 | - position: absolute; | |
| 386 | - bottom: 0; | |
| 387 | - color: #000000; | |
| 388 | - background-color: #ffffff; | |
| 389 | - line-height: 1.5rem; | |
| 390 | - padding: 0.3rem; | |
| 391 | - width: 14.4rem; | |
| 398 | + position: absolute; | |
| 399 | + bottom: 0; | |
| 400 | + color: #000000; | |
| 401 | + background-color: #ffffff; | |
| 402 | + line-height: 1.5rem; | |
| 403 | + padding: 0.3rem; | |
| 404 | + width: 14.4rem; | |
| 392 | 405 | } |
| 393 | 406 | </style> | ... | ... |
web_src/src/components/control.vue
| 1 | 1 | <template> |
| 2 | -<div id="app"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">控制台</span> | |
| 10 | - <div style="position: absolute; right: 17rem; top: 0.3rem;"> | |
| 11 | - 节点选择: <el-select size="mini" @change="chooseMediaChange" style="width: 18rem; margin-right: 8rem;" v-model="mediaServerChoose" placeholder="请选择" default-first-option> | |
| 12 | - <el-option | |
| 13 | - v-for="item in mediaServerList" | |
| 14 | - :key="item.id" | |
| 15 | - :label="item.id + '( ' + item.streamIp + ' )'" | |
| 16 | - :value="item.id"> | |
| 17 | - </el-option> | |
| 18 | - </el-select> | |
| 19 | - <span >{{loadCount}}</span> | |
| 20 | - </div> | |
| 21 | - <div style="position: absolute; right: 1rem; top: 0.3rem;"> | |
| 22 | - <el-popover placement="bottom" width="900" height="300" trigger="click"> | |
| 23 | - <div style="height: 600px; overflow:auto; padding: 20px"> | |
| 24 | - <el-descriptions v-for="(value, key, index) in serverConfig" :key="key" border :column="1" style="margin-bottom: 1rem"> | |
| 25 | - <template slot="title"> | |
| 26 | - {{key}} | |
| 27 | - </template> | |
| 28 | - <el-descriptions-item v-for="(value1, key1, index1) in serverConfig[key]" :key="key1"> | |
| 29 | - <template slot="label" > | |
| 30 | - {{ getMediaKeyNameFromKey(key1) }} | |
| 31 | - </template> | |
| 32 | - {{ value1 }} | |
| 33 | - </el-descriptions-item> | |
| 34 | - </el-descriptions> | |
| 35 | - </div> | |
| 36 | - <el-button type="primary" slot="reference" size="mini" @click="getServerConfig()">媒体服务器配置</el-button> | |
| 37 | - </el-popover> | |
| 38 | - <el-popover placement="bottom" width="900" height="300" trigger="click"> | |
| 39 | - <div style="height: 600px;overflow:auto; padding: 20px"> | |
| 40 | - <el-descriptions title="国标配置" border :column="1"> | |
| 41 | - <template slot="extra"> | |
| 42 | - <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> | |
| 43 | - </template> | |
| 44 | - <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.sip" :key="key"> | |
| 45 | - <template slot="label"> | |
| 46 | - {{ getNameFromKey(key) }} | |
| 47 | - </template> | |
| 48 | - {{ value }} | |
| 49 | - </el-descriptions-item> | |
| 50 | - </el-descriptions> | |
| 2 | + <div id="app" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">控制台</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + 节点选择: | |
| 7 | + <el-select size="mini" @change="chooseMediaChange" style="width: 18rem; margin-right: 8rem;" | |
| 8 | + v-model="mediaServerChoose" placeholder="请选择" default-first-option> | |
| 9 | + <el-option | |
| 10 | + v-for="item in mediaServerList" | |
| 11 | + :key="item.id" | |
| 12 | + :label="item.id + '( ' + item.streamIp + ' )'" | |
| 13 | + :value="item.id"> | |
| 14 | + </el-option> | |
| 15 | + </el-select> | |
| 16 | + <span>{{ loadCount }}</span> | |
| 17 | + </div> | |
| 18 | + <div class="page-header-btn"> | |
| 19 | + <el-popover placement="bottom" width="900" height="300" trigger="click"> | |
| 20 | + <div style="height: 600px; overflow:auto; padding: 20px"> | |
| 21 | + <el-descriptions v-for="(value, key, index) in serverConfig" :key="key" border :column="1" | |
| 22 | + style="margin-bottom: 1rem"> | |
| 23 | + <template slot="title"> | |
| 24 | + {{ key }} | |
| 25 | + </template> | |
| 26 | + <el-descriptions-item v-for="(value1, key1, index1) in serverConfig[key]" :key="key1"> | |
| 27 | + <template slot="label"> | |
| 28 | + {{ getMediaKeyNameFromKey(key1) }} | |
| 29 | + </template> | |
| 30 | + {{ value1 }} | |
| 31 | + </el-descriptions-item> | |
| 32 | + </el-descriptions> | |
| 33 | + </div> | |
| 34 | + <el-button type="primary" slot="reference" size="mini" @click="getServerConfig()">媒体服务器配置</el-button> | |
| 35 | + </el-popover> | |
| 36 | + <el-popover placement="bottom" width="900" height="300" trigger="click"> | |
| 37 | + <div style="height: 600px;overflow:auto; padding: 20px"> | |
| 38 | + <el-descriptions title="国标配置" border :column="1"> | |
| 39 | + <template slot="extra"> | |
| 40 | + <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝" | |
| 41 | + v-clipboard="JSON.stringify(wvpServerConfig.sip)|| ''" | |
| 42 | + @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button> | |
| 43 | + </template> | |
| 44 | + <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.sip" :key="key"> | |
| 45 | + <template slot="label"> | |
| 46 | + {{ getNameFromKey(key) }} | |
| 47 | + </template> | |
| 48 | + {{ value }} | |
| 49 | + </el-descriptions-item> | |
| 50 | + </el-descriptions> | |
| 51 | 51 | |
| 52 | - <div style="margin-top: 1rem"> | |
| 53 | - <el-descriptions title="基础配置" border :column="1"> | |
| 54 | - <template slot="extra"> | |
| 55 | - <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> | |
| 56 | - </template> | |
| 57 | - <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.base" :key="key"> | |
| 58 | - <template slot="label" > | |
| 59 | - {{ getNameFromKey(key) }} | |
| 60 | - </template> | |
| 61 | - <div v-if="key === 'interfaceAuthenticationExcludes'"> | |
| 62 | - <el-dropdown> | |
| 52 | + <div style="margin-top: 1rem"> | |
| 53 | + <el-descriptions title="基础配置" border :column="1"> | |
| 54 | + <template slot="extra"> | |
| 55 | + <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝" | |
| 56 | + v-clipboard="JSON.stringify(wvpServerConfig.base)|| ''" | |
| 57 | + @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button> | |
| 58 | + </template> | |
| 59 | + <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.base" :key="key"> | |
| 60 | + <template slot="label"> | |
| 61 | + {{ getNameFromKey(key) }} | |
| 62 | + </template> | |
| 63 | + <div v-if="key === 'interfaceAuthenticationExcludes'"> | |
| 64 | + <el-dropdown> | |
| 63 | 65 | <span class="el-dropdown-link"> |
| 64 | 66 | 查看<i class="el-icon-arrow-down el-icon--right"></i> |
| 65 | 67 | </span> |
| 66 | - <el-dropdown-menu slot="dropdown"> | |
| 67 | - <el-dropdown-item v-for="(value, key, index) in wvpServerConfig.base.interfaceAuthenticationExcludes" :key="key">{{value}}</el-dropdown-item> | |
| 68 | - </el-dropdown-menu> | |
| 69 | - </el-dropdown> | |
| 70 | - </div> | |
| 71 | - <div v-if="key !== 'interfaceAuthenticationExcludes'"> | |
| 72 | - <div v-if="value === true"> | |
| 73 | - 已启用 | |
| 74 | - </div> | |
| 75 | - <div v-if="value === false"> | |
| 76 | - 未启用 | |
| 77 | - </div> | |
| 78 | - <div v-if="value !== true && value !== false"> | |
| 79 | - {{ value }} | |
| 80 | - </div> | |
| 81 | - </div> | |
| 68 | + <el-dropdown-menu slot="dropdown"> | |
| 69 | + <el-dropdown-item | |
| 70 | + v-for="(value, key, index) in wvpServerConfig.base.interfaceAuthenticationExcludes" | |
| 71 | + :key="key">{{ value }} | |
| 72 | + </el-dropdown-item> | |
| 73 | + </el-dropdown-menu> | |
| 74 | + </el-dropdown> | |
| 75 | + </div> | |
| 76 | + <div v-if="key !== 'interfaceAuthenticationExcludes'"> | |
| 77 | + <div v-if="value === true"> | |
| 78 | + 已启用 | |
| 79 | + </div> | |
| 80 | + <div v-if="value === false"> | |
| 81 | + 未启用 | |
| 82 | + </div> | |
| 83 | + <div v-if="value !== true && value !== false"> | |
| 84 | + {{ value }} | |
| 85 | + </div> | |
| 86 | + </div> | |
| 82 | 87 | |
| 83 | - </el-descriptions-item> | |
| 84 | - </el-descriptions> | |
| 85 | - </div> | |
| 86 | - <div style="margin-top: 1rem"> | |
| 87 | - <el-descriptions title="版本信息" border :column="1"> | |
| 88 | - <template slot="extra"> | |
| 89 | - <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> | |
| 90 | - </template> | |
| 91 | - <el-descriptions-item v-for="(value, key, index) in wvpServerVersion" :key="key"> | |
| 92 | - <template slot="label"> | |
| 93 | - {{ getNameFromKey(key) }} | |
| 94 | - </template> | |
| 95 | - {{ value }} | |
| 96 | - </el-descriptions-item> | |
| 97 | - </el-descriptions> | |
| 88 | + </el-descriptions-item> | |
| 89 | + </el-descriptions> | |
| 90 | + </div> | |
| 91 | + <div style="margin-top: 1rem"> | |
| 92 | + <el-descriptions title="版本信息" border :column="1"> | |
| 93 | + <template slot="extra"> | |
| 94 | + <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝" | |
| 95 | + v-clipboard="JSON.stringify(wvpServerVersion) || ''" | |
| 96 | + @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button> | |
| 97 | + </template> | |
| 98 | + <el-descriptions-item v-for="(value, key, index) in wvpServerVersion" :key="key"> | |
| 99 | + <template slot="label"> | |
| 100 | + {{ getNameFromKey(key) }} | |
| 101 | + </template> | |
| 102 | + {{ value }} | |
| 103 | + </el-descriptions-item> | |
| 104 | + </el-descriptions> | |
| 98 | 105 | |
| 99 | 106 | |
| 100 | - </div> | |
| 101 | - </div> | |
| 102 | - <el-button type="primary" slot="reference" size="mini" @click="getWVPServerConfig()">信令服务器配置</el-button> | |
| 103 | - </el-popover> | |
| 104 | - <el-button style="margin-left: 1rem;" type="danger" size="mini" @click="reStartServer()">重启媒体服务器</el-button> | |
| 105 | - </div> | |
| 106 | 107 | </div> |
| 107 | - <el-row :gutter="30"> | |
| 108 | - <el-col :span="12"> | |
| 109 | - <div class="control-table" id="ThreadsLoad">table1</div> | |
| 110 | - </el-col> | |
| 111 | - <el-col :span="12"> | |
| 112 | - <div class="control-table" id="WorkThreadsLoad">table2</div> | |
| 113 | - </el-col> | |
| 114 | - </el-row> | |
| 115 | - <el-table :data="allSessionData" style="margin-top: 1rem;"> | |
| 116 | - <el-table-column prop="peer_ip" label="远端"></el-table-column> | |
| 117 | - <el-table-column prop="local_ip" label="本地"></el-table-column> | |
| 118 | - <el-table-column prop="typeid" label="类型"></el-table-column> | |
| 119 | - <el-table-column align="right"> | |
| 120 | - <template slot="header" slot-scope="scope"> | |
| 121 | - <el-button icon="el-icon-refresh-right" circle @click="getAllSession()"></el-button> | |
| 122 | - </template> | |
| 123 | - <template slot-scope="scope"> | |
| 124 | - <el-button @click.native.prevent="deleteRow(scope.$index, allSessionData)" type="text" size="small">移除</el-button> | |
| 125 | - </template> | |
| 126 | - </el-table-column> | |
| 127 | - </el-table> | |
| 108 | + </div> | |
| 109 | + <el-button type="primary" slot="reference" size="mini" @click="getWVPServerConfig()">信令服务器配置</el-button> | |
| 110 | + </el-popover> | |
| 111 | + <el-button style="margin-left: 1rem;" type="danger" size="mini" @click="reStartServer()">重启媒体服务器</el-button> | |
| 112 | + </div> | |
| 113 | + </div> | |
| 114 | + <!-- <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;">--> | |
| 115 | + <!-- <span style="font-size: 1rem; font-weight: bold;">控制台</span>--> | |
| 116 | + <!-- <div style="position: absolute; right: 17rem; top: 0.3rem;">--> | |
| 117 | + <!-- 节点选择:--> | |
| 118 | + <!-- <el-select size="mini" @change="chooseMediaChange" style="width: 18rem; margin-right: 8rem;"--> | |
| 119 | + <!-- v-model="mediaServerChoose" placeholder="请选择" default-first-option>--> | |
| 120 | + <!-- <el-option--> | |
| 121 | + <!-- v-for="item in mediaServerList"--> | |
| 122 | + <!-- :key="item.id"--> | |
| 123 | + <!-- :label="item.id + '( ' + item.streamIp + ' )'"--> | |
| 124 | + <!-- :value="item.id">--> | |
| 125 | + <!-- </el-option>--> | |
| 126 | + <!-- </el-select>--> | |
| 127 | + <!-- <span>{{ loadCount }}</span>--> | |
| 128 | + <!-- </div>--> | |
| 129 | + <!-- <div style="position: absolute; right: 1rem; top: 0.3rem;">--> | |
| 130 | + <!-- <el-popover placement="bottom" width="900" height="300" trigger="click">--> | |
| 131 | + <!-- <div style="height: 600px; overflow:auto; padding: 20px">--> | |
| 132 | + <!-- <el-descriptions v-for="(value, key, index) in serverConfig" :key="key" border :column="1"--> | |
| 133 | + <!-- style="margin-bottom: 1rem">--> | |
| 134 | + <!-- <template slot="title">--> | |
| 135 | + <!-- {{ key }}--> | |
| 136 | + <!-- </template>--> | |
| 137 | + <!-- <el-descriptions-item v-for="(value1, key1, index1) in serverConfig[key]" :key="key1">--> | |
| 138 | + <!-- <template slot="label">--> | |
| 139 | + <!-- {{ getMediaKeyNameFromKey(key1) }}--> | |
| 140 | + <!-- </template>--> | |
| 141 | + <!-- {{ value1 }}--> | |
| 142 | + <!-- </el-descriptions-item>--> | |
| 143 | + <!-- </el-descriptions>--> | |
| 144 | + <!-- </div>--> | |
| 145 | + <!-- <el-button type="primary" slot="reference" size="mini" @click="getServerConfig()">媒体服务器配置</el-button>--> | |
| 146 | + <!-- </el-popover>--> | |
| 147 | + <!-- <el-popover placement="bottom" width="900" height="300" trigger="click">--> | |
| 148 | + <!-- <div style="height: 600px;overflow:auto; padding: 20px">--> | |
| 149 | + <!-- <el-descriptions title="国标配置" border :column="1">--> | |
| 150 | + <!-- <template slot="extra">--> | |
| 151 | + <!-- <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝"--> | |
| 152 | + <!-- v-clipboard="JSON.stringify(wvpServerConfig.sip)|| ''"--> | |
| 153 | + <!-- @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button>--> | |
| 154 | + <!-- </template>--> | |
| 155 | + <!-- <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.sip" :key="key">--> | |
| 156 | + <!-- <template slot="label">--> | |
| 157 | + <!-- {{ getNameFromKey(key) }}--> | |
| 158 | + <!-- </template>--> | |
| 159 | + <!-- {{ value }}--> | |
| 160 | + <!-- </el-descriptions-item>--> | |
| 161 | + <!-- </el-descriptions>--> | |
| 162 | + | |
| 163 | + <!-- <div style="margin-top: 1rem">--> | |
| 164 | + <!-- <el-descriptions title="基础配置" border :column="1">--> | |
| 165 | + <!-- <template slot="extra">--> | |
| 166 | + <!-- <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝"--> | |
| 167 | + <!-- v-clipboard="JSON.stringify(wvpServerConfig.base)|| ''"--> | |
| 168 | + <!-- @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button>--> | |
| 169 | + <!-- </template>--> | |
| 170 | + <!-- <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.base" :key="key">--> | |
| 171 | + <!-- <template slot="label">--> | |
| 172 | + <!-- {{ getNameFromKey(key) }}--> | |
| 173 | + <!-- </template>--> | |
| 174 | + <!-- <div v-if="key === 'interfaceAuthenticationExcludes'">--> | |
| 175 | + <!-- <el-dropdown>--> | |
| 176 | + <!-- <span class="el-dropdown-link">--> | |
| 177 | + <!-- 查看<i class="el-icon-arrow-down el-icon--right"></i>--> | |
| 178 | + <!-- </span>--> | |
| 179 | + <!-- <el-dropdown-menu slot="dropdown">--> | |
| 180 | + <!-- <el-dropdown-item--> | |
| 181 | + <!-- v-for="(value, key, index) in wvpServerConfig.base.interfaceAuthenticationExcludes"--> | |
| 182 | + <!-- :key="key">{{ value }}--> | |
| 183 | + <!-- </el-dropdown-item>--> | |
| 184 | + <!-- </el-dropdown-menu>--> | |
| 185 | + <!-- </el-dropdown>--> | |
| 186 | + <!-- </div>--> | |
| 187 | + <!-- <div v-if="key !== 'interfaceAuthenticationExcludes'">--> | |
| 188 | + <!-- <div v-if="value === true">--> | |
| 189 | + <!-- 已启用--> | |
| 190 | + <!-- </div>--> | |
| 191 | + <!-- <div v-if="value === false">--> | |
| 192 | + <!-- 未启用--> | |
| 193 | + <!-- </div>--> | |
| 194 | + <!-- <div v-if="value !== true && value !== false">--> | |
| 195 | + <!-- {{ value }}--> | |
| 196 | + <!-- </div>--> | |
| 197 | + <!-- </div>--> | |
| 128 | 198 | |
| 129 | - </el-main> | |
| 130 | - <!-- <el-footer style="position: absolute; bottom: 0; width: 100%;">ZLMediaKit-VUE_UI v1</el-footer> --> | |
| 131 | - </el-container> | |
| 199 | + <!-- </el-descriptions-item>--> | |
| 200 | + <!-- </el-descriptions>--> | |
| 201 | + <!-- </div>--> | |
| 202 | + <!-- <div style="margin-top: 1rem">--> | |
| 203 | + <!-- <el-descriptions title="版本信息" border :column="1">--> | |
| 204 | + <!-- <template slot="extra">--> | |
| 205 | + <!-- <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝"--> | |
| 206 | + <!-- v-clipboard="JSON.stringify(wvpServerVersion) || ''"--> | |
| 207 | + <!-- @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button>--> | |
| 208 | + <!-- </template>--> | |
| 209 | + <!-- <el-descriptions-item v-for="(value, key, index) in wvpServerVersion" :key="key">--> | |
| 210 | + <!-- <template slot="label">--> | |
| 211 | + <!-- {{ getNameFromKey(key) }}--> | |
| 212 | + <!-- </template>--> | |
| 213 | + <!-- {{ value }}--> | |
| 214 | + <!-- </el-descriptions-item>--> | |
| 215 | + <!-- </el-descriptions>--> | |
| 132 | 216 | |
| 133 | -</div> | |
| 217 | + | |
| 218 | + <!-- </div>--> | |
| 219 | + <!-- </div>--> | |
| 220 | + <!-- <el-button type="primary" slot="reference" size="mini" @click="getWVPServerConfig()">信令服务器配置</el-button>--> | |
| 221 | + <!-- </el-popover>--> | |
| 222 | + <!-- <el-button style="margin-left: 1rem;" type="danger" size="mini" @click="reStartServer()">重启媒体服务器</el-button>--> | |
| 223 | + <!-- </div>--> | |
| 224 | + <!-- </div>--> | |
| 225 | + <el-row style="width: 100%"> | |
| 226 | + <el-col :span="12"> | |
| 227 | + <div class="control-table" id="ThreadsLoad" style="margin-right:10px;">table1</div> | |
| 228 | + </el-col> | |
| 229 | + <el-col :span="12"> | |
| 230 | + <div class="control-table" id="WorkThreadsLoad" style="margin-left:10px;">table2</div> | |
| 231 | + </el-col> | |
| 232 | + </el-row> | |
| 233 | + <el-table :data="allSessionData" style="margin-top: 1rem;"> | |
| 234 | + <el-table-column prop="peer_ip" label="远端"></el-table-column> | |
| 235 | + <el-table-column prop="local_ip" label="本地"></el-table-column> | |
| 236 | + <el-table-column prop="typeid" label="类型"></el-table-column> | |
| 237 | + <el-table-column align="right"> | |
| 238 | + <template slot="header" slot-scope="scope"> | |
| 239 | + <el-button icon="el-icon-refresh-right" circle @click="getAllSession()"></el-button> | |
| 240 | + </template> | |
| 241 | + <template slot-scope="scope"> | |
| 242 | + <el-button @click.native.prevent="deleteRow(scope.$index, allSessionData)" type="text" size="small">移除 | |
| 243 | + </el-button> | |
| 244 | + </template> | |
| 245 | + </el-table-column> | |
| 246 | + </el-table> | |
| 247 | + </div> | |
| 134 | 248 | </template> |
| 135 | 249 | |
| 136 | 250 | <script> |
| 137 | -import uiHeader from './UiHeader.vue' | |
| 251 | +import uiHeader from '../layout/UiHeader.vue' | |
| 138 | 252 | import MediaServer from './service/MediaServer' |
| 139 | 253 | |
| 140 | 254 | import echarts from 'echarts'; |
| 141 | -export default { | |
| 142 | - name: 'app', | |
| 143 | - components: { | |
| 144 | - echarts, | |
| 145 | - uiHeader | |
| 146 | - }, | |
| 147 | - data() { | |
| 148 | - return { | |
| 149 | - tableOption: { | |
| 150 | - // legend: {}, | |
| 151 | - xAxis: {}, | |
| 152 | - yAxis: {}, | |
| 153 | - label: {}, | |
| 154 | - tooltip: {}, | |
| 155 | - dataZoom: [], | |
| 156 | - series: [] | |
| 157 | - }, | |
| 158 | - table1Option: { | |
| 159 | - // legend: {}, | |
| 160 | - xAxis: {}, | |
| 161 | - yAxis: {}, | |
| 162 | - label: {}, | |
| 163 | - tooltip: {}, | |
| 164 | - series: [] | |
| 165 | - }, | |
| 166 | - mChart: null, | |
| 167 | - mChart1: null, | |
| 168 | - charZoomStart: 0, | |
| 169 | - charZoomEnd: 100, | |
| 170 | - chartInterval: 0, //更新图表统计图定时任务标识 | |
| 171 | - allSessionData: [], | |
| 172 | - visible: false, | |
| 173 | - wvpVisible: false, | |
| 174 | - serverConfig: {}, | |
| 175 | - wvpServerConfig: {}, | |
| 176 | - wvpServerVersion: {}, | |
| 177 | - mediaServer : new MediaServer(), | |
| 178 | - mediaServerChoose : null, | |
| 179 | - loadCount : 0, | |
| 180 | - mediaServerList : [] | |
| 181 | - }; | |
| 182 | - }, | |
| 183 | - mounted() { | |
| 184 | 255 | |
| 185 | - this.initTable(); | |
| 186 | - this.chartInterval = setInterval(this.updateData, 3000); | |
| 187 | - this.mediaServer.getOnlineMediaServerList((data)=>{ | |
| 188 | - this.mediaServerList = data.data; | |
| 189 | - if (this.mediaServerList && this.mediaServerList.length > 0) { | |
| 190 | - this.mediaServerChoose = this.mediaServerList[0].id | |
| 191 | - this.loadCount = this.mediaServerList[0].count; | |
| 192 | - this.updateData(); | |
| 193 | - } | |
| 194 | - }) | |
| 256 | +export default { | |
| 257 | + name: 'app', | |
| 258 | + components: { | |
| 259 | + echarts, | |
| 260 | + uiHeader | |
| 261 | + }, | |
| 262 | + data() { | |
| 263 | + return { | |
| 264 | + tableOption: { | |
| 265 | + // legend: {}, | |
| 266 | + xAxis: {}, | |
| 267 | + yAxis: {}, | |
| 268 | + label: {}, | |
| 269 | + tooltip: {}, | |
| 270 | + dataZoom: [], | |
| 271 | + series: [] | |
| 272 | + }, | |
| 273 | + table1Option: { | |
| 274 | + // legend: {}, | |
| 275 | + xAxis: {}, | |
| 276 | + yAxis: {}, | |
| 277 | + label: {}, | |
| 278 | + tooltip: {}, | |
| 279 | + series: [] | |
| 280 | + }, | |
| 281 | + mChart: null, | |
| 282 | + mChart1: null, | |
| 283 | + charZoomStart: 0, | |
| 284 | + charZoomEnd: 100, | |
| 285 | + chartInterval: 0, //更新图表统计图定时任务标识 | |
| 286 | + allSessionData: [], | |
| 287 | + visible: false, | |
| 288 | + wvpVisible: false, | |
| 289 | + serverConfig: {}, | |
| 290 | + wvpServerConfig: {}, | |
| 291 | + wvpServerVersion: {}, | |
| 292 | + mediaServer: new MediaServer(), | |
| 293 | + mediaServerChoose: null, | |
| 294 | + loadCount: 0, | |
| 295 | + mediaServerList: [] | |
| 296 | + }; | |
| 297 | + }, | |
| 298 | + mounted() { | |
| 299 | + this.initTable() | |
| 300 | + this.chartInterval = setInterval(this.updateData, 3000); | |
| 301 | + this.mediaServer.getOnlineMediaServerList((data) => { | |
| 302 | + this.mediaServerList = data.data; | |
| 303 | + if (this.mediaServerList && this.mediaServerList.length > 0) { | |
| 304 | + this.mediaServerChoose = this.mediaServerList[0].id | |
| 305 | + this.loadCount = this.mediaServerList[0].count; | |
| 306 | + this.updateData(); | |
| 307 | + } | |
| 308 | + }) | |
| 309 | + }, | |
| 310 | + destroyed() { | |
| 311 | + clearInterval(this.chartInterval); //释放定时任务 | |
| 312 | + }, | |
| 313 | + methods: { | |
| 314 | + chooseMediaChange: function (val) { | |
| 315 | + this.loadCount = 0 | |
| 316 | + this.initTable() | |
| 317 | + this.updateData(); | |
| 195 | 318 | }, |
| 196 | - destroyed() { | |
| 197 | - clearInterval(this.chartInterval); //释放定时任务 | |
| 319 | + updateData: function () { | |
| 320 | + this.getThreadsLoad(); | |
| 321 | + this.getLoadCount(); | |
| 322 | + this.getAllSession(); | |
| 198 | 323 | }, |
| 199 | - methods: { | |
| 200 | - chooseMediaChange: function (val) { | |
| 201 | - this.loadCount = 0 | |
| 202 | - this.initTable() | |
| 203 | - this.updateData(); | |
| 204 | - }, | |
| 205 | - updateData: function () { | |
| 206 | - this.getThreadsLoad(); | |
| 207 | - this.getLoadCount(); | |
| 208 | - this.getAllSession(); | |
| 209 | - }, | |
| 210 | - /** | |
| 211 | - * 获取线程状态 | |
| 212 | - */ | |
| 213 | - getThreadsLoad: function () { | |
| 214 | - let that = this; | |
| 215 | - if (that.mediaServerChoose != null) { | |
| 216 | - this.$axios({ | |
| 217 | - method: 'get', | |
| 218 | - url: '/zlm/' + that.mediaServerChoose +'/index/api/getThreadsLoad' | |
| 219 | - }).then(function (res) { | |
| 220 | - if (res.data.code == 0) { | |
| 221 | - that.tableOption.xAxis.data.push(new Date().toLocaleTimeString('chinese', { | |
| 222 | - hour12: false | |
| 223 | - })); | |
| 224 | - that.table1Option.xAxis.data.push(new Date().toLocaleTimeString('chinese', { | |
| 225 | - hour12: false | |
| 226 | - })); | |
| 324 | + /** | |
| 325 | + * 获取线程状态 | |
| 326 | + */ | |
| 327 | + getThreadsLoad: function () { | |
| 328 | + let that = this; | |
| 329 | + if (that.mediaServerChoose != null) { | |
| 330 | + this.$axios({ | |
| 331 | + method: 'get', | |
| 332 | + url: '/zlm/' + that.mediaServerChoose + '/index/api/getThreadsLoad' | |
| 333 | + }).then(function (res) { | |
| 334 | + if (res.data.code == 0) { | |
| 335 | + that.tableOption.xAxis.data.push(new Date().toLocaleTimeString('chinese', { | |
| 336 | + hour12: false | |
| 337 | + })); | |
| 338 | + that.table1Option.xAxis.data.push(new Date().toLocaleTimeString('chinese', { | |
| 339 | + hour12: false | |
| 340 | + })); | |
| 227 | 341 | |
| 228 | - for (var i = 0; i < res.data.data.length; i++) { | |
| 229 | - if (that.tableOption.series[i] === undefined) { | |
| 230 | - let data = { | |
| 231 | - data: [], | |
| 232 | - type: 'line' | |
| 233 | - }; | |
| 234 | - let data1 = { | |
| 235 | - data: [], | |
| 236 | - type: 'line' | |
| 237 | - }; | |
| 238 | - data.data.push(res.data.data[i].delay); | |
| 239 | - data1.data.push(res.data.data[i].load); | |
| 240 | - that.tableOption.series.push(data); | |
| 241 | - that.table1Option.series.push(data1); | |
| 242 | - } else { | |
| 243 | - that.tableOption.series[i].data.push(res.data.data[i].delay); | |
| 244 | - that.table1Option.series[i].data.push(res.data.data[i].load); | |
| 245 | - } | |
| 246 | - } | |
| 247 | - that.tableOption.dataZoom[0].start = that.charZoomStart; | |
| 248 | - that.tableOption.dataZoom[0].end = that.charZoomEnd; | |
| 249 | - that.table1Option.dataZoom[0].start = that.charZoomStart; | |
| 250 | - that.table1Option.dataZoom[0].end = that.charZoomEnd; | |
| 251 | - //that.myChart = echarts.init(document.getElementById('ThreadsLoad')); | |
| 252 | - that.myChart.setOption(that.tableOption, true); | |
| 253 | - // that.myChart1 = echarts.init(document.getElementById('WorkThreadsLoad')); | |
| 254 | - that.myChart1.setOption(that.table1Option, true); | |
| 255 | - } | |
| 256 | - }); | |
| 257 | - } | |
| 258 | - | |
| 259 | - }, | |
| 260 | - getLoadCount: function (){ | |
| 261 | - let that = this; | |
| 262 | - if (that.mediaServerChoose != null) { | |
| 263 | - that.mediaServer.getMediaServer(that.mediaServerChoose, (data)=>{ | |
| 264 | - if (data.code == 0) { | |
| 265 | - that.loadCount = data.data.count | |
| 342 | + for (var i = 0; i < res.data.data.length; i++) { | |
| 343 | + if (that.tableOption.series[i] === undefined) { | |
| 344 | + let data = { | |
| 345 | + data: [], | |
| 346 | + type: 'line' | |
| 347 | + }; | |
| 348 | + let data1 = { | |
| 349 | + data: [], | |
| 350 | + type: 'line' | |
| 351 | + }; | |
| 352 | + data.data.push(res.data.data[i].delay); | |
| 353 | + data1.data.push(res.data.data[i].load); | |
| 354 | + that.tableOption.series.push(data); | |
| 355 | + that.table1Option.series.push(data1); | |
| 356 | + } else { | |
| 357 | + that.tableOption.series[i].data.push(res.data.data[i].delay); | |
| 358 | + that.table1Option.series[i].data.push(res.data.data[i].load); | |
| 266 | 359 | } |
| 360 | + } | |
| 361 | + that.tableOption.dataZoom[0].start = that.charZoomStart; | |
| 362 | + that.tableOption.dataZoom[0].end = that.charZoomEnd; | |
| 363 | + that.table1Option.dataZoom[0].start = that.charZoomStart; | |
| 364 | + that.table1Option.dataZoom[0].end = that.charZoomEnd; | |
| 365 | + //that.myChart = echarts.init(document.getElementById('ThreadsLoad')); | |
| 366 | + that.myChart.setOption(that.tableOption, true); | |
| 367 | + // that.myChart1 = echarts.init(document.getElementById('WorkThreadsLoad')); | |
| 368 | + that.myChart1.setOption(that.table1Option, true); | |
| 369 | + that.$nextTick(() => { | |
| 370 | + that.myChart.resize() | |
| 371 | + that.myChart1.resize() | |
| 267 | 372 | }) |
| 268 | 373 | } |
| 269 | - }, | |
| 270 | - initTable: function () { | |
| 271 | - let that = this; | |
| 272 | - this.tableOption.xAxis = { | |
| 273 | - type: 'category', | |
| 274 | - data: [], // x轴数据 | |
| 275 | - name: '时间', // x轴名称 | |
| 276 | - // x轴名称样式 | |
| 277 | - nameTextStyle: { | |
| 278 | - fontWeight: 300, | |
| 279 | - fontSize: 15 | |
| 280 | - } | |
| 281 | - }; | |
| 282 | - this.tableOption.yAxis = { | |
| 283 | - type: 'value', | |
| 284 | - name: '延迟率', // y轴名称 | |
| 285 | - boundaryGap: [0, '100%'], | |
| 286 | - max: 100, | |
| 287 | - axisLabel: { | |
| 288 | - show: true, | |
| 289 | - interval: 'auto', | |
| 290 | - formatter: '{value} %' | |
| 291 | - }, | |
| 292 | - // y轴名称样式 | |
| 293 | - nameTextStyle: { | |
| 294 | - fontWeight: 300, | |
| 295 | - fontSize: 15 | |
| 296 | - } | |
| 297 | - }; | |
| 298 | - this.tableOption.dataZoom = [{ | |
| 299 | - show: true, | |
| 300 | - start: this.charZoomStart, | |
| 301 | - end: this.charZoomEnd | |
| 302 | - }]; | |
| 303 | - this.myChart = echarts.init(document.getElementById('ThreadsLoad')); | |
| 304 | - this.myChart.setOption(this.tableOption); | |
| 305 | - this.myChart.on('dataZoom', function (event) { | |
| 306 | - if (event.batch) { | |
| 307 | - that.charZoomStart = event.batch[0].start; | |
| 308 | - that.charZoomEnd = event.batch[0].end; | |
| 309 | - } else { | |
| 310 | - that.charZoomStart = event.start; | |
| 311 | - that.charZoomEnd = event.end; | |
| 312 | - } | |
| 313 | - }); | |
| 374 | + }); | |
| 375 | + } | |
| 314 | 376 | |
| 315 | - this.table1Option.xAxis = { | |
| 316 | - type: 'category', | |
| 317 | - data: [], // x轴数据 | |
| 318 | - name: '时间', // x轴名称 | |
| 319 | - // x轴名称样式 | |
| 320 | - nameTextStyle: { | |
| 321 | - fontWeight: 300, | |
| 322 | - fontSize: 15 | |
| 323 | - } | |
| 324 | - }; | |
| 325 | - this.table1Option.yAxis = { | |
| 326 | - type: 'value', | |
| 327 | - name: '负载率', // y轴名称 | |
| 328 | - boundaryGap: [0, '100%'], | |
| 329 | - max: 100, | |
| 330 | - axisLabel: { | |
| 331 | - show: true, | |
| 332 | - interval: 'auto', | |
| 333 | - formatter: '{value} %' | |
| 334 | - }, | |
| 335 | - // y轴名称样式 | |
| 336 | - nameTextStyle: { | |
| 337 | - fontWeight: 300, | |
| 338 | - fontSize: 15 | |
| 339 | - } | |
| 340 | - }; | |
| 341 | - this.table1Option.dataZoom = [{ | |
| 342 | - show: true, | |
| 343 | - start: this.charZoomStart, | |
| 344 | - end: this.charZoomEnd | |
| 345 | - }]; | |
| 346 | - this.myChart1 = echarts.init(document.getElementById('WorkThreadsLoad')); | |
| 347 | - this.myChart1.setOption(this.table1Option); | |
| 348 | - this.myChart1.on('dataZoom', function (event) { | |
| 349 | - if (event.batch) { | |
| 350 | - that.charZoomStart = event.batch[0].start; | |
| 351 | - that.charZoomEnd = event.batch[0].end; | |
| 352 | - } else { | |
| 353 | - that.charZoomStart = event.start; | |
| 354 | - that.charZoomEnd = event.end; | |
| 355 | - } | |
| 356 | - }); | |
| 377 | + }, | |
| 378 | + getLoadCount: function () { | |
| 379 | + let that = this; | |
| 380 | + if (that.mediaServerChoose != null) { | |
| 381 | + that.mediaServer.getMediaServer(that.mediaServerChoose, (data) => { | |
| 382 | + if (data.code == 0) { | |
| 383 | + that.loadCount = data.data.count | |
| 384 | + } | |
| 385 | + }) | |
| 386 | + } | |
| 387 | + }, | |
| 388 | + initTable: function () { | |
| 389 | + let that = this; | |
| 390 | + this.tableOption.xAxis = { | |
| 391 | + type: 'category', | |
| 392 | + data: [], // x轴数据 | |
| 393 | + name: '时间', // x轴名称 | |
| 394 | + // x轴名称样式 | |
| 395 | + nameTextStyle: { | |
| 396 | + fontWeight: 300, | |
| 397 | + fontSize: 15 | |
| 398 | + } | |
| 399 | + }; | |
| 400 | + this.tableOption.yAxis = { | |
| 401 | + type: 'value', | |
| 402 | + name: '延迟率', // y轴名称 | |
| 403 | + boundaryGap: [0, '100%'], | |
| 404 | + max: 100, | |
| 405 | + axisLabel: { | |
| 406 | + show: true, | |
| 407 | + interval: 'auto', | |
| 408 | + formatter: '{value} %' | |
| 357 | 409 | }, |
| 410 | + // y轴名称样式 | |
| 411 | + nameTextStyle: { | |
| 412 | + fontWeight: 300, | |
| 413 | + fontSize: 15 | |
| 414 | + } | |
| 415 | + }; | |
| 416 | + this.tableOption.dataZoom = [{ | |
| 417 | + show: true, | |
| 418 | + start: this.charZoomStart, | |
| 419 | + end: this.charZoomEnd | |
| 420 | + }]; | |
| 421 | + this.myChart = echarts.init(document.getElementById('ThreadsLoad')); | |
| 422 | + this.myChart.setOption(this.tableOption); | |
| 423 | + this.myChart.on('dataZoom', function (event) { | |
| 424 | + if (event.batch) { | |
| 425 | + that.charZoomStart = event.batch[0].start; | |
| 426 | + that.charZoomEnd = event.batch[0].end; | |
| 427 | + } else { | |
| 428 | + that.charZoomStart = event.start; | |
| 429 | + that.charZoomEnd = event.end; | |
| 430 | + } | |
| 431 | + }); | |
| 358 | 432 | |
| 359 | - getAllSession: function () { | |
| 360 | - let that = this; | |
| 361 | - that.allSessionData = []; | |
| 362 | - this.$axios({ | |
| 363 | - method: 'get', | |
| 364 | - url: '/zlm/' + that.mediaServerChoose +'/index/api/getAllSession' | |
| 365 | - }).then(function (res) { | |
| 366 | - res.data.data.forEach(item => { | |
| 367 | - let data = { | |
| 368 | - peer_ip: item.peer_ip, | |
| 369 | - local_ip: item.local_ip, | |
| 370 | - typeid: item.typeid, | |
| 371 | - id: item.id | |
| 372 | - }; | |
| 373 | - that.allSessionData.push(data); | |
| 374 | - }); | |
| 375 | - }); | |
| 433 | + this.table1Option.xAxis = { | |
| 434 | + type: 'category', | |
| 435 | + data: [], // x轴数据 | |
| 436 | + name: '时间', // x轴名称 | |
| 437 | + // x轴名称样式 | |
| 438 | + nameTextStyle: { | |
| 439 | + fontWeight: 300, | |
| 440 | + fontSize: 15 | |
| 441 | + } | |
| 442 | + }; | |
| 443 | + this.table1Option.yAxis = { | |
| 444 | + type: 'value', | |
| 445 | + name: '负载率', // y轴名称 | |
| 446 | + boundaryGap: [0, '100%'], | |
| 447 | + max: 100, | |
| 448 | + axisLabel: { | |
| 449 | + show: true, | |
| 450 | + interval: 'auto', | |
| 451 | + formatter: '{value} %' | |
| 376 | 452 | }, |
| 377 | - getServerConfig: function () { | |
| 378 | - let that = this; | |
| 379 | - this.$axios({ | |
| 380 | - method: 'get', | |
| 381 | - url: '/zlm/' + that.mediaServerChoose +'/index/api/getServerConfig' | |
| 382 | - }).then(function (res) { | |
| 383 | - let info = res.data.data[0]; | |
| 384 | - let serverInfo = {} | |
| 385 | - for (let i = 0; i < Object.keys(info).length; i++) { | |
| 386 | - let key = Object.keys(info)[i]; | |
| 387 | - let group = key.substring(0, key.indexOf(".")) | |
| 388 | - let itemKey = key.substring(key.indexOf(".") + 1) | |
| 389 | - if (!serverInfo[group]) serverInfo[group] = {} | |
| 390 | - serverInfo[group][itemKey] = info[key] | |
| 391 | - } | |
| 453 | + // y轴名称样式 | |
| 454 | + nameTextStyle: { | |
| 455 | + fontWeight: 300, | |
| 456 | + fontSize: 15 | |
| 457 | + } | |
| 458 | + }; | |
| 459 | + this.table1Option.dataZoom = [{ | |
| 460 | + show: true, | |
| 461 | + start: this.charZoomStart, | |
| 462 | + end: this.charZoomEnd | |
| 463 | + }]; | |
| 464 | + this.myChart1 = echarts.init(document.getElementById('WorkThreadsLoad')); | |
| 465 | + this.myChart1.setOption(this.table1Option); | |
| 466 | + this.myChart1.on('dataZoom', function (event) { | |
| 467 | + if (event.batch) { | |
| 468 | + that.charZoomStart = event.batch[0].start; | |
| 469 | + that.charZoomEnd = event.batch[0].end; | |
| 470 | + } else { | |
| 471 | + that.charZoomStart = event.start; | |
| 472 | + that.charZoomEnd = event.end; | |
| 473 | + } | |
| 474 | + }); | |
| 475 | + }, | |
| 392 | 476 | |
| 393 | - that.serverConfig = serverInfo; | |
| 394 | - that.visible = true; | |
| 395 | - }); | |
| 396 | - }, | |
| 397 | - getWVPServerConfig: function () { | |
| 398 | - let that = this; | |
| 399 | - this.$axios({ | |
| 400 | - method: 'get', | |
| 401 | - url: '/api/server/config' | |
| 402 | - }).then(function (res) { | |
| 403 | - console.log(res) | |
| 404 | - that.wvpServerConfig = res.data.data; | |
| 405 | - that.wvpVisible = true; | |
| 406 | - }); | |
| 407 | - this.$axios({ | |
| 408 | - method: 'get', | |
| 409 | - url: '/api/server/version' | |
| 410 | - }).then(function (res) { | |
| 411 | - console.log(res) | |
| 412 | - that.wvpServerVersion = res.data.data; | |
| 413 | - that.wvpVisible = true; | |
| 414 | - }); | |
| 415 | - }, | |
| 416 | - reStartServer: function () { | |
| 417 | - let that = this; | |
| 418 | - this.$confirm('此操作将重启媒体服务器, 是否继续?', '提示', { | |
| 419 | - confirmButtonText: '确定', | |
| 420 | - cancelButtonText: '取消', | |
| 421 | - type: 'warning' | |
| 422 | - }).then(() => { | |
| 423 | - let that = this; | |
| 424 | - this.$axios({ | |
| 425 | - method: 'get', | |
| 426 | - url: '/zlm/' + that.mediaServerChoose +'/index/api/restartServer' | |
| 427 | - }).then(function (res) { | |
| 428 | - that.getAllSession(); | |
| 429 | - if (res.data.code == 0) { | |
| 430 | - that.$message({ | |
| 431 | - type: 'success', | |
| 432 | - message: '操作完成' | |
| 433 | - }); | |
| 434 | - } | |
| 435 | - }); | |
| 436 | - }); | |
| 437 | - }, | |
| 438 | - deleteRow: function (index, tabledata) { | |
| 439 | - let that = this; | |
| 440 | - this.$confirm('此操作将断开该通信链路, 是否继续?', '提示', { | |
| 441 | - confirmButtonText: '确定', | |
| 442 | - cancelButtonText: '取消', | |
| 443 | - type: 'warning' | |
| 444 | - }) | |
| 445 | - .then(() => { | |
| 446 | - that.deleteSession(tabledata[index].id); | |
| 447 | - }) | |
| 448 | - .catch(() => { | |
| 449 | - console.log('id:' + JSON.stringify(tabledata[index])); | |
| 450 | - this.$message({ | |
| 451 | - type: 'info', | |
| 452 | - message: '已取消删除' | |
| 453 | - }); | |
| 454 | - }); | |
| 455 | - console.log(JSON.stringify(tabledata[index])); | |
| 456 | - }, | |
| 457 | - deleteSession: function (id) { | |
| 458 | - let that = this; | |
| 459 | - this.$axios({ | |
| 460 | - method: 'get', | |
| 461 | - url: '/zlm/' + that.mediaServerChoose +'/index/api/kick_session&id=' + id | |
| 462 | - }).then(function (res) { | |
| 463 | - that.getAllSession(); | |
| 464 | - that.$message({ | |
| 465 | - type: 'success', | |
| 466 | - message: '删除成功!' | |
| 467 | - }); | |
| 468 | - }); | |
| 469 | - }, | |
| 470 | - getNameFromKey: function(key) { | |
| 471 | - let nameData = { | |
| 472 | - "waitTrack": "等待编码信息", | |
| 473 | - "interfaceAuthenticationExcludes": "不进行鉴权的接口", | |
| 474 | - "playTimeout": "点播超时时间", | |
| 475 | - "autoApplyPlay": "自动点播", | |
| 476 | - "recordPushLive": "推流录像", | |
| 477 | - "redisConfig": "自动配置redis", | |
| 478 | - "thirdPartyGBIdReg": "stream信息正则", | |
| 479 | - "savePositionHistory": "保存轨迹信息", | |
| 480 | - "interfaceAuthentication": "接口鉴权", | |
| 481 | - "serverId": "服务ID", | |
| 482 | - "logInDatebase": "日志存储进数据库", | |
| 483 | - "seniorSdp": "扩展SDP", | |
| 484 | - "password": "密码", | |
| 485 | - "port": "端口号", | |
| 486 | - "keepaliveTimeOut": "心跳超时", | |
| 487 | - "domain": "国标域", | |
| 488 | - "ip": "IP地址", | |
| 489 | - "monitorIp": "监听IP", | |
| 490 | - "alarm": "存储报警信息", | |
| 491 | - "ptzSpeed": "云台控制速度", | |
| 492 | - "id": "国标ID", | |
| 493 | - "registerTimeInterval": "注册间隔", | |
| 494 | - "artifactId": "模块名称", | |
| 495 | - "version": "版本", | |
| 496 | - "project": "工程", | |
| 497 | - "git_Revision": "GIT修订版本", | |
| 498 | - "git_BRANCH": "GIT分支", | |
| 499 | - "git_URL": "GIT地址", | |
| 500 | - "build_DATE": "构建时间", | |
| 501 | - "create_By": "作者", | |
| 502 | - "git_Revision_SHORT": "GIT修订版本(短)", | |
| 503 | - "build_Jdk": "构建用JDK", | |
| 477 | + getAllSession: function () { | |
| 478 | + let that = this; | |
| 479 | + that.allSessionData = []; | |
| 480 | + this.$axios({ | |
| 481 | + method: 'get', | |
| 482 | + url: '/zlm/' + that.mediaServerChoose + '/index/api/getAllSession' | |
| 483 | + }).then(function (res) { | |
| 484 | + res.data.data.forEach(item => { | |
| 485 | + let data = { | |
| 486 | + peer_ip: item.peer_ip, | |
| 487 | + local_ip: item.local_ip, | |
| 488 | + typeid: item.typeid, | |
| 489 | + id: item.id | |
| 504 | 490 | }; |
| 505 | - console.log(key + ": " + nameData[key]) | |
| 491 | + that.allSessionData.push(data); | |
| 492 | + }); | |
| 493 | + }); | |
| 494 | + }, | |
| 495 | + getServerConfig: function () { | |
| 496 | + let that = this; | |
| 497 | + this.$axios({ | |
| 498 | + method: 'get', | |
| 499 | + url: '/zlm/' + that.mediaServerChoose + '/index/api/getServerConfig' | |
| 500 | + }).then(function (res) { | |
| 501 | + let info = res.data.data[0]; | |
| 502 | + let serverInfo = {} | |
| 503 | + for (let i = 0; i < Object.keys(info).length; i++) { | |
| 504 | + let key = Object.keys(info)[i]; | |
| 505 | + let group = key.substring(0, key.indexOf(".")) | |
| 506 | + let itemKey = key.substring(key.indexOf(".") + 1) | |
| 507 | + if (!serverInfo[group]) serverInfo[group] = {} | |
| 508 | + serverInfo[group][itemKey] = info[key] | |
| 509 | + } | |
| 506 | 510 | |
| 507 | - if (nameData[key]) { | |
| 508 | - return nameData[key] | |
| 509 | - }else { | |
| 510 | - return key; | |
| 511 | + that.serverConfig = serverInfo; | |
| 512 | + that.visible = true; | |
| 513 | + }); | |
| 514 | + }, | |
| 515 | + getWVPServerConfig: function () { | |
| 516 | + let that = this; | |
| 517 | + this.$axios({ | |
| 518 | + method: 'get', | |
| 519 | + url: '/api/server/config' | |
| 520 | + }).then(function (res) { | |
| 521 | + console.log(res) | |
| 522 | + that.wvpServerConfig = res.data.data; | |
| 523 | + that.wvpVisible = true; | |
| 524 | + }); | |
| 525 | + this.$axios({ | |
| 526 | + method: 'get', | |
| 527 | + url: '/api/server/version' | |
| 528 | + }).then(function (res) { | |
| 529 | + console.log(res) | |
| 530 | + that.wvpServerVersion = res.data.data; | |
| 531 | + that.wvpVisible = true; | |
| 532 | + }); | |
| 533 | + }, | |
| 534 | + reStartServer: function () { | |
| 535 | + let that = this; | |
| 536 | + this.$confirm('此操作将重启媒体服务器, 是否继续?', '提示', { | |
| 537 | + confirmButtonText: '确定', | |
| 538 | + cancelButtonText: '取消', | |
| 539 | + type: 'warning' | |
| 540 | + }).then(() => { | |
| 541 | + let that = this; | |
| 542 | + this.$axios({ | |
| 543 | + method: 'get', | |
| 544 | + url: '/zlm/' + that.mediaServerChoose + '/index/api/restartServer' | |
| 545 | + }).then(function (res) { | |
| 546 | + that.getAllSession(); | |
| 547 | + if (res.data.code == 0) { | |
| 548 | + that.$message({ | |
| 549 | + type: 'success', | |
| 550 | + message: '操作完成' | |
| 551 | + }); | |
| 511 | 552 | } |
| 512 | - }, | |
| 513 | - getMediaKeyNameFromKey: function(key) { | |
| 514 | - let nameData = { | |
| 515 | - "waitTrack": "等待编码信息", | |
| 516 | - "interfaceAuthenticationExcludes": "不进行鉴权的接口", | |
| 517 | - "playTimeout": "点播超时时间", | |
| 518 | - "autoApplyPlay": "自动点播", | |
| 519 | - "recordPushLive": "推流录像", | |
| 520 | - "redisConfig": "自动配置redis", | |
| 521 | - "thirdPartyGBIdReg": "stream信息正则", | |
| 522 | - "savePositionHistory": "保存轨迹信息", | |
| 523 | - "interfaceAuthentication": "接口鉴权", | |
| 524 | - "serverId": "服务ID", | |
| 525 | - "logInDatebase": "日志存储进数据库", | |
| 526 | - "seniorSdp": "扩展SDP", | |
| 527 | - "password": "密码", | |
| 528 | - "port": "端口号", | |
| 529 | - "keepaliveTimeOut": "心跳超时", | |
| 530 | - "domain": "国标域", | |
| 531 | - "ip": "IP地址", | |
| 532 | - "monitorIp": "监听IP", | |
| 533 | - "alarm": "存储报警信息", | |
| 534 | - "ptzSpeed": "云台控制速度", | |
| 535 | - "id": "国标ID", | |
| 536 | - "registerTimeInterval": "注册间隔", | |
| 537 | - "artifactId": "模块名称", | |
| 538 | - "version": "版本", | |
| 539 | - "project": "工程", | |
| 540 | - "git_Revision": "GIT修订版本", | |
| 541 | - "git_BRANCH": "GIT分支", | |
| 542 | - "git_URL": "GIT地址", | |
| 543 | - "build_DATE": "构建时间", | |
| 544 | - "create_By": "作者", | |
| 545 | - "git_Revision_SHORT": "GIT修订版本(短)", | |
| 546 | - "build_Jdk": "构建用JDK", | |
| 547 | - }; | |
| 548 | - console.log(key + ": " + nameData[key]) | |
| 553 | + }); | |
| 554 | + }); | |
| 555 | + }, | |
| 556 | + deleteRow: function (index, tabledata) { | |
| 557 | + let that = this; | |
| 558 | + this.$confirm('此操作将断开该通信链路, 是否继续?', '提示', { | |
| 559 | + confirmButtonText: '确定', | |
| 560 | + cancelButtonText: '取消', | |
| 561 | + type: 'warning' | |
| 562 | + }) | |
| 563 | + .then(() => { | |
| 564 | + that.deleteSession(tabledata[index].id); | |
| 565 | + }) | |
| 566 | + .catch(() => { | |
| 567 | + console.log('id:' + JSON.stringify(tabledata[index])); | |
| 568 | + this.$message({ | |
| 569 | + type: 'info', | |
| 570 | + message: '已取消删除' | |
| 571 | + }); | |
| 572 | + }); | |
| 573 | + console.log(JSON.stringify(tabledata[index])); | |
| 574 | + }, | |
| 575 | + deleteSession: function (id) { | |
| 576 | + let that = this; | |
| 577 | + this.$axios({ | |
| 578 | + method: 'get', | |
| 579 | + url: '/zlm/' + that.mediaServerChoose + '/index/api/kick_session&id=' + id | |
| 580 | + }).then(function (res) { | |
| 581 | + that.getAllSession(); | |
| 582 | + that.$message({ | |
| 583 | + type: 'success', | |
| 584 | + message: '删除成功!' | |
| 585 | + }); | |
| 586 | + }); | |
| 587 | + }, | |
| 588 | + getNameFromKey: function (key) { | |
| 589 | + let nameData = { | |
| 590 | + "waitTrack": "等待编码信息", | |
| 591 | + "interfaceAuthenticationExcludes": "不进行鉴权的接口", | |
| 592 | + "playTimeout": "点播超时时间", | |
| 593 | + "autoApplyPlay": "自动点播", | |
| 594 | + "recordPushLive": "推流录像", | |
| 595 | + "redisConfig": "自动配置redis", | |
| 596 | + "thirdPartyGBIdReg": "stream信息正则", | |
| 597 | + "savePositionHistory": "保存轨迹信息", | |
| 598 | + "interfaceAuthentication": "接口鉴权", | |
| 599 | + "serverId": "服务ID", | |
| 600 | + "logInDatebase": "日志存储进数据库", | |
| 601 | + "seniorSdp": "扩展SDP", | |
| 602 | + "password": "密码", | |
| 603 | + "port": "端口号", | |
| 604 | + "keepaliveTimeOut": "心跳超时", | |
| 605 | + "domain": "国标域", | |
| 606 | + "ip": "IP地址", | |
| 607 | + "monitorIp": "监听IP", | |
| 608 | + "alarm": "存储报警信息", | |
| 609 | + "ptzSpeed": "云台控制速度", | |
| 610 | + "id": "国标ID", | |
| 611 | + "registerTimeInterval": "注册间隔", | |
| 612 | + "artifactId": "模块名称", | |
| 613 | + "version": "版本", | |
| 614 | + "project": "工程", | |
| 615 | + "git_Revision": "GIT修订版本", | |
| 616 | + "git_BRANCH": "GIT分支", | |
| 617 | + "git_URL": "GIT地址", | |
| 618 | + "build_DATE": "构建时间", | |
| 619 | + "create_By": "作者", | |
| 620 | + "git_Revision_SHORT": "GIT修订版本(短)", | |
| 621 | + "build_Jdk": "构建用JDK", | |
| 622 | + }; | |
| 623 | + console.log(key + ": " + nameData[key]) | |
| 549 | 624 | |
| 550 | - if (nameData[key]) { | |
| 551 | - return nameData[key] | |
| 552 | - }else { | |
| 553 | - return key; | |
| 554 | - } | |
| 555 | - } | |
| 625 | + if (nameData[key]) { | |
| 626 | + return nameData[key] | |
| 627 | + } else { | |
| 628 | + return key; | |
| 629 | + } | |
| 630 | + }, | |
| 631 | + getMediaKeyNameFromKey: function (key) { | |
| 632 | + let nameData = { | |
| 633 | + "waitTrack": "等待编码信息", | |
| 634 | + "interfaceAuthenticationExcludes": "不进行鉴权的接口", | |
| 635 | + "playTimeout": "点播超时时间", | |
| 636 | + "autoApplyPlay": "自动点播", | |
| 637 | + "recordPushLive": "推流录像", | |
| 638 | + "redisConfig": "自动配置redis", | |
| 639 | + "thirdPartyGBIdReg": "stream信息正则", | |
| 640 | + "savePositionHistory": "保存轨迹信息", | |
| 641 | + "interfaceAuthentication": "接口鉴权", | |
| 642 | + "serverId": "服务ID", | |
| 643 | + "logInDatebase": "日志存储进数据库", | |
| 644 | + "seniorSdp": "扩展SDP", | |
| 645 | + "password": "密码", | |
| 646 | + "port": "端口号", | |
| 647 | + "keepaliveTimeOut": "心跳超时", | |
| 648 | + "domain": "国标域", | |
| 649 | + "ip": "IP地址", | |
| 650 | + "monitorIp": "监听IP", | |
| 651 | + "alarm": "存储报警信息", | |
| 652 | + "ptzSpeed": "云台控制速度", | |
| 653 | + "id": "国标ID", | |
| 654 | + "registerTimeInterval": "注册间隔", | |
| 655 | + "artifactId": "模块名称", | |
| 656 | + "version": "版本", | |
| 657 | + "project": "工程", | |
| 658 | + "git_Revision": "GIT修订版本", | |
| 659 | + "git_BRANCH": "GIT分支", | |
| 660 | + "git_URL": "GIT地址", | |
| 661 | + "build_DATE": "构建时间", | |
| 662 | + "create_By": "作者", | |
| 663 | + "git_Revision_SHORT": "GIT修订版本(短)", | |
| 664 | + "build_Jdk": "构建用JDK", | |
| 665 | + }; | |
| 666 | + console.log(key + ": " + nameData[key]) | |
| 667 | + | |
| 668 | + if (nameData[key]) { | |
| 669 | + return nameData[key] | |
| 670 | + } else { | |
| 671 | + return key; | |
| 672 | + } | |
| 556 | 673 | } |
| 674 | + } | |
| 557 | 675 | }; |
| 558 | 676 | </script> |
| 559 | 677 | |
| 560 | 678 | <style> |
| 561 | 679 | #app { |
| 562 | - height: 100%; | |
| 680 | + height: 100%; | |
| 563 | 681 | } |
| 564 | 682 | |
| 565 | 683 | .control-table { |
| 566 | - background-color: #ffffff; | |
| 567 | - height: 25rem; | |
| 684 | + background-color: #ffffff; | |
| 685 | + height: 25rem; | |
| 568 | 686 | } |
| 569 | 687 | |
| 570 | 688 | .table-c { |
| 571 | - border-right: 1px solid #dcdcdc; | |
| 572 | - border-bottom: 1px solid #dcdcdc; | |
| 689 | + border-right: 1px solid #dcdcdc; | |
| 690 | + border-bottom: 1px solid #dcdcdc; | |
| 573 | 691 | } |
| 574 | 692 | |
| 575 | 693 | .table-c td { |
| 576 | - border-left: 1px solid #dcdcdc; | |
| 577 | - border-top: 1px solid #dcdcdc; | |
| 578 | - padding: 0.2rem; | |
| 694 | + border-left: 1px solid #dcdcdc; | |
| 695 | + border-top: 1px solid #dcdcdc; | |
| 696 | + padding: 0.2rem; | |
| 579 | 697 | } |
| 580 | 698 | |
| 581 | 699 | .el-table { |
| 582 | - width: 99.9% !important; | |
| 700 | + width: 99.9% !important; | |
| 583 | 701 | } |
| 584 | 702 | </style> | ... | ... |
web_src/src/components/devicePosition.vue
| 1 | 1 | <template> |
| 2 | 2 | <div id="devicePosition" style="height: 100%"> |
| 3 | - <el-container style="height: 100%"> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: 500">设备定位 ({{ parentChannelId == 0 ? deviceId : parentChannelId }})</span> | |
| 10 | - </div> | |
| 11 | - <div style="background-color: #ffffff; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left; font-size: 14px;"> | |
| 12 | - <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem" type="primary" @click="showDevice">返回</el-button> | |
| 13 | - <!-- <span class="demonstration">从</span> --> | |
| 14 | - <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> | |
| 15 | - <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> | |
| 16 | - <el-button-group> | |
| 17 | - <el-button icon="el-icon-search" size="mini" type="primary" @click="showHistoryPath">历史轨迹</el-button> | |
| 18 | - <el-button icon="el-icon-search" size="mini" style="margin-right: 1rem" type="primary" @click="showLatestPosition">最新位置</el-button> | |
| 19 | - </el-button-group> | |
| 20 | - <el-tag style="width: 5rem; text-align: center" size="medium">过期时间</el-tag> | |
| 21 | - <el-input-number size="mini" v-model="expired" :min="300" :controls="false" style="width: 4rem;"></el-input-number> | |
| 22 | - <el-tag style="width: 5rem; text-align: center" size="medium">上报周期</el-tag> | |
| 23 | - <el-input-number size="mini" v-model="interval" :min="1" :controls="false" style="width: 4rem;"></el-input-number> | |
| 24 | - <el-button-group> | |
| 25 | - <el-button icon="el-icon-search" size="mini" type="primary" @click="subscribeMobilePosition">位置订阅</el-button> | |
| 26 | - <el-button icon="el-icon-search" size="mini" type="primary" @click="unSubscribeMobilePosition">取消订阅</el-button> | |
| 27 | - </el-button-group> | |
| 28 | - <el-checkbox size="mini" style="margin-right: 1rem; float: right" v-model="autoList" @change="autoListChange" >自动刷新</el-checkbox> | |
| 29 | - </div> | |
| 30 | - <div class="mapContainer" style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center; height: calc(100% - 10rem);"> | |
| 31 | - <div class="baidumap" id="allmap"></div> | |
| 32 | - </div> | |
| 33 | - </el-main> | |
| 34 | - </el-container> | |
| 3 | + <div style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> | |
| 4 | + <span style="font-size: 1rem; font-weight: 500">设备定位 ({{ parentChannelId == 0 ? deviceId : parentChannelId }})</span> | |
| 5 | + </div> | |
| 6 | + <div style="background-color: #ffffff; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left; font-size: 14px;"> | |
| 7 | + <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem" type="primary" @click="showDevice">返回</el-button> | |
| 8 | + <!-- <span class="demonstration">从</span> --> | |
| 9 | + <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> | |
| 10 | + <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> | |
| 11 | + <el-button-group> | |
| 12 | + <el-button icon="el-icon-search" size="mini" type="primary" @click="showHistoryPath">历史轨迹</el-button> | |
| 13 | + <el-button icon="el-icon-search" size="mini" style="margin-right: 1rem" type="primary" @click="showLatestPosition">最新位置</el-button> | |
| 14 | + </el-button-group> | |
| 15 | + <el-tag style="width: 5rem; text-align: center" size="medium">过期时间</el-tag> | |
| 16 | + <el-input-number size="mini" v-model="expired" :min="300" :controls="false" style="width: 4rem;"></el-input-number> | |
| 17 | + <el-tag style="width: 5rem; text-align: center" size="medium">上报周期</el-tag> | |
| 18 | + <el-input-number size="mini" v-model="interval" :min="1" :controls="false" style="width: 4rem;"></el-input-number> | |
| 19 | + <el-button-group> | |
| 20 | + <el-button icon="el-icon-search" size="mini" type="primary" @click="subscribeMobilePosition">位置订阅</el-button> | |
| 21 | + <el-button icon="el-icon-search" size="mini" type="primary" @click="unSubscribeMobilePosition">取消订阅</el-button> | |
| 22 | + </el-button-group> | |
| 23 | + <el-checkbox size="mini" style="margin-right: 1rem; float: right" v-model="autoList" @change="autoListChange" >自动刷新</el-checkbox> | |
| 24 | + </div> | |
| 25 | + <div class="mapContainer" style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center; height: calc(100% - 10rem);"> | |
| 26 | + <div class="baidumap" id="allmap"></div> | |
| 27 | + </div> | |
| 35 | 28 | </div> |
| 36 | 29 | </template> |
| 37 | 30 | |
| 38 | 31 | <script> |
| 39 | -import uiHeader from "./UiHeader.vue"; | |
| 40 | -import moment from "moment"; | |
| 32 | +import uiHeader from "../layout/UiHeader.vue"; | |
| 41 | 33 | import geoTools from "./GeoConvertTools.js"; |
| 42 | 34 | export default { |
| 43 | 35 | name: "devicePosition", |
| ... | ... | @@ -173,7 +165,7 @@ export default { |
| 173 | 165 | let self = this; |
| 174 | 166 | this.$axios({ |
| 175 | 167 | method: 'get', |
| 176 | - url:`/api/position/history/${this.deviceId}`, | |
| 168 | + url:`/api/position/history/${this.deviceId}`, | |
| 177 | 169 | params: { |
| 178 | 170 | start: self.startTime, |
| 179 | 171 | end: self.endTime, |
| ... | ... | @@ -259,7 +251,7 @@ export default { |
| 259 | 251 | }, |
| 260 | 252 | toGBString: function (dateTime) { |
| 261 | 253 | return ( |
| 262 | - dateTime.getFullYear() + | |
| 254 | + dateTime.getFullYear() + | |
| 263 | 255 | "-" + this.twoDigits(dateTime.getMonth() + 1) + |
| 264 | 256 | "-" + this.twoDigits(dateTime.getDate()) + |
| 265 | 257 | "T" + this.twoDigits(dateTime.getHours()) + | ... | ... |
web_src/src/components/live.vue
| 1 | 1 | <template> |
| 2 | - <div id="devicePosition" style="height: 100%"> | |
| 3 | - <el-container style="height: 100%"> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-container v-loading="loading" element-loading-text="拼命加载中" style="margin: 0 20px;"> | |
| 8 | - <el-aside width="300px" style="background-color: #ffffff"> | |
| 9 | - <div style="text-align: center;padding-top: 20px;">设备列表</div> | |
| 10 | - <el-menu v-loading="loading"> | |
| 11 | - <el-submenu v-for="device in deviceList" :key="device.deviceId" :index="device.deviceId" @click="sendDevicePush(item)"> | |
| 12 | - <template slot="title" > | |
| 13 | - <i class="el-icon-location-outline"></i> | |
| 14 | - {{device.name}} | |
| 15 | - </template> | |
| 16 | - <ChannelTree :device="device" @sendDevicePush="sendDevicePush"></ChannelTree> | |
| 17 | - </el-submenu> | |
| 18 | - </el-menu> | |
| 19 | - </el-aside> | |
| 20 | - <el-container> | |
| 21 | - <!-- <LivePlay></LivePlay> --> | |
| 22 | - <el-header height="40px" style="text-align: left;font-size: 17px;line-height: 40px;"> | |
| 23 | - 分屏: | |
| 24 | - <i class="el-icon-full-screen btn" :class="{active:spilt==1}" @click="spilt=1"/> | |
| 25 | - <i class="el-icon-menu btn" :class="{active:spilt==4}" @click="spilt=4"/> | |
| 26 | - <i class="el-icon-s-grid btn" :class="{active:spilt==9}" @click="spilt=9"/> | |
| 27 | - </el-header> | |
| 28 | - <el-main> | |
| 29 | - <div style="width: 100%;height: calc( 100vh - 110px );display: flex;flex-wrap: wrap;background-color: #000;"> | |
| 30 | - <div v-for="i in spilt" :key="i" class="play-box" | |
| 31 | - :style="liveStyle" :class="{redborder:playerIdx == (i-1)}" | |
| 32 | - @click="playerIdx = (i-1)" | |
| 33 | - > | |
| 34 | - <div v-if="!videoUrl[i-1]" style="color: #ffffff;font-size: 30px;font-weight: bold;">{{i}}</div> | |
| 35 | - <player v-else :ref="'player'+i" :videoUrl="videoUrl[i-1]" fluent autoplay :height="true" | |
| 36 | - :containerId="'player'+i" @screenshot="shot" @destroy="destroy"></player> | |
| 37 | - <!-- <player v-else ref="'player'+i" :idx="'player'+i" :visible.sync="showVideoDialog" :videoUrl="videoUrl[i-1]" :height="true" :hasAudio="hasAudio" fluent autoplay live ></player> --> | |
| 38 | - </div> | |
| 39 | - </div> | |
| 40 | - </el-main> | |
| 41 | - </el-container> | |
| 2 | + <div id="devicePosition" style="height: 100%;width: 100%"> | |
| 3 | + <el-container v-loading="loading" element-loading-text="拼命加载中"> | |
| 4 | + <el-aside width="300px" style="background-color: #ffffff"> | |
| 5 | + <div style="text-align: center;padding-top: 20px;">设备列表</div> | |
| 6 | + <el-menu v-loading="loading"> | |
| 7 | + <el-submenu v-for="device in deviceList" :key="device.deviceId" :index="device.deviceId" @click="sendDevicePush(item)"> | |
| 8 | + <template slot="title" > | |
| 9 | + <i class="el-icon-location-outline"></i> | |
| 10 | + {{device.name}} | |
| 11 | + </template> | |
| 12 | + <ChannelTree :device="device" @sendDevicePush="sendDevicePush"></ChannelTree> | |
| 13 | + </el-submenu> | |
| 14 | + </el-menu> | |
| 15 | + </el-aside> | |
| 16 | + <el-container> | |
| 17 | + <!-- <LivePlay></LivePlay> --> | |
| 18 | + <el-header height="40px" style="text-align: left;font-size: 17px;line-height: 40px;"> | |
| 19 | + 分屏: | |
| 20 | + <i class="el-icon-full-screen btn" :class="{active:spilt==1}" @click="spilt=1"/> | |
| 21 | + <i class="el-icon-menu btn" :class="{active:spilt==4}" @click="spilt=4"/> | |
| 22 | + <i class="el-icon-s-grid btn" :class="{active:spilt==9}" @click="spilt=9"/> | |
| 23 | + </el-header> | |
| 24 | + <el-main> | |
| 25 | + <div style="width: 100%;height: calc( 100vh - 150px );display: flex;flex-wrap: wrap;background-color: #000;"> | |
| 26 | + <div v-for="i in spilt" :key="i" class="play-box" | |
| 27 | + :style="liveStyle" :class="{redborder:playerIdx == (i-1)}" | |
| 28 | + @click="playerIdx = (i-1)" | |
| 29 | + > | |
| 30 | + <div v-if="!videoUrl[i-1]" style="color: #ffffff;font-size: 30px;font-weight: bold;">{{i}}</div> | |
| 31 | + <player v-else :ref="'player'+i" :videoUrl="videoUrl[i-1]" fluent autoplay :height="true" | |
| 32 | + :containerId="'player'+i" @screenshot="shot" @destroy="destroy"></player> | |
| 33 | + <!-- <player v-else ref="'player'+i" :idx="'player'+i" :visible.sync="showVideoDialog" :videoUrl="videoUrl[i-1]" :height="true" :hasAudio="hasAudio" fluent autoplay live ></player> --> | |
| 34 | + </div> | |
| 35 | + </div> | |
| 36 | + </el-main> | |
| 42 | 37 | </el-container> |
| 43 | 38 | </el-container> |
| 44 | 39 | </div> |
| 45 | 40 | </template> |
| 46 | 41 | |
| 47 | 42 | <script> |
| 48 | - import uiHeader from "./UiHeader.vue"; | |
| 43 | + import uiHeader from "../layout/UiHeader.vue"; | |
| 49 | 44 | import player from './dialog/jessibuca.vue' |
| 50 | 45 | import ChannelTree from './channelTree.vue' |
| 51 | 46 | ... | ... |
web_src/src/components/setting/Media.vue
web_src/src/components/setting/Sip.vue
web_src/src/components/setting/Web.vue
web_src/src/components/UiHeader.vue renamed to web_src/src/layout/UiHeader.vue
| 1 | 1 | <template> |
| 2 | - <div id="UiHeader"> | |
| 3 | - <el-menu router :default-active="activeIndex" menu-trigger="click" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" mode="horizontal"> | |
| 4 | - <el-menu-item index="/">控制台</el-menu-item> | |
| 5 | - <el-menu-item index="/live">实时监控</el-menu-item> | |
| 6 | - <el-menu-item index="/deviceList">国标设备</el-menu-item> | |
| 7 | - <el-menu-item index="/pushVideoList">推流列表</el-menu-item> | |
| 8 | - <el-menu-item index="/streamProxyList">拉流代理</el-menu-item> | |
| 9 | - <el-menu-item index="/cloudRecord">云端录像</el-menu-item> | |
| 10 | - <el-menu-item index="/mediaServerManger">节点管理</el-menu-item> | |
| 11 | - <el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item> | |
| 12 | - <el-menu-item @click="openDoc">在线文档</el-menu-item> | |
| 13 | -<!-- <el-submenu index="/setting">--> | |
| 14 | -<!-- <template slot="title">系统设置</template>--> | |
| 15 | -<!-- <el-menu-item index="/setting/web">WEB服务</el-menu-item>--> | |
| 16 | -<!-- <el-menu-item index="/setting/sip">国标服务</el-menu-item>--> | |
| 17 | -<!-- <el-menu-item index="/setting/media">媒体服务</el-menu-item>--> | |
| 18 | -<!-- </el-submenu>--> | |
| 19 | - <el-switch v-model="alarmNotify" active-text="报警信息推送" style="display: block float: right" @change="alarmNotifyChannge"></el-switch> | |
| 20 | -<!-- <el-menu-item style="float: right;" @click="loginout">退出</el-menu-item>--> | |
| 21 | - <el-submenu index="" style="float: right;" > | |
| 22 | - <template slot="title">欢迎,{{this.$cookies.get("session").username}}</template> | |
| 23 | - <el-menu-item @click="changePassword">修改密码</el-menu-item> | |
| 24 | - <el-menu-item @click="loginout">注销</el-menu-item> | |
| 25 | - </el-submenu> | |
| 26 | - </el-menu> | |
| 2 | + <div id="UiHeader"> | |
| 3 | + <el-menu router :default-active="activeIndex" menu-trigger="click" background-color="#545c64" text-color="#fff" | |
| 4 | + active-text-color="#ffd04b" mode="horizontal"> | |
| 5 | + <el-menu-item index="/control">控制台</el-menu-item> | |
| 6 | + <el-menu-item index="/live">实时监控</el-menu-item> | |
| 7 | + <el-menu-item index="/deviceList">国标设备</el-menu-item> | |
| 8 | + <el-menu-item index="/pushVideoList">推流列表</el-menu-item> | |
| 9 | + <el-menu-item index="/streamProxyList">拉流代理</el-menu-item> | |
| 10 | + <el-menu-item index="/cloudRecord">云端录像</el-menu-item> | |
| 11 | + <el-menu-item index="/mediaServerManger">节点管理</el-menu-item> | |
| 12 | + <el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item> | |
| 13 | + <el-menu-item @click="openDoc">在线文档</el-menu-item> | |
| 14 | + <!-- <el-submenu index="/setting">--> | |
| 15 | + <!-- <template slot="title">系统设置</template>--> | |
| 16 | + <!-- <el-menu-item index="/setting/web">WEB服务</el-menu-item>--> | |
| 17 | + <!-- <el-menu-item index="/setting/sip">国标服务</el-menu-item>--> | |
| 18 | + <!-- <el-menu-item index="/setting/media">媒体服务</el-menu-item>--> | |
| 19 | + <!-- </el-submenu>--> | |
| 20 | + <el-switch v-model="alarmNotify" active-text="报警信息推送" @change="alarmNotifyChannge"></el-switch> | |
| 21 | + <!-- <el-menu-item style="float: right;" @click="loginout">退出</el-menu-item>--> | |
| 22 | + <el-submenu index="" style="float: right;"> | |
| 23 | + <template slot="title">欢迎,{{ this.$cookies.get("session").username }}</template> | |
| 24 | + <el-menu-item @click="changePassword">修改密码</el-menu-item> | |
| 25 | + <el-menu-item @click="loginout">注销</el-menu-item> | |
| 26 | + </el-submenu> | |
| 27 | + </el-menu> | |
| 27 | 28 | <changePasswordDialog ref="changePasswordDialog"></changePasswordDialog> |
| 28 | - </div> | |
| 29 | + </div> | |
| 29 | 30 | </template> |
| 30 | 31 | |
| 31 | 32 | <script> |
| 32 | 33 | |
| 33 | -import changePasswordDialog from './dialog/changePassword.vue' | |
| 34 | +import changePasswordDialog from '../components/dialog/changePassword.vue' | |
| 35 | + | |
| 34 | 36 | export default { |
| 35 | - name: "UiHeader", | |
| 36 | - components: { Notification, changePasswordDialog }, | |
| 37 | - data() { | |
| 38 | - return { | |
| 39 | - alarmNotify: false, | |
| 40 | - sseSource: null, | |
| 41 | - activeIndex: this.$route.path, | |
| 42 | - }; | |
| 43 | - }, | |
| 44 | - created(){ | |
| 45 | - if (this.$route.path.startsWith("/channelList")){ | |
| 46 | - this.activeIndex = "/deviceList" | |
| 47 | - } | |
| 37 | + name: "UiHeader", | |
| 38 | + components: {Notification, changePasswordDialog}, | |
| 39 | + data() { | |
| 40 | + return { | |
| 41 | + alarmNotify: false, | |
| 42 | + sseSource: null, | |
| 43 | + activeIndex: this.$route.path, | |
| 44 | + }; | |
| 45 | + }, | |
| 46 | + created() { | |
| 47 | + if (this.$route.path.startsWith("/channelList")) { | |
| 48 | + this.activeIndex = "/deviceList" | |
| 49 | + } | |
| 48 | 50 | |
| 51 | + }, | |
| 52 | + mounted() { | |
| 53 | + window.addEventListener('beforeunload', e => this.beforeunloadHandler(e)) | |
| 54 | + // window.addEventListener('unload', e => this.unloadHandler(e)) | |
| 55 | + this.alarmNotify = this.getAlarmSwitchStatus() === "true"; | |
| 56 | + this.sseControl(); | |
| 57 | + }, | |
| 58 | + methods: { | |
| 59 | + loginout() { | |
| 60 | + this.$axios({ | |
| 61 | + method: 'get', | |
| 62 | + url: "/api/user/logout" | |
| 63 | + }).then((res) => { | |
| 64 | + // 删除cookie,回到登录页面 | |
| 65 | + this.$cookies.remove("session"); | |
| 66 | + this.$router.push('/login'); | |
| 67 | + this.sseSource.close(); | |
| 68 | + }).catch((error) => { | |
| 69 | + console.error("登出失败") | |
| 70 | + console.error(error) | |
| 71 | + }); | |
| 72 | + }, | |
| 73 | + changePassword() { | |
| 74 | + this.$refs.changePasswordDialog.openDialog() | |
| 49 | 75 | }, |
| 50 | - mounted() { | |
| 51 | - window.addEventListener('beforeunload', e => this.beforeunloadHandler(e)) | |
| 52 | - // window.addEventListener('unload', e => this.unloadHandler(e)) | |
| 53 | - this.alarmNotify = this.getAlarmSwitchStatus() === "true"; | |
| 54 | - this.sseControl(); | |
| 76 | + openDoc() { | |
| 77 | + console.log(process.env.BASE_API) | |
| 78 | + window.open(!!process.env.BASE_API ? process.env.BASE_API + "/doc.html" : "/doc.html") | |
| 55 | 79 | }, |
| 56 | - methods:{ | |
| 57 | - loginout(){ | |
| 58 | - this.$axios({ | |
| 59 | - method: 'get', | |
| 60 | - url:"/api/user/logout" | |
| 61 | - }).then((res)=> { | |
| 62 | - // 删除cookie,回到登录页面 | |
| 63 | - this.$cookies.remove("session"); | |
| 64 | - this.$router.push('/login'); | |
| 65 | - this.sseSource.close(); | |
| 66 | - }).catch((error)=> { | |
| 67 | - console.error("登出失败") | |
| 68 | - console.error(error) | |
| 80 | + beforeunloadHandler() { | |
| 81 | + this.sseSource.close(); | |
| 82 | + }, | |
| 83 | + alarmNotifyChannge() { | |
| 84 | + this.setAlarmSwitchStatus() | |
| 85 | + this.sseControl() | |
| 86 | + }, | |
| 87 | + sseControl() { | |
| 88 | + let that = this; | |
| 89 | + if (this.alarmNotify) { | |
| 90 | + console.log("申请SSE推送API调用,浏览器ID: " + this.$browserId); | |
| 91 | + this.sseSource = new EventSource('/api/emit?browserId=' + this.$browserId); | |
| 92 | + this.sseSource.addEventListener('message', function (evt) { | |
| 93 | + that.$notify({ | |
| 94 | + title: '收到报警信息', | |
| 95 | + dangerouslyUseHTMLString: true, | |
| 96 | + message: evt.data, | |
| 97 | + type: 'warning' | |
| 69 | 98 | }); |
| 70 | - }, | |
| 71 | - changePassword(){ | |
| 72 | - this.$refs.changePasswordDialog.openDialog() | |
| 73 | - }, | |
| 74 | - openDoc(){ | |
| 75 | - console.log(process.env.BASE_API) | |
| 76 | - window.open( !!process.env.BASE_API? process.env.BASE_API + "/doc.html": "/doc.html") | |
| 77 | - }, | |
| 78 | - beforeunloadHandler() { | |
| 79 | - this.sseSource.close(); | |
| 80 | - }, | |
| 81 | - alarmNotifyChannge(){ | |
| 82 | - this.setAlarmSwitchStatus() | |
| 83 | - this.sseControl() | |
| 84 | - }, | |
| 85 | - sseControl() { | |
| 86 | - let that = this; | |
| 87 | - if (this.alarmNotify) { | |
| 88 | - console.log("申请SSE推送API调用,浏览器ID: " + this.$browserId); | |
| 89 | - this.sseSource = new EventSource('/api/emit?browserId=' + this.$browserId); | |
| 90 | - this.sseSource.addEventListener('message', function(evt) { | |
| 91 | - that.$notify({ | |
| 92 | - title: '收到报警信息', | |
| 93 | - dangerouslyUseHTMLString: true, | |
| 94 | - message: evt.data, | |
| 95 | - type: 'warning' | |
| 96 | - }); | |
| 97 | - console.log("收到信息:" + evt.data); | |
| 98 | - }); | |
| 99 | - this.sseSource.addEventListener('open', function(e) { | |
| 100 | - console.log("SSE连接打开."); | |
| 101 | - }, false); | |
| 102 | - this.sseSource.addEventListener('error', function(e) { | |
| 103 | - if (e.target.readyState == EventSource.CLOSED) { | |
| 104 | - console.log("SSE连接关闭"); | |
| 105 | - } else { | |
| 106 | - console.log(e.target.readyState); | |
| 107 | - } | |
| 108 | - }, false); | |
| 109 | - } else { | |
| 110 | - if (this.sseSource != null) { | |
| 111 | - this.sseSource.removeEventListener('open', null); | |
| 112 | - this.sseSource.removeEventListener('message', null); | |
| 113 | - this.sseSource.removeEventListener('error', null); | |
| 114 | - this.sseSource.close(); | |
| 115 | - } | |
| 116 | - | |
| 117 | - } | |
| 118 | - }, | |
| 119 | - getAlarmSwitchStatus(){ | |
| 120 | - if (localStorage.getItem("alarmSwitchStatus") == null) { | |
| 121 | - localStorage.setItem("alarmSwitchStatus", false); | |
| 99 | + console.log("收到信息:" + evt.data); | |
| 100 | + }); | |
| 101 | + this.sseSource.addEventListener('open', function (e) { | |
| 102 | + console.log("SSE连接打开."); | |
| 103 | + }, false); | |
| 104 | + this.sseSource.addEventListener('error', function (e) { | |
| 105 | + if (e.target.readyState == EventSource.CLOSED) { | |
| 106 | + console.log("SSE连接关闭"); | |
| 107 | + } else { | |
| 108 | + console.log(e.target.readyState); | |
| 122 | 109 | } |
| 123 | - return localStorage.getItem("alarmSwitchStatus"); | |
| 124 | - }, | |
| 125 | - setAlarmSwitchStatus(){ | |
| 126 | - localStorage.setItem("alarmSwitchStatus", this.alarmNotify); | |
| 127 | - } | |
| 128 | - }, | |
| 129 | - destroyed() { | |
| 130 | - window.removeEventListener('beforeunload', e => this.beforeunloadHandler(e)) | |
| 110 | + }, false); | |
| 111 | + } else { | |
| 131 | 112 | if (this.sseSource != null) { |
| 132 | 113 | this.sseSource.removeEventListener('open', null); |
| 133 | 114 | this.sseSource.removeEventListener('message', null); |
| 134 | 115 | this.sseSource.removeEventListener('error', null); |
| 135 | 116 | this.sseSource.close(); |
| 136 | 117 | } |
| 118 | + | |
| 119 | + } | |
| 120 | + }, | |
| 121 | + getAlarmSwitchStatus() { | |
| 122 | + if (localStorage.getItem("alarmSwitchStatus") == null) { | |
| 123 | + localStorage.setItem("alarmSwitchStatus", false); | |
| 124 | + } | |
| 125 | + return localStorage.getItem("alarmSwitchStatus"); | |
| 137 | 126 | }, |
| 127 | + setAlarmSwitchStatus() { | |
| 128 | + localStorage.setItem("alarmSwitchStatus", this.alarmNotify); | |
| 129 | + } | |
| 130 | + }, | |
| 131 | + destroyed() { | |
| 132 | + window.removeEventListener('beforeunload', e => this.beforeunloadHandler(e)) | |
| 133 | + if (this.sseSource != null) { | |
| 134 | + this.sseSource.removeEventListener('open', null); | |
| 135 | + this.sseSource.removeEventListener('message', null); | |
| 136 | + this.sseSource.removeEventListener('error', null); | |
| 137 | + this.sseSource.close(); | |
| 138 | + } | |
| 139 | + }, | |
| 138 | 140 | |
| 139 | - } | |
| 141 | +} | |
| 140 | 142 | |
| 141 | 143 | </script> |
| 144 | +<style> | |
| 145 | +#UiHeader .el-switch__label { | |
| 146 | + color: white; | |
| 147 | +} | |
| 148 | +#UiHeader .el-switch__label.is-active{ | |
| 149 | + color: #409EFF; | |
| 150 | +} | |
| 151 | +</style> | ... | ... |
web_src/src/layout/index.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <el-container style="height: 100%"> | |
| 3 | + <el-header> | |
| 4 | + <ui-header/> | |
| 5 | + </el-header> | |
| 6 | + <el-main> | |
| 7 | + <el-container> | |
| 8 | + <transition name="fade"> | |
| 9 | + <router-view></router-view> | |
| 10 | + </transition> | |
| 11 | + </el-container> | |
| 12 | + </el-main> | |
| 13 | + </el-container> | |
| 14 | +</template> | |
| 15 | + | |
| 16 | +<script> | |
| 17 | +import uiHeader from "./UiHeader.vue"; | |
| 18 | + | |
| 19 | +export default { | |
| 20 | + name: "index", | |
| 21 | + components: { | |
| 22 | + uiHeader | |
| 23 | + }, | |
| 24 | +} | |
| 25 | +</script> | |
| 26 | +<style> | |
| 27 | +/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ | |
| 28 | +::-webkit-scrollbar { | |
| 29 | + width: 8px; | |
| 30 | + height: 8px; | |
| 31 | +} | |
| 32 | + | |
| 33 | +/*定义滚动条轨道 内阴影+圆角*/ | |
| 34 | +::-webkit-scrollbar-track { | |
| 35 | + border-radius: 4px; | |
| 36 | + background-color: #F5F5F5; | |
| 37 | +} | |
| 38 | + | |
| 39 | +/*定义滑块 内阴影+圆角*/ | |
| 40 | +::-webkit-scrollbar-thumb { | |
| 41 | + border-radius: 4px; | |
| 42 | + background-color: #c8c8c8; | |
| 43 | + box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); | |
| 44 | + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); | |
| 45 | +} | |
| 46 | + | |
| 47 | +/*定义标题栏*/ | |
| 48 | +.page-header { | |
| 49 | + background-color: #FFFFFF; | |
| 50 | + margin-bottom: 1rem; | |
| 51 | + padding: 0.5rem; | |
| 52 | + display: flex; | |
| 53 | + justify-content: space-between; | |
| 54 | + align-items: center; | |
| 55 | +} | |
| 56 | + | |
| 57 | +.page-title { | |
| 58 | + font-weight: bold; | |
| 59 | + text-align: left; | |
| 60 | +} | |
| 61 | + | |
| 62 | +.page-header-btn { | |
| 63 | + text-align: right; | |
| 64 | +} | |
| 65 | +</style> | |
| 66 | +<style scoped> | |
| 67 | +.el-main { | |
| 68 | + margin: 0; | |
| 69 | +} | |
| 70 | + | |
| 71 | +.fade-enter { | |
| 72 | + visibility: hidden; | |
| 73 | + opacity: 0; | |
| 74 | +} | |
| 75 | + | |
| 76 | +.fade-leave-to { | |
| 77 | + display: none; | |
| 78 | +} | |
| 79 | + | |
| 80 | +.fade-enter-active, | |
| 81 | +.fade-leave-active { | |
| 82 | + transition: opacity .5s ease; | |
| 83 | +} | |
| 84 | + | |
| 85 | +.fade-enter-to, | |
| 86 | +.fade-leave { | |
| 87 | + visibility: visible; | |
| 88 | + opacity: 1; | |
| 89 | +} | |
| 90 | +</style> | ... | ... |
web_src/src/router/index.js
| 1 | 1 | import Vue from 'vue' |
| 2 | 2 | import VueRouter from 'vue-router' |
| 3 | +import Layout from "../layout/index.vue" | |
| 3 | 4 | |
| 4 | 5 | import control from '../components/control.vue' |
| 5 | 6 | import deviceList from '../components/DeviceList.vue' |
| ... | ... | @@ -32,78 +33,86 @@ export default new VueRouter({ |
| 32 | 33 | routes: [ |
| 33 | 34 | { |
| 34 | 35 | path: '/', |
| 35 | - component: control, | |
| 36 | - }, | |
| 37 | - { | |
| 38 | - path: '/live', | |
| 39 | - component: live, | |
| 40 | - }, | |
| 41 | - { | |
| 42 | - path: '/deviceList', | |
| 43 | - component: deviceList, | |
| 44 | - }, | |
| 45 | - { | |
| 46 | - path: '/pushVideoList', | |
| 47 | - component: pushVideoList, | |
| 48 | - }, | |
| 49 | - { | |
| 50 | - path: '/streamProxyList', | |
| 51 | - component: streamProxyList, | |
| 36 | + name: 'home', | |
| 37 | + component: Layout, | |
| 38 | + redirect: '/control', | |
| 39 | + children: [ | |
| 40 | + { | |
| 41 | + path: '/control', | |
| 42 | + component: control, | |
| 43 | + }, | |
| 44 | + { | |
| 45 | + path: '/live', | |
| 46 | + component: live, | |
| 47 | + }, | |
| 48 | + { | |
| 49 | + path: '/deviceList', | |
| 50 | + component: deviceList, | |
| 51 | + }, | |
| 52 | + { | |
| 53 | + path: '/pushVideoList', | |
| 54 | + component: pushVideoList, | |
| 55 | + }, | |
| 56 | + { | |
| 57 | + path: '/streamProxyList', | |
| 58 | + component: streamProxyList, | |
| 59 | + }, | |
| 60 | + { | |
| 61 | + path: '/channelList/:deviceId/:parentChannelId/:count/:page', | |
| 62 | + name: 'channelList', | |
| 63 | + component: channelList, | |
| 64 | + }, | |
| 65 | + { | |
| 66 | + path: '/parentPlatformList/:count/:page', | |
| 67 | + name: 'parentPlatformList', | |
| 68 | + component: parentPlatformList, | |
| 69 | + }, | |
| 70 | + { | |
| 71 | + path: '/devicePosition/:deviceId/:parentChannelId/:count/:page', | |
| 72 | + name: 'devicePosition', | |
| 73 | + component: devicePosition, | |
| 74 | + }, | |
| 75 | + { | |
| 76 | + path: '/cloudRecord', | |
| 77 | + name: 'cloudRecord', | |
| 78 | + component: cloudRecord, | |
| 79 | + }, | |
| 80 | + { | |
| 81 | + path: '/mediaServerManger', | |
| 82 | + name: 'mediaServerManger', | |
| 83 | + component: mediaServerManger, | |
| 84 | + }, | |
| 85 | + { | |
| 86 | + path: '/setting/web', | |
| 87 | + name: 'web', | |
| 88 | + component: web, | |
| 89 | + }, | |
| 90 | + { | |
| 91 | + path: '/setting/sip', | |
| 92 | + name: 'sip', | |
| 93 | + component: sip, | |
| 94 | + }, | |
| 95 | + { | |
| 96 | + path: '/setting/media', | |
| 97 | + name: 'media', | |
| 98 | + component: media, | |
| 99 | + }, | |
| 100 | + { | |
| 101 | + path: '/play/wasm/:url', | |
| 102 | + name: 'wasmPlayer', | |
| 103 | + component: wasmPlayer, | |
| 104 | + }, | |
| 105 | + { | |
| 106 | + path: '/play/rtc/:url', | |
| 107 | + name: 'rtcPlayer', | |
| 108 | + component: rtcPlayer, | |
| 109 | + }, | |
| 110 | + ] | |
| 52 | 111 | }, |
| 53 | 112 | { |
| 54 | 113 | path: '/login', |
| 55 | 114 | name: '登录', |
| 56 | 115 | component: login, |
| 57 | 116 | }, |
| 58 | - { | |
| 59 | - path: '/channelList/:deviceId/:parentChannelId/:count/:page', | |
| 60 | - name: 'channelList', | |
| 61 | - component: channelList, | |
| 62 | - }, | |
| 63 | - { | |
| 64 | - path: '/parentPlatformList/:count/:page', | |
| 65 | - name: 'parentPlatformList', | |
| 66 | - component: parentPlatformList, | |
| 67 | - }, | |
| 68 | - { | |
| 69 | - path: '/devicePosition/:deviceId/:parentChannelId/:count/:page', | |
| 70 | - name: 'devicePosition', | |
| 71 | - component: devicePosition, | |
| 72 | - }, | |
| 73 | - { | |
| 74 | - path: '/cloudRecord', | |
| 75 | - name: 'cloudRecord', | |
| 76 | - component: cloudRecord, | |
| 77 | - }, | |
| 78 | - { | |
| 79 | - path: '/mediaServerManger', | |
| 80 | - name: 'mediaServerManger', | |
| 81 | - component: mediaServerManger, | |
| 82 | - }, | |
| 83 | - { | |
| 84 | - path: '/setting/web', | |
| 85 | - name: 'web', | |
| 86 | - component: web, | |
| 87 | - }, | |
| 88 | - { | |
| 89 | - path: '/setting/sip', | |
| 90 | - name: 'sip', | |
| 91 | - component: sip, | |
| 92 | - }, | |
| 93 | - { | |
| 94 | - path: '/setting/media', | |
| 95 | - name: 'media', | |
| 96 | - component: media, | |
| 97 | - }, | |
| 98 | - { | |
| 99 | - path: '/play/wasm/:url', | |
| 100 | - name: 'wasmPlayer', | |
| 101 | - component: wasmPlayer, | |
| 102 | - }, | |
| 103 | - { | |
| 104 | - path: '/play/rtc/:url', | |
| 105 | - name: 'rtcPlayer', | |
| 106 | - component: rtcPlayer, | |
| 107 | - }, | |
| 108 | 117 | ] |
| 109 | 118 | }) | ... | ... |