<template>
  <div v-if="!hidePanel"
       :class="['panel', { active: visible }]"
       id="panel"
       ref="container"
       :style="style">
    <el-container class="scrollbar"
                  id="container"
                  v-show="visible">
      <el-header id="header">
        <div class="panel-header"
             id="panelHeader">
          <div class="project">
            <div class="inline-flex items-center">
              <p>实训项目</p>
              <el-tooltip effect="dark"
                          content="点击右侧“下三角”按钮可切换实验项目"
                          placement="bottom">
                <i class="info el-icon-warning"
                   style="margin-left: 10px"></i>
              </el-tooltip>
            </div>
            <el-select v-model="param.projectId"
                       placeholder="请选择"
                       class="select"
                       :disabled="per != 0"
                       @change="getCache(1)">
              <el-option v-for="(item, i) in projectList"
                         :key="item.projectId"
                         :label="i + 1 + '. ' + item.projectName"
                         :value="item.projectId"></el-option>
            </el-select>
          </div>
          <div class="item">
            <div class="count">
              实训{{ text }}时间 <span>{{ day }}</span>天 <span>{{ hour }}</span>小时 <span>{{ minutes }}</span>分 <span>{{ seconds }}</span>秒
            </div>
          </div>
          <div class="item">
            <div>
              总得分：
              <span class="total-score">{{ grade }}</span>
            </div>
          </div>
          <div>
            <el-button class="h-[40px]"
                       @click="toReport"
                       v-if="isSubmit">查看实验报告</el-button>
            <el-button class="reload h-[40px]"
                       @click="reloadConfirm"
                       v-show="per == 0">重新开始</el-button>
            <el-button type="primary"
                       class="submit btn h-[40px]"
                       :loading="submiting"
                       @click="confirmSubmit"
                       :disabled="isSubmit || !projectList.length">提交</el-button>
          </div>
        </div>
      </el-header>
      <el-container id="infoContainer">
        <el-aside id="aside"
                  width="30%">
          <div class="aside-header">
            <div class="p-title">
              <i class="el-icon-s-order"></i>
              <p>实验目标</p>
            </div>
            <div class="goal">
              <div v-if="pd.experimentTargetType == 0 || !pd.experimentTargetType"
                   class="ql-editor"
                   v-html="pd.experimentTarget"></div>

              <mavon-editor v-else
                            class="md"
                            v-model="pd.experimentTarget"
                            :ishljs="true"
                            :subfield="false"
                            :editable="false"
                            :toolbarsFlag="false"
                            :boxShadowStyle="none" />
            </div>
          </div>
          <div class="aside-footer">
            <div class="p-title">
              <i class="el-icon-s-management"></i>
              <p>实验任务</p>
            </div>
            <div>
              <el-row>
                <el-col :span="24">
                  <el-card shadow="never"
                           :border="false">
                    <el-table class="task-table"
                              :data="taskList"
                              :stripe="true">
                      <el-table-column type="index"></el-table-column>
                      <el-table-column prop="name"
                                       label="判分点"
                                       align="center"></el-table-column>
                      <el-table-column prop="score"
                                       label="分值"
                                       width="60"
                                       align="center"></el-table-column>
                      <template v-if="!param.competitionId">
                        <el-table-column label="结果"
                                         width="60"
                                         align="center">
                          <template v-slot="scope">
                            <template v-if="isSubmit">
                              <div v-if="!param.competitionId"
                                   class="flex justify-center items-center">
                                <el-icon v-if="scope.row.finishedResult"
                                         color="#15d500"
                                         :size="16">
                                  <Check />
                                </el-icon>
                                <el-icon v-else
                                         color="#f00"
                                         :size="16">
                                  <Close />
                                </el-icon>
                              </div>
                              <template v-else>-</template>
                            </template>
                          </template>
                        </el-table-column>
                        <el-table-column prop="score"
                                         label="得分"
                                         width="60"
                                         align="center">
                          <template v-slot="scope">
                            <template v-if="isSubmit">{{ param.competitionId ? '-' : scope.row.examScore }}</template>
                          </template>
                        </el-table-column>
                      </template>
                    </el-table>
                  </el-card>
                </el-col>
              </el-row>
            </div>
          </div>
        </el-aside>
        <el-main id="main">
          <el-tabs class="info-tab"
                   v-model="pannelTab"
                   type="card">
            <el-tab-pane label="项目背景"
                         name="first">
              <div v-if="pd.experimentDescriptionType == 0 || !pd.experimentDescriptionType"
                   class="ql-editor"
                   v-html="pd.experimentDescription"></div>

              <mavon-editor v-else
                            class="md"
                            v-model="pd.experimentDescription"
                            :ishljs="true"
                            :subfield="false"
                            :editable="false"
                            :toolbarsFlag="false"
                            :boxShadowStyle="none" />
            </el-tab-pane>
            <el-tab-pane label="实验要求"
                         name="second">
              <el-collapse v-model="curReq">
                <el-collapse-item v-for="item in points"
                                  :name="item.judgmentId"
                                  :key="item.judgmentId">
                  <template v-slot:title>
                    <i class="el-icon-s-ticket"></i>
                    <div class="break-all des"
                         v-html="item.name"></div>
                  </template>
                  <div v-if="item.experimentalRequirementsType == 0 || !item.experimentalRequirementsType"
                       class="ql-editor"
                       v-html="item.experimentalRequirements"></div>

                  <mavon-editor v-else
                                class="md"
                                v-model="item.experimentalRequirements"
                                :ishljs="true"
                                :subfield="false"
                                :editable="false"
                                :toolbarsFlag="false"
                                :boxShadowStyle="none" />
                </el-collapse-item>
              </el-collapse>
            </el-tab-pane>
            <el-tab-pane label="实验提示"
                         name="third"
                         v-if="hintOpen">
              <div v-if="pd.experimentHintType == 0 || !pd.experimentHintType"
                   class="ql-editor"
                   v-html="pd.experimentHint"></div>

              <mavon-editor v-else
                            class="md"
                            v-model="pd.experimentHint"
                            :ishljs="true"
                            :subfield="false"
                            :editable="false"
                            :toolbarsFlag="false"
                            :boxShadowStyle="none" />
            </el-tab-pane>
          </el-tabs>
        </el-main>
      </el-container>
    </el-container>

    <div :class="['toggle absolute top-[200px] text-center', visible ? 'top-[35%] left-[100%]' : '']">
      <el-icon class="cursor-pointer"
               color="#f1772b"
               :size="24">
        <Rank id="toggle" />
      </el-icon>
      <div class="toggle-panel w-[40px] h-[175px] bg-[length:100%_100%] bg-no-repeat cursor-pointer"
           :class="{ active: visible }"
           ref="handle"
           @click="visible = !visible"></div>
    </div>
  </div>
  <div v-if="isSubmit && !isReport"
       class="z-[199] fixed top-[64px] right-0 bottom-0 left-0 bg-[rgba(0,0,0,.3)]"></div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, inject, computed, watch, onUnmounted } from 'vue';
