题库页面整改、文件上传

This commit is contained in:
18571350067 2021-11-09 09:14:29 +08:00
parent 20f2408aec
commit b45eddb9ee
4 changed files with 240 additions and 110 deletions

View File

@ -4,11 +4,12 @@ const questionApi = {
add: 'courseManagement/question/addOrUpdate', add: 'courseManagement/question/addOrUpdate',
get: '/courseManagement/question/details', get: '/courseManagement/question/details',
// update: 'sys/menu/update', // update: 'sys/menu/update',
del: 'courseManagement/course/delete', del: 'courseManagement/question/delete',
// updateStatus: 'sys/menu/updateStatus', // updateStatus: 'sys/menu/updateStatus',
// list: '/courseManagement/course/listPage', // list: '/courseManagement/course/listPage',
// coursewareList:'/courseManagement/course/courseware/details', // coursewareList:'/courseManagement/course/courseware/details',
// questionList:'/courseManagement/course/questionList' // questionList:'/courseManagement/course/questionList',
importTemplate: "courseManagement/question/importTemplate"
} }
@ -54,5 +55,13 @@ export function getQuestionDeatil (params) {
}) })
} }
// 题目批量导入
export function importTemplate (params) {
return request({
url: questionApi.importTemplate,
method: 'post',
params: params
})
}

View File

@ -1,7 +1,8 @@
import request from '@/utils/request' import request from '@/utils/request'
const ossApi = { const ossApi = {
list: '/sys/oss/list' list: '/sys/oss/list',
upload: '/sys/oss/upload'
} }
export function ossList (params) { export function ossList (params) {
@ -11,3 +12,7 @@ export function ossList (params) {
params: params params: params
}) })
} }
export function ossUpload () {
return process.env.VUE_APP_API_BASE_URL + ossApi.upload;
}

View File

