<template>
  <div v-loading="!orgSetting">
    <el-tabs v-model="activeName" type="card">
      <el-tab-pane label="考试规则设置" name="first">
        <el-form
          ref="form1"
          :model="form"
          :rules="rules"
          label-width="170px"
          inline
          :disabled="disableEdit"
        >
          <el-row>
            <el-form-item label="考试模式" prop="mode">
              <ExamTypeSelect
                :disabled="isEdit"
                v-model="form.mode"
              ></ExamTypeSelect>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="批次编码" prop="code">
              <el-input :disabled="isEdit" v-model.trim="form.code"></el-input>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="批次名称" prop="name">
              <el-input v-model.trim="form.name"></el-input>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="考试时间" prop="startEndTimeProxy">
              <el-date-picker
                v-model="form.startEndTimeProxy"
                type="datetimerange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                value-format="timestamp"
              >
              </el-date-picker>
            </el-form-item>
          </el-row>
          <el-row v-if="!isModeAnytime">
            <el-form-item label="候考时长（分钟）">
              <MinuteInput
                v-model.trim="form.prepareSeconds"
                :min="0"
                :max="10000"
              >
              </MinuteInput>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="考试次数限制" prop="examCount">
              <el-input-number
                v-model.number.trim="form.examCount"
                :min="1"
                :max="10000"
              ></el-input-number>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="考试时长（分钟）" prop="maxDurationSeconds">
              <MinuteInput v-model.trim="form.maxDurationSeconds">
              </MinuteInput>
            </el-form-item>
          </el-row>
          <el-row v-if="!isModeAnytime">
            <el-form-item label="迟到时长（分钟）" prop="openingSeconds">
              <MinuteInput v-model.trim="form.openingSeconds"> </MinuteInput>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="冻结时间（分钟）" prop="minDurationSeconds">
              <MinuteInput v-model.trim="form.minDurationSeconds" />
            </el-form-item>
          </el-row>
          <el-row v-if="!isModeAnytime">
            <el-form-item label="启用集中收卷">
              <el-radio v-model="form.forceFinish" :label="1">是</el-radio>
              <el-radio v-model="form.forceFinish" :label="0">否</el-radio>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="启用开考口令">
              <el-radio v-model="enableShortCodeProxy" :label="true"
                >是</el-radio
              >
              <el-radio v-model="enableShortCodeProxy" :label="false"
                >否</el-radio
              >
              <el-input
                v-if="enableShortCodeProxy"
                v-model.trim="form.shortCode"
              ></el-input>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="是否允许断点续考">
              <el-radio v-model="enableBreakProxy" :label="true">是</el-radio>
              <el-radio v-model="enableBreakProxy" :label="false">否</el-radio>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item v-if="enableBreakProxy" label="断点次数">
              <el-input-number
                v-model.trim="form.breakResumeCount"
                :min="0"
                :max="10000"
              ></el-input-number>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item
              v-if="enableBreakProxy"
              prop="breakExpireSeconds"
              label="断点时长（分钟）"
            >
              <MinuteInput v-model.trim="form.breakExpireSeconds">
              </MinuteInput>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="重考是否需要审核">
              <el-radio v-model="form.reexamAuditing" :label="1">是</el-radio>
              <el-radio v-model="form.reexamAuditing" :label="0">否</el-radio>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="取分策略">
              <el-radio
                v-model="form.recordSelectStrategy"
                :disabled="isEdit"
                label="LATEST"
              >
                最后一次提交
              </el-radio>
              <el-radio
                v-model="form.recordSelectStrategy"
                label="HIGHEST_OBJECTIVE_SCORE"
                :disabled="isEdit"
              >
                客观分最高
              </el-radio>
              <!-- <el-radio
                v-model="form.recordSelectStrategy"
                label="HIGHEST_TOTAL_SCORE"
                :disabled="isEdit"
              >
                总分最高
              </el-radio> -->
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="多选题给分规则">
              <el-radio v-model="form.objectiveScorePolicy" label="EQUAL">
                全对给分
              </el-radio>
              <el-radio v-model="form.objectiveScorePolicy" label="PARTIAL">
                漏选给一半分
              </el-radio>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="是否显示客观分">
              <el-radio v-model="form.showObjectiveScore" :label="1">
                是
              </el-radio>
              <el-radio v-model="form.showObjectiveScore" :label="0">
                否
              </el-radio>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="是否允许摄像头拍照作答">
              <el-radio v-model="form.cameraPhotoUpload" :label="1">
                是
              </el-radio>
              <el-radio v-model="form.cameraPhotoUpload" :label="0">
                否
              </el-radio>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="是否允许小程序作答">
              <el-radio v-model="form.mobilePhotoUpload" :label="1">
                是
              </el-radio>
              <el-radio v-model="form.mobilePhotoUpload" :label="0">
                否
              </el-radio>
            </el-form-item>
          </el-row>
        </el-form>
      </el-tab-pane>

      <el-tab-pane label="监考设置" name="second">
        <el-form
          ref="form2"
          :model="form"
          :rules="rules"
          label-width="180px"
          :disabled="disableEdit"
        >
          <el-row class="tab-invililation">
            <h2>开考检测</h2>
            <el-form-item label="" label-width="0px">
              <div class="d-flex flex-column tab-invililation-radio">
                <el-radio v-model="form.entryAuthenticationPolicy" label="OFF">
                  安全级别：<span style="color: #202b4b; font-size: 20px;">
                    无
                  </span>
                  <span class="desc-txt">
                    开考无检测
                  </span>
                </el-radio>
                <el-radio
                  v-model="form.entryAuthenticationPolicy"
                  label="FACE_VERIFY_OPTIONAL"
                >
                  安全级别：<span style="color: #1cd1a1; font-size: 20px;">
                    低
                  </span>
                  <span class="desc-txt"> 开考人脸比对，不强制比对 </span>
                </el-radio>
                <el-radio
                  v-model="form.entryAuthenticationPolicy"
                  label="FACE_VERIFY_FORCE"
                >
                  安全级别：<span style="color: #ff9f43; font-size: 20px;">
                    中
                  </span>
                  <span class="desc-txt"> 开考人脸强制比对 </span>
                </el-radio>
                <el-radio
                  v-model="form.entryAuthenticationPolicy"
                  :disabled="orgSettingDisableLiveness"
                  :title="orgSettingDisableLiveness && '原因：机构禁用活体'"
                  label="LIVENESS_VERIFY"
                >
                  安全级别：<span style="color: red; font-size: 20px;">
                    高
                  </span>
                  <span class="desc-txt"> 开考人脸比对及活体验证 </span>
                </el-radio>
              </div>
            </el-form-item>
          </el-row>
          <el-row class="tab-invililation">
            <h2>过程监控</h2>
            <el-form-item label="是否考中人脸识别">
              <el-radio
                :disabled="!!form.cameraPhotoUpload"
                :title="!!form.cameraPhotoUpload && '原因：拍照作答'"
                v-model="form.inProcessFaceVerify"
                :label="1"
                >是
              </el-radio>
              <el-radio
                :disabled="!!form.cameraPhotoUpload"
                :title="!!form.cameraPhotoUpload && '原因：拍照作答'"
                v-model="form.inProcessFaceVerify"
                :label="0"
                >否
              </el-radio>
            </el-form-item>
          </el-row>
          <el-row v-if="form.inProcessFaceVerify">
            <el-form-item label="是否考中陌生人脸识别">
              <el-radio
                :disabled="!!form.cameraPhotoUpload"
                :title="!!form.cameraPhotoUpload && '原因：拍照作答'"
                v-model="form.inProcessFaceStrangerIgnore"
                :label="0"
                >是
              </el-radio>
              <el-radio
                :disabled="!!form.cameraPhotoUpload"
                :title="!!form.cameraPhotoUpload && '原因：拍照作答'"
                v-model="form.inProcessFaceStrangerIgnore"
                :label="1"
                >否
              </el-radio>
            </el-form-item>
          </el-row>
          <el-row v-if="form.inProcessFaceVerify">
            <el-form-item label="是否考中开启真实性检测">
              <el-radio
                :disabled="!!form.cameraPhotoUpload"
                :title="!!form.cameraPhotoUpload && '原因：拍照作答'"
                v-model="form.inProcessRealnessVerify"
                :label="1"
                >是
              </el-radio>
              <el-radio
                :disabled="!!form.cameraPhotoUpload"
                :title="!!form.cameraPhotoUpload && '原因：拍照作答'"
                v-model="form.inProcessRealnessVerify"
                :label="0"
                >否
              </el-radio>
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="是否考中活体检测">
              <el-radio
                :disabled="
                  !!form.cameraPhotoUpload || orgSettingDisableLiveness
                "
                :title="
                  (!!form.cameraPhotoUpload || orgSettingDisableLiveness) &&
                  '原因：机构禁用活体或选择拍照作答'
                "
                v-model="form.inProcessLivenessVerify"
                :label="1"
                >是
              </el-radio>
              <el-radio
                :disabled="
                  !!form.cameraPhotoUpload || orgSettingDisableLiveness
                "
                :title="
                  (!!form.cameraPhotoUpload || orgSettingDisableLiveness) &&
                  '原因：机构禁用活体或选择拍照作答'
                "
                v-model="form.inProcessLivenessVerify"
                :label="0"
                >否
              </el-radio>
            </el-form-item>
          </el-row>
          <el-row v-if="form.inProcessLivenessVerify">
            <el-form-item
              label="活体验证弹出时间段"
              prop="inProcessLivenessFixedRange"
            >
              <MinuteInput
                v-model.trim="form.inProcessLivenessFixedRange[0]"
                style="width: 150px;"
              />
              ~
              <MinuteInput
                v-model.trim="form.inProcessLivenessFixedRange[1]"
                style="width: 150px;"
              />
              <span style="color: red;">
                *活体验证将该时间段内随机出现，且时间段设置不能超过冻结时间
              </span>
            </el-form-item>
          </el-row>
          <el-row v-if="form.inProcessLivenessVerify">
            <el-form-item label="活体验证结果的判定方案">
              <el-radio v-model="form.inProcessLivenessJudgePolicy" label="ANY">
                单条成功则通过
              </el-radio>
              <el-radio v-model="form.inProcessLivenessJudgePolicy" label="ALL">
                所有验证成功则通过
              </el-radio>
              <el-radio
                v-model="form.inProcessLivenessJudgePolicy"
                label="MORE"
              >
                成功次数大于失败则通过
              </el-radio>
            </el-form-item>
          </el-row>
          <el-row class="tab-invililation">
            <h2>监考直播</h2>
            <el-form-item label="是否开启考生端监考直播">
              <el-radio
                :disabled="!!form.cameraPhotoUpload"
                :title="!!form.cameraPhotoUpload && '原因：拍照作答'"
                v-model="form.monitorProxy"
                :label="true"
                >是
              </el-radio>
              <el-radio
                :disabled="!!form.cameraPhotoUpload"
                :title="!!form.cameraPhotoUpload && '原因：拍照作答'"
                v-model="form.monitorProxy"
                :label="false"
                >否
              </el-radio>
            </el-form-item>
          </el-row>
          <div
            class="monitor-config"
            v-if="form.monitorProxy && enablePrevilleges"
          >
            <div class="monitor-config-options">
              <h3 class="monitor-title">监考直播方案配置：</h3>
              <el-form-item label="电脑摄像头主机位">
                <el-radio-group
                  v-model="monitorVideoSource.CLIENT_CAMERA"
                  @change="monitorClientCameraChange"
                >
                  <el-radio
                    v-for="(val, key) in monitorTypes"
                    :key="key"
                    :label="key"
                    >{{ val }}
                  </el-radio>
                </el-radio-group>
              </el-form-item>
              <el-form-item label="电脑操作录屏">
                <el-radio-group
                  v-model="monitorVideoSource.CLIENT_SCREEN"
                  :disabled="monitorVideoSource.CLIENT_CAMERA !== '1'"
                  :title="
                    monitorVideoSource.CLIENT_CAMERA === '0' &&
                    '原因：先选择电脑摄像头主机位'
                  "
                  @change="monitorClientScreenChange"
                >
                  <el-radio
                    v-for="(val, key) in monitorTinyTypes"
                    :key="key"
                    :label="key"
                    >{{ val }}
                  </el-radio>
                </el-radio-group>
              </el-form-item>
              <el-form-item label="手机监考主机位">
                <el-radio-group
                  v-model="monitorVideoSource.MOBILE_FIRST"
                  @change="monitorMobileFirstChange"
                >
                  <el-radio
                    v-for="(val, key) in monitorTypes"
                    :key="key"
                    :label="key"
                    >{{ val }}
                  </el-radio>
                </el-radio-group>
              </el-form-item>
              <el-form-item label="手机监考辅机位">
                <el-radio-group
                  v-model="monitorVideoSource.MOBILE_SECOND"
                  :disabled="monitorVideoSource.MOBILE_FIRST === '0'"
                  :title="
                    monitorVideoSource.MOBILE_FIRST === '0' &&
                    '原因：先选择手机监考主机位'
                  "
                  @change="monitorVideoSourceChange"
                >
                  <el-radio
                    v-for="(val, key) in monitorTypes"
                    :key="key"
                    :label="key"
                    >{{ val }}
                  </el-radio>
                </el-radio-group>
              </el-form-item>
              <p class="tips-info tips-error">
                *主机位设备负责收音及播放监考提示
              </p>
            </div>
            <div class="monitor-config-view">
              <div class="monitor-item monitor-client-camera">
                <div
                  :class="['monitor-item-img', monitorImgSrc('CLIENT_CAMERA')]"
                />
                <p class="monitor-item-desc">电脑摄像头主机位</p>
              </div>
              <div class="monitor-item monitor-client-screen">
                <div
                  :class="['monitor-item-img', monitorImgSrc('CLIENT_SCREEN')]"
                />
                <p class="monitor-item-desc">电脑开启录屏</p>
              </div>
              <div class="monitor-item monitor-mobile-first">
                <div
                  :class="['monitor-item-img', monitorImgSrc('MOBILE_FIRST')]"
                />
                <p class="monitor-item-desc">手机监考主机位</p>
              </div>
              <div class="monitor-item monitor-mobile-second">
                <div
                  :class="['monitor-item-img', monitorImgSrc('MOBILE_SECOND')]"
                />
                <p class="monitor-item-desc">手机监考辅机位</p>
              </div>
              <div
                v-if="monitorVideoSource.MOBILE_SECOND !== '0'"
                class="monitor-line-mobile-second"
              >
                <span></span>
                <span></span>
              </div>
              <div
                v-if="monitorVideoSource.MOBILE_FIRST !== '0'"
                class="monitor-line-mobile-first"
              ></div>
              <div
                v-if="monitorVideoSource.CLIENT_CAMERA !== '0'"
                class="monitor-line-client-camera"
              ></div>
            </div>
          </div>
        </el-form>
      </el-tab-pane>

      <el-tab-pane label="其他设置" name="third">
        <el-form
          ref="form3"
          :model="form"
          label-width="170px"
          :rules="rules"
          inline
          :disabled="disableEdit"
        >
          <el-row>
            <el-form-item label="考试须知">
              <VEditor
                :value="form.preNoticeClone"
                style="width: 300px;"
                @result="(v) => (form.preNotice = v)"
              />
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="须知强制阅读时长">
              <el-input-number
                :min="1"
                :max="24 * 60"
                step-strictly
                :controls="false"
                v-model.trim="form.preNoticeStaySeconds"
              />（秒）
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="考后说明">
              <VEditor
                :value="form.postNoticeClone"
                style="width: 300px;"
                @result="(v) => (form.postNotice = v)"
              />
            </el-form-item>
          </el-row>
          <el-row>
            <el-form-item label="IP限制">
              <el-radio v-model="form.enableIpLimit" :label="1">是</el-radio>
              <el-radio v-model="form.enableIpLimit" :label="0">否</el-radio>
            </el-form-item>
          </el-row>
          <el-row v-if="form.enableIpLimit">
            <el-form-item label="IP段(*表示任意)：" prop="ipAllow">
              <el-input
                v-model.trim="form.ipAllow"
                placeholder="192.168.10.1, 192.168.11.*, 172.10.*.*"
              ></el-input>
            </el-form-item>
          </el-row>
        </el-form>
      </el-tab-pane>
    </el-tabs>

    <div class="tab-footer">
      <el-button
        type="primary"
        @click="save"
        :loading="loading"
        :disabled="disableEdit"
        >保存</el-button
      >
      <el-button @click="cancel">取消</el-button>
    </div>
  </div>
