试卷试题相关

master
yujialong 4 months ago
parent 279faf12a0
commit 8fc87aa06a
  1. 2
      public/static/ueditorPlus/ueditor.config.js
  2. 123
      src/pages/ques/detail/index.vue
  3. 60
      src/pages/ques/list/index.vue
  4. 66
      src/pages/testPaper/detail/auto.vue
  5. 162
      src/pages/testPaper/detail/index.vue
  6. 51
      src/pages/testPaper/detail/manual.vue
  7. 24
      src/pages/testPaper/list/index.vue
  8. 9
      src/styles/common.scss

@ -101,7 +101,7 @@
// 禁止本地上传 // 禁止本地上传
disableUpload: false, disableUpload: false,
} }
, zIndex: 3000 , zIndex: 2000
, fullscreen: false , fullscreen: false
, rgb2Hex: true, , rgb2Hex: true,

@ -1,8 +1,7 @@
<template> <template>
<div> <div>
<el-dialog :title="(detailType ? detailTypes[detailType] : '新增') + '试题'" :visible.sync="quesVisible" <el-dialog :title="diaTitle" :visible.sync="quesVisible" :modal-append-to-body="false" width="1000px"
:modal-append-to-body="false" width="1000px" :close-on-click-modal="false" custom-class="ques-dia" :close-on-click-modal="false" custom-class="ques-dia" @closed="closeDia">
@closed="closeDia">
<el-form :model="form" :rules="rules" ref="form" label-width="110px" :disabled="detailType === 2"> <el-form :model="form" :rules="rules" ref="form" label-width="110px" :disabled="detailType === 2">
<el-form-item label="题库分类"> <el-form-item label="题库分类">
<el-input v-model="questionBankCategory" disabled /> <el-input v-model="questionBankCategory" disabled />
@ -164,11 +163,11 @@
questionTypes.find(e => e.id === scope.row.questionType).name : '' }}</template> questionTypes.find(e => e.id === scope.row.questionType).name : '' }}</template>
</el-table-column> </el-table-column>
<el-table-column prop="stem" label="题干" align="center" min-width="120" show-overflow-tooltip></el-table-column> <el-table-column prop="stem" label="题干" align="center" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" align="center" width="240"> <!-- <el-table-column label="操作" align="center" width="240">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text">详情</el-button> <el-button type="text">详情</el-button>
</template> </template>
</el-table-column> </el-table-column> -->
</el-table> </el-table>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
@ -201,11 +200,11 @@ export default {
components: { Ueditor, Upload }, components: { Ueditor, Upload },
data () { data () {
return { return {
typeId: this.$route.query.id, typeId: this.$route.query.id, // id
questionBankName: this.$route.query.questionBankName, questionBankName: this.$route.query.questionBankName,
questionBankCategory: this.$route.query.questionBankCategory, questionBankCategory: this.$route.query.questionBankCategory,
numToLetter: Util.numToLetter, numToLetter: Util.numToLetter,
detailTypes: ['', '复制', '查看', '编辑'], detailTypes: ['', '复制', '查看', '编辑', '编辑'],
types: [], types: [],
cascaderValue: [], cascaderValue: [],
cascaderProps: { cascaderProps: {
@ -276,6 +275,21 @@ export default {
repeats: [] repeats: []
}; };
}, },
computed: {
//
diaTitle () {
const type = this.detailType
return (!type || type === 5 ?
'新增' :
type === 1 ?
'复制' :
type === 2 ?
'查看' :
type === 3 ?
'编辑' :
'') + '试题'
},
},
watch: { watch: {
visible () { visible () {
this.quesVisible = this.visible this.quesVisible = this.visible
@ -292,9 +306,14 @@ export default {
this.form = _.cloneDeep(this.originForm) this.form = _.cloneDeep(this.originForm)
this.handleSingleMultiple() this.handleSingleMultiple()
const type = this.detailType
// //
if (type < 4) {
const knowledgeCheck = this.$parent.$refs.typeTree.getCurrentNode() const knowledgeCheck = this.$parent.$refs.typeTree.getCurrentNode()
if (knowledgeCheck && knowledgeCheck.type) this.form.knowledgePointIds = [knowledgeCheck.path.split('/').map(e => +e)] if (knowledgeCheck && knowledgeCheck.type) this.form.knowledgePointIds = [knowledgeCheck.path.split('/').map(e => +e)]
} else if (type === 4) {
this.typeId = this.row.questionBankId
}
// //
this.$refs.stem && this.$refs.stem.setText('') this.$refs.stem && this.$refs.stem.setText('')
@ -314,6 +333,12 @@ export default {
const res = await this.$post(`${this.api.findQuestion}?questionId=${this.row.questionId}&version=${this.row.version}`) const res = await this.$post(`${this.api.findQuestion}?questionId=${this.row.questionId}&version=${this.row.version}`)
const r = res.message const r = res.message
const opts = r.questionAnswerVersionsList const opts = r.questionAnswerVersionsList
if (this.detailType === 4) {
this.questionBankName = r.questionBankName
// this.questionBankCategory = r.questionBankCategory
}
this.form = { this.form = {
questionId: r.questionId, questionId: r.questionId,
questionType: r.questionType, questionType: r.questionType,
@ -347,15 +372,17 @@ export default {
}, },
// //
async getKnowledge () { async getKnowledge () {
if (this.typeId) {
try { try {
const { data } = await this.$post(this.api.TreeStructure, { const { data } = await this.$post(this.api.TreeStructure, {
createSource: 1, createSource: 1,
questionBankId: this.typeId, questionBankId: this.typeId,
keyword: '' keyword: '',
}) })
this.handleType(data) this.handleType(data)
this.knowledges = data this.knowledges = data
} catch (e) { } } catch (e) { }
}
}, },
// //
async getProfessional () { async getProfessional () {
@ -486,7 +513,6 @@ export default {
}, },
questionItemReset (content) { questionItemReset (content) {
let spanRegex = new RegExp('<span class="gapfilling-span" (.*?)>(.*?)______(.*?)<\\/span>', 'g') let spanRegex = new RegExp('<span class="gapfilling-span" (.*?)>(.*?)______(.*?)<\\/span>', 'g')
let _this = this
let newFormItem = [] let newFormItem = []
let gapfillingItems = content.match(spanRegex) let gapfillingItems = content.match(spanRegex)
if (gapfillingItems !== null) { if (gapfillingItems !== null) {
@ -501,8 +527,6 @@ export default {
this.fillBlanks.push(e) this.fillBlanks.push(e)
} }
}) })
console.log("🚀 ~ questionItemReset ~ spanRegex:", gapfillingItems, newFormItem, this.fillBlanks)
// _this.fillBlanks = newFormItem
} }
}, },
// //
@ -552,9 +576,15 @@ export default {
form.questionAnswerVersions[0].answerAnalysis = answerAnalysis // form.questionAnswerVersions[0].answerAnalysis = answerAnalysis //
if (this.$refs.uploadInstructions) form.uploadInstructions = this.$refs.uploadInstructions.getUEContent() if (this.$refs.uploadInstructions) form.uploadInstructions = this.$refs.uploadInstructions.getUEContent()
if (form.questionType === 'fill_blank') form.questionAnswerVersions[0].answerData = JSON.stringify(this.fillBlanks) // fillBlanks
// fillBlanks
if (form.questionType === 'fill_blank') {
const blanks = this.fillBlanks
blanks.map((e, i) => e.serial = i + 1) //
form.questionAnswerVersions[0].answerData = JSON.stringify(blanks)
}
if (form.questionType === 'essay' && this.$refs.referenceAnswer) form.questionAnswerVersions[0].referenceAnswer = this.$refs.referenceAnswer.getUEContent() // () if (form.questionType === 'essay' && this.$refs.referenceAnswer) form.questionAnswerVersions[0].referenceAnswer = this.$refs.referenceAnswer.getUEContent() // ()
debugger // debugger
this.tempForm = form this.tempForm = form
this.keep = keep this.keep = keep
// 3 // 3
@ -566,7 +596,7 @@ export default {
} else { } else {
// //
try { try {
await this.$confirm(`<p style="margin-bottom: 10px;">确认仅更新此题吗?</p><p>更新后,相关试卷自动同步</p>`, '提示', { await this.$confirm(`<p style="margin-bottom: 10px;">确认仅更新此题吗?</p>${this.detailType === 4 ? '' : '<p>更新后,相关试卷自动同步</p>'}`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
@ -592,7 +622,11 @@ export default {
// //
async saveQues () { async saveQues () {
const form = this.tempForm const form = this.tempForm
await this.$post(this.api[this.detailType === 1 || !form.questionId ? 'addQuestion' : 'updateQuestion'], form) const type = this.detailType
// type: 1()234createNewVersion
const res = await this.$post(this.api[type === 4 ? 'createNewVersion' : type === 1 || !form.questionId ? 'addQuestion' : 'updateQuestion'], form)
type === 4 && this.$emit('updateQues', this.tempForm, res.questionVersionId)
Util.successMsg('保存成功') Util.successMsg('保存成功')
this.submiting = false this.submiting = false
!form.questionId && this.keep ? this.init() : (this.quesVisible = false) !form.questionId && this.keep ? this.init() : (this.quesVisible = false)
@ -636,11 +670,64 @@ export default {
} }
} }
/deep/.correct-check {
margin-right: 15px;
}
/deep/.ques-dia { /deep/.ques-dia {
z-index: 500; z-index: 500;
.fill-blanks {
.fills {
display: inline-flex;
align-items: center;
}
.fill-item {
display: inline-flex;
align-items: center;
margin-right: 10px;
.el-input {
width: 100px;
margin-right: 10px;
}
}
.add-fill {
margin-left: 10px;
}
.score-wrap {
display: inline-flex;
align-items: center;
.el-input {
width: 80px;
margin: 0 10px;
}
}
}
.opts {
.line {
display: flex;
align-items: center;
margin-bottom: 15px;
}
.el-radio {
margin-right: 15px;
}
.icon {
margin-left: 10px;
font-size: 18px;
cursor: pointer;
}
}
/deep/.correct-check {
margin-right: 15px;
}
} }
</style> </style>

@ -152,16 +152,6 @@
<i class="el-icon-edit m-l-10"></i> <i class="el-icon-edit m-l-10"></i>
</li> </li>
</ul> </ul>
<!-- <ul class="papers">
<li>题干</li>
<li>试卷</li>
</ul>
<ul class="papers">
<li v-for="(item, i) in curUsePapers" :key="i">
<p></p>
<p></p>
</li>
</ul> -->
</div> </div>
</div> </div>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
@ -470,7 +460,7 @@ export default {
this.multipleSelection = [] this.multipleSelection = []
this.$refs.table.clearSelection() this.$refs.table.clearSelection()
this.delVisible = false this.delVisible = false
this.getData() this.getList()
}, },
// //
async switchOff (val, row) { async switchOff (val, row) {
@ -605,55 +595,7 @@ export default {
} }
} }
/deep/.opts {
.line {
display: flex;
align-items: center;
margin-bottom: 15px;
}
.el-radio {
margin-right: 15px;
}
.icon {
margin-left: 10px;
font-size: 18px;
cursor: pointer;
}
}
/deep/.fill-blanks {
.fills {
display: inline-flex;
align-items: center;
}
.fill-item {
display: inline-flex;
align-items: center;
margin-right: 10px;
.el-input {
width: 100px;
margin-right: 10px;
}
}
.add-fill {
margin-left: 10px;
}
.score-wrap {
display: inline-flex;
align-items: center;
.el-input {
width: 80px;
margin: 0 10px;
}
}
}
.papers { .papers {
margin-top: 10px; margin-top: 10px;

@ -6,7 +6,7 @@
<ul class="filter"> <ul class="filter">
<li> <li>
<label>试卷难度</label> <label>试卷难度</label>
<el-select v-model="difficult" placeholder="请选择试卷难度" @change="difficultData"> <el-select v-model="difficult" placeholder="请选择试卷难度" @change="difficultChange">
<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>
</li> </li>
@ -179,6 +179,8 @@ export default {
this.yearCheck = this.years this.yearCheck = this.years
this.handleQuesList() this.handleQuesList()
this.getQuesBank() this.getQuesBank()
this.difficult = this.$parent.form.difficult
this.difficult && this.difficultChange(this.difficult)
}, },
// //
async getQuesBank () { async getQuesBank () {
@ -284,50 +286,47 @@ export default {
}, },
calculateQuestionNumbers (list, target) { //
difficultChange (val) {
// Decimal(e.score).add(Decimal(score)) // Decimal(e.score).add(Decimal(score))
const difficultyWeights = [0.2, 0.4, 0.6, 0.8] const difficultyWeights = [0.2, 0.4, 0.6, 0.8]
const names = ['basicDifficulty', 'normalDifficulty', 'hardDifficulty', 'veryHardDifficulty'] const names = ['basicDifficulty', 'normalDifficulty', 'hardDifficulty', 'veryHardDifficulty']
// //
list.forEach(e => { this.list.forEach(e => {
const total = e.questionNum const total = e.questionNum
if (target === 1) { let already = 0 //
let already = 0 if (val === 1) {
this.$set(e, 'basicDifficulty', Math.floor(total * 0.6)) this.$set(e, 'basicDifficulty', Math.floor(total * 0.7))
this.$set(e, 'normalDifficulty', Math.floor(total * 0.3)) this.$set(e, 'normalDifficulty', Math.floor(total * 0.3))
this.$set(e, 'hardDifficulty', Math.floor(total * 0.1)) this.$set(e, 'hardDifficulty', 0)
this.$set(e, 'veryHardDifficulty', 0) this.$set(e, 'veryHardDifficulty', 0)
already = Decimal(already).add(e.basicDifficulty).add(e.normalDifficulty).add(e.hardDifficulty).add(e.veryHardDifficulty).toNumber() } else if (val === 2) {
this.$set(e, 'basicDifficulty', Math.floor(total * 0.5))
this.$set(e, 'normalDifficulty', Math.floor(total * 0.5))
this.$set(e, 'hardDifficulty', 0)
this.$set(e, 'veryHardDifficulty', 0)
} else if (val === 3) {
this.$set(e, 'basicDifficulty', Math.floor(total * 0.3))
this.$set(e, 'normalDifficulty', Math.floor(total * 0.4))
this.$set(e, 'hardDifficulty', Math.floor(total * 0.3))
this.$set(e, 'veryHardDifficulty', 0)
} else if (val === 4) {
this.$set(e, 'basicDifficulty', Math.floor(total * 0.1))
this.$set(e, 'normalDifficulty', Math.floor(total * 0.2))
this.$set(e, 'hardDifficulty', Math.floor(total * 0.3))
this.$set(e, 'veryHardDifficulty', Math.floor(total * 0.5))
}
already = Decimal(already).add(e.basicDifficulty).add(e.normalDifficulty).add(e.hardDifficulty).add(e.veryHardDifficulty).toNumber()
//
while (total > already) { while (total > already) {
e.basicDifficulty++ e[names[val - 1]]++
already++ already++
} }
console.log(33, already) this.$set(e, 'randomDifficulty', 0)
}
//
// let totalWeight = Decimal(total).mul(Decimal(target)).toNumber()
// const maxCount = Math.ceil(total / 4)
// for (let i = 0; i < 4; i++) {
// if (totalWeight > 0) {
// const random = Math.floor(Math.random() * maxCount) + 1
// const weight = difficultyWeights[i]
// totalWeight = Decimal(totalWeight).sub(Decimal(weight * random)).toNumber()
// this.$set(e, names[i], totalWeight > 0 ? random : 0)
// // e[names[i]] = totalWeight > 0 ? random : 0
// }
// }
}) })
return list
},
//
difficultData (val) {
// debugger
console.log(111, this.calculateQuestionNumbers(this.list, val))
}, },
// //
yearAllChange (val) { yearAllChange (val) {
@ -377,7 +376,7 @@ export default {
let invalid = 0 let invalid = 0
let hasQues = 0 let hasQues = 0
list.map((e, i) => { list.map((e, i) => {
if (e.questionNum !== res.list[i].questions.length) invalid = 1 if (+e.questionNum !== res.list[i].questions.length) invalid = 1
if (e.examQuestions.length) hasQues = 1 if (e.examQuestions.length) hasQues = 1
e.score = 0 e.score = 0
}) })
@ -400,6 +399,7 @@ export default {
} }
list.map((e, i) => { list.map((e, i) => {
res.list[i].questions.map((e, i) => { res.list[i].questions.map((e, i) => {
// e.questionVersionId = e.id
e.serialNumber = i + 1 e.serialNumber = i + 1
}) })
this.$parent.form.paperOutline[i].examQuestions = res.list[i].questions this.$parent.form.paperOutline[i].examQuestions = res.list[i].questions

@ -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>简单系数 &lt;=0.3</p>
<p>普通0.3&lt;系数&lt;=0.4</p>
<p>较难0.4&lt;系数&lt;0.5</p>
<p>困难:系数&gt;=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>

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<el-dialog title="批量添加单选题" :visible.sync="quesVisible" width="1200px" :close-on-click-modal="false" <el-dialog :title="diaTitle" :visible.sync="selectQuesVisible" width="1200px" :close-on-click-modal="false"
@closed="closeDia"> @closed="closeDia">
<div class="wrap"> <div class="wrap">
<!-- 题库 --> <!-- 题库 -->
@ -75,16 +75,19 @@
</div> </div>
<div class="flex j-between"> <div class="flex j-between">
<p>未找到试题<a class="link" @click="toAddQues">去新增</a></p> <p>未找到试题<a class="link" @click="toAddQues">去新增</a></p>
<p>已选题数/目标题数{{ checkedLen }}/{{ $parent.curType.questionNum }}&emsp;&emsp;<a class="link" <p>已选题数/目标题数{{ checkedLen }}/{{ $parent.curType.questionNum }}&emsp;&emsp;
@click="toEditQues">修改目标</a></p> <!-- <a class="link" @click="toEditQues">修改目标</a> -->
</p>
</div> </div>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button @click="quesVisible = false">取消</el-button> <el-button @click="selectQuesVisible = false">取消</el-button>
<el-button type="primary" :loading="submiting" @click="submit">确定</el-button> <el-button type="primary" :loading="submiting" @click="submit">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<Detail :visible.sync="quesVisible" :row.sync="curRow" :detailType.sync="detailType" @updateQues="updateQues" />
</div> </div>
</template> </template>
<script> <script>
@ -92,11 +95,13 @@ import Setting from '@/setting'
import Util from '@/libs/util' import Util from '@/libs/util'
import _ from 'lodash' import _ from 'lodash'
import QuesConst from '@/const/ques' import QuesConst from '@/const/ques'
import Detail from '@/pages/ques/detail'
export default { export default {
components: { Detail },
props: ['visible', 'questionType'], props: ['visible', 'questionType'],
data () { data () {
return { return {
quesVisible: false, selectQuesVisible: false,
quesBankKeyword: '', quesBankKeyword: '',
knowledgeKeyword: '', knowledgeKeyword: '',
searchTimer: null, searchTimer: null,
@ -110,13 +115,25 @@ export default {
curCheckQues: [], curCheckQues: [],
submiting: false, submiting: false,
quesVisible: false,
curRow: {},
detailType: '',
}; };
}, },
computed: { computed: {
// + // +
checkedLen () { checkedLen () {
return this.curCheckQues.length + this.checked.length return this.curCheckQues.length + this.checked.length
} },
//
diaTitle () {
const { curQuesIndex, curQues } = this.$parent
return curQues ?
'更换试题' :
typeof curQuesIndex === 'number' ?
'添加试题' :
this.questionType ? `批量添加${QuesConst.questionTypes.find(e => e.id === this.questionType).name}` : ''
},
}, },
watch: { watch: {
'quesBankKeyword': function (val) { 'quesBankKeyword': function (val) {
@ -128,7 +145,7 @@ export default {
this.searchTimer = setTimeout(this.getKnowledge, 500) this.searchTimer = setTimeout(this.getKnowledge, 500)
}, },
visible () { visible () {
this.quesVisible = this.visible this.selectQuesVisible = this.visible
this.visible && this.init() this.visible && this.init()
} }
}, },
@ -189,8 +206,6 @@ export default {
questionBankId: this.$refs.quesBank.getCurrentKey(), questionBankId: this.$refs.quesBank.getCurrentKey(),
knowledgePointIds: [k.id], knowledgePointIds: [k.id],
questionTypes: this.questionType ? [this.questionType] : [], questionTypes: this.questionType ? [this.questionType] : [],
// questionBankId: 26,
// knowledgePointIds: [18],
}) })
const data = list const data = list
const checked = this.curCheckQues const checked = this.curCheckQues
@ -288,11 +303,19 @@ export default {
}, },
// //
toAddQues () { toAddQues () {
this.quesVisible = true
this.detailType = 5
}, },
// //
toEditQues () { toEditQues () {
},
//
updateQues (ques, id) {
// ques.questionAnswerVersionsList = ques.questionAnswerVersions
// delete ques.questionAnswerVersions
// ques.questionVersionId = id
// this.curType.examQuestions[this.curQuesIndex] = Object.assign(this.curRow, ques)
}, },
// //
async submit () { async submit () {
@ -308,7 +331,7 @@ export default {
this.$set(e, 'check', false) this.$set(e, 'check', false)
this.$set(e, 'sort', i + 1) this.$set(e, 'sort', i + 1)
this.$set(e, 'score', '') this.$set(e, 'score', '')
this.$set(e, 'questionVersionId', e.questionId) // this.$set(e, 'questionVersionId', e.questionId)
}) })
if (curQues) { if (curQues) {
@ -320,8 +343,12 @@ export default {
this.curCheckQues.splice(curQuesIndex + 1, 0, ...checked) : this.curCheckQues.splice(curQuesIndex + 1, 0, ...checked) :
this.curCheckQues.push(...checked) this.curCheckQues.push(...checked)
} }
//
this.curCheckQues.map((e, i) => {
this.$set(e, 'serialNumber', i + 1)
})
this.quesVisible = false this.selectQuesVisible = false
this.submiting = false this.submiting = false
} catch (e) { } catch (e) {
this.submiting = false this.submiting = false

@ -95,8 +95,8 @@
</li> </li>
<li> <li>
<label>状态</label> <label>状态</label>
<el-select v-model="filter.status" clearable placeholder="请选择状态" @change="initData"> <el-select v-model="status" clearable placeholder="请选择状态" @change="initData">
<el-option v-for="(item, i) in status" :key="i" :label="item.name" :value="item.id"></el-option> <el-option v-for="(item, i) in statusList" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
@ -106,7 +106,7 @@
</li> </li>
<div style="margin-bottom: 15px;"> <div style="margin-bottom: 15px;">
<el-button type="primary" @click="add">创建试卷</el-button> <el-button type="primary" @click="add">创建试卷</el-button>
<el-button type="primary" @click="add">批量移除 </el-button> <!-- <el-button type="primary" @click="add">批量移除 </el-button> -->
<el-button type="primary" @click="delAllSelection">批量删除</el-button> <el-button type="primary" @click="delAllSelection">批量删除</el-button>
</div> </div>
</ul> </ul>
@ -140,7 +140,7 @@
e.id === scope.row.paperType).name : '' }}</template> e.id === scope.row.paperType).name : '' }}</template>
</el-table-column> </el-table-column>
<el-table-column label="状态" align="center" width="60"> <el-table-column label="状态" align="center" width="60">
<template slot-scope="scope">{{ scope.row.status ? '发布' : '草稿' }}</template> <template slot-scope="scope">{{ scope.row.status ? '草稿' : (scope.row.isDisable ? '禁用' : '启用') }}</template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center" width="160" <el-table-column prop="createTime" label="创建时间" align="center" width="160"
sortable="custom"></el-table-column> sortable="custom"></el-table-column>
@ -149,9 +149,9 @@
<el-table-column prop="createUser" label="最近编辑人" align="center" width="90"></el-table-column> <el-table-column prop="createUser" label="最近编辑人" align="center" width="90"></el-table-column>
<el-table-column label="操作" align="center" width="240"> <el-table-column label="操作" align="center" width="240">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="edit(scope.row)">复制</el-button> <el-button type="text" @click="toDetail(scope.row, 1)">复制</el-button>
<el-button type="text" @click="edit(scope.row)">预览</el-button> <!-- <el-button type="text" @click="edit(scope.row)">预览</el-button> -->
<el-button type="text" @click="edit(scope.row)">编辑</el-button> <el-button type="text" @click="toDetail(scope.row)">编辑</el-button>
<el-button type="text" @click="del(scope.row)">删除</el-button> <el-button type="text" @click="del(scope.row)">删除</el-button>
<el-switch v-if="!scope.row.status" v-model="scope.row.isDisable" :active-value="false" <el-switch v-if="!scope.row.status" v-model="scope.row.isDisable" :active-value="false"
:inactive-value="true" style="margin: 0 10px 0 5px" :active-text="scope.row.isDisable ? '关' : '开'" :inactive-value="true" style="margin: 0 10px 0 5px" :active-text="scope.row.isDisable ? '关' : '开'"
@ -228,7 +228,7 @@ export default {
] ]
}, },
professionals: [], professionals: [],
status: [ statusList: [
{ {
id: 0, id: 0,
name: '启用' name: '启用'
@ -244,11 +244,11 @@ export default {
], ],
particularYear: '', particularYear: '',
questionType: [], questionType: [],
status: '',
filter: { filter: {
difficult: [], difficult: [],
professionalId: [], professionalId: [],
paperType: '', paperType: '',
status: '',
updateTimeOrder: '', updateTimeOrder: '',
crateTimeOrder: '', crateTimeOrder: '',
yearOrder: '', yearOrder: '',
@ -410,6 +410,8 @@ export default {
this.listLoading = true this.listLoading = true
const res = await this.$post(this.api.examPaperList, { const res = await this.$post(this.api.examPaperList, {
...this.filter, ...this.filter,
isDisable: this.status === 2 ? '' : this.status, //
status: this.status === 2 ? 1 : '', // 稿
particularYear: this.particularYear ? [this.particularYear] : [], particularYear: this.particularYear ? [this.particularYear] : [],
questionType: this.questionType.length ? this.questionType.join() : '', questionType: this.questionType.length ? this.questionType.join() : '',
type: this.isNotJoin, type: this.isNotJoin,
@ -473,8 +475,8 @@ export default {
this.$router.push(`detail?libraryId=${this.typeId}&classificationId=${this.$refs.typeTree.getCurrentKey() || ''}`) this.$router.push(`detail?libraryId=${this.typeId}&classificationId=${this.$refs.typeTree.getCurrentKey() || ''}`)
}, },
// //
async edit (row) { async toDetail (row, isCopy = '') {
this.$router.push(`detail?paperId=${row.paperId}&libraryId=${this.typeId}&classificationId=${this.$refs.typeTree.getCurrentKey() || ''}`) this.$router.push(`detail?paperId=${row.paperId}&libraryId=${this.typeId}&classificationId=${this.$refs.typeTree.getCurrentKey() || ''}&isCopy=${isCopy}`)
}, },
async delAllSelection () { async delAllSelection () {
const list = this.multipleSelection const list = this.multipleSelection

@ -380,15 +380,6 @@
.el-switch__label span { .el-switch__label span {
font-size: 12px; font-size: 12px;
} }
.el-tooltip__popper.is-dark {
padding: 18px 20px;
color: #606266;
line-height: 1.8;
background-color: #fff;
border: .0625rem solid #ebeef5;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border-radius: 4px;
}
.el-tooltip__popper[x-placement^="top"] { .el-tooltip__popper[x-placement^="top"] {
.popper__arrow { .popper__arrow {
border-top-color: #fff; border-top-color: #fff;

Loading…
Cancel
Save