@ -6,7 +6,7 @@
</template> </template>
<a-tabs :animated="false" :default-active-key="tabKey" @change="callback" :headStyle="{ paddingTop: '0px' }"> <a-tabs :animated="false" :default-active-key="tabKey" @change="callback" :headStyle="{ paddingTop: '0px' }">
<!-- 单选题 --> <!-- 单选题 -->
<a-tab-pane key="1" tab="单选"> <a-tab-pane key="1" tab="单选" :disabled="radio.disabled">
<a-radio-group v-model="radio.rightAnswers" style="width: 100%"> <a-radio-group v-model="radio.rightAnswers" style="width: 100%">
<a-card title="题目(题干内容)" :bordered="false"> <a-card title="题目(题干内容)" :bordered="false">
<a-textarea placeholder="" :rows="6" v-model="radio.questionName" style="width: 100%" /> <a-textarea placeholder="" :rows="6" v-model="radio.questionName" style="width: 100%" />
@ -46,7 +46,7 @@
</a-tab-pane> </a-tab-pane>
<!-- 多选题 --> <!-- 多选题 -->
<a-tab-pane key="2" tab="多选"> <a-tab-pane key="2" tab="多选" :disabled="multiselect.disabled">
<a-card title="题目(题干内容)" :bordered="false"> <a-card title="题目(题干内容)" :bordered="false">
<a-textarea placeholder="" :rows="6" v-model="multiselect.questionName" style="width: 100%" /> <a-textarea placeholder="" :rows="6" v-model="multiselect.questionName" style="width: 100%" />
</a-card> </a-card>
@ -84,7 +84,7 @@
</a-tab-pane> </a-tab-pane>
<!-- 判断题 --> <!-- 判断题 -->
<a-tab-pane key="3" tab="判断"> <a-tab-pane key="3" tab="判断" :disabled="estimate.disabled">
<a-radio-group v-model="estimate.rightAnswers" style="width: 100%"> <a-radio-group v-model="estimate.rightAnswers" style="width: 100%">
<a-card title="题目(题干内容)" :bordered="false"> <a-card title="题目(题干内容)" :bordered="false">
<a-textarea placeholder="" :rows="6" v-model="estimate.questionName" style="width: 100%" /> <a-textarea placeholder="" :rows="6" v-model="estimate.questionName" style="width: 100%" />
@ -103,7 +103,7 @@
</a-tab-pane> </a-tab-pane>
<!-- 简答题 --> <!-- 简答题 -->
<a-tab-pane key="4" tab="简答"> <a-tab-pane key="4" tab="简答" :disabled="shortAnswer.disabled">
<a-card title="题目(题干内容)" :bordered="false"> <a-card title="题目(题干内容)" :bordered="false">
<a-textarea placeholder="" :rows="6" v-model="shortAnswer.questionName" style="width: 100%" /> <a-textarea placeholder="" :rows="6" v-model="shortAnswer.questionName" style="width: 100%" />
</a-card> </a-card>
@ -117,7 +117,7 @@
</a-tab-pane> </a-tab-pane>
<!-- 填空题 --> <!-- 填空题 -->
<a-tab-pane key="5" tab="填空"> <a-tab-pane key="5" tab="填空" :disabled="Completion.disabled">
<a-card title="题目(题干内容)" :bordered="false"> <a-card title="题目(题干内容)" :bordered="false">
<a-textarea placeholder="" :rows="6" v-model="Completion.questionName" style="width: 100%" /> <a-textarea placeholder="" :rows="6" v-model="Completion.questionName" style="width: 100%" />
</a-card> </a-card>
@ -126,8 +126,8 @@
<a-button type="primary" style="width: 40%" @click="addAnswerSize">添加一个新填空</a-button> <a-button type="primary" style="width: 40%" @click="addAnswerSize">添加一个新填空</a-button>
<a-button style="width: 40%" @click="delAnswerSize">刪除一个新填空</a-button> <a-button style="width: 40%" @click="delAnswerSize">刪除一个新填空</a-button>
</div> </div>
<div v-for="(answer, index) in answerList" :key="index" style="margin-bottom: 10px"> <div v-for="(answer, index) in Completion.answerList" :key="index" style="margin-bottom: 10px">
<a-input :value="answerList[index]" @change="onChangeInput"> <a-input v-model="Completion.answerList[index]">
<template slot="addonBefore"> <template slot="addonBefore">
<b>填空{{ index+1 }}:</b> <b>填空{{ index+1 }}:</b>
</template> </template>
@ -155,21 +155,37 @@ export default {
multiselect: {}, multiselect: {},
estimate: {}, estimate: {},
shortAnswer: {}, shortAnswer: {},
answerList: ["111","222","333"], Completion: { answerList: [''] },
Completion: { },
tabKey: this.$route.query.questionType ? this.$route.query.questionType : '1' tabKey: this.$route.query.questionType ? this.$route.query.questionType : '1'
// tabKey,
} }
}, },
created() { created() {
if (this.$route.query.id) { if (this.$route.query.id && !this.$route.query.opt) {
this.radio.disabled = true;
this.multiselect.disabled = true;
this.estimate.disabled = true;
this.shortAnswer.disabled = true;
this.Completion.disabled = true;
getQuestionDeatil({ id: this.$route.query.id }).then((res) => { getQuestionDeatil({ id: this.$route.query.id }).then((res) => {
console.log(this.tabKey)
if (this.tabKey == '1') { if (this.tabKey == '1') {
this.radio = res.data this.radio = res.data;
this.radio.disabled = false;
} else if (this.tabKey == '2') { } else if (this.tabKey == '2') {
this.multiselect = res.data this.multiselect = res.data;
this.multiselect.disabled = false;
this.getRightAnswer();
} else if(this.tabKey == '3') {
this.estimate = res.data;
this.estimate.disabled = false;
} else if (this.tabKey == '4') {
this.shortAnswer = res.data;
this.shortAnswer.disabled = false;
} else if (this.tabKey == '5') {
this.Completion = res.data;
this.Completion.disabled = false;
} }
}) })
} }
@ -181,41 +197,36 @@ export default {
path: '/course/question/QuestionList', path: '/course/question/QuestionList',
query: { query: {
id: this.$route.query.courseId, id: this.$route.query.courseId,
questionId: this.$route.query.id,
isactive: this.$route.query.isactive,
}, },
}) })
}, },
// getQuestionType() {
// if (!this.$route.query.questionType || this.$route.query.questionType === '') tabKey = '1'
// tabKey = this.$route.query.questionType
// },
callback(key) { callback(key) {
this.radio = {} this.radio = {}
this.multiselect = {} this.multiselect = {}
this.estimate = {} this.estimate = {}
this.shortAnswer = {} this.shortAnswer = {}
this.Completion = { answerSize: 2 } this.Completion = { answerList: [''] }
this.tabKey = key this.tabKey = key
}, },
onChangeInput(e) {
},
// //
addAnswerSize() { addAnswerSize() {
if (this.answerList.length == 10) { if (this.Completion.answerList.length == 10) {
this.$message.error('填空数量最多不能超过10个') this.$message.error('填空数量最多不能超过10个')
return return
} }
this.answerList.push('') this.Completion.answerList.push('')
}, },
// //
delAnswerSize() { delAnswerSize() {
if (this.answerList.length == 1) { if (this.Completion.answerList.length == 1) {
this.$message.error('填空数量最少不能少于1个') this.$message.error('填空数量最少不能少于1个')
return return
} }
this.Completion.answerSize-- this.Completion.answerList.splice(this.Completion.answerList.length-1, 1);
}, },
// //
@ -368,25 +379,20 @@ export default {
this.$message.error('题干不能为空!') this.$message.error('题干不能为空!')
return false return false
} }
console.log(this.Completion.conten)
// if (!this.Completion.rightAnswers || this.Completion.rightAnswers === '') {
// this.$message.error('')
// return false
// }
// let answer =[];
// for(i in answerSize) {
// let daan ={};
// }
let tiank = this.Completion
console.log('tiank ', tiank)
let from = this.Completion let from = this.Completion
from.questionType = 5 from.questionType = 5
return from return from
}, },
//
getRightAnswer(){
if(this.multiselect.rightAnswers.indexOf('A') > -1) this.multiselect.a = true;
if(this.multiselect.rightAnswers.indexOf('B') > -1) this.multiselect.b = true;
if(this.multiselect.rightAnswers.indexOf('C') > -1) this.multiselect.c = true;
if(this.multiselect.rightAnswers.indexOf('D') > -1) this.multiselect.d = true;
console.log('1---', this.multiselect)
},
}, },
} }
</script> </script>

