|
@@ -0,0 +1,215 @@
|
|
|
|
+<template>
|
|
|
|
+ <div class="nested-question">
|
|
|
|
+ <el-form
|
|
|
|
+ ref="modalFormComp"
|
|
|
|
+ :model="modalForm"
|
|
|
|
+ :rules="rules"
|
|
|
|
+ label-width="100px"
|
|
|
|
+ >
|
|
|
|
+ <el-form-item prop="quesBody" label="大题题干">
|
|
|
|
+ <v-editor
|
|
|
|
+ v-model="modalForm.quesBody"
|
|
|
|
+ :enable-answer-point="IS_CLOZE"
|
|
|
|
+ @answer-point-changed="answerPointsChange"
|
|
|
|
+ @change="quesBodyChange"
|
|
|
|
+ ></v-editor> </el-form-item
|
|
|
|
+ ></el-form>
|
|
|
|
+
|
|
|
|
+ <div class="tips-info">
|
|
|
|
+ <p>小题数:{{ modalForm.subQuestions.length }}</p>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <el-collapse v-model="activeNames">
|
|
|
|
+ <el-collapse-item
|
|
|
|
+ v-for="(subq, index) in modalForm.subQuestions"
|
|
|
|
+ :key="index"
|
|
|
|
+ :name="index"
|
|
|
|
+ >
|
|
|
|
+ <div slot="title" class="subq-header">
|
|
|
|
+ <h3>
|
|
|
|
+ 第{{ index + 1 }}小题({{ subq.questionType | questionType }})
|
|
|
|
+ </h3>
|
|
|
|
+ <div>
|
|
|
|
+ <el-button
|
|
|
|
+ v-if="!deleleDisabled"
|
|
|
|
+ size="mini"
|
|
|
|
+ type="text"
|
|
|
|
+ icon="el-icon-delete"
|
|
|
|
+ title="删除"
|
|
|
|
+ @click.stop="removeSubQuestion(index)"
|
|
|
|
+ ></el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <component
|
|
|
|
+ :is="getStructTypeComp(subq.questionType)"
|
|
|
|
+ :key="subq.questionKey"
|
|
|
|
+ ref="QuestionEditDetail"
|
|
|
|
+ :question="subq"
|
|
|
|
+ ></component>
|
|
|
|
+ </el-collapse-item>
|
|
|
|
+ </el-collapse>
|
|
|
|
+
|
|
|
|
+ <el-popover
|
|
|
|
+ v-if="!IS_CLOZE"
|
|
|
|
+ popper-class="nested-subq-popover"
|
|
|
|
+ trigger="hover"
|
|
|
|
+ >
|
|
|
|
+ <div class="nested-subq-list">
|
|
|
|
+ <div
|
|
|
|
+ v-for="item in BASE_QUESTION_TYPES"
|
|
|
|
+ :key="item.code"
|
|
|
|
+ class="nested-subq-item"
|
|
|
|
+ @click="addSubQuestion(item.code)"
|
|
|
|
+ >
|
|
|
|
+ {{ item.name }}
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <el-button
|
|
|
|
+ slot="reference"
|
|
|
|
+ type="primary"
|
|
|
|
+ size="small"
|
|
|
|
+ icon="el-icon-circle-plus-outline"
|
|
|
|
+ >新增小题</el-button
|
|
|
|
+ >
|
|
|
|
+ </el-popover>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+import { isAnEmptyRichText } from "@/utils/utils";
|
|
|
|
+import { randomCode } from "@/plugins/utils";
|
|
|
|
+import {
|
|
|
|
+ getInitQuestionModel,
|
|
|
|
+ STRUCT_TYPE_COMP_DICT,
|
|
|
|
+} from "../model/questionModel";
|
|
|
|
+import BooleanQuestion from "./BooleanQuestion.vue";
|
|
|
|
+import FillBlankQuestion from "./FillBlankQuestion.vue";
|
|
|
|
+import SelectQuestion from "./SelectQuestion.vue";
|
|
|
|
+import TextAnswerQuestion from "./TextAnswerQuestion.vue";
|
|
|
|
+import { BASE_QUESTION_TYPES } from "@/constants/constants";
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ name: "NestedQuestion",
|
|
|
|
+ components: {
|
|
|
|
+ FillBlankQuestion,
|
|
|
|
+ SelectQuestion,
|
|
|
|
+ TextAnswerQuestion,
|
|
|
|
+ BooleanQuestion,
|
|
|
|
+ },
|
|
|
|
+ props: {
|
|
|
|
+ question: {
|
|
|
|
+ type: Object,
|
|
|
|
+ default() {
|
|
|
|
+ return {};
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ modalForm: {},
|
|
|
|
+ BASE_QUESTION_TYPES,
|
|
|
|
+ activeNames: [],
|
|
|
|
+ rules: {
|
|
|
|
+ quesBody: [
|
|
|
|
+ {
|
|
|
|
+ validator: (rule, value, callback) => {
|
|
|
|
+ if (!this.IS_CLOZE) return callback();
|
|
|
|
+
|
|
|
|
+ if (!value || isAnEmptyRichText(value)) {
|
|
|
|
+ return callback(new Error(`请输入题干`));
|
|
|
|
+ }
|
|
|
|
+ callback();
|
|
|
|
+ },
|
|
|
|
+ trigger: "change",
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ deleleDisabled() {
|
|
|
|
+ return this.IS_CLOZE;
|
|
|
|
+ },
|
|
|
|
+ IS_CLOZE() {
|
|
|
|
+ return this.modalForm.questionType === "CLOZE";
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ created() {
|
|
|
|
+ this.initData();
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ initData() {
|
|
|
|
+ this.modalForm = this.$objAssign(
|
|
|
|
+ getInitQuestionModel("READING_COMPREHENSION"),
|
|
|
|
+ this.question
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ getStructTypeComp(questionType) {
|
|
|
|
+ return STRUCT_TYPE_COMP_DICT[questionType];
|
|
|
|
+ },
|
|
|
|
+ addSubQuestion(questionType, index = null) {
|
|
|
|
+ let newQuestion = getInitQuestionModel(questionType);
|
|
|
|
+ newQuestion.questionKey = randomCode();
|
|
|
|
+ const nindex =
|
|
|
|
+ index === null ? this.modalForm.subQuestions.length : index + 1;
|
|
|
|
+ this.modalForm.subQuestions.splice(nindex, 0, newQuestion);
|
|
|
|
+ if (!this.activeNames.includes(nindex) && !this.IS_CLOZE)
|
|
|
|
+ this.activeNames.push(nindex);
|
|
|
|
+ },
|
|
|
|
+ async removeSubQuestion(index) {
|
|
|
|
+ if (this.deleleDisabled) return;
|
|
|
|
+
|
|
|
|
+ const res = await this.$confirm("确定要删除该小题吗?", "提示", {
|
|
|
|
+ type: "warning",
|
|
|
|
+ }).catch(() => {});
|
|
|
|
+ if (res !== "confirm") return;
|
|
|
|
+
|
|
|
|
+ this.modalForm.subQuestions.splice(index, 1);
|
|
|
|
+ },
|
|
|
|
+ answerPointsChange(answerPointsCount) {
|
|
|
|
+ let curSubQuestionCount = this.modalForm.subQuestions.length;
|
|
|
|
+ if (curSubQuestionCount === answerPointsCount) return;
|
|
|
|
+
|
|
|
|
+ if (curSubQuestionCount > answerPointsCount) {
|
|
|
|
+ this.modalForm.subQuestions = this.modalForm.subQuestions.slice(
|
|
|
|
+ 0,
|
|
|
|
+ answerPointsCount
|
|
|
|
+ );
|
|
|
|
+ } else {
|
|
|
|
+ for (let i = curSubQuestionCount; i < answerPointsCount; i++) {
|
|
|
|
+ this.addSubQuestion("SINGLE_ANSWER_QUESTION");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ quesBodyChange() {
|
|
|
|
+ this.$refs.modalFormComp.validateField(`quesBody`, () => {});
|
|
|
|
+ },
|
|
|
|
+ async validate() {
|
|
|
|
+ let errorQuestionIndexs = [];
|
|
|
|
+ for (let i = 0; i < this.$refs.QuestionEditDetail.length; i++) {
|
|
|
|
+ const compInst = this.$refs.QuestionEditDetail[i];
|
|
|
|
+ const res = await compInst.validate().catch(() => {});
|
|
|
|
+ if (!res) {
|
|
|
|
+ errorQuestionIndexs.push(i + 1);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (errorQuestionIndexs.length) {
|
|
|
|
+ this.$message.error(
|
|
|
|
+ `请完成第${errorQuestionIndexs.join()}小题的编辑!`
|
|
|
|
+ );
|
|
|
|
+ return Promise.reject();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+ },
|
|
|
|
+ getData() {
|
|
|
|
+ this.modalForm.subQuestions = this.$refs.QuestionEditDetail.map(
|
|
|
|
+ (compInst) => compInst.getData()
|
|
|
|
+ );
|
|
|
|
+ return this.modalForm;
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+</script>
|