yujialong 3 months ago
parent 66f11fef31
commit 0165016dd7
  1. 3
      src/pages/knowledge/index.vue
  2. 73
      src/pages/ques/detail/index.vue
  3. 5
      src/pages/ques/list/index.vue
  4. 1
      src/pages/quesBank/index.vue
  5. 96
      src/pages/testPaper/detail/auto.vue
  6. 222
      src/pages/testPaper/detail/index.vue
  7. 40
      src/pages/testPaper/detail/manual.vue
  8. 1
      src/pages/testPaper/detail/template.vue
  9. 10
      src/pages/testPaper/list/index.vue
  10. 2
      src/pages/testPaperLibraryType/index.vue
  11. 2
      src/plugins/requests/index.js

@ -324,9 +324,8 @@ export default {
}, },
// //
handleNodeClick (data) { handleNodeClick (data) {
this.$refs.table.clearSelection()
this.isNotJoin = '' this.isNotJoin = ''
this.getList() this.initData()
}, },
// //
closeType () { closeType () {

@ -86,10 +86,12 @@
<div v-for="(item, i) in fillBlanks" :key="i" class="opt j-between"> <div v-for="(item, i) in fillBlanks" :key="i" class="opt j-between">
<div class="fills"> <div class="fills">
<span>填空{{ i + 1 }}</span> <span>填空{{ i + 1 }}</span>
<div v-for="(fill, j) in item.fills" :key="j" class="fill-item"> <div v-if="item.fills" class="fill-items">
<el-input placeholder="请输入" v-model="fill.val" /> <div v-for="(fill, j) in item.fills" :key="j" class="fill-item">
<i v-if="j" class="action-icon el-icon-remove-outline" @click="item.fills.splice(j, 1)"></i> <el-input type="textarea" autosize resize="none" placeholder="请输入" v-model="fill.val" />
<span v-if="j !== item.fills.length - 1"></span> <i v-if="j" class="action-icon el-icon-remove-outline" @click="item.fills.splice(j, 1)"></i>
<span v-if="j !== item.fills.length - 1"></span>
</div>
</div> </div>
<el-button class="add-fill" type="primary" size="small" @click="addFill(item)">新增答案</el-button> <el-button class="add-fill" type="primary" size="small" @click="addFill(item)">新增答案</el-button>
@ -256,7 +258,7 @@ export default {
questionAnswerVersions: [], questionAnswerVersions: [],
questionBankId: '', questionBankId: '',
questionType: 'single_choice', questionType: 'single_choice',
specialtyIds: [], specialtyIds: [1],
stem: '', stem: '',
allowAttachment: 0, allowAttachment: 0,
stemAttachment: '', stemAttachment: '',
@ -333,19 +335,22 @@ export default {
} else if (type === 4) { } else if (type === 4) {
// this.questionBankId = this.row.questionBankId // this.questionBankId = this.row.questionBankId
} }
const { stem, answerAnalysis } = this.$refs const { stem, answerAnalysis, referenceAnswer, uploadInstructions } = this.$refs
stem && stem.instance && stem.setText('') stem && stem.instance && stem.setText('')
answerAnalysis && answerAnalysis.instance && answerAnalysis.setText('') answerAnalysis && answerAnalysis.instance && answerAnalysis.setText('')
referenceAnswer && referenceAnswer.instance && referenceAnswer.setText('')
uploadInstructions && uploadInstructions.instance && uploadInstructions.setText('')
this.answerAnalysis = '' this.answerAnalysis = ''
this.uploadList = []
// //
if (v) { if (v) {
const { form } = this const { form, beforeSubmitForm: before } = this
form.difficulty = v.difficulty form.difficulty = v.difficulty
form.givenYear = v.givenYear form.givenYear = v.givenYear
form.knowledgePointIds = this.beforeSubmitForm.knowledgePointIds form.knowledgePointIds = this.beforeSubmitForm.knowledgePointIds
form.questionType = v.questionType form.questionType = v.questionType
form.specialtyIds = v.specialtyIds form.specialtyIds = before.specialtyIds
this.questionTypeChange(v.questionType) this.questionTypeChange(v.questionType)
} else { } else {
this.handleSingleMultiple() this.handleSingleMultiple()
@ -423,7 +428,7 @@ export default {
pageSize: 1000, pageSize: 1000,
}) })
this.professionals = res.pageList.records this.professionals = res.pageList.records
if (!this.questionId) this.form.specialtyIds = [1] // if (!this.questionId) this.form.specialtyIds = [1]
} catch (e) { } } catch (e) { }
}, },
// //
@ -605,6 +610,7 @@ export default {
const opt = form.questionAnswerVersions const opt = form.questionAnswerVersions
if (!stem) return Util.warningMsg('请输入题干') if (!stem) return Util.warningMsg('请输入题干')
const blanks = this.fillBlanks
if (form.questionType !== 'fill_blank' && form.questionType !== 'essay') { if (form.questionType !== 'fill_blank' && form.questionType !== 'essay') {
let invalid = 0 let invalid = 0
for (const e of opt) { for (const e of opt) {
@ -614,9 +620,17 @@ export default {
break break
} }
} }
// debugger
if (invalid) return false if (invalid) return false
if (!opt.find(e => e.answerIsCorrect)) return Util.warningMsg('请设置正确答案') if (!opt.find(e => e.answerIsCorrect)) return Util.warningMsg('请设置正确答案')
} else if (form.questionType === 'fill_blank') {
for (const e of blanks) {
if (e.fills.every(n => !n.val)) {
Util.warningMsg('请输入填空项正确答案')
invalid = 1
break
}
}
} }
this.submiting = true this.submiting = true
@ -634,7 +648,6 @@ export default {
// fillBlanks // fillBlanks
if (form.questionType === 'fill_blank') { if (form.questionType === 'fill_blank') {
const blanks = this.fillBlanks
blanks.map((e, i) => e.serial = i + 1) // blanks.map((e, i) => e.serial = i + 1) //
form.questionAnswerVersions[0].answerData = JSON.stringify(blanks) form.questionAnswerVersions[0].answerData = JSON.stringify(blanks)
} else if (form.questionType === 'essay' && this.$refs.referenceAnswer) { } else if (form.questionType === 'essay' && this.$refs.referenceAnswer) {
@ -652,11 +665,11 @@ export default {
// //
await this.$post(this.api.checkQuestion, form) await this.$post(this.api.checkQuestion, form)
// //
this.saveQues() form.questionId || this.saveQues()
} else { }
// if (form.questionId) {
try { try {
await this.$confirm(`<p style="margin-bottom: 10px;">您确定要保存对本题所做的更改吗?</p>${this.detailType === 4 ? '' : '<p>保存后,所有关联的试卷将会自动更新</p>'}`, '提示', { await this.$confirm(`<p style="margin-bottom: 10px;">您确定要保存对本题所做的更改吗?</p>${this.detailType === 4 ? '' : '<p style="margin-bottom: 10px;">保存后,所有关联的试卷将会自动更新</p>'}${keep ? '<p>系统未识别到与本题相似的题目</p>' : ''}`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
@ -725,6 +738,10 @@ export default {
font-size: 13px; font-size: 13px;
} }
/deep/img {
max-width: 100%;
}
.sum { .sum {
margin: 15px 0; margin: 15px 0;
font-size: 13px; font-size: 13px;
@ -735,18 +752,32 @@ export default {
.fill-blanks { .fill-blanks {
.fills { .fills {
display: inline-flex; display: inline-flex;
align-items: center; align-items: flex-start;
flex-wrap: wrap;
flex: 1;
}
.fill-items {
width: calc(100% - 215px);
margin-right: 40px;
} }
.fill-item { .fill-item {
display: inline-flex; display: flex;
align-items: center; align-items: center;
margin-right: 10px; margin-bottom: 10px;
.el-input { .el-textarea {
width: 100px; width: 100%;
margin-right: 10px; margin-right: 10px;
} }
&:first-child,
&:last-child {
.el-textarea {
width: calc(100% - 52px);
}
}
} }
.add-fill { .add-fill {
@ -767,7 +798,7 @@ export default {
.opts { .opts {
.opt { .opt {
display: flex; display: flex;
align-items: center; align-items: flex-start;
margin-bottom: 15px; margin-bottom: 15px;
} }

@ -45,7 +45,8 @@
</li> </li>
<li> <li>
<label>专业</label> <label>专业</label>
<el-select v-model="filter.specialtyIds" clearable placeholder="请选择专业" multiple @change="initData"> <el-select v-model="filter.specialtyIds" filterable clearable placeholder="请选择专业" multiple
@change="initData">
<el-option v-for="(item, i) in professionals" :key="i" :label="item.professionalName" <el-option v-for="(item, i) in professionals" :key="i" :label="item.professionalName"
:value="item.professionalId"></el-option> :value="item.professionalId"></el-option>
</el-select> </el-select>
@ -64,7 +65,7 @@
</li> </li>
<li> <li>
<label>知识点</label> <label>知识点</label>
<el-cascader :disabled="isNotJoin !== 0" placeholder="请选择知识点" v-model="knowledgePointIds" <el-cascader :disabled="isNotJoin !== 0" filterable placeholder="请选择知识点" v-model="knowledgePointIds"
:options="knowledges" :props="{ value: 'id', label: 'name', multiple: true }" clearable collapse-tags :options="knowledges" :props="{ value: 'id', label: 'name', multiple: true }" clearable collapse-tags
@change="initData"></el-cascader> @change="initData"></el-cascader>
</li> </li>

@ -197,7 +197,6 @@ export default {
handleNodeClick () { handleNodeClick () {
this.isNotJoin = '' this.isNotJoin = ''
this.initData() this.initData()
this.$refs.table.clearSelection()
}, },
// //
async getList () { async getList () {

@ -94,18 +94,13 @@
<span>题库名称</span> <span>题库名称</span>
</div> </div>
<div class="able-check"> <div class="able-check lines">
<div v-for="(item, i) in quesBanks" :key="i" :class="['line', { active: curQuesBank.id === item.id }]" <div v-for="(item, i) in quesBanks" :key="i" :class="['line', { active: curQuesBank.id === item.id }]"
@click="questionBankClick(item)"> @click="questionBankClick(item)">
<span class="serial first">{{ i + 1 }}</span> <span class="serial first">{{ i + 1 }}</span>
<p class="stem" :title="item.questionBankName">{{ item.questionBankName }}</p> <p class="stem" :title="item.questionBankName">{{ item.questionBankName }}</p>
</div> </div>
</div> </div>
<div class="pagination">
<el-pagination background @current-change="currentChangeQuesBank" :current-page="pageQuesBank"
layout="total, prev, pager, next" :total="totalQuesBank"></el-pagination>
</div>
</template> </template>
<div v-else class="empty"> <div v-else class="empty">
<img class="icon" src="@/assets/images/empty.svg" alt=""> <img class="icon" src="@/assets/images/empty.svg" alt="">
@ -114,6 +109,7 @@
</div> </div>
<!-- 知识点 --> <!-- 知识点 -->
<div class="item"> <div class="item">
<p class="total m-b-10">知识点</p>
<ul class="filter"> <ul class="filter">
<li class="m-b-10"> <li class="m-b-10">
<label>知识点框架</label> <label>知识点框架</label>
@ -133,16 +129,13 @@
<span>知识点名称</span> <span>知识点名称</span>
</div> </div>
<div v-for="(item, i) in knowledges" :key="i" class="line"> <div class="lines">
<el-checkbox v-model="item.check" :disabled="item.disabled" <div v-for="(item, i) in knowledges" :key="i" class="line">
@change="val => knowledgeChange(val, item)"></el-checkbox> <el-checkbox v-model="item.check" :disabled="item.disabled"
<span class="serial">{{ i + 1 }}</span> @change="val => knowledgeChange(val, item)"></el-checkbox>
<p class="stem" :title="item.name">{{ item.name }}</p> <span class="serial">{{ i + 1 }}</span>
</div> <p class="stem" :title="item.name">{{ item.name }}</p>
</div>
<div class="pagination">
<el-pagination background @current-change="currentChangeKn" :current-page="pageKn"
layout="total, prev, pager, next" :total="totalKn"></el-pagination>
</div> </div>
</template> </template>
<div v-else class="empty"> <div v-else class="empty">
@ -235,6 +228,7 @@ export default {
yearAll: true, yearAll: true,
yearCheck: [], yearCheck: [],
submiting: false, submiting: false,
loaded: 0,
}; };
}, },
computed: { computed: {
@ -266,12 +260,15 @@ export default {
methods: { methods: {
// //
init () { init () {
this.yearCheck = this.years if (!this.loaded) {
this.handleQuesList() this.loaded = 1
this.getQuesBankType() this.yearCheck = this.years
this.initQuesBank() this.handleQuesList()
this.difficult = this.$parent.form.difficult this.getQuesBankType()
this.difficult && this.difficultChange(this.difficult) this.initQuesBank()
this.difficult = this.$parent.form.difficult
this.difficult && this.difficultChange(this.difficult)
}
}, },
// //
async getQuesBankType () { async getQuesBankType () {
@ -290,8 +287,8 @@ export default {
const type = this.quesBankTypeVal const type = this.quesBankTypeVal
const res = await this.$post(this.api.questionBankList, { const res = await this.$post(this.api.questionBankList, {
status: 1, status: 1,
pageNum: this.pageQuesBank, pageNum: 1,
pageSize: this.pageSizeQuesBank, pageSize: 1000,
questionCategoryId: type.length ? type[type.length - 1] : '', questionCategoryId: type.length ? type[type.length - 1] : '',
name: this.quesBankKeyword name: this.quesBankKeyword
}) })
@ -345,8 +342,8 @@ export default {
if (id) { if (id) {
const type = this.knowledgeTypeVal const type = this.knowledgeTypeVal
const res = await this.$post(this.api.knowledgeHierarchyList, { const res = await this.$post(this.api.knowledgeHierarchyList, {
pageNum: this.pageKn, pageNum: 1,
pageSize: this.pageSizeKn, pageSize: 1000,
questionBankId: id, questionBankId: id,
knowledgePointCategoryId: type.length ? type[type.length - 1] : '', knowledgePointCategoryId: type.length ? type[type.length - 1] : '',
name: this.knowledgeKeyword, name: this.knowledgeKeyword,
@ -501,15 +498,34 @@ export default {
async submit () { async submit () {
if (this.submiting) return false if (this.submiting) return false
const { list } = this const { list } = this
// let invalid = 0 let invalid = 0
// for (const e of list) { for (const i in list) {
// if (!e.questionType) { const e = list[i]
// Util.warningMsg('') const name = `${Util.arabicToChinese(+i + 1)}大题`
// invalid = 1 if (!e.questionType) {
// break Util.warningMsg(`${name}请先选择题型`)
// } invalid = 1
// } break
// if (invalid) return false }
if (!e.questionNum || isNaN(e.questionNum) || e.questionNum <= 0) {
Util.warningMsg(`${name}的目标题数请输入正整数`)
invalid = 1
break
}
let total = Decimal(e.basicDifficulty || 0).add(e.normalDifficulty || 0).add(e.hardDifficulty || 0).add(e.veryHardDifficulty || 0).toNumber() // 4
if (total) { // 41
this.$set(e, 'randomDifficulty', 0)
} else {
total = e.basicDifficulty || 0
}
console.log("🚀 ~ submit ~ total:", total)
if (total > e.questionNum) {
Util.warningMsg(`${name}的小题总数大于目标题数,请重新输入`)
invalid = 1
break
}
}
if (invalid) return false
this.submiting = true this.submiting = true
const k = this.allKnowledges.map(e => e.id) const k = this.allKnowledges.map(e => e.id)
@ -527,7 +543,7 @@ export default {
} }
}) })
list.map(e => { list.map(e => {
e.randomDifficulty = 0 // e.randomDifficulty = 0
e.givenYears = years e.givenYears = years
e.knowledgePointsIds = k e.knowledgePointsIds = k
}) })
@ -562,6 +578,7 @@ export default {
res.list[i].questions.map((e, i) => { res.list[i].questions.map((e, i) => {
// e.questionVersionId = e.id // e.questionVersionId = e.id
e.serialNumber = i + 1 e.serialNumber = i + 1
this.$parent.handleFillScore(e)
}) })
this.$parent.form.paperOutline[i].examQuestions = res.list[i].questions this.$parent.form.paperOutline[i].examQuestions = res.list[i].questions
}) })
@ -616,10 +633,8 @@ export default {
.item { .item {
width: 30%; width: 30%;
height: calc(100vh - 190px);
padding: 15px; padding: 15px;
border-right: 1px solid #eee; border-right: 1px solid #eee;
overflow: auto;
&:last-child { &:last-child {
width: 40%; width: 40%;
@ -645,6 +660,11 @@ export default {
margin-top: 10px; margin-top: 10px;
} }
.lines {
height: calc(100vh - 392px);
overflow: auto;
}
.line { .line {
display: flex; display: flex;
padding: 5px 0; padding: 5px 0;

@ -1,8 +1,8 @@
<template> <template>
<div class="page"> <div class="page">
<Breadcrumb :data="crumbs" /> <Breadcrumb :data="crumbs" />
<p class="page-name mb">试卷</p>
<el-form :model="form" :rules="rules" class="input-form model" ref="form" label-width="140px"> <el-form :model="form" :rules="rules" class="input-form model" ref="form" label-width="140px">
<p class="page-name mb">试卷基础信息</p>
<el-form-item prop="name" label="试卷名称"> <el-form-item prop="name" label="试卷名称">
<el-input style="width: 940px" placeholder="请输入试卷名称" v-model="form.name" clearable maxlength="100" /> <el-input style="width: 940px" placeholder="请输入试卷名称" v-model="form.name" clearable maxlength="100" />
</el-form-item> </el-form-item>
@ -14,7 +14,7 @@
</el-form-item> </el-form-item>
<el-form-item prop="classificationId" label="所属试卷分类"> <el-form-item prop="classificationId" label="所属试卷分类">
<el-cascader filterable placeholder="请选择所属试卷分类" :options="types" v-model="form.classificationId" <el-cascader filterable placeholder="请选择所属试卷分类" :options="types" v-model="form.classificationId"
:props="cascaderProps" clearable style="width: 100%"> :props="cascaderProps" style="width: 100%">
</el-cascader> </el-cascader>
</el-form-item> </el-form-item>
</div> </div>
@ -38,7 +38,8 @@
</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" placeholder="系统自动评估,也可手动选择" @change="difficultSelected = true"> <el-select v-model="form.difficult" clearable placeholder="系统自动评估,也可手动选择"
@change="val => difficultSelected = !!val">
<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"> <el-tooltip placement="top">
@ -67,9 +68,10 @@
<div class="line"></div> <div class="line"></div>
<div class="flex j-between m-b-20"> <p class="page-name mb">试卷大纲</p>
<p>默认模板</p> <div class="relative text-center m-b-40">
<el-button type="primary" size="small" @click="showTemplate">选择大纲模板</el-button> <p class="fs-16">{{ templateName }}</p>
<el-button class="tem-btn" type="primary" size="small" @click="showTemplate">选择大纲模板</el-button>
</div> </div>
<el-table :data="form.paperOutline" stripe header-align="center" row-key="id"> <el-table :data="form.paperOutline" stripe header-align="center" row-key="id">
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
@ -105,7 +107,7 @@
<div class="line"></div> <div class="line"></div>
<div class="flex j-between a-center"> <div class="flex j-between a-center">
<h6 class="page-name" style="margin-bottom: 0">选择试题</h6> <h6 class="page-name" style="margin-bottom: 0">试卷试题</h6>
<div> <div>
<el-button type="primary" @click="allocationAll">一键分配分值</el-button> <el-button type="primary" @click="allocationAll">一键分配分值</el-button>
<el-button type="primary" @click="showAuto">自动选题</el-button> <el-button type="primary" @click="showAuto">自动选题</el-button>
@ -144,7 +146,7 @@
<span class="label">{{ j + 1 }} / {{ item.examQuestions.length }}</span> <span class="label">{{ j + 1 }} / {{ item.examQuestions.length }}</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> </div>
<div class="stem" :id="'stem' + ques.questionVersionId" v-html="getQuesStem(ques)"></div> <div class="stem" :id="'stem' + ques.questionVersionId" v-html="ques.stem"></div>
</div> </div>
</div> </div>
@ -162,32 +164,32 @@
{{ item.questionType === 'essay' ? '参考答案' : '正确答案' }} {{ item.questionType === 'essay' ? '参考答案' : '正确答案' }}
<div v-html="getCorrectAnswer(ques)"></div> <div v-html="getCorrectAnswer(ques)"></div>
</div> </div>
<div class="actions"> </div>
<p v-if="item.questionType !== 'fill_blank'" class="m-r-10 input-wrap"> <div class="actions">
<el-input class="l-input" placeholder="请输入分值" v-model="ques.score" /></p> <p v-if="item.questionType !== 'fill_blank'" class="m-r-10 input-wrap">
<el-input class="l-input" placeholder="请输入分值" v-model="ques.score" /></p>
<el-popover v-else placement="bottom" width="400" trigger="click">
<div v-if="ques.fillScores" class="fill-scores"> <el-popover v-else placement="bottom" width="400" trigger="click">
<p class="fill-title">每空分值</p> <div v-if="ques.fillScores" class="fill-scores">
<div v-for="(score, k) in ques.fillScores" :key="k" class="input-wrap"> <p class="fill-title">每空分值</p>
<el-input class="l-input" placeholder="请输入分值" v-model="score.val" <div v-for="(score, k) in ques.fillScores" :key="k" class="input-wrap">
@change="fillScoreChange(ques)" />&emsp;填空项{{ k + 1 }} <el-input class="l-input" placeholder="请输入分值" v-model="score.val"
</div> @change="fillScoreChange(ques)" />&emsp;填空项{{ k + 1 }}
</div>
<div slot="reference" class="input-wrap">
查看每空分值<el-input class="l-input" placeholder="请输入分值" v-model="ques.score" />
</div> </div>
</el-popover>
<!-- <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)">添加试题</el-button>
<el-button type="text" @click="delQues(item, j)">移除试题</el-button>
<div class="input-wrap">
<span>排序</span>
<el-input class="l-input sort-input" v-model="ques.serialNumber"
@change="sortChange(item, ques)" />
</div> </div>
<div slot="reference" class="input-wrap">
查看每空分值<el-input class="l-input" placeholder="请输入分值" v-model="ques.score" readonly />
</div>
</el-popover>
<!-- <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)">添加试题</el-button>
<el-button type="text" @click="delQues(item, j)">移除试题</el-button>
<div class="input-wrap">
<span>排序</span>
<el-input class="l-input sort-input" v-model="ques.serialNumber"
@change="sortChange(item, ques)" />
</div> </div>
</div> </div>
</div> </div>
@ -198,8 +200,8 @@
</ul> </ul>
</el-form> </el-form>
<div class="btns"> <div class="btns">
<el-button @click="submit(1)">保存草稿</el-button> <el-button @click="submit(0)">保存草稿</el-button>
<el-button type="primary" @click="submit(0)">发布</el-button> <el-button type="primary" @click="submit(1)">发布</el-button>
<el-button v-if="paperId" @click="preview">预览</el-button> <el-button v-if="paperId" @click="preview">预览</el-button>
<el-button @click="back">取消</el-button> <el-button @click="back">取消</el-button>
</div> </div>
@ -224,6 +226,7 @@ import dayjs from 'dayjs'
import QuesConst from '@/const/ques' import QuesConst from '@/const/ques'
import TestPaperConst from '@/const/testPaper' import TestPaperConst from '@/const/testPaper'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
import { template } from 'lodash'
export default { export default {
components: { UeditorPlus, Breadcrumb, Template, Manual, Auto, RepeatQues, Draggable }, components: { UeditorPlus, Breadcrumb, Template, Manual, Auto, RepeatQues, Draggable },
@ -333,6 +336,7 @@ export default {
{ required: true, message: '请输入试卷名称', trigger: 'blur' } { required: true, message: '请输入试卷名称', trigger: 'blur' }
], ],
}, },
templateName: '默认模板',
templateVisible: false, templateVisible: false,
manualVisible: false, manualVisible: false,
curType: {}, curType: {},
@ -399,11 +403,12 @@ export default {
e.examQuestions.map((n, j) => { e.examQuestions.map((n, j) => {
n.originSort = j + 1 n.originSort = j + 1
Object.assign(n, n.question) Object.assign(n, n.question)
this.handleFillScore(n)
}) })
}) })
if (r.particularYear) r.particularYear = r.particularYear + '' if (r.particularYear) r.particularYear = r.particularYear + ''
if (r.professionalId) r.professionalId = r.professionalId.split(',').map(e => +e) r.professionalId = r.professionalId ? r.professionalId.split(',').map(e => +e) : []
this.form = r this.form = r
} }
} catch (e) { } } catch (e) { }
@ -530,14 +535,11 @@ export default {
data.avgValueList.map((e, i) => { data.avgValueList.map((e, i) => {
// scores-1 // scores-1
if (!e.scores.includes(-1)) { if (!e.scores.includes(-1)) {
const stem = document.querySelector(`#stem` + e.questionVersionId) const { fillScores } = list[i]
if (stem) { debugger
const inputs = stem.querySelectorAll('.fill-input') if (fillScores) {
if (inputs) { for (const j in fillScores) {
for (const j in e.scores) { fillScores[j].val = e.scores[j]
const item = inputs[j]
inputs[j].value = e.scores[j]
}
} }
} }
} }
@ -588,35 +590,45 @@ export default {
} 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) if (e.questionAnswerVersionsList) {
return correct ? (e.questionType === 'judgement' ? correct[0].optionText : correct.map(e => Util.numToLetter(e.optionNumber - 1)).join('')) : '' // ABC 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('')) : '' // ABC
}
} }
}, },
//
getQuesStem (ques) { //
let { stem } = ques handleFillScore (ques) {
try { try {
if (ques.questionType === 'fill_blank') { // const opts = ques.questionAnswerVersionsList
let { jsonText } = ques if (ques.questionType === 'fill_blank' && opts && opts.length) {
if (jsonText) { // json
jsonText = JSON.parse(jsonText) let { answerData } = opts[0]
const scores = jsonText.scores.map(e => { if (answerData) {
answerData = JSON.parse(answerData)
//
let { jsonText } = ques
let scores
if (jsonText) {
jsonText = JSON.parse(jsonText)
scores = jsonText.scores
}
const fillScores = answerData.map((e, i) => {
return { return {
val: e val: scores ? scores[i] : ''
} }
}) })
console.log("🚀 ~ getQuesStem ~ ques.scores:", scores) ques.fillScores = fillScores
// this.$set(ques, 'fillScores', scores)
} }
} }
} catch (e) { } } catch (e) { }
return stem
}, },
// //
fillScoreChange (ques) { fillScoreChange (ques) {
let total = 0 let total = 0
ques.scores.map(e => { ques.fillScores.map(e => {
if (e.val && !isNaN(e.val)) total = Decimal(total).add(e.val).toNumber() if (e.val && !isNaN(e.val)) total = Decimal(total).add(e.val).toNumber()
}) })
ques.score = total ques.score = total
@ -707,18 +719,20 @@ export default {
if (e.questionType !== 'fill_blank' && e.questionType !== 'essay') { if (e.questionType !== 'fill_blank' && e.questionType !== 'essay') {
// //
const opts = e.questionAnswerVersionsList const opts = e.questionAnswerVersionsList
let diff = 0 if (opts) {
for (const j in opts) { let diff = 0
// debugger for (const j in opts) {
if (!n.questionAnswerVersionsList[j] || n.questionAnswerVersionsList[j].optionText !== opts[j].optionText) { // debugger
diff = 1 if (!n.questionAnswerVersionsList || !n.questionAnswerVersionsList[j] || n.questionAnswerVersionsList[j].optionText !== opts[j].optionText) {
break diff = 1
break
}
} }
}
if (e.questionType === n.questionType && e.stem === n.stem && !diff) { if (e.questionType === n.questionType && e.stem === n.stem && !diff) {
e.repeat = true e.repeat = true
n.repeat = true n.repeat = true
}
} }
} else { } else {
// /+ // /+
@ -741,7 +755,7 @@ export default {
}, },
// //
submit (status) { submit (status) {
if (status) { if (!status) {
// 稿 // 稿
if (!this.form.name) return Util.warningMsg('请输入试卷名称') if (!this.form.name) return Util.warningMsg('请输入试卷名称')
this.validForm(status) this.validForm(status)
@ -750,7 +764,7 @@ export default {
const { form } = this const { form } = this
if (form.name === '') return Util.warningMsg('请输入试卷名称') if (form.name === '') return Util.warningMsg('请输入试卷名称')
if (!form.particularYear) return Util.warningMsg('请选择年份') if (!form.particularYear) return Util.warningMsg('请选择年份')
if (!form.classificationId.length) return Util.warningMsg('请选择所属试卷分类') if (!form.classificationId) return Util.warningMsg('请选择所属试卷分类')
if (form.paperType === '') return Util.warningMsg('请选择建议用途') if (form.paperType === '') return Util.warningMsg('请选择建议用途')
if (form.suggestTime === '') return Util.warningMsg('请输入估计用时') if (form.suggestTime === '') return Util.warningMsg('请输入估计用时')
if (valid) { if (valid) {
@ -778,7 +792,7 @@ export default {
const allQues = [] const allQues = []
// //
if (!status) { if (status) {
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('估计用时请输入正整数')
let invalid = 0 let invalid = 0
for (const i in paper) { for (const i in paper) {
@ -816,13 +830,10 @@ export default {
if (e.questionType === 'fill_blank') { if (e.questionType === 'fill_blank') {
let totalScore = 0 let totalScore = 0
e.examQuestions.map(n => { e.examQuestions.map(n => {
const stem = document.querySelector(`#stem` + n.questionVersionId) const { fillScores } = n
if (stem) { if (fillScores) {
const inputs = stem.querySelectorAll('.fill-input') for (const e of fillScores) {
if (inputs) { totalScore = Decimal(totalScore).add(e.val || 0).toNumber()
for (const e of inputs) {
totalScore = Decimal(totalScore).add(e.value || 0).toNumber()
}
} }
} }
}) })
@ -876,21 +887,13 @@ export default {
e.examQuestions = e.examQuestions.map((n, j) => { e.examQuestions = e.examQuestions.map((n, j) => {
// //
if (n.questionType === 'fill_blank') { if (n.questionType === 'fill_blank') {
const stem = document.querySelector(`#stem` + n.questionVersionId) const { fillScores } = n
const scores = []
if (stem) {
const inputs = stem.querySelectorAll('.fill-input')
if (inputs) {
for (const e of inputs) {
scores.push(e.value)
}
}
}
n.jsonText = JSON.stringify({ n.jsonText = JSON.stringify({
questionVersionId: n.questionVersionId, questionVersionId: n.questionVersionId,
scores scores: fillScores ? fillScores.map(m => m.val) : []
}) })
} }
return { return {
questionVersionId: n.questionVersionId, questionVersionId: n.questionVersionId,
serialNumber: n.serialNumber, serialNumber: n.serialNumber,
@ -925,8 +928,19 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.input-form.model {
height: calc(100vh - 130px);
}
.tem-btn {
position: absolute;
top: 0;
right: 0;
}
.ques { .ques {
li { li {
padding-bottom: 10px;
margin: 20px 0 10px; margin: 20px 0 10px;
border: 1px solid #dbdbdb; border: 1px solid #dbdbdb;
} }
@ -980,6 +994,10 @@ export default {
padding: 15px; padding: 15px;
} }
/deep/img {
max-width: 100%;
}
.ques-info { .ques-info {
position: relative; position: relative;
width: calc(100% - 40px); width: calc(100% - 40px);
@ -1070,26 +1088,6 @@ export default {
} }
} }
/deep/.fill-input {
width: 100px;
height: 28px;
padding: 0 15px;
margin: 0 10px;
font-size: 13px;
line-height: 28px;
color: #606266;
border: 1px solid #DCDEE0;
border-radius: 2px;
&::placeholder {
color: #cfd1db;
}
&:focus {
outline: none;
}
}
.opt { .opt {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
@ -1117,8 +1115,10 @@ export default {
} }
.actions { .actions {
display: inline-flex; display: flex;
justify-content: flex-end;
align-items: center; align-items: center;
margin-top: 10px;
.el-button { .el-button {
margin: 0 20px 0 0; margin: 0 20px 0 0;

@ -24,18 +24,13 @@
<span>题库名称</span> <span>题库名称</span>
</div> </div>
<div class="able-check"> <div class="able-check lines">
<div v-for="(item, i) in quesBanks" :key="i" :class="['line', { active: curQuesBank.id === item.id }]" <div v-for="(item, i) in quesBanks" :key="i" :class="['line', { active: curQuesBank.id === item.id }]"
@click="questionBankClick(item)"> @click="questionBankClick(item)">
<span class="serial">{{ i + 1 }}</span> <span class="serial">{{ i + 1 }}</span>
<p class="quesBank" :title="item.questionBankName">{{ item.questionBankName }}</p> <p class="quesBank" :title="item.questionBankName">{{ item.questionBankName }}</p>
</div> </div>
</div> </div>
<div class="pagination">
<el-pagination background @current-change="currentChangeQuesBank" small :current-page="pageQuesBank"
layout="total, prev, pager, next" :total="totalQuesBank"></el-pagination>
</div>
</template> </template>
<div v-else class="empty"> <div v-else class="empty">
<img class="icon" src="@/assets/images/empty.svg" alt=""> <img class="icon" src="@/assets/images/empty.svg" alt="">
@ -65,16 +60,18 @@
<span class="kl">知识点</span> <span class="kl">知识点</span>
</div> </div>
<div v-for="(item, i) in ques" :key="i" class="line"> <div class="lines">
<el-checkbox v-model="item.check" :disabled="item.disabled" <div v-for="(item, i) in ques" :key="i" class="line">
@change="val => quesChange(val, item)"></el-checkbox> <el-checkbox v-model="item.check" :disabled="item.disabled"
<span class="serial">{{ i + 1 }}</span> @change="val => quesChange(val, item)"></el-checkbox>
<el-tooltip effect="dark" :content="item.stemText" placement="top-start"> <span class="serial">{{ i + 1 }}</span>
<p class="stem">{{ item.stemText }}</p> <el-tooltip effect="dark" :content="item.stemText" placement="top-start">
</el-tooltip> <p class="stem">{{ item.stemText }}</p>
<el-tooltip effect="dark" :content="item.knowledgePointName" placement="top-start"> </el-tooltip>
<p class="kl">{{ item.knowledgePointName }}</p> <el-tooltip effect="dark" :content="item.knowledgePointName" placement="top-start">
</el-tooltip> <p class="kl">{{ item.knowledgePointName }}</p>
</el-tooltip>
</div>
</div> </div>
</template> </template>
<div v-else class="empty"> <div v-else class="empty">
@ -256,8 +253,8 @@ export default {
const type = this.quesBankTypeVal const type = this.quesBankTypeVal
const res = await this.$post(this.api.questionBankList, { const res = await this.$post(this.api.questionBankList, {
status: 1, status: 1,
pageNum: this.pageQuesBank, pageNum: 1,
pageSize: this.pageSizeQuesBank, pageSize: 1000,
questionCategoryId: type.length ? type[type.length - 1] : '', questionCategoryId: type.length ? type[type.length - 1] : '',
name: this.quesBankKeyword name: this.quesBankKeyword
}) })
@ -441,6 +438,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.$parent.handleFillScore(e)
// this.$set(e, 'questionVersionId', e.questionVersionId) // this.$set(e, 'questionVersionId', e.questionVersionId)
}) })
@ -502,10 +500,8 @@ export default {
.item { .item {
width: 38%; width: 38%;
height: calc(100vh - 173px);
padding: 15px; padding: 15px;
border-right: 1px solid #eee; border-right: 1px solid #eee;
overflow: auto;
} }
.total { .total {
@ -513,6 +509,10 @@ export default {
color: #333; color: #333;
} }
.lines {
height: calc(100vh - 358px);
overflow: auto;
}
.line { .line {
display: flex; display: flex;

@ -245,6 +245,7 @@ export default {
e.examQuestions = [] e.examQuestions = []
}) })
this.$parent.form.paperOutline = data.paperOutline this.$parent.form.paperOutline = data.paperOutline
this.$parent.templateName = data.templateName
this.listVisible = false this.listVisible = false
}, },
// //

@ -76,7 +76,8 @@
</li> </li>
<li> <li>
<label>所属专业</label> <label>所属专业</label>
<el-select v-model="filter.professionalId" clearable placeholder="请选择所属专业" multiple @change="initData"> <el-select v-model="filter.professionalId" filterable clearable placeholder="请选择所属专业" multiple
@change="initData">
<el-option v-for="(item, i) in professionals" :key="i" :label="item.professionalName" <el-option v-for="(item, i) in professionals" :key="i" :label="item.professionalName"
:value="item.professionalId"></el-option> :value="item.professionalId"></el-option>
</el-select> </el-select>
@ -249,8 +250,8 @@ export default {
difficult: [], difficult: [],
professionalId: [], professionalId: [],
paperType: '', paperType: '',
updateTimeOrder: 2, updateTimeOrder: '',
crateTimeOrder: '', crateTimeOrder: 2,
yearOrder: '', yearOrder: '',
keyWord: '', keyWord: '',
difficultOrder: '', difficultOrder: '',
@ -384,9 +385,8 @@ export default {
}, },
// //
handleNodeClick (data) { handleNodeClick (data) {
this.$refs.table.clearSelection()
this.isNotJoin = '' this.isNotJoin = ''
this.getList() this.initData()
}, },
// //
closeType () { closeType () {

@ -243,7 +243,7 @@ export default {
async switchOff (val, row) { async switchOff (val, row) {
try { try {
row.isDisable = !val row.isDisable = !val
if (val) { if (val && row.children && row.children.length) {
await this.$confirm(`<p>确认要禁用【${row.libraryClassificationName}】吗?</p><p style="color: #f56c6c;">禁用后,此试卷库分类及其子分类将被禁用</p>`, '提示', { await this.$confirm(`<p>确认要禁用【${row.libraryClassificationName}】吗?</p><p style="color: #f56c6c;">禁用后,此试卷库分类及其子分类将被禁用</p>`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',

@ -38,7 +38,9 @@ service.interceptors.response.use(
if (!logouted) { if (!logouted) {
Util.local.remove(Setting.storeKey) Util.local.remove(Setting.storeKey)
Util.local.remove(Setting.tokenKey) Util.local.remove(Setting.tokenKey)
window.top.exitSystem && window.top.exitSystem()
Util.errorMsg(res.msg.includes('顶') ? '您的账号已在其他设备登录,您已被迫下线!' : '登录过期,请重新登录!') Util.errorMsg(res.msg.includes('顶') ? '您的账号已在其他设备登录,您已被迫下线!' : '登录过期,请重新登录!')
localStorage.removeItem('examPath')
setTimeout(() => { setTimeout(() => {
// store.dispatch('user/logout') // store.dispatch('user/logout')
logouted = 0 logouted = 0

Loading…
Cancel
Save