首页 > 其他分享 >【Vue】考试功能实现

【Vue】考试功能实现

时间:2024-08-20 11:05:02浏览次数:6  
标签:COMMENT 功能 Vue const utf8mb4 dataForm paperList NULL 考试

一、需求场景

 最近临时加的一个功能模块,让我两天就实现....

 部门成员需要进行测验考试,简单来说就是刷题练习

 关于题库导入的部分在这篇文章已经写好了:https://www.cnblogs.com/mindzone/p/18362194

 分值计算的需求目前没加入进来,只判断对错与否,然后计数题目总数和做对题数

二、表结构

考试题库

DROP TABLE IF EXISTS `trn_ex_qabank`;
CREATE TABLE `trn_ex_qabank` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `qa_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '考题类型',
  `qa_subject` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '考题题目',
  `qa_answer` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '考题答案',
  `qa_analy` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '考题分析',
  `cre_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `cre_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '创建人',
  `upd_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  `upd_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '更新人',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考试题库';

考试信息

DROP TABLE IF EXISTS `trn_ex_info`;
CREATE TABLE `trn_ex_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `in_code` varchar(14) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '考试编号',
  `in_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
  `in_username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名',
  `qa_sc_total` int(11) NOT NULL COMMENT '单选总数',
  `qq_sc_hit` int(11) NOT NULL COMMENT '单选正确数',
  `qa_mc_total` int(11) NOT NULL COMMENT '多选总数',
  `qa_mc_hit` int(11) NOT NULL COMMENT '多选正确数',
  `qa_ju_total` int(11) NOT NULL COMMENT '判断总数',
  `qa_ju_hit` int(11) NOT NULL COMMENT '判断正确数',
  `qa_sa_total` int(11) NOT NULL COMMENT '简单总数',
  `qa_sa_hit` int(11) NOT NULL COMMENT '简单正确数',
  `in_aw_state` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '考试状态',
  `in_ap_state` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '评卷状态',
  `cre_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '创建人',
  `upd_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  `upd_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '更新人',
  `cre_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考试信息';

考试试卷

