平安校园
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

242 linhas
7.1 KiB

  1. <template>
  2. <div class="fullscreen-container">
  3. <myHeader place="1" ref="myHeaderRef" @getClassRoomInfo="getClassRoomInfo"></myHeader>
  4. <div style="position: absolute; width: 100%; display: flex; justify-content: space-between; top: 102px">
  5. <img style="width: 846px" src="/static/screen/img/header-aside-left.png" alt="" />
  6. <img style="width: 845px" src="/static/screen/img/header-aside-right.png" alt="" />
  7. </div>
  8. <main v-if="ready">
  9. <div class="main-top">
  10. <div class="tearchBox myborder">
  11. <div class="headimgBox">
  12. <div class="imgBox">
  13. <img src="/static/screen/testimg/7.png" alt="" />
  14. </div>
  15. <div class="title">{{ classRoom.teacher }}老师</div>
  16. <div class="status" :style="{ backgroundColor: classRoom.isClassing ? '#11ca2e' : '#b1b3b8' }">
  17. {{ classRoom.isClassing ? "正在上课" : "未上课" }}
  18. </div>
  19. <!-- <img class="setting" src="/static/screen/img/setting.png" alt="" /> -->
  20. </div>
  21. <div class="classTime">
  22. <div>
  23. <div>上课时间</div>
  24. <div class="time">{{ classRoom.classTime }}</div>
  25. </div>
  26. <div>
  27. <div>下课时间</div>
  28. <div class="time">{{ classRoom.classBreakTime }}</div>
  29. </div>
  30. </div>
  31. </div>
  32. <div class="video">
  33. <!-- <img style="width: 100%; height: 100%" src="/static/screen/testimg/3.png" alt="" /> -->
  34. <iframe :src="rtsUrl" frameborder="0" style="width: 100%; height: 100%"></iframe>
  35. </div>
  36. <div class="stuEnterList myborder">
  37. <stuEnterList ref="stuEnterListRef" :screenData="screenData"></stuEnterList>
  38. </div>
  39. </div>
  40. <div class="main-bottom">
  41. <div class="classStatistics myborder">
  42. <classStatistics ref="classStatisticsRef" :screenData="screenData"></classStatistics>
  43. </div>
  44. <div class="classNotice myborder">
  45. <classNotice ref="classNoticeRef" :screenData="screenData"></classNotice>
  46. </div>
  47. <div class="classAnalysis myborder">
  48. <classAnalysis ref="classAnalysisRef" :screenData="screenData" />
  49. </div>
  50. </div>
  51. </main>
  52. </div>
  53. </template>
  54. <script setup>
  55. import myHeader from "./component/header.vue";
  56. import stuEnterList from "./component/classroom/stuEnterList.vue";
  57. import classNotice from "./component/classroom/classNotice.vue";
  58. import classAnalysis from "./component/classroom/classAnalysis.vue";
  59. import classStatistics from "./component/classroom/classStatistics.vue";
  60. import { screenApi } from "@/api";
  61. const myHeaderRef = ref(null);
  62. const screenData = ref({});
  63. const classInfo = ref({});
  64. const ready = ref(false);
  65. const classRoom = ref({});
  66. const stuEnterListRef = ref(null);
  67. const classStatisticsRef = ref(null);
  68. const classNoticeRef = ref(null);
  69. const classAnalysisRef = ref(null);
  70. const getClassRoomInfo = obj => {
  71. if (obj) classInfo.value = obj;
  72. if (!timer) refresh(getClassRoomInfo, 60000);
  73. // 归寝人数信息
  74. return screenApi.getSmartClassroom({ personSetId: classInfo.value.value }).then(res => {
  75. if (res.code == 200) {
  76. screenData.value = res.data;
  77. classRoom.value = screenData.value.classRoom;
  78. let classTime = new Date(classRoom.value.classTime).valueOf();
  79. let classBreakTime = new Date(classRoom.value.classBreakTime).valueOf();
  80. let currTime = new Date().valueOf();
  81. if (currTime > classTime && currTime < classBreakTime) {
  82. classRoom.value.isClassing = true;
  83. }
  84. showRts(classRoom.value.cameraId);
  85. console.log(res.data);
  86. ready.value = true;
  87. nextTick(() => {
  88. stuEnterListRef.value.init();
  89. classStatisticsRef.value.init();
  90. classNoticeRef.value.init();
  91. classAnalysisRef.value.init();
  92. myHeaderRef.value.setBoder();
  93. });
  94. }
  95. });
  96. };
  97. // 定时刷新
  98. var timer = "";
  99. const refresh = (fn = () => {}, time = 5000) => {
  100. timer = setInterval(async () => {
  101. await fn();
  102. // stuEnterListRef.value.init();
  103. // classStatisticsRef.value.init();
  104. // classNoticeRef.value.init();
  105. // classAnalysisRef.value.init();
  106. }, time);
  107. };
  108. // 监控
  109. const streamId = ref("");
  110. const videoToken = ref("");
  111. const rtsUrl = ref("");
  112. const sensorId = ref("");
  113. const showRts = sensorId_ => {
  114. if (sensorId_) {
  115. if (sensorId.value == sensorId_) return;
  116. if (streamId.value) stopUrl();
  117. let rtsUrl_ = "/static/rtsPlayer.html?height=556px&rtsUrl=";
  118. sensorId.value = sensorId_;
  119. screenApi.detail({ sensorId: sensorId_ }).then(res => {
  120. // if (res.code == 200) {
  121. // if (res.data.rtsPullStreamUrls[0]) {
  122. // rtsUrl.value = rtsUrl_ + res.data.rtsPullStreamUrls[0].url;
  123. // }
  124. // streamId.value = res.data.streamId;
  125. // videoToken.value = res.data.videoToken;
  126. // }
  127. // 演示
  128. rtsUrl.value = rtsUrl_ + "http://123.57.209.16:8004/video/5.mp4";
  129. });
  130. }
  131. };
  132. const stopUrl = () => {
  133. if (!streamId.value) return;
  134. screenApi.stopUrl({
  135. sensorId: sensorId.value,
  136. streamId: streamId.value,
  137. videoToken: videoToken.value
  138. });
  139. };
  140. onUnmounted(() => {
  141. stopUrl();
  142. timer && clearInterval(timer);
  143. });
  144. </script>
  145. <style lang="scss" scoped>
  146. main {
  147. padding: 41px 53px 0px 58px;
  148. .main-top {
  149. height: 556px;
  150. display: flex;
  151. justify-content: space-between;
  152. > div {
  153. height: 100%;
  154. box-sizing: border-box;
  155. }
  156. .tearchBox {
  157. width: 208px;
  158. .headimgBox {
  159. box-sizing: border-box;
  160. border-bottom: 1px solid #2e84e5;
  161. height: 304px;
  162. text-align: center;
  163. position: relative;
  164. .setting {
  165. position: absolute;
  166. top: 37px;
  167. right: 24px;
  168. width: 25px;
  169. }
  170. .imgBox {
  171. margin-top: 83px;
  172. width: 87px;
  173. height: 87px;
  174. border-radius: 50%;
  175. overflow: hidden;
  176. display: inline-block;
  177. img {
  178. width: 100%;
  179. height: 100%;
  180. }
  181. }
  182. .title {
  183. color: #fff;
  184. font-size: 18px;
  185. margin-top: 16px;
  186. }
  187. .status {
  188. margin-top: 16px;
  189. display: inline-block;
  190. border-radius: 4px;
  191. width: 67px;
  192. height: 26px;
  193. color: #fff;
  194. font-size: 12px;
  195. line-height: 26px;
  196. }
  197. }
  198. .classTime {
  199. color: #78dfff;
  200. text-align: center;
  201. font-size: 14px;
  202. > div {
  203. margin-top: 50px;
  204. .time {
  205. margin-top: 11px;
  206. }
  207. }
  208. }
  209. }
  210. .video {
  211. width: 872px;
  212. }
  213. .stuEnterList {
  214. width: 1338px;
  215. padding: 35px 40px;
  216. }
  217. }
  218. .main-bottom {
  219. height: 652px;
  220. margin-top: 36px;
  221. display: flex;
  222. justify-content: space-between;
  223. > div {
  224. height: 100%;
  225. box-sizing: border-box;
  226. }
  227. .classStatistics {
  228. width: 579px;
  229. padding: 35px 37px;
  230. }
  231. .classNotice {
  232. width: 1095px;
  233. padding: 30px 40px;
  234. }
  235. .classAnalysis {
  236. width: 742px;
  237. padding: 30px 45px;
  238. }
  239. }
  240. }
  241. </style>