mjh пре 5 година
родитељ
комит
2677afd4c1

+ 30 - 0
src/components/QuestionCard/AnswerDisplay/ChoiceDisplay/ChoiceItem.vue

@@ -0,0 +1,30 @@
+<template>
+  <slot name="choiceItem">
+    <div v-if="questionVO.answer.split('').indexOf(name) !== -1" class="correct-answer">
+      <MarkdownText :raw="name+': '+content"></MarkdownText>
+    </div>
+    <div v-else>
+      <MarkdownText :raw="name+': '+content"></MarkdownText>
+    </div>
+  </slot>
+</template>
+
+<script>
+import MarkdownText from "@/components/MarkdownText";
+
+export default {
+  name: "ChoiceItem",
+  components:{
+    MarkdownText
+  },
+  props:{
+    questionVO: Object,
+    name: String,
+    content: String,
+  },
+}
+</script>
+
+<style scoped>
+
+</style>

+ 62 - 0
src/components/QuestionCard/AnswerDisplay/ChoiceDisplay/UpdatingChoiceDisplay.vue

@@ -0,0 +1,62 @@
+<template>
+  <div v-for="(value,key) in newQuestionVO.options">
+    <choice-item :question-v-o="newQuestionVO" :name="key" :content="value">
+      <template v-slot:choiceItem>
+        <div class="contrast-wrapper">
+          <div class="old-content">
+            <MarkdownText v-if="isCorrectAnswer(oldQuestionVO.answer, key)"
+                          class="correct-answer"
+                          :raw="key+': '+oldQuestionVO.options[key]"/>
+            <MarkdownText v-else
+                          :raw="key+': '+oldQuestionVO.options[key]"/>
+          </div>
+          <el-divider direction="vertical"/>
+          <div class="new-content">
+            <MarkdownText v-if="isCorrectAnswer(newQuestionVO.answer, key)"
+                          :raw="key+': '+newQuestionVO.options[key]"
+                          class="correct-answer"/>
+            <MarkdownText v-else
+                          :raw="key+': '+newQuestionVO.options[key]"></MarkdownText>
+          </div>
+        </div>
+      </template>
+    </choice-item>
+  </div>
+</template>
+
+<script>
+import MarkdownText from "@/components/MarkdownText";
+import ChoiceItem from "@/components/QuestionCard/AnswerDisplay/ChoiceDisplay/ChoiceItem";
+
+export default {
+  name: "UpdateChoiceOption",
+  components: {
+    MarkdownText,
+    ChoiceItem,
+  },
+  data() {
+    return {}
+  },
+  props: {
+    oldQuestionVO: Object,
+    newQuestionVO: Object,
+  },
+  methods: {
+    isCorrectAnswer(answer, option) {
+      return answer.split('').indexOf(option) !== -1;
+    },
+  },
+  mounted() {
+  }
+}
+</script>
+
+<style scoped>
+.correct-answer {
+  font-family: "Kaiti SC";
+  font-size: 22px;
+  /*color: #f1939c;*/
+  font-weight: bold;
+  text-decoration: underline;
+}
+</style>

+ 31 - 0
src/components/QuestionCard/AnswerDisplay/ChoiceDisplay/index.vue

@@ -0,0 +1,31 @@
+<template>
+  <div v-for="(value,key) in questionVO.options">
+    <choice-item :question-v-o="questionVO" :name="key" :content="value"></choice-item>
+  </div>
+</template>
+
+<script>
+import ChoiceItem from "@/components/QuestionCard/AnswerDisplay/ChoiceDisplay/ChoiceItem";
+import MarkdownText from "@/components/MarkdownText";
+
+export default {
+  name: "ChoiceDisplay",
+  components: {
+    MarkdownText,
+    ChoiceItem,
+  },
+  props: {
+    questionVO: Object
+  },
+}
+</script>
+
+<style>
+.correct-answer {
+  font-family: "Kaiti SC";
+  font-size: 22px;
+  color: #f1939c;
+  font-weight: bold;
+  text-decoration: underline;
+}
+</style>

+ 0 - 38
src/components/QuestionCard/AnswerOption/ChoiceOption.vue

@@ -1,38 +0,0 @@
-<template>
-  <div>
-    <div v-if="questionVO!==undefined" v-for="(value,key) in questionVO.options">
-      <slot :name="'choiceOption'+key">
-        <div v-if="questionVO.answer.split('').indexOf(key) !== -1" class="correct-answer">
-          <MarkdownText :raw="key+': '+value"></MarkdownText>
-        </div>
-        <div v-else>
-          <MarkdownText :raw="key+': '+value"></MarkdownText>
-        </div>
-      </slot>
-    </div>
-  </div>
-</template>
-
-<script>
-import MarkdownText from "@/components/MarkdownText";
-
-export default {
-  name: "ChoiceOption",
-  components: {
-    MarkdownText
-  },
-  props: {
-    questionVO: Object
-  },
-}
-</script>
-
-<style scoped>
-.correct-answer {
-  font-family: "Kaiti SC";
-  font-size: 22px;
-  color: #f1939c;
-  font-weight: bold;
-  text-decoration: underline;
-}
-</style>

+ 0 - 139
src/components/QuestionCard/AnswerOption/UpdatingChoiceOption.vue