</template>

<script>
import ExamTypeSelect from "@/components/ExamTypeSelect";
import MinuteInput from "@/components/MinuteInput";
import { saveExam, getExamDetail } from "@/api/examwork-exam";
import { isNumber } from "lodash-es";
import { searchOrg } from "@/api/system-org";

export default {
  name: "ExamEdit",
  components: { ExamTypeSelect, MinuteInput },
  computed: {
    examId() {
      return this.$route.params.id;
    },
    isEdit() {
      return !!this.examId;
    },
    isModeAnytime() {
      return this.form.mode === "ANYTIME";
    },
    enableShortCodeProxy: {
      get() {
        return !!this.form.shortCode;
      },
      set(v) {
        if (v) {
          this.form.shortCode = "123";
        } else {
          this.form.shortCode = null;
        }
      },
    },
    enableBreakProxy: {
      get() {
        return !!(this.form.breakResumeCount || this.form.breakExpireSeconds);
      },
      set(v) {
        if (v) {
          this.form.breakResumeCount = 1;
          this.form.breakExpireSeconds = 0;
        } else {
          this.form.breakResumeCount = null;
          this.form.breakExpireSeconds = null;
        }
      },
    },
    orgSettingDisableLiveness() {
      return !this.orgSetting?.enableLiveness;
    },
    disableEdit() {
      return this.form.monitorStatus === "FINISHED";
    },
    enablePrevilleges() {
      return !!this.$store.state.user.orgInfo.enableMonitorRecord;
    },
  },
  watch: {
    "form.mode": {
      immediate: true,
      handler(v) {
        if (v === "ANYTIME") {
          this.form.forceFinish = 0;
          this.form.prepareSeconds = 0;
          this.form.openingSeconds = 0;
        }
      },
    },
    "form.startEndTimeProxy": {
      immediate: true,
      handler(v) {
        this.form.startTime = new Date(v[0]).valueOf();
        this.form.endTime = new Date(v[1]).valueOf();
      },
    },
    "form.monitorProxy": {
      immediate: true,
      handler(v) {
        if (!v) {
          this.form.monitorVideoSource = [];
          this.form.monitorRecord = [];
        }
        if (this.form.monitorVideoSource === null) {
          this.form.monitorVideoSource = [];
        }
      },
    },
    "form.cameraPhotoUpload": {
      handler(v) {
        if (v) {
          this.form.mobilePhotoUpload = 0;

          this.form.inProcessFaceVerify = 0;
          this.form.inProcessFaceStrangerIgnore = 0;
          this.form.inProcessRealnessVerify = 0;
          this.form.inProcessLivenessVerify = 0;
          this.form.monitorProxy = false;
        }
      },
    },
    "form.mobilePhotoUpload": {
      handler(v) {
        if (v) {
          this.form.cameraPhotoUpload = 0;
        }
      },
    },
  },
  async created() {
    if (this.isEdit) {
      const res = await getExamDetail({ id: this.examId });
      this.form = { ...this.form, ...res.data.data };
      if (!this.form.inProcessLivenessFixedRange) {
        this.form.inProcessLivenessFixedRange = [0, 0];
      }
      this.form.startEndTimeProxy = [this.form.startTime, this.form.endTime];
      this.form.monitorRecord = this.form.monitorRecord || [];
      this.form.monitorVideoSource = this.form.monitorVideoSource || [];
      this.form.monitorProxy = !!this.form.monitorVideoSource;
      this.form.preNoticeClone = this.form.preNotice;
      this.form.postNoticeClone = this.form.postNotice;
      this.parseMonitorVideoSource();
    }

    // sleep
    // await new Promise((res) =>
    //   setTimeout(() => {
    //     res();
    //   }, 3000)
    // );
    const res = await searchOrg(this.$store.state.user.orgId);
    this.orgSetting = res.data.data[0];
    if (!this.orgSetting.enableLiveness) {
      if (this.form.entryAuthenticationPolicy === "LIVENESS_VERIFY") {
        this.form.entryAuthenticationPolicy = "FACE_VERIFY_FORCE";
      }
      this.form.inProcessLivenessVerify = 0;
    }
  },
  data() {
    return {
      activeName: "first",
      form: {
        mode: "",
        code: "",
        name: "",
        startEndTimeProxy: [],
        startTime: 0,
        endTime: 0,
        prepareSeconds: 0,
        maxDurationSeconds: 0,
        openingSeconds: 0,
        minDurationSeconds: 0,
        forceFinish: 1,
        shortCode: "",
        breakResumeCount: 0,
        breakExpireSeconds: 0,
        reexamAuditing: 0,
        recordSelectStrategy: "HIGHEST_OBJECTIVE_SCORE",
        objectiveScorePolicy: "EQUAL",
        showObjectiveScore: 0,
        cameraPhotoUpload: 0,
        mobilePhotoUpload: 0,
        entryAuthenticationPolicy: "OFF",
        inProcessFaceVerify: 0,
        inProcessFaceStrangerIgnore: 0,
        inProcessRealnessVerify: 0,
        inProcessLivenessVerify: 0,
        inProcessLivenessFixedRange: [0, 0],
        inProcessLivenessJudgePolicy: "ALL",
        monitorProxy: false,
        monitorRecord: [],
        monitorVideoSource: [],
        ipAllow: "",
      },
      rules: {
        mode: { required: true, message: "必填" },
        name: [
          { required: true, message: "必填" },
          { type: "string", min: 1, max: 30, message: "长度必须在1到30之间" },
        ],
        code: [
          { required: true, message: "必填" },
          { type: "string", min: 1, max: 30, message: "长度必须在1到30之间" },
        ],
        startEndTimeProxy: { required: true, message: "必填" },
        examCount: [
          { required: true, message: "必填" },
          { type: "number", min: 1, message: "必须大于0" },
        ],
        maxDurationSeconds: [
          { required: true, message: "必填" },
          { type: "number", min: 1, message: "必须大于0" },
        ],
        openingSeconds: {
          validator: (rule, value) => {
            // console.log(value);
            return new Promise((resolve, reject) => {
              if (
                !this.form.isModeAnytime &&
                this.form.maxDurationSeconds < value
              ) {
                reject("迟到时长必须小于考试时长");
              } else {
                resolve();
              }
            });
          },
        },
        minDurationSeconds: {
          trigger: "change",
          validator: (rule, value) => {
            // console.log(value);
            return new Promise((resolve, reject) => {
              if (this.form.maxDurationSeconds < value) {
                reject("冻结时长必须小于考试时长");
              } else {
                resolve();
              }
            });
          },
        },
        breakExpireSeconds: {
          trigger: "change",
          validator: (rule, value) => {
            // console.log(value);
            return new Promise((resolve, reject) => {
              if (
                this.enableBreakProxy &&
                this.form.monitorRecord.length &&
                value > 25 * 60
              ) {
                reject("开启回放情况下，断点时长不得超过25分钟");
              } else {
                resolve();
              }
            });
          },
        },
        inProcessLivenessFixedRange: {
          validator: (rule, value) => {
            return new Promise((resolve, reject) => {
              const isNull = value === null;
              if (
                (this.form.inProcessLivenessVerify === 0 && isNull) ||
                (value.length === 2 &&
                  isNumber(value[0]) &&
                  isNumber(value[1]) &&
                  value[0] < value[1] &&
                  value[0] > 0 &&
                  value[1] < this.form.minDurationSeconds)
              ) {
                resolve();
                return;
              }
              if (this.form.inProcessLivenessVerify && value[0] <= 0) {
                reject("开始时间必须大于0");
              } else if (
                this.form.inProcessLivenessVerify &&
                value[1] >= this.form.minDurationSeconds
              ) {
                reject("结束时间必须小于冻结时间");
              } else {
                reject("格式错误");
              }
            });
          },
          // message: "格式错误",
        },
        ipAllow: {
          validator: (rule, value) => {
            // console.log(value);
            return new Promise((resolve, reject) => {
              if (!this.form.enableIpLimit) {
                resolve();
                return;
              }
              const ips = value.split(",").map((v) => v.trim());
              // console.log(ips);
              const checkIpSeg = (seg, idx) => {
                if (idx < 2) {
                  if (!/^\d+$/.test(seg)) {
                    return false;
                  }
                } else if (idx >= 2 && idx < 4) {
                  if (!(/^\d+$/.test(seg) || /^\*$/.test(seg))) {
                    return false;
                  }
                }
                return true;
              };
              if (
                ips.every(
                  (v) =>
                    v.split(".").length === 4 && v.split(".").every(checkIpSeg)
                )
              ) {
                resolve();
              } else {
                reject("格式不匹配");
              }
            });
          },
        },
      },
      sources: [
        "MOBILE_FIRST",
        "MOBILE_SECOND",
        "CLIENT_CAMERA",
        "CLIENT_SCREEN",
      ],
      monitorTypes: {
        0: "关闭",
        1: "直播",
        2: "直播+回放",
      },
      monitorTinyTypes: {
        0: "关闭",
        1: "直播",
      },
      monitorVideoSource: {
        CLIENT_CAMERA: "0",
        CLIENT_SCREEN: "0",
        MOBILE_FIRST: "0",
        MOBILE_SECOND: "0",
      },
      orgSetting: null,
      loading: false,
    };
  },
  methods: {
    monitorImgSrc(monitorSource) {
      const selected = this.monitorVideoSource[monitorSource] !== "0";
      const selectedStr = selected ? "-selected" : "";
      if (monitorSource === "MOBILE_FIRST") {
        return `mobile-first-img${selectedStr}`;
      } else if (monitorSource === "MOBILE_SECOND") {
        return `mobile-second-img${selectedStr}`;
        // return `./imgs/手机监考辅机位${selectedStr}.png`;
      } else if (monitorSource === "CLIENT_CAMERA") {
        // return `./imgs/手机监考辅机位${selectedStr}.png`;
        return `client-camera-img${selectedStr}`;
      } else if (monitorSource === "CLIENT_SCREEN") {
        // return `./imgs/手机监考辅机位${selectedStr}.png`;
        return `client-screen-img${selectedStr}`;
      }

      return "";
    },
    monitorClientCameraChange(val) {
      if (val === "0" || val === "2") {
        this.monitorVideoSource.CLIENT_SCREEN = "0";
      }

      this.monitorVideoSourceChange();
    },
    monitorClientScreenChange() {
      this.monitorVideoSourceChange();
    },
    monitorMobileFirstChange(val) {
      if (val === "0") this.monitorVideoSource.MOBILE_SECOND = "0";
      this.monitorVideoSourceChange();
    },
    monitorVideoSourceChange() {
      let monitorVideoSource = [],
        monitorRecord = [];
      this.sources.forEach((source) => {
        if (this.monitorVideoSource[source] === "0") return;
        if (this.monitorVideoSource[source] === "2") {
          monitorRecord.push(source);
        }
        monitorVideoSource.push(source);
      });

      this.form.monitorVideoSource = monitorVideoSource;
      this.form.monitorRecord = monitorRecord;
    },
    parseMonitorVideoSource() {
      this.sources.forEach((source) => {
        const hasRecord = this.form.monitorRecord.includes(source);
        const hasSource = this.form.monitorVideoSource.includes(source);
        if (hasRecord) {
          this.monitorVideoSource[source] = "2";
        } else if (hasSource) {
          this.monitorVideoSource[source] = "1";
        } else {
          this.monitorVideoSource[source] = "0";
        }
      });
    },
    async save() {
      try {
        await this.$refs.form1.validate();
        await this.$refs.form2.validate();
        await this.$refs.form3.validate();
      } catch (error) {
        console.log("校验失败", error);
        this.$notify({
          title: "保存失败",
          message: "请检查不合法的输入项",
          type: "waring",
        });
        return;
      }

      try {
        this.loading = true;
        await saveExam(this.form);
        this.$notify({ title: "保存成功", type: "success" });
        this.$router.back();
      } finally {
        this.loading = false;
      }
    },
    cancel() {
      this.$router.back();
    },
  },
};
</script>

