Procházet zdrojové kódy

新增考试页面及自动判分逻辑

cfort před 2 roky
rodič
revize
0910cbf243

+ 4 - 1
src/views/platform/examine/question/edit.vue

@@ -263,11 +263,13 @@ export default {
                 fu_tu_: '',
                 fu_tu_: '',
                 xuan_xiang_lei_xi: '文本',
                 xuan_xiang_lei_xi: '文本',
                 da_an_: '',
                 da_an_: '',
+                xuan_xiang_shu_: '',
                 zheng_que_da_an_: '',
                 zheng_que_da_an_: '',
                 ping_fen_fang_shi: rateType[defaultType] || '',
                 ping_fen_fang_shi: rateType[defaultType] || '',
                 ping_fen_ren_: userId,
                 ping_fen_ren_: userId,
                 fen_zhi_: '',
                 fen_zhi_: '',
-                bei_zhu_: ''
+                bei_zhu_: '',
+                zhuang_tai_: '启用'
             },
             },
             toolbars: [
             toolbars: [
                 {
                 {
@@ -450,6 +452,7 @@ export default {
                 case '填空题':
                 case '填空题':
                     this.form.xuan_xiang_lei_xi = ''
                     this.form.xuan_xiang_lei_xi = ''
                     this.form.da_an_ = ''
                     this.form.da_an_ = ''
+                    this.form.xuan_xiang_shu_ = a3.length
                     this.form.zheng_que_da_an_ = JSON.stringify(a3)
                     this.form.zheng_que_da_an_ = JSON.stringify(a3)
                     break
                     break
                 case '判断题':
                 case '判断题':

+ 111 - 33
src/views/platform/examine/questionBank/edit.vue

@@ -22,25 +22,6 @@
             <el-form-item label="题库名称:" prop="ti_ku_ming_cheng_">
             <el-form-item label="题库名称:" prop="ti_ku_ming_cheng_">
                 <el-input v-model="form.ti_ku_ming_cheng_" type="text" :maxlength="128" />
                 <el-input v-model="form.ti_ku_ming_cheng_" type="text" :maxlength="128" />
             </el-form-item>
             </el-form-item>
-            <el-form-item label="所属范围:" prop="suo_shu_fan_wei_">
-                <el-radio-group v-model="form.suo_shu_fan_wei_">
-                    <el-radio label="科级">科级</el-radio>
-                    <el-radio label="组级">组级</el-radio>
-                </el-radio-group>
-                <el-select
-                    v-if="form.suo_shu_fan_wei_ === '组级'"
-                    v-model="form.bian_zhi_bu_men_"
-                    width="100%"
-                    placeholder="请选择专业组"
-                >
-                    <el-option
-                        v-for="item in deptList"
-                        :key="item.positionId"
-                        :label="item.positionName"
-                        :value="item.positionId"
-                    />
-                </el-select>
-            </el-form-item>
             <el-form-item label="题库分类:" prop="ti_ku_fen_lei_">
             <el-form-item label="题库分类:" prop="ti_ku_fen_lei_">
                 <el-select
                 <el-select
                     v-model="form.ti_ku_fen_lei_"
                     v-model="form.ti_ku_fen_lei_"
@@ -63,19 +44,75 @@
                     <el-radio label="不可用">不可用</el-radio>
                     <el-radio label="不可用">不可用</el-radio>
                 </el-radio-group>
                 </el-radio-group>
             </el-form-item>
             </el-form-item>
-            <el-form-item label="限考次数:" prop="xian_kao_ci_shu_" :maxlength="16">
-                <el-radio-group v-model="form.isLimit" @change="changeLimit">
-                    <el-radio :label="0">不限</el-radio>
-                    <el-radio :label="1">限制</el-radio>
+            <el-form-item label="所属范围:" prop="suo_shu_fan_wei_" class="inline-item">
+                <el-radio-group v-model="form.suo_shu_fan_wei_">
+                    <el-radio label="科级">科级</el-radio>
+                    <el-radio label="组级">组级</el-radio>
+                </el-radio-group>
+                <el-select
+                    v-if="form.suo_shu_fan_wei_ === '组级'"
+                    v-model="form.bian_zhi_bu_men_"
+                    width="100%"
+                    placeholder="请选择专业组"
+                >
+                    <el-option
+                        v-for="item in deptList"
+                        :key="item.positionId"
+                        :label="item.positionName"
+                        :value="item.positionId"
+                    />
+                </el-select>
+            </el-form-item>
+            <el-form-item label="限考次数:" prop="isLimit" class="inline-item">
+                <el-radio-group v-model="form.isLimit">
+                    <el-radio label="0">不限</el-radio>
+                    <el-radio label="1">限制</el-radio>
+                </el-radio-group>
+                <div v-if="form.isLimit === '1'" class="time">
+                    <el-input-number
+                        v-model="form.xian_kao_ci_shu_"
+                        :min="1"
+                        :precision="0"
+                        placeholder="请输入单个用户最大限考次数"
+                    />
+                    <div class="unit">次</div>
+                </div>
+            </el-form-item>
+            <el-form-item label="考试时长:" prop="kao_shi_shi_chang" class="inline-item">
+                <el-radio-group v-model="form.limitTime">
+                    <el-radio label="0">不限</el-radio>
+                    <el-radio label="1">限制</el-radio>
                 </el-radio-group>
                 </el-radio-group>
+                <template v-if="form.limitTime === '1'">
+                    <div class="time">
+                        <el-input-number
+                            v-model="form.hours"
+                            :min="0"
+                            :max="72"
+                            :precision="0"
+                        />
+                        <div class="unit">小时</div>
+                    </div>
+                    <div class="time">
+                        <el-input-number
+                            v-model="form.minutes"
+                            :min="0"
+                            :max="59"
+                            :precision="0"
+                        />
+                        <div class="unit">分钟</div>
+                    </div>
+                </template>
+            </el-form-item>
+            <el-form-item label="达标分值占比:" prop="da_biao_zhan_bi_">
                 <el-input-number
                 <el-input-number
-                    v-if="form.isLimit"
-                    v-model="form.xian_kao_ci_shu_"
-                    :min="1"
+                    v-model="form.da_biao_zhan_bi_"
+                    :min="50"
+                    :max="100"
                     :precision="0"
                     :precision="0"
-                    type="number"
-                    placeholder="请输入单个用户最大限考次数"
+                    placeholder="请输入达标分值占比"
                 />
                 />
+                <div class="unit">%</div>
             </el-form-item>
             </el-form-item>
             <el-form-item label="默认评分人:" prop="ping_fen_ren_">
             <el-form-item label="默认评分人:" prop="ping_fen_ren_">
                 <!-- <el-cascader v-model="form.ping_fen_ren_" :options="getRaterOptions(userList)" :show-all-levels="false" /> -->
                 <!-- <el-cascader v-model="form.ping_fen_ren_" :options="getRaterOptions(userList)" :show-all-levels="false" /> -->
@@ -140,9 +177,13 @@ export default {
                 ti_ku_zhuang_tai_: '可用',
                 ti_ku_zhuang_tai_: '可用',
                 xian_kao_ci_shu_: '不限',
                 xian_kao_ci_shu_: '不限',
                 ping_fen_ren_: '',
                 ping_fen_ren_: '',
+                da_biao_zhan_bi_: 60,
                 miao_shu_: '',
                 miao_shu_: '',
                 ti_shu_: 0,
                 ti_shu_: 0,
-                isLimit: 0
+                isLimit: '0',
+                limitTime: '0',
+                hours: null,
+                minutes: null
             },
             },
             toolbars: [
             toolbars: [
                 {
                 {
@@ -161,7 +202,9 @@ export default {
                 bian_zhi_bu_men_: [{ required: true, message: this.$t('validate.required') }],
                 bian_zhi_bu_men_: [{ required: true, message: this.$t('validate.required') }],
                 ti_ku_fen_lei_: [{ required: true, message: this.$t('validate.required') }],
                 ti_ku_fen_lei_: [{ required: true, message: this.$t('validate.required') }],
                 ti_ku_zhuang_tai_: [{ required: true, message: this.$t('validate.required') }],
                 ti_ku_zhuang_tai_: [{ required: true, message: this.$t('validate.required') }],
-                xian_kao_ci_shu_: [{ required: true, message: this.$t('validate.required') }]
+                xian_kao_ci_shu_: [{ required: true, message: this.$t('validate.required') }],
+                kao_shi_shi_chang: [{ required: true, message: this.$t('validate.required') }],
+                da_biao_zhan_bi_: [{ required: true, message: this.$t('validate.required') }]
             }
             }
 
 
         }
         }
@@ -239,15 +282,24 @@ export default {
             if (this.$utils.isEmpty(this.formId)) {
             if (this.$utils.isEmpty(this.formId)) {
                 return
                 return
             }
             }
-            const sql = `select id_, bian_zhi_ren_, bian_zhi_bu_men_, bian_zhi_shi_jian, ti_ku_ming_cheng_, ti_ku_fen_lei_, ti_ku_zhuang_tai_, xian_kao_ci_shu_, ping_fen_ren_, miao_shu_, suo_shu_fan_wei_ from t_question_bank where id_ = '${this.formId}'`
+            const sql = `select id_, bian_zhi_ren_, bian_zhi_bu_men_, bian_zhi_shi_jian, ti_ku_ming_cheng_, ti_ku_fen_lei_, ti_ku_zhuang_tai_, xian_kao_ci_shu_, ping_fen_ren_, miao_shu_, suo_shu_fan_wei_, kao_shi_shi_chang, da_biao_zhan_bi_ from t_question_bank where id_ = '${this.formId}'`
             this.$common.request('sql', sql).then(res => {
             this.$common.request('sql', sql).then(res => {
                 const { data = [] } = res.variables || {}
                 const { data = [] } = res.variables || {}
                 if (!data.length) {
                 if (!data.length) {
                     this.$message.error('数据不存在')
                     this.$message.error('数据不存在')
                     return
                     return
                 }
                 }
+                data[0].isLimit = data[0].xian_kao_ci_shu_ === '不限' ? '0' : '1'
+                if (data[0].kao_shi_shi_chang === '不限') {
+                    data[0].limitTime = '0'
+                    data[0].hours = null
+                    data[0].minutes = null
+                } else {
+                    data[0].limitTime = '1'
+                    data[0].hours = Math.floor(data[0].kao_shi_shi_chang / (1000 * 60 * 60))
+                    data[0].minutes = (data[0].kao_shi_shi_chang % (1000 * 60 * 60)) / (60 * 1000)
+                }
                 this.form = data[0]
                 this.form = data[0]
-                this.form.isLimit = data[0].xian_kao_ci_shu_ === '不限' ? 0 : 1
             })
             })
         },
         },
         handleSubmit () {
         handleSubmit () {
@@ -261,10 +313,22 @@ export default {
             })
             })
         },
         },
         submitForm () {
         submitForm () {
+            if (this.form.limitTime === '0') {
+                this.form.kao_shi_shi_chang = '不限'
+            } else {
+                this.form.kao_shi_shi_chang = (this.form.hours * 60 + this.form.minutes) * 60 * 1000
+            }
             delete this.form.isLimit
             delete this.form.isLimit
+            delete this.form.limitTime
+            delete this.form.hours
+            delete this.form.minutes
             const addParams = {
             const addParams = {
                 tableName: 't_question_bank',
                 tableName: 't_question_bank',
-                paramWhere: [this.form]
+                paramWhere: [{
+                    ...this.form,
+                    ti_shu_: 0,
+                    zong_fen_: 0
+                }]
             }
             }
             const updateParams = {
             const updateParams = {
                 tableName: 't_question_bank',
                 tableName: 't_question_bank',
@@ -305,5 +369,19 @@ export default {
                 padding-top: 6px;
                 padding-top: 6px;
             }
             }
         }
         }
+        .inline-item {
+            ::v-deep {
+                .el-radio-group {
+                    margin-right: 20px;
+                }
+            }
+            .time {
+                display: inline-block;
+            }
+        }
+        .unit {
+            display: inline-block;
+            margin: 0 20px 0 5px;
+        }
     }
     }
 </style>
 </style>

