Procházet zdrojové kódy

试题评阅和参加考试新增页码分页,调整渲染逻辑

luoaoxuan před 1 rokem
rodič
revize
ed9bd45514

+ 124 - 79
src/views/platform/examination/question/judge.vue

@@ -15,89 +15,103 @@
     >
         <div class="container">
             <div class="question">
-                <div
-                    v-for="(item, index) in questionList"
-                    v-show="showIndex === index + 1"
-                    :key="item.dataId"
-                    class="question-item"
-                >
-                    <div class="type">{{ item.questionType }}</div>
-                    <div class="stem">
-                        <span>{{ `【${index + 1}】${item.stem}` }}</span>
-                        <el-tag type="info" size="small">{{ `${item.score}分` }}</el-tag>
-                    </div>
-                    <div v-if="item.img && item.img.length" class="img">
-                        <ibps-image
-                            :value="item.img"
-                            height="100"
-                            width="100"
-                            accept=".jpg,.jpeg,.png,.gif,.bmp,.webp"
-                            download
-                            disabled
-                        />
-                    </div>
-                    <div class="answer">
-                        <div class="mine">
-                            <div class="title">考生答案:</div>
-                            <div class="content">
-                                <el-input
-                                    v-for="(o, i) in item.answer"
-                                    :key="`${index}${i}`"
-                                    :value="o"
-                                    :type="item.questionType === '简答题' ? 'textarea' : 'text'"
-                                    :rows="item.questionType === '简答题' ? 12 : 1"
-                                    readonly
-                                />
-                            </div>
+                <template v-for="(item, index) in questionList">
+                    <div
+                        v-if="showIndex === index + 1"
+                        :key="item.dataId"
+                        class="question-item"
+                    >
+                        <div class="type">{{ item.questionType }}</div>
+                        <div class="stem">
+                            <span>{{ `【${index + 1}】${item.stem}` }}</span>
+                            <el-tag type="info" size="small">{{ `${item.score}分` }}</el-tag>
+                        </div>
+                        <div v-if="item.img && item.img.length" class="img">
+                            <ibps-image
+                                :value="item.img"
+                                height="100"
+                                width="100"
+                                accept=".jpg,.jpeg,.png,.gif,.bmp,.webp"
+                                download
+                                disabled
+                            />
                         </div>
-                        <div class="right">
-                            <div class="title">参考答案:</div>
-                            <div class="content">
-                                <el-input
-                                    v-for="(o, i) in item.rightKey"
-                                    :key="`${index}${i}`"
-                                    :value="o"
-                                    :type="item.questionType === '简答题' ? 'textarea' : 'text'"
-                                    :rows="item.questionType === '简答题' ? 12 : 1"
-                                    readonly
-                                />
+                        <div class="answer">
+                            <div class="mine">
+                                <div class="title">考生答案:</div>
+                                <div class="content">
+                                    <el-input
+                                        v-for="(o, i) in item.answer"
+                                        :key="`${index}${i}`"
+                                        :value="o"
+                                        :type="item.questionType === '简答题' ? 'textarea' : 'text'"
+                                        :rows="item.questionType === '简答题' ? 12 : 1"
+                                        readonly
+                                    />
+                                </div>
+                            </div>
+                            <div class="right">
+                                <div class="title">参考答案:</div>
+                                <div class="content">
+                                    <el-input
+                                        v-for="(o, i) in item.rightKey"
+                                        :key="`${index}${i}`"
+                                        :value="o"
+                                        :type="item.questionType === '简答题' ? 'textarea' : 'text'"
+                                        :rows="item.questionType === '简答题' ? 12 : 1"
+                                        readonly
+                                    />
+                                </div>
                             </div>
                         </div>
-                    </div>
-                    <div class="result">
-                        <div class="title">试题得分
-                            <el-tooltip effect="dark" content="请输入根据考生答案与参考答案给出题目得分" placement="top">
-                                <i class="el-icon-question" />
+                        <div class="result">
+                            <div class="title">试题得分
+                                <el-tooltip effect="dark" content="请输入根据考生答案与参考答案给出题目得分" placement="top">
+                                    <i class="el-icon-question" />
+                                </el-tooltip>
+                            </div>
+                            <el-tooltip effect="dark" content="错误,该题计0分" placement="top">
+                                <el-button type="danger" icon="el-icon-close" circle @click="changeScore(index, 0)" />
+                            </el-tooltip>
+                            <el-input-number
+                                v-model="item.resultScore"
+                                :min="0"
+                                :max="item.score"
+                                :precision="1"
+                                class="score-input"
+                                placeholder=""
+                            />
+                            <el-tooltip effect="dark" content="正确,该题计满分" placement="top">
+                                <el-button type="success" icon="el-icon-check" circle @click="changeScore(index, item.score)" />
+                            </el-tooltip>
+                            <el-tooltip effect="dark" content="取消已有评分,未评分的题目不会被提交" placement="top">
+                                <el-button type="warning" icon="el-icon-delete" @click="changeScore(index, undefined)">取消评分</el-button>
                             </el-tooltip>
                         </div>
