Browse Source

feat: questioncard

mjh 5 years ago
parent
commit
6f24dc1313

+ 1 - 0
package.json

@@ -12,6 +12,7 @@
     "core-js": "^3.6.5",
     "element-plus": "^1.0.2-beta.70",
     "marked": "^3.0.2",
+    "mockjs": "^1.1.0",
     "node-sass": "^4.14.1",
     "typescript": "^4.3.5",
     "vue": "^3.0.0",

+ 10 - 5
src/api/axios.config.js

@@ -7,7 +7,8 @@ export default function axiosConfig() {
     axios.interceptors.response.use(
         function(response) {
             if (process.env.NODE_ENV === 'development') {
-                console.log('[AXIOS] response value: ', response)
+                // mjh change
+                // console.log('[AXIOS] response value: ', response)
             }
 
             const responseData = response.data
@@ -15,7 +16,8 @@ export default function axiosConfig() {
             if (responseData.code === '00000') {
                 return Promise.resolve(response)
             } else {
-                console.log('reject')
+                // mjh change
+                // console.log('reject')
                 if (responseData.code === 'A0223' || responseData.code === 'A0230') {
                     jumpToLogin()
                 }
@@ -24,7 +26,8 @@ export default function axiosConfig() {
         },
         function(error) {
             if (process.env.NODE_ENV === 'development') {
-                console.error('[AXIOS] response error: ', error.response)
+                // mjh change
+                // console.error('[AXIOS] response error: ', error.response)
             }
 
             if (error.response) {
@@ -41,7 +44,8 @@ export default function axiosConfig() {
     axios.interceptors.request.use(
         function(config) {
             if (process.env.NODE_ENV === 'development') {
-                console.log('[AXIOS] request config: ', config)
+                // mjh change
+                // console.log('[AXIOS] request config: ', config)
             }
             if (store.state.token) {
                 config.headers = {
@@ -54,7 +58,8 @@ export default function axiosConfig() {
         // Do something with request error
         function(error) {
             if (process.env.NODE_ENV === 'development') {
-                console.error('[AXIOS] request error: ', error)
+                // mjh change
+                // console.error('[AXIOS] request error: ', error)
             }
             return Promise.reject(error)
         }

+ 21 - 0
src/api/mock.js

@@ -0,0 +1,21 @@
+import axios from "axios";
+
+export function mockTest() {
+    return axios.get("/mock/get")
+}
+
+export function mockGetUpdateQuestion(){
+    return axios.get("/mock/searchQuestion/update")
+}
+
+export function mockGetCreateQuestion(){
+    return axios.get("/mock/searchQuestion/create")
+}
+
+export function mockGetExecuteQuestion(){
+    return axios.get("/mock/searchQuestion/execute")
+}
+
+export function mockGetDeleteQuestion(){
+    return axios.get("/mock/searchQuestion/delete")
+}

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

@@ -0,0 +1,38 @@
+<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>

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

@@ -0,0 +1,139 @@
+<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>

+ 96 - 0
src/components/QuestionCard/CreatingQuestionCard.vue

@@ -0,0 +1,96 @@
+<template>
+  <primary-question-card v-if="questionVO!==undefined" :questionvo="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"/>
+      </el-col>
+      <el-col :span="1">
+        <el-button type="danger" icon="el-icon-close" circle @click="mockDisapproveQuestion"/>
+      </el-col>
+    </template>
+  </primary-question-card>
+</template>
+
+<script>
+import PrimaryQuestionCard from '@/components/QuestionCard/PrimaryQuestionCard';
+
+export default {
+  name: "CreatingQuestionCard",
+  components: {
+    PrimaryQuestionCard
+  },
+  data() {
+    return {}
+  },
+  props: {
+    questionVO: Object,
+    curNum: Number,
+    totalNum: Number
+  },
+  mounted() {
+  },
+  methods: {
+    // 审核通过新建的题目
+    approveQuestion() {
+      const _this = this
+      _this.questionVO.state = "APPROVED"
+      let record = {
+        userId: _this.$store.state.user.id,
+        operationType: "Approve",
+      }
+      // 更新题目信息
+      _this.$api.updateQuestion(this.questionVO)
+        .then(async res => {
+          console.log(res)
+          _this.$message({
+            type: "success",
+            message: "新建审核通过",
+          })
+          record.questionId = res.data.result.id;
+          record.time = new Date();
+          // 添加新的操作记录
+          await _this.$api.createRecord(record)
+            .then(recordRes => {
+              console.log(recordRes)
+            })
+            .catch(recordErr => {
+              console.log(recordErr)
+            })
+          // 向父组件更新题目列表信息
+          _this.$emit("approve")
+        })
+      .catch(err=>{
+        _this.$message({
+          type: "error",
+          message: "新建审核不通过"
+        })
+      })
+    },
+
+    // 审核不通过新建的题目
+    disapproveQuestion(){},
+
+    mockApproveQuestion() {
+      const _this = this
+      _this.$message({
+        type: "success",
+        message: "新建审核通过"
+      })
+      _this.$emit("approve")
+    },
+
+    mockDisapproveQuestion() {
+      const _this = this
+      _this.$message({
+        type: "error",
+        message: "新建审核不通过"
+      })
+    },
+  },
+  emits:["approve"]
+}
+</script>
+
+<style scoped>
+
+</style>

+ 44 - 0
src/components/QuestionCard/DeletedQuestionCard.vue

@@ -0,0 +1,44 @@
+<template>
+  <primary-question-card v-if="questionVO!==undefined"
+                         :questionvo="questionVO"
+                         :cur-num="curNum"
+                         :total-num="totalNum">
+    <template v-slot:button>
+      <el-col :span="1">
+        <el-button type="danger" icon="el-icon-delete" circle @click="mockRemoveQuestion"/>
+      </el-col>
+      <el-col :span="1">
+        <el-button type="primary" icon="el-icon-refresh-left" circle @click="mockRecoverQuestion"/>
+      </el-col>
+    </template>
+  </primary-question-card>
+</template>
+
+<script>
+import PrimaryQuestionCard from "@/components/QuestionCard/PrimaryQuestionCard";
+
+export default {
+  name: "DeletedQuestionCard",
+  components: {PrimaryQuestionCard},
+  props: {
+    questionVO: Object,
+    curNum: Number,
+    totalNum: Number,
+  },
+  methods:{
+    // todo
+    removeQuestion(){},
+
+    mockRemoveQuestion(){},
+
+    // todo
+    recoverQuestion(){},
+
+    mockRecoverQuestion(){},
+  },
+}
+</script>
+
+<style scoped>
+
+</style>

+ 52 - 0
src/components/QuestionCard/ExecutingQuestionCard.vue

@@ -0,0 +1,52 @@
+<template>
+  <primary-question-card v-if="questionVO!==undefined"
+                         :questionvo="questionVO"
+                         :cur-num="curNum"
+                         :total-num="totalNum">
+    <template v-slot:button>
+      <el-col :span="1">
+        <el-button type="danger" icon="el-icon-check" circle @click="mockExecuteQuestion"/>
+      </el-col>
+      <el-col :span="1">
+        <el-button type="primary" icon="el-icon-close" circle @click="mockPardonQuestion"/>
+      </el-col>
+    </template>
+  </primary-question-card>
+</template>
+
+<script>
+import PrimaryQuestionCard from "@/components/QuestionCard/PrimaryQuestionCard";
+
+export default {
+  name: "ExecutingQuestionCard",
+  components: {
+    PrimaryQuestionCard
+  },
+  props: {
+    questionVO: Object,
+    curNum: Number,
+    totalNum: Number,
+  },
+  methods: {
+    // 确认删除(处决)该题目
+    // todo
+    executeQuestion(){
+    },
+
+    mockExecuteQuestion(){
+    },
+
+    // 取消删除(赦免)该题目
+    // todo
+    pardonQuestion(){
+    },
+
+    mockPardonQuestion(){
+    },
+  },
+}
+</script>
+
+<style scoped>
+
+</style>

+ 398 - 0
src/components/QuestionCard/PrimaryQuestionCard.vue

@@ -0,0 +1,398 @@
+<template>
+  <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>
+      </slot>
+    </template>
+
+    <!--题目内容部分-->
+    <div class="primary-question-card-body">
+      <!--题干部分-->
+      <!--题干-题目描述部分-->
+      <slot name="stem">
+        <MarkdownText :raw="'<strong>题目: </strong>'+questionvo.stem"></MarkdownText>
+      </slot>
+      <!--题干-题目答案部分-->
+      <div v-show="isAll">
+        <!--单选题和多选题答案-->
+        <slot name="choiceOption"
+              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="correct_answer">
+              __{{ 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>
+      </div>
+    </div>
+
+    <el-divider v-show="isAll"></el-divider>
+
+    <!--题目解析部分-->
+    <div class="primary-question-card-analysis" v-show="isAll">
+      <!--题目解析-题目信息部分-->
+      <div class="analysis-block">
+        <el-row>
+          <slot name="keypoint">
+            <el-col :span="10">
+              <strong>KeyPoints: </strong>{{ questionvo.keyPoints }}
+            </el-col>
+          </slot>
+          <slot name="difficulty">
+            <el-col :span="6">
+              <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">
+                {{ item }}
+              </el-tag>
+            </span>
+              <span v-else>
+              <span>no tags</span>
+            </span>
+            </el-col>
+          </slot>
+        </el-row>
+      </div>
+      <!--题目解析-正确答案-->
+      <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>
+        </slot>
+        <!--todo: 简答-->
+      </div>
+      <!--题目解析-解析部分-->
+      <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>
+        </slot>
+        <!--填空-->
+        <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>
+      </div>
+    </div>
+
+    <el-divider v-show="isAll"></el-divider>
+
+    <!--题目操作记录部分-->
+    <div class="primary-question-card-record" v-show="isAll">
+      <!--题目当前状态-->
+      <div class="record-block">
+        <el-row>
+          <el-col :span="3">
+            <div><strong>状态: </strong>{{ questionvo.state }}</div>
+          </el-col>
+          <el-col :span="5">
+            <div><strong>审核人: </strong>{{ checkedUserName }}</div>
+          </el-col>
+        </el-row>
+      </div>
+      <!--题目历史操作记录-->
+      <div class="record-block" v-if="recordList.length !== 0">
+        <el-table :data="recordTable" style="width: 100%;background-color: transparent" height="100">
+          <el-table-column prop="序号" label="序号" width="240"/>
+          <el-table-column prop="操作时间" label="操作时间" width="320"/>
+          <el-table-column prop="操作人" label="操作人" width="240"/>
+          <el-table-column prop="操作类型" label="操作类型" width="240"/>
+          <el-table-column prop="备注" label="备注"/>
+        </el-table>
+      </div>
+      <div class="record-block" v-else>
+        <p>No Record!</p>
+      </div>
+    </div>
+  </el-card>
+
+  <el-drawer
+    title="更新题目"
+    :before-close="handleClose"
+    v-model="dialog"
+    direction="rtl"
+    custom-class="question-drawer"
+    ref="drawer"
+    size="35%"
+  >
+    <QuestionUpdater :question="questionvo" @closeDialog="closeDialog"/>
+  </el-drawer>
+
+</template>
+
+<script>
+import MarkdownText from "@/components/MarkdownText";
+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";
+
+export default {
+  name: "PrimaryQuestionCard",
+  components: {
+    MarkdownText,
+    QuestionUpdater,
+
+    ChoiceOption,
+  },
+  props: {
+    questionvo: Object,
+    curNum: Number,
+    totalNum: Number,
+  },
+  data() {
+    return {
+      isAll: false,
+      isAllRecord: false,
+      isDelete: false,
+      dialog: false,
+      checkedUserName: '',
+      recordList: [],
+      recordNameDict: {},
+    }
+  },
+  methods: {
+    toMyDate,
+    map,
+    expand() {
+      if (!this.isAll) {
+        this.isAll = true;
+      }
+    },
+    withdraw() {
+      if (this.isAll) {
+        this.isAll = false;
+      }
+    },
+    updateQuestion() {
+      this.dialog = true;
+    },
+    handleClose() {
+      this.$confirm('此操作将丢失填写信息, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.dialog = false;
+      })
+    },
+    closeDialog() {
+      this.dialog = false;
+    },
+    deleteQuestion() {
+      this.$confirm('此操作将删除该题目, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.questionvo.lastModifiedTime = new Date();
+        this.questionvo.state = "DELETED";
+        let record = {
+          userId: store.state.user.id,
+          operationType: "Delete",
+        }
+        this.$api.updateQuestion(this.questionvo)
+          .then(res => {
+            this.$message({
+              type: 'success',
+              message: '删除成功!'
+            });
+            this.isDelete = true;
+            record.questionId = res.data.result.id;
+            record.time = new Date();
+            this.$api.createRecord(record)
+              .then(res1 => {
+                console.log(res1);
+              }).catch(err1 => {
+              console.log(err1);
+            })
+          }).catch(error => {
+          console.log(error);
+          this.$notify.error({
+            title: '错误',
+            message: '删除失败'
+          });
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消删除'
+        });
+      });
+    },
+    recoverQuestion() {
+      alert("Delete successfully!");
+    },
+
+  },
+  computed: {
+    reversedRecordList() {
+      return this.recordList.reverse();
+    },
+    recordTable() {
+      let recordTable1 = [];
+      let length = this.recordList.length;
+      for (let i = 0; i < length; i++) {
+        let recordDict = {};
+        recordDict["序号"] = i + 1;
+        recordDict["操作时间"] = this.toMyDate(this.recordList[length - i - 1].time);
+        recordDict["操作人"] = this.recordNameDict[this.recordList[length - i - 1].userId];
+        recordDict["操作类型"] = this.recordList[length - i - 1].operationType;
+        recordDict["备注"] = this.recordList[length - i - 1].remark;
+        recordTable1.push(recordDict);
+      }
+      return recordTable1;
+    }
+  },
+  mounted() {
+    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;
+          }
+        }).catch(err => {
+        console.log(err);
+      })
+    }
+
+    this.$api.getRecordByQid(this.questionvo.id) // 异步函数2:根据题目id获得ope_record
+      .then(res1 => {
+        let tempList = res1.data.result.content;
+        this.recordList = tempList;
+        for (let record of tempList) { //这里换成this.recordList是没问题的
+          if (!this.recordNameDict[record.userId]) {
+            this.$api.getUserById(record.userId) //异步函数3:根据记录中的用户ID获得其name
+              .then(res2 => {
+                if (res2.data.result.name) {
+                  this.recordNameDict[record.userId] = res2.data.result.name;
+                }
+              }).catch(err2 => {
+              console.log(err2);
+            })
+          }
+        }
+      }).catch(err1 => {
+      console.log(err1);
+    });
+  }
+}
+</script>
+
+<style>
+.primary-question-card {
+  margin: 20px;
+  font-size: 18px;
+  background-color: #eef7f2;
+}
+
+.primary-question-card-body {
+  text-align: left;
+  /*margin-left: 32px;*/
+  font-size: 20px;
+  font-family: "Songti SC";
+}
+
+p {
+  display: block;
+  margin-block-start: 0px;
+  margin-block-end: 0px;
+  margin-inline-start: 0px;
+  margin-inline-end: 0px;
+}
+
+.bQuestion-card-body-options {
+  margin-top: 10px;
+  font-size: 18px;
+}
+
+.underline-correct-answer {
+  font-family: "Kaiti SC";
+  font-size: 22px;
+  color: #f1939c;
+  font-weight: bold;
+  text-decoration: underline;
+}
+
+.correct_answer {
+  font-family: "Kaiti SC";
+  font-size: 21px;
+  color: #f1939c;
+  font-weight: bold;
+}
+
+.analysis-block {
+  /*margin-bottom: 10px;*/
+}
+
+.fail-check-option {
+  padding: 5px;
+  width: 100%;
+}
+
+.record-block {
+  margin-bottom: 10px;
+}
+
+</style>

+ 12 - 0
src/components/QuestionCard/RefusedQuestionCard.vue

@@ -0,0 +1,12 @@
+<template>
+</template>
+
+<script>
+export default {
+  name: "RefusedQuestionCard"
+}
+</script>
+
+<style scoped>
+
+</style>

+ 311 - 0
src/components/QuestionCard/UpdatingQuestionCard.vue

@@ -0,0 +1,311 @@
+<template>
+  <!--更新题目卡片里不变的内容,如题目类型、修改记录等内容均参考newQuestionVO-->
+  <primary-question-card v-if="newQuestionVO!==undefined && oldQuestionVO!==undefined"
+                         :questionvo="newQuestionVO"
+                         :cur-num="curNum"
+                         :total-num="totalNum">
+    <!--新旧题目知识点不同-->
+    <template v-if="!isKnowledgeIdEqual" v-slot:knowledgeId>
+      <div class="contrast-wrapper">
+        <!--oldQuestionVO知识点显示内容-->
+        <div class="old-content">
+          <span><strong>KnowledgeId: </strong></span>
+          <el-tooltip v-if="oldQuestionVO.knowledgeId && oldQuestionVO.knowledgeId.length !== 0"
+                      v-for="item in oldQuestionVO.knowledgeId"
+                      effect="dark"
+                      placement="bottom">
+            <template #content>
+              {{ map(item) }}
+            </template>
+            <el-tag effect="dark" style="margin-right: 2px" class="old-tag">{{ item }}</el-tag>
+          </el-tooltip>
+          <span v-else>null</span>
+        </div>
+        <el-divider direction="vertical"/>
+        <!--newQuestionVO知识点显示内容-->
+        <div class="new-content">
+          <span><strong>KnowledgeId: </strong></span>
+          <el-tooltip v-if="newQuestionVO.knowledgeId && newQuestionVO.knowledgeId.length !== 0"
+                      v-for="item in newQuestionVO.knowledgeId"
+                      effect="dark"
+                      placement="bottom">
+            <template #content>
+              {{ map(item) }}
+            </template>
+            <el-tag effect="dark" style="margin-right: 2px" class="new-tag">{{ item }}</el-tag>
+          </el-tooltip>
+          <span v-else>null</span>
+        </div>
+      </div>
+    </template>
+    <!--更新审核题目卡片的按钮-->
+    <template v-slot:button>
+      <el-col :span="1">
+        <el-button type="primary" icon="el-icon-check" circle @click="mockApproveQuestion"/>
+      </el-col>
+      <el-col :span="1">
+        <el-button type="danger" icon="el-icon-close" circle @click="mockDisapproveQuestion"/>
+      </el-col>
+    </template>
+    <!--新旧题目题干不同-->
+    <template v-if="!isStemEqual" v-slot:stem>
+      <div class="contrast-wrapper">
+        <markdown-text class="old-content"
+                       :raw="'<strong>题目: </strong>'+oldQuestionVO.stem"/>
+        <el-divider direction="vertical"/>
+        <markdown-text class="new-content"
+                       :raw="'<strong>题目: </strong>'+newQuestionVO.stem"/>
+      </div>
+    </template>
+    <!--新旧选择题答案选项内容不同-->
+    <template v-if="!isChoiceOptionEqual" v-slot:choiceOption>
+      <update-choice-option :new-question-v-o="newQuestionVO" :old-question-v-o="oldQuestionVO"/>
+    </template>
+    <!--todo: 其他若干答案显示组件-->
+    <!--新旧题目关键词不同-->
+    <template v-if="!isKeypointEqual" v-slot:keypoint>
+      <div class="contrast-wrapper">
+        <div class="old-content">
+          <span>
+            <strong>KeyPoints: </strong>
+            {{ oldQuestionVO.keyPoints }}
+          </span>
+        </div>
+        <el-divider direction="vertical"/>
+        <span class="new-content">
+          <strong>KeyPoints: </strong>
+          {{ newQuestionVO.keyPoints }}
+        </span>
+      </div>
+    </template>
+    <!--新旧题目难度不同-->
+    <template v-if="!isDifficultyEqual" v-slot:difficulty>
+      <div class="contrast-wrapper">
+        <!--old difficulty-->
+        <div class="old-content">
+          <span>
+            <strong>题目难度: </strong>
+            {{ oldQuestionVO.weight }}/5
+          </span>
+        </div>
+        <!--new difficulty-->
+        <el-divider direction="vertical"/>
+        <div class="new-content">
+          <span>
+            <strong>题目难度: </strong>
+            {{ newQuestionVO.weight }}/5
+          </span>
+        </div>
+      </div>
+    </template>
+    <!--新旧题目Tag不同-->
+    <template v-if="!isTagEqual" v-slot:tag>
+      <div class="contrast-wrapper">
+        <!--old tag-->
+        <div class="old-content">
+          <span><strong>Tags: </strong></span>
+          <span v-if="oldQuestionVO.tags && oldQuestionVO.tags.length !== 0">
+            <el-tag v-for="(item, index) in oldQuestionVO.tags" effect="dark" class="old-tag">
+              {{ item }}
+            </el-tag>
+          </span>
+          <span v-else>
+            <span>no tags</span>
+          </span>
+        </div>
+        <el-divider direction="vertical"/>
+        <!--new tag-->
+        <div class="new-content">
+          <span><strong>Tags: </strong></span>
+          <span v-if="newQuestionVO.tags && newQuestionVO.tags.length !== 0">
+            <el-tag v-for="(item, index) in newQuestionVO.tags" effect="dark" class="new-tag">
+              {{ item }}
+            </el-tag>
+          </span>
+          <span v-else>
+            <span>no tags</span>
+          </span>
+        </div>
+      </div>
+    </template>
+    <!--新旧题目正确答案不同-->
+    <template v-if="!isAnswerEqual" v-slot:answer1>
+      <div class="contrast-wrapper">
+        <!--old answer-->
+        <MarkdownText class="old-content" :raw="'<strong>正确答案: </strong>'+oldQuestionVO.answer"/>
+        <el-divider direction="vertical"/>
+        <!--new answer-->
+        <MarkdownText class="new-content" :raw="'<strong>正确答案: </strong>'+newQuestionVO.answer"/>
+      </div>
+    </template>
+    <!--新旧题目解析不同-->
+    <template v-if="!isAnalysisEqual" v-slot:analysis1>
+      <div class="contrast-wrapper">
+        <!--old analysis-->
+        <MarkdownText class="old-content" :raw="'<strong>解析: </strong>'+oldQuestionVO.analysis"></MarkdownText>
+        <el-divider direction="vertical"/>
+        <!--new analysis-->
+        <MarkdownText class="new-content" :raw="'<strong>解析: </strong>'+newQuestionVO.analysis"></MarkdownText>
+      </div>
+    </template>
+  </primary-question-card>
+</template>
+
+<script>
+import PrimaryQuestionCard from "@/components/QuestionCard/PrimaryQuestionCard";
+import MarkdownText from "@/components/MarkdownText";
+import UpdateChoiceOption from "@/components/QuestionCard/AnswerOption/UpdatingChoiceOption";
+import {map} from "@/utils/knowledgeMapper";
+
+export default {
+  name: "UpdatingQuestionCard",
+  components: {
+    PrimaryQuestionCard,
+    MarkdownText,
+    UpdateChoiceOption,
+  },
+  props: {
+    oldQuestionVO: Object,
+    newQuestionVO: Object,
+    curNum: Number,
+    totalNum: Number,
+  },
+  computed: {
+    // 新旧题目的知识点是否相同
+    isKnowledgeIdEqual() {
+      const _this = this
+      let o = _this.oldQuestionVO.knowledgeId
+      let n = _this.newQuestionVO.knowledgeId
+      if (o.length !== n.length) {
+        return false;
+      }
+      for (let i = 0; i < o.length; i++) {
+        if (n.indexOf(o[i]) === -1) {
+          return false;
+        }
+      }
+      return true;
+    },
+
+    // 新旧题目的题干是否相同
+    isStemEqual() {
+      return this.oldQuestionVO.stem === this.newQuestionVO.stem;
+    },
+
+    // 新旧选择题答案选项内容是否相同
+    isChoiceOptionEqual() {
+      const _this = this
+      let o = _this.oldQuestionVO.options
+      let n = _this.newQuestionVO.options
+      return (o.A === n.A) && (o.B === n.B) && (o.C === n.C) && (o.D === n.D)
+    },
+
+    // 新旧题目的关键词是否相同
+    isKeypointEqual() {
+      return this.oldQuestionVO.keyPoints === this.newQuestionVO.keyPoints;
+    },
+
+    // 新旧题目的难度是否相同
+    isDifficultyEqual() {
+      return this.oldQuestionVO.weight === this.newQuestionVO.weight;
+    },
+
+    // 新旧题目的Tag是否相同
+    isTagEqual() {
+      const _this = this
+      let o = _this.oldQuestionVO.tags
+      let n = _this.newQuestionVO.tags
+      if (o.length !== n.length) {
+        return false;
+      }
+      for (let i = 0; i < o.length; i++) {
+        if (n.indexOf(o[i]) === -1) {
+          return false;
+        }
+      }
+      return true;
+    },
+
+    // 新旧题目的正确答案是否相同
+    isAnswerEqual() {
+      return this.oldQuestionVO.answer === this.newQuestionVO.answer;
+    },
+
+    // 新旧题目的解析是否相同
+    isAnalysisEqual() {
+      return this.oldQuestionVO.analysis === this.newQuestionVO.analysis;
+    }
+  },
+  mounted() {
+  },
+  methods: {
+    map,
+
+    // 审核通过更新的题目
+    approveQuestion() {
+    },
+
+    mockApproveQuestion() {
+      const _this = this
+      _this.$message({
+        type: "success",
+        message: "更新审核通过"
+      })
+    },
+
+    // 审核不通过更新的题目
+    disapproveQuestion() {
+    },
+
+    mockDisapproveQuestion() {
+      const _this = this
+      _this.$message({
+        type: "error",
+        message: "更新审核不通过"
+      })
+    },
+  },
+}
+</script>
+
+<style>
+.contrast-wrapper {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+}
+
+.old-content {
+  text-align: center;
+  background: #feefea;
+  color: #dc745a;
+  border-color: #dc745a;
+  width: 49%;
+}
+
+.new-content {
+  text-align: center;
+  background: #e8fdf4;
+  color: #59a48d;
+  border-color: #59a48d;
+  width: 49%;
+}
+
+.old-tag {
+  background: #feefea;
+  color: #dc745a;
+  border-color: #dc745a;
+}
+
+.new-tag {
+  background: #e8fdf4;
+  color: #59a48d;
+  border-color: #59a48d;
+}
+
+.el-divider--vertical {
+  margin-left: 1%;
+  margin-right: 1%;
+  height: auto;
+}
+</style>

+ 1 - 1
src/components/checkQuestionCard.vue

@@ -40,7 +40,7 @@
             </el-row>
         </template>
         <div class="question-body">
-            <div class="bQuestion-card-body">
+            <div class="primary-question-card-body">
                 <div class="bQuestion-card-body-stem">
                     <div>
                         <MarkdownText :raw="'<strong>题目: </strong>'+questionvo.stem"></MarkdownText>

+ 2 - 1
src/main.js

@@ -2,10 +2,11 @@ import { createApp } from 'vue'
 import App from './App.vue'
 import router from './router'
 import store from './store'
+import './mock/index'
 
 import ElementPlus from 'element-plus';
 import 'element-plus/lib/theme-chalk/index.css';
-import {api} from '@/api/index'
+import {api} from './api/index'
 
 let Vue = createApp(App);
 

+ 74 - 0
src/mock/index.js

@@ -0,0 +1,74 @@
+import Mock from 'mockjs';
+
+// mockjs拦截下来的请求方法写在@/api/mock.js中
+
+let questionVO = {
+    analysis: "测试",
+    answer: "A",
+    blanks: null,
+    checkedUserId: 364,
+    createdTime: "2021-10-31T11:47:29.412Z",
+    id: "596adc65-f595-4515-a433-e49ef7752e80",
+    inputOutputMapping: null,
+    keyPoints: "",
+    knowledgeId: ['2','1'],
+    lastModifiedTime: null,
+    memoryLimit: null,
+    millisecondLimit: null,
+    options: {A: '1', B: '2', C: '3 ', D: '4'},
+    savedUserId: 1481,
+    state: "APPROVED",
+    stem: "测试2",
+    tags: ['Java'],
+    title: null,
+    type: "choice",
+    weight: 1,
+}
+
+Mock.mock('/mock/test', 'get', () => {
+    return "hello, mock!"
+})
+
+Mock.mock('/mock/searchQuestion/update', 'get', () => {
+    let oldQuestionVO = questionVO
+
+    let newQuestionVO = {
+        analysis: "测试111",
+        answer: "B",
+        blanks: null,
+        checkedUserId: 364,
+        createdTime: "2021-10-31T11:47:29.412Z",
+        id: "596adc65-f595-4515-a433-e49ef7752e80",
+        inputOutputMapping: null,
+        keyPoints: "1",
+        knowledgeId: ['1'],
+        lastModifiedTime: null,
+        memoryLimit: null,
+        millisecondLimit: null,
+        options: {A: '11', B: '2', C: '33', D: '44'},
+        savedUserId: 1481,
+        state: "APPROVED",
+        stem: "测试2",
+        tags: ['Python','C'],
+        title: null,
+        type: "choice",
+        weight: 2
+    }
+
+    return [{
+        oldQuestionVO,
+        newQuestionVO,
+    }]
+})
+
+Mock.mock('/mock/searchQuestion/create', 'get', () => {
+    return [questionVO]
+})
+
+Mock.mock("/mock/searchQuestion/execute", "get", ()=>{
+    return [questionVO]
+})
+
+Mock.mock("/mock/searchQuestion/delete", "get", ()=>{
+    return [questionVO]
+})

+ 230 - 137
src/views/Bok/Main/Check.vue

@@ -1,155 +1,248 @@
 <template>
-    <div>
-        <h1>题目审查</h1>
-        <el-tabs v-model="activeName" @tab-click="handleClick">
-            <el-tab-pane label="未审核" name="checking">
-                <div class="el-pagination-body">
-                    <el-pagination
-                        @size-change="handleSizeChange"
-                        @current-change="handleCurrentChange(currentPage, questionList, 'CHECKING')"
-                        :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>
-                    <checkQuestionCard v-for="(item, index) in questionList"
-                                       :questionvo="item"
-                                       :key="item.id"
-                                       :cur-num="index+(currentPage-1)*pageSize"
-                                       :total-num="totalNum"
-                                       @approved="handleApproved(item)"
-                    ></checkQuestionCard>
-                </div>
-            </el-tab-pane>
-            <el-tab-pane label="未通过" name="refused">
-                <div class="el-pagination-body">
-                    <el-pagination
-                        @size-change="handleSizeChange"
-                        @current-change="handleCurrentChange(refusedCurrentPage, refusedQuestionList, 'REFUSED')"
-                        :current-page="refusedCurrentPage"
-                        :page-sizes="[5, 10, 15, 20]"
-                        :page-size="pageSize"
-                        layout="total, sizes, prev, pager, next, jumper"
-                        :total=refusedTotalNum
-                        v-if="refusedQuestionList.length !== 0"
-                    >
-                    </el-pagination>
-                </div>
-                <div>
-                    <checkQuestionCard v-for="(item, index) in refusedQuestionList"
-                                       :questionvo="item"
-                                       :key="item.id"
-                                       :cur-num="index+(refusedCurrentPage-1)*pageSize"
-                                       :total-num="refusedTotalNum"
-                                       @approved="handleApproved(item, refusedQuestionList)"
-                    ></checkQuestionCard>
-                </div>
-            </el-tab-pane>
-        </el-tabs>
-
-    </div>
+  <div>
+    <h1>题目审查</h1>
+    <el-tabs v-model="activeName" @tab-click="handleClick">
+      <el-tab-pane label="新建审核" name="create">
+        <el-pagination
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange(createCurrentPage, createQuestionList, 'CHECKING')"
+          :current-page="createCurrentPage"
+          :page-sizes="[5, 10, 15, 20]"
+          :page-size="pageSize"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total=this.createTotalNum
+          v-if="this.createQuestionList.length !== 0"
+        />
+        <creating-question-card
+          v-for="(item, index) in createQuestionList"
+          :question-v-o="item"
+          :key="item.id"
+          :cur-num="index+(createCurrentPage-1)*pageSize"
+          :total-num="createTotalNum"
+          @approve="handleApproved(item, createQuestionList)"
+        />
+      </el-tab-pane>
+
+      <el-tab-pane label="更新审核" name="update">
+        <!--todo: 设计UpdateQuestionCard并且在这里应用-->
+        <el-pagination
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange(updateCurrentPage, updateQuestionList, 'UPDATE')"
+          :current-page="updateCurrentPage"
+          :page-sizes="[5, 10, 15, 20]"
+          :page-size="pageSize"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total=updateTotalNum
+          v-if="updateQuestionList.length !== 0"
+        />
+        <updating-question-card
+          v-for="(item, index) in updateQuestionList"
+          :old-question-v-o="item.oldQuestionVO"
+          :new-question-v-o="item.newQuestionVO"
+          :key="item.id"
+          :cur-num="index+(updateCurrentPage-1)*pageSize"
+          :total-num="updateTotalNum"
+        />
+      </el-tab-pane>
+
+      <el-tab-pane label="审核失败" name="refuse">
+        <!--todo: 设计RefuseQuestionCard并且在这里应用-->
+      </el-tab-pane>
+
+      <el-tab-pane label="删除审核" name="execute">
+        <!--todo: 设计DeleteQuestionCard并且在这里应用-->
+        <el-pagination
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange(executeCurrentPage, executeQuestionList, 'EXECUTED')"
+          :current-page="executeCurrentPage"
+          :page-sizes="[5, 10, 15, 20]"
+          :page-size="pageSize"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total=executeTotalNum
+          v-if="executeQuestionList.length !== 0"
+        />
+        <executing-question-card v-for="(item, index) in executeQuestionList"
+                                 :question-v-o="item"
+                                 :key="item.id"
+                                 :cur-num="index+(executeCurrentPage-1)*pageSize"
+                                 :total-num="executeTotalNum"
+        />
+      </el-tab-pane>
+
+      <el-tab-pane label="删除完成" name="delete">
+        <!--todo: 设计DeleteQuestionCard并且在这里应用-->
+        <el-pagination
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange(deleteCurrentPage, deleteQuestionList, 'DELETED')"
+          :current-page="deleteCurrentPage"
+          :page-sizes="[5, 10, 15, 20]"
+          :page-size="pageSize"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total=deleteTotalNum
+          v-if="deleteQuestionList.length !== 0"
+        />
+        <deleted-question-card v-for="(item, index) in deleteQuestionList"
+                               :question-v-o="item"
+                               :key="item.id"
+                               :cur-num="index+(deleteCurrentPage-1)*pageSize"
+                               :total-num="deleteTotalNum"
+        />
+      </el-tab-pane>
+    </el-tabs>
+  </div>
 </template>
 
 <script>
 import checkQuestionCard from "../../../components/checkQuestionCard";
+import CreatingQuestionCard from "@/components/QuestionCard/CreatingQuestionCard";
+import * as mockApi from "@/api/mock";
+import UpdatingQuestionCard from "@/components/QuestionCard/UpdatingQuestionCard";
+import ExecutingQuestionCard from "@/components/QuestionCard/ExecutingQuestionCard";
+import DeletedQuestionCard from "@/components/QuestionCard/DeletedQuestionCard";
 
 export default {
-    name: "Check",
-    components: {
-        checkQuestionCard,
-    },
-    data() {
-        return {
-            questionList: [],
-            currentPage: 1,
-            pageSize: 20,
-            totalNum: 0,
-
-            // 分页所需数据
-            activeName: "checking",
-
-            // 未通过审核题目列表
-            refusedQuestionList: [],
-            refusedCurrentPage: 1,
-            refusedTotalNum: 0,
-        }
+  name: "Check",
+  components: {
+    DeletedQuestionCard,
+    checkQuestionCard,
+    CreatingQuestionCard,
+    UpdatingQuestionCard,
+    ExecutingQuestionCard,
+  },
+  data() {
+    return {
+      pageSize: 20,
+
+      // 分页所需数据
+      activeName: "create",
+
+      // 新建审核题目列表
+      createQuestionList: [],
+      createCurrentPage: 1,
+      createTotalNum: 0,
+
+      // 审核失败题目列表
+      refuseQuestionList: [],
+      refuseCurrentPage: 1,
+      refuseTotalNum: 0,
+
+      // 更新审核题目列表
+      updateQuestionList: [],
+      updateCurrentPage: 1,
+      updateTotalNum: 0,
+
+      // 删除审核题目列表
+      executeQuestionList: [],
+      executeCurrentPage: 1,
+      executeTotalNum: 0,
+
+      // 删除完成题目列表
+      deleteQuestionList: [],
+      deleteCurrentPage: 1,
+      deleteTotalNum: 0,
+    }
+  },
+  methods: {
+
+    handleSizeChange(val) {
+      console.log(`QuestionRepository/index-handleSizeChange 每页 ${val} 条`);
+      this.pageSize = val;
     },
-    methods: {
-        handleSizeChange(val) {
-            console.log(`QuestionRepository/index-handleSizeChange 每页 ${val} 条`);
-            this.pageSize = val;
-        },
-        handleCurrentChange(val, currentPage, questionList, states) { // 当点击新的页面时才请求新的数据
-            console.log(`Check-handleCurrentChange 当前页: ${val}`);
-            currentPage = val;
-            this.$api.getStateQuestion(states, val - 1, this.pageSize)
-                .then(res => {
-                    console.log("handleCurrentChange-check");
-                    console.log(res);
-                    questionList = res.data.result.content;
-                }).catch(error => {
-                console.log(error);
-            })
-        },
-
-        // 切换分页
-        handleClick(tab, event) {
-            switch (tab.props.name){
-                case "checking":
-                    this.$api.getStateQuestion(tab.props.name.toUpperCase(), 0, this.pageSize)
-                        .then(res => {
-                            console.log("getStateQuestion-CHECKING");
-                            console.log(res);
-                            this.questionList = res.data.result.content;
-                            this.totalNum = res.data.result.totalElements;
-                        }).catch(err => {
-                        console.log(err);
-                    })
-                    break;
-                case "refused":
-                    this.$api.getStateQuestion(tab.props.name.toUpperCase(), 0, this.pageSize)
-                        .then(res => {
-                            console.log("getStateQuestion-REFUSED");
-                            console.log(res);
-                            this.refusedQuestionList = res.data.result.content;
-                            this.refusedTotalNum = res.data.result.totalElements;
-                        }).catch(err => {
-                        console.log(err);
-                    })
-                    break;
-            }
-        },
-
-        // 处理题目审核通过
-        handleApproved(item, questionList){
-            questionList = questionList.filter(function (q, index){
-                return q !== item
-            })
-        },
+    handleCurrentChange(val, currentPage, questionList, states) { // 当点击新的页面时才请求新的数据
+      console.log(`Check-handleCurrentChange 当前页: ${val}`);
+      currentPage = val;
+      this.$api.getStateQuestion(states, val - 1, this.pageSize)
+        .then(res => {
+          console.log("handleCurrentChange-check");
+          console.log(res);
+          questionList = res.data.result.content;
+        }).catch(error => {
+        console.log(error);
+      })
     },
-    mounted() {
-        let states = "CHECKING"
-        this.$api.getStateQuestion(states, 0, this.pageSize)
+
+    // 切换分页
+    handleClick(tab, event) {
+      const _this = this
+      switch (tab.props.name) {
+        // 新建审核
+        case "create":
+          // todo: 用真实代码替换mockjs
+          // this.$api.getStateQuestion(tab.props.name.toUpperCase(), 0, this.pageSize)
+          //   .then(res => {
+          //     // mjh change
+          //     // console.log("getStateQuestion-CHECKING");
+          //     // console.log(res);
+          //     this.createQuestionList = res.data.result.content;
+          //     this.createTotalNum = res.data.result.totalElements;
+          //   })
+          //   .catch(err => {
+          //     console.log(err);
+          //   })
+          mockApi.mockGetCreateQuestion().then().catch(err => {
+            _this.createQuestionList = err.data
+            _this.createTotalNum = err.data.length
+          })
+          break;
+        // 更新审核
+        case "update":
+          mockApi.mockGetUpdateQuestion().then().catch(err => {
+            _this.updateTotalNum = err.data.length;
+            _this.updateQuestionList = err.data
+          })
+          break;
+        // 审核失败
+        case "refuse":
+          this.$api.getStateQuestion(tab.props.name.toUpperCase(), 0, this.pageSize)
             .then(res => {
-                console.log("getStateQuestion-CHECKING");
-                console.log(res);
-                this.questionList = res.data.result.content;
-                this.totalNum = res.data.result.totalElements;
+              console.log("getStateQuestion-REFUSED");
+              console.log(res);
+              this.refuseQuestionList = res.data.result.content;
+              this.refuseTotalNum = res.data.result.totalElements;
             }).catch(err => {
             console.log(err);
-        })
-    }
+          })
+          break;
+        // 删除审核
+        case "execute":
+          mockApi.mockGetExecuteQuestion().then().catch(err => {
+            console.log(err)
+            _this.executeTotalNum = err.data.length;
+            _this.executeQuestionList = err.data
+          })
+          break;
+        case "delete":
+          mockApi.mockGetExecuteQuestion().then().catch(err => {
+            console.log(err)
+            _this.deleteTotalNum = err.data.length;
+            _this.deleteQuestionList = err.data
+          })
+          break;
+        default:
+          break;
+      }
+    },
+
+    // 处理题目审核通过
+    handleApproved(index, questionList) {
+      const _this = this
+      _this.$message({
+        type: "success",
+        message: "handle approved"
+      })
+      // todo: 更换真实代码后取消注释
+      // questionList.splice(index, 1)
+    },
+  },
+  mounted() {
+    this.handleClick({props: {name: "create"}}, null);
+  }
 }
 </script>
 
 <style>
-.el-tabs__header{
-    padding-left: 20px;
-    padding-right: 20px;
+.el-tabs__header {
+  padding-left: 20px;
+  padding-right: 20px;
 }
 </style>

+ 6 - 1
src/views/Bok/Main/QuestionRepository/index.vue

@@ -77,14 +77,17 @@
   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";
 
 export default {
   name: "QuestionRepository",
   components: {
+    CreatingQuestionCard,
     QuestionCreater,
     QuestionGroupCreater,
     BriefQuestionCard,
-    AbstractQuestionCard
+    AbstractQuestionCard: PrimaryQuestionCard,
   },
   data() {
     return{
@@ -98,6 +101,8 @@ export default {
     }
   },
   mounted() {
+    console.log(this.questionList)
+
     // 挂载时获取第一页题目列表
     let states = 'APPROVED';
     this.$api.getStateQuestion(states, 0, this.pageSize)