channelList.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  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>
  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. 搜索: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input>
  14. 通道类型: <el-select size="mini" @change="search" style="margin-right: 1rem;" v-model="channelType" placeholder="请选择" default-first-option>
  15. <el-option label="全部" value=""></el-option>
  16. <el-option label="设备" value="false"></el-option>
  17. <el-option label="子目录" value="true"></el-option>
  18. </el-select>
  19. 在线状态: <el-select size="mini" style="margin-right: 1rem;" @change="search" v-model="online" placeholder="请选择" default-first-option>
  20. <el-option label="全部" value=""></el-option>
  21. <el-option label="在线" value="true"></el-option>
  22. <el-option label="离线" value="false"></el-option>
  23. </el-select>
  24. <el-checkbox size="mini" style="margin-right: 1rem; float: right;" v-model="autoList" @change="autoListChange">自动刷新</el-checkbox>
  25. </div>
  26. <devicePlayer ref="devicePlayer" v-loading="isLoging"></devicePlayer>
  27. <!--设备列表-->
  28. <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%">
  29. <el-table-column prop="channelId" label="通道编号" width="210">
  30. </el-table-column>
  31. <el-table-column prop="channelId" label="设备编号" width="210">
  32. </el-table-column>
  33. <el-table-column prop="name" label="通道名称">
  34. </el-table-column>
  35. <el-table-column prop="subCount" label="子节点数">
  36. </el-table-column>
  37. <el-table-column label="开启音频" align="center">
  38. <template slot-scope="scope">
  39. <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF">
  40. </el-switch>
  41. </template>
  42. </el-table-column>
  43. <el-table-column label="状态" width="180" align="center">
  44. <template slot-scope="scope">
  45. <div slot="reference" class="name-wrapper">
  46. <el-tag size="medium" v-if="scope.row.status == 1">开启</el-tag>
  47. <el-tag size="medium" type="info" v-if="scope.row.status == 0">关闭</el-tag>
  48. </div>
  49. </template>
  50. </el-table-column>
  51. <el-table-column prop="ptztypeText" label="云台类型">
  52. </el-table-column>
  53. <el-table-column label="操作" width="280" align="center" fixed="right">
  54. <template slot-scope="scope">
  55. <el-button-group>
  56. <!-- <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">播放</el-button> -->
  57. <el-button size="mini" icon="el-icon-video-play" @click="sendDevicePush(scope.row)">播放</el-button>
  58. <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="!!scope.row.streamId" @click="stopDevicePush(scope.row)">停止</el-button>
  59. <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.parental == 1" @click="changeSubchannel(scope.row)">查看</el-button>
  60. <el-button size="mini" icon="el-icon-video-camera" type="primary" @click="queryRecords(scope.row)">设备录象</el-button>
  61. <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">录像查询</el-button> -->
  62. </el-button-group>
  63. </template>
  64. </el-table-column>
  65. </el-table>
  66. <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">
  67. </el-pagination>
  68. </el-main>
  69. </el-container>
  70. </div>
  71. </template>
  72. <script>
  73. import devicePlayer from './dialog/devicePlayer.vue'
  74. import uiHeader from './UiHeader.vue'
  75. import moment from "moment";
  76. export default {
  77. name: 'channelList',
  78. components: {
  79. devicePlayer,
  80. uiHeader
  81. },
  82. data() {
  83. return {
  84. deviceId: this.$route.params.deviceId,
  85. parentChannelId: this.$route.params.parentChannelId,
  86. deviceChannelList: [],
  87. videoComponentList: [],
  88. currentPlayerInfo: {}, //当前播放对象
  89. updateLooper: 0, //数据刷新轮训标志
  90. searchSrt: "",
  91. channelType: "",
  92. online: "",
  93. winHeight: window.innerHeight - 250,
  94. currentPage: parseInt(this.$route.params.page),
  95. count: parseInt(this.$route.params.count),
  96. total: 0,
  97. beforeUrl: "/deviceList",
  98. isLoging: false,
  99. autoList: true
  100. };
  101. },
  102. mounted() {
  103. this.initData();
  104. if (this.autoList) {
  105. this.updateLooper = setInterval(this.initData, 5000);
  106. }
  107. },
  108. destroyed() {
  109. this.$destroy('videojs');
  110. clearTimeout(this.updateLooper);
  111. },
  112. methods: {
  113. initData: function () {
  114. if (this.parentChannelId == "" || this.parentChannelId == 0) {
  115. this.getDeviceChannelList();
  116. } else {
  117. this.showSubchannels();
  118. }
  119. },
  120. initParam: function () {
  121. this.deviceId = this.$route.params.deviceId;
  122. this.parentChannelId = this.$route.params.parentChannelId;
  123. this.currentPage = parseInt(this.$route.params.page);
  124. this.count = parseInt(this.$route.params.count);
  125. if (this.parentChannelId == "" || this.parentChannelId == 0) {
  126. this.beforeUrl = "/deviceList"
  127. }
  128. },
  129. currentChange: function (val) {
  130. var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}`
  131. console.log(url)
  132. this.$router.push(url).then(() => {
  133. this.initParam();
  134. this.initData();
  135. })
  136. },
  137. handleSizeChange: function (val) {
  138. var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1`
  139. this.$router.push(url).then(() => {
  140. this.initParam();
  141. this.initData();
  142. })
  143. },
  144. getDeviceChannelList: function () {
  145. let that = this;
  146. this.$axios({
  147. method: 'get',
  148. url: `/api/device/query/devices/${this.$route.params.deviceId}/channels`,
  149. params:{
  150. page: that.currentPage,
  151. count: that.count,
  152. query: that.searchSrt,
  153. online: that.online,
  154. channelType: that.channelType
  155. }
  156. }).then(function (res) {
  157. console.log(res);
  158. that.total = res.data.total;
  159. that.deviceChannelList = res.data.list;
  160. // 防止出现表格错位
  161. that.$nextTick(() => {
  162. that.$refs.channelListTable.doLayout();
  163. })
  164. }).catch(function (error) {
  165. console.log(error);
  166. });
  167. },
  168. //通知设备上传媒体流
  169. sendDevicePush: function (itemData) {
  170. console.log(itemData);
  171. let deviceId = this.deviceId;
  172. this.isLoging = true;
  173. let channelId = itemData.channelId;
  174. console.log("通知设备推流1:" + deviceId + " : " + channelId );
  175. let that = this;
  176. this.$axios({
  177. method: 'get',
  178. url: '/api/play/start/' + deviceId + '/' + channelId
  179. }).then(function (res) {
  180. console.log(res.data)
  181. let streamId = res.data.streamId;
  182. that.isLoging = false;
  183. if (!!streamId) {
  184. // that.$refs.devicePlayer.play(res.data, deviceId, channelId, itemData.hasAudio);
  185. that.$refs.devicePlayer.openDialog("media", deviceId, channelId, {
  186. streamInfo: res.data,
  187. hasAudio: itemData.hasAudio
  188. });
  189. that.initData();
  190. } else {
  191. that.$message.error(res.data);
  192. }
  193. }).catch(function (e) {});
  194. },
  195. queryRecords: function (itemData) {
  196. var format = moment().format("YYYY-M-D");
  197. let deviceId = this.deviceId;
  198. let channelId = itemData.channelId;
  199. this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format})
  200. },
  201. stopDevicePush: function (itemData) {
  202. console.log(itemData)
  203. var that = this;
  204. this.$axios({
  205. method: 'get',
  206. url: '/api/play/stop/' + itemData.streamId
  207. }).then(function (res) {
  208. console.log(JSON.stringify(res));
  209. that.initData();
  210. }).catch(function (error) {
  211. if (error.response.status == 402) { // 已经停止过
  212. that.initData();
  213. }else {
  214. console.log(error)
  215. }
  216. });
  217. },
  218. showDevice: function () {
  219. this.$router.push(this.beforeUrl).then(() => {
  220. this.initParam();
  221. this.initData();
  222. })
  223. },
  224. changeSubchannel(itemData) {
  225. console.log(this.$router.currentRoute)
  226. this.beforeUrl = this.$router.currentRoute.path;
  227. var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}/${this.$router.currentRoute.params.count}/1`
  228. this.$router.push(url).then(() => {
  229. this.searchSrt = "";
  230. this.channelType = "";
  231. this.online = "";
  232. this.initParam();
  233. this.initData();
  234. })
  235. },
  236. showSubchannels: function (channelId) {
  237. let that = this;
  238. this.$axios({
  239. method: 'get',
  240. url:`/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`,
  241. params: {
  242. page: that.currentPage,
  243. count: that.count,
  244. query: that.searchSrt,
  245. online: that.online,
  246. channelType: that.channelType
  247. }
  248. }).then(function (res) {
  249. that.total = res.data.total;
  250. that.deviceChannelList = res.data.list;
  251. // 防止出现表格错位
  252. that.$nextTick(() => {
  253. that.$refs.channelListTable.doLayout();
  254. })
  255. }).catch(function (error) {
  256. console.log(error);
  257. });
  258. },
  259. search: function () {
  260. console.log(this.searchSrt)
  261. this.currentPage = 1;
  262. this.total = 0;
  263. this.initData();
  264. },
  265. updateChannel: function (row) {
  266. console.log(row)
  267. this.$axios({
  268. method: 'post',
  269. url: `/api/device/query/channel/update/${this.deviceId}`,
  270. params: row
  271. }).then(function (res) {
  272. console.log(JSON.stringify(res));
  273. });
  274. },
  275. autoListChange: function () {
  276. if (this.autoList) {
  277. this.updateLooper = setInterval(this.initData, 1500);
  278. }else{
  279. window.clearInterval(this.updateLooper);
  280. }
  281. }
  282. }
  283. };
  284. </script>
  285. <style>
  286. .videoList {
  287. display: flex;
  288. flex-wrap: wrap;
  289. align-content: flex-start;
  290. }
  291. .video-item {
  292. position: relative;
  293. width: 15rem;
  294. height: 10rem;
  295. margin-right: 1rem;
  296. background-color: #000000;
  297. }
  298. .video-item-img {
  299. position: absolute;
  300. top: 0;
  301. bottom: 0;
  302. left: 0;
  303. right: 0;
  304. margin: auto;
  305. width: 100%;
  306. height: 100%;
  307. }
  308. .video-item-img:after {
  309. content: "";
  310. display: inline-block;
  311. position: absolute;
  312. z-index: 2;
  313. top: 0;
  314. bottom: 0;
  315. left: 0;
  316. right: 0;
  317. margin: auto;
  318. width: 3rem;
  319. height: 3rem;
  320. background-image: url("../assets/loading.png");
  321. background-size: cover;
  322. background-color: #000000;
  323. }
  324. .video-item-title {
  325. position: absolute;
  326. bottom: 0;
  327. color: #000000;
  328. background-color: #ffffff;
  329. line-height: 1.5rem;
  330. padding: 0.3rem;
  331. width: 14.4rem;
  332. }
  333. </style>