import { submitOpe } from '@/api/bank';
import { getSandTableLastCache, deleteOperationData } from '@/api/judgment';
import { getProjectBySystemId, getProjectDetail, getDetailById, getCompetition, getStartTime, heartbeatDetection } from '@/api/system';
import Settings from '@/settings';
import { useRouter, useRoute, beforeRouteLeave } from 'vue-router';
import type { Action } from 'element-plus';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Close, Check, Rank } from '@element-plus/icons-vue';
import dayjs from 'dayjs';
import Cookies from 'js-cookie';
import { mavonEditor } from 'mavon-editor';
import 'mavon-editor/dist/css/index.css';
import '@vueup/vue-quill/dist/vue-quill.snow.css';
import { useDraggable } from '@vueuse/core';
import { logout } from '@/store/useCurrentUser';
import { getIds, getNow } from '@/utils/common';

const router = useRouter();
const route = useRoute();
const param = reactive<Record<string, any>>(route.query);
const hidePanel = computed(() => Settings.hidePanelPath.includes(route.path));
const curSystemId = ref<number>(1);
const per = ref<number>(0); // 项目权限(0、练习 1、考核 2、竞赛)
const isSubmit = ref<boolean>(false); // 是否提交的标识
const entryTime = ref<any>(new Date());
const visible = ref<boolean>(true);
const isReport = ref<boolean>(true);
const grade = ref<string | number>('00');
const text = ref<string>(''); // 倒计时前面的文字，练习：所用；考核：剩余。练习是计时，考核是倒计时
const counterTimer = ref<any>(null);
const heartBeatTimer = ref<any>(null);
const day = ref<number | string>(0);
const seconds = ref<number | string>(0);
const minutes = ref<number | string>(0);
const hour = ref<number | string>(0);
const projectList = ref<Record<string, any>[]>([]);
const pd = ref<Record<string, any>>({});
const hintOpen = ref<boolean>(false);
const points = ref<Record<string, any>[]>([]);
const judgmentId = ref<string | number>('');
const curReq = ref<Record<string, any>[]>([]);
const taskList = ref<Record<string, any>[]>([]);
const pannelTab = ref<string>('first');
const submiting = ref<boolean>(false);
const reportId = ref<string | number>('');
const countVal = ref<any>('');
const getLevel = ref();
const container = ref<HTMLElement | null>(null);
const handle = ref<HTMLElement | null>(null);
// 实验面板拖拽
const { x, y, style } = useDraggable(container, {
  initialValue: { x: 0, y: 200 },
  stopPropagation: true,
  handle: handle.value,
  onStart(position, e) {
    const { id } = e.target;
    if (id !== 'panelHeader' && id !== 'toggle') return false;
  },
});

