yujialong 3 months ago
parent b15d416d74
commit 3de7b8fad9
  1. 6
      src/libs/util.js
  2. 20
      src/pages/knowledge/index.vue
  3. 34
      src/pages/ques/detail/index.vue
  4. 14
      src/pages/testPaper/detail/auto.vue
  5. 97
      src/pages/testPaper/detail/index.vue
  6. 28
      src/pages/testPaper/detail/manual.vue
  7. 3
      src/pages/testPaper/list/index.vue

@ -147,6 +147,12 @@ const util = {
return result return result
}, },
// 去掉html里的标签及空格 // 去掉html里的标签及空格
delTag (html) {
const el = document.createElement('div')
el.innerHTML = html
return el.innerText
},
// 循环去掉列表里html里的标签及空格
removeTag (list, prop = 'stem') { removeTag (list, prop = 'stem') {
list.map(e => { list.map(e => {
const el = document.createElement('div') const el = document.createElement('div')

@ -1,6 +1,6 @@
<template> <template>
<div class="page"> <div :class="['page', { inQues }]">
<Breadcrumb style="margin-bottom: 0;" :data="crumbs" /> <Breadcrumb v-if="!inQues" style="margin-bottom: 0;" :data="crumbs" />
<div class="wrap"> <div class="wrap">
<div class="side"> <div class="side">
<div class="m-b-20"> <div class="m-b-20">
@ -41,7 +41,7 @@
</div> </div>
<el-dialog :title="typeForm.id ? '编辑' : '新增' + '知识点分类'" :visible.sync="typeVisible" <el-dialog :title="typeForm.id ? '编辑' : '新增' + '知识点分类'" :visible.sync="typeVisible"
:close-on-click-modal="false" width="400px"> :close-on-click-modal="false" append-to-body width="400px">
<el-form v-if="typeVisible" ref="typeForm" :model="typeForm" :rules="typeRules" label-width="130px"> <el-form v-if="typeVisible" ref="typeForm" :model="typeForm" :rules="typeRules" label-width="130px">
<el-form-item label="知识点分类名称" prop="name"> <el-form-item label="知识点分类名称" prop="name">
<el-input v-model.trim="typeForm.name" placeholder="请输入知识点分类" maxlength="20"></el-input> <el-input v-model.trim="typeForm.name" placeholder="请输入知识点分类" maxlength="20"></el-input>
@ -98,7 +98,7 @@
layout="total, prev, pager, next" :total="total"></el-pagination> layout="total, prev, pager, next" :total="total"></el-pagination>
</div> </div>
<el-dialog :title="!form.id ? '添加知识点' : '编辑知识点'" :visible.sync="knowledgeVisible" width="400px" <el-dialog :title="!form.id ? '添加知识点' : '编辑知识点'" :visible.sync="knowledgeVisible" width="400px" append-to-body
:close-on-click-modal="false"> :close-on-click-modal="false">
<el-form :model="form" :rules="rules" label-width="100px"> <el-form :model="form" :rules="rules" label-width="100px">
<el-form-item prop="parentId" label="知识点分类"> <el-form-item prop="parentId" label="知识点分类">
@ -118,7 +118,8 @@
</div> </div>
<el-dialog title="提示" :visible.sync="delVisible" width="400px" :close-on-click-modal="false" custom-class="del-dia"> <el-dialog title="提示" :visible.sync="delVisible" width="400px" :close-on-click-modal="false" append-to-body
custom-class="del-dia">
<div class="del-wrap"> <div class="del-wrap">
<div class="icon el-icon-warning"></div> <div class="icon el-icon-warning"></div>
<div> <div>
@ -142,7 +143,9 @@ export default {
components: { Breadcrumb }, components: { Breadcrumb },
data () { data () {
return { return {
crumbs: [],
questionBankId: this.$route.query.questionBankId, questionBankId: this.$route.query.questionBankId,
inQues: false,
createSource: 1, createSource: 1,
loading: false, loading: false,
keyword: '', keyword: '',
@ -226,7 +229,8 @@ export default {
{ {
name: '知识点列表' name: '知识点列表'
}, },
], ]
this.inQues = this.$route.path === '/ques/detail' //
this.getType() this.getType()
}, },
methods: { methods: {
@ -463,6 +467,10 @@ export default {
width: 100%; width: 100%;
} }
.inQues {
padding: 0 25px;
}
.wrap { .wrap {
display: flex; display: flex;

@ -36,9 +36,10 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="knowledgePointIds" label="所属知识点"> <el-form-item prop="knowledgePointIds" label="所属知识点">
<el-cascader placeholder="请选择所属知识点" v-model="form.knowledgePointIds" :options="knowledges" <el-cascader class="m-r-10" placeholder="请选择所属知识点" v-model="form.knowledgePointIds" :options="knowledges"
:props="{ value: 'id', label: 'name', multiple: true, checkStrictly: true }" :show-all-levels="false" :props="{ value: 'id', label: 'name', multiple: true, checkStrictly: true }" :show-all-levels="false"
filterable clearable></el-cascader> filterable clearable></el-cascader>
<el-button @click="toKp">设置</el-button>
</el-form-item> </el-form-item>
</div> </div>
<div class="item-line"> <div class="item-line">
@ -208,6 +209,12 @@
<el-button type="primary" @click="saveQues">确定</el-button> <el-button type="primary" @click="saveQues">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-drawer title="知识点设置" :visible.sync="kpVisible" size="1200px" :close-on-click-modal="false" append-to-body
custom-class="kp-dia" @closed="getKnowledge">
<Knowledge />
</el-drawer>
</div> </div>
</template> </template>
<script> <script>
@ -215,6 +222,7 @@ import Setting from '@/setting'
import Util from '@/libs/util' import Util from '@/libs/util'
import Breadcrumb from '@/components/breadcrumb' import Breadcrumb from '@/components/breadcrumb'
import UeditorPlus from '@/components/ueditorPlus' import UeditorPlus from '@/components/ueditorPlus'
import Knowledge from '@/pages/knowledge'
import Upload from '@/components/upload' import Upload from '@/components/upload'
import Oss from '@/components/upload/upload.js' import Oss from '@/components/upload/upload.js'
import dayjs from 'dayjs' import dayjs from 'dayjs'
@ -223,7 +231,7 @@ import Const from '@/const/ques'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
export default { export default {
props: ['paperType', 'curQues'], // props: ['paperType', 'curQues'], //
components: { Breadcrumb, UeditorPlus, Upload }, components: { Breadcrumb, UeditorPlus, Upload, Knowledge },
data () { data () {
return { return {
crumbs: [], crumbs: [],
@ -295,7 +303,9 @@ export default {
keep: 0, keep: 0,
repeatVisible: false, repeatVisible: false,
repeats: [] repeats: [],
kpVisible: false,
}; };
}, },
computed: { computed: {
@ -397,10 +407,11 @@ export default {
const opts = r.questionAnswerVersionsList const opts = r.questionAnswerVersionsList
opts.map(e => e.focus = 0) opts.map(e => e.focus = 0)
const isCopy = this.detailType === 1
this.form = { this.form = {
questionId: r.questionId, questionId: isCopy ? '' : r.questionId,
questionType: r.questionType, questionType: r.questionType,
questionVersionId: r.questionVersionId, questionVersionId: isCopy ? '' : r.questionVersionId,
version: r.version, version: r.version,
givenYear: r.givenYear, givenYear: r.givenYear,
difficulty: r.difficulty, difficulty: r.difficulty,
@ -456,6 +467,10 @@ export default {
} catch (e) { } } catch (e) { }
} }
}, },
//
toKp () {
this.kpVisible = true
},
// //
async getProfessional () { async getProfessional () {
try { try {
@ -699,7 +714,6 @@ export default {
e.optionNumber = i + 1 e.optionNumber = i + 1
}) })
} }
// debugger
this.tempForm = form this.tempForm = form
this.keep = keep this.keep = keep
// 3 // 3
@ -711,7 +725,7 @@ export default {
} }
if (form.questionId) { if (form.questionId) {
try { try {
await this.$confirm(`<p style="margin-bottom: 10px;">您确定要保存对本题所做的更改吗?</p>${this.detailType === 4 ? '' : `<p style="margin-bottom: 10px;">保存后,所有关联的试卷将会自动更新。${keep ? '系统未识别到与本题相似的题目' : ''}</p>`}`, '提示', { await this.$confirm(`<p style="margin-bottom: 10px;">您确定要保存对本题所做的更改吗?</p>${this.detailType === 4 ? '' : `<p>保存后,所有关联的试卷将会自动更新。${keep ? '系统未识别到与本题相似的题目' : ''}</p>`}`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
@ -888,4 +902,10 @@ export default {
.correct-check { .correct-check {
margin-right: 15px; margin-right: 15px;
} }
/deep/.kp-dia {
.el-drawer__header {
margin-bottom: 0;
}
}
</style> </style>

@ -348,8 +348,12 @@ export default {
knowledgePointCategoryId: type.length ? type[type.length - 1] : '', knowledgePointCategoryId: type.length ? type[type.length - 1] : '',
name: this.knowledgeKeyword, name: this.knowledgeKeyword,
}) })
this.knowledges = res.message.records const list = res.message.records
this.totalKn = res.message.total const { allKnowledges } = this
list.map(e => {
e.check = !!allKnowledges.find(n => n.id === e.id)
})
this.knowledges = list
} }
} catch (e) { } } catch (e) { }
}, },
@ -499,6 +503,7 @@ export default {
if (this.submiting) return false if (this.submiting) return false
const { list } = this const { list } = this
let invalid = 0 let invalid = 0
let totalCount = 0
for (const i in list) { for (const i in list) {
const e = list[i] const e = list[i]
const name = `${Util.arabicToChinese(+i + 1)}大题` const name = `${Util.arabicToChinese(+i + 1)}大题`
@ -515,17 +520,16 @@ export default {
let total = Decimal(e.basicDifficulty || 0).add(e.normalDifficulty || 0).add(e.hardDifficulty || 0).add(e.veryHardDifficulty || 0).toNumber() // 4 let total = Decimal(e.basicDifficulty || 0).add(e.normalDifficulty || 0).add(e.hardDifficulty || 0).add(e.veryHardDifficulty || 0).toNumber() // 4
if (total) { // 41 if (total) { // 41
this.$set(e, 'randomDifficulty', 0) this.$set(e, 'randomDifficulty', 0)
} else {
total = e.basicDifficulty || 0
} }
console.log("🚀 ~ submit ~ total:", total)
if (total > e.questionNum) { if (total > e.questionNum) {
Util.warningMsg(`${name}的小题总数大于目标题数,请重新输入`) Util.warningMsg(`${name}的小题总数大于目标题数,请重新输入`)
invalid = 1 invalid = 1
break break
} }
totalCount = Decimal(totalCount).add(total).toNumber()
} }
if (invalid) return false if (invalid) return false
if (!totalCount) return Util.warningMsg(`请填写难度题数`)
this.submiting = true this.submiting = true
const k = this.allKnowledges.map(e => e.id) const k = this.allKnowledges.map(e => e.id)

@ -104,7 +104,7 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<p class="m-t-10 m-b-20 text-right">目标总题数{{ questionCount }}目标总分{{ score }}</p> <p class="m-t-10 m-b-20 text-right">目标总题数{{ overview.questionCount }}目标总分{{ overview.totalScore }}</p>
<div class="line"></div> <div class="line"></div>
@ -140,7 +140,6 @@
@update="e => updateSort(e, item)"> @update="e => updateSort(e, item)">
<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>
{{ ques.repeat }}
<div :class="['ques-info', { disabled: !ques.status, del: ques.isDel, repeat: ques.repeat }]"> <div :class="['ques-info', { disabled: !ques.status, del: ques.isDel, repeat: ques.repeat }]">
<div class="top-line"> <div class="top-line">
<div class="stem-info"> <div class="stem-info">
@ -168,7 +167,7 @@
查看每空分值<el-input class="l-input" placeholder="请输入分值" v-model="ques.score" readonly /> 查看每空分值<el-input class="l-input" placeholder="请输入分值" v-model="ques.score" readonly />
</div> </div>
</el-popover> </el-popover>
<el-button type="text" @click="toQues(item, j, ques)">编辑试题</el-button> <el-button v-if="!ques.isDel" 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>
@ -216,6 +215,31 @@
</div> </div>
</div> </div>
<div v-if="form.paperOutline && form.paperOutline.length" class="layer">
<table class="table">
<thead>
<tr>
<th width="30%">大题</th>
<th width="35%">已添加题数/目标题数</th>
<th width="35%">已分配分值/目标分值</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, i) in form.paperOutline" :key="i">
<td>{{ arabicToChinese(i + 1) }}大题</td>
<td>{{ item.examQuestions.length }}/{{ item.questionNum }}</td>
<td>{{ item.examQuestions.reduce((e, j) => (e += +j.score), 0) }}/{{ item.targetScore }}</td>
</tr>
<tr>
<td>总计</td>
<td>{{ overview.alreadyQuesCount }}/{{ overview.questionCount }}</td>
<td>{{ overview.alreadyScore }}/{{ overview.totalScore }}</td>
</tr>
</tbody>
</table>
</div>
<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" />
@ -386,8 +410,32 @@ export default {
// //
score () { score () {
return this.form.paperOutline.reduce((e, j) => (e += +j.targetScore), 0) return this.form.paperOutline.reduce((e, j) => (e += +j.targetScore), 0)
},
//
overview () {
const paper = this.form.paperOutline
let questionCount = 0
let alreadyQuesCount = 0
let totalScore = 0
let alreadyScore = 0
paper.forEach(e => {
questionCount += +e.questionNum //
if (e.examQuestions) {
alreadyQuesCount += e.examQuestions.length //
totalScore = Decimal(totalScore).add(+e.targetScore || 0).toNumber() //
e.examQuestions.forEach(n => {
alreadyScore = Decimal(alreadyScore).add(+n.score || 0).toNumber() //
})
}
})
return {
questionCount,
alreadyQuesCount,
totalScore,
alreadyScore,
} }
}, },
},
mounted () { mounted () {
this.crumbs = [ this.crumbs = [
{ {
@ -674,7 +722,7 @@ export default {
this.curRow = ques this.curRow = ques
this.addQuesVisible = true this.addQuesVisible = true
}, },
// //
closeAdd () { closeAdd () {
this.addQuesVisible = false this.addQuesVisible = false
}, },
@ -824,7 +872,7 @@ export default {
// //
async validForm (status) { async validForm (status) {
if (this.submiting) return false if (this.submiting) return false
const { isCopy } = this // const { isCopy, overview } = this //
const form = _.cloneDeep(this.form) const form = _.cloneDeep(this.form)
const paper = form.paperOutline const paper = form.paperOutline
const allQues = [] const allQues = []
@ -909,9 +957,9 @@ export default {
form.professionalId = form.professionalId.join() form.professionalId = form.professionalId.join()
form.particularYear = +(dayjs(form.particularYear).format('YYYY')) form.particularYear = +(dayjs(form.particularYear).format('YYYY'))
form.libraryId = this.libraryId form.libraryId = this.libraryId
form.questionCount = this.questionCount form.questionCount = overview.questionCount
form.remarks = this.$refs.remarks.getUEContent() form.remarks = this.$refs.remarks.getUEContent()
form.score = this.score form.score = overview.totalScore
form.status = status form.status = status
paper.map(e => { paper.map(e => {
@ -1059,6 +1107,7 @@ export default {
color: #fff; color: #fff;
background-color: #f00; background-color: #f00;
transform: rotate(45deg); transform: rotate(45deg);
opacity: .6;
} }
} }
@ -1181,6 +1230,40 @@ export default {
} }
} }
.layer {
z-index: 2000;
position: fixed;
top: 40%;
right: 10px;
width: 265px;
max-height: 300px;
background-color: #fff;
box-shadow: 0 0 7px rgba(235, 235, 235, .8);
overflow: auto;
.table {
text-align: center;
border-collapse: collapse;
th {
padding: 10px 8px;
font-size: 13px;
color: #fff;
background-color: #2bbb61;
}
td {
padding: 10px;
font-size: 12px;
color: #333;
&:first-child {
background-color: #f1f1f1;
}
}
}
}
/deep/.editques-dia { /deep/.editques-dia {
.el-drawer__header { .el-drawer__header {
margin-bottom: 0; margin-bottom: 0;

@ -104,7 +104,7 @@
<span class="kl">知识点</span> <span class="kl">知识点</span>
</div> </div>
<div class="lines"> <div :class="['lines', { switch: $parent.curQues }]">
<template v-for="(item, i) in checked"> <template v-for="(item, i) in checked">
<div v-if="item.stemText.includes(checkedKeyword) || item.knowledgePointName.includes(checkedKeyword)" <div v-if="item.stemText.includes(checkedKeyword) || item.knowledgePointName.includes(checkedKeyword)"
:key="i" class="line"> :key="i" class="line">
@ -241,8 +241,9 @@ export default {
this.knowledgeKeyword = '' this.knowledgeKeyword = ''
// //
const parent = this.$parent.curType const { curType, curQues } = this.$parent
this.curCheckQues = parent.examQuestions if (curQues) curQues.stemText = Util.delTag(curQues.stem)
this.curCheckQues = curType.examQuestions
this.getQuesBankType() this.getQuesBankType()
this.initQuesBank() this.initQuesBank()
@ -338,9 +339,7 @@ export default {
const data = list const data = list
const { curCheckQues, checked } = this const { curCheckQues, checked } = this
data.map(e => { data.map(e => {
const el = document.createElement('div') e.stemText = Util.delTag(e.stem)
el.innerHTML = e.stem
e.stemText = el.innerText
const quesChecked = !!curCheckQues.find(n => n.questionVersionId === e.questionVersionId) const quesChecked = !!curCheckQues.find(n => n.questionVersionId === e.questionVersionId)
e.disabled = quesChecked e.disabled = quesChecked
e.check = !!checked.find(n => n.questionVersionId === e.questionVersionId) || quesChecked e.check = !!checked.find(n => n.questionVersionId === e.questionVersionId) || quesChecked
@ -385,12 +384,6 @@ export default {
try { try {
const checked = this.checked.filter(e => e.check) const checked = this.checked.filter(e => e.check)
if (checked.length) { if (checked.length) {
await this.$confirm(`确认要移除吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
closeOnClickModal: false,
})
checked.map(e => { checked.map(e => {
const cur = this.ques.find(n => n.questionVersionId === e.questionVersionId) const cur = this.ques.find(n => n.questionVersionId === e.questionVersionId)
if (cur) { if (cur) {
@ -408,12 +401,6 @@ export default {
// //
async delChecked (item) { async delChecked (item) {
try { try {
await this.$confirm(`确认要移除吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
closeOnClickModal: false,
})
const cur = this.ques.find(e => e.questionVersionId === item.questionVersionId) const cur = this.ques.find(e => e.questionVersionId === item.questionVersionId)
if (cur) cur.check = false if (cur) cur.check = false
this.checked.splice(this.checked.findIndex(e => e.questionVersionId === item.questionVersionId), 1) this.checked.splice(this.checked.findIndex(e => e.questionVersionId === item.questionVersionId), 1)
@ -527,7 +514,6 @@ export default {
.lines { .lines {
height: calc(100vh - 358px); height: calc(100vh - 358px);
// padding-right: 10px;
overflow: auto; overflow: auto;
} }
@ -535,6 +521,10 @@ export default {
.lines { .lines {
height: calc(100vh - 328px); height: calc(100vh - 328px);
overflow: auto; overflow: auto;
&.switch {
height: calc(100vh - 394px);
}
} }
} }

@ -117,7 +117,8 @@
@selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange"> @selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<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>
<el-table-column prop="name" label="试卷名称" align="center" min-width="100"></el-table-column> <el-table-column prop="name" label="试卷名称" align="center" min-width="100"
show-overflow-tooltip></el-table-column>
<el-table-column prop="questionCount" label="试题总数" align="center" width="70"></el-table-column> <el-table-column prop="questionCount" label="试题总数" align="center" width="70"></el-table-column>
<el-table-column prop="score" label="总分" align="center" width="60"></el-table-column> <el-table-column prop="score" label="总分" align="center" width="60"></el-table-column>
<el-table-column prop="medianScore" label="中分位数" align="center" width="70"></el-table-column> <el-table-column prop="medianScore" label="中分位数" align="center" width="70"></el-table-column>

Loading…
Cancel
Save