<template>
  <div class="index" v-loading="loading || submiting">
    <div class="top">
      <div class="item">
        <p class="names">{{ curStage.stageName }}：{{ curStage.paperName }}</p>

        <div class="count m-l-30">
          阶段剩余时间
          <span>{{ counterVal.day }}</span>天
          <span>{{ counterVal.hour }}</span>小时
          <span>{{ counterVal.minutes }}</span>分
          <span>{{ counterVal.seconds }}</span>秒
        </div>
      </div>

      <div class="item">
        <div class="count m-r-30">
          用时
          <span>{{ timeSum.day }}</span>天
          <span>{{ timeSum.hour }}</span>小时
          <span>{{ timeSum.minutes }}</span>分
          <span>{{ timeSum.seconds }}</span>秒
        </div>

        <el-button class="submit" :loading="submiting" :disabled="submited" @click="confirmSubmit">提交</el-button>
        <img class="exit" src="@/assets/img/exit.svg" alt="" @click="close">
      </div>
    </div>

    <div class="wrap">
      <div class="left">
        <h6 class="title">答题卡</h6>
        <div class="progress">
          <p class="fs-14">答题进度</p>
          <el-progress class="m-t-5 m-b-5" :percentage="progress" :format="progressFormat"></el-progress>
          <p>共{{ form.questionCount }}题，满分{{ form.score }}分</p>
        </div>
        <div v-if="form.paperOutline" class="type-wrap">
          <template v-for="(item, i) in form.paperOutline">
            <div
              v-if="item.examQuestions.length && (!sheetStatus || item.examQuestions.some(e => (sheetStatus === 1 && !e.answered) || (sheetStatus === 2 && e.answered) || (sheetStatus === 3 && e.partAnswer) || (sheetStatus === 4 && e.sign)))"
              :key="i" class="type">
              <h6 class="stem">{{ arabicToChinese(i + 1) }}、{{ item.outlineName }}（本题共{{ item.questionNum }}小题，共{{
                item.targetScore }}分）</h6>
              <ul class="serials">
                <template v-for="(ques, j) in item.examQuestions">
                  <li
                    v-if="!sheetStatus || (sheetStatus === 1 && !ques.answered) || (sheetStatus === 2 && ques.answered) || (sheetStatus === 3 && ques.partAnswer) || (sheetStatus === 4 && ques.sign)"
                    :key="j" :class="{ answered: ques.answered, partAnswer: ques.partAnswer }"
                    @click="scrollToQues(ques, item)">
                    <img v-if="ques.sign" class="tag" src="@/assets/img/tag-active.svg" alt="">
                    {{ j + 1 }}
                  </li>
                </template>
              </ul>
            </div>
          </template>
        </div>
        <ul class="status-filter">
          <li :class="{ active: sheetStatus === 1 }" @click="filterStatus(1)">未作答</li>
          <li :class="{ active: sheetStatus === 2 }" @click="filterStatus(2)">已作答</li>
          <li :class="{ active: sheetStatus === 3 }" @click="filterStatus(3)">部分已作答</li>
          <li :class="{ active: sheetStatus === 4 }" @click="filterStatus(4)"><img class="tag"
              src="@/assets/img/tag-active.svg" alt=""> 已标记</li>
        </ul>
      </div>

      <ul v-if="form.paperOutline" class="ques-wrap" id="quesWrap">
        <li v-for="(item, i) in form.paperOutline" :key="i">
          <div class="outline">
            {{ arabicToChinese(i + 1) }}、{{ item.outlineName }}（本题共{{ item.questionNum }}小题，共{{
              item.targetScore }}分）
            <img :class="['shrink', { active: item.shrink }]" src="@/assets/img/shrink.svg" alt=""
              @click="item.shrink = !item.shrink">
          </div>
          <div :class="['ques', { hide: item.shrink }]">
            <div v-for="(ques, j) in item.examQuestions" :key="j" class="item" :id="'ques' + ques.id">
              <div class="stem-wrap">
                <div class="labels">
                  <span class="label">{{ j + 1 }} / {{ item.questionNum }}</span>
                  <span class="label">{{ item.questionTypeName }}</span>
                </div>
                <div class="stem html-parse" :id="'stem' + ques.id" v-html="ques.stem"></div>
                <p>（{{ ques.score }}分）</p>
                <img class="tag" :src="require('@/assets/img/' + (ques.sign ? 'tag-active' : 'tag') + '.svg')" alt=""
                  @click="ques.sign = ques.sign ? 0 : 1">
              </div>

              <!-- 单选、多选、判断的选项 -->
              <template
                v-if="item.questionType !== 'fill_blank' && item.questionType !== 'essay' && ques.questionAnswerVersionsList">
                <div v-for="(opt, j) in ques.questionAnswerVersionsList" :key="j" class="opt">
                  <el-checkbox v-if="item.questionType === 'multiple_choice'" v-model="opt.answer" :true-label="1"
                    @change="mulChange(ques)"></el-checkbox>
                  <el-radio v-else v-model="opt.answer" tabindex="-1" :true-label="1" :label="1"
                    @change="singleChange(ques, j)"></el-radio>

                  <span>{{ numToLetter(j) }}.&nbsp;</span>
                  <div class="text html-parse" v-html="opt.optionText"></div>
                </div>
              </template>
              <!-- 简答题需要展示题干文件及富文本 -->
              <template v-if="item.questionType === 'essay'">
                <div v-if="ques.stemAttachment" class="m-b-20">
                  <el-link class="m-r-10" type="primary" @click="preview(ques.stemAttachment)">{{ ques.fileName ||
                    ques.stemAttachment }}</el-link>
                  <el-button type="primary" size="mini" round
                    @click="download(ques.fileName || ques.stemAttachment, ques.stemAttachment)">下载</el-button>
                </div>
                <UeditorPlus :ref="'essayAnswer' + ques.id" v-model="ques.answer"
                  @ready="editor => essayAnswerReady(editor, ques)" />
                <div v-if="ques.allowAttachment" class="m-t-20">
                  <div v-if="ques.uploadInstructions" class="flex m-b-10 fs-12">
                    <span>上传要求说明：</span>
                    <div class="html-parse" v-html="ques.uploadInstructions"></div>
                  </div>
                  <el-upload style="max-width: 700px;" accept=".csv,.xlsx,.xls,.docx,.doc,.pdf,.jpg,.png,.zip,.rar,.7z"
                    :before-upload="beforeUpload" :on-remove="e => handleRemove(ques)" :on-error="uploadError"
                    :before-remove="beforeRemove" :on-preview="handlePreview" :limit="1" action="#"
                    :on-exceed="handleExceed" :file-list="ques.fileList" :http-request="e => handleRequest(e, ques)">
                    <el-button type="primary" plain>上传文件</el-button>
                  </el-upload>
                </div>
              </template>
            </div>
          </div>
        </li>
      </ul>
    </div>

    <el-dialog title="图片预览" :visible.sync="previewImgVisible" width="800px" :close-on-click-modal="false">
      <el-image style="max-width: 100px; max-height: 100px" :src="previewImg" :preview-src-list="[previewImg]">
      </el-image>
    </el-dialog>
    <PdfDia :key="pdfVisible" :visible.sync="pdfVisible" :src.sync="pdfSrc" />
  </div>