if (param.token) {
  // 从url带进来的参数，存cookie里，其他页面直接取cookie
  param.token && Cookies.set('sand-token', param.token);
  Cookies.set('sand-projectId', param.projectId ?? '');
  Cookies.set('sand-systemId', param.systemId ?? '');
  Cookies.set('sand-classId', param.classId ?? '');
  Cookies.set('sand-cid', param.cid ?? '');
  Cookies.set('sand-assessmentId', param.assessmentId ?? '');
  Cookies.set('sand-competitionId', param.competitionId ?? '');
  Cookies.set('sand-stageId', param.stageId ?? '');
  Cookies.set('sand-teamId', param.teamId ?? '');
  Cookies.set('sand-mallId', param.mallId ?? '');
  Cookies.set('sand-referrer', param.referrer ?? '');
  Cookies.set('sand-className', param.className ?? '');
  Cookies.set('sand-startTime', param.startTime ?? '');
  Cookies.set('sand-resultsDetails', param.resultsDetails ?? '');
  Cookies.set('sand-resultAnnouncementTime', param.resultAnnouncementTime ?? '');
  Cookies.set('sand-curriculumName', param.curriculumName ?? '');
  Cookies.set('sand-stopTime', param.stopTime ?? '');
  Cookies.set('sand-userId', param.userId ?? '');
  Cookies.set('sand-account', param.account ?? '');
  Cookies.set('sand-admin', param.admin ?? ''); // 从中台进来的标识
  Cookies.remove('sand-submit');
  Cookies.remove('sand-loaded');
  router.replace(route.path);
} else {
  param.systemId = Cookies.get('sand-systemId');
  param.projectId = Cookies.get('sand-projectId');
  param.classId = Cookies.get('sand-classId');
  param.cid = Cookies.get('sand-cid');
  param.assessmentId = Cookies.get('sand-assessmentId');
  param.competitionId = Cookies.get('sand-competitionId');
  param.stageId = Cookies.get('sand-stageId');
  param.teamId = Cookies.get('sand-teamId');
  param.mallId = Cookies.get('sand-mallId');
  param.className = Cookies.get('sand-className');
  param.startTime = Cookies.get('sand-startTime');
  param.resultsDetails = Cookies.get('sand-resultsDetails');
  param.resultAnnouncementTime = Cookies.get('sand-resultAnnouncementTime');
  param.curriculumName = Cookies.get('sand-curriculumName');
  param.stopTime = Cookies.get('sand-stopTime');
  param.userId = Cookies.get('sand-userId');
  param.account = Cookies.get('sand-account');
  isSubmit.value = Cookies.get('sand-submit') === 'true';
}
if (param.projectId) param.projectId = +param.projectId;