@@ -1,139 +0,0 @@
-<template>
-  <!--新旧选择题答案选项相同部分参考newQuestionVO-->
-  <choice-option :question-v-o="newQuestionVO">
-    <!--todo: 这里应该用v-for和v-slot的共同使用来减少代码量的-->
-    <!--A-->
-    <template
-      v-if="oldQuestionVO.options.A!==newQuestionVO.options.A||(isCorrectAnswer(oldQuestionVO.answer, 'A')!==isCorrectAnswer(newQuestionVO.answer, 'A'))"
-      v-slot:choiceOptionA>
-      <!--old A-->
-      <div class="contrast-wrapper">
-        <div class="old-content">
-          <MarkdownText v-if="isCorrectAnswer(oldQuestionVO.answer, 'A')"
-                        class="correct-answer"
-                        :raw="'A: '+oldQuestionVO.options.A"/>
-          <MarkdownText v-else
-                        :raw="'A: '+oldQuestionVO.options.A"/>
-        </div>
-        <el-divider direction="vertical"/>
-        <!--new A-->
-        <div class="new-content">
-          <MarkdownText v-if="isCorrectAnswer(newQuestionVO.answer, 'A')"
-                        :raw="'A: '+newQuestionVO.options.A"
-                        class="correct-answer"/>
-          <MarkdownText v-else
-                        :raw="'A: '+newQuestionVO.options.A"></MarkdownText>
-        </div>
-      </div>
-    </template>
-    <!--B-->
-    <template
-      v-if="oldQuestionVO.options.B!==newQuestionVO.options.B||(isCorrectAnswer(oldQuestionVO.answer, 'B')!==isCorrectAnswer(newQuestionVO.answer, 'B'))"
-      v-slot:choiceOptionB>
-      <!--old B-->
-      <div class="contrast-wrapper">
-        <div class="old-content">
-          <MarkdownText v-if="isCorrectAnswer(oldQuestionVO.answer, 'B')"
-                        class="correct-answer"
-                        :raw="'B: '+oldQuestionVO.options.B"/>
-          <MarkdownText v-else
-                        :raw="'B: '+oldQuestionVO.options.B"/>
-        </div>
-        <el-divider direction="vertical"/>
-        <!--new B-->
-        <div class="new-content">
-          <MarkdownText v-if="isCorrectAnswer(newQuestionVO.answer, 'B')"
-                        :raw="'B: '+newQuestionVO.options.B"
-                        class="correct-answer"/>
-          <MarkdownText v-else
-                        :raw="'B: '+newQuestionVO.options.B"></MarkdownText>
-        </div>
-      </div>
-    </template>
-    <!--C-->
-    <template
-      v-if="oldQuestionVO.options.C!==newQuestionVO.options.C||(isCorrectAnswer(oldQuestionVO.answer, 'C')!==isCorrectAnswer(newQuestionVO.answer, 'C'))"
-      v-slot:choiceOptionC>
-      <!--old C-->
-      <div class="contrast-wrapper">
-        <div class="old-content">
-          <MarkdownText v-if="isCorrectAnswer(oldQuestionVO.answer, 'C')"
-                        class="correct-answer"
-                        :raw="'C: '+oldQuestionVO.options.C"/>
-          <MarkdownText v-else
-                        :raw="'C: '+oldQuestionVO.options.C"/>
-        </div>
-        <el-divider direction="vertical"/>
-        <!--new C-->
-        <div class="new-content">
-          <MarkdownText v-if="isCorrectAnswer(newQuestionVO.answer, 'C')"
-                        :raw="'C: '+newQuestionVO.options.C"
-                        class="correct-answer"/>
-          <MarkdownText v-else
-                        :raw="'C: '+newQuestionVO.options.C"></MarkdownText>
-        </div>
-      </div>
-    </template>
-    <!--D-->
-    <template
-      v-if="oldQuestionVO.options.D!==newQuestionVO.options.D||(isCorrectAnswer(oldQuestionVO.answer, 'D')!==isCorrectAnswer(newQuestionVO.answer, 'D'))"
-      v-slot:choiceOptionD>
-      <!--old D-->
-      <div class="contrast-wrapper">
-        <div class="old-content">
-          <MarkdownText v-if="isCorrectAnswer(oldQuestionVO.answer, 'D')"
-                        class="correct-answer"
-                        :raw="'D: '+oldQuestionVO.options.D"/>
-          <MarkdownText v-else
-                        :raw="'D: '+oldQuestionVO.options.D"/>
-        </div>
-        <el-divider direction="vertical"/>
-        <!--new D-->
-        <div class="new-content">
-          <MarkdownText v-if="isCorrectAnswer(newQuestionVO.answer, 'D')"
-                        :raw="'D: '+newQuestionVO.options.D"
-                        class="correct-answer"/>
-          <MarkdownText v-else
-                        :raw="'D: '+newQuestionVO.options.D"></MarkdownText>
-        </div>
-      </div>
-    </template>
-  </choice-option>
-</template>
-
-<script>
-import MarkdownText from "@/components/MarkdownText";
-import ChoiceOption from "@/components/QuestionCard/AnswerOption/ChoiceOption";
-
-export default {
-  name: "UpdateChoiceOption",
-  components: {
-    MarkdownText,
-    ChoiceOption,
-  },
-  data() {
-    return {}
-  },
-  props: {
-    oldQuestionVO: Object,
-    newQuestionVO: Object,
-  },
-  methods: {
-    isCorrectAnswer(answer, option) {
-      return answer.split('').indexOf(option) !== -1;
-    },
-  },
-  mounted() {
-  }
-}
-</script>
-
-<style scoped>
-.correct-answer {
-  font-family: "Kaiti SC";
-  font-size: 22px;
-  /*color: #f1939c;*/
-  font-weight: bold;
-  text-decoration: underline;
-}
-</style>

+ 1 - 1
src/components/QuestionCard/CreatingQuestionCard.vue

@@ -1,5 +1,5 @@
 <template>
-  <primary-question-card v-if="questionVO!==undefined" :questionvo="questionVO" :cur-num="curNum" :total-num="totalNum">
+  <primary-question-card v-if="questionVO!==undefined" :question-v-o="questionVO" :cur-num="curNum" :total-num="totalNum">
     <template v-slot:button>
       <el-col :span="1">
         <el-button type="primary" icon="el-icon-check" circle @click="mockApproveQuestion"/>