<style lang="scss" scoped>
.tab-invililation {
  > h2 {
    font-size: 20px;
    font-weight: 500;
    color: #8c94ac;
    line-height: 28px;
    margin-bottom: 26px;
  }

  &-radio {
    padding-left: 30px;
    .el-radio {
      margin-bottom: 18px;
      height: 30px;
    }
  }

  .desc-txt {
    color: #fe5863;
    border: 1px solid #fe5863;
    border-radius: 0 6px 6px 0;
    padding: 6px 10px 6px 16px;
    margin-left: 20px;
    border-left: 0;
    position: relative;

    &::before {
      content: "";
      display: block;
      position: absolute;
      width: 12px;
      height: 30px;
      left: -11px;
      top: -1px;
      background-image: url(../../../assets/bg-angle.png);
      background-repeat: no-repeat;
      background-size: 100% 100%;
    }
  }
}

.monitor-config {
  &-options {
    display: inline-block;
    vertical-align: top;
    width: 470px;

    .el-form-item {
      margin-bottom: 10px;
    }
  }

  &-view {
    position: relative;
    display: inline-block;
    vertical-align: top;
    width: 498px;
    height: 257px;
    background: #f0f4f9;
    border-radius: 6px;
    border: 1px solid #e8edf3;
  }
}
.monitor-title {
  height: 20px;
  font-size: 14px;
  font-weight: 600;
  color: #202b4b;
  line-height: 20px;
  margin-bottom: 20px;
  padding-left: 20px;

  &::before {
    content: "";
    display: inline-block;
    vertical-align: middle;
    width: 4px;
    height: 10px;
    background: #1886fe;
    border-radius: 2px;
    margin-right: 10px;
  }
}

