平安校园
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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