watch(
  route,
  () => {
    visible.value = route.path === '/';
    isReport.value = route.path === '/report';
  },
  {
    immediate: true,
  },
);

// 获取上次实验的时间
let getSumTime = (reset?: number): Promise<any> => {
  return new Promise(async (resolve, reject) => {
    const res = await getStartTime({
      permissions: per.value,
      projectId: param.projectId,
      reset,
    });
    resolve(res.startTime ? new Date(res.startTime) : '');
  });
};
// 获取进入时间
let getEntryTime = async (resetTime?: number) => {
  let now = await getSumTime(resetTime); // 获取上次进入实验的时间，如果没有，说明是第一次进入，然后直接从服务器获取当前时间
  if (!now) now = await getNow();
  entryTime.value = now;
};
// 倒计时
const timeFormat = (num: number): string | number => {
  return num < 10 ? `0${num}` : num;
};
// 清除时间
let reloadCount = () => {
  clearInterval(counterTimer.value);
  countVal.value = '';
  day.value = '00';
  seconds.value = '00';
  minutes.value = '00';
  hour.value = '00';
};
// 计时器（考核是倒计时，练习是计时）
let counter = async (counterTime: number) => {
  if (counterTime <= 0) {
    if (per.value) {
      clearInterval(counterTimer.value);
      // 考核/竞赛的倒计时结束后自动提交
      if (!Cookies.get('sand-submit')) {
        Cookies.set('sand-submit', 'true');
        await submit();
        submiting.value = true;
        ElMessageBox.alert(`${per.value === 1 ? '考核' : '竞赛'}时间已到，系统已自动交卷`, '提示', {
          confirmButtonText: '确定',
          closeOnClickModal: false,
          showClose: false,
          callback: (action: Action) => {
            logout();
          },
        });
      }
    }
  } else {
    const leave1 = counterTime % (24 * 3600); // 计算天数后剩余的毫秒数
    const leave2 = leave1 % 3600; // 计算小时数后剩余的毫秒数
    const leave3 = leave2 % 60; // 计算分钟数后剩余的毫秒数

    day.value = timeFormat(Math.floor(counterTime / (24 * 3600)));
    hour.value = timeFormat(Math.floor(leave1 / 3600));
    minutes.value = timeFormat(Math.floor(leave2 / 60));
    seconds.value = timeFormat(Math.round(leave3));
  }
};
// 启动倒计时
let startCount = () => {
  clearInterval(counterTimer.value);
  counterTimer.value = setInterval(() => {
    counter(per.value ? countVal.value-- : countVal.value++);
  }, 1000);
};
// 提交状态
let setSubmit = (val: boolean) => {
  isSubmit.value = val;
  val ? Cookies.set('sand-submit', val) : Cookies.remove('sand-submit');
};
// 获取考核列表来查询该考核是否已经考过
let getAssList = async () => {
  await getAssStatus();
  await getProDetail();
};
// 查询考核状态（查到考核如果结束后，直接提交考核）
let getAssStatus = async () => {
  // 未提交才需要查询状态
  if (!isSubmit.value) {
    const { data } = await getDetailById(param.assessmentId);
    const done = data ? data.status === 2 : false; // 状态(0、待开始 1、进行中 2、已结束)
    // 如果考核已结束，自动提交
    if (done) {
      submit();
      ElMessageBox.alert(`考核时间已到，系统已自动交卷`, '提示', {
        confirmButtonText: '确定',
        closeOnClickModal: false,
        showClose: false,
        callback: (action: Action) => {
          logout();
        },
      });
    }
  }
};

