一、需求場景
最近臨時加的一個功能模組,讓我兩天就實現....
部門成員需要進行測驗考試,簡單來說就是刷題練習
關於題庫匯入的部分在這篇文章已經寫好了: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('閱卷成功') },