|
@@ -0,0 +1,257 @@
|
|
|
+<template>
|
|
|
+ <div class="mark-param-objective-answer">
|
|
|
+ <div class="part-box part-box-pad">
|
|
|
+ <div>
|
|
|
+ <p class="tips-info">1.请录入客观题标答;</p>
|
|
|
+ <p class="tips-info">
|
|
|
+ 2.多选题请根据需求设置判分策略,目前支持漏选给半分,任选给半分或者不设置,不设置时表示与标答一致得分,否则不得分。
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="part-box part-box-pad">
|
|
|
+ <p class="tips-info mb-1">
|
|
|
+ <i class="el-icon-warning"></i> 客观题标答只能输入大写字母ABCDE...
|
|
|
+ ,判断题正确请输入A,错误输入B
|
|
|
+ </p>
|
|
|
+ <el-table
|
|
|
+ ref="TableList"
|
|
|
+ :data="tableData"
|
|
|
+ border
|
|
|
+ :row-class-name="getRowClassName"
|
|
|
+ >
|
|
|
+ <el-table-column width="50" align="center">
|
|
|
+ <template slot-scope="scope" v-if="scope.row.mainFirstSub">
|
|
|
+ <div
|
|
|
+ :class="[
|
|
|
+ 'expand-btn',
|
|
|
+ { 'expand-btn-unexpand': !scope.row.expandSub },
|
|
|
+ ]"
|
|
|
+ @click="switchExpandSub(scope.row)"
|
|
|
+ >
|
|
|
+ <i
|
|
|
+ :class="scope.row.expandSub ? 'el-icon-minus' : 'el-icon-plus'"
|
|
|
+ ></i>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="mainTitle" label="大题名称">
|
|
|
+ <span slot-scope="scope" v-if="scope.row.mainFirstSub">
|
|
|
+ {{ scope.row.mainTitle }}
|
|
|
+ </span>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="mainNumber" label="大题号" width="80">
|
|
|
+ <template slot-scope="scope" v-if="scope.row.mainFirstSub">
|
|
|
+ <span>{{ scope.row.mainNumber }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="subNumber"
|
|
|
+ label="小题号"
|
|
|
+ width="80"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column prop="totalScore" label="小题满分" width="105">
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="答案" width="200px" class-name="answer-column">
|
|
|
+ <div
|
|
|
+ slot-scope="scope"
|
|
|
+ :class="['el-form-item', { 'is-error': scope.row.error }]"
|
|
|
+ >
|
|
|
+ <div class="el-form-item__content">
|
|
|
+ <el-input
|
|
|
+ v-model.trim="scope.row.answer"
|
|
|
+ :placeholder="
|
|
|
+ scope.row.type === 3 ? 'A:正确,B:错误' : '请输入答案'
|
|
|
+ "
|
|
|
+ :maxlength="scope.row.optionCount"
|
|
|
+ clearable
|
|
|
+ @change="validateAnswer(scope.row)"
|
|
|
+ ></el-input>
|
|
|
+ <div v-if="scope.row.error" class="el-form-item__error">
|
|
|
+ {{ scope.row.errMsg }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="判分策略" width="140px">
|
|
|
+ <template v-if="scope.row.type === 2" slot-scope="scope">
|
|
|
+ <el-select v-model="scope.row.objectivePolicy">
|
|
|
+ <el-option
|
|
|
+ v-for="(val, key) in QUESTION_SCORE_TYPE"
|
|
|
+ :key="key"
|
|
|
+ :value="key"
|
|
|
+ :label="val"
|
|
|
+ ></el-option>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="text-center">
|
|
|
+ <el-button type="primary" :disabled="loading" @click="submit"
|
|
|
+ >提交</el-button
|
|
|
+ >
|
|
|
+ <el-button @click="cancel">取消</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { QUESTION_SCORE_TYPE } from "@/constants/enumerate";
|
|
|
+import {
|
|
|
+ markObjectiveQuestionList,
|
|
|
+ markObjectiveQuestionSave,
|
|
|
+} from "../../api";
|
|
|
+import { mapState } from "vuex";
|
|
|
+import { omit } from "lodash";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "mark-param-objective-answer",
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ loading: false,
|
|
|
+ tableData: [],
|
|
|
+ QUESTION_SCORE_TYPE,
|
|
|
+ abc: "abcdefghijklmnopqrstuvwxyz".toUpperCase(),
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapState("markParam", ["basicInfo"]),
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.initData();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ async initData() {
|
|
|
+ const params = {
|
|
|
+ examId: this.basicInfo.examId,
|
|
|
+ paperNumber: this.basicInfo.paperNumber,
|
|
|
+ };
|
|
|
+ const res = await markObjectiveQuestionList(params);
|
|
|
+ let objectiveStructure = res || [];
|
|
|
+ let curMainNumber = null;
|
|
|
+ let curMainId = null;
|
|
|
+ this.tableData = objectiveStructure.map((item) => {
|
|
|
+ let nitem = {
|
|
|
+ ...item,
|
|
|
+ id: this.$randomCode(),
|
|
|
+ mainFirstSub: false,
|
|
|
+ expandSub: true,
|
|
|
+ error: false,
|
|
|
+ errMsg: "",
|
|
|
+ };
|
|
|
+ if (nitem.mainNumber !== curMainNumber) {
|
|
|
+ curMainNumber = nitem.mainNumber;
|
|
|
+ nitem.mainFirstSub = true;
|
|
|
+ curMainId = this.$randomCode();
|
|
|
+ }
|
|
|
+ nitem.mainId = curMainId;
|
|
|
+ return nitem;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getRowClassName({ row }) {
|
|
|
+ let classNames = [];
|
|
|
+ if (row.mainFirstSub) {
|
|
|
+ classNames.push("row-main-first-sub");
|
|
|
+ }
|
|
|
+ if (!row.mainFirstSub && !row.expandSub) {
|
|
|
+ classNames.push("row-unexpand-sub");
|
|
|
+ }
|
|
|
+ return classNames.join(" ");
|
|
|
+ },
|
|
|
+ switchExpandSub(row) {
|
|
|
+ row.expandSub = !row.expandSub;
|
|
|
+ this.tableData
|
|
|
+ .filter((item) => item.mainId === row.mainId && !item.mainFirstSub)
|
|
|
+ .forEach((item) => (item.expandSub = row.expandSub));
|
|
|
+ },
|
|
|
+ validateAnswer(row) {
|
|
|
+ if (!row.answer) {
|
|
|
+ row.error = true;
|
|
|
+ row.errMsg = "不能为空";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!/^[A-Z]{1,26}$/.test(row.answer)) {
|
|
|
+ row.error = true;
|
|
|
+ row.errMsg = "只能输入英文大写字母";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const validAnswers = this.abc.substring(0, row.optionCount);
|
|
|
+ // 单选题 判断题
|
|
|
+ if (row.questionType === 1 || row.questionType === 3) {
|
|
|
+ if (
|
|
|
+ row.answer.length !== 1 ||
|
|
|
+ row.answer.split("").some((item) => !validAnswers.includes(item))
|
|
|
+ ) {
|
|
|
+ row.error = true;
|
|
|
+ row.errMsg = `只能输入${validAnswers}中的一个`;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 多选题
|
|
|
+ if (row.questionType === 2) {
|
|
|
+ if (row.answer.length <= 1) {
|
|
|
+ row.error = true;
|
|
|
+ row.errMsg = `答案必须为多个`;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (row.answer.split("").some((item) => !validAnswers.includes(item))) {
|
|
|
+ row.error = true;
|
|
|
+ row.errMsg = `只能输入${validAnswers}中的字符`;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const ansSet = new Set(row.answer.split(""));
|
|
|
+ if (ansSet.size !== row.answer.length) {
|
|
|
+ row.error = true;
|
|
|
+ row.errMsg = "答案不能重复";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ row.error = false;
|
|
|
+ row.errMsg = "";
|
|
|
+ },
|
|
|
+ checkData() {
|
|
|
+ this.tableData.forEach((item) => {
|
|
|
+ this.validateAnswer(item);
|
|
|
+ });
|
|
|
+
|
|
|
+ return !this.tableData.some((item) => item.error);
|
|
|
+ },
|
|
|
+ async submit() {
|
|
|
+ if (!this.checkData()) return;
|
|
|
+
|
|
|
+ if (this.loading) return;
|
|
|
+ this.loading = true;
|
|
|
+ const datas = {
|
|
|
+ examId: this.basicInfo.examId,
|
|
|
+ paperNumber: this.basicInfo.paperNumber,
|
|
|
+ objectiveInfo: this.tableData.map((item) =>
|
|
|
+ omit(item, [
|
|
|
+ "id",
|
|
|
+ "mainFirstSub",
|
|
|
+ "expandSub",
|
|
|
+ "error",
|
|
|
+ "errMsg",
|
|
|
+ "mainId",
|
|
|
+ ])
|
|
|
+ ),
|
|
|
+ };
|
|
|
+ const data = await markObjectiveQuestionSave(datas).catch(() => {});
|
|
|
+ this.loading = false;
|
|
|
+ if (!data) return;
|
|
|
+
|
|
|
+ this.$message.success("保存成功!");
|
|
|
+ // this.$emit("confirm");
|
|
|
+ },
|
|
|
+ cancel() {
|
|
|
+ this.$emit("cancel");
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|