// 查询竞赛状态（查到竞赛如果结束后，直接提交竞赛）
let getCompetitionStatus = async () => {
  // 未提交才需要查询状态
  if (!isSubmit.value) {
    const { competition } = await getCompetition(param.competitionId);
    const stages = competition.competitionStage;
    if (stages) {
      const stage = stages.find((e) => e.stageId == param.stageId);
      const endTime = new Date(stage.endTime);
      const now = await getNow();
      // 如果已经结束
      if (now >= endTime) {
        submit();
        ElMessageBox.alert(`竞赛时间已到，系统已自动交卷`, '提示', {
          confirmButtonText: '确定',
          closeOnClickModal: false,
          showClose: false,
          callback: (action: Action) => {
            logout();
          },
        });
      } else {
        // 没结束，则显示倒计时
        countVal.value = (endTime - now) / 1000;
        startCount();
      }
    }
  }
};
// 删除缓存
let delCache = async () => {
  await deleteOperationData({
    cid: param.cid,
    projectId: param.projectId,
    assessmentId: param.assessmentId,
    competitionId: param.competitionId,
  });
};
// 项目切换完后的操作
let setNewProject = (reloadPage?: number) => {
  Cookies.set('sand-projectId', param.projectId);
  getProDetail();
  reload();
  getEntryTime();

  if (reloadPage) {
    // 在选择关卡的页面，直接刷新；否则调选择关卡页的获取关卡接口
    if (route.path === '/') {
      location.reload();
    } else {
      getLevel.value && getLevel.value();
    }
  }
};
// 项目选择回调
let getCache = async (reloadPage?: number) => {
  // 查询该项目是否有缓存记录
  const res = await getSandTableLastCache({
    cid: param.cid,
    projectId: param.projectId,
    assessmentId: param.assessmentId || '',
    competitionId: param.competitionId || '',
  });
  // 如果有缓存
  if (res.getLastCache) {
    ElMessageBox.confirm('是否要继续上次的操作记录？', '提示', {
      confirmButtonText: '是',
      cancelButtonText: '否',
      type: 'success',
      closeOnClickModal: false,
      showClose: false,
    })
      .then(async () => {
        // 如果返回了关卡id，则存起来
        if (res.checkpointId) {
          Cookies.set('sand-level', res.checkpointId);
        }

        setNewProject(reloadPage);
      })
      .catch(async () => {
        Cookies.remove('sand-level');
        setNewProject();
        delCache();
        // 在选择关卡的页面，直接刷新；否则调选择关卡页的获取关卡接口
        if (reloadPage) {
          if (route.path === '/') {
            location.reload();
          } else {
            getLevel.value && getLevel.value();
          }
        }
      });
  } else {
    Cookies.remove('sand-level');
    setNewProject();
  }
};
let handleCache = () => {
  // 没提交的情况下才需要查
  if (!isSubmit.value) {
    param.cid && getEntryTime();
    visible.value && !Cookies.get('sand-loaded') && getCache(0); // 选择关卡页面才需要弹出是否恢复缓存的弹框
  }
};
// 查看实验报告
const toReport = () => {
  router.push('/report');
};
// 重新开始
let reload = async () => {
  if (!per.value) {
    reloadCount();
    startCount();
    grade.value = '00';
    pannelTab.value = 'first';
    setSubmit(false);
    router.push('/');
  }
};
// 重新开始询问框
let reloadConfirm = async () => {
  ElMessageBox.confirm('此操作将会清空所有操作记录，确定重新开始？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
    closeOnClickModal: false,
  })
    .then(async () => {
      getEntryTime(1);
      await delCache(); // 点了重新开始才需要删除缓存，切换了项目不需要删除缓存
      Cookies.remove('sand-level');
      reload();
    })
    .catch(() => {
      submiting.value = false;
    });
};
// 提交
let submit = async () => {
  if (!submiting.value) {
    submiting.value = true;
    const checkpointId = Cookies.get('sand-level') ?? '';
    const date = await getNow();
    const timeSum = Math.ceil((date.getTime() - entryTime.value.getTime()) / 60000); // 计算实验用时（分钟），向上取整
    const submitTime = dayjs(date).format('YYYY-MM-DD HH:mm:ss');
    reloadCount();
    try {
      const { retMap } = await submitOpe({
        classId: param.classId ? param.classId : '',
        className: param.className ? param.className : '',
        curriculumId: param.cid,
        startTime: dayjs(entryTime.value).format('YYYY-MM-DD HH:mm:ss'), // 取页面进入的时间
        endTime: per.value ? param.stopTime : submitTime, // 结束时间（考核：直接从职站取考核的结束时间；练习：取提交时间）
        submitTime, // 提交时间，即当前时间（这3个时间都是传完整的日期时间格式）
        timeSum,
        checkpointId,
        projectId: param.projectId,
        projectName: projectList.value.find((e) => e.projectId == param.projectId)?.projectName,
        lcId: curReq.value,
        systemId: curSystemId.value,
        purpose: pd.value.experimentTarget, // 实验目的
        assessmentId: param.assessmentId,
        competitionId: param.competitionId,
        stageId: param.stageId,
        teamId: param.teamId,
        mallId: param.mallId,
      });
      setSubmit(true);

      // 给判分列表添加分数和运行结果
      taskList.value.map((e) => {
        const item = retMap?.scoreInfo.find((n) => n.lcId === e.judgmentId);
        try {
          if (item) {
            e.examScore = item.questionScore;
            e.finishedResult = item.calculate; // 1：正确，2：错误
          } else {
            e.examScore = 0;
          }
        } catch (e) {}
      });
      const score = retMap.totalScore;
      grade.value = score < 10 && !(score % 1) ? '0' + score : score;
      reportId.value = retMap.reportId;
      Cookies.set('sand-reportId', retMap.reportId);
      Cookies.set('sand-score', grade.value);
      localStorage.setItem('sand-taskList', JSON.stringify(taskList.value));
      delCache();
      submiting.value = false;

      // 非练习
      if (per.value) {
        const time = param.resultAnnouncementTime;
        const msg =
          time === '0' ? '提交成功！成绩将在比赛结束后公布，请前往参赛信息模块查看' : time > 0 ? `提交成功！成绩将在比赛结束后${time}小时公布，请前往参赛信息模块查看` : '提交成功';
        ElMessageBox.alert(msg, '提示', {
          confirmButtonText: '确定',
          closeOnClickModal: false,
          showClose: false,
          callback: (action: Action) => {
            logout();
          },
        });
      }
    } catch (e) {
      submiting.value = false;
    }
  }
};
// 提交前的询问框
let confirmSubmit = () => {
  if (isSubmit.value) return false;
  if (!Cookies.get('sand-level')) return ElMessage.error('请选择关卡');
  ElMessageBox.confirm('此操作将视为结束考试，是否继续？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
    closeOnClickModal: false,
  })
    .then(submit)
    .catch(() => {
      submiting.value = false;
    });
};

