试卷发布判断重复试题等

master
yujialong 3 months ago
parent a0d8246419
commit 872a1f6514
  1. 2
      public/static/ueditorPlus/ueditor.config.js
  2. 26
      src/pages/ques/detail/index.vue
  3. 2
      src/pages/ques/list/index.vue
  4. 142
      src/pages/testPaper/detail/index.vue
  5. 16
      src/pages/testPaper/detail/manual.vue
  6. 69
      src/pages/testPaper/detail/repeatQues.vue
  7. 5
      src/pages/testPaper/list/index.vue

@ -65,7 +65,7 @@
//工具栏上的所有的功能按钮和下拉框,可以在new编辑器的实例时选择自己需要的重新定义
// , "insertvideo"
toolbars: [
["fullscreen", "source", "|", "bold", "italic", "underline", "forecolor", "fontfamily", "fontsize", "|", "link", "unlink", "anchor", "|", "imagenone", "imageleft", "imagecenter", "imageright", "|", "justifyleft", "justifycenter", "justifyright", "justifyjustify", "|", "insertcode", "insertimage", "insertvideo", "inserttable", 'formula', "gapfilling", 'combox']
["fullscreen", "source", "|", "bold", "italic", "underline", "rowspacingtop", "rowspacingbottom", "lineheight", "|", "customstyle", "paragraph", "forecolor", "fontfamily", "fontsize", "|", "backcolor", "insertorderedlist", "insertunorderedlist", "|", "link", "unlink", "anchor", "|", "imagenone", "imageleft", "imagecenter", "imageright", "|", "justifyleft", "justifycenter", "justifyright", "justifyjustify", "|", "insertcode", "insertimage", "insertvideo", "inserttable", 'formula', "gapfilling", 'combox']
]
// 公式配置
, formulaConfig: {

@ -160,8 +160,7 @@
<el-dialog title="提示" :visible.sync="repeatVisible" width="800px" :close-on-click-modal="false">
<el-alert title="与当前题库中已有的试题重复(如下),是否继续保存?" type="warning" effect="dark" :closable="false">
</el-alert>
<el-alert title="与当前题库中已有的试题重复(如下),是否继续保存?" type="warning" effect="dark" :closable="false" />
<el-table class="m-t-10" :data="repeats" stripe header-align="center" row-key="id">
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="题型" align="center" min-width="120">
@ -647,16 +646,19 @@ export default {
},
//
async saveQues () {
const form = this.tempForm
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('保存成功')
this.submiting = false
!form.questionId && this.keep ? this.init() : (this.quesVisible = false)
this.repeatVisible = false
try {
const form = this.tempForm
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('保存成功')
!form.questionId && this.keep ? this.init() : (this.quesVisible = false)
this.repeatVisible = false
} finally {
this.submiting = false
}
},
//
closeDia () {

@ -255,7 +255,7 @@ export default {
givenYearSort: '',
difficultySort: '',
correctRateSort: '',
updateTimeSort: '',
updateTimeSort: 'desc',
referenceCountSort: '',
},
list: [],

@ -134,7 +134,8 @@
@update="e => updateSort(e, item)">
<div v-for="(ques, j) in item.examQuestions" :key="j" class="ques-item">
<el-checkbox v-model="ques.check"></el-checkbox>
<div :class="['ques-info', { disabled: !ques.status, del: ques.isDel, repeat: ques.isRepeat }]">
{{ ques.repeat }}
<div :class="['ques-info', { disabled: !ques.status, del: ques.isDel, repeat: ques.repeat }]">
<div class="top-line">
<div class="labels">
<span class="label">{{ j + 1 }} / {{ item.examQuestions.length }}</span>
@ -189,25 +190,27 @@
<Manual :visible.sync="manualVisible" :questionType.sync="curType.questionType" />
<Auto :visible.sync="autoVisible" />
<Detail :visible.sync="quesVisible" :row.sync="curRow" :detailType.sync="detailType" @updateQues="updateQues" />
<RepeatQues :visible.sync="repeatVisible" :list.sync="repeatQues" />
</div>
</template>
<script>
import Setting from '@/setting'
import Util from '@/libs/util'
import dayjs from 'dayjs'
import Decimal from 'decimal.js'
import Draggable from 'vuedraggable'
import UeditorPlus from '@/components/ueditorPlus'
import Breadcrumb from '@/components/breadcrumb'
import QuesConst from '@/const/ques'
import TestPaperConst from '@/const/testPaper'
import Template from './template'
import Manual from './manual'
import Auto from './auto'
import RepeatQues from './repeatQues'
import Detail from '@/pages/ques/detail'
import Setting from '@/setting'
import Util from '@/libs/util'
import dayjs from 'dayjs'
import QuesConst from '@/const/ques'
import TestPaperConst from '@/const/testPaper'
import Decimal from 'decimal.js'
export default {
components: { UeditorPlus, Breadcrumb, Template, Manual, Auto, Detail, Draggable },
components: { UeditorPlus, Breadcrumb, Template, Manual, Auto, RepeatQues, Detail, Draggable },
data () {
return {
crumbs: [],
@ -325,6 +328,7 @@ export default {
repeatVisible: false,
repeatQues: [],
tempForm: {},
submiting: false,
};
},
computed: {
@ -338,60 +342,6 @@ export default {
}
},
mounted () {
function distributeScores (objects, totalScore) {
const numObjects = objects.length;
//
const baseScore = totalScore / numObjects;
const hasFraction = baseScore % 1 !== 0; //
//
for (let i = 0; i < numObjects; i++) {
objects[i].score = Math.floor(baseScore);
}
//
let fractionalPartSum = 0;
if (hasFraction) {
for (let i = 0; i < numObjects; i++) {
fractionalPartSum += baseScore % 1;
}
}
//
let remainingObjects = numObjects;
while (fractionalPartSum > 0) {
objects[--remainingObjects].score += 1;
fractionalPartSum -= 1;
}
//
if (totalScore < numObjects) {
//
const fractionalDistribution = Math.ceil(fractionalPartSum);
for (let i = 0; i < fractionalDistribution; i++) {
objects[i].score += 1;
}
}
return objects;
}
//
const objects = [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 }
];
const totalScore = 3; //
const result = distributeScores(objects, totalScore);
console.log(result);
this.crumbs = [
{
name: '试卷管理',
@ -473,8 +423,8 @@ export default {
//
questionTypeChange (row) {
// 5
if (this.questionTypes.find(e => e.name === row.outlineName)) row.outlineName = this.questionTypes.find(e => e.id === row.questionType).name
// 5
if (!row.outlineName || this.questionTypes.find(e => e.name === row.outlineName)) row.outlineName = this.questionTypes.find(e => e.id === row.questionType).name
},
//
addLine (i) {
@ -552,7 +502,7 @@ export default {
data.avgValueList.map((e, i) => {
// scores-1
if (!e.scores.includes(-1)) {
const stem = document.querySelector(`#stem` + e.questionId)
const stem = document.querySelector(`#stem` + e.questionVersionId)
if (stem) {
const inputs = stem.querySelectorAll('.fill-input')
if (inputs) {
@ -695,21 +645,37 @@ export default {
},
//
hasRepeatQues (list) {
const result = list.filter(e => {
if (e.questionType !== 'fill_blank' && e.questionType !== 'essay') {
// ++
const opts = e.questionAnswerVersionsList
//
const first = opts[0].optionText
const someOpt = opts.every(n => n.optionText === first)
return e.questionType === e.questionType && e.stem === e.stem && someOpt
} else {
// /+
return (e.questionType === e.questionType && e.stem === e.stem)
}
})
list.forEach(e => {
list.forEach(n => {
if (e.questionVersionId !== n.questionVersionId && !e.repeat) {
// ++
if (e.questionType !== 'fill_blank' && e.questionType !== 'essay') {
//
const opts = e.questionAnswerVersionsList
let diff = 0
for (const j in opts) {
// debugger
if (!n.questionAnswerVersionsList[j] || n.questionAnswerVersionsList[j].optionText !== opts[j].optionText) {
diff = 1
break
}
}
if (e.questionType === n.questionType && e.stem === n.stem && !diff) {
e.repeat = true
n.repeat = true
}
} else {
// /+
if (e.questionType === n.questionType && e.stem === n.stem) {
e.repeat = true
n.repeat = true
}
}
}
})
})
const result = list.filter(e => e.repeat)
//
if (result.length) {
this.repeatVisible = true
@ -737,13 +703,12 @@ export default {
try {
await this.$post(this.api.saveExamPaper, this.tempForm)
Util.successMsg('保存成功')
this.submiting = false
this.back()
} catch (e) {
} finally {
this.submiting = false
}
},
//
//
async validForm (status) {
if (this.submiting) return false
const { isCopy } = this //
@ -819,11 +784,16 @@ export default {
invalid = 1
break
}
e.examQuestions.map((n, j) => {
n.outlineName = e.outlineName
n.paperIndex = i
n.quesIndex = j
n.repeat = false
})
allQues.push(...e.examQuestions)
}
if (invalid) return false
}
this.submiting = true
form.particularYear = +(dayjs(form.particularYear).format('YYYY'))
@ -877,8 +847,7 @@ export default {
if (isCopy) form.paperId = ''
this.tempForm = form
// debugger
// if (this.hasRepeatQues(allQues)) return false
if (this.hasRepeatQues(allQues)) return false
this.saveTestPaper()
},
//
@ -982,8 +951,11 @@ export default {
}
&.repeat {
border-color: #ff962a;
&:after {
content: '存在重复题';
background-color: #ff962a;
}
}
}

@ -221,8 +221,8 @@ export default {
const el = document.createElement('div')
el.innerHTML = e.stem
e.stemText = el.innerText
e.check = !!this.checked.find(n => n.questionId === e.questionId)
e.disabled = !!checked.find(n => n.questionVersionId === e.questionId)
e.check = !!this.checked.find(n => n.questionVersionId === e.questionVersionId)
e.disabled = !!checked.find(n => n.questionVersionId === e.questionVersionId)
})
this.ques = data
}
@ -253,7 +253,7 @@ export default {
},
//
quesChange (val, item) {
const cur = this.checked.findIndex(e => e.questionId === item.questionId)
const cur = this.checked.findIndex(e => e.questionVersionId === item.questionVersionId)
//
if (val) {
if (cur === -1) {
@ -282,7 +282,7 @@ export default {
closeOnClickModal: false,
})
checked.map(e => {
const cur = this.ques.find(n => n.questionId === e.questionId)
const cur = this.ques.find(n => n.questionVersionId === e.questionVersionId)
if (cur) {
cur.check = false
}
@ -304,9 +304,9 @@ export default {
// type: 'warning',
// closeOnClickModal: false,
// })
const cur = this.ques.find(e => e.questionId === item.questionId)
const cur = this.ques.find(e => e.questionVersionId === item.questionVersionId)
if (cur) cur.check = false
this.checked.splice(this.checked.findIndex(e => e.questionId === item.questionId), 1)
this.checked.splice(this.checked.findIndex(e => e.questionVersionId === item.questionVersionId), 1)
} catch (e) { }
},
//
@ -332,14 +332,14 @@ export default {
if (!checked.length) return Util.warningMsg('请选择试题')
const { curType, curQuesIndex, curQues } = this.$parent
if (this.checkedLen > +curType.questionNum) return Util.warningMsg(`目标题数为${curType.questionNum},已选题数不得大于目标题数`)
if (!curQues && this.checkedLen > +curType.questionNum) return Util.warningMsg(`目标题数为${curType.questionNum},已选题数不得大于目标题数`)
try {
checked.map((e, i) => {
this.$set(e, 'check', false)
this.$set(e, 'sort', i + 1)
this.$set(e, 'score', '')
// this.$set(e, 'questionVersionId', e.questionId)
// this.$set(e, 'questionVersionId', e.questionVersionId)
})
if (curQues) {

@ -1,16 +1,20 @@
<template>
<el-dialog title="提示" :visible.sync="listVisible" width="800px" :close-on-click-modal="false">
<el-alert title="以下试题在试卷中疑似出现重复,是否要继续发布!" type="warning" effect="dark" :closable="false">
</el-alert>
<el-table class="m-t-10" :data="list" stripe header-align="center" row-key="id">
<el-table-column prop="name" label="大题名称" align="center" width="90"></el-table-column>
<el-table-column prop="name" label="题号" align="center" width="60"></el-table-column>
<el-table-column prop="stem" label="题干" align="center" min-width="120" show-overflow-tooltip></el-table-column>
<el-dialog title="提示" :visible.sync="listVisible" width="800px" :close-on-click-modal="false" :show-close="false"
@closed="closeDia">
<el-alert title="以下试题在试卷中疑似出现重复,是否要继续发布!" type="warning" effect="dark" :closable="false" />
<el-table class="m-t-10" :data="data" stripe header-align="center" row-key="id">
<el-table-column prop="outlineName" label="大题名称" align="center" width="90"></el-table-column>
<el-table-column prop="serialNumber" label="题号" align="center" width="60"></el-table-column>
<el-table-column prop="stem" label="题干" align="center" min-width="120">
<template slot-scope="scope">
<div v-html="scope.row.stem"></div>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="240">
<template slot-scope="scope">
<el-button type="text">详情</el-button>
<el-button type="text">移除</el-button>
<el-button type="text">替换</el-button>
<el-button type="text" @click="toQues(scope.row)">详情</el-button>
<el-button type="text" @click="delQues(scope.row, scope.$index)">移除</el-button>
<el-button type="text" @click="switchQues(scope.row, scope.$index)">替换</el-button>
</template>
</el-table-column>
</el-table>
@ -22,15 +26,13 @@
</el-dialog>
</template>
<script>
import Setting from '@/setting'
import Util from '@/libs/util'
import _ from 'lodash'
export default {
props: ['visible', 'list'],
data () {
return {
listVisible: false,
// list: [],
data: [],
submiting: false,
};
},
@ -45,32 +47,53 @@ export default {
},
methods: {
init () {
this.data = this.list
},
//
async getList () {
//
toQues (row) {
const paper = this.$parent.form.paperOutline
this.$parent.toQues(paper[row.paperIndex], row.quesIndex, paper[row.paperIndex].examQuestions[row.quesIndex])
},
//
async delQues (row, i) {
try {
const res = await this.$post(this.api.examPaperTemplateList, {
pageNum: this.page,
pageSize: this.pageSize,
...this.filter
await this.$confirm(`确认要移除吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
closeOnClickModal: false,
})
this.list = res.pageList.records
this.total = res.pageList.total
this.$parent.delQues(this.$parent.form.paperOutline[row.paperIndex], row.quesIndex)
this.data.splice(i, 1)
} catch (e) { }
},
//
switchQues (row) {
const paper = this.$parent.form.paperOutline
this.$parent.showManualDia(paper[row.paperIndex], row.quesIndex, paper[row.paperIndex].examQuestions[row.quesIndex])
this.listVisible = false
},
//
async check () {
const { list } = this
this.$parent.form.paperOutline.map(e => {
e.examQuestions.map(n => {
if (list.find(m => m.questionVersionId === n.questionVersionId)) this.$set(n, 'repeat', true)
})
})
this.$parent.submiting = false
this.listVisible = false
},
//
async submit () {
if (this.submiting) return false
this.submiting = true
this.$parent.saveTestPaper()
await this.$parent.saveTestPaper()
this.submiting = false
},
//
closeDia () {
this.$parent.submiting = false
this.$emit('update:visible', false)
}
}

@ -249,7 +249,7 @@ export default {
difficult: [],
professionalId: [],
paperType: '',
updateTimeOrder: '',
updateTimeOrder: 2,
crateTimeOrder: '',
yearOrder: '',
keyWord: '',
@ -408,6 +408,7 @@ export default {
async getList () {
try {
this.listLoading = true
const type = this.$refs.typeTree
const res = await this.$post(this.api.examPaperList, {
...this.filter,
isDisable: this.status === 2 ? '' : this.status, //
@ -418,7 +419,7 @@ export default {
pageNum: this.page,
pageSize: this.pageSize,
libraryId: this.typeId,
classificationId: this.$refs.typeTree.getCurrentKey() || '',
classificationId: type ? type.getCurrentKey() || '' : '',
})
this.list = res.pageList.records
this.total = res.pageList.total

Loading…
Cancel
Save