+ 1 - 1
src/components/QuestionCard/DeletedQuestionCard.vue

@@ -1,6 +1,6 @@
 <template>
   <primary-question-card v-if="questionVO!==undefined"
-                         :questionvo="questionVO"
+                         :question-v-o="questionVO"
                          :cur-num="curNum"
                          :total-num="totalNum">
     <template v-slot:button>

+ 1 - 1
src/components/QuestionCard/ExecutingQuestionCard.vue

@@ -1,6 +1,6 @@
 <template>
   <primary-question-card v-if="questionVO!==undefined"
-                         :questionvo="questionVO"
+                         :question-v-o="questionVO"
                          :cur-num="curNum"
                          :total-num="totalNum">
     <template v-slot:button>

+ 85 - 91
src/components/QuestionCard/PrimaryQuestionCard.vue

@@ -1,97 +1,86 @@
 <template>
-  <el-card v-if="questionvo!==undefined" class="primary-question-card" shadow="hover">
+  <el-card v-if="questionVO!==undefined" class="primary-question-card" shadow="hover">
     <template #header>
-      <el-row>
-        <el-col :span="2">
-          <span><strong>S/N: </strong>{{ curNum + 1 }} / {{ totalNum }}</span>
-        </el-col>
-        <el-col :span="12">
-          <span><strong>题目类型: </strong>{{ questionvo.type }}</span>
-        </el-col>
-
-        <el-col :span="8">
-          <el-button type="text" circle @click="expand" v-show="!isAll"><strong>展开</strong></el-button>
-          <el-button type="text" circle @click="withdraw" v-show="isAll"><strong>收起</strong></el-button>
-        </el-col>
-        <slot name="button">
-          <!--按钮插槽,用于不同的卡片更换不同的按钮-->
-          <el-col :span="1">
-            <el-button type="primary" icon="el-icon-edit" circle @click="updateQuestion"/>
-          </el-col>
-          <el-col :span="1">
-            <el-button v-if="isDelete === false" type="danger" icon="el-icon-delete" circle @click="deleteQuestion"/>
-            <el-button v-else type="success" icon="el-icon-delete" circle @click="recoverQuestion"/>
-          </el-col>
-        </slot>
-      </el-row>
-      <!--知识点插槽,用于更新题目卡片中可能存在的知识点改变差异-->
-      <slot name="knowledgeId">
-        <span><strong>KnowledgeId: </strong></span>
-        <!--知识点显示内容-->
-        <el-tooltip
-          v-if="questionvo.knowledgeId && questionvo.knowledgeId.length !== 0"
-          v-for="item in questionvo.knowledgeId"
-          effect="dark"
-          placement="bottom">
-          <template #content>
-            {{ map(item) }}
-          </template>
-          <el-tag effect="dark" style="margin-right: 2px">{{ item }}</el-tag>
-        </el-tooltip>
-        <span v-else>null</span>
+      <!--      <el-space>-->
+      <el-space style="display: flex">
+        <span><strong>S/N: </strong>{{ curNum + 1 }} / {{ totalNum }}</span>
+        <span><strong>题目类型: </strong>{{ questionVO.type }}</span>
+        <el-button type="text" circle @click="isAllShow=!isAllShow"><strong>{{ isAllShowText }}</strong></el-button>
+        <div>
+          <!--知识点插槽,用于更新题目卡片中可能存在的知识点改变差异-->
+          <slot name="knowledgeId">
+            <span><strong>KnowledgeId: </strong></span>
+            <!--知识点显示内容-->
+            <el-tooltip
+              v-if="questionVO.knowledgeId && questionVO.knowledgeId.length !== 0"
+              v-for="item in questionVO.knowledgeId"
+              effect="dark"
+              placement="bottom">
+              <template #content>
+                {{ map(item) }}
+              </template>
+              <el-tag effect="dark" style="margin-right: 2px">{{ item }}</el-tag>
+            </el-tooltip>
+            <span v-else>null</span>
+          </slot>
+        </div>
+      </el-space>
+      <slot name="button">
+        <!--按钮插槽,用于不同的卡片更换不同的按钮-->
+        <el-button type="primary" icon="el-icon-edit" circle @click="updateQuestion"/>
+        <el-button v-if="isDelete === false" type="danger" icon="el-icon-delete" circle @click="deleteQuestion"/>
+        <el-button v-else type="success" icon="el-icon-delete" circle @click="recoverQuestion"/>
       </slot>
+      <!--      </el-space>-->
     </template>
-
     <!--题目内容部分-->
     <div class="primary-question-card-body">
       <!--题干部分-->
       <!--题干-题目描述部分-->
       <slot name="stem">
-        <MarkdownText :raw="'<strong>题目: </strong>'+questionvo.stem"></MarkdownText>
+        <MarkdownText :raw="'<strong>题目: </strong>'+questionVO.stem"></MarkdownText>
       </slot>
       <!--题干-题目答案部分-->
-      <div v-show="isAll">
+      <div v-show="isAllShow">
         <!--单选题和多选题答案-->
         <slot name="choiceOption"
-              v-if="questionvo.type==='choice' || questionvo.type==='multiple_choice'">
-          <choice-option :question-v-o="questionvo"/>
+              v-if="questionVO.type==='choice' || questionVO.type==='multiple_choice'">
+          <choice-option :question-v-o="questionVO"/>
         </slot>
         <!--todo:其他若干答案显示组件替代这里的div-->