</template>

<script>
import Util from '@/libs/util'
import Setting from "@/setting"
import QuesConst from '@/const/ques'
import TestPaperConst from '@/const/testPaper'
import _ from 'lodash'
import Upload from '@/components/upload'
import UeditorPlus from '@/components/ueditorPlus'
import PdfDia from '@/components/pdf'
import Bus from '@/libs/bus'
import OSS from 'ali-oss'
import OssConfig from '@/components/upload/config.js'
import Oss from '@/components/upload/upload.js'

export default {
  components: {
    Upload, UeditorPlus, PdfDia
  },
  data () {
    return {
      loading: false,
      per: 2, // 项目权限(0、练习 1、考核 2、竞赛)
      questionTypes: QuesConst.questionTypes,
      numToLetter: Util.numToLetter,
      arabicToChinese: Util.arabicToChinese,
      headers: {
        token: Util.local.get(Setting.tokenKey)
      },
      token: Util.local.get(Setting.tokenKey),
      id: +this.$route.query.id, // 赛事id
      stageId: +this.$route.query.stageId,
      teamId: this.$route.query.teamId || '',
      entryTime: '',
      curStage: {
        stageName: '',
        paperName: '',
      },
      timer: null,
      counterTimer: null,
      countVal: 0,
      // 倒计时
      counterVal: {
        day: 0,
        seconds: 0,
        minutes: 0,
        hour: 0,
      },
      timeSumVal: 0,
      // 用时
      timeSum: {
        day: 0,
        seconds: 0,
        minutes: 0,
        hour: 0,
      },
      totalAnswered: 0,
      progress: 0,
      sheetStatus: '',
      form: {
        questionCount: 0,
      },
      submiting: false,
      submited: false,
      warned: 0,
      quesWrapWidth: 0,
      previewImgVisible: false,
      previewImg: '',
      pdfVisible: false,
      pdfSrc: '',
      client: null,
    };
  },
  mounted () {
    this.$once('hook:beforeDestroy', function () {
      clearInterval(this.counterTimer)
    })

    // websocket实时刷新
    Bus.$on('matchSocket', () => {
      this.getCompetition()
    })

    this.getCompetition(1)
    this.initOss()
  },
  methods: {
    // 获取竞赛信息
    async getCompetition (load) {
      if (load) this.loading = true
      const { competition } = await this.$post(`${this.api.getCompetition}?competitionId=${this.id}`)
      const stages = competition.contentList
      if (stages) {
        const stage = stages.find(e => e.stageId === this.stageId)
        const item = competition.competitionStage.find(e => e.stageId === this.stageId)
        if (item) {
          stage.stageName = item.stageName
          stage.resultAnnouncementTime = item.resultAnnouncementTime
        }
        this.curStage = stage
        const endTime = new Date(stage.endTime)
        const now = await Util.getNow()
        // 如果已经结束
        if (now >= endTime) {
          this.loading = false
          this.$alert('竞赛时间已到，系统已自动交卷', '提示', {
            confirmButtonText: '确定'
          })
          this.submit(1)
        } else { // 没结束，则显示倒计时
          this.countVal = (endTime - now) / 1000
          load && this.getPaper(now)
        }
      }
    },
    // 获取试卷详情
    async getPaper (now) {
      try {
        const { paperId, stageId } = this.curStage
        if (paperId) {
          // 试卷详情
          const { examPaper } = await this.$get(this.api.examPaperDetails, { id: paperId })

          // 缓存，如果有，则全部回显到页面上
          const { examSubmitReq: cache } = await this.$post(this.api.getExamPaperCache, {
            competitionId: this.id,
            paperId,
            stageId
          })
          let cacheQues = []
          if (cache) {
            this.entryTime = new Date(cache.startTime)
            this.timeSumVal = (now - new Date(cache.startTime)) / 1000
            cacheQues = cache.examSubmitJudgeList
          } else {
            this.entryTime = now
          }
          this.startCount()

          const r = examPaper
          const paper = r.paperOutline
          const types = this.questionTypes
          paper.map(e => {
            const type = e.questionType
            e.questionTypeName = types.find(n => n.id === type).name
            e.shrink = false
            e.examQuestions.map(n => {
              Object.assign(n, n.question)
              const curQues = cacheQues.find(m => m.outlineId === e.outlineId && m.questionVersionId === n.questionVersionId) // 缓存里的试题
              n.sign = curQues ? curQues.sign : 0
              const opts = n.questionAnswerVersionsList
              if (type !== 'fill_blank' && type !== 'essay' && opts) { // 选择题
                opts.map(m => {
                  m.answer = curQues && curQues.answer && curQues.answer.length && curQues.answer.some(n => n == m.optionNumber) ? 1 : 0
                })
                if (opts.some(m => m.answer)) n.answered = 1
              } else if (type === 'fill_blank') { // 填空题
                n.fills = curQues && curQues.answer && curQues.answer.length && curQues.answer.some(m => m) ? curQues.answer : ''
                let { answerData } = opts[0]
                if (answerData) answerData = JSON.parse(answerData)
                n.answered = n.fills && answerData && answerData.length === n.fills.filter(m => m).length ? 1 : 0
                n.partAnswer = n.fills && answerData && answerData.length !== n.fills.filter(m => m).length ? 1 : 0
                n.stem = this.getQuesStem(n)
              } else if (type === 'essay') { // 简答题
                n.answer = type === 'essay' && curQues ? curQues.answerContent : ''
                n.attachmentName = curQues ? curQues.attachmentName : ''
                n.attachmentUrl = curQues ? curQues.attachmentUrl : ''
                n.fileList = []
                if (n.attachmentUrl) {
                  n.fileList = [{
                    name: n.attachmentName,
                    url: n.attachmentUrl
                  }]
                }
                // 附件
                const url = n.attachmentUrl
                if (url) {
                  n.uploadList = [{
                    name: n.attachmentName || url,
                    url
                  }]
                }
                if (n.answer || url) n.answered = 1
              }
            })
          })
          this.form = r
          this.loading = false

          // 给填空题的每个空监听input事件，用以显示已作答状态
          this.$nextTick(() => {
            cache || this.submit(0) // 如果没有缓存，则先缓存一次（只是为了缓存进入时间，因为只有在每个小题答题后才会调缓存接口，所以只能第一次进入就缓存一次进入时间）
            paper.map(e => {
              e.examQuestions.map(n => {
                if (e.questionType === 'fill_blank') {
                  const stem = document.querySelector(`#stem` + n.id)
                  if (stem) {
                    const inputs = stem.querySelectorAll('.fill-input')
                    if (inputs) {
                      for (const e of inputs) {
                        e.addEventListener('input', () => {
                          const answers = []
                          let hasFillLen = 0
                          for (const e of inputs) {
                            const val = e.innerText
                            if (val) hasFillLen++
                            answers.push(val)
                          }
                          n.fills = answers
                          n.answered = hasFillLen === inputs.length ? 1 : 0
                          n.partAnswer = hasFillLen && hasFillLen !== inputs.length ? 1 : 0

                          clearTimeout(this.timer)
                          this.timer = setTimeout(() => {
                            this.submit(0)
                            this.calcProgress()
                          }, 500)
                        })
                      }
                    }
                  }
                }
              })
            })
            this.calcProgress()
          })
        }
      } catch (e) {
        this.loading = false
      }
    },
    // 计时器
    handleCounter (counterTime, isCount) {
      let leave1 = counterTime % (24 * 3600) //计算天数后剩余的毫秒数
      let leave2 = leave1 % 3600 //计算小时数后剩余的毫秒数
      let leave3 = leave2 % 60 //计算分钟数后剩余的毫秒数
      let day = Math.floor(counterTime / (24 * 3600)) //计算相差天数
      let hour = Math.floor(leave1 / 3600) //计算相差小时
      let minutes = Math.floor(leave2 / 60) //计算相差分钟
      let seconds = Math.round(leave3) //计算相差秒
      day = this.timeFormat(day)
      hour = this.timeFormat(hour)
      minutes = this.timeFormat(minutes)
      seconds = this.timeFormat(seconds)
      const count = this[isCount ? 'counterVal' : 'timeSum']
      count.day = day
      count.hour = hour
      count.minutes = minutes
      count.seconds = seconds
    },
    // 计时前的判断
    counter (counterTime) {
      if (counterTime <= 0) {
        if (this.per) { // 竞赛/考核
          clearInterval(this.counterTimer)
          this.$alert(`${this.per == 2 ? '竞赛' : '考核'}时间已到，系统已自动交卷`, '提示', {
            confirmButtonText: '确定',
            type: 'warning'
          })
          this.submit(1)
        } else {
          this.handleCounter(counterTime, 1)
        }
      } else {
        // 剩15分钟时要提示
        if (counterTime === 900) {
          this.warned || this.$alert(`请注意，${this.per == 2 ? '比赛' : '考核'}还剩15分钟，请尽快完成答题并提交试卷。`, '提示', {
            confirmButtonText: '确定',
            type: 'warning'
          })
          this.warned = 1
        }
        this.handleCounter(counterTime, 1)
      }
    },
    // 启动倒计时
    startCount () {
      clearInterval(this.counterTimer)
      this.counterTimer = setInterval(() => {
        this.counter(this.per ? this.countVal-- : this.countVal++)
        this.timeSumVal >= 0 && this.handleCounter(this.timeSumVal++)
      }, 1000)
    },
    timeFormat (param) {
      return param < 10 ? '0' + param : param
    },
    // 计算答题进度
    calcProgress () {
      let answered = 0
      this.form.paperOutline.map(e => {
        answered += e.examQuestions.filter(n => n.answered).length
      })
      this.totalAnswered = answered
      this.progress = +(answered / this.form.questionCount * 100).toFixed(1)
    },
    // 答题进度格式
    progressFormat (e) {
      return this.totalAnswered + '/' + this.form.questionCount
    },
    scrollToSmooth (position, duration) {
      let startTime = Date.now()

      function scroll () {
        let now = Date.now()
        let progress = Math.min(1, (now - startTime) / duration)
        document.querySelector('#quesWrap').scrollTo(0, position * progress)

        if (progress < 1) {
          window.requestAnimationFrame(scroll)
        }
      }

      window.requestAnimationFrame(scroll)
    },
    // 答题卡题目点击滚动
    scrollToQues (e, item) {
      item.shrink = false
      const el = document.querySelector('#ques' + e.id)
      this.$nextTick(() => {
        el && this.scrollToSmooth(el.offsetTop - document.querySelector('#quesWrap').offsetTop, 200)
      })
    },
    // 答题卡筛选
    filterStatus (e) {
      this.sheetStatus = this.sheetStatus === e ? '' : e
    },
    // 处理题干显示
    getQuesStem (ques) {
      let { stem } = ques
      if (ques.questionType === 'fill_blank') { // 填空题
        let { fills } = ques

        const regex = /<span class="gapfilling-span" data-id="(.*?)">______<\/span>/g
        let match
        let index = 0 // 用于跟踪索引
        let result = stem

        while ((match = regex.exec(stem)) !== null) {
          const newInput = `<span contenteditable placeholder="(${index + 1})" class="fill-input">${fills && fills.length ? fills[index] : ''}</span>`
          result = result.replace(match[0], newInput)
          index++
        }
        return result
      } else {
        return stem
      }
    },
    preventAllKeyPress (event) {
      // 阻止所有键盘事件
      event.preventDefault();
    },
    // 单选题回调
    singleChange (ques, j) {
      ques.questionAnswerVersionsList.map(e => {
        e.answer = 0
      })
      ques.questionAnswerVersionsList[j].answer = 1

      ques.answered = 1
      this.calcProgress()
      this.submit(0)
    },
    // 多选题回调
    mulChange (ques) {
      ques.answered = ques.questionAnswerVersionsList.some(e => e.answer)
      this.calcProgress()
      this.submit(0)
    },

    // 简答题富文本加载完毕回调
    essayAnswerReady (editor, ques) {
      editor.ques = ques
      editor.addListener('contentChange', () => {
        const content = editor.getContent()
        ques.answered = content ? 1 : 0
        ques.answers = content

        clearTimeout(this.timer)
        this.timer = setTimeout(() => {
          this.submit(0)
          this.calcProgress()
        }, 500)
      })
      ques.answer && editor.setContent(ques.answer)
    },
    // 预览附件
    preview (url) {
      const ext = url.split('.').pop()
      if (Util.isDoc(ext)) {
        window.open('https://view.officeapps.live.com/op/view.aspx?src=' + url)
      } else if (Util.isImg(ext)) {
        this.previewImgVisible = true
        this.previewImg = url
      } else if (ext === 'pdf') {
        this.pdfVisible = true
        this.pdfSrc = url
      }
    },
    // 下载附件
    download (name, url) {
      Util.downloadFile(name, url)
    },


    async initOss () {
      const o = await OssConfig()
      this.client = new OSS(o.config)
    },
    // 附件上传前
    beforeUpload (file) {
      const oversize = file.size / 1024 / 1024 < 50
      if (!oversize) Util.warningMsg('请上传小于50M的文件！')
      if (oversize) {
        return true
      } else {
        return false
      }
    },
    // 自定义上传
    async handleRequest (e, ques) {
      const { file } = e
      try {
        ques.fileList = []
        const { name } = await this.client.multipartUpload(Date.now() + '.' + Util.getFileExt(file.name), file)
        const url = 'https://huoran.oss-cn-shenzhen.aliyuncs.com/' + name
        ques.fileList = [{
          name: file.name,
          url
        }]
        ques.attachmentName = file.name
        ques.attachmentUrl = url
        this.submit(0)
      } catch (e) { }
    },
    handlePreview ({ url }) {
      this.preview(url)
    },
    uploadError () {
      this.$message({
        message: "上传出错，请重试！",
        type: "error",
        center: true
      })
    },
    beforeRemove (file) {
      return this.$confirm(`确定移除 ${file.name}？`);
    },
    handleExceed () {
      Util.warningMsg(`当前限制选择 1 个文件，如需更换，请删除上一个文件再重新选择！`);
    },
    handleRemove (ques) {
      Oss.del(ques.attachmentUrl)
      ques.fileList = []
      ques.attachmentName = ''
      ques.attachmentUrl = ''
      this.submit(0)
    },


    // 解析富文本加载完毕回调
    answerAnalysisReady (editor) {
      this.answerAnalysis && editor.setContent(this.answerAnalysis)
    },
    // 提交询问
    async confirmSubmit () {
      if (this.submiting) return false
      let msg = '此操作将视为结束答题，确认要提交吗？'

      for (const e of this.form.paperOutline) {
        if (e.examQuestions.some(n => !n.answered)) {
          msg = '还有试题未答完，确认要提交吗？'
          break
        }
      }
      try {
        await this.$confirm(msg, '提示', {
          // confirmButtonText: '确定',
          // cancelButtonText: '取消',
          type: 'warning',
          closeOnClickModal: false
        })
        this.submit(1)
      } catch (e) { }
    },
    // 提交
    async submit (isSubmit) {
      if (isSubmit && this.submiting) return false
      try {
        if (isSubmit) this.submiting = true
        const form = _.cloneDeep(this.form)
        const { entryTime, curStage } = this
        const ques = []
        form.paperOutline.map(e => {
          const type = e.questionType
          e.examQuestions.map(n => {
            let answer = []
            let answerContent = ''
            if (type !== 'fill_blank' && type !== 'essay') { // 选择题
              answer = n.questionAnswerVersionsList.filter(m => m.answer).map(m => m.optionNumber)
            } else if (type === 'essay') { // 简答题
              if (n.answers) answerContent = n.answers
            } else { // 填空题
              answer = n.fills || []
            }
            ques.push({
              answer,
              answerContent,
              attachmentName: n.attachmentName,
              attachmentUrl: n.attachmentUrl,
              outlineId: e.outlineId,
              questionType: type,
              questionVersionId: n.questionVersionId,
              serialNumber: n.serialNumber,
              setScore: n.score,
              sign: n.sign,
            })
          })
        })

        const data = {
          competitionId: this.id,
          stageId: curStage.stageId,
          teamId: this.teamId,
          startTime: Util.formatDate('yyyy-MM-dd hh:mm:ss', entryTime), // 取页面进入的时间
          totalScore: form.score,
          paperId: curStage.paperId,
          examSubmitJudgeList: ques,
        }
        // if (isSubmit) {
        const now = isSubmit ? await Util.getNow() : new Date()
        const submitTime = Util.formatDate('yyyy-MM-dd hh:mm:ss', now)
        data.endTime = this.per ? curStage.endTime : submitTime
        data.submitTime = submitTime
        data.timeSum = Math.ceil((now - entryTime) / 60000) // 计算实验用时（分钟），向上取整
        // }

        // 缓存跟提交接口的参数一样
        await this.$post(this.api[isSubmit ? 'submitTheExamPaper' : 'examPaperRecordCache'], data)

        if (isSubmit) {
          window.opener && window.opener.location.reload()
          clearInterval(this.counterTimer)
          this.submiting = false
          this.submited = true
          // 如果是竞赛，并且勾选了公布成绩详情的选项，则弹框提示
          if (this.id) {
            const time = curStage.resultAnnouncementTime
            const msg =
              time === 0 ? '提交成功！成绩将在比赛结束后公布，请前往参赛信息模块查看' : time > 0 ? `提交成功！成绩将在比赛结束后${time}小时公布，请前往参赛信息模块查看` : '提交成功';
            this.$alert(msg, '提示', {
              confirmButtonText: '确定',
              type: 'success',
              callback: () => {
                this.close()
              }
            })
          } else {
            this.$message.success('提交成功！')
          }
        }
      } catch (e) {
        this.submiting = false
      }
    },
    close () {
      window.close()
    },
  }
};
</script>