.monitor-item {
  position: absolute;
  text-align: center;

  &-img {
    margin: 0 auto;
  }
  &-desc {
    font-size: 12px;
    line-height: 1;
    margin: 5px 0 0;
  }
}
.monitor-client-camera {
  left: 171px;
  top: 21px;
}
.monitor-client-screen {
  left: 124px;
  bottom: 20px;
}
.monitor-mobile-first {
  left: 20px;
  top: 20px;
}
.monitor-mobile-second {
  bottom: 20px;
  right: 20px;
}

.mobile-first-img {
  background-image: url(./imgs/手机监考主机位.png);
  background-repeat: no-repeat;
  background-size: 52px 80px;
  width: 52px;
  height: 80px;
  &-selected {
    @extend .mobile-first-img;
    background-image: url(./imgs/手机监考主机位-选中.png);
  }
}

.mobile-second-img {
  background-image: url(./imgs/手机监考辅机位.png);
  background-repeat: no-repeat;
  background-size: 52px 80px;
  width: 52px;
  height: 80px;
  &-selected {
    @extend .mobile-second-img;
    background-image: url(./imgs/手机监考辅机位-选中.png);
  }
}

.client-camera-img {
  background-image: url(./imgs/电脑摄像头主机位.png);
  background-repeat: no-repeat;
  background-size: 33px 40px;
  width: 33px;
  height: 40px;
  &-selected {
    @extend .client-camera-img;
    background-image: url(./imgs/电脑摄像头主机位-选中.png);
  }
}