View File

@ -1,34 +1,77 @@
<template> <template>
<page-header-wrapper> <!-- <page-header-wrapper> -->
<a-card :bordered="false"> <a-card :bordered="false" title="题库管理">
<template slot="extra">
<a-button size="small" @click="questionColse">返回</a-button>
</template>
<div class="questionLeft"> <div class="questionLeft">
<div class="div-button">
<a-button type="primary" class="close-button" style="font-size: 15px" @click="questionColse"> 关闭 </a-button>
<a-button type="primary" class="create-button" style="font-size: 15px" @click="questionSave"> 新增 </a-button>
</div>
<h1 class="questionNumber">题序</h1> <h1 class="questionNumber">题序</h1>
<!-- 题目序号 --> <!-- 题目序号 -->
<div v-for="(item, index) in quesitonList" :key="item" class="questionLeftItem" @click="quesionId(item)"> <div
v-for="(item, index) in quesitonList"
:key="item"
class="questionLeftItem"
@click="quesionId(item, index)"
:class="{ active_color: index == isactive }"
>
{{ index + 1 }} {{ index + 1 }}
</div> </div>
</div> </div>
<div class="questionDetail"> <div class="questionDetail">
<br /> <br />
<a-button type="primary" class="create-button" style="font-size: 15px; margin:0px 10px 10px 0px" @click="questionBatch" > 批量导入 </a-button> <a-button
<a-button type="primary" class="create-button" style="font-size: 15px; margin:0px 10px 10px 0px" @click="questionBatchDownload" > 模板下载 </a-button> type="primary"
class="create-button"
style="font-size: 15px; margin: 0px 10px 10px 0px"
@click="questionSave"
>新增题目</a-button
>
<a-button
type="primary"
class="create-button"
style="font-size: 15px; margin: 0px 10px 10px 0px"
@click="questionBatch"
>
批量导入
</a-button>
<a-button
type="primary"
class="create-button"
style="font-size: 15px; margin: 0px 10px 10px 0px"
@click="questionBatchDownload"
>
模板下载
</a-button>
<b><h1 class="questionContent">课程题目库预览</h1></b> <b><h1 class="questionContent">课程题目库预览</h1></b>
<a-divider :style="{ backgroundColor: '#000' }" /> <a-divider :style="{ backgroundColor: '#000' }" />
<div class="question"> <div class="question">
<h1 class="questionName"> <h1 class="questionName">
{{ questionDetail.questionType }}{{questionDetail.questionName}} {{ questionDetail.questionTypeName }}{{ questionDetail.questionName }}
<span class="edit" @click="edit(questionDetail.id)">编辑</span> <span class="edit" @click="edit(questionDetail.id)">编辑</span>
<span class="edit" @click="del(questionDetail.id)">删除</span> <a-popconfirm title="确定要删除此题?" ok-text="确定" cancel-text="取消" @confirm="del(questionDetail.id)">
<span class="edit">删除</span>
</a-popconfirm>
</h1> </h1>
<!-- 显示单选题和多选题 -->
<div v-if="questionDetail.questionType == 1 || questionDetail.questionType == 2">
<div class="answer">A. {{ questionDetail.answerA }}</div> <div class="answer">A. {{ questionDetail.answerA }}</div>
<div class="answer">B. {{ questionDetail.answerB }}</div> <div class="answer">B. {{ questionDetail.answerB }}</div>
<div class="answer">C. {{ questionDetail.answerC }}</div> <div class="answer">C. {{ questionDetail.answerC }}</div>
<div class="answer">D. {{ questionDetail.answerD }}</div> <div class="answer">D. {{ questionDetail.answerD }}</div>
</div>
<!-- 显示简答题 -->
<div v-if="questionDetail.questionType == 4">
<div class="answer">正确答案:&nbsp;&nbsp;&nbsp;&nbsp;{{ questionDetail.rightAnswers }}</div>
</div>
<!-- 显示填空题 -->
<div v-if="questionDetail.questionType == 5">
<div class="answer" v-for="(item,ind) in questionDetail.answerList" :key="ind">正确答案{{ ind+1 }}:&nbsp;&nbsp;&nbsp;&nbsp;{{ item }}</div>
</div>
<div class="info_parent"> <div class="info_parent">
<div class="info">解析</div> <div class="info">解析</div>
<div class="info_main"> <div class="info_main">
@ -38,39 +81,58 @@
<a-divider :style="{ backgroundColor: '#000' }" /> <a-divider :style="{ backgroundColor: '#000' }" />
</div> </div>
</div> </div>
<input ref="inputFile" type="file" style="display: none;" @change="questionBatchImport">
</a-card> </a-card>
</page-header-wrapper> <!-- </page-header-wrapper> -->
</template> </template>
<script> <script>
import { getQuestionListByCourseId } from '@/api/course/course' import { getQuestionListByCourseId } from '@/api/course/course'
import { getQuestionDeatil,deleteQuestion } from '@/api/course/question/question' import { getQuestionDeatil, deleteQuestion, importTemplate } from '@/api/course/question/question'
import { ossUpload } from '@/api/sys/oss'
import axios from 'axios'
import storage from 'store'
import { ACCESS_TOKEN } from '@/store/mutation-types'
export default { export default {
data() { data() {
return { return {
quesitonList: [], quesitonList: [],
questionDetail: {}, questionDetail: {},
isactive: 1,
} }
}, },
created: function () { created: function () {
let parameter = {id : this.$route.query.id} this.getQuestion()
},
methods: {
getQuestion() {
// id // id
getQuestionListByCourseId(parameter).then((res) => { getQuestionListByCourseId({ id: this.$route.query.id }).then((res) => {
this.quesitonList = res.data this.quesitonList = res.data
if (!res.data.length) return if (!res.data) return
this.quesionId(this.quesitonList[0]) // this.quesionId(this.quesitonList[0])
this.quesionId(this.$route.query.questionId || this.quesitonList[0], this.$route.query.isactive || 0);
}) })
}, },
methods: { //ID
//ID quesionId: function (i, index) {
quesionId: function (i) { this.isactive = index;
this.questionId = i;
getQuestionDeatil({ id: i }).then((res) => { getQuestionDeatil({ id: i }).then((res) => {
this.questionDetail = res.data this.questionDetail = res.data
//
if (this.questionDetail.questionType == '1') this.questionDetail.questionTypeName = '单选题'
if (this.questionDetail.questionType == '2') this.questionDetail.questionTypeName = '多选题'
if (this.questionDetail.questionType == '3') this.questionDetail.questionTypeName = '判断题'
if (this.questionDetail.questionType == '4') this.questionDetail.questionTypeName = '简答题'
if (this.questionDetail.questionType == '5') this.questionDetail.questionTypeName = '填空题'
}) })
}, },
@ -78,36 +140,78 @@ export default {
questionColse() { questionColse() {
this.$router.push({ this.$router.push({
path: '/course/CourseList', path: '/course/CourseList',
query: { query: {},
},
}) })
}, },
questionSave() { questionSave() {
this.$router.push({ this.$router.push({
path: '/course/question/QuestionAdd', query :{ path: '/course/question/QuestionAdd',
query: {
courseId: this.$route.query.id, courseId: this.$route.query.id,
}}); isactive: this.isactive,
id: this.questionId,
opt: 'add'
},
})
}, },
edit(record) { edit(record) {
console.log(record) console.log(record)
this.$router.push({ path : '/course/question/QuestionAdd', query:{ id: record , questionType:this.questionDetail.questionType ,courseId:this.$route.query.id}}); this.$router.push({
path: '/course/question/QuestionAdd',
query: {
id: record,
isactive: this.isactive,
questionType: this.questionDetail.questionType,
courseId: this.$route.query.id
}, },
del(record){
console.log(record)
deleteQuestion({id:record}).then(res => {
if(res.code == 200) this.$refs.table.refresh(true);
}) })
},
//
del(id) {
deleteQuestion({ id: id }).then((res) => {
if (res.code == 200) this.getQuestion()
})
}, },
// //
questionBatch() { questionBatch() {
alert('批量导入') this.$refs.inputFile.click();
courseId:this.$route.query.id
}, },
questionBatchDownload(){ questionBatchImport(){
window.location.href="/dawa/sys/oss/show/20211108/2420f1de94174bb8a0fb1a2f1e9e1742.xlsx"; if(!this.$refs.inputFile.value || this.$refs.inputFile.value === '') return;
const data = new FormData();
data.append('file', this.$refs.inputFile.files[0]);
data.append('sourceId', 'questionImport');
data.append('fileType', 'excel');
const header = {};
header['Content-Type'] = 'multipart/form-data';
header[ACCESS_TOKEN] = storage.get(ACCESS_TOKEN);
axios.post(ossUpload(), data, { headers: header }).then(res => {
if(res.data.code === 200){
let params = { fileUrl: res.data.url, courseId: this.$route.query.id }
importTemplate(params).then(res1 => {
this.$refs.inputFile.value = '';
this.$message.success('题目导入成功!');
this.getQuestion()
});
}else{
this.$message.error(res.data.msg);
this.$refs.inputFile.value = '';
} }
}).catch(err => {
this.$message.error(res);
this.$refs.inputFile.value = '';
});
},
//
questionBatchDownload() {
window.location.href = '/dawa/sys/oss/show/20211108/2420f1de94174bb8a0fb1a2f1e9e1742.xlsx'
},
}, },
} }
</script> </script>
@ -128,8 +232,14 @@ export default {
border: 1px solid #000; border: 1px solid #000;
margin: 5px 5px; margin: 5px 5px;
cursor: pointer; cursor: pointer;
background-color: white;
}
.active_color {
background-color: wheat; background-color: wheat;
} }
/* wheat */
.questionDetail { .questionDetail {
width: calc(100% - 300px - 20px); width: calc(100% - 300px - 20px);
height: auto; height: auto;
@ -158,7 +268,7 @@ export default {
font-size: 23px; font-size: 23px;
font: bold; font: bold;
background-color: gainsboro; background-color: gainsboro;
margin-top: 45px; /* margin-top: 45px; */
} }
.questionContent { .questionContent {
margin-left: 10px; margin-left: 10px;