+ 525 - 0
src/views/platform/examine/questionBank/test.vue

@@ -0,0 +1,525 @@
+<template>
+    <el-dialog
+        :title="title"
+        :visible.sync="dialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        append-to-body
+        fullscreen
+        class="dialog test-dialog"
+        top="0"
+        @open="loadData"
+        @close="closeDialog"
+    >
+        <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">
+                            <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">
+                            <el-checkbox
+                                v-for="(o, i) in item.options"
+                                :key="`${index}${i}`"
+                                :label="o.label"
+                            >{{ o.value }}</el-checkbox>
+                        </el-checkbox-group>
+                        <el-radio-group v-else-if="item.questionType === '判断题'" v-model="item.answer">
+                            <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-else-if="item.questionType === '简答题'"
+                            v-model="item.answer"
+                            type="textarea"
+                            :autosize="{ minRows: 4, maxRows: 8}"
+                            placeholder="请输入您的答案"
+                        />
+                    </div>
+                </div>
+            </div>
+            <div class="question-link">
+                <el-progress
+                    type="line"
+                    class="progress"
+                    :text-inside="true"
+                    :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>
+        </div>
+        <div slot="footer" class="el-dialog--center">
+            <ibps-toolbar
+                :actions="toolbars"
+                @action-event="handleActionEvent"
+            />
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+import ActionUtils from '@/utils/action'
+import { paperTypeOptions } from '../constants'
+export default {
+    components: {
+        IbpsImage: () => import('@/business/platform/file/image')
+    },
+    props: {
+        visible: {
+            type: Boolean,
+            default: false
+        },
+        id: {
+            type: String,
+            default: ''
+        },
+        parentId: {
+            type: String,
+            default: ''
+        }
+    },
+    data () {
+        const { userId } = this.$store.getters || {}
+        return {
+            paperTypeOptions,
+            title: '参加考试',
+            dialogVisible: this.visible,
+            toolbars: [
+                {
+                    key: 'prev',
+                    icon: 'ibps-icon-chevron-left',
+                    label: '上一题',
+                    disabled: () => {
+                        return this.showIndex === 1
+                    }
+                },
+                {
+                    key: 'next',
+                    icon: 'ibps-icon-chevron-right',
+                    label: '下一题',
+                    disabled: () => {
+                        return this.showIndex === this.questionList.length
+                    }
+                },
+                {
+                    key: 'submit',
+                    icon: 'ibps-icon-send',
+                    label: '交卷',
+                    hidden: () => {
+                        return this.readonly
+                    }
+                },
+                { key: 'cancel', label: '退出' }
+            ],
+            questionList: [],
+            showIndex: 1
+        }
+    },
+    computed: {
+        formData () {
+            return this.data
+        }
+    },
+    watch: {
+        visible: {
+            handler (val, oldVal) {
+                this.dialogVisible = this.visible
+            }
+            // immediate: true
+        },
+        showIndex: {
+            handler (val, oldVal) {
+                const temp = this.questionList[oldVal - 1]
+                if (temp.questionType === '填空题') {
+                    temp.answer = temp.options.map(item => item.answer)
+                }
+            }
+        }
+    },
+    created () {
+        // this.getQuestionData()
+    },
+    mounted () {
+        this.loadData()
+        // 监听键盘事件
+        window.addEventListener('keyup', this.handleKeyPress)
+    },
+    beforeDestroy () {
+        window.removeEventListener('keyup', this.handleKeyPress)
+    },
+    methods: {
+        // 获取题库数据
+        async loadData () {
+            if (!this.parentId) {
+                this.$message.error('获取题目信息失败,请重试!')
+                this.closeDialog()
+                return
+            }
+            this.questionList = await this.getQuestionData()
+            // console.log(this.questionList)
+        },
+        handleActionEvent ({ key }) {
+            switch (key) {
+                case 'prev':
+                    this.showIndex--
+                    break
+                case 'next':
+                    this.showIndex++
+                    break
+                case 'submit':
+                    this.handleSubmit()
+                    break
+                case 'cancel':
+                    this.closeDialog()
+                    break
+                default:
+                    break
+            }
+        },
+        getQuestionData () {
+            const sql = `select id_ as questionId, ti_gan_ as stem, ti_xing_ as questionType, fu_tu_ as img, xuan_xiang_lei_xi as optionType, da_an_ as options, xuan_xiang_shu_ as optionsLength, fen_zhi_ as score, ping_fen_fang_shi as rateType, ping_fen_ren_ as rater, zheng_que_da_an_ as rightKey from t_questions where parent_id_ = '${this.parentId}' and zhuang_tai_ = '启用' order by field(ti_xing_, '单选题', '多选题', '判断题', '填空题', '简答题')`
+            return new Promise((resolve, reject) => {
+                this.$common.request('sql', sql).then(res => {
+                    const { data = [] } = res.variables || {}
+                    if (!data.length) {
+                        this.$message.error('获取题目信息失败!')
+                        this.closeDialog()
+                        return
+                    }
+                    data.map(item => {
+                        if (item.options) {
+                            const temp = item.options ? JSON.parse(item.options) : {}
+                            const o = []
+                            Object.keys(temp).forEach(key => {
+                                o.push({
+                                    label: key,
+                                    value: temp[key]
+                                })
+                            })
+                            item.options = o
+                        } else {
+                            item.options = Array.from({ length: item.optionsLength }, (v, k) => {
+                                return { answer: null }
+                            })
+                        }
+                        item.img = item.img ? JSON.parse(item.img) : ''
+                        item.answer = null
+                    })
+                    resolve(data)
+                }).catch(error => {
+                    reject(error)
+                })
+            })
+        },
+        getProgress () {
+            const finished = []
+            this.questionList.forEach(item => {
+                if (item.questionType === '填空题') {
+                    finished.push(item.answer && !item.answer.some(i => i === '' || i === null))
+                } else {
+                    finished.push(item.answer && 1)
+                }
+            })
+            // const finished = this.questionList.filter(item => (item.questionType !== '填空题' && item.answer) || (item.questionType === '填空题' && item.answer && !item.answer.some(i => i === '' || i === null))).length
+            const finishedCount = finished.filter(i => i).length
+            return parseInt(finishedCount / this.questionList.length * 100)
+        },
+        setClassName (item, index) {
+            const result = []
+            if (item.answer) {
+                // 填空题且未填写所有答案
+                if (item.questionType === '填空题' && (item.options.every(i => !i.answer))) {
+                    result.push('')
+                } else if (item.questionType === '填空题' && (item.options.some(i => !i.answer))) {
+                    result.push('incomplete')
+                } else {
+                    result.push('finished')
+                }
+            }
+            if (this.showIndex === index + 1) {
+                result.push('active')
+            }
+            return result.join(' ')
+        },
+        handleKeyPress (event) {
+            if (event.keyCode === 37 || event.key === 'ArrowLeft') {
+                if (this.showIndex === 1) {
+                    this.$message.warning('已经是第一题了!')
+                    return
+                }
+                this.showIndex--
+            } else if (event.keyCode === 39 || event.key === 'ArrowRight') {
+                if (this.showIndex === this.questionList.length) {
+                    this.$message.warning('已经是最后一题了!')
+                    return
+                }
+                this.showIndex++
+            }
+        },
+        getScore ({ questionType, answer, rightKey, score }) {
+            if (questionType === '多选题') {
+                const temp = JSON.parse(rightKey)
+                return answer.length === temp.length && answer.every(i => temp.includes(i)) ? score : 0
+            } else {
+                return answer === rightKey ? score : 0
+            }
+        },
+        handleSubmit () {
+            console.log(this.questionList)
+            let incompleteList = []
+            this.questionList.forEach((item, index) => {
+                if (item.questionType === '填空题') {
+                    const t = item.answer && item.answer.some(i => i === '' || i === null)
+                    incompleteList.push(!t ? index + 1 : '')
+                } else {
+                    incompleteList.push(!item.answer ? index + 1 : '')
+                }
+            })
+            incompleteList = incompleteList.filter(i => i)
+            const tip = incompleteList.length ? `还有第${incompleteList.join('、')}题未作答,您确定要直接交卷吗?` : '您已完成作答,确定要交卷吗?'
+            this.$confirm(tip, '提示', {
+                type: incompleteList.length ? 'warning' : 'info',
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                showClose: false,
+                closeOnClickModal: false
+            }).then(() => {
+                const submitData = []
+                this.questionList.forEach((item, index) => {
+                    const autoType = ['单选题', '多选题', '判断题'].includes(item.questionType)
+                    const multipleType = ['多选题', '填空题'].includes(item.questionType)
+                    submitData.push({
+                        parent_id_: this.parentId,
+                        ti_mu_id_: item.questionId,
+                        ti_gan_: item.stem,
+                        ti_xing_: item.questionType,
+                        fen_zhi_: item.score,
+                        fu_tu_: item.img,
+                        xuan_xiang_lei_xi: item.optionType,
+                        xuan_xiang_: item.options,
+                        can_kao_da_an_: item.rightKey,
+                        ping_fen_fang_shi: item.rateType,
+                        ping_fen_ren_: item.rater,
+                        hui_da_: multipleType ? JSON.stringify(item.answer) : item.answer,
+                        shi_fou_yi_yue_: autoType ? '是' : '否',
+                        de_fen_: autoType ? this.getScore(item) : '',
+                        jie_xi_: ''
+                    })
+                })
+                this.submitForm(submitData)
+            }).catch(() => {})
+        },
+        submitForm (data) {
+            const addParams = {
+                tableName: 't_examination_detail',
+                paramWhere: data
+            }
+            const updateParams = {
+                tableName: 't_examination',
+                updList: [
+                    {
+                        where: {
+                            id_: this.id
+                        },
+                        param: {
+                            jie_shu_shi_jian_: this.$common.getDateNow(19),
+                            ti_ku_zong_fen_: data.reduce((sum, item) => sum + parseInt(item.fen_zhi_), 0),
+                            zhuang_tai_: '已完成',
+                            // sheng_yu_shi_chan: ''
+                        }
+                    }
+                ]
+            }
+            console.log(addParams, updateParams)
+            this.$common.request('add', addParams).then(() => {
+                this.$common.request('update', updateParams).then(() => {
+                    this.$message.success('提交成功!')
+                    this.closeDialog()
+                })
+            })
+        },
+        // 关闭当前窗口
+        closeDialog () {
+            this.$emit('close', false)
+        }
+    }
+}
+</script>
+<style lang="scss" scoped>
+    .test-dialog {
+        ::v-deep {
+            .el-dialog__body {
+                height: calc(100vh - 55px);
+                width: 1080px;
+                margin: 0 auto;
+                box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+                .el-radio {
+                    display: block;
+                    margin-bottom: 10px;
+                }
+                .el-radio__label, .el-checkbox__label {
+                    font-size: 16px;
+                }
+                .el-input {
+                    margin-bottom: 10px;
+                }
+                .el-tag {
+                    margin-right: 0;
+                }
+                .list-group {
+                    display: inline-block;
+                    width: 100%;
+                }
+            }
+            .el-dialog__header {
+                text-align: center;
+            }
+        }
+        .container {
+            position: relative;
+            height: calc(100vh - 160px);
+            padding: 20px;
+            .question {
+                font-size: 16px;
+                .question-item {
+                    margin-bottom: 10px;
+                    .type {
+                        font-size: 20px;
+                        font-weight: 600;
+                        margin-bottom: 20px;
+                    }
+                    .stem {
+                        display: flex;
+                        margin-bottom: 20px;
+                        align-items: flex-start;
+                        > span:first-child {
+                            line-height: 1.5;
+                            margin-right: 10px;
+                        }
+                    }
+                    .img {
+                        position: relative;
+                        width: 100%;
+                        margin-bottom: 10px;
+                    }
+                    .answer {
+
+                    }
+                }
+            }
+            .question-link {
+                display: flex;
+                flex-wrap: wrap;
+                justify-content: flex-start;
+                position: absolute;
+                width: calc(100% - 40px);
+                bottom: 20px;
+                .el-progress {
+                    width: 100%;
+                    margin-bottom: 10px;
+                }
+                .link-item {
+                    width: 32px;
+                    height: 32px;
+                    text-align: center;
+                    line-height: 32px;
+                    border: 1px solid #DCDFE6;
+                    margin: 3px;
+                    border-radius: 2px;
+                    cursor: pointer;
+                    &:hover {
+                        background-color: #F5F7FA;
+                    }
+                }
+                $button-themes: (
+                    active: (#409EFF, #fff, #409EFF),
+                    incomplete: (#E6A23C, #fff, #E6A23C),
+                    finished: (#67C23A, #fff, #67C23A)
+                );
+                @each $theme, $colors in $button-themes {
+                    .#{$theme} {
+                        background-color: nth($colors, 1);
+                        color: nth($colors, 2);
+                        border-color: nth($colors, 3);
+
+                        &:hover {
+                            background-color: lighten(nth($colors, 1), 10%);
+                            border-color: lighten(nth($colors, 1), 10%);
+                        }
+                    }
+                }
+                // .active {
+                //     background-color: #409EFF;
+                //     color: #fff;
+                //     border-color: #409EFF;
+                //     &:hover {
+                //         background-color: #66b1ff;
+                //         color: #fff;
+                //         border-color: #66b1ff;
+                //     }
+                // }
+                // .incomplete {
+                //     background-color: #E6A23C;
+                //     color: #fff;
+                //     border-color: #E6A23C;
+                //     &:hover {
+                //         background-color: #E6A23C;
+                //         color: #fff;
+                //         border-color: #E6A23C;
+                //     }
+                // }
+                // .finished {
+                //     background-color: #67C23A;
+                //     color: #fff;
+                //     border-color: #67C23A;
+                //     &:hover {
+                //         background-color: #85ce61;
+                //         color: #fff;
+                //         border-color: #85ce61;
+                //     }
+                // }
+            }
+        }
+    }
+</style>