.client-screen-img {
  background-image: url(./imgs/电脑操作录屏.png);
  background-repeat: no-repeat;
  background-size: 190px 110px;
  width: 190px;
  height: 110px;
  &-selected {
    @extend .client-screen-img;
    background-image: url(./imgs/电脑操作录屏-选中.png);
  }
}
.monitor-line-point {
  content: "";
  display: block;
  position: absolute;
  width: 5px;
  height: 5px;
  border: 1px solid #c1cbdb;
  border-radius: 50%;
  background: #f0f4f9;
}
.monitor-line-client-camera {
  position: absolute;
  width: 0;
  height: 23px;
  border-left: 1px solid #c1cbdb;
  top: 89px;
  left: 219px;

  &::before {
    @extend .monitor-line-point;
    left: -3px;
    top: 0;
  }
  &::after {
    @extend .monitor-line-point;
    left: -3px;
    bottom: 0;
  }
}
.monitor-line-mobile-first {
  position: absolute;
  width: 56px;
  height: 28px;
  bottom: 96px;
  left: 63px;
  border-left: 1px solid #c1cbdb;
  border-bottom: 1px solid #c1cbdb;

  &::before {
    @extend .monitor-line-point;
    left: -3px;
    top: 0;
  }
  &::after {
    @extend .monitor-line-point;
    right: 0;
    bottom: -3px;
  }
}
.monitor-line-mobile-second {
  span:nth-of-type(1) {
    display: block;
    position: absolute;
    width: 35px;
    height: 63px;
    bottom: 92px;
    right: 139px;
    border-right: 1px solid #c1cbdb;
    border-bottom: 1px solid #c1cbdb;

    &::before {
      @extend .monitor-line-point;
      left: 0;
      bottom: -3px;
    }
  }
  span:nth-of-type(2) {
    display: block;
    position: absolute;
    width: 78px;
    height: 23px;
    top: 100px;
    right: 61px;
    border-right: 1px solid #c1cbdb;
    border-top: 1px solid #c1cbdb;

    &::after {
      @extend .monitor-line-point;
      right: -3px;
      bottom: 0;
    }
  }
}
</style>
