Przeglądaj źródła

Merge branch 'master' of http://119.23.210.103:3000/wy/zdqy_firm_former

cfort 1 rok temu
rodzic
commit
bd925d2b62

+ 14 - 0
src/assets/styles/fixed/element.scss

@@ -154,3 +154,17 @@
     }
 }
 
+.ibps-layout-header-aside-menu-side{
+    .is-active > .el-submenu__title{
+        background: #e0f0ee !important;
+    }
+    .el-menu .el-menu-item:hover{
+        background: #e0f0ee !important;
+    }
+    .el-submenu .el-submenu__title:hover {
+        background: #e0f0ee !important;
+    }
+    .el-menu .el-menu-item.is-active {
+        color: #67afa9 !important;
+    }
+}

+ 15 - 5
src/views/platform/examination/exam/detail.vue

@@ -48,11 +48,11 @@
                 </div>
                 <div class="info-item">
                     <span class="label">题目数量:</span>
-                    <span class="value">{{ paperData.questionCount }}</span>
+                    <span class="value">{{ paperData.isRand==='1'?paperData.randTotal:paperData.questionCount }}</span>
                 </div>
                 <div class="info-item">
                     <span class="label">总分:</span>
-                    <span class="value">{{ paperData.totalScore }}分</span>
+                    <span class="value">{{ paperData.isRand==='1'?paperData.randScore:paperData.totalScore }}分</span>
                 </div>
                 <div class="info-item">
                     <el-tooltip
@@ -64,6 +64,10 @@
                     </el-tooltip>
                     <span class="value">{{ paperData.qualifiedRadio }}%</span>
                 </div>
+                <div class="info-item">
+                    <span class="label">是否随机:</span>
+                    <span class="value">{{ paperData.isRand==='1'?'是':'否' }}</span>
+                </div>
                 <div class="info-item">
                     <span class="label">最高分:</span>
                     <span class="value">{{ maxScore }}</span>
@@ -115,6 +119,8 @@
 
                 <el-button
                     type="primary"
+                    size="mini"
+                    icon="el-icon-s-data"
                     @click="showStatistics"
                 >各部门数据统计</el-button>
             </div>
@@ -130,7 +136,7 @@
                     class="exam-table"
                     @row-dblclick="handleRowDblclick"
                 >
-                    <el-table-column label="序号" type="index" width="50" />
+                    <el-table-column label="序号" type="index" :index="showIndex" width="50" />
                     <el-table-column prop="userName" label="考生姓名" width="100" />
                     <el-table-column prop="positionId" label="部门" width="100">
                         <template slot-scope="{ row }">
