From 926fd4d1b89e7e5e6338d8f292edc4f728049856 Mon Sep 17 00:00:00 2001 From: zhouwx <1175765986@qq.com> Date: 星期五, 02 八月 2024 17:33:05 +0800 Subject: [PATCH] 试卷批改 --- src/views/onlineEducation/groupExams/components/examDialog.vue | 91 +++++- src/views/onlineEducation/groupExams/components/viewExamQuestion.vue | 111 +++++-- src/views/onlineEducation/groupExams/components/student.vue | 68 +++- src/views/onlineEducation/questionBankManagement/questionManage/index.vue | 13 src/views/onlineEducation/groupExams/components/correctExam.vue | 379 +++++++++++++++++++++++++ src/views/onlineEducation/groupExams/index.vue | 5 src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue | 142 +++++++-- src/router/index.js | 13 src/api/onlineEducation/exam.js | 34 + 9 files changed, 730 insertions(+), 126 deletions(-) diff --git a/src/api/onlineEducation/exam.js b/src/api/onlineEducation/exam.js index 2eddade..6ce3a84 100644 --- a/src/api/onlineEducation/exam.js +++ b/src/api/onlineEducation/exam.js @@ -82,12 +82,28 @@ method: 'delete' }) } -// -// //企业课时变更记录列表(分页) -// export function getCompanyPeriod(param) { -// return request({ -// url: '/company-period/list', -// method: 'get', -// params: param -// }) -// } + +//根据id查询学院试卷信息 +export function getPaperStu(param) { + return request({ + url: '/paper-student/getPaperStudentById', + method: 'get', + params: param + }) +} +//根据id试卷信息 +export function getPaper(id) { + return request({ + url: '/exam-paper/'+id, + method: 'get', + }) +} + +//提交批改试卷 +export function doConfirmExam(data) { + return request({ + url: '/paper-student/doReview', + method: 'post', + data: data + }) +} diff --git a/src/router/index.js b/src/router/index.js index 0856c65..d0ea350 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -92,6 +92,19 @@ } ] }, + { + path: '/correctExam', + component: Layout, + redirect: '/correctExam', + children: [ + { + path: '/correctExam', + component: () => import('@/views/onlineEducation/groupExams/components/correctExam.vue'), + name: 'CorrectExam', + meta: { title: '批改试卷',icon: 'form', affix: true } + } + ] + }, // { // path: '', // component: Layout, diff --git a/src/views/onlineEducation/groupExams/components/correctExam.vue b/src/views/onlineEducation/groupExams/components/correctExam.vue new file mode 100644 index 0000000..abbcb36 --- /dev/null +++ b/src/views/onlineEducation/groupExams/components/correctExam.vue @@ -0,0 +1,379 @@ +<template> + <div class="app-container"> + <div style="display: flex;justify-content: flex-end;margin-bottom: 10px"> + <div> + <el-button + type="primary" + plain + @click="back" + >返回</el-button> + </div> + </div> + <div class="paper-contain"> + <div class="paper-left"> + <div class="left-content"> + <el-card style="height: 80%;overflow-y: auto"> + <div> + <span style="font-size: 20px">{{data.form.examPaper.name}}</span> + <div class="examInfo"> + <span>得分:{{data.form.score}} / {{data.form.totalScore}}</span> + <span>学生:{{data.form.student.name}}</span> + <el-divider style="margin-top: 10px" /> + </div> + <div v-if="data.form.questions && data.form.questions.length>0" style="display: flex;flex-wrap: wrap;line-height: 40px"> + <div v-for="(item,index) in data.form.questions" :key="index" style="margin-right: 5px"> + <el-tag size="large" style="cursor: pointer" effect="light" :type="item.studentAnswer.passed == 0 ? 'danger' :item.studentAnswer.passed == 1?'success': 'warning'">{{index+1}}</el-tag> + </div> + <el-divider /> + </div> + <div style="display: flex;justify-content: center;"> + <el-button type="primary" @click="submitExam">提交批改</el-button> + </div> + </div> + </el-card> + </div> + </div> + <div class="paper-right"> + <div style="height: 100%"> + <el-card> + <div style="display: flex;flex-direction: column;margin: 0 30px" > + <div v-if="data.singleList && data.singleList.length >0"> + <span style="font-size: 18px;font-weight: 600">单选题</span> + + <div v-for="(item,index) in data.singleList" :key="index" style="margin-left: 15px;margin-top: 10px"> + <div style="display: flex;flex-direction: column;"> + <div style="margin-top: 10px;display: flex;align-items: center"> + <span style="font-size: 15px">{{index+1}}.</span> + <span style="margin-left: 10px;font-size: 16px">{{item.title}}</span> + </div> + <div style="display: flex;margin-top: 15px;margin-left: 25px"> + <div v-for="single in item.content.items" :class="{toRed : item.studentAnswer.answer == single.prefix}"> + <span style="font-size: 15px;margin-right: 5px">{{single.prefix}}.</span> + <span style="font-size: 15px;margin-right: 20px">{{single.content}}</span> + </div> + </div> + <div style="display: flex;flex-direction: column;margin-left: 25px;margin-top: 20px;font-size: 14px;line-height: 25px"> + <div style="display: flex"> + <span>结果:</span> + <el-tag size="small" :type="item.studentAnswer.passed == 0 ? 'danger' :item.studentAnswer.passed == 1?'success': 'warning'">{{item.studentAnswer.passed == 0 ? '错误' :item.studentAnswer.passed == 1? '正确' :'待批改' }}</el-tag> + </div> + <span>分数:{{data.form.examPaper.singleScore}}</span> + <span>解析:{{item.content.analyze}}</span> + <span>正确答案:{{item.answer}}</span> + + </div> + <el-divider /> + </div> + </div> + </div> + </div> + <div style="display: flex;flex-direction: column;margin: 0 30px" > + <div v-if="data.multiList && data.multiList.length >0"> + <span style="font-size: 18px;font-weight: 600">多选题</span> + <div v-for="(item,index) in data.multiList" :key="index" style="margin-left: 15px;margin-top: 10px"> + <div style="display: flex;flex-direction: column;"> + <div style="margin-top: 10px;display: flex;align-items: center"> + <span style="font-size: 15px">{{data.singleList.length + index+1}}.</span> + <span style="margin-left: 10px;font-size: 16px">{{item.title}}</span> + </div> + <div style="display: flex;margin-top: 15px;margin-left: 25px"> + <div v-for="single in item.content.items" :class="{toRed : item.studentAnswer.answerArr.includes(single.prefix)}"> + <span style="font-size: 15px;margin-right: 5px">{{single.prefix}}.</span> + <span style="font-size: 15px;margin-right: 20px">{{single.content}}</span> + </div> + </div> + <div style="display: flex;flex-direction: column;margin-left: 25px;margin-top: 20px;font-size: 14px;line-height: 25px"> + <div style="display: flex"> + <span>结果:</span> + <el-tag size="small" :type="item.studentAnswer.passed == 0 ? 'danger' :item.studentAnswer.passed == 1?'success': 'warning'">{{item.studentAnswer.passed == 0 ? '错误' :item.studentAnswer.passed == 1? '正确' :'待批改' }}</el-tag> + </div> + <span>分数:{{data.form.examPaper.multiScore}}</span> + <span>解析:{{item.content.analyze}}</span> + <span>正确答案:{{item.answer}}</span> + + </div> + <el-divider /> + </div> + </div> + </div> + </div> + <div style="display: flex;flex-direction: column;margin: 0 30px" > + <div v-if="data.judgeList && data.judgeList.length >0"> + <span style="font-size: 18px;font-weight: 600">判断题</span> + <div v-for="(item,index) in data.judgeList" :key="index" style="margin-left: 15px;margin-top: 10px"> + <div style="display: flex;flex-direction: column;"> + <div style="margin-top: 10px;display: flex;align-items: center"> + <span style="font-size: 15px">{{data.singleList.length+data.multiList.length + index+1}}.</span> + <span style="margin-left: 10px;font-size: 16px">{{item.title}}</span> + </div> + <div style="display: flex;margin-top: 15px;margin-left: 25px"> + <div v-for="single in item.content.items" :class="{toRed : item.studentAnswer.answer == single.prefix}"> + <span style="font-size: 15px;margin-right: 5px">{{single.prefix}}.</span> + <span style="font-size: 15px;margin-right: 20px">{{single.content}}</span> + </div> + </div> + <div style="display: flex;flex-direction: column;margin-left: 25px;margin-top: 20px;font-size: 14px;line-height: 25px"> + <div style="display: flex"> + <span>结果:</span> + <el-tag size="small" :type="item.studentAnswer.passed == 0 ? 'danger' :item.studentAnswer.passed == 1?'success': 'warning'">{{item.studentAnswer.passed == 0 ? '错误' :item.studentAnswer.passed == 1? '正确' :'待批改' }}</el-tag> + </div> + <span>分数:{{data.form.examPaper.judgeScore}}</span> + <span>解析:{{item.content.analyze}}</span> + <span>正确答案:{{item.answer}}</span> + </div> + <el-divider /> + </div> + </div> + </div> + </div> + <div style="display: flex;flex-direction: column;margin: 0 30px" > + <div v-if="data.easyList && data.easyList.length >0"> + <span style="font-size: 18px;font-weight: 600">简答题</span> + <div v-for="(item,index) in data.easyList" :key="index" style="margin-left: 15px;margin-top: 10px"> + <div style="display: flex;flex-direction: column;"> + <div style="margin-top: 10px;display: flex;align-items: center"> + <span style="font-size: 15px">{{data.singleList.length + data.multiList.length + data.judgeList.length + index+1}}.</span> + <span style="margin-left: 10px;font-size: 16px">{{item.title}}</span> + </div> + <div style="display: flex;margin-top: 15px;margin-left: 30px"> + <span style="font-weight: 600">{{item.studentAnswer.answer}}</span> + </div> + <div style="display: flex;flex-direction: column;margin-left: 25px;margin-top: 20px;font-size: 14px;line-height: 25px"> + <div style="display: flex"> + <span>结果:</span> + <el-tag size="small" :type="item.studentAnswer.passed == 0 ? 'danger' :item.studentAnswer.passed == 1?'success': 'warning'">{{item.studentAnswer.passed == 0 ? '错误' :item.studentAnswer.passed == 1? '正确' :'待批改' }}</el-tag> + </div> + <span>分数:{{data.form.examPaper.easyScore}}</span> + <span>解析:{{item.content.analyze}}</span> + <span>正确答案:{{item.answer}}</span> + <div style="display: flex;align-items: center;margin-top: 5px" v-if="item.studentAnswer.passed == 2"> + <span style="color: #EAB308">批改:</span> + <el-input-number v-model="item.score" :min="0" :max="data.form.examPaper.easyScore" :step="1" /> + </div> + <div style="display: flex;align-items: center;margin-top: 5px" v-else> + <span style="color: #EAB308">得分:</span> + <el-input-number v-model="item.studentAnswer.score" :min="0" :max="data.form.examPaper.easyScore" :step="1" disabled /> + </div> + + </div> + <el-divider /> + </div> + </div> + </div> + </div> + </el-card> + </div> + </div> + + </div> + </div> +</template> +<script setup> +import {onMounted, reactive, ref} from "vue"; +import Cookies from "js-cookie"; +import {useRoute, useRouter} from "vue-router"; +import {getClassification} from "@/api/onlineEducation/courseClass"; +import {ElMessage} from "element-plus"; +import {doConfirmExam, getPaperStu} from "@/api/onlineEducation/exam"; +const route = useRoute() +const router = useRouter(); + +const backValue = ref() +const data = reactive({ + queryParams: { + id: null, + paperId: null, + pageNum: 1, + pageSize: 10, + }, + form: { + id: null, + paperId: null, + studentId: null, + examPaper: {}, + questions: [], + student: {} + }, + singleList:[], + judgeList: [], + multiList:[], + easyList: [], +}); +onMounted(async ()=>{ + const val = JSON.parse(route.query.val) + backValue.value = val + data.queryParams.paperId = val.paperId + data.queryParams.id = val.id + await getStuPaper() +}) + +const getStuPaper = async () => { + const param = { + paperStudentId: data.queryParams.id + } + const res = await getPaperStu(param); + if(res.code === 200){ + data.form = res.data + data.form.totalScore = res.data.examPaper.judgeNum * res.data.examPaper.judgeScore + res.data.examPaper.multiNum * res.data.examPaper.multiScore + res.data.examPaper.singleNum * res.data.examPaper.singleScore+ res.data.examPaper.easyNum * res.data.examPaper.easyScore + reduceData(); + }else{ + ElMessage.warning(res.message) + } +} +const reduceData = () => { + let result = data.form.questions.reduce((a, b) => { + if (a[b.questionType]) { + a[b.questionType].push(b); + } else { + a[b.questionType] = [b]; + } + return a; + }, {}); + for (const resultKey in result) { + if(resultKey == 1){ + data.singleList.push(result[resultKey]) + + }else if(resultKey == 2){ + data.multiList.push(result[resultKey]) + }else if(resultKey == 3){ + data.judgeList.push(result[resultKey]) + }else { + data.easyList.push(result[resultKey]) + } + } + if(data.singleList && data.singleList.length>0){ + data.singleList = JSON.parse(JSON.stringify(data.singleList[0])).map(item => { + return { + ...item, + content: JSON.parse(item.content) + } + }) + } + if(data.judgeList && data.judgeList.length>0){ + data.judgeList = JSON.parse(JSON.stringify(data.judgeList[0])).map(item => { + return { + ...item, + content: JSON.parse(item.content), + } + }) + } + if(data.multiList && data.multiList.length>0){ + data.multiList = JSON.parse(JSON.stringify(data.multiList[0])).map(item => { + return { + ...item, + content: JSON.parse(item.content), + studentAnswer: { + answerArr:item.studentAnswer.answer?item.studentAnswer.answer.split(','):[], + answer: item.studentAnswer.answer, + id: item.studentAnswer.id, + paperId: item.studentAnswer.paperId, + passed: item.studentAnswer.passed, + questionId: item.studentAnswer.questionId, + score: item.studentAnswer.score, + studentId: item.studentAnswer.studentId, + } + } + }) + } + if(data.easyList && data.easyList.length>0){ + data.easyList = JSON.parse(JSON.stringify(data.easyList[0])).map(item => { + return { + ...item, + content: JSON.parse(item.content) + } + }) + } +} +const back = () => { + const obj = { + type: 'exam', + paperId: data.queryParams.paperId, + pageNum: backValue.value.pageNum, + pageSize: backValue.value.pageSize, + } + const v = JSON.stringify(obj) + router.push({ path: "/examStu", query: { val: v } }); +} +const submitExam = async() => { + const questions = data.easyList.map(item => { + return { + questionId: item.id, + score: item.score, + } + }) + const param = { + id:data.form.id, + paperId: data.form.paperId, + studentId: data.form.studentId, + questions: questions + } + + const res = await doConfirmExam(param); + if(res.code === 200){ + await getStuPaper() + }else{ + ElMessage.warning(res.message) + } + console.log('简答',param) + +} + +</script> + +<style scoped lang="scss"> +.app-container { + .paper-contain { + display: flex; + flex-direction: row; + //background-color: #eff3f7; + height: 100%; + } + + .paper-left { + width: 270px; + height: 100%; + + .left-content { + width: 270px; + height: 100%; + position: fixed; + z-index: 999; + } + } + + .paper-right { + flex: 1; + //background-color: #fff; + margin-left: 20px + } + + :deep(.el-tag--large) { + width: 32px + } + ::-webkit-scrollbar { + width: 5px; + height: 5px; + background-color: #e7e7e7; + opacity: 0; + } + ::-webkit-scrollbar-track { + border-radius: 10px; + background-color: #ffffff; + } + ::-webkit-scrollbar-thumb { + border-radius: 10px; + /*-webkit-box-shadow: inset 0 0 6px rgba(154,154,154,.3);*/ + background-color: #e7e7e7; + } +} +.examInfo{ + font-size: 15px; + margin-top: 20px; + display: flex; + flex-direction: column; + line-height: 25px; +} +.toRed{ + color: #3b4cf6; +} +</style> diff --git a/src/views/onlineEducation/groupExams/components/examDialog.vue b/src/views/onlineEducation/groupExams/components/examDialog.vue index ba9aa9c..96a6fb0 100644 --- a/src/views/onlineEducation/groupExams/components/examDialog.vue +++ b/src/views/onlineEducation/groupExams/components/examDialog.vue @@ -151,8 +151,49 @@ </el-radio-group> </div> </div> + <div style="display: flex"> + <div class="group"> + <div> + 简答:<el-input style="max-width: 40px" v-model="state.form.easyNum"></el-input> 题 + </div> + <div style="margin-left: 20px"> + 每题:<el-input style="max-width: 40px" v-model="state.form.easyScore"></el-input> 分 + </div> + </div> + <div class="group" > + <div> + 共 + <span style="max-width: 30px" v-show="state.form.easyNum && state.form.easyScore">{{state.form.easyNum * state.form.easyScore}}</span> + <!-- <span v-else></span>--> + 分 + </div> + <el-select + clearable + v-model="state.form.easyBankId" + style="width: 160px;margin: 0 20px" + v-loadMoreNew:[reselectSingle]="handleScroll" + :popper-class="reselectSingle.name" + class="item-width" + placeholder="请选择简答题题库" + > + <el-option + v-for="item in state.bankListSingle" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + <el-radio-group v-model="state.form.easyMethod" > + <el-radio :label="1" style="max-width: 30px">随机</el-radio> + <el-radio :label="2" style="max-width: 30px">顺序</el-radio> + </el-radio-group> + <el-radio-group v-model="state.form.easyRebuild" style="margin-left: 30px" > + <el-radio :label="1" v-if="title === '编辑'" style="max-width: 30px">重新出题</el-radio> + </el-radio-group> + </div> + </div> <span class="group" style="margin-bottom: 20px">共计: - {{state.form.judgeNum * state.form.judgeScore+state.form.multiNum * state.form.multiScore+state.form.singleNum * state.form.singleScore}} + {{state.form.judgeNum * state.form.judgeScore+state.form.multiNum * state.form.multiScore+state.form.singleNum * state.form.singleScore+state.form.easyNum * state.form.easyScore}} 分</span> <div style="display: flex;justify-content: space-between;align-items: center"> <el-form-item label="合格分数:" prop="passScore"> @@ -273,10 +314,15 @@ limited: 1, limitTime: null, passScore: null, - judgeRebuild: 0, - multiRebuild: 0, - singleRebuild: 0, - deadline: '' + judgeRebuild: null, + multiRebuild: null, + singleRebuild: null, + easyRebuild: null, + deadline: '', + easyNum: null, + easyScore: null, + easyBankId: null, + easyMethod: 1, }, formRules: { @@ -315,6 +361,14 @@ title.value = type === 'addFirst' || type === 'add' ? '新增' : type ==='edit' ? '编辑' : '' ; if(type === 'edit') { state.form = value + state.form.easyNum = state.form.easyNum ? state.form.easyNum: null + state.form.easyScore = state.form.easyScore ? state.form.easyScore: null + state.form.singleNum = state.form.singleNum ? state.form.singleNum: null + state.form.singleScore = state.form.singleScore ? state.form.singleScore: null + state.form.multiNum = state.form.multiNum ? state.form.multiNum: null + state.form.multiScore = state.form.multiScore ? state.form.multiScore: null + state.form.judgeNum = state.form.judgeNum ? state.form.judgeNum: null + state.form.judgeScore = state.form.judgeScore ? state.form.judgeScore: null startUsername.value = value.name; }else if(type === 'add' && value ){ state.form.parentId = value.id @@ -330,7 +384,7 @@ // }); // return; // } - const total = state.form.judgeNum * state.form.judgeScore+state.form.multiNum * state.form.multiScore+state.form.singleNum * state.form.singleScore + const total = state.form.judgeNum * state.form.judgeScore+state.form.multiNum * state.form.multiScore+state.form.singleNum * state.form.singleScore+state.form.easyNum * state.form.easyScore if(state.form.passScore > total){ ElMessage({ type: 'warning', @@ -338,13 +392,13 @@ }); return; } - if(!(state.form.judgeBankId || state.form.multiBankId || state.form.singleBankId)){ - ElMessage({ - type: 'warning', - message: '请选择题库' - }); - return; - } + // if(!(state.form.judgeBankId || state.form.multiBankId || state.form.singleBankId)){ + // ElMessage({ + // type: 'warning', + // message: '请选择题库' + // }); + // return; + // } const valid = await busRef.value.validate(); if(valid){ if(title.value === '新增'){ @@ -447,9 +501,14 @@ limited: 1, limitTime: null, passScore: null, - judgeRebuild: 0, - multiRebuild: 0, - singleRebuild: 0, + judgeRebuild: null, + multiRebuild: null, + singleRebuild: null, + easyRebuild: null, + easyNum: null, + easyScore: null, + easyBankId: null, + easyMethod: 1, deadline: '' } state.bankListSingle = []; diff --git a/src/views/onlineEducation/groupExams/components/student.vue b/src/views/onlineEducation/groupExams/components/student.vue index 6489d7f..5707369 100644 --- a/src/views/onlineEducation/groupExams/components/student.vue +++ b/src/views/onlineEducation/groupExams/components/student.vue @@ -13,9 +13,9 @@ <el-form-item label="学生姓名:" > <el-input v-model="data.queryParams.studentName" placeholder="请输入学生姓名"></el-input> </el-form-item> - <el-form-item label="考试是否完成:" > + <el-form-item label="试卷状态:" > <el-select - v-model="data.queryParams.completed" + v-model="data.queryParams.state" class="w100" style="max-width: 180px" clearable @@ -70,23 +70,29 @@ <span>{{scope.row.student.phone}}</span> </template> </el-table-column> - <el-table-column label="考试是否完成" prop="completed" align="center" > + <el-table-column label="试卷状态" prop="state" align="center" > <template #default="scope"> - <span>{{scope.row.completed ===0 ? '未完成' : '已完成'}}</span> + <span>{{scope.row.state ===0 ? '待考试' : scope.row.state ===1 ? '待批阅':'批阅完成'}}</span> </template> </el-table-column> +<!-- <el-table-column label="考试是否完成" prop="completed" align="center" >--> +<!-- <template #default="scope">--> +<!-- <span>{{scope.row.completed ===0 ? '未完成' : '已完成'}}</span>--> +<!-- </template>--> +<!-- </el-table-column>--> <el-table-column label="成绩" prop="score" align="center" > <template #default="scope"> - <span>{{scope.row.completed ===0 ? '--' : scope.row.score}}</span> + <span>{{scope.row.state ===0 ? '--' : scope.row.score}}</span> </template> </el-table-column> <el-table-column label="是否合格" prop="passed" align="center" > <template #default="scope"> - <span>{{scope.row.completed ===0 ? '--' : scope.row.passed === 0 ? '不合格' : '合格'}}</span> + <span>{{scope.row.state ===0 ? '--' : scope.row.passed === 0 ? '不合格' : '合格'}}</span> </template> </el-table-column> <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180"> <template #default="scope"> + <el-button link type="primary" @click="correct(scope.row)" v-if="scope.row.state != 0">批阅</el-button> <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> </template> </el-table-column> @@ -124,7 +130,7 @@ queryParams: { paperId: null, studentName: '', - completed: null, + state: null, pageNum: 1, pageSize: 10, }, @@ -134,13 +140,17 @@ chooseStu: [], completeList: [ { - id: 1, - name: '是' + id: 0, + name: '待考试' }, { - id: 0, - name: '否' - } + id: 1, + name: '待批阅' + }, + { + id: 2, + name: '批阅完成' + }, ] }); @@ -150,6 +160,18 @@ const backValue = ref() onMounted(async ()=>{ + if(route.query.val){ + const val = JSON.parse(route.query.val) + if(val.type == 'index'){ + data.queryParams.pageNum = val.pageNum; + data.queryParams.pageSize = val.pageSize; + data.queryParams.paperId = val.id + }else { + data.queryParams.paperId = val.paperId + data.queryParams.pageNum = val.pageNum; + data.queryParams.pageSize = val.pageSize; + } + } const userInfo = JSON.parse(Cookies.get('userInfo')) console.log("userInfo",userInfo) if(userInfo.userType === 0){ @@ -157,10 +179,6 @@ }else { data.isAdmin = false; } - const val = JSON.parse(route.query.val) - backValue.value = val - // data.queryParams.pageId = val.id - data.queryParams.paperId = val.id await getList() }) onUnmounted(()=>{ @@ -175,8 +193,9 @@ // router.push("/group"); const obj = { - pageNum: backValue.value.pageNum, - pageSize: backValue.value.pageSize, + + pageNum: data.queryParams.pageNum, + pageSize: data.queryParams.pageSize, } const v = JSON.stringify(obj) router.push({ path: "/group", query: { val: v } }); @@ -202,7 +221,7 @@ data.queryParams = { paperId: data.queryParams.paperId, studentName: '', - completed: null, + state: null, pageNum: 1, pageSize: 10, } @@ -213,6 +232,17 @@ console.log("选中的行", val) data.chooseStu = val.map(item => item.id) } + +const correct = (val) => { + const obj = { + id: val.id, + paperId: data.queryParams.paperId, + pageNum: data.queryParams.pageNum, + pageSize: data.queryParams.pageSize, + } + const v = JSON.stringify(obj) + router.push({ path: "/correctExam", query: { val: v } }); +} const handleDelete = (val) => { ElMessageBox.confirm( '确定删除此条数据?', diff --git a/src/views/onlineEducation/groupExams/components/viewExamQuestion.vue b/src/views/onlineEducation/groupExams/components/viewExamQuestion.vue index d8f6051..36d6a69 100644 --- a/src/views/onlineEducation/groupExams/components/viewExamQuestion.vue +++ b/src/views/onlineEducation/groupExams/components/viewExamQuestion.vue @@ -69,6 +69,20 @@ </div> </div> </div> + <div style="display: flex;flex-direction: column;margin: 0 30px" > + <div v-if="state.easyList && state.easyList.length >0"> + <span style="font-size: 18px;font-weight: 600">简答</span> + <div v-for="(item,index) in state.easyList" :key="index" style="margin-left: 15px;margin-top: 10px"> + <div style="display: flex;flex-direction: column;"> + <div style="margin-top: 10px;display: flex"> + <span style="font-size: 15px">题目{{index+1}}:</span> + <span style="margin-left: 10px;font-size: 16px">{{item.title}}</span> + </div> + <el-divider /> + </div> + </div> + </div> + </div> </el-card> </el-dialog> </div> @@ -76,6 +90,7 @@ <script setup> import {reactive, ref, toRefs} from 'vue' import {ElMessage} from "element-plus"; +import {getPaper} from "@/api/onlineEducation/exam"; const dialogVisible = ref(false); const title = ref(""); const busRef = ref(); @@ -94,55 +109,79 @@ questionList: [], singleList:[], judgeList: [], - multiList:[] + multiList:[], + easyList: [] }) const openDialog = async (value) => { -console.log('111',value) + console.log('111',value) dialogVisible.value = true; - let result = value.questions.reduce((a, b) => { - if (a[b.questionType]) { - a[b.questionType].push(b); - } else { - a[b.questionType] = [b]; - } - return a; - }, {}); - for (const resultKey in result) { - if(resultKey == 1){ - state.singleList.push(result[resultKey]) + const res = await getPaper(value.id) + if(res.code == 200){ + let result = res.data.questions.reduce((a, b) => { + if (a[b.questionType]) { + a[b.questionType].push(b); + } else { + a[b.questionType] = [b]; + } + return a; + }, {}); + for (const resultKey in result) { + if(resultKey == 1){ + state.singleList.push(result[resultKey]) - }else if(resultKey == 2){ - state.multiList.push(result[resultKey]) - }else { - state.judgeList.push(result[resultKey]) + }else if(resultKey == 2){ + state.multiList.push(result[resultKey]) + }else if(resultKey == 3){ + state.judgeList.push(result[resultKey]) + }else { + state.easyList.push(result[resultKey]) + } } + if(state.singleList && state.singleList.length>0){ + state.singleList = JSON.parse(JSON.stringify(state.singleList[0])).map(item => { + return { + ...item, + content: JSON.parse(item.content) + } + }) + } + if(state.judgeList && state.judgeList.length>0){ + state.judgeList = JSON.parse(JSON.stringify(state.judgeList[0])).map(item => { + return { + ...item, + content: JSON.parse(item.content) + } + }) + } + if(state.multiList && state.multiList.length>0){ + state.multiList = JSON.parse(JSON.stringify(state.multiList[0])).map(item => { + return { + ...item, + content: JSON.parse(item.content) + } + }) + } + if(state.easyList && state.easyList.length>0){ + state.easyList = JSON.parse(JSON.stringify(state.easyList[0])).map(item => { + return { + ...item, + content: JSON.parse(item.content) + } + }) + } + }else{ + ElMessage.warning(res.message) } - state.singleList = JSON.parse(JSON.stringify(state.singleList[0])).map(item => { - return { - ...item, - content: JSON.parse(item.content) - } - }) - state.judgeList = JSON.parse(JSON.stringify(state.judgeList[0])).map(item => { - return { - ...item, - content: JSON.parse(item.content) - } - }) - state.multiList = JSON.parse(JSON.stringify(state.multiList[0])).map(item => { - return { - ...item, - content: JSON.parse(item.content) - } - }) - console.log('state.singleList',state.singleList) + + console.log('state.singleList',state.multiList) } const handleClose = () => { state.singleList = []; state.multiList = []; state.judgeList = []; + state.easyList = []; dialogVisible.value = false; emit("getList") diff --git a/src/views/onlineEducation/groupExams/index.vue b/src/views/onlineEducation/groupExams/index.vue index 3b89be8..96c9c6b 100644 --- a/src/views/onlineEducation/groupExams/index.vue +++ b/src/views/onlineEducation/groupExams/index.vue @@ -61,7 +61,7 @@ </el-table-column> <el-table-column label="合格分/总分" prop="" align="center" width="120" > <template #default="scope"> - <span>{{scope.row.passScore}}/{{scope.row.judgeNum * scope.row.judgeScore + scope.row.multiNum * scope.row.multiScore + scope.row.singleNum * scope.row.singleScore}}</span> + <span>{{scope.row.passScore}}/{{scope.row.judgeNum * scope.row.judgeScore + scope.row.multiNum * scope.row.multiScore + scope.row.singleNum * scope.row.singleScore+ scope.row.easyNum * scope.row.easyScore}}</span> </template> </el-table-column> <el-table-column label="合格率" prop="passRate" align="center" /> @@ -215,7 +215,8 @@ const obj = { pageNum: data.queryParams.pageNum, pageSize: data.queryParams.pageSize, - id: val.id + id: val.id, + type: 'index' } // val.pageNum = data.queryParams.pageNum; // val.pageSize = data.queryParams.pageSize diff --git a/src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue b/src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue index 96c48aa..941c5cc 100644 --- a/src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue +++ b/src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue @@ -3,7 +3,7 @@ <el-dialog v-model="dialogVisible" :title="title" - width="50%" + width="750px" :before-close="handleClose" :close-on-press-escape="false" :close-on-click-modal="false" @@ -22,13 +22,16 @@ </el-form-item> <el-form-item label="归属题库:" prop="bankName"> <el-select + clearable v-model="state.form.bankName" + filterable + remote + reserve-keyword + placeholder="请输入题库名称" + remote-show-suffix + :remote-method="getBankList" style="width: 100%" - v-loadMoreNew:[reselect]="handleScroll" - :popper-class="reselect.name" @change="selectValue" - class="item-width" - placeholder="请选择题库" > <el-option v-for="item in state.bankList" @@ -37,13 +40,29 @@ :value="item.name" /> </el-select> +<!-- <el-select--> +<!-- v-model="state.form.bankName"--> +<!-- style="width: 100%"--> +<!-- v-loadMoreNew:[reselect]="handleScroll"--> +<!-- :popper-class="reselect.name"--> +<!-- @change="selectValue"--> +<!-- class="item-width"--> +<!-- placeholder="请选择题库"--> +<!-- >--> +<!-- <el-option--> +<!-- v-for="item in state.bankList"--> +<!-- :key="item.id"--> +<!-- :label="item.name"--> +<!-- :value="item.name"--> +<!-- />--> +<!-- </el-select>--> </el-form-item> <el-form-item label="题目内容:" prop="title"> <el-input v-model.trim="state.form.title" type="textarea" placeholder="请输入题目内容"></el-input> </el-form-item> - <el-form-item label="选项:" prop="content"> + <el-form-item label="选项:" prop="content" v-if="state.form.questionType != 4"> <div style="display: flex;flex-direction: column;width: 100%"> - <el-button :disabled="state.form.questionType ===3" type="primary" @click="addOption" size="default" style="width: 65px;margin-bottom: 15px">添加</el-button> + <el-button :disabled="state.form.questionType ===3 || state.form.questionType==null " type="primary" @click="addOption" size="default" style="width: 65px;margin-bottom: 15px">添加</el-button> <div v-for="(item,index) in state.optionItem.items" :key="index" style="width: 100%"> <div style="display: flex;align-items: center"> <span>{{String.fromCharCode(index + 65)}}</span> @@ -53,9 +72,7 @@ </div> </div> </el-form-item> - <el-form-item label="解析:" > - <el-input type="textarea" v-model="state.optionItem.analyze" placeholder="请输入题目解析" style="width: 100%;margin-bottom: 10px"></el-input> - </el-form-item> + <el-form-item label="正确答案:" prop="answer"> <el-radio-group v-model="state.form.answer" v-if="state.form.questionType === 1 || state.form.questionType === 3"> <div v-for="(item,index) in state.optionItem.items"> @@ -67,6 +84,10 @@ <el-checkbox :label="String.fromCharCode(index + 65)" style="margin-left: 20px;">{{String.fromCharCode(index + 65)}}</el-checkbox> </div> </el-checkbox-group> + <el-input v-if="state.form.questionType === 4" v-model="state.form.answer" type="textarea" placeholder="请输入正确答案"></el-input> + </el-form-item> + <el-form-item label="解析:" > + <el-input type="textarea" v-model="state.optionItem.analyze" placeholder="请输入题目解析" style="width: 100%;margin-bottom: 10px"></el-input> </el-form-item> </el-form> <template #footer> @@ -138,6 +159,10 @@ { id: 3, name: '判断题' + }, + { + id: 4, + name: '简答题' } ], optionItem: { @@ -177,7 +202,7 @@ console.log(" state.optionItem.items.", state.optionItem.items) } const openDialog = async (type, value) => { - await loadMoreBankData(); + await getBankList(''); const userInfo = JSON.parse(Cookies.get('userInfo')) console.log("userInfo",userInfo) if(userInfo.userType === 0){ @@ -203,6 +228,32 @@ } } dialogVisible.value = true; +} + +const getBankList = async (val)=>{ + if(val != ""){ + const queryParams = { + name: val + } + const res = await getQuestionBank(queryParams) + if (res.code == 200) { + state.bankList = res.data.list + + } else { + ElMessage.warning(res.message) + } + }else { + const queryParams = { + pageNum: 1, + pageSize: 10 + } + const res = await getQuestionBank(queryParams) + if (res.code == 200) { + state.bankList = res.data.list + } else { + ElMessage.warning(res.message) + } + } } const handleScroll = () => { @@ -232,20 +283,26 @@ if(valid){ if(title.value === '新增'){ const {id,bankName, ...data} = JSON.parse(JSON.stringify(state.form)) - data.answer = data.questionType === 1 || data.questionType === 3 ? data.answer : state.checkList.join(',') - // data.content = data.questionType === 1 ? JSON.stringify(state.singleQuestion) : data.questionType === 2 ? JSON.stringify(state.multiQuestion) : JSON.stringify(state.judgeQuestion) - const options = state.optionItem.items.map((op,index) => { - return { - prefix: String.fromCharCode(index + 65), - content: op.content, - } - }) - data.content = JSON.stringify( - { - analyze: state.optionItem.analyze, - items: options + data.answer = data.questionType === 1 || data.questionType === 3 || data.questionType === 4? data.answer : state.checkList.join(',') + if(data.questionType !== 4){ + const options = state.optionItem.items.map((op,index) => { + return { + prefix: String.fromCharCode(index + 65), + content: op.content, } - ) + }) + data.content = JSON.stringify( + { + analyze: state.optionItem.analyze, + items: options + } + ) + }else { + data.content = JSON.stringify( + { + analyze: state.optionItem.analyze, + }) + } console.log('state.form',data) const res = await addQuestion(data) if(res.code === 200){ @@ -262,20 +319,26 @@ dialogVisible.value = false; }else if(title.value === '编辑'){ const {bankName,...data} = JSON.parse(JSON.stringify(state.form)) - data.answer = data.questionType === 1 || data.questionType === 3 ? data.answer : state.checkList.join(',') - // data.content = data.questionType === 1 ? JSON.stringify(state.singleQuestion) : data.questionType === 2 ? JSON.stringify(state.multiQuestion) : JSON.stringify(state.judgeQuestion) - const options = state.optionItem.items.map((op,index) => { - return { - prefix: String.fromCharCode(index + 65), - content: op.content, - } - }) - data.content = JSON.stringify( - { - analyze: state.optionItem.analyze, - items: options + data.answer = data.questionType === 1 || data.questionType === 3 || data.questionType === 4 ? data.answer : state.checkList.join(',') + if(data.questionType !== 4){ + const options = state.optionItem.items.map((op,index) => { + return { + prefix: String.fromCharCode(index + 65), + content: op.content, } - ) + }) + data.content = JSON.stringify( + { + analyze: state.optionItem.analyze, + items: options + } + ) + }else { + data.content = JSON.stringify( + { + analyze: state.optionItem.analyze, + }) + } const res = await editQuestion(data) if(res.code === 200){ ElMessage({ @@ -293,6 +356,10 @@ } } const changeType = () => { + state.optionItem = { + analyze: '', + items: [] + } if(state.form.questionType === 3) { state.optionItem.items = [ { @@ -307,6 +374,7 @@ ] } + } const handleClose = () => { busRef.value.clearValidate(); diff --git a/src/views/onlineEducation/questionBankManagement/questionManage/index.vue b/src/views/onlineEducation/questionBankManagement/questionManage/index.vue index 15d422b..de18c69 100644 --- a/src/views/onlineEducation/questionBankManagement/questionManage/index.vue +++ b/src/views/onlineEducation/questionBankManagement/questionManage/index.vue @@ -36,10 +36,9 @@ filterable remote reserve-keyword - placeholder="请选择题库" + placeholder="请输入题库名称" remote-show-suffix :remote-method="getBankList" - :loading="loading" style="width: 200px" > <el-option @@ -79,7 +78,7 @@ <el-table-column label="所属题库" prop="bankName" align="center" /> <el-table-column label="题目类型" prop="questionType" align="center" > <template #default="scope"> - <span>{{scope.row.questionType === 1 ? '单选题' : scope.row.questionType === 2 ? '多选题' : '判断题'}}</span> + <span>{{scope.row.questionType === 1 ? '单选题' : scope.row.questionType === 2 ? '多选题' : scope.row.questionType === 3 ? '判断题': '简答题'}}</span> </template> </el-table-column> <el-table-column label="题目内容" prop="title" align="center" /> @@ -139,6 +138,10 @@ { id: 3, name: '判断题' + }, + { + id: 4, + name: '简答题' } ], bankList: [], @@ -205,27 +208,23 @@ // } const getBankList = async (val)=>{ if(val != ""){ - loading.value = true; const queryParams = { name: val } const res = await getQuestionBank(queryParams) if (res.code == 200) { - loading.value = false; data.bankList = res.data.list } else { ElMessage.warning(res.message) } }else { - loading.value = true; const queryParams = { pageNum: 1, pageSize: 10 } const res = await getQuestionBank(queryParams) if (res.code == 200) { - loading.value = false; data.bankList = res.data.list } else { ElMessage.warning(res.message) -- Gitblit v1.9.2