-        <div class="bQuestion-card-body-blanks" v-if="questionvo.type === 'blank'">
-          <div v-for="index in Object.keys(questionvo.blanks).length">
+        <div class="bQuestion-card-body-blanks" v-if="questionVO.type === 'blank'">
+          <div v-for="index in Object.keys(questionVO.blanks).length">
             <div class="correct_answer">
-              __{{ index }}__: {{ questionvo.blanks['__' + index + '__'] }}
+              __{{ index }}__: {{ questionVO.blanks['__' + index + '__'] }}
             </div>
           </div>
         </div>
-        <div class="bQuestion-card-body-true_false" v-if="questionvo.type === 'true_false'">
-          <div class="correct_answer"> {{ questionvo.answer }}</div>
+        <div class="bQuestion-card-body-true_false" v-if="questionVO.type === 'true_false'">
+          <div class="correct_answer"> {{ questionVO.answer }}</div>
         </div>
       </div>
     </div>
-
-    <el-divider v-show="isAll"></el-divider>
-
+    <el-divider v-show="isAllShow"></el-divider>
     <!--题目解析部分-->
-    <div class="primary-question-card-analysis" v-show="isAll">
+    <div class="primary-question-card-analysis" v-show="isAllShow">
       <!--题目解析-题目信息部分-->
       <div class="analysis-block">
         <el-row>
           <slot name="keypoint">
             <el-col :span="10">
-              <strong>KeyPoints: </strong>{{ questionvo.keyPoints }}
+              <strong>KeyPoints: </strong>{{ questionVO.keyPoints }}
             </el-col>
           </slot>
           <slot name="difficulty">
             <el-col :span="6">
-              <strong>题目难度: </strong>{{ questionvo.weight }}/5
+              <strong>题目难度: </strong>{{ questionVO.weight }}/5
             </el-col>
           </slot>
           <slot name="tag">
             <el-col :span="4">
               <span><strong>Tags: </strong></span>
-              <span v-if="questionvo.tags && questionvo.tags.length !== 0">
-              <el-tag v-for="(item, index) in questionvo.tags" effect="dark">
+              <span v-if="questionVO.tags && questionVO.tags.length !== 0">
+              <el-tag v-for="(item, index) in questionVO.tags" effect="dark">
                 {{ item }}
               </el-tag>
             </span>
@@ -106,11 +95,11 @@
       <div class="analysis-block">
         <!--单选、多选、判断、简单-->
         <slot name="answer1"
-              v-if="questionvo.type === 'choice' ||
-                questionvo.type === 'multiple_choice' ||
-                questionvo.type === 'true_false' ||
-                questionvo.type === 'short_answer'">
-          <MarkdownText :raw="'<strong>正确答案: </strong>'+questionvo.answer"></MarkdownText>
+              v-if="questionVO.type === 'choice' ||
+                questionVO.type === 'multiple_choice' ||
+                questionVO.type === 'true_false' ||
+                questionVO.type === 'short_answer'">
+          <MarkdownText :raw="'<strong>正确答案: </strong>'+questionVO.answer"></MarkdownText>
         </slot>
         <!--todo: 简答-->
       </div>
@@ -118,31 +107,29 @@
       <div class="analysis-block">
         <!--单选、多选、判断-->
         <slot name="analysis1"
-              v-if="questionvo.type === 'choice' ||
-              questionvo.type === 'multiple_choice' ||
-              questionvo.type === 'true_false'">
-          <MarkdownText :raw="'<strong>解析: </strong>'+questionvo.analysis"></MarkdownText>
+              v-if="questionVO.type === 'choice' ||
+              questionVO.type === 'multiple_choice' ||
+              questionVO.type === 'true_false'">
+          <MarkdownText :raw="'<strong>解析: </strong>'+questionVO.analysis"></MarkdownText>
         </slot>
         <!--填空-->
-        <div v-if="questionvo.type === 'blank' && questionvo.analysis.length > 5">
-          <MarkdownText :raw="'<strong>解析: </strong>'+questionvo.analysis"></MarkdownText>
+        <div v-if="questionVO.type === 'blank' && questionVO.analysis.length > 5">
+          <MarkdownText :raw="'<strong>解析: </strong>'+questionVO.analysis"></MarkdownText>
         </div>
         <!--简答-->
-        <div v-if="questionvo.type === 'short_answer' && questionvo.analysis.length > 5">
-          <MarkdownText :raw="'<strong>解析: </strong>'+questionvo.analysis"></MarkdownText>
+        <div v-if="questionVO.type === 'short_answer' && questionVO.analysis.length > 5">
+          <MarkdownText :raw="'<strong>解析: </strong>'+questionVO.analysis"></MarkdownText>
         </div>
       </div>
     </div>
-
-    <el-divider v-show="isAll"></el-divider>
-
+    <el-divider v-show="isAllShow"></el-divider>
     <!--题目操作记录部分-->
-    <div class="primary-question-card-record" v-show="isAll">
+    <div class="primary-question-card-record" v-show="isAllShow">
       <!--题目当前状态-->
       <div class="record-block">
         <el-row>
           <el-col :span="3">
-            <div><strong>状态: </strong>{{ questionvo.state }}</div>
+            <div><strong>状态: </strong>{{ questionVO.state }}</div>
           </el-col>
           <el-col :span="5">
             <div><strong>审核人: </strong>{{ checkedUserName }}</div>
@@ -174,7 +161,7 @@
     ref="drawer"
     size="35%"
   >
-    <QuestionUpdater :question="questionvo" @closeDialog="closeDialog"/>
+    <QuestionUpdater :question="questionVO" @closeDialog="closeDialog"/>
   </el-drawer>
 
 </template>
@@ -185,8 +172,9 @@ import {map} from "@/utils/knowledgeMapper";
 import {toMyDate} from "@/utils/dateConvertor";
 import QuestionUpdater from "@/components/QuestionUpdater";
 import store from "@/store";