-                        <el-tooltip effect="dark" content="错误,该题计0分" placement="top">
-                            <el-button type="danger" icon="el-icon-close" circle @click="changeScore(index, 0)" />
-                        </el-tooltip>
-                        <el-input-number
-                            v-model="item.resultScore"
-                            :min="0"
-                            :max="item.score"
-                            :precision="1"
-                            class="score-input"
-                            placeholder=""
-                        />
-                        <el-tooltip effect="dark" content="正确,该题计满分" placement="top">
-                            <el-button type="success" icon="el-icon-check" circle @click="changeScore(index, item.score)" />
-                        </el-tooltip>
-                        <el-tooltip effect="dark" content="取消已有评分,未评分的题目不会被提交" placement="top">
-                            <el-button type="warning" icon="el-icon-delete" @click="changeScore(index, undefined)">取消评分</el-button>
-                        </el-tooltip>
                     </div>
-                </div>
+                </template>
+
             </div>
+
             <div class="question-link">
-                <div
-                    v-for="(item, index) in questionList"
-                    :key="item.dataId"
-                    class="link-item"
-                    :class="setClassName(item, index)"
-                    @click="showIndex = index + 1"
-                >{{ index + 1 }}</div>
+                <div class="tabs">
+                    <el-tabs v-model="activeName">
+                        <el-tab-pane v-for="(item) in pageTotal" :key="item" :label="pageLabel(item)" :name="item+''" />
+                    </el-tabs>
+                </div>
+                <div class="question">
+                    <template v-for="(item, index) in questionList">
+                        <div
+                            v-if="index+1>=pageRange(pagination.currentPage).start &&index+1<=pageRange(pagination.currentPage).end"
+                            :key="item.dataId"
+                            class="link-item"
+                            :class="setClassName(item, index)"
+                            @click="showIndex = index + 1"
+                        >{{ index + 1 }}</div>
+                    </template>
+
+                </div>
+
             </div>
         </div>
         <div slot="footer" class="el-dialog--center">