@@ -389,7 +395,7 @@ export default {
             return ((passList.length / list.length) * 100).toFixed(2) + '%'
         },
         getQuestionData () {
-            const sql = `select qb.ti_ku_ming_cheng_ as bankName, ex.id_ as examId, ex.ti_ku_id_ as bankId, e.id_ as paperId, ex.zhuang_tai_ as examState, e.zhuang_tai_ as paperState, qb.ti_shu_ as questionCount, qb.zong_fen_ as totalScore, ex.kao_shi_ming_chen as examName, ex.can_kao_ren_yuan_ as examinee, e.kao_shi_ren_ as examineeId, ex.create_by_ as createBy, ex.chuang_jian_shi_j as createTime, ex.fa_bu_shi_jian_ as publishDate, ex.xian_kao_shi_jian as limitDate, ex.kao_shi_shi_chang as duration, ex.xian_kao_ci_shu_ as limitCount, ex.da_biao_zhan_bi_ as qualifiedRadio, ex.ji_fen_fang_shi_ as scoringType, ex.yun_xu_bao_ming_ as allowRegist, ex.kao_shi_miao_shu_ as examDesc, e.de_fen_ as score, e.bao_ming_shi_jian as applyTime, e.kai_shi_shi_jian_ as startTime, e.jie_shu_shi_jian_ as endTime from t_exams ex, t_question_bank qb, t_examination e where ex.ti_ku_id_ = qb.id_ and e.exam_id_ = ex.id_ and ex.id_ = '${this.examId}' order by e.kao_shi_ren_ desc, e.jie_shu_shi_jian_ desc`
+            const sql = `select qb.ti_ku_ming_cheng_ as bankName, ex.id_ as examId, ex.ti_ku_id_ as bankId, e.id_ as paperId, ex.zhuang_tai_ as examState, e.zhuang_tai_ as paperState, qb.ti_shu_ as questionCount, qb.zong_fen_ as totalScore, ex.kao_shi_ming_chen as examName, ex.can_kao_ren_yuan_ as examinee, e.kao_shi_ren_ as examineeId, ex.create_by_ as createBy, ex.chuang_jian_shi_j as createTime, ex.fa_bu_shi_jian_ as publishDate, ex.xian_kao_shi_jian as limitDate, ex.kao_shi_shi_chang as duration, ex.xian_kao_ci_shu_ as limitCount, ex.da_biao_zhan_bi_ as qualifiedRadio, ex.ji_fen_fang_shi_ as scoringType, ex.yun_xu_bao_ming_ as allowRegist, ex.kao_shi_miao_shu_ as examDesc,ex.sui_ji_chou_ti_ as isRand, ex.sui_ji_ti_shu_ as randNumber,ex.chou_ti_zong_fen_ as randScore,ex.ti_mu_zong_shu_ as randTotal, e.de_fen_ as score, e.bao_ming_shi_jian as applyTime, e.kai_shi_shi_jian_ as startTime, e.jie_shu_shi_jian_ as endTime from t_exams ex, t_question_bank qb, t_examination e where ex.ti_ku_id_ = qb.id_ and e.exam_id_ = ex.id_ and ex.id_ = '${this.examId}' order by e.kao_shi_ren_ desc, e.jie_shu_shi_jian_ desc`
             return new Promise((resolve, reject) => {
                 this.$common
                     .request('sql', sql)
@@ -414,7 +420,7 @@ export default {
                                 result.push({
                                     ...item,
                                     totalCount: data.length,
-                                    totalScore: parseFloat(item.totalScore),
+                                    totalScore: item.isRand === '1' ? parseFloat(item.randScore) : parseFloat(item.totalScore),
                                     statusList: [item.paperState],
                                     scoreList: [parseFloat(item.score || -1)]
                                 })
@@ -501,6 +507,10 @@ export default {
             this.pageSize = val
             this.currentPage = 1
         },
+        // 分页连续序号
+        showIndex (index) {
+            return index + 1 + (this.currentPage - 1) * this.pageSize
+        },
         // position部门所有应参考人数
         filterdepartmentData (position) {
             let count = 0

+ 152 - 11
src/views/platform/examination/exam/edit.vue

@@ -67,6 +67,52 @@
           > -->
                 </div>
             </el-form-item>
+            <el-form-item>
+                <template slot="label">
+                    随机抽题
+                    <el-tooltip
+                        effect="dark"
+                        content="是否开启从题库中随机抽题。"
+                        placement="top"
+                    >
+                        <i class="el-icon-question question-icon">:</i>
+                    </el-tooltip>
+                </template>
+                <el-radio-group v-model="form.sui_ji_chou_ti_" :disabled="isDisabled">
+                    <el-radio label="0">关闭</el-radio>
+                    <el-radio label="1" :disabled="!(!!form.ti_ku_id_)">开启</el-radio>
+                </el-radio-group>
+            </el-form-item>
+            <el-form-item v-if="form.sui_ji_chou_ti_ === '1'" class="handrand">
+                <template slot="label">
+                    抽题规则
+                    <el-tooltip
+                        effect="dark"
+                        content="设置每类题型的抽题数量,相同题型相同分值可以自由选择抽题数量,相同题型不同分值只能全抽或不抽。"
+                        placement="top"
+                    >
+                        <i class="el-icon-question question-icon">:</i>
+                    </el-tooltip>
+                </template>
+                <div v-for="item in handList" :key="item.itemType" class="hand-item">
+                    <template v-if="item.list.length>0">
+                        <span>{{ item.itemType }}:</span>
+                        <el-input-number
+                            v-model="item.questionNumber"
+                            style="width:120px"
+                            :min="0"
+                            :max="item.list.length"
+                            :precision="0"
+                            :disabled="form.sui_ji_chou_ti_ === '0' || isDisabled"
+                            placeholder="请输入抽题数量"
+                            :step="item.step"
+                            step-strictly
+                        />
+                    </template>
+
+                </div>
+
+            </el-form-item>
             <el-form-item prop="xian_kao_shi_jian">
                 <template slot="label">
                     限考时间
@@ -308,6 +354,13 @@ export default {
             level
         } = this.$store.getters || {}
         return {
+            handList: [
+                { itemType: '单选题', questionNumber: 0, list: [], step: 1 },
+                { itemType: '多选题', questionNumber: 0, list: [], step: 1 },
+                { itemType: '判断题', questionNumber: 0, list: [], step: 1 },
+                { itemType: '填空题', questionNumber: 0, list: [], step: 1 },
+                { itemType: '简答题', questionNumber: 0, list: [], step: 1 }
+            ],
             userList,
             examTypeOptions,
             deptList: deptList.filter((i) => i.depth === 4),
@@ -316,6 +369,7 @@ export default {
             dialogVisible: this.visible,
             dialogLoading: false,
             randButtonDisabled: false,
+            isFirst: true,
             form: {
                 di_dian_: level.second || level.first,
                 chuang_jian_shi_j: '',
@@ -335,6 +389,10 @@ export default {
                 isCountLimit: '0',
                 isTimeLimit: '0',
                 isDateLimit: '0',
+                sui_ji_chou_ti_: '0',
+                chou_ti_zong_fen_: 0,
+                ti_mu_zong_shu_: 0,
+                sui_ji_ti_shu_: [],
                 hours: 2,
                 minutes: 30
             },
@@ -385,12 +443,53 @@ export default {
                 this.dialogVisible = this.visible
             }
             // immediate: true
+        },
+        'form.ti_ku_id_': {
+            handler (val) {
+                if (val) {
+                    const sql = `select * from t_questions where parent_id_ = '${val}' and zhuang_tai_ = '启用' order by field(ti_xing_, '单选题', '多选题', '判断题', '填空题', '简答题')`
+                    this.$common.request('sql', sql).then((res) => {
+                        const { data = [] } = res.variables || {}
+                        this.getHandList(data)
+                    })
+                }
+            }
         }
     },
     mounted () {
         this.getExamData()
     },
     methods: {
+        // 题型分类
+        getHandList (data) {
+            // 确定每种类型的题目
+            this.handList.forEach(hand => {
+                hand.list = data.filter(item => item.ti_xing_ === hand.itemType)
+            })
+
+            if (this.$utils.isEmpty(this.id)) {
+                // 设置每种类型题目的默认题数
+                this.handList.forEach(hand => {
+                    hand.questionNumber = hand.list.length
+                })
+            } else {
+                if (!this.isFirst) {
+                    this.handList.forEach(hand => {
+                        hand.questionNumber = hand.list.length
+                    })
+                } else {
+                    this.isFirst = false
+                }
+            }
+
+            // 设置每种类型题目的步数
+            this.handList.forEach(hand => {
+                if (hand.list.length > 0) {
+                    const isSame = hand.list.every(item => item.fen_zhi_ === hand.list[0].fen_zhi_)
+                    hand.step = isSame ? 1 : hand.list.length
+                }
+            })
+        },
         changeLimit (e, type, defaultValue) {
             this.form[type] = e === '1' ? defaultValue : '不限'
         },
@@ -415,7 +514,7 @@ export default {
                 this.randButtonDisabled = true
                 this.$message.info('非未发布状态的考试仅可修改限考时间!')
             }
-            const sql = `select id_, create_by_, ti_ku_id_, guan_lian_id_, kao_shi_ming_chen, kao_shi_lei_xing_, chuang_jian_shi_j, fa_bu_shi_jian_, fa_bu_ren_, xian_kao_shi_jian, xian_kao_ci_shu_, kao_shi_shi_chang, can_kao_ren_yuan_, zhuang_tai_, da_biao_zhan_bi_, ji_fen_fang_shi_, kao_shi_miao_shu_, yun_xu_bao_ming_ from t_exams where id_ = '${this.id}'`
+            const sql = `select id_, create_by_, ti_ku_id_, guan_lian_id_, kao_shi_ming_chen, kao_shi_lei_xing_, chuang_jian_shi_j, fa_bu_shi_jian_, fa_bu_ren_, xian_kao_shi_jian, xian_kao_ci_shu_, kao_shi_shi_chang, can_kao_ren_yuan_, zhuang_tai_, da_biao_zhan_bi_, ji_fen_fang_shi_, kao_shi_miao_shu_, yun_xu_bao_ming_, sui_ji_chou_ti_, sui_ji_ti_shu_,chou_ti_zong_fen_,ti_mu_zong_shu_ from t_exams where id_ = '${this.id}'`
             this.$common.request('sql', sql).then((res) => {
                 const { data = [] } = res.variables || {}
                 if (!data.length) {
@@ -437,9 +536,15 @@ export default {
             (data[0].kao_shi_shi_chang % (1000 * 60 * 60)) / (60 * 1000)
                 }
                 this.form = data[0]
+                if (this.form.sui_ji_chou_ti_ === '1') {
+                    this.form.sui_ji_ti_shu_ = this.form.sui_ji_ti_shu_.split(',')
+                    this.form.sui_ji_ti_shu_.forEach((item, index) => {
+                        this.handList[index].questionNumber = item
+                    })
+                }
             })
         },
-        // 随机题库
+        // 随机题库 弃用
         randTiku () {
             this.randButtonDisabled = true
             const sql = `select id_ from t_question_bank where ti_ku_zhuang_tai_='可用'`
@@ -453,6 +558,31 @@ export default {
         handleSubmit () {
             this.$refs.form.validate((valid) => {
                 if (valid) {
+                    this.form.sui_ji_ti_shu_ = []
+                    this.form.chou_ti_zong_fen_ = 0
+                    this.form.ti_mu_zong_shu_ = 0
+                    if (this.form.sui_ji_chou_ti_ === '1') {
+                        // 计算总分 总数量
+                        this.handList.forEach(item => {
+                            if (item.list.length > 0) {
+                                this.form.sui_ji_ti_shu_.push(item.questionNumber)
+                                this.form.ti_mu_zong_shu_ += item.questionNumber
+                                this.form.chou_ti_zong_fen_ += item.list.slice(0, item.questionNumber).reduce((pre, cur) => {
+                                    return pre + +cur.fen_zhi_
+                                }, 0)
+                            } else {
+                                this.form.sui_ji_ti_shu_.push(0)
+                            }
+                        })
+
+                        if (this.form.ti_mu_zong_shu_ === 0) {
+                            return this.$message.warning('请填写需要抽取的题目数量!')
+                        }
+                    }
+                    this.form.chou_ti_zong_fen_ += ''
+                    this.form.ti_mu_zong_shu_ += ''
+                    this.form.sui_ji_ti_shu_ = this.form.sui_ji_ti_shu_.join(',')
+
                     const { isTimeLimit, xian_kao_shi_jian = '' } = this.form || {}
                     // 转换考试时长
                     if (isTimeLimit === '0') {
@@ -510,12 +640,12 @@ export default {
 </script>
 <style lang="scss" scoped>
 .exam-dialog {
-  ::v-deep {
-    .el-dialog {
-      max-width: 1080px;
-    }
-    .el-dialog__body {
-      height: calc(88vh - 200px);
+    ::v-deep {
+        .el-dialog {
+            max-width: 1080px;
+        }
+        .el-dialog__body {
+      height: calc(88vh - 150px);
     }
     .el-form-item {
       margin-bottom: 14px !important;
@@ -561,10 +691,21 @@ export default {
     display: inline-block;
     margin: 0 20px 0 5px;
   }
+  .handrand{
+    ::v-deep .el-form-item__content{
+        display: flex;
+        flex-wrap: wrap;
+    }
+    .hand-item{
+        display: flex;
+        margin-right: 20px;
+        margin-bottom: 10px;
+    }
+  }
 }
 .tiku {
-  .el-button {
-    margin-left: 20px;
-  }
+    .el-button {
+        margin-left: 20px;
+    }
 }
 </style>

+ 17 - 3
src/views/platform/examination/questionBank/detail.vue

@@ -224,7 +224,7 @@
                     <el-card
                         class="timeline-card"
                         :class="paper.dataId === showPaperId ? 'active-card' : ''"
-                        @click.native="changePaper(paper.dataId)"
+                        @click.native="changePaper(paper.dataId,paper.status)"
                     >
                         <div class="card-item">{{ `开始时间:${paper.startTime}` }}</div>
                         <div class="card-item">{{ `结束时间:${paper.endTime}` }}</div>
@@ -360,6 +360,13 @@ export default {
             this.paperData =
         this.paperList.find((i) => i.dataId === this.id) || this.paperList[0]
             this.showPaperId = this.paperData.dataId
+
+            const isAllNotFinish = this.paperList.every(item => item.status !== '已完成')
+            if (isAllNotFinish) {
+                this.$message.error('考试未完成或未评分,请稍后再试!')
+                this.closeDialog()
+                return
+            }
         },
         handleActionEvent ({ key }) {
             switch (key) {
@@ -454,7 +461,7 @@ export default {
                                     paperName,
                                     totalScore: parseFloat(totalScore),
                                     resultScore: parseFloat(resultScore),
-                                    totalCount: data.length,
+                                    // totalCount: data.length,
                                     scoringType,
                                     list: [
                                         {
@@ -478,12 +485,15 @@ export default {
                             }
                         })
                         result.forEach((item) => {
+                            let count = 0
                             item.list.forEach((i) => {
+                                count += i.questions.length
                                 i.totalScore = i.questions.reduce(
                                     (a, b) => a + parseFloat(b.questionScore),
                                     0
                                 )
                             })
+                            item.totalCount = count
                         })
                         // 获取最高分最低分
                         const { maxScore, minScore } = result
@@ -509,7 +519,11 @@ export default {
                     })
             })
         },
-        changePaper (id) {
+        changePaper (id, status) {
+            if (status !== '已完成') {
+                this.$message.error('考试未完成或未评分,暂时无法查看!')
+                return
+            }
             this.showPaperId = id
             this.paperData = this.paperList.find((i) => i.dataId === id)
             console.log(id)

+ 67 - 23
src/views/platform/examination/questionBank/test.vue

@@ -119,6 +119,7 @@
 
 <script>
 // import Watermark from '@/layout/header-aside/components/header-message/watermark/watermark-cont'
+import { shuffle } from 'lodash'
 import { round } from 'lodash'
 export default {
     components: {
@@ -204,6 +205,7 @@ export default {
         },
         showIndex: {
             handler (val, oldVal) {
+                // console.log(val)
                 const temp = this.questionList[oldVal - 1]
                 if (['填空题'].includes(temp.questionType)) {
                     temp.answer = temp.options.map(item => item.answer)
@@ -235,6 +237,7 @@ export default {
             }
             this.questionList = await this.getQuestionData()
             // console.log(this.questionList)
+            // console.log(this.examData)
         },
         startCountdown () {
             const timer = setInterval(() => {
@@ -277,17 +280,41 @@ export default {
         formatNum (num) {
             return num < 10 ? `0${num}` : num
         },
+        // 随机题目
+        getRandQuestionData (data) {
+            data = shuffle(data)
+            const temp = []
+            const type = ['单选题', '多选题', '判断题', '填空题', '简答题']
+            this.examData.randNumber = this.examData.randNumber.split(',')
+            for (let i = 0; i < this.examData.randNumber.length; i++) {
+                let t = +this.examData.randNumber[i]
+                // console.log(t)
+                if (t !== 0) {
+                    for (let j = 0; j < data.length && t; j++) {
+                        const item = data[j]
+                        if (item.questionType === type[i]) {
+                            temp.push(item)
+                            t--
+                        }
+                    }
+                }
+            }
+            return temp
+        },
         getQuestionData () {
             this.loading = true
             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.bankId}' and zhuang_tai_ = '启用' order by field(ti_xing_, '单选题', '多选题', '判断题', '填空题', '简答题')`
             return new Promise((resolve, reject) => {
                 this.$common.request('sql', sql).then(res => {
-                    const { data = [] } = res.variables || {}
+                    let { data = [] } = res.variables || {}
                     if (!data.length) {
                         this.$message.error('获取题目信息失败!')
                         this.closeDialog()
                         return
                     }
+                    if (this.examData.isRand === '1') {
+                        data = this.getRandQuestionData(data)
+                    }
                     data.map(item => {
                         if (item.options) {
                             const temp = JSON.parse(item.options) || {}
@@ -385,7 +412,9 @@ export default {
             if (this.showIndex === this.questionList.length) {
                 return
             }
-            this.showIndex++
+            setTimeout(() => {
+                this.showIndex++
+            }, 200)
         },
         getScore ({ questionType, answer, rightKey, score }) {
             if (questionType === '多选题') {
@@ -396,29 +425,42 @@ export default {
             }
         },
         handleSubmit () {
-            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 if (item.questionType === '多选题') {
-                    const t = item.answer && item.answer.length
-                    incompleteList.push(!t ? index + 1 : '')
+            const nextHandle = () => {
+                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 if (item.questionType === '多选题') {
+                        const t = item.answer && item.answer.length
+                        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(() => {
+                    this.submitForm(this.dealFormData())
+                }).catch(() => {})
+            }
+            // 处理最后一题无法自动提交的bug
+            if (this.questionList[this.questionList.length - 1] !== '判断题' && this.questionList[this.questionList.length - 1] !== '单选题') {
+                if (this.showIndex !== this.questionList.length) {
+                    this.showIndex = this.questionList.length
                 } else {
-                    incompleteList.push(!item.answer ? index + 1 : '')
+                    this.showIndex = 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(() => {
-                this.submitForm(this.dealFormData())
-            }).catch(() => {})
+                this.$nextTick(nextHandle)
+            } else {
+                nextHandle()
+            }
         },
         dealFormData () {
             const submitData = []
@@ -570,6 +612,8 @@ export default {
                 }
             }
             .question-link {
+                overflow: auto;
+                max-height: 150px;
                 display: flex;
                 flex-wrap: wrap;
                 justify-content: flex-start;