// 获取项目详情
let getProDetail = async () => {
  const res = await getProjectDetail({
    projectId: param.projectId,
    stuAssessent: 1,
  });
  const pointsList = res.projectJudgmentVos;
  const project = res.projectManage;
  Cookies.set('sand-projectId', param.projectId);
  // 考核/竞赛
  if (per.value) {
    projectList.value = [
      {
        projectId: param.projectId,
        projectName: project.projectName,
      },
    ];
    // Cookies.set('sand-projectName', project.projectName);
  }
  curReq.value = pointsList.map((e) => e.judgmentId); // 实验要求默认全部展开，通过judgmentId来选中item
  points.value = pointsList;
  taskList.value = isSubmit.value ? JSON.parse(localStorage.getItem('sand-taskList')) : pointsList; // 实验任务
  grade.value = isSubmit.value ? Cookies.get('sand-score') : '00';
  judgmentId.value = pointsList[0].judgmentId; // 默认取第一个判分点
  pd.value = project;
  curSystemId.value = project.systemId;
  hintOpen.value = project.founder ? !project.hintOpenBySchool : !project.hintOpen; // 0显示，1不显示，系统跟老师的禁用字段不一样
  const isPrac = per.value === 0; // 是否是练习
  text.value = isPrac ? '已用' : '剩余';
  // 竞赛不需要
  if (!param.competitionId && !isSubmit.value) {
    const now = await getNow();
    countVal.value = (isPrac ? now - entryTime.value : new Date(param.stopTime).getTime() - now) / 1000; // 如果是考核，取考核的结束时间减去当前时间去做倒计时，练习则直接取当前时间减去上次进来的时间做计时
    startCount();
  }
};