<style lang="scss" scoped>
.top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 20px;
  color: #fff;
  background-color: #5786fc;

  .item {
    display: inline-flex;
    align-items: center;
  }

  .names {
    font-size: 18px;
    font-weight: 600;
  }

  .submit {
    width: 106px;
    font-size: 15px;
  }

  .exit {
    margin-left: 20px;
    cursor: pointer;

    &:hover {
      opacity: .9;
    }
  }
}

/deep/.wrap {
  display: flex;
  padding: 15px;

  .left {
    width: 293px;
    margin-right: 15px;
    background-color: #fff;

    .title {
      padding: 10px 0;
      font-size: 16px;
      text-align: center;
      color: #333;
    }

    .progress {
      padding: 10px;
      color: #5a5a5a;
      background-color: #d4e9ff;
    }

    .type-wrap {
      max-height: calc(100vh - 297px);
      padding: 10px;
      overflow: auto;

      .type {
        margin-bottom: 20px;
      }

      .stem {
        font-size: 15px;
        color: #333;
      }
    }

    .serials {
      display: flex;
      flex-wrap: wrap;
      margin-top: 5px;

      li {
        position: relative;
        width: 30px;
        margin: 7px 9px;
        font-size: 13px;
        text-align: center;
        line-height: 30px;
        color: #505050;
        border: 1px solid #d3d3d3;
        cursor: pointer;

        &:hover {
          opacity: .9;
        }

        &.answered {
          color: #fff;
          background-color: #66b2ff;
          border-color: #66b2ff;
        }

        &.partAnswer {
          border-color: #66b2ff;
        }
      }

      .tag {
        position: absolute;
        top: -2px;
        left: -4px;
      }
    }

    .status-filter {
      display: flex;
      justify-content: space-between;
      padding: 10px;
      border-top: 1px solid #e5e5e5;

      li {
        display: inline-flex;
        align-items: center;
        padding: 0 3px;
        font-size: 12px;
        color: #333;
        cursor: pointer;
        border: 1px solid transparent;

        &:not(:last-child):before {
          content: '';
          width: 13px;
          height: 13px;
          margin-right: 5px;
          border: 1px solid #ccc;
        }

        &:nth-child(2):before {
          background-color: #56aaff;
          border: 0;
        }

        &:nth-child(3):before {
          border-color: #56aaff;
        }

        &.active {
          font-weight: 600;
          color: #007eff;
          border-color: #007eff;

          &:last-child {
            color: #d81e06;
            border-color: #d81e06;
          }
        }
      }
    }
  }

  .ques-wrap {
    width: calc(100% - 308px);
    height: calc(100vh - 128px);
    background-color: #fff;
    overflow: auto;
    outline: none;

    &>li {
      margin-bottom: 15px;
    }

    .outline {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 10px 15px;
      font-size: 15px;
      font-weight: 600;
      color: #333;
      background-color: #e8f0ff;
    }

    .shrink {
      cursor: pointer;
      transition: .5s;

      &.active {
        transform: rotate(180deg);
      }
    }

    .ques {
      max-height: none;
      padding: 15px;
      margin-bottom: 15px;
      transition: all 1.5s;
      overflow: hidden;

      &.hide {
        max-height: 10px;
      }
    }

    .item:not(:last-child) {
      padding-bottom: 15px;
      margin-bottom: 15px;
      border-bottom: 1px dashed #e1e1e1;
    }

    .stem-wrap {
      display: flex;
      align-items: baseline;
      margin-bottom: 10px;
    }

    img {
      max-width: 100%;
    }

    .tag {
      margin-left: 10px;
      cursor: pointer;

      &:hover {
        opacity: .9;
      }
    }

    .labels {
      display: inline-flex;
      align-items: center;
    }

    .label {
      padding: 3px 5px;
      margin-right: 10px;
      font-size: 12px;
      line-height: 1;
      color: $main-color;
      white-space: nowrap;
      border: 1px solid;
      border-radius: 2px;
    }

    .stem {
      max-width: calc(100% - 197px);
    }

    .fill-input {
      position: relative;
      display: inline;
      min-width: 50px;
      height: 28px;
      padding: 3px;
      margin: 0 10px;
      font-size: 14px;
      line-height: 28px;
      color: #333;
      border: 0;
      border-bottom: 1px solid #DCDEE0;
      outline: none;

      &:empty {
        display: inline-block;
        width: 3em;
      }

    }

    .opt {
      display: flex;
      flex-wrap: wrap;
      align-items: baseline;
      padding-left: 10px;
      margin-bottom: 5px;
      font-size: 14px;
      color: #707070;
      line-height: 1.6;

      .el-radio,
      .el-checkbox {
        margin-right: 15px;
      }

      .el-radio__label {
        display: none;
      }

      .text {
        max-width: calc(100% - 48px);
      }
    }
  }
}
</style>