平安校园
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

747 lines
16 KiB

  1. <template>
  2. <view class="inspectionCenter">
  3. <view v-show="showVideo" class="poupBox">
  4. <view class="videoHeader">
  5. </view>
  6. <view class="contentBox">
  7. <view class="closeBox">
  8. <view class="title">
  9. {{sensorName+'(' + sensorId + ')'}}
  10. </view>
  11. <view class="closes" @click="closeDialog">
  12. <u-icon name="close-circle-fill" color="#ccc" size="22"></u-icon>
  13. </view>
  14. </view>
  15. <view class="botbox">
  16. <view id="url-player-test"></view>
  17. </view>
  18. </view>
  19. <view class="bottom-content">
  20. </view>
  21. </view>
  22. <view class="searchBox">
  23. <view class="searchLine">
  24. <view class="searchLabels" @click="showTree">
  25. <image v-show="isShowSearch==false" src="@/static/image/earlyWarning/group.png" mode="">
  26. </image>
  27. <image v-show="isShowSearch" src="@/static/image/earlyWarning/group2.png" mode="">
  28. </image>
  29. <text class="labels">选择分组</text>
  30. <view class="values">{{this.searchForm.groupName}}</view>
  31. </view>
  32. <view class="arrow">
  33. <image v-show="isShowSearch==false" src="@/static/image/earlyWarning/arrow1.png" mode="">
  34. </image>
  35. <image v-show="isShowSearch" src="@/static/image/earlyWarning/arrow2.png" mode=""></image>
  36. </view>
  37. </view>
  38. <view @click="isShowSearch=false" class="searchDialog" v-if="isShowSearch">
  39. <view class="content" @click.stop="isSelect">
  40. <u-row justify="space-between" gutter="10">
  41. <u-col span="7">
  42. <view class="demo-layout">
  43. <view class="left-layout">
  44. <text>{{'警告类型'}}</text>
  45. </view>
  46. <view class="right-layout">
  47. <image style="width: 30rpx;height:30rpx;"
  48. src="@/static/image/earlyWarning/arrowRight.png" mode=""></image>
  49. </view>
  50. </view>
  51. </u-col>
  52. <u-col span="5">
  53. <view class="demo-layout" @click="toOpenSelect">
  54. <view class="left-layout">
  55. <text>{{'处理状态'}}</text>
  56. </view>
  57. <view class="right-layout">
  58. <image style="width: 30rpx;height:30rpx;"
  59. src="@/static/image/earlyWarning/arrowRight.png" mode=""></image>
  60. </view>
  61. </view>
  62. </u-col>
  63. </u-row>
  64. <view class="btnBox">
  65. <view class="leftBtn" @click="clearform">
  66. 重置
  67. </view>
  68. <view class="rightBtn" @click="onsubmit">
  69. 确认
  70. </view>
  71. </view>
  72. </view>
  73. </view>
  74. </view>
  75. <view class="tableBox">
  76. <u-empty marginTop="100rpx" :show="monitorList.length == 0&&status == 'nomore'" mode="list" text="暂无数据"></u-empty>
  77. <u-list @scrolltolower="scrolltolower" style="height: calc(100% - 0rpx);">
  78. <u-list-item v-for="(item, index) in monitorList" :key="index">
  79. <view class="liBox">
  80. <view class="topCard">
  81. <view class="pic">
  82. <image :src="item.snapshotUrl" mode="aspectFill"></image>
  83. <view class="resolvingPower">
  84. {{item.resWidth}}*{{item.resHeight}}
  85. </view>
  86. </view>
  87. <view class="rightCard">
  88. <view class="firstCard">
  89. <view class="schoolName">
  90. 摄像头ID:{{item.sensorId}}
  91. </view>
  92. </view>
  93. <view class="secondCard">
  94. <view class="txt">
  95. 摄像头名称:{{item.sensorName}}
  96. </view>
  97. </view>
  98. <view class="thirdCard">
  99. <view class="txt">
  100. 设备IP:{{item.directUrlIp}}
  101. </view>
  102. </view>
  103. </view>
  104. </view>
  105. <view class="btoCard">
  106. <view class="leftBox btoBox">
  107. <image src="@/static/image/earlyWarning/school.png" mode=""></image>
  108. <view class="txt">
  109. 所属学校:演示学校
  110. </view>
  111. </view>
  112. <view class="rightBox btoBox" @click="startClick(item.sensorId,item.sensorName)">
  113. <view class="txt">
  114. 播放
  115. </view>
  116. </view>
  117. </view>
  118. </view>
  119. </u-list-item>
  120. <u-loadmore :status="status" />
  121. </u-list>
  122. </view>
  123. <!-- <web-view :webview-styles="styles" src="/hybrid/html/players.html"></web-view> -->
  124. <!-- <u-modal :show="showVideo" :title="videoTitle" :closeOnClickOverlay="false" :showCancelButton="true"
  125. @confirm="confirmVideo" @cancel="cancelVideo">
  126. <view class="slot-content">
  127. <cover-view style="width: 100%;height:500px">
  128. </cover-view>
  129. </view>
  130. </u-modal> -->
  131. <tki-tree ref="tkitree" title="摄像头分组" :showChild="showChild" :selectParent="selectParent" :multiple="multiple"
  132. :range="treelist" :foldAll="flod" rangeKey="name" @confirm="treeConfirm" @cancel="treeCancel"></tki-tree>
  133. </view>
  134. </template>
  135. <script>
  136. import tkiTree from '@/components/tki-tree/tki-tree.vue';
  137. import {
  138. groupList, //获取摄像头分组
  139. list, //获取摄像头列表
  140. startUrl, //说去视频地址
  141. stopUrl //停止视频流获取
  142. } from '@/api/monitor/index.js'
  143. export default {
  144. components: {
  145. tkiTree
  146. },
  147. data() {
  148. return {
  149. styles: {
  150. width: '100%',
  151. height: '100%',
  152. zIndex: '999999999999999999999999999'
  153. // bottom: '56px'
  154. },
  155. showVideo: false,
  156. videoTitle: '',
  157. isShowSearch: false,
  158. searchForm: {
  159. groupName: '全部',
  160. groupId: '',
  161. pageNum: 1,
  162. pageSize: 10
  163. },
  164. monitorList: [],
  165. isLoading: false,
  166. status: 'loadmore', //loading正在加载 loadmore加载更多 nomore没有更多了
  167. treelist: [],
  168. multiple: false, //是否多选
  169. selectParent: true, //父级可选择
  170. flod: false, //折叠
  171. showChild: true,
  172. player: null,
  173. sensorId: '',
  174. sensorName: '',
  175. videoUrl: '',
  176. streamId: '',
  177. videoToken: '',
  178. }
  179. },
  180. watch: {
  181. },
  182. mounted() {
  183. },
  184. onLoad() {
  185. this.getGroupList()
  186. // 获取列表数据
  187. this.loadmore()
  188. },
  189. onUnload() {
  190. if(this.showVideo) {
  191. this.closeDialog()
  192. }
  193. },
  194. onPullDownRefresh() {
  195. uni.stopPullDownRefresh()
  196. this.status = 'loadmore'
  197. this.searchForm.pageNum = 1;
  198. this.monitorList = []
  199. this.loadmore()
  200. },
  201. methods: {
  202. setVideo() {
  203. let that = this;
  204. this.loadWebPlayerSDK().then(() => {
  205. // 如果需要使用自定义组件,打开以下注释
  206. // this.loadComponent().then(() => {
  207. this.player = new Aliplayer({
  208. id: "url-player-test",
  209. source: this.videoUrl + "&subaudio=no&jitterbuffer=6000",
  210. width: "100%",
  211. height: "100%",
  212. isLive: true,
  213. rtsFallback: true,
  214. rtsFallbackType: 'HLS',
  215. }, function(player) {
  216. player.mute()
  217. });
  218. this.player.one('canplay', function() {
  219. // console.log('canplay', this.player.tag);
  220. that.player.tag.play();
  221. });
  222. // }).catch((e) => { console.log("加载组件失败", e) })
  223. }).catch((e) => {
  224. console.log("加载播放器SDK失败", e);
  225. });
  226. },
  227. closeDialog() {
  228. if (this.player) {
  229. this.player.dispose();
  230. }
  231. this.showVideo = false;
  232. let params = {
  233. sensorId: this.sensorId,
  234. streamId: this.streamId,
  235. videoToken: this.videoToken
  236. };
  237. stopUrl(params).then(res => {
  238. })
  239. },
  240. loadWebPlayerSDK() {
  241. return new Promise((resolve, reject) => {
  242. const s_tag = document.createElement('script'); // 引入播放器js
  243. s_tag.type = 'text/javascript';
  244. s_tag.src = 'https://g.alicdn.com/apsara-media-box/imp-web-player/2.25.1/aliplayer-min.js'
  245. // s_tag.src = 'https://g.alicdn.com/apsara-media-box/imp-web-player/2.20.3/aliplayer-min.js';
  246. s_tag.charset = 'utf-8';
  247. s_tag.onload = () => {
  248. resolve();
  249. }
  250. document.body.appendChild(s_tag);
  251. const l_tag = document.createElement('link'); // 引入播放器css
  252. l_tag.rel = 'stylesheet';
  253. l_tag.href =
  254. 'https://g.alicdn.com/apsara-media-box/imp-web-player/2.25.1/skins/default/aliplayer-min.css'
  255. // 'https://g.alicdn.com/apsara-media-box/imp-web-player/2.20.3/skins/default/aliplayer-min.css';
  256. document.body.appendChild(l_tag);
  257. });
  258. },
  259. loadComponent() {
  260. return new Promise((resolve, reject) => {
  261. const s_tag = document.createElement('script');
  262. s_tag.type = 'text/javascript';
  263. // 需要先下载组件 js 文件,放到项目 /static/ 目录下
  264. // 下载地址:https://github.com/aliyunvideo/AliyunPlayer_Web/blob/master/customComponents/dist/aliplayer-components/aliplayercomponents-1.0.9.min.js
  265. s_tag.src = './static/aliplayercomponents-1.0.9.min.js';
  266. s_tag.charset = 'utf-8';
  267. s_tag.onload = () => {
  268. resolve();
  269. }
  270. document.body.appendChild(s_tag);
  271. });
  272. },
  273. addAttribute(data) { // tree结构递归添加属性
  274. for (var i = 0; i < data.length; i++) {
  275. data[i].isShow = false
  276. data[i].name = data[i].title
  277. if (data[i].children && data[i].children.length > 0) {
  278. this.addAttribute(data[i].children)
  279. }
  280. }
  281. return data
  282. },
  283. // 确定回调事件
  284. treeConfirm(e) {
  285. this.searchForm.groupName = e[0].name;
  286. this.searchForm.groupId = e[0].id;
  287. this.status = 'loadmore'
  288. this.searchForm.pageNum = 1;
  289. this.monitorList = []
  290. this.loadmore()
  291. },
  292. // 取消回调事件
  293. treeCancel(e) {
  294. // console.log(e)
  295. },
  296. // 显示树形选择器
  297. showTree() {
  298. this.$refs.tkitree._show();
  299. },
  300. cancelVideo() {
  301. this.showVideo = false;
  302. },
  303. getGroupList() {
  304. groupList({}).then((res) => {
  305. if (res.code == 200) {
  306. this.treelist = [...[{
  307. id: "",
  308. name: "全部",
  309. checked: true
  310. }], ...res.data];
  311. }
  312. });
  313. },
  314. // 获取视频地址
  315. startClick(id,name) {
  316. this.sensorId = id;
  317. this.sensorName = name;
  318. this.showVideo = true;
  319. startUrl({
  320. sensorId: id
  321. }).then(res => {
  322. let {
  323. code,
  324. data
  325. } = res;
  326. if (code == 200) {
  327. this.videoUrl = data.rtsPullStreamUrls[0].url;
  328. this.streamId = data.streamId;
  329. this.videoToken = data.videoToken;
  330. this.setVideo()
  331. }
  332. })
  333. },
  334. confirmVideo() {
  335. this.showVideo = false;
  336. },
  337. isSelect() {
  338. },
  339. scrolltolower() {
  340. if (this.status == 'loading' || this.status == 'nomore') {
  341. return;
  342. }
  343. this.searchForm.pageNum += 1;
  344. this.loadmore()
  345. },
  346. loadmore() {
  347. if (this.status != 'loadmore') return
  348. this.status = 'loading'
  349. this.isLoading = true;
  350. list(this.searchForm).then(res => {
  351. if (res?.code === 200) {
  352. this.monitorList = [...this.monitorList, ...res?.data?.list];
  353. this.isLoading = false;
  354. // 获取到的总条数>=接口总条数
  355. if (this.monitorList.length >= res.data.total) {
  356. this.status = 'nomore'
  357. } else {
  358. this.status = 'loadmore'
  359. }
  360. }
  361. })
  362. }
  363. }
  364. }
  365. </script>
  366. <style lang="scss" scoped>
  367. .container {
  368. padding: 20px;
  369. font-size: 14px;
  370. height: 800px;
  371. }
  372. // .contentBox {
  373. // height: calc(100% - 375rpx);
  374. .inspectionCenter {
  375. width: 100%;
  376. height: calc(100% - 88rpx);
  377. position: relative;
  378. .u-modal__title {
  379. color: #000000;
  380. }
  381. .poupBox {
  382. height: 100vh;
  383. position: absolute;
  384. left: 0;
  385. top: 0;
  386. width: 100%;
  387. z-index: 100000000000000;
  388. // background: red;
  389. background: rgba(0, 0, 0, 0.5);
  390. .videoHeader {
  391. height: 255rpx;
  392. }
  393. .contentBox {
  394. // z-index: 1000000;
  395. width: 100%;
  396. height: 590rpx;
  397. background: #000;
  398. // margin: 50rpx auto;
  399. .closeBox {
  400. text-align: right;
  401. height: 80rpx;
  402. display: flex;
  403. justify-content: space-between;
  404. align-items: center;
  405. padding: 0 25rpx;
  406. background: #fff;
  407. .title {
  408. font-weight: 700;
  409. font-size: 28rpx;
  410. }
  411. .closes {
  412. // background: #ccc;
  413. }
  414. }
  415. .botbox {
  416. height:calc(100% - 80rpx);
  417. }
  418. }
  419. .bottom-content {
  420. height: calc(100% - 590rpx -255rpx);
  421. }
  422. }
  423. }
  424. .searchBox {
  425. // height: calc(100% - 360rpx);
  426. position: relative;
  427. .searchLine {
  428. height: 88rpx;
  429. display: flex;
  430. align-items: center;
  431. justify-content: space-between;
  432. padding: 0 15px;
  433. box-sizing: border-box;
  434. background: #fff;
  435. font-size: 28rpx;
  436. .searchLabels {
  437. display: flex;
  438. align-items: center;
  439. width: calc(100% - 34rpx);
  440. image {
  441. width: 40rpx;
  442. height: 40rpx;
  443. flex-shrink: 1;
  444. }
  445. .labels {
  446. width: 120rpx;
  447. display: block;
  448. color: #333333;
  449. margin-left: 10rpx;
  450. flex-shrink: 1;
  451. }
  452. .values {
  453. width: calc(100% - 40rpx - 120rpx);
  454. color: #2388FF;
  455. font-weight: 700;
  456. margin-left: 18rpx;
  457. overflow: hidden;
  458. word-wrap: break-word;
  459. white-space: pre-wrap;
  460. display: -webkit-box;
  461. -webkit-box-orient: vertical;
  462. -webkit-line-clamp: 1;
  463. }
  464. }
  465. .arrow {
  466. // text-align: right;
  467. // flex-shrink: 1;
  468. image {
  469. width: 34rpx;
  470. height: 34rpx;
  471. }
  472. }
  473. .leftSearchBox {
  474. display: flex;
  475. align-items: center;
  476. width: calc(100% - 40px);
  477. .searchLabel {
  478. flex-shrink: 1;
  479. color: #333333;
  480. width: 80px;
  481. }
  482. .searchValue {
  483. width: calc(100% - 60px);
  484. margin-left: 10px;
  485. color: #2388FF;
  486. overflow: hidden;
  487. word-wrap: break-word;
  488. white-space: pre-wrap;
  489. display: -webkit-box;
  490. -webkit-box-orient: vertical;
  491. -webkit-line-clamp: 1;
  492. }
  493. }
  494. }
  495. .searchDialog {
  496. position: absolute;
  497. z-index: 990;
  498. top: 89rpx;
  499. width: 100%;
  500. height: calc(100vh - 375rpx - 100rpx);
  501. font-size: 26rpx;
  502. background: rgba(0, 0, 0, 0.2);
  503. .content {
  504. background: #FFFFFF;
  505. padding: 15px;
  506. box-sizing: border-box;
  507. border-top: 1px solid rgba(0, 0, 0, 0.1);
  508. .demo-layout {
  509. height: 80rpx;
  510. border-radius: 8rpx;
  511. background: #F5F5F5;
  512. display: flex;
  513. justify-content: space-between;
  514. align-items: center;
  515. padding: 0 10px;
  516. box-sizing: border-box;
  517. .left-layout {
  518. color: #777777;
  519. }
  520. .right-layout {}
  521. .startBox {
  522. color: #777777;
  523. }
  524. text {
  525. color: #777777;
  526. }
  527. .endBox {
  528. color: #777777;
  529. }
  530. .timeIcon {}
  531. }
  532. }
  533. .btnBox {
  534. display: flex;
  535. align-items: center;
  536. margin-top: 15px;
  537. .leftBtn {
  538. width: 50%;
  539. height: 74rpx;
  540. line-height: 74rpx;
  541. border: 1px solid #BABABA;
  542. border-radius: 12rpx;
  543. color: #333333;
  544. text-align: center;
  545. }
  546. .rightBtn {
  547. width: 50%;
  548. height: 74rpx;
  549. line-height: 74rpx;
  550. border: 1px solid #2388FF;
  551. border-radius: 12rpx;
  552. color: #fff;
  553. text-align: center;
  554. background: #2388FF;
  555. margin-left: 15rpx;
  556. }
  557. }
  558. }
  559. }
  560. .tableBox {
  561. height: 100%;
  562. padding: 0 30rpx;
  563. box-sizing: border-box;
  564. .liBox {
  565. background: #fff;
  566. padding: 24rpx 30rpx;
  567. box-sizing: border-box;
  568. border-radius: 20rpx;
  569. margin-top: 30rpx;
  570. .topCard {
  571. display: flex;
  572. align-items: center;
  573. .pic {
  574. position: relative;
  575. width: 268rpx;
  576. height: 201rpx;
  577. image {
  578. width: 268rpx;
  579. height: 201rpx;
  580. border-radius: 4px;
  581. }
  582. .resolvingPower {
  583. position: absolute;
  584. top: 15rpx;
  585. right: 15rpx;
  586. background: #000000;
  587. color: #fff;
  588. padding: 8rpx;
  589. box-sizing: border-box;
  590. font-size: 20rpx;
  591. border-radius: 4rpx;
  592. font-family: 'PingFang SC';
  593. }
  594. }
  595. .rightCard {
  596. margin-left: 20rpx;
  597. .firstCard {
  598. display: flex;
  599. justify-content: space-between;
  600. align-items: center;
  601. margin-bottom: 60rpx;
  602. .schoolName {
  603. font-size: 32rpx;
  604. font-family: 'PingFang SC';
  605. font-weight: 700;
  606. color: #333333;
  607. overflow: hidden;
  608. word-wrap: break-word;
  609. white-space: pre-wrap;
  610. // font-size: 14px;
  611. display: -webkit-box;
  612. -webkit-box-orient: vertical;
  613. -webkit-line-clamp: 1;
  614. }
  615. }
  616. .secondCard,
  617. .thirdCard {
  618. display: flex;
  619. align-items: center;
  620. margin-top: 16rpx;
  621. .txt {
  622. font-size: 26rpx;
  623. font-family: 'PingFang SC';
  624. color: #333333;
  625. }
  626. }
  627. }
  628. }
  629. .btoCard {
  630. border-top: 1px solid rgba(0, 0, 0, 0.1);
  631. margin-top: 24rpx;
  632. padding: 24rpx 0 0 0;
  633. display: flex;
  634. justify-content: space-between;
  635. align-items: center;
  636. .btoBox {
  637. // width: 33.3%;
  638. display: flex;
  639. justify-content: center;
  640. align-items: center;
  641. position: relative;
  642. font-size: 26rpx;
  643. color: #333;
  644. font-family: 'PingFang SC';
  645. image {
  646. width: 36rpx;
  647. height: 36rpx;
  648. margin-right: 15rpx;
  649. }
  650. }
  651. .rightBox {
  652. width: 120rpx;
  653. height: 60rpx;
  654. background: #2388FF;
  655. color: #fff;
  656. border-radius: 80rpx;
  657. }
  658. }
  659. }
  660. }
  661. // }
  662. </style>