<template>
  <div class="warning-detail">
    <div class="warning-detail-head">
      <h2>预警详情</h2>
      <el-button size="mini" icon="el-icon-arrow-left" @click="goBack"
        >返回列表</el-button
      >
      <!-- <el-button
          @click="initSubscribeVideo"
          type="primary"
          size="mini"
          icon="el-icon-arrow-left"
          >开始视频</el-button
        >
        <el-button
          @click="closeSubscribeVideo"
          type="danger"
          size="mini"
          icon="el-icon-arrow-left"
          >关闭视频</el-button
        > -->
    </div>

    <div class="warning-detail-body">
      <div class="detail-body-head">
        <div class="detail-body-head-left">
          <p>
            <i class="icon icon-person"></i>
            <span>{{ detailInfo.examStudentName }}</span>
          </p>
          <p>
            <span>证件号：</span><span>{{ detailInfo.identity }}</span>
          </p>
          <p>
            <span>科目（代码）：</span
            ><span>{{ detailInfo.courseNameCode }}</span>
          </p>
        </div>
        <div class="detail-body-head-right">
          <el-button
            type="primary"
            title="查看上一个"
            :disabled="holding"
            @click="changeStudent(0)"
          >
            <i class="icon icon-arrow-left"></i>
          </el-button>
          <el-button
            type="primary"
            title="查看下一个"
            :disabled="holding"
            @click="changeStudent(1)"
          >
            <i class="icon icon-arrow-right"></i>
          </el-button>
        </div>
      </div>
      <div class="warning-detail-main">
        <div class="warning-action">
          <div class="student-avatar">
            <img
              :src="detailInfo.basePhotoPath"
              :alt="detailInfo.examStudentName"
              v-if="detailInfo.basePhotoPath"
            />
            <div class="avatar-default" v-else>
              <i class="el-icon-user-solid"></i>
            </div>
            <div class="avatar-title">学生底照</div>
          </div>
          <div class="warning-summary">
            <div class="warning-summary-row">
              <p class="warning-summary-col">
                <i class="icon icon-bell"></i>
                <span class="line-name"
                  >系统预警
                  <em :class="{ 'color-danger': detailInfo.warningCount > 0 }"
                    >{{ detailInfo.warningCount }}次</em
                  ></span
                >
              </p>
              <p class="warning-summary-col">
                <i class="icon icon-face"></i>
                <span class="line-name"
                  >陌生人脸
                  <em>{{ detailInfo.multipleFaceCount }}次</em>
                </span>
              </p>
            </div>
            <div class="warning-summary-row">
              <p class="warning-summary-col">
                <i class="icon icon-info"></i>
                <span class="line-name"
                  >异常处理
                  <em>{{ detailInfo.exceptionCount }}次</em>
                </span>
              </p>
              <p class="warning-summary-col">
                <i class="icon icon-success"></i>
                <span class="line-name"
                  >违纪状态
                  <em :class="{ 'color-danger': isBreach }">
                    {{ isBreach ? "违纪" : "正常" }}</em
                  >
                </span>
              </p>
            </div>
            <div class="summary-bg">
              <div class="summary-bg-line"></div>
              <div class="summary-bg-line"></div>
              <div class="summary-bg-spin"></div>
              <div class="summary-bg-spin"></div>
              <div class="summary-bg-spin"></div>
              <div class="summary-bg-spin"></div>
            </div>
          </div>
          <div class="action-list">
            <div v-if="actionValid" class="action-item">
              <el-button
                icon="icon icon-text-message"
                size="mideum"
                @click="toSendTextMsg"
                >文字提醒</el-button
              >
            </div>
            <div v-if="actionValid" class="action-item">
              <el-button
                icon="icon icon-record"
                size="mideum"
                @click="toSendAudioMsg"
                >录音提醒</el-button
              >
            </div>
            <div
              v-if="detailInfo.monitorVideoSource && actionValid"
              class="action-item"
            >
              <el-button
                icon="icon icon-call"
                size="mideum"
                :loading="holding"
                @click="answer(0)"
                >语音通话</el-button
              >
            </div>
            <div
              v-if="detailInfo.monitorVideoSource && actionValid"
              class="action-item"
            >
              <el-button
                icon="icon icon-media"
                size="mideum"
                :loading="holding"
                @click="answer(1)"
                >视频通话</el-button
              >
            </div>
            <div class="action-item">
              <el-button
                icon="icon icon-info-danger"
                size="mideum"
                @click="toBreach(0)"
                >违纪处理</el-button
              >
            </div>
            <div
              v-if="detailInfo.statusCode === 'ANSWERING'"
              class="action-item"
            >
              <el-button
                icon="icon icon-paper-danger"
                size="mideum"
                @click="toFinish"
                >强制收卷</el-button
              >
            </div>
          </div>
        </div>
        <div class="warning-content">
          <div class="warning-videos">
            <div
              v-for="item in viewVideos"
              :key="item.liveUrl"
              class="student-video-item"
            >
              <div class="student-video-container">
                <div class="student-video-tips">{{ item.name }}</div>
                <flv-media
                  :ref="item.ref"
                  :live-url="item.liveUrl"
                  @muted-change="videoAllMuted"
                ></flv-media>
              </div>
            </div>
          </div>
          <!-- track -->
          <div class="warning-track">
            <h3 class="warning-track-title">
              <i class="icon icon-track"></i>考试轨迹
            </h3>
            <div
              class="warning-track-item"
              v-for="log in detailInfo.examStudentLogList"
              :key="log.id"
            >
              <div
                :class="[
                  'warning-track-type',
                  log.viewType === 'common' ? 'type-common' : 'type-exception',
                ]"
              >
                <i :class="['icon', `icon-track-${log.viewType}`]"></i>
              </div>
              <div class="warning-track-body">
                <div class="warning-track-info">
                  <div class="warning-track-info-title">
                    <template v-if="log.type === 'BREACH_HANDLE'">
                      <span
                        v-if="!log.breachLogStatus"
                        class="warning-track-cancel"
                        @click="toBreach(1, log.objId)"
                        >撤销违纪</span
                      >
                      <span v-else>已撤销</span>
                    </template>
                    <h3>{{ log.title }}</h3>
                  </div>
                  <p v-if="log.desc">{{ log.desc }}</p>
                  <p>
                    时间段：
                    <span v-if="log.startTime">{{ log.startTime }} ~ </span>
                    <span>{{ log.endTime }}</span>
                  </p>
                  <p v-if="log.durationTime">
                    持续时长约：{{ log.durationTime }}
                  </p>
                </div>
                <ul class="warning-track-media" v-if="log.photos">
                  <li v-for="(photo, pindex) in log.photos" :key="pindex">
                    <img :src="photo" @click="toViewImg(photo)" />
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- student-breach-dialog -->
    <student-breach-dialog
      :instance="curDetail"
      @modified="breachFinish"
      ref="StudentBreachDialog"
    ></student-breach-dialog>
    <!-- warning-text-message-dialog -->
    <warning-text-message-dialog
      :record-id="examRecordId"
      ref="WarningTextMessageDialog"
    ></warning-text-message-dialog>
    <!-- audio-record-dialog -->
    <audio-record-dialog
      :record-id="examRecordId"
      ref="AudioRecordDialog"
    ></audio-record-dialog>
    <!-- image-preview -->
    <simple-image-preview
      :cur-image="curImage"
      ref="SimpleImagePreview"
    ></simple-image-preview>

    <!-- 通话弹出层 -->
    <div
      v-if="dialogVisible"
      class="communication-dialog"
      v-move-ele.prevent.stop
    >
      <div class="communication-box" v-show="!isWaiting">
        <div class="communication-host" id="communication-host"></div>
        <div class="communication-guest" id="communication-guest"></div>
        <div class="communication-action" @mousedown.stop>
          <el-button round type="danger" @click.stop="hangup"
            >结束通话</el-button
          >
        </div>
        <div class="communication-info">
          <span>持续时长：<second-timer ref="SecondTimer"></second-timer></span>
        </div>
      </div>
      <div class="communication-wait" v-show="isWaiting">
        <p class="communication-wait-tips">等待接听…</p>
        <div class="communication-wait-avatar">
          <img
            :src="detailInfo.basePhotoPath"
            :alt="detailInfo.examStudentName"
          />
        </div>
        <p class="communication-wait-username">
          {{ detailInfo.examStudentName }}
        </p>
        <div class="communication-wait-action" @mousedown.stop>
          <el-button round type="danger" @click="hangup">取消通话</el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {
  checkSystemRequirements,
  createClient,
  createStream,
} from "@/plugins/trtc";
import {
  invigilateDetail,
  invigilateFinish,
  communicationCalling,
  communicationOver,
  warningStudentDetail,
  getUserMonitorKey,
} from "@/api/invigilation";
import FlvMedia from "../common/FlvMedia";
import StudentBreachDialog from "./StudentBreachDialog";
import WarningTextMessageDialog from "./WarningTextMessageDialog";
import AudioRecordDialog from "./audioRecord/AudioRecordDialog";
import SimpleImagePreview from "@/components/imagePreview/SimpleImagePreview";
import SecondTimer from "../common/SecondTimer";
import {
  formatDate,
  timeNumberToText,
  objTypeOf,
  snakeToHump,
} from "@/utils/utils";
import MoveEle from "@/plugins/move-ele";
import { mapState } from "vuex";

