|
|
@ -38,9 +38,27 @@ |
|
|
|
</el-select> |
|
|
|
</el-select> |
|
|
|
</el-form-item> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item prop="difficult" label="试卷难度"> |
|
|
|
<el-form-item prop="difficult" label="试卷难度"> |
|
|
|
<el-select v-model="form.difficult" clearable placeholder="请选择试卷难度"> |
|
|
|
<el-select v-model="form.difficult" clearable placeholder="系统自动评估,也可手动选择"> |
|
|
|
<el-option v-for="(item, i) in difficults" :key="i" :label="item.name" :value="item.id"></el-option> |
|
|
|
<el-option v-for="(item, i) in difficults" :key="i" :label="item.name" :value="item.id"></el-option> |
|
|
|
</el-select> |
|
|
|
</el-select> |
|
|
|
|
|
|
|
<el-tooltip placement="top"> |
|
|
|
|
|
|
|
<div class="diff-text" slot="content"> |
|
|
|
|
|
|
|
<p>基础题:难度系数0.2</p> |
|
|
|
|
|
|
|
<p>普通题:难度系数0.4</p> |
|
|
|
|
|
|
|
<p>较难题:难度系数0.6</p> |
|
|
|
|
|
|
|
<p>困难题:难度系数0.8</p> |
|
|
|
|
|
|
|
<p>(1)<span class="em">题型难度系数</span>=对应题型所有试题的难度系数之和/总试题数</p> |
|
|
|
|
|
|
|
<p>(2)<span class="em">试卷总难度系数</span>=所有试题的难度系数之和/总试题数</p> |
|
|
|
|
|
|
|
<p>(3)<span class="em">难度系数评价</span>:</p> |
|
|
|
|
|
|
|
<div class="coe"> |
|
|
|
|
|
|
|
<p>简单:系数 <=0.3</p> |
|
|
|
|
|
|
|
<p>普通:0.3<系数<=0.4</p> |
|
|
|
|
|
|
|
<p>较难:0.4<系数<0.5</p> |
|
|
|
|
|
|
|
<p>困难:系数>=0.5</p> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<i class="el-icon-question m-l-10" style="font-size: 16px;color: #8f8f8f;cursor: pointer;"></i> |
|
|
|
|
|
|
|
</el-tooltip> |
|
|
|
</el-form-item> |
|
|
|
</el-form-item> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<el-form-item prop="remarks" label="试卷说明"> |
|
|
|
<el-form-item prop="remarks" label="试卷说明"> |
|
|
@ -113,12 +131,13 @@ |
|
|
|
<div :class="['ques-wrap', { hide: item.shrink }]"> |
|
|
|
<div :class="['ques-wrap', { hide: item.shrink }]"> |
|
|
|
<div v-for="(ques, j) in item.examQuestions" :key="j" class="ques-item"> |
|
|
|
<div v-for="(ques, j) in item.examQuestions" :key="j" class="ques-item"> |
|
|
|
<el-checkbox v-model="ques.check"></el-checkbox> |
|
|
|
<el-checkbox v-model="ques.check"></el-checkbox> |
|
|
|
<div class="ques-info"> |
|
|
|
<div :class="['ques-info', { disabled: !ques.status, del: ques.isDel, repeat: ques.isRepeat }]"> |
|
|
|
<div class="top-line"> |
|
|
|
<div class="top-line"> |
|
|
|
<span class="label">{{ j + 1 }} / 10</span> |
|
|
|
<span class="label">{{ j + 1 }} / 10</span> |
|
|
|
<span class="label">{{ questionTypes.find(e => e.id === item.questionType).name }}</span> |
|
|
|
<span class="label">{{ questionTypes.find(e => e.id === item.questionType).name }}</span> |
|
|
|
<div v-html="ques.stem"></div> |
|
|
|
<div v-html="ques.stem"></div> |
|
|
|
<p>(<el-input class="score" placeholder="请输入" v-model="ques.score" />分)</p> |
|
|
|
<p v-if="ques.questionType !== 'fill_blank'">(<el-input class="score" placeholder="请输入" |
|
|
|
|
|
|
|
v-model="ques.score" />分)</p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<!-- 单选、多选、判断的选项 --> |
|
|
|
<!-- 单选、多选、判断的选项 --> |
|
|
@ -140,7 +159,7 @@ |
|
|
|
<span>排序</span> |
|
|
|
<span>排序</span> |
|
|
|
<el-input class="score" v-model="ques.serialNumber" /> |
|
|
|
<el-input class="score" v-model="ques.serialNumber" /> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<el-button type="text">编辑试题</el-button> |
|
|
|
<el-button type="text" @click="toQues(item, j, ques)">编辑试题</el-button> |
|
|
|
<el-button type="text" @click="showManualDia(item, j, ques)">更换试题</el-button> |
|
|
|
<el-button type="text" @click="showManualDia(item, j, ques)">更换试题</el-button> |
|
|
|
<el-button type="text" @click="showManualDia(item, j)">添加试题</el-button> |
|
|
|
<el-button type="text" @click="showManualDia(item, j)">添加试题</el-button> |
|
|
|
<el-button type="text" @click="delQues(item, j)">移除试题</el-button> |
|
|
|
<el-button type="text" @click="delQues(item, j)">移除试题</el-button> |
|
|
@ -163,6 +182,7 @@ |
|
|
|
<Template :visible.sync="templateVisible" /> |
|
|
|
<Template :visible.sync="templateVisible" /> |
|
|
|
<Manual :visible.sync="manualVisible" :questionType.sync="curType.questionType" /> |
|
|
|
<Manual :visible.sync="manualVisible" :questionType.sync="curType.questionType" /> |
|
|
|
<Auto :visible.sync="autoVisible" /> |
|
|
|
<Auto :visible.sync="autoVisible" /> |
|
|
|
|
|
|
|
<Detail :visible.sync="quesVisible" :row.sync="curRow" :detailType.sync="detailType" @updateQues="updateQues" /> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
<script> |
|
|
|
<script> |
|
|
@ -171,24 +191,18 @@ import Util from '@/libs/util' |
|
|
|
import dayjs from 'dayjs' |
|
|
|
import dayjs from 'dayjs' |
|
|
|
import Ueditor from '@/components/ueditor' |
|
|
|
import Ueditor from '@/components/ueditor' |
|
|
|
import Breadcrumb from '@/components/breadcrumb' |
|
|
|
import Breadcrumb from '@/components/breadcrumb' |
|
|
|
|
|
|
|
import QuesConst from '@/const/ques' |
|
|
|
|
|
|
|
import TestPaperConst from '@/const/testPaper' |
|
|
|
import Template from './template' |
|
|
|
import Template from './template' |
|
|
|
import Manual from './manual' |
|
|
|
import Manual from './manual' |
|
|
|
import Auto from './auto' |
|
|
|
import Auto from './auto' |
|
|
|
import QuesConst from '@/const/ques' |
|
|
|
import Detail from '@/pages/ques/detail' |
|
|
|
import TestPaperConst from '@/const/testPaper' |
|
|
|
|
|
|
|
export default { |
|
|
|
export default { |
|
|
|
components: { Ueditor, Breadcrumb, Template, Manual, Auto }, |
|
|
|
components: { Ueditor, Breadcrumb, Template, Manual, Auto, Detail }, |
|
|
|
data () { |
|
|
|
data () { |
|
|
|
return { |
|
|
|
return { |
|
|
|
crumbs: [ |
|
|
|
crumbs: [], |
|
|
|
{ |
|
|
|
|
|
|
|
name: '试卷管理', |
|
|
|
|
|
|
|
route: 'list' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
name: '创建试卷' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
questionTypes: QuesConst.questionTypes, |
|
|
|
questionTypes: QuesConst.questionTypes, |
|
|
|
difficults: TestPaperConst.difficults, |
|
|
|
difficults: TestPaperConst.difficults, |
|
|
|
paperTypes: TestPaperConst.paperTypes, |
|
|
|
paperTypes: TestPaperConst.paperTypes, |
|
|
@ -196,6 +210,7 @@ export default { |
|
|
|
numToLetter: Util.numToLetter, |
|
|
|
numToLetter: Util.numToLetter, |
|
|
|
paperId: this.$route.query.paperId, |
|
|
|
paperId: this.$route.query.paperId, |
|
|
|
libraryId: this.$route.query.libraryId, |
|
|
|
libraryId: this.$route.query.libraryId, |
|
|
|
|
|
|
|
isCopy: this.$route.query.isCopy, |
|
|
|
headers: { |
|
|
|
headers: { |
|
|
|
token: Util.local.get(Setting.tokenKey) |
|
|
|
token: Util.local.get(Setting.tokenKey) |
|
|
|
}, |
|
|
|
}, |
|
|
@ -287,6 +302,11 @@ export default { |
|
|
|
curQues: null, |
|
|
|
curQues: null, |
|
|
|
|
|
|
|
|
|
|
|
autoVisible: false, |
|
|
|
autoVisible: false, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
quesVisible: false, |
|
|
|
|
|
|
|
curRow: {}, |
|
|
|
|
|
|
|
detailType: '', |
|
|
|
}; |
|
|
|
}; |
|
|
|
}, |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
computed: { |
|
|
@ -300,6 +320,18 @@ export default { |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
mounted () { |
|
|
|
mounted () { |
|
|
|
|
|
|
|
this.crumbs = [ |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
name: '试卷管理', |
|
|
|
|
|
|
|
route: 'list', |
|
|
|
|
|
|
|
query: { |
|
|
|
|
|
|
|
id: this.libraryId |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
name: '创建试卷' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
] |
|
|
|
this.getDetail() |
|
|
|
this.getDetail() |
|
|
|
this.getType() |
|
|
|
this.getType() |
|
|
|
this.getProfessional() |
|
|
|
this.getProfessional() |
|
|
@ -316,6 +348,7 @@ export default { |
|
|
|
const r = res.examPaper |
|
|
|
const r = res.examPaper |
|
|
|
const paper = r.paperOutline |
|
|
|
const paper = r.paperOutline |
|
|
|
paper.map(e => { |
|
|
|
paper.map(e => { |
|
|
|
|
|
|
|
e.shrink = false |
|
|
|
e.examQuestions.map(n => { |
|
|
|
e.examQuestions.map(n => { |
|
|
|
Object.assign(n, n.question) |
|
|
|
Object.assign(n, n.question) |
|
|
|
}) |
|
|
|
}) |
|
|
@ -417,14 +450,39 @@ export default { |
|
|
|
// 处理正确答案的显示 |
|
|
|
// 处理正确答案的显示 |
|
|
|
getCorrectAnswer (e) { |
|
|
|
getCorrectAnswer (e) { |
|
|
|
if (e.questionType === 'fill_blank') { // 填空题 |
|
|
|
if (e.questionType === 'fill_blank') { // 填空题 |
|
|
|
// return e.questionAnswerVersionsList.filter(e => e.answerIsCorrect) |
|
|
|
// answerData里存了该填空题所有填空项的正确答案及分值占比,对象转化为字符串存起来了 |
|
|
|
|
|
|
|
let data = e.questionAnswerVersionsList[0].answerData |
|
|
|
|
|
|
|
if (data) { |
|
|
|
|
|
|
|
data = JSON.parse(data) |
|
|
|
|
|
|
|
let result = '' |
|
|
|
|
|
|
|
data.map((e, i) => { |
|
|
|
|
|
|
|
result += `填空项${i + 1}:${e.fills.map(n => n.val).join('|')};` |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
return result |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return '' |
|
|
|
} else if (e.questionType === 'essay') { // 问答题取参考答案 |
|
|
|
} else if (e.questionType === 'essay') { // 问答题取参考答案 |
|
|
|
return e.questionAnswerVersionsList[0].referenceAnswer |
|
|
|
return e.questionAnswerVersionsList[0].referenceAnswer || '暂无' |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
const correct = e.questionAnswerVersionsList.filter(e => e.answerIsCorrect) |
|
|
|
const correct = e.questionAnswerVersionsList.filter(e => e.answerIsCorrect) |
|
|
|
return correct ? (e.questionType === 'judgement' ? correct[0].optionText : correct.map(e => Util.numToLetter(e.optionNumber - 1)).join('')) : '' |
|
|
|
return correct ? (e.questionType === 'judgement' ? correct[0].optionText : correct.map(e => Util.numToLetter(e.optionNumber - 1)).join('')) : '' // 单选多选显示ABC选项,判断题显示选项内容 |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
// 编辑试题 |
|
|
|
|
|
|
|
toQues (item, i, ques) { |
|
|
|
|
|
|
|
this.curType = item |
|
|
|
|
|
|
|
this.curQuesIndex = i |
|
|
|
|
|
|
|
this.curRow = ques |
|
|
|
|
|
|
|
this.quesVisible = true |
|
|
|
|
|
|
|
this.detailType = 4 |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
// 编辑试题完成后把新的试题信息带过来 |
|
|
|
|
|
|
|
updateQues (ques, id) { |
|
|
|
|
|
|
|
ques.questionAnswerVersionsList = ques.questionAnswerVersions |
|
|
|
|
|
|
|
delete ques.questionAnswerVersions |
|
|
|
|
|
|
|
ques.questionVersionId = id |
|
|
|
|
|
|
|
this.curType.examQuestions[this.curQuesIndex] = Object.assign(this.curRow, ques) |
|
|
|
|
|
|
|
}, |
|
|
|
// 添加题目 |
|
|
|
// 添加题目 |
|
|
|
showManualDia (item, i, ques) { |
|
|
|
showManualDia (item, i, ques) { |
|
|
|
this.curType = item |
|
|
|
this.curType = item |
|
|
@ -477,11 +535,10 @@ export default { |
|
|
|
}, |
|
|
|
}, |
|
|
|
// 提交 |
|
|
|
// 提交 |
|
|
|
async submit (status) { |
|
|
|
async submit (status) { |
|
|
|
// this.form.paperOutline[0].examQuestions.reduce((e, j) => (e += +j.score), 0) |
|
|
|
|
|
|
|
// return console.log(44,) |
|
|
|
|
|
|
|
if (this.submiting) return false |
|
|
|
if (this.submiting) return false |
|
|
|
this.$refs.form.validate(async (valid) => { |
|
|
|
this.$refs.form.validate(async (valid) => { |
|
|
|
if (valid) { |
|
|
|
if (valid) { |
|
|
|
|
|
|
|
const { isCopy } = this // 复制 |
|
|
|
const form = _.cloneDeep(this.form) |
|
|
|
const form = _.cloneDeep(this.form) |
|
|
|
if (isNaN(form.suggestTime) || form.suggestTime < 1 || form.suggestTime % 1) return Util.warningMsg('估计用时请输入正整数') |
|
|
|
if (isNaN(form.suggestTime) || form.suggestTime < 1 || form.suggestTime % 1) return Util.warningMsg('估计用时请输入正整数') |
|
|
|
const paper = form.paperOutline |
|
|
|
const paper = form.paperOutline |
|
|
@ -516,6 +573,13 @@ export default { |
|
|
|
invalid = 1 |
|
|
|
invalid = 1 |
|
|
|
break |
|
|
|
break |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 试题里存在被禁用或者被删除的,不予提交 |
|
|
|
|
|
|
|
if (e.examQuestions.some(e => !e.status || e.isDel)) { |
|
|
|
|
|
|
|
Util.warningMsg(`当前试卷存在已被删除或已被禁用的试题,请进行相应调整 `) |
|
|
|
|
|
|
|
invalid = 1 |
|
|
|
|
|
|
|
break |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// debugger |
|
|
|
// debugger |
|
|
|
if (invalid) return false |
|
|
|
if (invalid) return false |
|
|
@ -529,20 +593,26 @@ export default { |
|
|
|
form.status = status |
|
|
|
form.status = status |
|
|
|
|
|
|
|
|
|
|
|
paper.map(e => { |
|
|
|
paper.map(e => { |
|
|
|
|
|
|
|
// 复制不需要传id |
|
|
|
|
|
|
|
if (isCopy) { |
|
|
|
|
|
|
|
e.paperId = '' |
|
|
|
|
|
|
|
e.outlineId = '' |
|
|
|
|
|
|
|
} |
|
|
|
e.targetScore = +e.targetScore |
|
|
|
e.targetScore = +e.targetScore |
|
|
|
e.examQuestions = e.examQuestions.map(n => { |
|
|
|
e.examQuestions = e.examQuestions.map(n => { |
|
|
|
return { |
|
|
|
return { |
|
|
|
questionVersionId: n.questionVersionId, |
|
|
|
questionVersionId: n.questionVersionId, |
|
|
|
serialNumber: n.serialNumber, |
|
|
|
serialNumber: n.serialNumber, |
|
|
|
score: +n.score, |
|
|
|
score: +n.score, |
|
|
|
paperId: n.paperId || '', |
|
|
|
paperId: !isCopy && this.paperId || '', |
|
|
|
outlineId: e.outlineId || '', |
|
|
|
outlineId: !isCopy && e.outlineId || '', |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
|
}) |
|
|
|
}) |
|
|
|
if (typeof form.classificationId === 'object') form.classificationId = form.classificationId[form.classificationId.length - 1] |
|
|
|
if (typeof form.classificationId === 'object') form.classificationId = form.classificationId[form.classificationId.length - 1] |
|
|
|
form.questionType = [...new Set(paper.map(e => e.questionType))].join('、') |
|
|
|
form.questionType = [...new Set(paper.map(e => e.questionType))].join('、') // 试题类型 |
|
|
|
form.createSource = 1 |
|
|
|
form.createSource = 1 |
|
|
|
|
|
|
|
if (isCopy) form.paperId = '' |
|
|
|
try { |
|
|
|
try { |
|
|
|
await this.$post(this.api.saveExamPaper, form) |
|
|
|
await this.$post(this.api.saveExamPaper, form) |
|
|
|
Util.successMsg('保存成功') |
|
|
|
Util.successMsg('保存成功') |
|
|
@ -612,10 +682,42 @@ export default { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.ques-info { |
|
|
|
.ques-info { |
|
|
|
|
|
|
|
position: relative; |
|
|
|
width: calc(100% - 40px); |
|
|
|
width: calc(100% - 40px); |
|
|
|
padding: 10px; |
|
|
|
padding: 10px; |
|
|
|
margin-left: 20px; |
|
|
|
margin-left: 20px; |
|
|
|
border: 1px solid #e9e9e9; |
|
|
|
border: 1px solid #e9e9e9; |
|
|
|
|
|
|
|
overflow: hidden; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&.disabled, |
|
|
|
|
|
|
|
&.del, |
|
|
|
|
|
|
|
&.repeat { |
|
|
|
|
|
|
|
border-color: #f00; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&:after { |
|
|
|
|
|
|
|
content: '已 禁 用'; |
|
|
|
|
|
|
|
position: absolute; |
|
|
|
|
|
|
|
top: 17px; |
|
|
|
|
|
|
|
right: -33px; |
|
|
|
|
|
|
|
padding: 5px 36px; |
|
|
|
|
|
|
|
font-size: 14px; |
|
|
|
|
|
|
|
color: #fff; |
|
|
|
|
|
|
|
background-color: #f00; |
|
|
|
|
|
|
|
transform: rotate(45deg); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&.del { |
|
|
|
|
|
|
|
&:after { |
|
|
|
|
|
|
|
content: '已 删 除'; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&.repeat { |
|
|
|
|
|
|
|
&:after { |
|
|
|
|
|
|
|
content: '存在重复题'; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.top-line { |
|
|
|
.top-line { |
|
|
@ -681,4 +783,16 @@ export default { |
|
|
|
font-size: 12px; |
|
|
|
font-size: 12px; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.diff-text { |
|
|
|
|
|
|
|
line-height: 1.6; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.em { |
|
|
|
|
|
|
|
font-weight: 600; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.coe { |
|
|
|
|
|
|
|
padding-left: 32px; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
</style> |
|
|
|
</style> |