dev_review
yujialong 3 months ago
parent 8eb83be7c7
commit 5c7bb7eba0
  1. 67
      src/views/match/add/set.vue
  2. 85
      src/views/match/manage/theoryReport.vue

@ -87,12 +87,10 @@
<template v-else> <template v-else>
<el-card shadow="hover" class="mgr20 m-b-20"> <el-card shadow="hover" class="mgr20 m-b-20">
<div> <div>
<p class="m-b-20">系统</p> <p class="m-b-20">课程</p>
<div class="inline-input"> <div class="inline-input">
<el-select v-model="systemId" placeholder="请选择系统" @change="getProject"> <el-cascader ref="cur" v-model="mallIds" :options="curs" :props="{ checkStrictly: true, value: 'id' }"
<el-option v-for="(item, i) in systems" :key="i" :label="item.systemName" :value="item.systemId"> popper-class="course-cas" @expand-change="curChange" @change="curChange"></el-cascader>
</el-option>
</el-select>
</div> </div>
</div> </div>
</el-card> </el-card>
@ -157,7 +155,8 @@ export default {
difficults: TestPaperConst.difficults, difficults: TestPaperConst.difficults,
paperTypes: TestPaperConst.paperTypes, paperTypes: TestPaperConst.paperTypes,
loadIns: null, loadIns: null,
systems: [], mallIds: [],
curs: [],
paperLibraries: [], paperLibraries: [],
testPapers: [], testPapers: [],
keyword: '', keyword: '',
@ -166,7 +165,7 @@ export default {
pageSize: 5, pageSize: 5,
total: 0, total: 0,
libraryId: '', libraryId: '',
systemId: '', sysId: '',
paperId: '', paperId: '',
paperName: '', paperName: '',
permissionsKeys: ['练习', '考核', '竞赛'], permissionsKeys: ['练习', '考核', '竞赛'],
@ -201,19 +200,59 @@ export default {
// //
async getCourse () { async getCourse () {
const sid = this.$store.state.dataPer.find(e => e.permissionName === '服务配置') const sid = this.$store.state.dataPer.find(e => e.permissionName === '服务配置')
const res = await this.$post(this.api.queryServiceConfig, { const { serviceList } = await this.$post(this.api.queryServiceConfig, {
pageNum: 1, pageNum: 1,
pageSize: 1000, pageSize: 1000,
supplierId: sid ? sid.supplierId : '' supplierId: sid ? sid.supplierId : ''
}) })
const { records } = res.serviceList const { page } = await this.$post(this.api.listOfGoods, {
pageNum: 1,
pageSize: 10000,
hotTag: 1,
sort: 0,
isAssociatedProduct: 1,
isShelves: 0,
})
const { records } = page
const { mallId, cid, systemId } = this.form
if (records.length) { if (records.length) {
this.systems = records serviceList.records.map(e => {
this.systemId = records[0].systemId e.id = +e.systemId
e.label = e.systemName
})
records.map(e => {
e.id = +e.mallId
e.label = e.productName
e.children = serviceList.records.filter(n => e.systemId && e.systemId.split(',').includes(n.systemId)) //
})
this.curs = records
//
const first = records[0]
this.mallIds = [mallId || first.mallId, systemId || first.children[0].id]
this.form.mallId = mallId || first.mallId
this.form.cid = cid || +first.associatedProduct
this.form.systemId = systemId || first.systemId
this.sysId = systemId || first.systemId
this.loadIns = Loading.service() this.loadIns = Loading.service()
this.getProject() this.getProject()
} }
}, },
//
curChange (val) {
const id = val[0]
const item = this.curs.find(e => e.id == id)
if (val.length === 1) {
//
this.mallIds = [id, item.children[0].id]
}
this.form.mallId = id
this.form.cid = +item.associatedProduct
this.form.systemId = this.mallIds[1]
this.sysId = this.mallIds[1]
this.loadIns = Loading.service()
this.getProject()
},
// //
async getLibrary () { async getLibrary () {
try { try {
@ -248,11 +287,12 @@ export default {
this.total = res.pageList.total this.total = res.pageList.total
} else { } else {
// //
const { data } = await this.$post(this.api.getCompetitionProjectByMiddleGround, { const { data } = await this.$post(this.api.getProjectAssessmentByCompetition, {
pageNum: this.page, pageNum: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
cid: this.form.cid,
projectName: this.keyword, projectName: this.keyword,
systemId: this.systemId, systemId: this.sysId,
permissions: 2 permissions: 2
}) })
this.projects = data.records this.projects = data.records
@ -311,7 +351,6 @@ export default {
if (!form.time.length) return util.warningMsg('请选择比赛时间') if (!form.time.length) return util.warningMsg('请选择比赛时间')
const { playStartTime, playEndTime } = this.step1 const { playStartTime, playEndTime } = this.step1
if (new Date(form.time[0]) < new Date(playStartTime) || new Date(form.time[1]) > new Date(playEndTime)) return util.warningMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。') if (new Date(form.time[0]) < new Date(playStartTime) || new Date(form.time[1]) > new Date(playEndTime)) return util.warningMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。')
// //
if (this.isTheory) { if (this.isTheory) {
if (!this.libraryId) return util.warningMsg('请选择试卷库') if (!this.libraryId) return util.warningMsg('请选择试卷库')

@ -17,7 +17,8 @@
item.targetScore }}</h6> item.targetScore }}</h6>
<ul class="serials"> <ul class="serials">
<template v-for="(ques, j) in item.userAnswerList"> <template v-for="(ques, j) in item.userAnswerList">
<li v-if="!sheetStatus || sheetStatus === ques.isCorrect" :key="j" :class="'status' + ques.isCorrect"> <li v-if="!sheetStatus || sheetStatus === ques.isCorrect" :key="j" :class="'status' + ques.isCorrect"
@click="scrollToQues(ques)">
<p :class="['serial', { answered: ques.answered, partAnswer: ques.partAnswer }]">{{ j + 1 }}</p> <p :class="['serial', { answered: ques.answered, partAnswer: ques.partAnswer }]">{{ j + 1 }}</p>
<p class="score">{{ ques.userScore }}</p> <p class="score">{{ ques.userScore }}</p>
</li> </li>
@ -101,7 +102,7 @@
</el-table> </el-table>
</div> </div>
<ul v-if="paper" class="ques-wrap"> <ul v-if="paper" class="ques-wrap" id="quesWrap">
<li v-for="(item, i) in paper" :key="i"> <li v-for="(item, i) in paper" :key="i">
<div class="outline"> <div class="outline">
{{ arabicToChinese(i + 1) }}{{ item.questionTypeName }}本题共{{ item.questionNum }}小题{{ {{ arabicToChinese(i + 1) }}{{ item.questionTypeName }}本题共{{ item.questionNum }}小题{{
@ -110,7 +111,7 @@
@click="item.shrink = !item.shrink"> @click="item.shrink = !item.shrink">
</div> </div>
<div :class="['ques', { hide: item.shrink }]"> <div :class="['ques', { hide: item.shrink }]">
<div v-for="(ques, j) in item.userAnswerList" :key="j" class="item"> <div v-for="(ques, j) in item.userAnswerList" :key="j" class="item" :id="'ques' + ques.id">
<div class="stem-wrap"> <div class="stem-wrap">
<div class="labels"> <div class="labels">
<span class="label">{{ j + 1 }} / {{ item.questionNum }}</span> <span class="label">{{ j + 1 }} / {{ item.questionNum }}</span>
@ -126,9 +127,10 @@
v-if="item.questionType !== 'fill_blank' && item.questionType !== 'essay' && ques.questionAnswerVersionsList" v-if="item.questionType !== 'fill_blank' && item.questionType !== 'essay' && ques.questionAnswerVersionsList"
class="m-b-10"> class="m-b-10">
<div v-for="(opt, j) in ques.questionAnswerVersionsList" :key="j" class="opt"> <div v-for="(opt, j) in ques.questionAnswerVersionsList" :key="j" class="opt">
<el-checkbox v-if="item.questionType === 'multiple_choice'" v-model="opt.answerIsCorrect" <img v-if="opt.optCorrect === 1" src="@/assets/img/right.svg" alt="" class="icon">
:true-label="1"></el-checkbox> <img v-else-if="!opt.optCorrect" src="@/assets/img/wrong.svg" alt="" class="icon">
<el-radio v-else v-model="opt.answerIsCorrect" :true-label="1" :label="1" disabled></el-radio> <span v-else class="icon not-ans"></span>
<span>{{ numToLetter(j) }}.&nbsp;</span> <span>{{ numToLetter(j) }}.&nbsp;</span>
<div class="text" v-html="opt.optionText"></div> <div class="text" v-html="opt.optionText"></div>
</div> </div>
@ -164,7 +166,8 @@
</div> </div>
<div class="line"> <div class="line">
<span>考生答案</span> <span>考生答案</span>
<div v-html="ques.answerContent"></div> <div v-if="ques.answerContent" v-html="ques.answerContent"></div>
<div v-else>未作答</div>
</div> </div>
<div v-if="ques.attachmentUrl" class="line"> <div v-if="ques.attachmentUrl" class="line">
<span>考生上传附件</span> <span>考生上传附件</span>
@ -179,7 +182,7 @@
<p v-if="item.questionType !== 'fill_blank'">{{ ques.userAnswerStr }}</p> <p v-if="item.questionType !== 'fill_blank'">{{ ques.userAnswerStr }}</p>
<div v-else-if="ques.userAnswerFill" class="fill-answers"> <div v-else-if="ques.userAnswerFill" class="fill-answers">
<p v-for="(ans, j) in ques.userAnswerFill" :key="j" class="fill-answer"> <p v-for="(ans, j) in ques.userAnswerFill" :key="j" class="fill-answer">
填空{{ j + 1 }}{{ ans.studentAnswer }} 填空{{ j + 1 }}{{ ans.studentAnswer || '未作答' }}
<img v-if="ans.correct" src="@/assets/img/right.svg" alt="" class="icon"> <img v-if="ans.correct" src="@/assets/img/right.svg" alt="" class="icon">
<img v-else src="@/assets/img/wrong.svg" alt="" class="icon"> <img v-else src="@/assets/img/wrong.svg" alt="" class="icon">
</p> </p>
@ -288,17 +291,26 @@ export default {
const opts = n.questionAnswerVersionsList const opts = n.questionAnswerVersionsList
if (type !== 'fill_blank' && type !== 'essay') { // if (type !== 'fill_blank' && type !== 'essay') { //
if (!n.userScore) n.userScore = 0
n.isCorrect = n.userScore && n.userScore === n.questionScore ? 1 : 2 n.isCorrect = n.userScore && n.userScore === n.questionScore ? 1 : 2
//
let { userAnswer } = n
if (userAnswer) {
userAnswer = JSON.parse(userAnswer)
n.userAnswerStr = userAnswer.length ? userAnswer.map(m => numToLetter(+m - 1)).join('') : '未作答'
} else {
userAnswer = []
}
const quesAnswer = [] const quesAnswer = []
opts && opts.map((m, j) => { opts && opts.map((m, j) => {
const selected = userAnswer.includes(m.optionNumber)
m.optCorrect = m.answerIsCorrect ? (selected ? 1 : -1) : (selected ? 0 : -1) // (10-1)
m.answerIsCorrect && quesAnswer.push(numToLetter(j)) m.answerIsCorrect && quesAnswer.push(numToLetter(j))
}) })
n.quesAnswer = quesAnswer.join('') n.quesAnswer = quesAnswer.join('')
let { userAnswer } = n
if (userAnswer) {
userAnswer = JSON.parse(userAnswer)
n.userAnswerStr = userAnswer.map(m => numToLetter(+m - 1)).join('')
}
} else if (type === 'fill_blank') { // } else if (type === 'fill_blank') { //
// //
let { jsonText } = n let { jsonText } = n
@ -321,6 +333,7 @@ export default {
} }
} }
if (!n.userScore) n.userScore = 0
// //
let rightLen = 0 let rightLen = 0
if (n.userAnswerFill) rightLen = n.userAnswerFill.filter(m => m.correct).length // if (n.userAnswerFill) rightLen = n.userAnswerFill.filter(m => m.correct).length //
@ -349,6 +362,26 @@ export default {
this.loading = false this.loading = false
} }
}, },
scrollToSmooth (position, duration) {
let startTime = Date.now()
function scroll () {
let now = Date.now()
let progress = Math.min(1, (now - startTime) / duration)
document.querySelector('#quesWrap').scrollTo(0, position * progress)
if (progress < 1) {
window.requestAnimationFrame(scroll)
}
}
window.requestAnimationFrame(scroll)
},
//
scrollToQues (e) {
const el = document.querySelector('#ques' + e.id)
el && this.scrollToSmooth(el.offsetTop - document.querySelector('#quesWrap').offsetTop, 200)
},
// //
filterStatus (e) { filterStatus (e) {
this.sheetStatus = this.sheetStatus === e ? '' : e this.sheetStatus = this.sheetStatus === e ? '' : e
@ -446,7 +479,7 @@ samp {
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif; font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
} }
.report { /deep/.report {
display: flex; display: flex;
.r-title { .r-title {
@ -550,7 +583,7 @@ samp {
} }
} }
/deep/ .table th { .table th {
background-color: #e5dfff !important; background-color: #e5dfff !important;
.cell { .cell {
@ -603,6 +636,11 @@ samp {
margin: 7px 9px; margin: 7px 9px;
font-size: 13px; font-size: 13px;
text-align: center; text-align: center;
cursor: pointer;
&:hover {
opacity: .9;
}
} }
.serial { .serial {
@ -723,6 +761,7 @@ samp {
padding: 10px; padding: 10px;
background-color: #fff; background-color: #fff;
overflow: auto; overflow: auto;
outline: none;
&>li { &>li {
margin-bottom: 15px; margin-bottom: 15px;
@ -873,24 +912,26 @@ samp {
.opt { .opt {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: baseline; align-items: flex-start;
padding-left: 10px; padding-left: 10px;
margin-bottom: 5px; margin-bottom: 5px;
font-size: 14px; font-size: 14px;
color: #707070; color: #707070;
line-height: 1.6; line-height: 1.6;
.el-radio, &>.icon {
.el-checkbox { margin-right: 12px;
margin-right: 15px;
} }
.el-radio__label { .not-ans {
display: none; width: 18px;
height: 18px;
border: 1px solid #ccc;
border-radius: 50%;
} }
.text { .text {
max-width: calc(100% - 48px); max-width: calc(100% - 55px);
} }
} }
} }

Loading…
Cancel
Save