瀏覽代碼

Merge branch 'sub-question-render' into baiyou

hehaitao 1 年之前
父節點
當前提交
2e343bd983

+ 31 - 0
src/assets/styles/common.scss

@@ -594,6 +594,34 @@
   flex: 5;
 }
 
+.gap5 {
+  gap: 5px;
+}
+.gap-x-5 {
+  row-gap: 5px;
+}
+.gap-y-5 {
+  column-gap: 5px;
+}
+.gap10 {
+  gap: 10px;
+}
+.gap-x-10 {
+  row-gap: 10px;
+}
+.gap-y-10 {
+  column-gap: 10px;
+}
+.gap20 {
+  gap: 20px;
+}
+.gap-x-20 {
+  row-gap: 20px;
+}
+.gap-y-20 {
+  column-gap: 20px;
+}
+
 .pd10 {
   padding: 10px;
 }
@@ -638,6 +666,9 @@
 .bd-f2 {
   border: 1px solid #f2f2f2;
 }
+.bd-ddd {
+  border: 1px solid #dddddd;
+}
 
 .bg-border {
   background-color: #EEEEEE;

+ 34 - 0
src/components/MxCollectButton/MxCollectButton.vue

@@ -0,0 +1,34 @@
+<template>
+  <div class="fx-row ai-cen gap5 f14 pointer el-button el-button--text" @click="handleClick">
+    <svg-icon :icon-class="value?'star-fill-16':'star-16'" :class="value?'f-primary':'f-666'"/>
+    <span class="f-666">{{ value ? '取消收藏' : '点击收藏' }}</span>
+  </div>
+</template>
+
+<script>
+import {createInjectDefaultClosure, nonsensicalFn} from "@/utils";
+
+export default {
+  name: "MxCollectButton",
+  inject: {
+    collectFn: createInjectDefaultClosure(nonsensicalFn),
+    collectCancelFn: createInjectDefaultClosure(nonsensicalFn)
+  },
+  props: {
+    value: {
+      type: Boolean,
+      default: false
+    }
+  },
+  methods: {
+    handleClick() {
+      if (!this.value) this.collectFn()
+      else this.collectCancelFn()
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 1 - 1
src/components/MxPaper/mx-question-content.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="fx-column" :id="'question_'+question.questionId">
-    <div v-html="questionWithSeq" class="answer"></div>
+    <div v-html="questionWithSeq" class="answer fx-row"></div>
     <div class="fx-column mt30 pl20 pr20">
       <!-- 递归,支持子题 -->
       <template v-if="question['subQuestions']">

+ 121 - 0
src/components/MxQuestionReadonly/MxQuestionReadonly.vue

@@ -0,0 +1,121 @@
+<template>
+  <div class="fx-column bd-ddd pd20" :id="`question_`+question.id">
+    <mx-question-content :options="standardOptions"/>
+    <el-divider/>
+    <div class="fx-row fx-bet-cen">
+      <div class="fx-row ai-cen gap20 f12 f-999">
+        <span>ID: {{ question.id }}</span>
+        <span>题型: {{ question.qtpye }}</span>
+        <span>难度: {{ diffText }}</span>
+      </div>
+      <div class="fx-row ai-cen gap20">
+        <slot name="prefix" />
+        <mx-collect-button :value="question.collect" />
+        <el-button type="text" @click="$emit('correct')">
+          <i class="el-icon-info f-red"></i>
+          <span class="f-666">试题纠错</span>
+        </el-button>
+        <el-button type="text" @click="toggleParse">
+          <i class="el-icon-search f-warning"></i>
+          <span class="f-666">查看解析</span>
+        </el-button>
+        <slot name="suffix" />
+      </div>
+    </div>
+    <div :id="parseEleId" v-if="showParse" class="mt20">
+      <div v-html="'【解答】'+question.answer2" class="mb20"></div>
+      <div v-html="'【解析】'+question.parse"></div>
+    </div>
+  </div>
+</template>
+
+<script>
+import MxQuestionContent from "@/components/MxPaper/mx-question-content.vue";
+import MxCollectButton from "@/components/MxCollectButton/MxCollectButton.vue";
+import {queCancelCollect, queCollect} from "@/api/webApi/webQue";
+
+// 收拢旧的question模型
+export default {
+  name: "MxQuestionReadonly",
+  components: {MxCollectButton, MxQuestionContent},
+  props: {
+    seq: {
+      type: String | Number,
+      default: ''
+    },
+    question: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      showParse: false
+    }
+  },
+  computed: {
+    standardOptions() {
+      return {
+        question: this.toStandardQuestion(this.question, this.seq),
+        allowAnswer: false,
+        allowScore: false,
+        examineeType: '',
+        paperOptions: {}
+      }
+    },
+    diffText() {
+      if (this.question.diff > 3) return '难'
+      if (this.question.diff < 3) return '易'
+      return '中'
+    },
+    parseEleId() {
+      return `question_parse_${this.question.id}`
+    }
+  },
+  provide() {
+    return {
+      collectFn: this.questionCollect,
+      collectCancelFn: this.questionCollectCancel
+    }
+  },
+  methods: {
+    toStandardQuestion(q, seq) {
+      const options = []
+      const prefix = 'option'
+      Object.keys(q).forEach(prop => {
+        if (prop.startsWith(prefix) && prop.length > prefix.length) {
+          const val = q[prop]
+          if (val) options.push(val)
+        }
+      })
+      return {
+        ...q,
+        seq: q.seq || seq,
+        questionId: q.id,
+        options,
+        subQuestions: q.subquestions?.length ? q.subquestions.map((item, i) => this.toStandardQuestion(item, `(${i + 1})`)) : undefined
+      }
+    },
+    questionCollect() {
+      queCollect({questionId: this.question.id}).then((res) => {
+        this.question.collect = !this.question.collect
+        this.msgSuccess('收藏成功')
+      })
+    },
+    questionCollectCancel() {
+      queCancelCollect({questionId: this.question.id}).then((res) => {
+        this.question.collect = !this.question.collect
+        this.msgSuccess('取消收藏成功')
+      })
+    },
+    toggleParse() {
+      this.showParse = !this.showParse
+      if (this.showParse) this.$nextTick(_ => this.mxGlobal.MathQueue(this.parseEleId))
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 12 - 0
src/utils/index.js

@@ -473,3 +473,15 @@ export function formatDuration(totalSeconds, short = true) {
     return month + '月' + day + '天' + hours + '小时' + minutes + '分' + seconds + '秒'
   }
 }
+
+export function createInjectDefaultClosure(defVal) {
+  return {
+    default: function () {
+      return () => defVal
+    }
+  }
+}
+
+export function nonsensicalFn() {
+
+}

+ 28 - 270
src/views/questioncenter/PaperPreview.vue

@@ -1,93 +1,32 @@
 <template>
-  <div class="preview_container">
-    <el-card>
-      <div class="paper_header">
-        <div class="paper_title">{{ paperName }}</div>
-        <div class="operation">
-          <div class="shoucan">
-            <div v-if="collectFlag" class="fx-row ai-center" @click="cancelCollect()">
-              <img src="@/assets/images/icon_shoucang_s.png" alt=""/>
-              <span class="sc_text">已收藏</span>
-            </div>
-            <div v-else @click="Collect()" class="fx-row ai-center">
-              <img src="@/assets/images/icon_shoucang_n.png" alt=""/>
-              <span class="sc_text">收藏</span>
-            </div>
-            <span class="btn" @click="paperDownLoad(paperId)">下载试卷</span>
-          </div>
+  <div class="app-container">
+    <el-card shadow="never">
+      <!-- 标题 -->
+      <div class="fx-row fx-bet-cen gap20 mb20">
+        <div class="f18 bold f-333">{{ paperName }}</div>
+        <div class="fx-row fx-bet-cen gap20">
+          <mx-collect-button :value="collectFlag"/>
+          <el-button type="primary" @click="paperDownLoad(paperId)">下载试卷</el-button>
         </div>
       </div>
       <!-- 题目 -->
-      <div class="paper_questions" id="question_list">
-        <div class="que_item" v-for="(item, index) in opticList" :key="item.id">
-          <div class="que_content" style="display: flex">
-            <div>{{ index + 1 }}.</div>
-            <span v-html="item.title"></span>
-          </div>
-          <div class="option-list">
-            <span v-html="'A&nbsp'+item.optionA" v-if="item.optionA != ''"></span>
-            <span v-html="'B&nbsp'+item.optionB" v-if="item.optionB != ''"></span>
-            <span v-html="'C&nbsp'+item.optionC" v-if="item.optionC != ''"></span>
-            <span v-html="'D&nbsp'+item.optionD" v-if="item.optionD != ''"></span>
-          </div>
-          <div class="subQueBox" v-if="item.issub == 1 && item.subquestions != null">
-            <div class="subQueItem" v-for="(item,index) in item.subquestions" :key="index" v-html="item.title">
-
-            </div>
-          </div>
-          <div class="que_footer">
-            <div class="spans">
-              <span class="id">ID: {{ item.id }}</span>
-              <span>题型: {{ item.qtpye }}</span>
-              <span>难度: 一般</span>
-            </div>
-            <div class="operation">
-              <div class="shoucan">
-                <div v-show="item.collect" @click="toCancelCollectQue(item)" style="display: flex;align-items: center;">
-                  <img src="@/assets/images/icon_shoucang_s.png" alt=""/>
-                  <span>已收藏</span>
-                </div>
-                <div v-show="!item.collect" @click="toCollectQue(item)" style="display: flex;align-items: center;">
-                  <img src="@/assets/images/icon_shoucang_n.png" alt=""/>
-                  <span>收藏</span>
-                </div>
-              </div>
-              <div class="jiucuo mr20" @click="$refs.correct.open(item.id)">
-                <img src="@/assets/images/icon_jiucuo.png" alt=""/>
-                <span>纠错</span>
-              </div>
-              <div class="detail" @click="handleParseVisible(item)">
-                <img src="@/assets/images/icon_chakan.png" alt=""/>
-                <span>查看详情>></span>
-              </div>
-            </div>
-          </div>
-          <!-- NOTE: 改v-if否则全部公式渲染太费时间 -->
-          <div :id="`question_parse_${item.id}`" v-if="item.updateTime" class="info">
-            <div v-html="'【解答】'+item.answer2" class="mb20"></div>
-            <div v-html="'【解析】'+item.parse"></div>
-          </div>
-        </div>
+      <div class="fx-column gap10" id="question_list">
+        <mx-question-readonly v-for="(q,i) in opticList" :key="i" :seq="i+1" :question="q"
+                              @correct="$refs.correct.open(q.id)"/>
       </div>
     </el-card>
     <correct-question ref="correct"></correct-question>
   </div>
 </template>
 <script>
-import {
-  downloadRealPaper,
-  isCollected,
-  papersCancelCollect,
-  papersCollect,
-  preview,
-  queCancelCollect,
-  queCollect
-} from '@/api/webApi/webQue.js'
-import { mapGetters } from 'vuex'
+import {downloadRealPaper, isCollected, papersCancelCollect, papersCollect, preview} from '@/api/webApi/webQue.js'
+import {mapGetters} from 'vuex'
 import correctQuestion from '../../components/MxPaper/plus/correct-question-dialog.vue'
+import MxCollectButton from "@/components/MxCollectButton/MxCollectButton.vue";
+import MxQuestionReadonly from "@/components/MxQuestionReadonly/MxQuestionReadonly.vue";
 
 export default {
-  components: { correctQuestion },
+  components: {MxQuestionReadonly, MxCollectButton, correctQuestion},
   data() {
     return {
       collectFlag: false,
@@ -99,49 +38,35 @@ export default {
   computed: {
     ...mapGetters(['period'])
   },
+  provide() {
+    return {
+      collectFn: this.paperCollect,
+      collectCancelFn: this.paperCollectCancel
+    }
+  },
   created() {
     this.paperId = this.$route.query.paperId
     this.paperName = this.$route.query.paperName
-    isCollected({ paperId: this.paperId }).then((res) => {
-      console.log(res)
+    isCollected({paperId: this.paperId}).then((res) => {
       this.collectFlag = res.data
     })
     this.getOptics()
   },
   methods: {
     getOptics() {
-      preview({ paperId: this.paperId }).then((res) => {
+      preview({paperId: this.paperId}).then((res) => {
         this.opticList = res.data
         setTimeout(_ => this.mxGlobal.MathQueue('question_list'))
       })
     },
-    async handleParseVisible(item) {
-      item.updateTime = !item.updateTime
-      const parseEl = `question_parse_${item.id}`
-      this.$nextTick(_ => this.mxGlobal.MathQueue(parseEl))
-    },
-    toCollectQue(item) {
-      queCollect({ questionId: item.id }).then((res) => {
-        item.collect = !item.collect
-        this.msgSuccess('收藏成功')
-        console.log(res)
-      })
-    },
-    toCancelCollectQue(item) {
-      queCancelCollect({ questionId: item.id }).then((res) => {
-        item.collect = !item.collect
-        this.msgSuccess('取消收藏成功')
-        console.log(res)
-      })
-    },
-    cancelCollect() {
-      papersCancelCollect({ paperId: this.paperId }).then((res) => {
+    paperCollectCancel() {
+      papersCancelCollect({paperId: this.paperId}).then((res) => {
         this.collectFlag = false
         this.msgSuccess('取消收藏成功')
       })
     },
-    Collect() {
-      papersCollect({ paperId: this.paperId }).then((res) => {
+    paperCollect() {
+      papersCollect({paperId: this.paperId}).then((res) => {
         this.collectFlag = true
         this.msgSuccess('收藏成功')
       })
@@ -153,171 +78,4 @@ export default {
 }
 </script>
 <style scoped>
-.preview_container {
-  padding: 20px;
-}
-
-.paper_header {
-  overflow: hidden;
-  margin-bottom: 33px;
-}
-
-.paper_title {
-  height: 25px;
-  font-size: 18px;
-  font-family: PingFangSC-Medium, PingFang SC;
-  font-weight: 500;
-  color: #292929;
-  line-height: 25px;
-  float: left;
-}
-
-.operation {
-  float: right;
-}
-
-.shoucan {
-  display: flex;
-  align-items: center;
-  margin-right: 53px;
-  font-size: 14px;
-  font-family: PingFangSC-Regular, PingFang SC;
-  font-weight: 400;
-}
-
-.shoucan img {
-  margin-right: 6px;
-  cursor: pointer;
-}
-
-.shoucan .sc_text {
-  color: #9f9f9f;
-  line-height: 20px;
-  cursor: pointer;
-  margin-right: 28px;
-}
-
-.shoucan .btn {
-  padding: 6px 20px;
-  cursor: pointer;
-  background: #47c6a2;
-  color: white;
-  border-radius: 4px;
-}
-
-.que_item {
-  border-radius: 1px;
-  border: 1px solid #dedede;
-  margin-bottom: 8px;
-}
-
-.que_content {
-  padding: 12px 24px 0 33px;
-  font-size: 14px;
-  font-family: PingFangSC-Medium, PingFang SC;
-  font-weight: 500;
-  color: #4c4c4c;
-  line-height: 27px;
-  margin-bottom: 10px;
-}
-
-.options {
-  padding-left: 36px;
-  font-size: 14px;
-  font-family: PingFangSC-Regular, PingFang SC;
-  font-weight: 400;
-  color: #4c4c4c;
-  line-height: 27px;
-  border-bottom: 1px solid #dedede;
-}
-
-.options .option {
-  margin-bottom: 10px;
-}
-
-.que_footer {
-  border-top: 1px solid #dedede;
-  padding-left: 33px;
-  overflow: hidden;
-  padding-bottom: 23px;
-  padding-top: 21px;
-}
-
-.que_footer .spans {
-  float: left;
-  font-size: 12px;
-  font-family: PingFangSC-Regular, PingFang SC;
-  font-weight: 400;
-  color: #979797;
-  line-height: 20px;
-}
-
-.que_footer .spans > span {
-  margin-right: 20px;
-}
-
-.operation {
-  display: flex;
-  align-items: center;
-  font-size: 14px;
-  font-family: PingFangSC-Regular, PingFang SC;
-  font-weight: 400;
-  color: #47c6a2;
-  line-height: 20px;
-}
-
-.operation > div {
-  display: flex;
-  align-items: center;
-  cursor: pointer;
-}
-
-.operation .shoucan {
-  margin-right: 46px;
-}
-
-.operation .detail span {
-  border-radius: 1px;
-  border-bottom: 1px solid #47c6a2;
-}
-
-.operation .detail {
-  margin-right: 32px;
-}
-
-.operation > div > img {
-  margin-right: 10px;
-}
-
-.operation .addQue {
-  padding: 7px;
-  border-radius: 4px;
-  border: 1px solid #979797;
-  margin-right: 24px;
-}
-
-.info {
-  padding: 12px 40px;
-}
-
-.option-list {
-  display: flex;
-  flex-direction: column;
-  margin-bottom: 40px;
-  font-size: 14px;
-}
-
-.option-list span {
-  padding: 5px 40px;
-  clear: both;
-}
-
-.subQueBox {
-  padding: 5px 40px;
-}
-
-.subQueBox .subQueItem {
-  margin-bottom: 10px;
-  font-size: 14px;
-}
 </style>

+ 39 - 112
src/views/questioncenter/components/collect.vue

@@ -1,78 +1,15 @@
 <template>
   <div>
-    <mx-condition ref="condition" :query-params="queryParams" :require-fields="requireFields" @query="handleQuery"
-                  @invalid="handleInvalidQuery"
-    ></mx-condition>
+    <mx-condition ref="condition" :query-params="queryParams" :require-fields="requireFields" @query="handleQuery"/>
     <!-- 试题收藏 -->
     <div class="mt20">
       <div class="topic" v-show="queryParams.favCollectType == 'question'">
         <!-- 题目 -->
-        <div class="paper_questions" id="collect-question">
-          <div
-            class="que_item"
-            v-for="(item, index) in collectQue"
-            :key="item.id"
-          >
-            <div class="que_content" style="display: flex">
-              <div>{{ index + 1 }}.</div>
-              <div v-html="item.title"></div>
-            </div>
-            <div class="option" v-if="item.optionA">
-              <div style="margin-right: 5px">A:</div>
-              <div v-html="item.optionA"></div>
-            </div>
-            <div class="option" v-if="item.optionB">
-              <div style="margin-right: 5px">B:</div>
-              <div v-html="item.optionB"></div>
-            </div>
-            <div class="option" v-if="item.optionC">
-              C:
-              <div v-html="item.optionC"></div>
-            </div>
-            <div class="option" v-if="item.optionD">
-              <div style="margin-right: 5px">D:</div>
-              <div v-html="item.optionD"></div>
-            </div>
-            <div class="que_footer">
-              <div class="spans">
-                <span class="id">ID: {{ item.id }}</span>
-                <span>题型: {{ item.qtpye }}</span>
-                <span>难度: 一般</span>
-              </div>
-              <div class="operation">
-                <div class="shoucan">
-                  <div
-                    v-show="item.collect"
-                    @click="toCancelCollectQue(item)"
-                    style="display: flex; align-items: center"
-                  >
-                    <img
-                      src="@/assets/images/icon_shoucang_s.png"
-                      style="margin-right: 8px"
-                    />
-                    <span>已收藏</span>
-                  </div>
-                  <div
-                    v-show="!item.collect"
-                    @click="toCollectQue(item)"
-                    style="display: flex; align-items: center"
-                  >
-                    <img
-                      src="@/assets/images/icon_shoucang_n.png"
-                      style="margin-right: 8px"
-                    />
-                    <span>收藏</span>
-                  </div>
-                </div>
-                <div class="detail" @click="viewDetail(item)">
-                  <img src="@/assets/images/icon_chakan.png" alt=""/>
-                  <span>查看解析>></span>
-                </div>
-              </div>
-            </div>
-            <div class="pd20" v-show="item.expand" v-html="'【解答】'+item.answer2"></div>
-            <div class="pd20" v-show="item.expand" v-html="'【解析】'+item.parse"></div>
-          </div>
+        <div class="fx-column gap10" id="collect-question">
+          <mx-question-readonly v-for="(q, i) in collectQue" :key="i" :question="q"
+                                :seq="(pageForm.pageNum-1)*pageForm.pageSize+i+1"
+                                @correct="$refs.correct.open(q.id)"/>
+          <el-empty v-if="!loading && !collectQue.length" />
         </div>
       </div>
       <!-- 试卷收藏 -->
@@ -119,16 +56,21 @@
       @pagination="onChangePage"
     />
 
+    <correct-question-dialog ref="correct"/>
   </div>
 </template>
 <script>
 import MxCondition from '@/components/MxCondition/mx-condition'
-import { favPapers, favQuestions, favQueTypes, favSubjects } from '@/api/webApi/webQue.js'
+import {favPapers, favQuestions, favSubjects} from '@/api/webApi/webQue.js'
 import PaperActionsMixin from "@/views/questioncenter/components/paper-actions-mixin";
+import MxQuestionReadonly from "@/components/MxQuestionReadonly/MxQuestionReadonly.vue";
+import CorrectQuestionDialog from "@/components/MxPaper/plus/correct-question-dialog.vue";
 
 export default {
   mixins: [PaperActionsMixin],
   components: {
+    CorrectQuestionDialog,
+    MxQuestionReadonly,
     MxCondition,
   },
   created() {
@@ -136,25 +78,26 @@ export default {
   },
   data() {
     return {
+      loading: false,
       form: {
         type: 'question',
         subjectName: '',
         wrongType: ''
       },
-      queryParams:{
-        favCollectType:'',
-        favSubject:'',
-        favQueType:''
+      queryParams: {
+        favCollectType: '',
+        favSubject: '',
+        favQueType: ''
       },
-      requireFields:['favCollectType','favSubject','favQueType'],
+      requireFields: ['favCollectType', 'favSubject', 'favQueType'],
       pageForm: {
         total: 0,
         pageSize: 10,
         pageNum: 1
       },
       types: [
-        { type: 'question', name: '试题收藏' },
-        { type: 'paper', name: '试卷收藏' }
+        {type: 'question', name: '试题收藏'},
+        {type: 'paper', name: '试卷收藏'}
       ],
       subjects: [],
       queTypes: [],
@@ -162,17 +105,16 @@ export default {
       collectPaper: []
     }
   },
-  watch:{
-    'queryParams.favCollectType':{
-      immediate:false,
-      handler(data){
-        console.log(data)
-        if(data == 'question') {
+  watch: {
+    'queryParams.favCollectType': {
+      immediate: false,
+      handler(data) {
+        if (data == 'question') {
           this.queryParams['favQueType'] = ''
-          if(!this.requireFields.find(item => item == 'favQueType')){
+          if (!this.requireFields.find(item => item == 'favQueType')) {
             this.requireFields.push('favQueType')
           }
-        }else {
+        } else {
           delete this.queryParams['favQueType']
           this.requireFields.remove('favQueType')
         }
@@ -180,22 +122,20 @@ export default {
     }
   },
   methods: {
-    handleQuery(){
-      if(this.queryParams.favCollectType == 'question') {
+    handleQuery() {
+      if (this.queryParams.favCollectType == 'question') {
         this.getFavQuestions()
-      }else {
+      } else {
         this.getFavPapers()
       }
 
-    },
-    handleInvalidQuery(){
-
     },
     onChangePage() {
       this.getFavQuestions()
     },
     // 收藏的问题列表
     getFavQuestions() {
+      this.loading = true
       favQuestions({
         subjectName: this.queryParams.favSubject,
         qtype: this.queryParams.favQueType,
@@ -203,34 +143,16 @@ export default {
         pageSize: this.pageForm.pageSize
       }).then((res) => {
         this.pageForm.total = res.total
-        this.collectQue = res.rows.map(item => {
-          item.expand = false
-          return item
-        })
+        this.collectQue = res.rows
         this.$nextTick(_ => this.mxGlobal.MathQueue('collect-question'))
-        console.log(res)
-      })
-    },
-    toCollectQue(item) {
-      queCollect({ questionId: item.id }).then((res) => {
-        item.collect = !item.collect
-        this.msgSuccess('收藏成功')
-        console.log(res)
-      })
-    },
-    toCancelCollectQue(item) {
-      queCancelCollect({ questionId: item.id }).then((res) => {
-        item.collect = !item.collect
-        this.msgSuccess('取消收藏成功')
-        console.log(res)
-      })
+      }).finally(() => this.loading = false)
     },
     viewDetail(item) {
       item.expand = !item.expand
     },
     // 收藏涉及的学科
     getSubjects() {
-      favSubjects({ type: this.form.type }).then((res) => {
+      favSubjects({type: this.form.type}).then((res) => {
         console.log(res)
         this.form.subjectName = res.data[0]
         this.subjects = res.data
@@ -261,20 +183,25 @@ export default {
   .el-dialog__header .el-dialog__title {
     color: #47c6a2;
   }
+
   .radio_contianer .el-radio-button__inner {
     border-left: 1px solid #dcdfe6;
   }
+
   .radio_contianer .el-radio-button .el-radio-button__inner {
     border-radius: 16px;
     margin-bottom: 5px;
   }
+
   .radio_contianer .el-radio-button:first-child:last-child .el-radio-button__inner {
     border-radius: 16px;
   }
+
   .radio_contianer .el-radio-button {
     margin-right: 8px;
   }
 }
+
 .radio_contianer > div {
   margin-bottom: 16px;
   display: flex;

+ 9 - 63
src/views/questioncenter/components/generate-tabs/paper-by-hand.vue

@@ -29,68 +29,13 @@
         <!-- 主题内容 -->
         <div class="main_con">
           <!-- 题目 -->
-          <div class="paper_questions" :id="mathId">
-            <div class="que_item" v-for="(item, index) in queList" :key="item.id">
-              <div class="que_content">
-                <div class="que-content-title">
-                  <div class="index">{{ (pageSize * (pageNum - 1) + index + 1) }}.</div>
-                  <div v-html="item.title"></div>
-                </div>
-                <div class="que-option">
-                  <div v-if="item.optionA">
-                    <span>A</span>
-                    <span v-html="item.optionA"></span>
-                  </div>
-                  <div v-if="item.optionB">
-                    <span>B</span>
-                    <span v-html="item.optionB"></span>
-                  </div>
-                  <div v-if="item.optionC">
-                    <span>C</span>
-                    <span v-html="item.optionC"></span>
-                  </div>
-                  <div v-if="item.optionD">
-                    <span>D</span>
-                    <span v-html="item.optionD"></span>
-                  </div>
-                </div>
-              </div>
-              <div class="que_footer pd20 fx-row ai-center jc-between">
-                <div class="spans">
-                  <span class="id">ID: {{ item.id }}</span>
-                  <span>题型: {{ item.qtpye }}</span>
-                  <span>难度: 一般</span>
-                </div>
-                <div class="operation">
-                  <div class="shoucan">
-                    <div v-show="item.collect" @click="toCancelCollectQue(item)"
-                         style="display: flex; align-items: center">
-                      <img src="@/assets/images/icon_shoucang_s.png" alt="" style="margin-right: 8px"/>
-                      <span>已收藏</span>
-                    </div>
-                    <div v-show="!item.collect" @click="toCollectQue(item)" style="display: flex; align-items: center">
-                      <img src="@/assets/images/icon_shoucang_n.png" style="margin-right: 8px" alt=""/>
-                      <span>收藏</span>
-                    </div>
-                  </div>
-                  <div class="jiucuo" @click="$refs.correct.open(item.id)">
-                    <img src="@/assets/images/icon_jiucuo.png" alt=""/>
-                    <span>纠错</span>
-                  </div>
-                  <div class="detail" @click="viewDetail(item)">
-                    <img src="@/assets/images/icon_chakan.png" alt=""/>
-                    <span>查看详情>></span>
-                  </div>
-                  <div class="addQue">
-                    <el-button @click="addQueCard(item)" icon="el-icon-shopping-cart-2" type="success" plain
-                               :disabled="queCardForm.queList.some((q) => q.id == item.id)">加入选题
-                    </el-button>
-                  </div>
-                </div>
-              </div>
-              <div class="pd20" v-show="item.expand" v-html="'【解答】'+item.answer2"></div>
-              <div class="pd20" v-show="item.expand" v-html="'【解析】'+item.parse"></div>
-            </div>
+          <div class="fx-column gap10" :id="mathId">
+            <mx-question-readonly v-for="(q, i) in queList" :key="i" :question="q" :seq="pageSize*(pageNum-1)+i+1"
+                                  @correct="$refs.correct.open(q.id)">
+              <el-button slot="suffix" @click="addQueCard(q)" icon="el-icon-shopping-cart-2" type="success" plain
+                         :disabled="queCardForm.queList.some((item) => item.id == q.id)">加入选题
+              </el-button>
+            </mx-question-readonly>
             <div v-if="queList.length == 0" class="empty-text">
               暂时没有内容
             </div>
@@ -161,11 +106,12 @@ import CorrectQuestionDialog from '@/components/MxPaper/plus/correct-question-di
 import LeftTreeSide from '@/views/questioncenter/components/generate-tabs/plugins/left-tree-side'
 import PaperWorkIdentifierMixin from './paper-work-identifier-mixin'
 import EventBus from '@/components/EventBus'
+import MxQuestionReadonly from "@/components/MxQuestionReadonly/MxQuestionReadonly.vue";
 
 export default {
   mixins: [PaperWorkIdentifierMixin],
   name: 'paper-by-hand',
-  components: { LeftTreeSide, CorrectQuestionDialog, MxCondition },
+  components: {MxQuestionReadonly, LeftTreeSide, CorrectQuestionDialog, MxCondition },
   data() {
     return {
       queryParams: null,

+ 1 - 1
src/views/questioncenter/components/learn-record.vue

@@ -119,7 +119,7 @@
           </p>
         </el-col>
       </el-row>
-      <evaluation-empty v-else shadow title="暂无数据"></evaluation-empty>
+      <el-empty v-else />
     </div>
     <div class="record_contian">
       <div class="tit">知识点诊断记录</div>

+ 21 - 66
src/views/questioncenter/components/mistake.vue

@@ -1,62 +1,18 @@
 <template>
   <div class="mistake">
-    <mx-condition ref="condition" :query-params="queryParams" :requireFields="requireFields"  @query="handleQuery"
-                  @invalid="handleInvalidQuery"></mx-condition>
+    <mx-condition ref="condition" :query-params="queryParams" :requireFields="requireFields"  @query="handleQuery" />
     <div class="topic">
       <!-- 题目 -->
-      <div class="paper_questions" id="wrong-question">
-        <div
-          class="que_item"
-          v-for="(item, index) in wrongList"
-          :key="item.id"
-        >
-          <div class="que_content" style="display: flex">
-            <div>{{ index + 1 }}.</div>
-            <div v-html="item.title"></div>
-          </div>
-          <div class="option" v-if="item.optionA">
-            <div style="margin-right: 5px">A:</div>
-            <div v-html="item.optionA"></div>
-          </div>
-          <div class="option" v-if="item.optionB">
-            <div style="margin-right: 5px">B:</div>
-            <div v-html="item.optionB"></div>
-          </div>
-          <div class="option" v-if="item.optionC">
-            C:
-            <div v-html="item.optionC"></div>
-          </div>
-          <div class="option" v-if="item.optionD">
-            <div style="margin-right: 5px">D:</div>
-            <div v-html="item.optionD"></div>
-          </div>
-          <div class="que_footer">
-            <div class="spans">
-              <span>题型: {{ item.qtpye }}</span>
-              <span>难度: 一般</span>
-            </div>
-            <div class="operation">
-              <div class="delete" style="display: flex; align-items: center">
-                <div
-                  style="margin-right: 24px; cursor: pointer; display: flex;align-items: center;"
-                  @click="toDeleteWrongQue(item.id, index)"
-                >
-                  <img
-                    src="@/assets/images/icon_wrong.png"
-                    style="margin-right: 8px"
-                  />
-                  <span>删除错题</span>
-                </div>
-              </div>
-              <div class="detail" @click="viewWrongDetail(item)">
-                <img src="@/assets/images/icon_chakan.png" alt="" />
-                <span>查看解析>></span>
-              </div>
-            </div>
-          </div>
-          <div class="pd20" v-show="item.expand" v-html="'【解答】'+item.answer2"></div>
-          <div class="pd20" v-show="item.expand" v-html="'【解析】'+item.parse"></div>
-        </div>
+      <div class="fx-column gap10" id="wrong-question">
+        <mx-question-readonly v-for="(q,i) in wrongList" :key="i" :question="q"
+                              :seq="(pageForm.pageNum-1)*pageForm.pageSize+i+1"
+                              @correct="$refs.correct.open(q.id)">
+          <el-button slot="prefix" type="text" @click="toDeleteWrongQue(q.id, i)">
+            <i class="el-icon-delete f-danger"></i>
+            <span class="f-666">删除错题</span>
+          </el-button>
+        </mx-question-readonly>
+        <el-empty v-if="!loading && !wrongList.length" />
       </div>
     </div>
     <!-- 错题分页 -->
@@ -68,18 +24,25 @@
       :page-size="10"
       @pagination="onChangePage"
     />
+
+    <correct-question-dialog ref="correct" />
   </div>
 </template>
 <script>
 import { deleteWrongQuestion, wrongQuestions } from '@/api/webApi/webQue'
 import MxCondition from '@/components/MxCondition/mx-condition'
+import CorrectQuestionDialog from "@/components/MxPaper/plus/correct-question-dialog.vue";
+import MxQuestionReadonly from "@/components/MxQuestionReadonly/MxQuestionReadonly.vue";
 
 export  default {
   components:{
+    MxQuestionReadonly,
+    CorrectQuestionDialog,
     MxCondition
   },
   data() {
     return {
+      loading: false,
       pageForm:{
         pageSize:10,
         pageNum:1
@@ -94,9 +57,6 @@ export  default {
     }
   },
   methods:{
-    viewWrongDetail(item) {
-      item.expand = !item.expand
-    },
     onChangePage(page) {
       this.pageForm.pageSize = page.limit
       this.pageForm.pageNum = page.page
@@ -113,22 +73,17 @@ export  default {
       });
     },
     getWrongQuestions() {
+      this.loading = true
       wrongQuestions({
         subjectName: this.queryParams.wrongSubject,
         qtype: this.queryParams.wrongType,
         pageSize: this.pageForm.pageSize,
         pageNum: this.pageForm.pageNum,
       }).then((res) => {
-        this.wrongList = res.rows.map(item => {
-          item.expand = false
-          return item
-        });
+        this.wrongList = res.rows
         this.total = res.total;
         this.$nextTick(_=>this.mxGlobal.MathQueue('wrong-question'))
-      });
-    },
-    handleInvalidQuery() {
-
+      }).finally(() => this.loading = false);
     }
   }
 }

+ 1 - 1
src/views/questioncenter/paper.vue

@@ -31,7 +31,7 @@
               {{ index2 + 1 }}.
               <span style="color: #1890ff">题号:{{ questionInfo.id }}({{ questionInfo.score }}分)</span><span v-html="questionInfo.title"></span>
             </div>
-            <!--<div v-for="child in questionInfo.subquestions" v-html="child.title"></div>-->
+            <div v-for="child in questionInfo.subquestions" v-html="child.title"></div>
           </div>
         </div>
       </el-card>