// 获取项目列表
const getList = async () => {
  const { projects } = await getProjectBySystemId({
    systemId: param.systemId,
    cId: param.cid ?? '',
    mallId: param.mallId,
    permissions: per.value,
  });
  projectList.value = projects;
  if (!per.value && !param.projectId) param.projectId = projects[0]?.projectId ?? 0; // 默认取第一个项目
  getProDetail();
};

// websocket获取考核及竞赛信息，用于自动提交
// socket连接成功
const open = () => {
  console.log('socket连接成功');
};
// socket连接失败
const error = () => {
  console.log('连接错误');
};
// 接收消息
const getMessage = (msg) => {
  console.log('==websocket接收数据==');
  console.log(JSON.parse(msg.data));
  const { content } = JSON.parse(msg.data);
  // 1赛事、2创业、3考核、4模型。-号拼接携带id
  if (content == 1 && per.value === 2) {
    getCompetitionStatus();
  } else if (content.includes('3-') && per.value === 1) {
    // 考核：3-考核id
    getAssStatus();
  }
};
// 关闭socket
const close = () => {
  console.log('socket已经关闭');
};
// 初始化socket
const initSocket = () => {
  // 实例化socket
  const socket = new WebSocket(`wss://${location.host}/nakadai/websocket/${param.userId}/${param.account}`);
  // this.socket = new WebSocket(`ws://121.37.12.51:9100/nakadai/websocket/${id}/${account}`)
  // 监听socket连接
  socket.onopen = open;
  // 监听socket错误信息
  socket.onerror = error;
  // 监听socket消息
  socket.onmessage = getMessage;
};
// 心跳检测
let setHeartbeatDetection = () => {
  heartBeatTimer.value = setInterval(async () => {
    await heartbeatDetection();
  }, 58 * 1000);
};
// 初始化
const init = async () => {
  console.log('init');
  per.value = param.assessmentId ? 1 : param.competitionId ? 2 : 0;

  if (param.assessmentId) {
    // 考核
    await getAssList();
    handleCache();
    initSocket();
    setHeartbeatDetection();
  } else if (param.competitionId) {
    // 竞赛
    getCompetitionStatus();
    handleCache();
    initSocket();
    setHeartbeatDetection();
  } else {
    // 练习
    param.cid && getList();
    handleCache();
  }

  if (!Cookies.get('sand-loaded')) {
    Cookies.set('sand-loaded', 1); // 初次加载的标识
  } else if (per.value) {
    // 考核/竞赛不查询项目列表，直接查询项目详情
    getProDetail();
  }
};
onMounted(init);
onUnmounted(() => {
  counter = null;
  submit = null;
  setHeartbeatDetection = null;
  getProDetail = null;
  getCache = null;
  getAssList = null;
  getAssStatus = null;
  getCompetitionStatus = null;
  confirmSubmit = null;
  handleCache = null;
  getSumTime = null;
  getEntryTime = null;
  reloadCount = null;
  delCache = null;
  setNewProject = null;
  reload = null;
  reloadConfirm = null
  startCount = null;
  setSubmit = null;
  clearInterval(counterTimer.value);
  clearInterval(heartBeatTimer.value);
  console.log('onUnmounted');
  // next();
});
</script>