-
-import ChoiceOption from "@/components/QuestionCard/AnswerOption/ChoiceOption";
+import ChoiceOption from "@/components/QuestionCard/AnswerDisplay/ChoiceDisplay/index";
+import {ElDivider} from "element-plus";
+import {h, resolveComponent} from "vue";
 
 export default {
   name: "PrimaryQuestionCard",
@@ -197,32 +185,34 @@ export default {
     ChoiceOption,
   },
   props: {
-    questionvo: Object,
+    questionVO: Object,
     curNum: Number,
     totalNum: Number,
   },
   data() {
     return {
-      isAll: false,
+      isAllShow: false,
       isAllRecord: false,
       isDelete: false,
       dialog: false,
       checkedUserName: '',
       recordList: [],
       recordNameDict: {},
+
+      spacer: h(ElDivider, {direction: 'vertical'})
     }
   },
   methods: {
     toMyDate,
     map,
     expand() {
-      if (!this.isAll) {
-        this.isAll = true;
+      if (!this.isAllShow) {
+        this.isAllShow = true;
       }
     },
     withdraw() {
-      if (this.isAll) {
-        this.isAll = false;
+      if (this.isAllShow) {
+        this.isAllShow = false;
       }
     },
     updateQuestion() {
@@ -246,13 +236,13 @@ export default {
         cancelButtonText: '取消',
         type: 'warning'
       }).then(() => {
-        this.questionvo.lastModifiedTime = new Date();
-        this.questionvo.state = "DELETED";
+        this.questionVO.lastModifiedTime = new Date();
+        this.questionVO.state = "DELETED";
         let record = {
           userId: store.state.user.id,
           operationType: "Delete",
         }
-        this.$api.updateQuestion(this.questionvo)
+        this.$api.updateQuestion(this.questionVO)
           .then(res => {
             this.$message({
               type: 'success',
@@ -303,11 +293,15 @@ export default {
         recordTable1.push(recordDict);
       }
       return recordTable1;
-    }
+    },
+
+    isAllShowText() {
+      return this.isAllShow ? "收起" : "展开";
+    },
   },
   mounted() {
-    if (this.questionvo.checkedUserId) {
-      this.$api.getUserById(this.questionvo.checkedUserId) // 异步函数1:根据用户ID获得用户名称
+    if (this.questionVO.checkedUserId) {
+      this.$api.getUserById(this.questionVO.checkedUserId) // 异步函数1:根据用户ID获得用户名称
         .then(res => {
           if (res.data.result.name) {
             this.checkedUserName = res.data.result.name;
@@ -317,7 +311,7 @@ export default {
       })
     }
 
-    this.$api.getRecordByQid(this.questionvo.id) // 异步函数2:根据题目id获得ope_record
+    this.$api.getRecordByQid(this.questionVO.id) // 异步函数2:根据题目id获得ope_record
       .then(res1 => {
         let tempList = res1.data.result.content;
         this.recordList = tempList;

+ 2 - 2
src/components/QuestionCard/UpdatingQuestionCard.vue

@@ -1,7 +1,7 @@
 <template>
   <!--更新题目卡片里不变的内容,如题目类型、修改记录等内容均参考newQuestionVO-->
   <primary-question-card v-if="newQuestionVO!==undefined && oldQuestionVO!==undefined"
-                         :questionvo="newQuestionVO"
+                         :question-v-o="newQuestionVO"
                          :cur-num="curNum"
                          :total-num="totalNum">
     <!--新旧题目知识点不同-->
@@ -154,7 +154,7 @@
 <script>
 import PrimaryQuestionCard from "@/components/QuestionCard/PrimaryQuestionCard";
 import MarkdownText from "@/components/MarkdownText";
-import UpdateChoiceOption from "@/components/QuestionCard/AnswerOption/UpdatingChoiceOption";
+import UpdateChoiceOption from "@/components/QuestionCard/AnswerDisplay/ChoiceDisplay/UpdatingChoiceDisplay";
 import {map} from "@/utils/knowledgeMapper";
 
 export default {

+ 39 - 0
src/components/QuestionCreator/AnswerCreator/ChoiceCreator.vue

@@ -0,0 +1,39 @@
+<template>
+  <el-space direction="vertical">
+    <el-space v-for="(value, key) in options">
+      <strong>{{ key }}:</strong>
+      <!--todo: 这里将输入框替换为富文本输入-->
+      <el-input v-model="options[key]"/>
+    </el-space>
+    <el-space>
+      <strong>正确答案:</strong>
+      <el-select v-model="correctAnswer" placeholder="请选择" @change="handleChange">
+        <el-option v-for="(value, key) in options" :label="key" :value="key"></el-option>
+      </el-select>
+    </el-space>
+  </el-space>
+</template>
+
+<script>
+export default {
+  name: "ChoiceCreator",
+  data() {
+    return {
+    }
+  },
+  props:{
+    options: Object,
+    correctAnswer: String,
+  },
+  emits:['select'],
+  methods:{
+    handleChange(value){
+      this.$emit("select", value)
+    },
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 189 - 0
src/components/QuestionCreator/SingleQuestionCreator.vue

@@ -0,0 +1,189 @@
+<template>
+  <el-space v-if="state===0" direction="vertical" size="large">
+    <strong>请选择题目的类型</strong>
+    <el-select v-model="questionType" placeholder="请选择">
+      <el-option
+        v-for="item in questionTypeOptions"
+        :key="item.value"
+        :label="item.label"
+        :value="item.value">
+      </el-option>
+    </el-select>
+    <strong>"测试阶段暂时只能新建单选题"</strong>
+    <el-button type="primary" @click="acknowledgeQuestionType">确认</el-button>
+  </el-space>
+
+  <el-space v-if="state===1" direction="vertical" size="large" :spacer="spacer">
+    <el-space>
+      <strong>题目:</strong>
+      <!--todo: 此处将输入框替换为富文本输入-->
+      <el-input v-model="questionStem"/>
+    </el-space>
+    <choice-creator v-if="questionType==='choice'"
+                    :options="questionOptions"
+                    :correct-answer="questionAnswer"
+                    @select="handleAnswerSelect"/>
+    <el-space>
+      <strong>解析:</strong>
+      <!--todo-->
+      <el-input v-model="questionAnalysis"/>
+    </el-space>
+    <el-space>
+      <strong>难度:</strong>
+      <el-select v-model="questionDifficulty">
+        <el-option v-for="item in [1,2,3,4,5]" :label="item" :value="item"></el-option>
+      </el-select>
+    </el-space>
+    <strong>"测试阶段下列三项可不填"</strong>
+    <el-space>
+      <strong>知识点:</strong>
+    </el-space>
+    <el-space>
+      <strong>标签(Tag):</strong>
+    </el-space>
+    <el-space>
+      <strong>关键词(Keypoint):</strong>
+    </el-space>
+    <el-button type="primary" @click="acknowledgeCreateQuestion">确认</el-button>
+  </el-space>
+</template>
+
+<script>
+import ChoiceCreator from "@/components/QuestionCreator/AnswerCreator/ChoiceCreator";
+import {ElDivider} from "element-plus";
+import {h, resolveComponent} from "vue";
+
+export default {
+  name: "SingleQuestionCreator",
+  components: {ChoiceCreator},
+  data() {
+    return {
+      state: 0,
+      questionType: '',
+      questionTypeOptions: [{
+        value: 'choice',
+        label: '单选题'
+      }, {
+        value: 'multiple_choice',
+        label: '多选题'
+      }, {
+        value: 'true_false',
+        label: '判断题'
+      }, {
+        value: 'blank',
+        label: '填空题'
+      }, {
+        value: 'short_answer',
+        label: '简答题'
+      }],
+      questionStem: "",
+      questionOptions: {
+        A: "", B: "", C: "", D: ""
+      },
+      questionAnswer: "",
+      questionAnalysis: "",
+      questionDifficulty: 1,
+      questionKnowledgeId: ["SE"],
+      questionTag: ["SE"],
+      questionKeypoint: ["SE"],
+      spacer: h(ElDivider, {
+        style:"margin:0;"
+      })
+    }
+  },
+  methods: {
+    //
+    init() {
+    },
+
+    //
+    acknowledgeQuestionType() {
+      if (this.questionType === "") {
+        this.$message({
+          type: "warning",
+          message: "请选择将要新建的题目类型",
+        })
+        return;
+      }
+      this.$confirm('请确认将要新建的题目类型:' + this.questionTypeMapper, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.state += 1;
+      })
+    },
+
+    //
+    acknowledgeQuestionInfo() {
+      if (this.questionStem === "") {
+        this.$message.error("题目内容未填写!")
+        return false
+      }
+      for (let questionOptionsKey in this.questionOptions) {
+        if (this.questionOptions[questionOptionsKey] === "") {
+          this.$message.error("选项内容未填写!")
+          return false
+        }
+      }
+      if (this.questionAnswer === "") {
+        this.$message.error("答案内容未填写!")
+        return false
+      }
+      if(this.questionAnalysis === ""){
+        this.$message.error("解析内容未填写")
+        return false;
+      }
+      if(this.questionKnowledgeId.length===0){
+        this.$message.error("知识点未填写")
+        return false;
+      }
+      return true;
+    },
+
+    //
+    handleAnswerSelect(value){
+      this.questionAnswer = value;
+      console.log(this.questionAnswer)
+    },
+
+    acknowledgeCreateQuestion(){
+      if(!this.acknowledgeQuestionInfo()){
+        return;
+      }
+      let question={
+        id: null,
+        stem: this.questionStem,
+        type: this.questionType,
+        state: null,
+        checkedUserId: 0,
+        savedUserId: 0,
+        options: this.questionOptions,
+        keyPoints: this.questionKeypoint,
+        tags: this.questionTag,
+        knowledgeId: this.questionKnowledgeId,
+        answer: this.questionAnswer,
+        analysis: this.analysis,
+        weight: this.questionDifficulty,
+        createdTime: null
+      }
+      // todo 调用后端
+    }
+  },
+  computed: {
+    questionTypeMapper() {
+      for (let option of this.questionTypeOptions) {
+        if (option.value === this.questionType) {
+          return option.label;
+        }
+      }
+    }
+  },
+}
+</script>
+
+<style scoped>
+.el-divider{
+  margin: 0;
+}
+</style>

+ 12 - 12
src/views/Bok/Main/Check.vue

@@ -2,7 +2,7 @@
   <div>
     <h1>题目审查</h1>
     <el-tabs v-model="activeName" @tab-click="handleClick">
-      <el-tab-pane label="新建审核" name="create">
+      <el-tab-pane label="新建审核" name="creating">
         <el-pagination
           @size-change="handleSizeChange"
           @current-change="handleCurrentChange(createCurrentPage, createQuestionList, 'CHECKING')"
@@ -23,7 +23,7 @@
         />
       </el-tab-pane>
 
-      <el-tab-pane label="更新审核" name="update">
+      <el-tab-pane label="更新审核" name="updating">
         <!--todo: 设计UpdateQuestionCard并且在这里应用-->
         <el-pagination
           @size-change="handleSizeChange"
@@ -45,11 +45,11 @@
         />
       </el-tab-pane>
 
-      <el-tab-pane label="审核失败" name="refuse">
+      <el-tab-pane label="审核失败" name="refused">
         <!--todo: 设计RefuseQuestionCard并且在这里应用-->
       </el-tab-pane>
 
-      <el-tab-pane label="删除审核" name="execute">
+      <el-tab-pane label="删除审核" name="executing">
         <!--todo: 设计DeleteQuestionCard并且在这里应用-->
         <el-pagination
           @size-change="handleSizeChange"
@@ -69,7 +69,7 @@
         />
       </el-tab-pane>
 
-      <el-tab-pane label="删除完成" name="delete">
+      <el-tab-pane label="删除完成" name="deleted">
         <!--todo: 设计DeleteQuestionCard并且在这里应用-->
         <el-pagination
           @size-change="handleSizeChange"
@@ -114,7 +114,7 @@ export default {
       pageSize: 20,
 
       // 分页所需数据
-      activeName: "create",
+      activeName: "creating",
 
       // 新建审核题目列表
       createQuestionList: [],
@@ -166,7 +166,7 @@ export default {
       const _this = this
       switch (tab.props.name) {
         // 新建审核
-        case "create":
+        case "creating":
           // todo: 用真实代码替换mockjs
           // this.$api.getStateQuestion(tab.props.name.toUpperCase(), 0, this.pageSize)
           //   .then(res => {
@@ -185,14 +185,14 @@ export default {
           })
           break;
         // 更新审核
-        case "update":
+        case "updating":
           mockApi.mockGetUpdateQuestion().then().catch(err => {
             _this.updateTotalNum = err.data.length;
             _this.updateQuestionList = err.data
           })
           break;
         // 审核失败
-        case "refuse":
+        case "refused":
           this.$api.getStateQuestion(tab.props.name.toUpperCase(), 0, this.pageSize)
             .then(res => {
               console.log("getStateQuestion-REFUSED");
@@ -204,14 +204,14 @@ export default {
           })
           break;
         // 删除审核
-        case "execute":
+        case "executing":
           mockApi.mockGetExecuteQuestion().then().catch(err => {
             console.log(err)
             _this.executeTotalNum = err.data.length;
             _this.executeQuestionList = err.data
           })
           break;
-        case "delete":
+        case "deleted":
           mockApi.mockGetExecuteQuestion().then().catch(err => {
             console.log(err)
             _this.deleteTotalNum = err.data.length;
@@ -235,7 +235,7 @@ export default {
     },
   },
   mounted() {
-    this.handleClick({props: {name: "create"}}, null);
+    this.handleClick({props: {name: "creating"}}, null);
   }
 }
 </script>

+ 103 - 103
src/views/Bok/Main/QuestionRepository/index.vue

@@ -1,103 +1,93 @@
 <template>
-  <div class="index-title">
-    <h1>Question Repository</h1>
-  </div>
+  <h1>Question Repository</h1>
 
-  <div class="index-operation">
-    <el-button @click="createQuestion">新建题目</el-button>
-    <el-button @click="createQuestionByGruop">新建题目组</el-button>
+  <div>
+    <el-button @click="isSingleQuestionCreatorVisible=true">新建题目</el-button>
+    <el-button @click="createQuestion">新建题目组</el-button>
   </div>
 
-  <div class="index-body">
-    <div class="el-pagination-body">
-      <el-pagination
-              @size-change="handleSizeChange"
-              @current-change="handleCurrentChange"
-              :current-page="currentPage"
-              :page-sizes="[5, 10, 15, 20]"
-              :page-size="pageSize"
-              layout="total, sizes, prev, pager, next, jumper"
-              :total=this.totalNum
-              v-if="this.questionList.length !== 0"
-      >
-      </el-pagination>
-    </div>
-
-    <div class="QuestionBody">
-      <AbstractQuestionCard v-for="(item,index) in questionList"
-                         :key="item.id"
-                         :questionvo="item" :total-num="totalNum" :cur-num="index+(currentPage-1)*pageSize" />
-    </div>
+  <el-divider/>
+
+  <div>
+    <el-pagination @size-change="handleSizeChange"
+                   @current-change="handleCurrentChange"
+                   :current-page="currentPage"
+                   :page-sizes="[5, 10, 15, 20]"
+                   :page-size="pageSize"
+                   layout="total, sizes, prev, pager, next, jumper"
+                   :total=this.totalNum
+                   v-if="this.questionList.length !== 0"
+    />
+    <primary-question-card v-for="(item,index) in questionList"
+                           :key="item.id"
+                           :question-v-o="item"
+                           :total-num="totalNum"
+                           :cur-num="index+(currentPage-1)*pageSize"/>
 
     <el-backtop :bottom="50">
-      <div
-              style="{
-        height: 100%;
-        width: 100%;
-        background-color: #f2f5f6;
-        box-shadow: 0 0 6px rgba(0,0,0, .12);
-        text-align: center;
-        line-height: 40px;
-        color: #1989fa;
-      }"
-      >
+      <div style="height: 100%;width: 100%;background-color: #f2f5f6;box-shadow: 0 0 6px rgba(0,0,0, .12);line-height: 40px;">
         UP
       </div>
     </el-backtop>
   </div>
 
   <el-drawer
-          title="新建题目"
-          :before-close="handleClose"
-          v-model="dialog"
-          direction="rtl"
-          custom-class="question-drawer"
-          ref="drawer"
-          size="35%"
+    title="新建题目"
+    :before-close="handleClose"
+    v-model="dialog"
+    direction="rtl"
+    custom-class="question-drawer"
+    ref="drawer"
+    size="35%"
   >
     <QuestionCreater :dialog="dialog" @closeDialog="closeDialog"/>
   </el-drawer>
 
+  <el-dialog title="新建题目" v-model="isSingleQuestionCreatorVisible">
+    <single-question-creator></single-question-creator>
+  </el-dialog>
+
   <el-drawer
-          title="批量新建题目"
-          :before-close="handleClose"
-          v-model="dialog1"
-          direction="rtl"
-          custom-class="questionGroup-drawer"
-          ref="drawer"
-          size="35%"
+    title="批量新建题目"
+    :before-close="handleClose"
+    v-model="dialog1"
+    direction="rtl"
+    custom-class="questionGroup-drawer"
+    ref="drawer"
+    size="35%"
   >
     <QuestionGroupCreater :dialog="dialog1" @closeDialog="closeDialog1"/>
   </el-drawer>
 </template>
 
 <script>
-  import axios from "axios";
-  import QuestionCreater from "../../../../components/QuestionCreater.vue";
-  import QuestionGroupCreater from "../../../../components/QuestionGroupCreater.vue";
-  import BriefQuestionCard from "../../../../components/BriefQuestionCard.vue";
-  import AbstractQuestionCard from "../../../../components/AbstractQuestionCard";
-  import PrimaryQuestionCard from "@/components/QuestionCard/PrimaryQuestionCard";
-  import CreatingQuestionCard from "@/components/QuestionCard/CreatingQuestionCard";
+import QuestionGroupCreater from "../../../../components/QuestionGroupCreater.vue";
+import QuestionCreater from "@/components/QuestionCreater";
+import BriefQuestionCard from "../../../../components/BriefQuestionCard.vue";
+import PrimaryQuestionCard from "@/components/QuestionCard/PrimaryQuestionCard";
+import SingleQuestionCreator from "@/components/QuestionCreator/SingleQuestionCreator";
 
 export default {
   name: "QuestionRepository",
   components: {
-    CreatingQuestionCard,
-    QuestionCreater,
     QuestionGroupCreater,
     BriefQuestionCard,
-    AbstractQuestionCard: PrimaryQuestionCard,
+    PrimaryQuestionCard,
+    SingleQuestionCreator,
+    QuestionCreater
   },
   data() {
-    return{
+    return {
       info: null,
       questionList: [],
-      dialog:false,
-      dialog1:false,
+      dialog: false,
+      dialog1: false,
       currentPage: 1,
       pageSize: 20,
       totalNum: 0,
+
+      //
+      isSingleQuestionCreatorVisible: true,
     }
   },
   mounted() {
@@ -106,61 +96,67 @@ export default {
     // 挂载时获取第一页题目列表
     let states = 'APPROVED';
     this.$api.getStateQuestion(states, 0, this.pageSize)
-            .then(res => {
-              console.log("QuestionRepository/index");
-              console.log(res);
-              this.questionList = res.data.result.content;
-              this.totalNum = res.data.result.totalElements;
-            }).catch(error => {
+      .then(res => {
+        console.log("QuestionRepository/index");
+        console.log(res);
+        this.questionList = res.data.result.content;
+        this.totalNum = res.data.result.totalElements;
+      }).catch(error => {
       console.log(error);
     })
   },
-  computed: {
-  },
+  computed: {},
   methods: {
-    createQuestion(){
+    createQuestion() {
       this.dialog = true;
     },
-    createQuestionByGruop(){
+
+    createQuestionByGruop() {
       this.dialog1 = true;
     },
+
     handleClose(done) {
-      if (this.loading) {
-        return;
-      }
-      this.$confirm('确定要提交表单吗?')
-              .then(_ => {
-                this.loading = true;
-                this.timer = setTimeout(() => {
-                  done();
-                  // 动画关闭需要一定的时间
-                  setTimeout(() => {
-                    this.loading = false;
-                  }, 400);
-                }, 2000);
-              })
-              .catch(_ => {});
+      // if (this.loading) {
+      //   return;
+      // }
+      // this.$confirm('确定要提交表单吗?')
+      //   .then(_ => {
+      //     this.loading = true;
+          // this.timer = setTimeout(() => {
+          //   done();
+          //   // 动画关闭需要一定的时间
+          //   setTimeout(() => {
+          //     this.loading = false;
+          //   }, 400);
+          // }, 2000);
+        // })
+        // .catch(_ => {
+        // });
     },
-    closeDialog(){
+
+    closeDialog() {
       this.dialog = false;
     },
-    closeDialog1(){
+
+    closeDialog1() {
       this.dialog1 = false;
     },
+
     handleSizeChange(val) {
       console.log(`QuestionRepository/index-handleSizeChange 每页 ${val} 条`);
       this.pageSize = val;
     },
+
     handleCurrentChange(val) { // 当点击新的页面时才请求新的数据
       console.log(`QuestionRepository/index-handleCurrentChange 当前页: ${val}`);
       this.currentPage = val;
       let states = 'APPROVED';
-      this.$api.getStateQuestion(states, val-1, this.pageSize)
-              .then(res => {
-                console.log("handleCurrentChange-result");
-                console.log(res);
-                this.questionList = res.data.result.content;
-              }).catch(error => {
+      this.$api.getStateQuestion(states, val - 1, this.pageSize)
+        .then(res => {
+          console.log("handleCurrentChange-result");
+          console.log(res);
+          this.questionList = res.data.result.content;
+        }).catch(error => {
         console.log(error);
       })
     },
@@ -169,11 +165,15 @@ export default {
 </script>
 
 <style>
-  .el-pagination-body{
-    margin: 20px auto;
-  }
+.el-pagination-body {
+  margin: 20px auto;
+}
 
-  .el-drawer{
-    overflow-y: auto;
-  }
+.el-drawer {
+  overflow-y: auto;
+}
+
+.el-dialog{
+  margin: auto;
+}
 </style>