DROP TABLE IF EXISTS `trn_ex_paper`;
CREATE TABLE `trn_ex_paper` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `trn_ex_in_id` int(11) NOT NULL COMMENT '所属考次',
  `trn_ex_qa_id` int(11) NOT NULL COMMENT '所属题目',
  `qa_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '考题类型',
  `qa_subject` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '考题题目',
  `qa_sa_answer` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '考题答案',
  `pa_state` char(1) NOT NULL COMMENT '是否答题',
  `is_right` char(1) NOT NULL COMMENT '是否正确',
  `cre_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '创建人',
  `upd_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '更新人',
  `upd_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  `cre_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考试试卷';

  

三、功能实现

1、生成考卷接口

目前的设计是放到考试表单中让用户自己决定每种题型的数量

SQL实现通过 ORDER BY RAND() LIMIT【题型数】

List<TrnExQabankListVO> fetchRandomCollect(@Param("qaType") String qaType, @Param("limit") Integer limit);

mapper映射文件

<select id="fetchRandomCollect" resultType="cn.anmte.cper.model.TrnExQabankListVO">
    SELECT a.* FROM trn_ex_qabank a WHERE a.qa_type = #{qaType} ORDER BY RAND() LIMIT #{limit}
</select>

业务方法:

@Override
public List<TrnExQabankListVO> createExam(TrnExInfoForm trnExInfoForm) {
    Integer qaScTotal = trnExInfoForm.getQaScTotal();
    Integer qaMcTotal = trnExInfoForm.getQaMcTotal();
    Integer qaJuTotal = trnExInfoForm.getQaJuTotal();
    Integer qaSaTotal = trnExInfoForm.getQaSaTotal();
List<TrnExQabankListVO> radioTypeList = baseMapper.fetchRandomCollect(DbcpExamUtil.TYPE1_RADIO, qaScTotal); List<TrnExQabankListVO> checkboxTypeList = baseMapper.fetchRandomCollect(DbcpExamUtil.TYPE2_CHECKBOX, qaMcTotal); List<TrnExQabankListVO> trueOrFalseTypeList = baseMapper.fetchRandomCollect(DbcpExamUtil.TYPE3_TRUE_OR_FASE, qaJuTotal); List<TrnExQabankListVO> shortQaTypeList = baseMapper.fetchRandomCollect(DbcpExamUtil.TYPE4_SHORT_QA, qaSaTotal);
List<TrnExQabankListVO> paperList = new ArrayList<>(); paperList.addAll(radioTypeList); paperList.addAll(checkboxTypeList); paperList.addAll(trueOrFalseTypeList); paperList.addAll(shortQaTypeList); return paperList; }

  

2、界面表单参数:

这里我设置默认题型数量,除了简答题为5题,其他设置为10题

可以生成试卷,也可以重置试卷,刷新题目重做

已经保存的和已经交卷的试卷不能再重新生成试卷

试卷生成方法:

因为要展示生成试卷的序号,正好追加一个序号属性,通过序号对题目元素进行CRUD的操作

    createExamItems() {
      this.$refs['dataForm'].validate((valid) => {
        if (!valid) return
        this.btnLoading = true
        const { qaScTotal, qaMcTotal, qaJuTotal, qaSaTotal } = this.dataForm
        const allOptions = [qaScTotal, qaMcTotal, qaJuTotal, qaSaTotal]
        const isEmptyOption = allOptions.every(opt => opt === 0)
        if (isEmptyOption) return this.$message.error('无效总数,请调整后尝试')
        createExamPapers({qaScTotal, qaMcTotal, qaJuTotal, qaSaTotal}).then(res => {
          const totalPapers = res.data.map((x, idx, arr) => {
            return {
              ...x,
              id: '',
              trnExInId: '', /* 无考次 */
              trnExQaId: x.id,
              qaSaAnswer: '', /* 默认清空答案 */
              paState: '0', /* 未答题 */
              isRight: '0', /* 错误 */
              no: idx + 1
            }
          })
          this.dataForm.paperList = [...totalPapers]
          this.radioTypePapers = [...totalPapers.filter(p => p.qaType === '0')]
          this.checkTypePapers = [...totalPapers.filter(p => p.qaType === '1')]
          this.tureFalseTypePapers = [...totalPapers.filter(p => p.qaType === '2')]
          this.shortQaTypePapers = [...totalPapers.filter(p => p.qaType === '3')]

          /* 置为当前第一道题 */
          this.currentPaperIdx = 1
          this.whenPaperIdxChange(this.currentPaperIdx)
          this.btnLoading = false
        });
      })
    },

题目清除方法:

清除当前题目下标和试题及每种题型

    clearExamItems() {
      this.dataForm.paperList = []
      this.radioTypePapers = []
      this.checkTypePapers = []
      this.tureFalseTypePapers = []
      this.shortQaTypePapers = []
      this.currentPaperIdx = 0
    },
当前题目对象:
currentPaperIdx: 0,
currentPaper: {
  id: '',
  trnExInId: '',
  trnExQaId: '',
  qaType: '',
  qaSubject: '',
  qaAnswer: '',
  qaSaAnswer: '',
  qaSaCheckboxAnswer: [],
  paState: '',
  qaAnaly: '',
  isRight: ''
},

3、题目交互界面

我最开始的项目就是一个集合全渲染出来,但是老板又补了句我想做两三百题目这页面不得卡死来

题目切换方法:

async whenPaperIdxChange(val) {
  const targetPaper = this.dataForm.paperList.find(p => p.no === val)
  if (this.dataForm.inAwState === '1') {
    const { trnExQaId } = targetPaper
    const { data: qaInfo } = await getQaBankInfo(trnExQaId)
    if (qaInfo) {
      this.currentPaper = {
        ... targetPaper,
        qaSaCheckboxAnswer: [],
        qaAnswer: targetPaper.qaType === '3' ? '' : qaInfo.qaAnswer,
        qaAnaly: targetPaper.qaType === '3' ? qaInfo.qaAnswer : qaInfo.qaAnaly }
    } else {
      this.currentPaper = {
        ... targetPaper,
        qaSaCheckboxAnswer: [],
        qaAnswer: '',
        qaAnaly: ''
      }
    }
  } else {
    const isCheckBox = targetPaper.qaType === '1'
    this.currentPaper = { ... targetPaper, qaSaCheckboxAnswer: isCheckBox ? [... targetPaper.qaSaAnswer] : [] }
    console.log(this.currentPaper)
  }
},

1、所以就想到应该是当前只展示一个题目,然后上面会放上每个题目的单选框和序号,点击序号单选框跳转到这题来

题型组件代码:

<el-row v-if="dataForm.paperList.length > 0" class="nav-div"><i class="el-icon-document nav-title" />考试试题</el-row>
<el-row :gutter="15">
  <jnpf-form-tip-item label="单选题" prop="" v-if="radioTypePapers.length > 0">
    <el-radio-group v-model="currentPaperIdx" @change="whenPaperIdxChange">
      <el-badge v-for="(item, idx) in radioTypePapers" :key="`radioTypePapers${idx}`" :is-dot="item.paState === '0'" class="pa-state-0-dot">
        <el-radio :label="item.no" class="paper-radio">
          {{ item.no }}
          <el-tag type="success" v-if="item.isRight === '1' && dataForm.inApState === '1'">√</el-tag>
          <el-tag type="danger" v-if="item.isRight === '0' && dataForm.inApState === '1'" >×</el-tag>
        </el-radio>
      </el-badge>
    </el-radio-group>
  </jnpf-form-tip-item>
  <jnpf-form-tip-item label="多选题" prop="" v-if="checkTypePapers.length > 0">
    <el-radio-group v-model="currentPaperIdx" @change="whenPaperIdxChange">
      <el-badge v-for="(item, idx) in checkTypePapers" :key="`checkTypePapers${idx}`" :is-dot="item.paState === '0'" class="pa-state-0-dot">
        <el-radio :label="item.no" class="paper-radio">
          {{ item.no }}
          <el-tag type="success" v-if="item.isRight === '1' && dataForm.inApState === '1'">√</el-tag>
          <el-tag type="danger" v-if="item.isRight === '0' && dataForm.inApState === '1'" >×</el-tag>
        </el-radio>
      </el-badge>
    </el-radio-group>
  </jnpf-form-tip-item>
  <jnpf-form-tip-item label="判断题" prop="" v-if="tureFalseTypePapers.length > 0">
    <el-radio-group v-model="currentPaperIdx" @change="whenPaperIdxChange">
      <el-badge v-for="(item, idx) in tureFalseTypePapers" :key="`tureFalseTypePapers${idx}`" :is-dot="item.paState === '0'" class="pa-state-0-dot">
        <el-radio :label="item.no" class="paper-radio">
          {{ item.no }}
          <el-tag type="success" v-if="item.isRight === '1' && dataForm.inApState === '1'">√</el-tag>
          <el-tag type="danger" v-if="item.isRight === '0' && dataForm.inApState === '1'" >×</el-tag>
        </el-radio>
      </el-badge>
    </el-radio-group>
  </jnpf-form-tip-item>
  <jnpf-form-tip-item label="简答题" prop="" v-if="shortQaTypePapers.length > 0">
    <el-radio-group v-model="currentPaperIdx" @change="whenPaperIdxChange">
      <el-badge v-for="(item, idx) in shortQaTypePapers" :key="`shortQaTypePapers${idx}`" :is-dot="item.paState === '0'" class="pa-state-0-dot">
        <el-radio :label="item.no" class="paper-radio">
          {{ item.no }}
          <el-tag type="success" v-if="item.isRight === '1' && dataForm.inApState === '1'">√</el-tag>
          <el-tag type="danger" v-if="item.isRight === '0' && dataForm.inApState === '1'" >×</el-tag>
        </el-radio>
      </el-badge>
    </el-radio-group>
  </jnpf-form-tip-item>
</el-row>

2、除了点击序号单选,还可以像翻页一样,跳转到上一题和下一题

goToPrevPaper() {
  if (this.currentPaperIdx === 1) return this.$message.warning('已经是第一道题了!')
  const currIdx = this.currentPaperIdx -= 1
  this.whenPaperIdxChange(currIdx)
},
goToNextPaper() {
  const lastNo = this.dataForm.paperList.length
  if (this.currentPaperIdx === lastNo) return this.$message.warning('已经是最后一道题了!')
  const currIdx = this.currentPaperIdx += 1
  this.whenPaperIdxChange(currIdx)
},

  

3、确定是确认当前题目的答题内容,同时设置当前题目为【已答题】状态

4、为了方便展示有些那些题目没做,使用小红点badge标识是否答题

5、最开始设置答题表单项的时候默认统一用文本域处理,然后迭代成根据题型标识动态显示,

   单选题、判断题、简答题都可以使用单选框、文本域简单处理

<el-row :gutter="15" v-if="currentPaperIdx !== 0 && dataForm.inApState !== '1'">
  <jnpf-form-tip-item label-width="30px">
    <div class="qa-subject" v-html="currentPaper.qaSubject ? currentPaper.qaSubject.replaceAll('\n', '<br/>') : ''" />
    <el-radio-group v-if="currentPaper.qaType === '0'" v-model="currentPaper.qaSaAnswer">
      <el-radio :disabled="isDetail" label="A">A</el-radio>
      <el-radio :disabled="isDetail" label="B">B</el-radio>
      <el-radio :disabled="isDetail" label="C">C</el-radio>
      <el-radio :disabled="isDetail" label="D">D</el-radio>
      <el-radio :disabled="isDetail" label="E">E</el-radio>
      <el-radio :disabled="isDetail" label="F">F</el-radio>
    </el-radio-group>
    <el-checkbox-group v-if="currentPaper.qaType === '1'" v-model="currentPaper.qaSaCheckboxAnswer">
      <el-checkbox :disabled="isDetail" label="A">A</el-checkbox>
      <el-checkbox :disabled="isDetail" label="B">B</el-checkbox>
      <el-checkbox :disabled="isDetail" label="C">C</el-checkbox>
      <el-checkbox :disabled="isDetail" label="D">D</el-checkbox>
      <el-checkbox :disabled="isDetail" label="E">E</el-checkbox>
      <el-checkbox :disabled="isDetail" label="F">F</el-checkbox>
    </el-checkbox-group>
    <el-radio-group v-if="currentPaper.qaType === '2'" v-model="currentPaper.qaSaAnswer">
      <el-radio :disabled="isDetail" label="A">A / 对</el-radio>
      <el-radio :disabled="isDetail" label="B">B / 错</el-radio>
    </el-radio-group>
    <el-input v-if="currentPaper.qaType === '3'" :class="{'cus-detail':isDetail}" v-model="currentPaper.qaSaAnswer" maxlength="1024" show-word-limit type="textarea" :rows="6" placeholder="请输入考题答案" clearable :disabled="isDetail" />
  </jnpf-form-tip-item>
</el-row>

  

   但是复选框要处理一下,在选中题目的时候 回显选项,确定事件时转换选项保存

 回显复选框答案:

 展示效果

点击确定时的保存方法处理:

currentPaperSubmit() {
  const { qaSaAnswer, qaType, qaSaCheckboxAnswer } = this.currentPaper
  const isCheckBox = qaType === '1'
  if (isCheckBox && qaSaCheckboxAnswer.length === 0) return this.$message('请填写答案!')
  else if (!isCheckBox && !qaSaAnswer) return this.$message('请填写答案!')
  const target = this.dataForm.paperList.find(x => x.no === this.currentPaperIdx)
  const paperIdx = this.dataForm.paperList.indexOf(target)
  let optTarget, optIdx
  switch (qaType) {
    case '0':
      optTarget = this.radioTypePapers.find(x => x.no === this.currentPaperIdx)
      optIdx = this.radioTypePapers.indexOf(optTarget)
      this.$set(this.radioTypePapers[optIdx], 'paState', '1')
      break
    case '1':
      optTarget = this.checkTypePapers.find(x => x.no === this.currentPaperIdx)
      optIdx = this.checkTypePapers.indexOf(optTarget)
      this.$set(this.checkTypePapers[optIdx], 'paState', '1')
      break
    case '2':
      optTarget = this.tureFalseTypePapers.find(x => x.no === this.currentPaperIdx)
      optIdx = this.tureFalseTypePapers.indexOf(optTarget)
      this.$set(this.tureFalseTypePapers[optIdx], 'paState', '1')
      break
    case '3':
      optTarget = this.shortQaTypePapers.find(x => x.no === this.currentPaperIdx)
      optIdx = this.shortQaTypePapers.indexOf(optTarget)
      this.$set(this.shortQaTypePapers[optIdx], 'paState', '1')
      break
  }
  this.$set(this.dataForm.paperList[paperIdx], 'qaSaAnswer', isCheckBox ? qaSaCheckboxAnswer.join('')  : qaSaAnswer)
  this.$set(this.dataForm.paperList[paperIdx], 'paState', '1')
  this.$message.success('答题成功')
},

  

6、存在一次考试做好几百道题的情况,不一定马上交卷

    提交按钮就分为【保存】和 【交卷】

 

保存和交卷逻辑:

    examSubmit() {
      if (this.dataForm.paperList.length === 0) return this.$message.error('没有要提交的试题!')
      this.$refs['dataForm'].validate((valid) => {
        if (!valid) return
        const undoneCount = this.dataForm.paperList.filter(x => x.paState === '0').length
        const hasUndone = undoneCount > 0
        this.$confirm(`还有${undoneCount}道题目未完成, 是否交卷?`, '提示', {
          type: 'warning'
        }).then(() => {
          this.btnLoading = true
          let _data = this.dataList()
          examDataSubmit(_data).then((res) => {
            this.$message({
              message: res.msg,
              type: 'success',
              duration: 1000,
              onClose: () => {
                this.localVisible = false
                this.btnLoading = false
                this.$emit('refresh', true)
              }
            })
          }).catch(() => {
            this.btnLoading = false
          })
        }).catch(() => { })
      })
    },
    examSave() {
      if (this.dataForm.paperList.length === 0) return this.$message.error('没有要提交的试题!')
      this.$refs['dataForm'].validate((valid) => {
        if (!valid) return
        const undoneCount = this.dataForm.paperList.filter(x => x.paState === '0').length
        const hasUndone = undoneCount > 0
        this.$confirm(`还有${undoneCount}道题目未完成, 是否保存?`, '提示', {
          type: 'warning'
        }).then(() => {
          this.request()
        }).catch(() => { })
      })
    },

  

三、评卷功能实现

在交卷后,除了简答题外,其他题目可以通过查询题库id判断是否正确

交卷接口的业务实现:

    @Override
    public void evaluationSubmit(TrnExInfoForm form) {
        Integer trnExId = form.getId();
        /* 清除历史存留 */
        List<Integer> collect = lambdaQuery().eq(TrnExPaper::getTrnExInId, trnExId).list().stream().map(TrnExPaper::getId).collect(Collectors.toList());
        boolean hasExist = CollectionUtils.isNotEmpty(collect);
        if (hasExist) baseMapper.deleteBatchIds(collect);

        /* 计算对错,评估得分 */
        List<TrnExPaper> paperList = form.getPaperList();
        List<Integer> qaIdList = paperList.stream().map(TrnExPaper::getTrnExQaId).collect(Collectors.toList());
        List<TrnExQabank> trnExQabanks = trnExQabankMapper.selectBatchIds(qaIdList);

        for (TrnExPaper trnExPaper : paperList) {
            trnExPaper.setTrnExInId(form.getId());
            /* 简答题默认错误 */
            if (DbcpExamUtil.TYPE4_SHORT_QA.equals(trnExPaper.getQaType())) {
                trnExPaper.setIsRight(TrainingConstant.IS_RIGHT_NO);
                baseMapper.insert(trnExPaper);
                continue;
            }
            /* 其他类型则判断是否匹配了题库,如果没有则按错误处理,反之匹配是否正确 */
            Optional<TrnExQabank> qaOpt = trnExQabanks.stream().filter(qa -> qa.getId().equals(trnExPaper.getTrnExQaId())).findFirst();
            boolean matched = qaOpt.isPresent();
            if (matched) {
                TrnExQabank trnExQabank = qaOpt.get();
                String qaAnswer = trnExQabank.getQaAnswer();
                String qaSaAnswer = trnExPaper.getQaSaAnswer();
                boolean isRight = qaAnswer.equalsIgnoreCase(qaSaAnswer);
                trnExPaper.setIsRight(isRight ? TrainingConstant.IS_RIGHT_YES : TrainingConstant.IS_RIGHT_NO);
            } else trnExPaper.setIsRight(TrainingConstant.IS_RIGHT_NO);
            baseMapper.insert(trnExPaper);
        }

        /* 在写入完成后统计正确个数 */
        Long radioRightCount = paperList.parallelStream().filter(p -> DbcpExamUtil.TYPE1_RADIO.equals(p.getQaType()) && TrainingConstant.IS_RIGHT_YES.equals(p.getIsRight())).count();
        Long checkBoxRightCount = paperList.parallelStream().filter(p -> DbcpExamUtil.TYPE2_CHECKBOX.equals(p.getQaType()) && TrainingConstant.IS_RIGHT_YES.equals(p.getIsRight())).count();
        Long trueFalseRightCount = paperList.parallelStream().filter(p -> DbcpExamUtil.TYPE3_TRUE_OR_FASE.equals(p.getQaType()) && TrainingConstant.IS_RIGHT_YES.equals(p.getIsRight())).count();
        Long shortQaCount = 0L; /* 简答题默认0正确,无法判断 */

        form.setQqScHit(radioRightCount.intValue());
        form.setQaMcHit(checkBoxRightCount.intValue());
        form.setQaJuHit(trueFalseRightCount.intValue());
        form.setQaSaHit(shortQaCount.intValue());
        /* 更新状态 */
        form.setInAwState(TrainingConstant.IN_AW_STATE_FINISH);
        form.setInApState(TrainingConstant.IN_AP_STATE_AWAIT);
    }

  

评卷表单除了之前的内容外,每个题目需要展示对错与否

除了考生提交的答案,还要显示正确答案和解析,并且可以设置是否正确

 

题目对错的展示处理

试题信息是没有正确答案和解析,所以要通过试卷信息的题库id来查询查询题库信息

 阅卷方法保存的是是否正确选项:

currentPaperSubmit() {
  const { isRight, qaType } = this.currentPaper
  const target = this.dataForm.paperList.find(x => x.no === this.currentPaperIdx)
  const paperIdx = this.dataForm.paperList.indexOf(target)
  let optTarget, optIdx
  switch (qaType) {
    case '0':
      optTarget = this.radioTypePapers.find(x => x.no === this.currentPaperIdx)
      optIdx = this.radioTypePapers.indexOf(optTarget)
      this.$set(this.radioTypePapers[optIdx], 'isRight', isRight)
      break
    case '1':
      optTarget = this.checkTypePapers.find(x => x.no === this.currentPaperIdx)
      optIdx = this.checkTypePapers.indexOf(optTarget)
      this.$set(this.checkTypePapers[optIdx], 'isRight', isRight)
      break
    case '2':
      optTarget = this.tureFalseTypePapers.find(x => x.no === this.currentPaperIdx)
      optIdx = this.tureFalseTypePapers.indexOf(optTarget)
      this.$set(this.tureFalseTypePapers[optIdx], 'isRight', isRight)
      break
    case '3':
      optTarget = this.shortQaTypePapers.find(x => x.no === this.currentPaperIdx)
      optIdx = this.shortQaTypePapers.indexOf(optTarget)
      this.$set(this.shortQaTypePapers[optIdx], 'isRight', isRight)
      break
  }
  this.$set(this.dataForm.paperList[paperIdx], 'isRight', isRight)
  this.$message.success('阅卷成功')
},

  

 

标签:COMMENT,功能,Vue,const,utf8mb4,dataForm,paperList,NULL,考试
From: https://www.cnblogs.com/mindzone/p/18368822

相关文章

  • Vue 3 组件渲染“暂停”技巧
    目录为什么需要“暂停”渲染?实现思路示例实现1.创建组件2.解释实现优化建议更深入的渲染控制1.异步组件2.使用Suspense3.废弃管理性能优化技巧1.虚拟滚动2.使用watchEffect3.事件处理实际应用场景        在使用Vue3开发复杂应用时,有时我们......
  • 在K8S中,Kube-proxy有什么功能?
    Kube-proxy是Kubernetes中的一个核心组件,它运行在每个节点上,负责实现Kubernetes服务(Services)的概念。Kube-proxy主要有以下功能:1.主要功能服务发现:Kube-proxy实现了服务发现机制,使得Pod能够通过服务名找到对应的服务端点(Endpoints)。负载均衡:当Pod需要访问......
  • Vue 项目 毒鸡汤 壮士可要来一碗!
    项目灵感来自“聆听远方”的毒鸡汤非常简单适合Vue新童鞋按国际惯例先上图来不及解释了快把代码复制走poison-soup.html<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,......
  • Vue 项目 毒鸡汤 壮士可要来一碗!
    项目灵感来自“聆听远方”的毒鸡汤非常简单适合Vue新童鞋按国际惯例先上图来不及解释了快把代码复制走poison-soup.html<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,......
  • 关系代数、函数依赖、Armstrong公理及软考试题解析
    注:本文面向于软考高级—系统架构设计师,具体来说是数据库部分,知识点偏零碎化。想要系统学习数据库原理的,可考虑去看《数据库原理》,清华大学出版社或其他出版社皆可。概述概念关系,就是二维表。特性:列不可分性:关系中每一列都是不可再分的属性,即不能出现如下复合属性行列无序性:......
  • 如何降低论文AI率? 试试笔灵AI降AI功能。
    在当今时代,人工智能技术日渐普及,诸多学子已掌握运用ChatGPT或其他AI工具以助论文撰写之技巧。然而,论文检测系统却日趋严格,除了常规的查重检测外,竟然还出现了AI率检测。不少高等院校亦开始对AI率实施限制,AI率过高可能导致论文不予通过,这无疑令众多学子感到困扰。于是,如何有效降......
  • AI写作后如何避免高AI率? 笔灵AI降AI功能,专为解决这一难题而生
    现在AI“大行其道”,很多同学都学会了用chatgpt或者其他AI工具来辅助写论文,但是一些论文检测平台却管得更严了,不仅有查重检测,居然还有AI率检测!很多高校也开始卡AI率,AI率不过关的很有可能论文不通过,真可让不少同学又苦恼了……那怎么样才能降AI呢?如果一字一字修改未免太耗时耗......
  • vue3 响应式 API:computed()
    介绍基本概念:computed()接收一个getter函数或者一个包含getter和setter函数的对象作为参数,并返回一个基于原始响应式数据计算得到的新的响应式数据对象。计算属性的值会根据其依赖的响应式数据自动更新,当依赖的数据发生变化时,计算属性的值也会自动重新计算。返......
  • 盲盒电商系统功能模块分析
    盲盒电商系统是一种创新的电子商务模式,通过结合盲盒的随机性和购物体验,为消费者带来了新颖的购物方式。以下是对盲盒电商系统功能模块的分析:会员体系构建:盲盒电商平台通过会员注册和购买盲盒来构建用户基础,新会员可以通过购买任意盲盒成为会员,并获取入门奖励,有效降低参与门槛......
  • vue3---vite框架
    在使用VUE3的时候,可以使用vite脚手架:Vite的特点:1.快速的冷启动,不需要等待打包2.即时的热模块更新3.真正的按需编译,不用等待整个项目编译完成1、构建vite项目npminitvite@latest#初始化vite项目或者npmcreatevite@latest#创建vite项目选择Vue根据醒目需要选......