New file |
| | |
| | | import { post } from '@/utils/request' |
| | | |
| | | export default { |
| | | page: query => post('/api/admin/examPaperAnswer/page', query), |
| | | pageExamPaper: query => post('/api/admin/examPaperAnswer/pageExamPaper', query), |
| | | read: id => post('/api/admin/examPaperAnswer/read/' + id) |
| | | } |
New file |
| | |
| | | <template> |
| | | <div v-loading="qLoading" style="line-height:1.8"> |
| | | <div v-if="qType == 1 || qType == 2 || qType == 3 || qType == 4 || qType == 5"> |
| | | <div v-if="qType == 1"> |
| | | <div class="q-title" v-html="question.title" /> |
| | | <div class="q-content"> |
| | | <el-radio-group v-model="answer.content"> |
| | | <el-radio v-for="item in question.items" :key="item.prefix" :label="item.prefix"> |
| | | <span class="question-prefix">{{ item.prefix }}.</span> |
| | | <span v-html="item.content" class="q-item-span-content"></span> |
| | | </el-radio> |
| | | </el-radio-group> |
| | | </div> |
| | | </div> |
| | | <div v-else-if="qType == 2"> |
| | | <div class="q-title" v-html="question.title" /> |
| | | <div class="q-content"> |
| | | <el-checkbox-group v-model="answer.contentArray"> |
| | | <el-checkbox v-for="item in question.items" :label="item.prefix" :key="item.prefix"> |
| | | <span class="question-prefix">{{ item.prefix }}.</span> |
| | | <span v-html="item.content" class="q-item-span-content"></span> |
| | | </el-checkbox> |
| | | </el-checkbox-group> |
| | | </div> |
| | | </div> |
| | | <div v-else-if="qType == 3"> |
| | | <div class="q-title" v-html="question.title" style="display: inline;margin-right: 10px" /> |
| | | <span style="padding-right: 10px;">(</span> |
| | | <el-radio-group v-model="answer.content"> |
| | | <el-radio v-for="item in question.items" :key="item.prefix" :label="item.prefix"> |
| | | <span v-html="item.content" class="q-item-span-content"></span> |
| | | </el-radio> |
| | | </el-radio-group> |
| | | <span style="padding-left: 10px;">)</span> |
| | | </div> |
| | | <div v-else-if="qType == 4"> |
| | | <div class="q-title" v-html="question.title" /> |
| | | <div v-if="answer.contentArray !== null"> |
| | | <el-form-item :label="item.prefix" :key="item.prefix" v-for="item in question.items" label-width="50px" |
| | | style="margin-top: 10px;margin-bottom: 10px;"> |
| | | <el-input v-model="answer.contentArray[item.prefix - 1]" /> |
| | | </el-form-item> |
| | | </div> |
| | | </div> |
| | | <div v-else-if="qType == 5"> |
| | | <div class="q-title" v-html="question.title" /> |
| | | <div> |
| | | <el-input v-model="answer.content" type="textarea" rows="5"></el-input> |
| | | </div> |
| | | </div> |
| | | <div class="question-answer-show-item" style="margin-top: 15px"> |
| | | <span class="question-show-item">结果:</span> |
| | | <el-tag :type="doRightTagFormatter(answer.doRight)"> |
| | | {{ doRightTextFormatter(answer.doRight) }} |
| | | </el-tag> |
| | | </div> |
| | | <div class="question-answer-show-item"> |
| | | <span class="question-show-item">分数:</span> |
| | | <span>{{ question.score }}</span> |
| | | </div> |
| | | <div class="question-answer-show-item"> |
| | | <span class="question-show-item">难度:</span> |
| | | <el-rate disabled v-model="question.difficult" class="question-show-item"></el-rate> |
| | | </div> |
| | | <br /> |
| | | <div class="question-answer-show-item" style="line-height: 1.8"> |
| | | <span class="question-show-item">解析:</span> |
| | | <span v-html="question.analyze" class="q-item-span-content" /> |
| | | </div> |
| | | <div class="question-answer-show-item"> |
| | | <span class="question-show-item">正确答案:</span> |
| | | <span v-if="qType == 1 || qType == 2 || qType == 5" v-html="question.correct" class="q-item-span-content" /> |
| | | <span v-if="qType == 3" v-html="trueFalseFormatter(question)" class="q-item-span-content" /> |
| | | <span v-if="qType == 4">{{ question.correctArray }}</span> |
| | | </div> |
| | | </div> |
| | | <div v-else> |
| | | </div> |
| | | </div> |
| | | |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapState, mapGetters } from 'vuex' |
| | | export default { |
| | | name: 'QuestionShow', |
| | | props: { |
| | | question: { |
| | | type: Object, |
| | | default: function () { |
| | | return {} |
| | | } |
| | | }, |
| | | answer: { |
| | | type: Object, |
| | | default: function () { |
| | | return { id: null, content: '', contentArray: [], doRight: false } |
| | | } |
| | | }, |
| | | qLoading: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | qType: { |
| | | type: Number, |
| | | default: 0 |
| | | } |
| | | }, |
| | | methods: { |
| | | trueFalseFormatter(question) { |
| | | return question.items.filter(d => d.prefix === question.correct)[0].content |
| | | }, |
| | | doRightTagFormatter(status) { |
| | | return this.enumFormat(this.doRightTag, status) |
| | | }, |
| | | doRightTextFormatter(status) { |
| | | return this.enumFormat(this.doRightEnum, status) |
| | | } |
| | | }, |
| | | computed: { |
| | | ...mapGetters('enumItem', ['enumFormat']), |
| | | ...mapState('enumItem', { |
| | | doRightEnum: state => state.exam.question.answer.doRightEnum, |
| | | doRightTag: state => state.exam.question.answer.doRightTag |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| | |
| | | component: () => import('@/views/answer/list'), |
| | | name: 'AnswerPageList', |
| | | meta: { title: '答卷列表', noCache: true } |
| | | }, |
| | | { |
| | | path: 'answer-list', |
| | | component: () => import('@/views/answer/info'), |
| | | name: 'answerList', |
| | | meta: { title: '答卷信息', noCache: true }, |
| | | hidden: true |
| | | }, |
| | | { |
| | | path: 'answer-detail', |
| | | component: () => import('@/views/answer/detail'), |
| | | name: 'answerDetail', |
| | | meta: { title: '答卷详情', noCache: true }, |
| | | hidden: true |
| | | } |
| | | ] |
| | | }, |
New file |
| | |
| | | <template> |
| | | <div style="background-color: #FFFFFF; padding-top: 50px;min-height: 900px;"> |
| | | <el-row class="do-exam-title" style="background-color: #F5F5DC"> |
| | | <el-col :span="24"> |
| | | <span :key="item.itemOrder" v-for="item in answer.answerItems"> |
| | | <el-tag :type="questionDoRightTag(item.doRight)" class="do-exam-title-tag" |
| | | @click="goAnchor('#question-' + item.itemOrder)">{{ item.itemOrder }}</el-tag> |
| | | </span> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row class="do-exam-title-hidden"> |
| | | <el-col :span="24"> |
| | | <span :key="item.itemOrder" v-for="item in answer.answerItems"> |
| | | <el-tag class="do-exam-title-tag">{{ item.itemOrder }}</el-tag> |
| | | </span> |
| | | </el-col> |
| | | </el-row> |
| | | <el-container class="app-item-contain"> |
| | | <el-header class="align-center"> |
| | | <h1>{{ form.name }}</h1> |
| | | <div> |
| | | <span class="question-title-padding">试卷得分:{{ answer.score }}</span> |
| | | <span class="question-title-padding">试卷耗时:{{ formatSeconds(answer.doTime) }}</span> |
| | | </div> |
| | | </el-header> |
| | | <el-main> |
| | | <el-form :model="form" ref="form" v-loading="formLoading" label-width="100px"> |
| | | <el-row :key="index" v-for="(titleItem, index) in form.titleItems"> |
| | | <h3>{{ titleItem.name }}</h3> |
| | | <el-card class="exampaper-item-box" v-if="titleItem.questionItems.length !== 0"> |
| | | <el-form-item :key="questionItem.itemOrder" :label="questionItem.itemOrder + '.'" |
| | | v-for="questionItem in titleItem.questionItems" class="exam-question-item" |
| | | label-width="50px" :id="'question-' + questionItem.itemOrder"> |
| | | <QuestionAnswerShow :qType="questionItem.questionType" :question="questionItem" |
| | | :answer="answer.answerItems[questionItem.itemOrder - 1]" /> |
| | | </el-form-item> |
| | | </el-card> |
| | | </el-row> |
| | | </el-form> |
| | | </el-main> |
| | | </el-container> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapState, mapGetters } from 'vuex' |
| | | import QuestionAnswerShow from '@/components/questionAnswerShow' |
| | | import examPaperAnswerApi from '@/api/examPaperAnswer' |
| | | export default { |
| | | components: { QuestionAnswerShow }, |
| | | data() { |
| | | return { |
| | | form: {}, |
| | | formLoading: false, |
| | | answer: { |
| | | id: null, |
| | | score: 0, |
| | | doTime: 0, |
| | | answerItems: [], |
| | | doRight: false |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | let id = this.$route.query.id |
| | | let _this = this |
| | | if (id && parseInt(id) !== 0) { |
| | | _this.formLoading = true |
| | | examPaperAnswerApi.read(id).then(re => { |
| | | _this.form = re.data.paper |
| | | _this.answer = re.data.answer |
| | | _this.formLoading = false |
| | | }) |
| | | } |
| | | }, |
| | | methods: { |
| | | formatSeconds(theTime) { |
| | | let theTime1 = 0 |
| | | let theTime2 = 0 |
| | | if (theTime > 60) { |
| | | theTime1 = parseInt(theTime / 60) |
| | | theTime = parseInt(theTime % 60) |
| | | if (theTime1 > 60) { |
| | | theTime2 = parseInt(theTime1 / 60) |
| | | theTime1 = parseInt(theTime1 % 60) |
| | | } |
| | | } |
| | | let result = '' + parseInt(theTime) + '秒' |
| | | if (theTime1 > 0) { |
| | | result = '' + parseInt(theTime1) + '分' + result |
| | | } |
| | | if (theTime2 > 0) { |
| | | result = '' + parseInt(theTime2) + '小时' + result |
| | | } |
| | | return result |
| | | }, |
| | | questionDoRightTag(status) { |
| | | return this.enumFormat(this.doRightTag, status) |
| | | }, |
| | | goAnchor(selector) { |
| | | this.$el.querySelector(selector).scrollIntoView({ behavior: 'instant', block: 'center', inline: 'nearest' }) |
| | | } |
| | | }, |
| | | computed: { |
| | | ...mapGetters('enumItem', ['enumFormat']), |
| | | ...mapState('enumItem', { |
| | | doRightTag: state => state.exam.question.answer.doRightTag |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .align-center { |
| | | text-align: center |
| | | } |
| | | |
| | | .exam-question-item { |
| | | padding: 10px; |
| | | |
| | | .el-form-item__label { |
| | | font-size: 15px !important; |
| | | } |
| | | } |
| | | |
| | | .question-title-padding { |
| | | padding-left: 25px; |
| | | padding-right: 25px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <!-- 答卷管理 --> |
| | | <template> |
| | | <div class="c"> |
| | | <div class="bg"> |
| | | <div class="main"> |
| | | <!-- 待返回的标题 --> |
| | | <TitleIndex title="答卷管理" /> |
| | | <div class="content"> |
| | | <!-- 搜索 --> |
| | | <div> |
| | | <el-form :inline="true" :model="queryParam" class="demo-form-inline" label-width="80px"> |
| | | <el-form-item> |
| | | <el-input v-model="queryParam.userName" placeholder="请输入用户名称" clearable></el-input> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button style="width:100px;" type="primary" size="small" @click="search()">查询</el-button> |
| | | <el-button style="width:100px;" type="danger" size="small" @click="handleExport()">导出</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <!-- 表格 --> |
| | | <el-table v-loading="listLoading" :data="tableData" border fit highlight-current-row style="width: 100%"> |
| | | <el-table-column prop="paperName" label="试卷名称" align="center" /> |
| | | <el-table-column prop="userName" label="用户名称" align="center" /> |
| | | <el-table-column label="得分" width="100px"> |
| | | <template slot-scope="{row}"> |
| | | {{ row.userScore }} / {{ row.paperScore }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="题目对错" width="100px" align="center"> |
| | | <template slot-scope="{row}"> |
| | | {{ row.questionCorrect }} / {{ row.questionCount }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="doTime" label="耗时" width="80px" align="center" /> |
| | | <el-table-column prop="createTime" label="提交时间" width="160px" align="center" /> |
| | | <el-table-column label="操作" width="200px" align="center"> |
| | | <template slot-scope="{row}"> |
| | | <el-button size="mini" @click="view(row)">详情</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" :page.sync="queryParam.pageIndex" |
| | | :limit.sync="queryParam.pageSize" @pagination="search" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <script> |
| | | // 引入彈出窗口組件 |
| | | import examPaperAnswerApi from '@/api/examPaperAnswer' |
| | | import Pagination from '@/components/Pagination' |
| | | |
| | | export default { |
| | | // 注册 |
| | | components: { |
| | | Pagination |
| | | }, |
| | | data() { |
| | | return { |
| | | listLoading: true, |
| | | queryParam: { |
| | | examPaperId: '', |
| | | userName: '', |
| | | pageIndex: 1, |
| | | pageSize: 10 |
| | | }, |
| | | formLoading: false, |
| | | total: 0, |
| | | tableData: [], |
| | | visible: false, |
| | | subjects: [] |
| | | }; |
| | | }, |
| | | created() { |
| | | this.queryParam.examPaperId = this.$route.query.id |
| | | this.search() |
| | | }, |
| | | methods: { |
| | | // 获取列表 |
| | | search() { |
| | | this.listLoading = true |
| | | examPaperAnswerApi.page(this.queryParam).then(re => { |
| | | this.tableData = re.data.list |
| | | this.total = re.data.total |
| | | this.queryParam.pageSize = re.data.pageSize |
| | | this.queryParam.pageIndex = re.data.pageNum |
| | | this.listLoading = false |
| | | }) |
| | | }, |
| | | view(row) { |
| | | this.$router.push({ path: '/answer/answer-detail', query: { id: row.id } }); |
| | | }, |
| | | handleExport() { |
| | | let that = this |
| | | let url = '/api/admin/examPaperAnswer/exportExcel?examPaperId=' + this.queryParam.examPaperId + '&userName=' + this.queryParam.userName |
| | | var x = new XMLHttpRequest(); |
| | | x.open("POST", url, true); |
| | | x.responseType = "blob"; |
| | | x.onload = function () { |
| | | var url = window.URL.createObjectURL(x.response); |
| | | var a = document.createElement("a"); |
| | | a.href = url; |
| | | a.download = that.tableData[0].paperName + '.xlsx'; |
| | | a.click(); |
| | | }; |
| | | x.send(); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | .flex { |
| | | display: flex; |
| | | } |
| | | |
| | | // 内容 |
| | | .content { |
| | | width: 1262px; |
| | | margin-bottom: 80px; |
| | | background-color: #fff; |
| | | padding: 20px 40px; |
| | | border-radius: 10px; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParam" ref="queryForm" :inline="true"> |
| | | <el-form-item label="学科:" > |
| | | <el-select v-model="queryParam.subjectId" clearable> |
| | | <el-form :inline="true" :model="queryParam" class="demo-form-inline" label-width="80px"> |
| | | <el-form-item> |
| | | <el-input v-model="queryParam.name" placeholder="请输入名称" clearable></el-input> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-select v-model="queryParam.subjectId" placeholder="请选择科目" clearable multiple @change="search"> |
| | | <el-option v-for="item in subjects" :key="item.id" :value="item.id" :label="item.name"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="submitForm">查询</el-button> |
| | | <el-button style="width:100px;" type="primary" size="small" @click="search()">查询</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-table v-loading="listLoading" :data="tableData" border fit highlight-current-row style="width: 100%"> |
| | | <el-table-column prop="id" label="Id" width="100" /> |
| | | <el-table-column prop="paperName" label="试卷名称"/> |
| | | <el-table-column prop="userName" label="用户名称"/> |
| | | <el-table-column label="得分" width="100px" > |
| | | <el-table v-loading="listLoading" :data="tableData" border style="width: 100%;"> |
| | | <el-table-column align="center" prop="paperName" label="试卷名称" /> |
| | | <el-table-column align="center" prop="subjectName" label="科目" /> |
| | | <el-table-column align="center" prop="paperType" label="试卷类型" width="150px"> |
| | | <template slot-scope="{row}"> |
| | | {{row.userScore}} / {{row.paperScore}} |
| | | <span v-if="row.paperType === 1">固定试卷</span> |
| | | <span v-if="row.paperType === 2">随机试卷</span> |
| | | <span v-if="row.paperType === 3">顺序试卷</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="题目对错" width="80px" > |
| | | <el-table-column align="center" prop="questionCount" label="题目数量" width="100px" /> |
| | | <el-table-column align="center" prop="systemScore" label="总分" width="100px" /> |
| | | <el-table-column align="center" prop="suggestTime" label="建议时长" width="100px" /> |
| | | <el-table-column align="center" prop="personAnswerNum" label="参考人数" width="100px"> |
| | | <template slot-scope="{row}"> |
| | | {{row.questionCorrect}} / {{row.questionCount}} |
| | | <span>{{ row.personAnswerNum + "/" + row.personTotalNum }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="doTime" label="耗时" width="100px"/> |
| | | <el-table-column prop="createTime" label="提交时间" width="160px"/> |
| | | <el-table-column align="center" prop="userName" label="创建人" width="100px" /> |
| | | <el-table-column label="操作" align="center"> |
| | | <template slot-scope="{row}"> |
| | | <el-button size="mini" @click="view(row)">查看</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total>0" :total="total" :page.sync="queryParam.pageIndex" :limit.sync="queryParam.pageSize" |
| | | @pagination="search"/> |
| | | <pagination v-show="total > 0" :total="total" :page.sync="queryParam.pageIndex" |
| | | :limit.sync="queryParam.pageSize" @pagination="search" /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | |
| | | import { mapGetters, mapState, mapActions } from 'vuex' |
| | | import Pagination from '@/components/Pagination' |
| | | import examPaperAnswerApi from '@/api/examPaperAnwser' |
| | | import examPaperAnswerApi from '@/api/examPaperAnswer' |
| | | |
| | | export default { |
| | | components: { Pagination }, |
| | | data () { |
| | | return { |
| | | listLoading: true, |
| | | queryParam: { |
| | | subjectId: null, |
| | | name: '', |
| | | pageIndex: 1, |
| | | pageSize: 10 |
| | | }, |
| | | listLoading: false, |
| | | formLoading: false, |
| | | total: 0, |
| | | tableData: [], |
| | | total: 0 |
| | | } |
| | | visible: false |
| | | }; |
| | | }, |
| | | created () { |
| | | this.initSubject() |
| | | this.search() |
| | | }, |
| | | methods: { |
| | | search () { |
| | | // 获取列表 |
| | | search() { |
| | | this.listLoading = true |
| | | examPaperAnswerApi.page(this.queryParam).then(data => { |
| | | const re = data.data |
| | | this.tableData = re.list |
| | | this.total = re.total |
| | | this.queryParam.pageIndex = re.pageNum |
| | | examPaperAnswerApi.pageExamPaper(this.queryParam).then(re => { |
| | | this.tableData = re.data.list |
| | | this.total = re.data.total |
| | | this.queryParam.pageSize = re.data.pageSize |
| | | this.queryParam.pageIndex = re.data.pageNum |
| | | this.listLoading = false |
| | | }) |
| | | }, |
| | | submitForm () { |
| | | this.queryParam.pageIndex = 1 |
| | | this.search() |
| | | view(row) { |
| | | this.$router.push({ path: '/answer/answer-list', query: { id: row.id } }); |
| | | }, |
| | | ...mapActions('exam', { initSubject: 'initSubject' }) |
| | | }, |