@@ -127,6 +141,11 @@ export default {
     data () {
         const { userId } = this.$store.getters || {}
         return {
+            pagination: {
+                currentPage: 1,
+                pageSize: 100
+            },
+            activeName: '1',
             title: '试题评阅',
             dialogVisible: this.visible,
             loading: false,
@@ -165,9 +184,17 @@ export default {
     computed: {
         formData () {
             return this.data
+        },
+        pageTotal () {
+            return Math.ceil(this.questionList.length / this.pagination.pageSize)
         }
     },
     watch: {
+        activeName: {
+            handler (val) {
+                this.pagination.currentPage = +val
+            }
+        },
         visible: {
             handler (val, oldVal) {
                 this.dialogVisible = this.visible
@@ -176,6 +203,8 @@ export default {
         },
         showIndex: {
             handler (val, oldVal) {
+                this.pagination.currentPage = Math.ceil(val / this.pagination.pageSize)
+                this.activeName = this.pagination.currentPage + ''
                 const temp = this.questionList[oldVal - 1]
             }
         }
@@ -189,6 +218,16 @@ export default {
         window.removeEventListener('keyup', this.handleKeyPress)
     },
     methods: {
+        pageRange (pageNo) {
+            return {
+                start: (pageNo - 1) * this.pagination.pageSize + 1,
+                end: pageNo * this.pagination.pageSize > this.questionList.length ? this.questionList.length : pageNo * this.pagination.pageSize
+            }
+        },
+        pageLabel (pageNo) {
+            const { start, end } = this.pageRange(pageNo)
+            return `${start}-${end}`
+        },
         // 获取题库数据
         async loadData () {
             this.questionList = await this.getQuestionData()
@@ -475,13 +514,19 @@ export default {
             }
             .question-link {
                 display: flex;
-                flex-wrap: wrap;
-                justify-content: flex-start;
+                flex-direction: column;
                 position: absolute;
                 width: calc(100% - 40px);
                 bottom: 20px;
-                height: 80px;
-                overflow-y: auto;
+
+                .question{
+                    display: flex;
+                    flex-wrap: wrap;
+                    align-content: flex-start;
+                    height: 80px;
+                    overflow-y: auto;
+                }
+
                 .el-progress {
                     width: 100%;
                     margin-bottom: 10px;

+ 106 - 66
src/views/platform/examination/questionBank/test.vue

@@ -15,66 +15,72 @@
     >
         <div class="container">
             <div class="question">
-                <div
-                    v-for="(item, index) in questionList"
-                    v-show="showIndex === index + 1"
-                    :key="index"
-                    class="question-item"
-                >
-                    <div class="type">{{ item.questionType }}</div>
-                    <div class="stem">
-                        <span>{{ `【${index + 1}】${item.stem}` }}</span>
-                        <el-tag type="info" size="small">{{ `${item.score}分` }}</el-tag>
-                    </div>
-                    <div v-if="item.img && item.img.length" class="img">
-                        <ibps-image
-                            v-model="item.img"
-                            height="100"
-                            width="100"
-                            accept=".jpg,.jpeg,.png,.gif,.bmp,.webp"
-                            download
-                            disabled
-                        />
-                    </div>
-                    <div class="answer">
-                        <el-radio-group v-if="item.questionType === '单选题'" v-model="item.answer" @change="goNext">
-                            <el-radio
-                                v-for="(o, i) in item.options"
-                                :key="`${index}${i}`"
-                                :label="o.label"
-                            >{{ `${o.label}.${o.value}` }}</el-radio>
-                        </el-radio-group>
-                        <el-checkbox-group v-else-if="item.questionType === '多选题'" v-model="item.answer" @change="changeOptions">
-                            <el-checkbox
-                                v-for="(o, i) in item.options"
-                                :key="`${index}${i}`"
-                                :label="o.label"
-                            >{{ `${o.label}.${o.value}` }}</el-checkbox>
-                        </el-checkbox-group>
-                        <el-radio-group v-else-if="item.questionType === '判断题'" v-model="item.answer" @change="goNext">
-                            <el-radio-button label="√">√</el-radio-button>
-                            <el-radio-button label="×">×</el-radio-button>
-                        </el-radio-group>
-                        <template v-else-if="item.questionType === '填空题'">
+                <template v-for="(item, index) in questionList">
+                    <div
+                        v-if="showIndex === index + 1"
+                        :key="index"
+                        class="question-item"
+                    >
+                        <div class="type">{{ item.questionType }}</div>
+                        <div class="stem">
+                            <span>{{ `【${index + 1}】${item.stem}` }}</span>
+                            <el-tag type="info" size="small">{{ `${item.score}分` }}</el-tag>
+                        </div>
+                        <div v-if="item.img && item.img.length" class="img">
+                            <ibps-image
+                                v-model="item.img"
+                                height="100"
+                                width="100"
+                                accept=".jpg,.jpeg,.png,.gif,.bmp,.webp"
+                                download
+                                disabled
+                            />
+                        </div>
+                        <div class="answer">
+                            <el-radio-group v-if="item.questionType === '单选题'" v-model="item.answer" @change="goNext">
+                                <el-radio
+                                    v-for="(o, i) in item.options"
+                                    :key="`${index}${i}`"
+                                    :label="o.label"
+                                >{{ `${o.label}.${o.value}` }}</el-radio>
+                            </el-radio-group>
+                            <el-checkbox-group v-else-if="item.questionType === '多选题'" v-model="item.answer" @change="changeOptions">
+                                <el-checkbox
+                                    v-for="(o, i) in item.options"
+                                    :key="`${index}${i}`"
+                                    :label="o.label"
+                                >{{ `${o.label}.${o.value}` }}</el-checkbox>
+                            </el-checkbox-group>
+                            <el-radio-group v-else-if="item.questionType === '判断题'" v-model="item.answer" @change="goNext">
+                                <el-radio-button label="√">√</el-radio-button>
+                                <el-radio-button label="×">×</el-radio-button>
+                            </el-radio-group>
+                            <template v-else-if="item.questionType === '填空题'">
+                                <el-input
+                                    v-for="(o, i) in item.options"
+                                    :key="`${index}${i}`"
+                                    v-model="o.answer"
+                                    type="text"
+                                    placeholder="请输入您的答案"
+                                />
+                            </template>
                             <el-input
-                                v-for="(o, i) in item.options"
-                                :key="`${index}${i}`"
-                                v-model="o.answer"
-                                type="text"
+                                v-else-if="item.questionType === '简答题'"
+                                v-model="item.answer"
+                                type="textarea"
+                                :autosize="{ minRows: 4, maxRows: 8}"
                                 placeholder="请输入您的答案"
                             />
-                        </template>
-                        <el-input
-                            v-else-if="item.questionType === '简答题'"
-                            v-model="item.answer"
-                            type="textarea"
-                            :autosize="{ minRows: 4, maxRows: 8}"
-                            placeholder="请输入您的答案"
-                        />
+                        </div>
                     </div>
-                </div>
+                </template>
             </div>
             <div class="question-link">
+                <div class="tabs">
+                    <el-tabs v-model="activeName">
+                        <el-tab-pane v-for="(item) in pageTotal" :key="item" :label="pageLabel(item)" :name="item+''" />
+                    </el-tabs>
+                </div>
                 <el-progress
                     type="line"
                     class="progress"
@@ -82,13 +88,19 @@
                     :stroke-width="20"
                     :percentage="getProgress()"
                 />
-                <div
-                    v-for="(item, index) in questionList"
-                    :key="index"
-                    class="link-item"
-                    :class="setClassName(item, index)"
-                    @click="showIndex = index + 1"
-                >{{ index + 1 }}</div>
+                <div class="question">
+                    <template v-for="(item, index) in questionList">
+                        <div
+                            v-if="index+1>=pageRange(pagination.currentPage).start &&index+1<=pageRange(pagination.currentPage).end"
+                            :key="index"
+                            class="link-item"
+                            :class="setClassName(item, index)"
+                            @click="showIndex = index + 1"
+                        >{{ index + 1 }}</div>
+                    </template>
+
+                </div>
+
             </div>
         </div>
         <div class="tips">
@@ -148,6 +160,11 @@ export default {
         const { duration } = this.examData || {}
         const countdown = duration === '不限' ? 0 : parseInt(duration / 1000)
         return {
+            pagination: {
+                currentPage: 1,
+                pageSize: 100
+            },
+            activeName: '1',
             countdown,
             title: this.examData.examName || '参加考试',
             dialogVisible: this.visible,
@@ -189,6 +206,9 @@ export default {
         formData () {
             return this.data
         },
+        pageTotal () {
+            return Math.ceil(this.questionList.length / this.pagination.pageSize)
+        },
         formattedCountdown () {
             const h = this.formatNum(parseInt(this.countdown / 60 / 60))
             const m = this.formatNum(parseInt(this.countdown / 60 % 60))
@@ -197,6 +217,11 @@ export default {
         }
     },
     watch: {
+        activeName: {
+            handler (val) {
+                this.pagination.currentPage = +val
+            }
+        },
         visible: {
             handler (val, oldVal) {
                 this.dialogVisible = this.visible
@@ -205,7 +230,8 @@ export default {
         },
         showIndex: {
             handler (val, oldVal) {
-                // console.log(val)
+                this.pagination.currentPage = Math.ceil(val / this.pagination.pageSize)
+                this.activeName = this.pagination.currentPage + ''
                 const temp = this.questionList[oldVal - 1]
                 if (['填空题'].includes(temp.questionType)) {
                     temp.answer = temp.options.map(item => item.answer)
@@ -228,6 +254,16 @@ export default {
         // Watermark.set('', '')
     },
     methods: {
+        pageRange (pageNo) {
+            return {
+                start: (pageNo - 1) * this.pagination.pageSize + 1,
+                end: pageNo * this.pagination.pageSize > this.questionList.length ? this.questionList.length : pageNo * this.pagination.pageSize
+            }
+        },
+        pageLabel (pageNo) {
+            const { start, end } = this.pageRange(pageNo)
+            return `${start}-${end}`
+        },
         // 获取题库数据
         async loadData () {
             if (!this.bankId) {
@@ -612,14 +648,18 @@ export default {
                 }
             }
             .question-link {
-                overflow: auto;
-                max-height: 150px;
                 display: flex;
-                flex-wrap: wrap;
-                justify-content: flex-start;
+                flex-direction: column;
                 position: absolute;
                 width: calc(100% - 40px);
                 bottom: 20px;
+                .question{
+                    display: flex;
+                    flex-wrap: wrap;
+                    align-content: flex-start;
+                    height: 120px;
+                    overflow-y: auto;
+                }
                 .progress {
                     width: 100%;
                     margin-bottom: 10px;