VideoCommunication.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <template>
  2. <div class="video-communication">
  3. <div class="part-box-head">
  4. <div class="part-box-head-left"><h1>通话申请列表</h1></div>
  5. <div class="part-box-head-right">
  6. <el-radio-group
  7. size="small"
  8. v-model="callStatus"
  9. @change="getCommunicationList"
  10. >
  11. <el-radio-button label="START">待处理</el-radio-button>
  12. <el-radio-button label="CANCEL">未接通话</el-radio-button>
  13. <el-radio-button label="STOP">已处理</el-radio-button>
  14. </el-radio-group>
  15. <el-button
  16. style="vertical-align: top; margin-left: 10px;"
  17. icon="el-icon-arrow-left"
  18. @click="goBack"
  19. >返回</el-button
  20. >
  21. </div>
  22. </div>
  23. <div class="student-list">
  24. <el-row :gutter="20">
  25. <el-col :md="6" :lg="6" :xl="4" v-for="item in students" :key="item.id">
  26. <div class="student-item">
  27. <div class="student-cover">
  28. <img
  29. :src="item.basePhotoPath"
  30. :alt="item.examStudentId"
  31. v-if="item.basePhotoPath"
  32. />
  33. <div class="avatar-default" v-else>
  34. <i class="el-icon-user-solid"></i>
  35. </div>
  36. </div>
  37. <h4 class="student-name">{{ item.examStudentName }}</h4>
  38. <div v-if="callStatus === 'START' || callStatus === 'CANCEL'">
  39. <el-button round type="success" @click="answer(item, 0)"
  40. >语音通话</el-button
  41. >
  42. <br />
  43. <el-button round type="primary" @click="answer(item, 1)"
  44. >视频通话</el-button
  45. >
  46. </div>
  47. <div class="student-call-info" v-else>
  48. <p>
  49. 通话时间段:
  50. <span>{{ item.startTime }} ~ </span>
  51. <span>{{ item.endTime }}</span>
  52. </p>
  53. <p v-if="item.durationTime">
  54. 持续时长约:{{ item.durationTime }}
  55. </p>
  56. </div>
  57. </div>
  58. </el-col>
  59. </el-row>
  60. </div>
  61. <div class="part-page">
  62. <el-pagination
  63. background
  64. layout="prev, pager, next,total,sizes,jumper"
  65. :current-page="current"
  66. :total="total"
  67. :page-size.sync="size"
  68. @size-change="toPage(1)"
  69. @current-change="toPage"
  70. >
  71. </el-pagination>
  72. </div>
  73. </div>
  74. </template>
  75. <script>
  76. import { communicationList } from "@/api/invigilation";
  77. import { formatDate, timeNumberToText } from "@/utils/utils";
  78. import timeMixin from "../../../mixins/timeMixin";
  79. export default {
  80. name: "VideoCommunication",
  81. mixins: [timeMixin],
  82. data() {
  83. return {
  84. examId: this.$route.params.examId,
  85. roomCode: this.$route.params.roomCode,
  86. callStatus: "START",
  87. students: [],
  88. current: 1,
  89. total: 0,
  90. size: 100,
  91. loopRunning: false,
  92. };
  93. },
  94. mounted() {
  95. const cachePageInfo = window.sessionStorage.getItem(
  96. "videoCommunicationCache"
  97. );
  98. if (cachePageInfo) {
  99. const { pageNumber, callStatus } = JSON.parse(cachePageInfo);
  100. this.pageNumber = pageNumber;
  101. this.callStatus = callStatus;
  102. window.sessionStorage.removeItem("videoCommunicationCache");
  103. }
  104. this.loopRunning = true;
  105. this.getCommunicationList();
  106. },
  107. methods: {
  108. async getCommunicationList() {
  109. if (!this.loopRunning) return;
  110. this.clearSetTs();
  111. this.students = [];
  112. const res = await communicationList({
  113. examId: this.examId,
  114. roomCode: this.roomCode,
  115. callStatus: this.callStatus,
  116. pageNumber: this.current,
  117. pageSize: this.size,
  118. }).catch(() => {});
  119. if (res) {
  120. this.students = res.data.data.records.map((item) => {
  121. item.durationTime = timeNumberToText(item.endTime - item.startTime);
  122. item.startTime = formatDate(
  123. "YYYY-MM-DD HH:mm:ss",
  124. new Date(item.startTime)
  125. );
  126. item.endTime = formatDate(
  127. "YYYY-MM-DD HH:mm:ss",
  128. new Date(item.endTime)
  129. );
  130. return item;
  131. });
  132. this.total = res.data.data.total;
  133. }
  134. // 当前页没有数据,同时当前页不是第一页,则自动跳到前一页。
  135. if (!this.students.length && this.current > 1) {
  136. this.current--;
  137. this.getCommunicationList();
  138. } else {
  139. this.addSetTime(() => {
  140. this.getCommunicationList();
  141. }, 5000);
  142. }
  143. },
  144. toPage(page) {
  145. this.current = page;
  146. this.getCommunicationList();
  147. },
  148. answer(student, isVideo) {
  149. window.sessionStorage.setItem(
  150. "autoAnswerInfo",
  151. JSON.stringify({ ...student, isVideo })
  152. );
  153. window.sessionStorage.setItem(
  154. "videoCommunicationCache",
  155. JSON.stringify({
  156. pageNumber: this.pageNumber,
  157. callStatus: this.callStatus,
  158. })
  159. );
  160. this.$router.push({
  161. name: "WarningDetail",
  162. params: {
  163. examRecordId: student.examRecordId,
  164. },
  165. });
  166. },
  167. goBack() {
  168. window.history.go(-1);
  169. },
  170. },
  171. beforeDestroy() {
  172. this.loopRunning = false;
  173. this.clearSetTs();
  174. },
  175. };
  176. </script>
  177. <style lang="scss" scoped>
  178. .student-list {
  179. .student-item {
  180. padding: 20px;
  181. background: #fff;
  182. border-radius: 10px;
  183. text-align: center;
  184. margin-bottom: 20px;
  185. .el-button {
  186. margin-bottom: 12px;
  187. }
  188. }
  189. .student-cover {
  190. height: 200px;
  191. border-radius: 6px;
  192. overflow: hidden;
  193. img {
  194. width: 100%;
  195. height: 100%;
  196. object-fit: contain;
  197. }
  198. }
  199. .student-name {
  200. margin: 20px 0;
  201. font-size: 18px;
  202. line-height: 25px;
  203. color: #202b4b;
  204. }
  205. .student-call-info {
  206. p {
  207. margin: 0;
  208. text-align: left;
  209. }
  210. }
  211. }
  212. </style>