<style lang="scss" scoped>
.el-main {
  width: 60%;
  background-color: #fff;
  color: #333;
  padding: 0;
  font-size: 16px;
  margin: 0px 20px 10px 10px;
  white-space: pre-wrap;
  overflow: hidden;
}
.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  .project {
    display: inline-flex;
    align-items: center;
    width: 28%;
  }
  .item {
    font-size: 16px;
    margin: 0 10px;
    padding: 20px 0;
  }
  .count {
    margin-left: -40px;
    span {
      padding: 5px 15px;
      margin: 0 5px;
      color: #333;
      font-size: 14px;
      text-align: center;
      background: #fff;
      border-radius: 18px;
    }
  }
  .total-score {
    @apply p-[10px] text-sm text-center rounded-[6px] bg-[#e0e0e0];
  }
  .submit {
    width: 106px;
    font-size: 16px;
  }
  .reload {
    color: #d0d0d0;
    font-size: 16px;
    background-color: #202020;
  }
}
:deep(.des) {
  font-size: 16px;
  font-family: 'Microsoft YaHei';
  img {
    max-width: 100%;
  }
}
:deep(.el-collapse-item__wrap) {
  border-bottom: none;
}
:deep(.el-collapse-item__header) {
  border-bottom: none;
}
:deep(.el-icon-s-ticket:before) {
  padding: 5px;
  font-size: 16px;
}
:deep(.el-collapse-item__arrow) {
  margin: 0 5px 0 0;
}
:deep(.info-tab.el-tabs--card) {
  .el-tabs__item {
    font-size: 16px;
  }
  .el-tabs__item.is-active {
    @apply text-white bg-[#568df2];
  }
  .el-tabs__header .el-tabs__nav {
    border: none;
  }
  .el-tabs__header .el-tabs__item {
    border-left: none;
  }
  .el-tabs__header {
    padding: 5px 20px;
    border-bottom: none;
  }
  & > .el-tabs__content {
    margin: 0 20px;
    max-height: calc(70vh - 210px);
    overflow: auto;
  }
}
:deep(.el-collapse) {
  border-bottom: none;
  border-top: none;
}
.el-aside {
  margin-bottom: 10px;
  color: #333;
  background-color: #fff;
}
.el-aside :deep([class*=' el-icon-']),
[class^='el-icon-'] {
  line-height: 40px;
  font-size: 16px;
}
.aside-header {
  margin: 0px 10px 10px 10px;
  background-color: #fff;
}
.aside-footer {
  margin: 0px 10px 10px 10px;
  background-color: #fff;
}
.p-title {
  @apply flex justify-center h-[40px] bg-[url('@/assets/images/panel/header.png')] bg-[length:100%_100%] bg-no-repeat;
  p {
    padding-left: 10px;
    line-height: 40px;
    font-size: 16px;
    color: #fff;
  }
  i {
    color: #fff;
  }
}
:deep(.el-card__body) {
  padding: 0;
}
:deep(.task-table) {
  font-size: 12px;
  thead {
    @apply text-white text-[10px];
  }
  th.el-table__cell {
    @apply bg-[#badfff];
  }
  th > .cell {
    font-weight: 100;
  }
  td,
  th.is-leaf {
    border-bottom: 0 !important;
  }
  .el-table__cell {
    padding: 6px 0;
  }
}
.goal {
  padding: 10px 0;
  margin: 0 10px;
  font-size: 14px;
}
:deep(.select) {
  @apply flex-1;
  .el-select__caret:before {
    // content: '\e78f';
    padding: 3px;
    font-size: 16px;
    color: #fff;
    background-color: #568df2;
    border-radius: 50%;
  }
  .el-input__icon {
    line-height: 60px;
  }
  .el-input {
    padding: 10px 0;
  }
  .el-input--suffix .el-input__inner {
    height: 40px !important;
    padding-right: 50px;
    margin-left: 15px;
    color: #333;
    font-size: 14px;
    border-radius: 30px;
    border: none;
    background-color: #fff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}
.panel {
  z-index: 200;
  position: fixed;
  top: 200px;
  bottom: 20px;
  left: 0;
  width: 0;
  height: 0;
  .toggle-panel {
    @apply bg-[url('@/assets/images/panel/right.png')];
    &.active {
      @apply bg-[url('@/assets/images/panel/left.png')];
    }
  }
  &.active {
    position: fixed;
    width: 85%;
    height: 70%;
  }
}
:deep(.el-container) {
  height: calc(100% - 60px);
  &.is-vertical {
    background-color: #f5f5f5;
  }
}
.right {
  color: #00af00;
  font-size: 20px;
}
.wrong {
  color: #f00;
  font-size: 20px;
}
.info {
  color: #bfbfbf;
  cursor: pointer;
  &:hover {
    opacity: 0.9;
  }
}
.ql-editor {
  @apply text-sm;
}
</style>