const domEmpty = (dom) => {
  dom.childNodes.forEach((childNode) => {
    dom.removeChild(childNode);
  });
};

export default {
  name: "WarningDetail",
  components: {
    FlvMedia,
    StudentBreachDialog,
    WarningTextMessageDialog,
    AudioRecordDialog,
    SimpleImagePreview,
    SecondTimer,
  },
  directives: { MoveEle },
  data() {
    return {
      examRecordId: this.$route.params.examRecordId,
      autoAnswerInfo: null,
      detailInfo: {},
      curDetail: {},
      serialIds: [],
      exceptionSummary: [],
      viewVideos: [],
      viewVideoReady: false,
      holding: false,
      // communication
      userMonitor: {},
      client: null,
      localStream: null,
      dialogVisible: false,
      isWaiting: false,
      subscribeSetTs: [],
      loopRunning: false,
      loopSetTs: [],
      isHandup: false,
      curImage: { imgSrc: "" },
    };
  },
  computed: {
    ...mapState("invigilation", ["detailIds", "liveDomains"]),
    isBreach() {
      return (
        !this.detailInfo.breachStatus && this.detailInfo.breachStatus !== null
      );
    },
    actionValid() {
      return (
        this.detailInfo.statusCode &&
        ["FIRST_PREPARE", "ANSWERING"].includes(this.detailInfo.statusCode)
      );
    },
  },
  watch: {
    $route: {
      handler() {
        this.initData();
      },
    },
  },
  mounted() {
    const autoAnswerInfo = window.sessionStorage.getItem("autoAnswerInfo");
    this.autoAnswerInfo = autoAnswerInfo ? JSON.parse(autoAnswerInfo) : null;
    this.initData();
  },
  methods: {
    async initData() {
      this.examRecordId = this.$route.params.examRecordId;
      await this.getInvigilateDetail().catch(() => {});
      await this.getStudentVideo().catch(() => {});
      this.holding = false;

      // 学生正在考试，开启定时更新
      // 自动更新新增正在候考阶段
      if (["FIRST_PREPARE", "ANSWERING"].includes(this.detailInfo.statusCode)) {
        this.loopRunning = true;
        this.clearLoopSetTs();
        this.loopSetTs.push(
          setTimeout(() => {
            this.timerUpdatePage();
          }, 10 * 1000)
        );
      } else {
        this.loopRunning = false;
        this.clearLoopSetTs();
      }

      // 自动应答
      if (this.autoAnswerInfo) {
        this.autoAnswer();
      }
    },
    clearSubscribeSetTs() {
      if (!this.subscribeSetTs.length) return;
      this.subscribeSetTs.forEach((sett) => {
        clearTimeout(sett);
      });
      this.subscribeSetTs = [];
    },
    clearLoopSetTs() {
      if (!this.loopSetTs.length) return;
      this.loopSetTs.forEach((sett) => {
        clearTimeout(sett);
      });
      this.loopSetTs = [];
    },
    async timerUpdatePage() {
      this.clearLoopSetTs();
      if (!this.loopRunning) return;

      await this.getInvigilateDetail().catch(() => {});

      this.loopSetTs.push(
        setTimeout(() => {
          this.timerUpdatePage();
        }, 10 * 1000)
      );
    },
    async getStudentVideo() {
      this.viewVideos = [];
      const res = await warningStudentDetail({
        examRecordId: this.examRecordId,
      });
      const orderSources = [
        "CLIENT_CAMERA",
        "CLIENT_SCREEN",
        "MOBILE_FIRST",
        "MOBILE_SECOND",
      ];
      const sourceNames = {
        CLIENT_CAMERA: "电脑摄像头",
        CLIENT_SCREEN: "考生屏幕",
        MOBILE_FIRST: "手机主机位",
        MOBILE_SECOND: "手机辅机位",
      };

      let records = {};
      res.data.data.forEach((item, index) => {
        const domain = this.liveDomains[index] || this.liveDomains[0];
        item.liveUrl = item.liveUrl
          ? `${domain}/live/${item.liveUrl.toLowerCase()}.flv`
          : "";
        item.name = sourceNames[item.source];
        item.ref = snakeToHump(item.source) + "Video";
        records[item.source] = item;
      });

      orderSources.forEach((source) => {
        if (records[source]) {
          this.viewVideos.push(records[source]);
        }
      });
      // 展示所有
      // this.viewVideos = orderSources.map((source) => {
      //   return (
      //     records[source] || {
      //       liveUrl: null,
      //       source,
      //       name: sourceNames[source],
      //       ref: snakeToHump(source) + "Video",
      //     }
      //   );
      // });
      this.initSubscribeVideo();
    },
    async getInvigilateDetail() {
      const res = await invigilateDetail(this.examRecordId);
      this.detailInfo = res.data.data;
      this.detailInfo.examStudentLogList = this.parseStudentLogs(
        this.detailInfo.examStudentLogList
      );
      this.exceptionSummary = this.detailInfo.examStudentLogList
        .filter((item) => item.viewType === "warning")
        .slice(0, 3);
    },
    parseStudentLogs(examStudentLogList) {
      const statusTypes = {
        common: [
          "FIRST_START",
          "RESUME_START",
          "IN_PROCESS",
          "PREPARE",
          "ANSWERING",
          "BREAK_OFF",
          "RESUME_PREPARE",
          "FINISHED",
          "FIRST_PREPARE",
        ],
        warning: [
          "FACE_COUNT_ERROR",
          "FACE_COMPARE_ERROR",
          "EYE_CLOSE_ERROR",
          "LIVENESS_ACTION_ERROR",
          "REALNESS",
          "NONE",
          // exception:
          "NET_TIME_OUT",
          "MACHING_STOP",
          "NET_TIME_BREAK",
          "SOFTWARE_STOP",
          "POWER_CUT",
          "BREACH_HANDLE",
          "BREACH_REVOKE",
        ],
      };
      const transformInfo = {
        FIRST_START: "身份识别",
        ANSWERING: "进入考试",
        RESUME_START: "身份识别",
      };
      let statusTypeMap = {};
      Object.keys(statusTypes).map((k) => {
        statusTypes[k].map((item) => {
          statusTypeMap[item] = k;
        });
      });

      const logs = examStudentLogList.map((item) => {
        let info = { ...item };
        info.endTime = formatDate("HH:mm:ss", new Date(info.createTime));
        info.viewType = statusTypeMap[info.type] || "common";
        const content = info.info.split(/【|】/);
        if (content.length === 3) {
          info.title = content[1];
          info.desc = content[2];
        } else {
          info.title = transformInfo[info.type] || content[0];
        }
        if (info.remark && info.remark.includes('{"')) {
          info.remark = JSON.parse(info.remark);
          if (info.remark["MIN_CREATE_TIME"]) {
            info.startTime = formatDate(
              "HH:mm:ss",
              new Date(info.remark["MIN_CREATE_TIME"])
            );
            info.durationTime = timeNumberToText(
              info.createTime - info.remark["MIN_CREATE_TIME"]
            );
          }

          let photos = [];
          Object.keys(info.remark).map((key) => {
            if (key.includes("PHOTO")) {
              const kPhotos =
                objTypeOf(info.remark[key]) === "array"
                  ? info.remark[key]
                  : [info.remark[key]];
              photos = [...photos, ...kPhotos];
            }
          });
          info.photos = photos;
        } else if (info.updateTime) {
          info.startTime = formatDate("HH:mm:ss", new Date(info.createTime));
          info.endTime = formatDate("HH:mm:ss", new Date(info.updateTime));
          info.durationTime = timeNumberToText(
            info.updateTime - info.createTime
          );
        }

        // 撤销违纪的特别处理
        if (item.type === "BREACH_HANDLE" && item.title.includes('{"')) {
          const tinfo = JSON.parse(item.title);
          info.breachLogStatus = tinfo.breachLogStatus;
        }

        return info;
      });
      return logs;
    },
    changeStudent(type) {
      let index = this.detailIds.indexOf(this.examRecordId);
      if (type) {
        if (index >= this.detailIds.length - 1) {
          this.$message.error("当前没有下一个学生了");
          return;
        }
        index++;
      } else {
        if (index <= 0) {
          this.$message.error("当前没有上一个学生了");
          return;
        }
        index--;
      }

      if (this.holding) return;
      this.holding = true;

      this.closeSubscribeVideo();
      console.log(this.detailIds[index]);

      this.$router.replace({
        name: "WarningDetail",
        params: {
          examRecordId: this.detailIds[index],
        },
      });
    },
    toBreach(status = 0, breachLogId = null) {
      this.curDetail = {
        examStudentName: this.detailInfo.examStudentName,
        identity: this.detailInfo.identity,
        courseNameCode: this.detailInfo.courseNameCode,
        description: "",
        examRecordId: [this.detailInfo.examRecordId],
        // 状态,0:新建,1:撤销
        status,
        // 违纪日志id，新建违纪时为null，撤销违纪时需填值
        breachLogId,
        type: "",
      };
      this.$refs.StudentBreachDialog.open();
    },
    async toFinish() {
      const result = await this.$confirm(
        "试卷若被强制回收，考试再无法重置继续完成考试，请您慎重选择！您确定要强制回收改考试试卷吗？",
        "强制收卷确认提醒",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          iconClass: "el-icon-warning",
          customClass: "el-message-box__error",
        }
      ).catch(() => {});

      if (!result) return;

      await invigilateFinish({
        examRecordId: [this.detailInfo.examRecordId],
        type: "INTERRUPT",
      });
      this.$message.success("强制收卷成功！");
      this.goBack();
    },
    toSendTextMsg() {
      this.$refs.WarningTextMessageDialog.open();
    },
    toSendAudioMsg() {
      this.$refs.AudioRecordDialog.open();
    },
    breachFinish() {
      this.getInvigilateDetail();
    },
    // video relative
    notifyError(content) {
      this.$notify({
        type: "error",
        message: content,
      });
    },
    async initClient(examRecordId) {
      const res = await getUserMonitorKey(examRecordId);
      this.userMonitor = res.data.data;
      this.client = createClient({
        mode: "live",
        sdkAppId: this.userMonitor.appId * 1,
        userId: this.userMonitor.monitorUserId,
        userSig: this.userMonitor.monitorUserSig,
        useStringRoomId: true,
      });
    },
    async getLocalMedia(isVideo) {
      const localStream = createStream({
        userId: this.userMonitor.monitorUserId,
        audio: true,
        video: !!isVideo,
      });
      const errorTips = {
        NotFoundError: "找不到硬件设备，请确保硬件设备正常。",
        NotAllowedError: "不授权摄像头/麦克风访问无法进行音视频通话。",
        NotReadableError:
          "暂时无法访问摄像头/麦克风，请确保当前没有其他应用请求访问摄像头/麦克风，并重试。",
        OverConstrainedError: "设备异常",
        AbortError: "设备异常",
      };

      let initLocalStreamResult = true;
      await localStream.initialize().catch((error) => {
        console.log(errorTips[error.name]);
        this.notifyError(errorTips[error.name] || "未知错误");
        initLocalStreamResult = false;
        localStream.close();
      });
      return initLocalStreamResult && localStream;
    },
    async autoAnswer() {
      await this.answer(this.autoAnswerInfo.isVideo);
      // 更改学生的通话申请状态
      await communicationCalling({
        recordId: this.examRecordId,
        source: this.autoAnswerInfo.source,
      });
    },
    async answer(isVideo) {
      const result = await checkSystemRequirements().catch(() => {
        this.$message.error(
          `您的浏览器不支持当前音视频通讯版本。建议使用最新版的chrome浏览器！`
        );
      });
      if (!result) return;

      // 客户端两路视频公用一个userId：
      // main：有音频，有视频
      // auxiliary：无音频，有视频
      // 手机端userId各不同
      if (this.holding) return;
      this.holding = true;
      this.videoAllMuted();

      await this.initClient(this.examRecordId).catch(() => {});
      if (!this.client) {
        this.holding = false;
        return;
      }
      this.localStream = await this.getLocalMedia(isVideo);
      if (!this.localStream) {
        this.holding = false;
        return;
      }

      this.dialogVisible = true;
      this.holding = false;
      // 添加远程用户视频发布监听
      this.client.on("stream-added", (event) => {
        console.log(event);
        console.log(event.stream.getUserId(), this.userMonitor.sourceUserId);
        const remoteStream = event.stream;
        if (remoteStream.getUserId() !== this.userMonitor.sourceUserId) return;
        if (remoteStream.getType() !== "main") return;
        console.log(`有效视频${remoteStream.getUserId()}，准备订阅`);

        if (this.autoAnswerInfo) {
          // 存在自动应答信息时，不再延迟订阅学生音视频流
          this.client
            .subscribe(remoteStream, { audio: true, video: true })
            .catch((error) => {
              console.log(`${remoteStream.getUserId()}视频订阅失败！`, error);
              this.notifyError("学生视频获取失败！");
            });
        } else {
          // 延迟订阅视频
          this.subscribeSetTs.push(
            setTimeout(() => {
              this.client
                .subscribe(remoteStream, { audio: true, video: true })
                .catch((error) => {
                  console.log(
                    `${remoteStream.getUserId()}视频订阅失败！`,
                    error
                  );
                  this.notifyError("学生视频获取失败！");
                });
            }, 5000)
          );
        }
      });
      this.client.on("stream-subscribed", (event) => {
        const remoteStream = event.stream;
        console.log(event);
        console.log(`${remoteStream.getUserId()}视频已订阅！`);
        this.isWaiting = false;
        this.$nextTick(() => {
          if (!this.$refs.SecondTimer.recoding) this.$refs.SecondTimer.start();
          domEmpty(document.getElementById("communication-host"));
          remoteStream.play("communication-host", { objectFit: "contain" });
        });
      });
      this.client.on("stream-removed", (event) => {
        const remoteStream = event.stream;
        if (
          remoteStream.getUserId() !== this.userMonitor.sourceUserId ||
          remoteStream.getType() !== "main" ||
          this.isHandup
        )
          return;

        console.log(event);
        console.log(`${remoteStream.getUserId()}已退出房间！`);
        this.notifyError("对方已挂断！");
        this.hangup();
      });

      // 加入房间
      let roomJoinResult = true;
      await this.client
        .join({
          roomId: this.userMonitor.monitorKey,
          role: "audience",
        })
        .catch((error) => {
          roomJoinResult = false;
          console.log("加入房间失败！", error);
          this.notifyError("发起通信失败！");
        });
      if (!roomJoinResult) return;
      console.log("加入房间成功！");

      // 切换角色，连麦互动
      let switchResult = true;
      await this.client.switchRole("anchor").catch((error) => {
        console.log("切换角色失败！", error);
        this.notifyError("角色错误！");
        switchResult = false;
      });
      if (!switchResult) return;

      // 发布本地视频
      let publishStreamResult = true;
      this.client.publish(this.localStream).catch((error) => {
        console.log("发布本地视频失败！", error);
        this.notifyError("本地音视频推送失败！");
        publishStreamResult = false;
      });
      if (!publishStreamResult) return;
      console.log("发布本地音视频成功！");

      // 播放本地视频
      this.localStream.play("communication-guest", { muted: true });
      this.isHandup = false;
    },
    async hangup() {
      if (this.isHandup) return;
      this.isHandup = true;
      this.clearSubscribeSetTs();
      this.$refs.SecondTimer.end();

      // 取消发布本地视频
      await this.client.unpublish(this.localStream).catch((error) => {
        console.log("取消发布本地视频失败！", error);
      });

      this.localStream.close();
      this.localStream = null;

      // 离开房间
      let result = true;
      await this.client.leave().catch((error) => {
        console.log("离开房间失败！", error);
        this.notifyError("操作异常，请重新尝试！");
        result = false;
      });
      if (!result) return;

      this.client.off("*");
      this.client = null;
      this.userMonitor = {};

      this.dialogVisible = false;
      this.isWaiting = true;
      // this.initSubscribeVideo();

      if (this.autoAnswerInfo) {
        // 结束学生的通话
        await communicationOver({
          recordId: this.examRecordId,
          source: this.autoAnswerInfo.source,
        }).catch(() => {
          console.log("结束通话状态异常！");
        });

        this.goBack();
      }
    },
    initSubscribeVideo() {
      this.viewVideoReady = true;
    },
    closeSubscribeVideo() {
      this.viewVideoReady = false;
    },
    videoAllMuted() {
      this.viewVideos
        .filter((vv) => vv.liveUrl)
        .forEach((vv) => {
          this.$refs[vv.ref][0].mutedPlayer(true);
        });
    },
    toViewImg(photo) {
      this.curImage = { imgSrc: photo };
      this.$refs.SimpleImagePreview.open();
    },
    goBack() {
      window.history.go(-1);
    },
  },
  beforeDestroy() {
    window.sessionStorage.removeItem("autoAnswerInfo");
    this.loopRunning = false;
    this.clearLoopSetTs();
    this.clearSubscribeSetTs();
    if (this.client) {
      this.client.leave();
      this.client.off("*");
    }
  },
};
</script>
