master
parent
0c602151a6
commit
b1d31b8c32
36 changed files with 3329 additions and 438 deletions
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 985 KiB |
@ -0,0 +1,262 @@ |
||||
<template> |
||||
<div class="box"> |
||||
<h1 class="title">{{paperName }}</h1> |
||||
<div class="metas"> |
||||
<div style="margin-right: 20px;"> |
||||
<span class="name">总分:</span> |
||||
<span class="val">100分</span> |
||||
</div> |
||||
<div> |
||||
<span class="name">考试时长:</span> |
||||
<span class="val">{{time}}分钟</span> |
||||
</div> |
||||
</div> |
||||
|
||||
<ul class="tab"> |
||||
<li v-for="(item,index) in tabs" :key="index" :class="{active: active == item.id}" @click="tabChange(item.id)">{{item.name}}</li> |
||||
</ul> |
||||
|
||||
<div class="wrap"> |
||||
<div class="item" v-for="(item,index) in curType" :key="index"> |
||||
<div class="answer"> |
||||
<div class="info"> |
||||
<p class="key">序号:</p> |
||||
<p class="val">{{index+1}}</p> |
||||
</div> |
||||
<div class="info"> |
||||
<p class="key">得分:</p> |
||||
<p class="val">{{item.question_score}}</p> |
||||
</div> |
||||
</div> |
||||
<div class="meta"> |
||||
<p class="key">题干:</p> |
||||
<p class="val" v-html="item.question_stem"></p> |
||||
</div> |
||||
<div class="meta"> |
||||
<p class="key">选项:</p> |
||||
<div class="val"> |
||||
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p> |
||||
</div> |
||||
</div> |
||||
<div class="meta ans"> |
||||
<div class="info"> |
||||
<p class="key">正确答案:</p> |
||||
<p class="val">{{item.answer}}</p> |
||||
</div> |
||||
<div class="info"> |
||||
<p class="key">学生答案:</p> |
||||
<p class="val">{{item.user_answer}}</p> |
||||
</div> |
||||
</div> |
||||
<div class="meta"> |
||||
<p class="key">答案解析:</p> |
||||
<p class="val" v-html="item.answer_analysis"></p> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import mixins from '@/mixins/setBackground' |
||||
import { mapState } from 'vuex' |
||||
export default { |
||||
mixins: [ mixins ], |
||||
data() { |
||||
return { |
||||
paperName: '', |
||||
time: 0, |
||||
selectVisible: false, |
||||
tabs: [ |
||||
{ |
||||
id: 1, |
||||
name: '单选题' |
||||
},{ |
||||
id: 2, |
||||
name: '多选题' |
||||
},{ |
||||
id: 3, |
||||
name: '判断题' |
||||
},{ |
||||
id: 4, |
||||
name: '简答题' |
||||
},{ |
||||
id: 5, |
||||
name: '填空题' |
||||
} |
||||
], |
||||
active: 1, |
||||
curType: [] |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapState('user', [ |
||||
'userId' |
||||
]), |
||||
...mapState('achievement', [ |
||||
'id','assessmentId','stuId' |
||||
]) |
||||
}, |
||||
mounted() { |
||||
this.getData() |
||||
}, |
||||
methods: { |
||||
getData() { |
||||
this.$post(`${this.api.answerDetail}?userId=${this.stuId}&assessmentId=${this.assessmentId}&paperId=${this.id}`) |
||||
.then(res => { |
||||
this.paperName = res.paperName |
||||
this.time = res.time |
||||
this.allData = res.data |
||||
this.curType = this.allData.list1 |
||||
this.handleOptions() |
||||
}) |
||||
.catch(err => {}) |
||||
}, |
||||
tabChange(id){ |
||||
this.active = id |
||||
this.curType = this.allData[`list${id}`] |
||||
this.handleOptions() |
||||
}, |
||||
handleOptions(){ |
||||
let curType = this.curType |
||||
curType.forEach(n => { |
||||
if(!n.options){ |
||||
let options = {} |
||||
let answer = [] |
||||
for(let i in n){ |
||||
if(i.includes('option') && n[i]){ |
||||
options[i.replace('option_','')] = n[i] |
||||
if(n.typeName == '填空题') answer.push(n[i]) |
||||
} |
||||
} |
||||
if(n.typeName == '填空题') n.answer = answer.join('|') |
||||
n.options = options |
||||
} |
||||
}) |
||||
this.curType = curType |
||||
} |
||||
}, |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.box{ |
||||
width: 90%; |
||||
margin: 0 auto; |
||||
} |
||||
.title{ |
||||
text-align: center; |
||||
font-size: 18px; |
||||
font-weight: 600; |
||||
} |
||||
.metas{ |
||||
display: flex; |
||||
justify-content: center; |
||||
margin: 20px 0 30px; |
||||
.name{ |
||||
font-size: 12px; |
||||
color: #717171; |
||||
} |
||||
.val{ |
||||
font-size: 12px; |
||||
color: #929292; |
||||
} |
||||
} |
||||
.tab{ |
||||
display: flex; |
||||
align-items: center; |
||||
margin-bottom: 10px; |
||||
li{ |
||||
position: relative; |
||||
padding: 0 44px; |
||||
margin-right: 7px; |
||||
font-size: 13px; |
||||
line-height: 46px; |
||||
text-align: center; |
||||
color: #444; |
||||
border: 1px solid #ececec; |
||||
cursor: pointer; |
||||
&:hover{ |
||||
opacity: .8; |
||||
} |
||||
&.active:after{ |
||||
content: ''; |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
height: 4px; |
||||
background-color: #e80909; |
||||
} |
||||
} |
||||
} |
||||
.wrap{ |
||||
.item{ |
||||
padding-bottom: 30px; |
||||
margin-bottom: 30px; |
||||
border-bottom: 1px dashed #f4f4f4; |
||||
|
||||
.key{ |
||||
font-weight: bold; |
||||
color: #333; |
||||
font-size: 14px; |
||||
} |
||||
.val{ |
||||
color: #757575; |
||||
font-size: 14px; |
||||
} |
||||
.answer{ |
||||
display: flex; |
||||
align-items: center; |
||||
padding: 15px; |
||||
margin: 15px 0; |
||||
font-size: 12px; |
||||
border: 1px solid #e8e8e8; |
||||
background-color: #f3f2f2; |
||||
.info{ |
||||
display: inline-flex; |
||||
align-items: center; |
||||
margin-right: 30px; |
||||
} |
||||
} |
||||
.meta{ |
||||
padding-left: 10px; |
||||
margin: 20px 0; |
||||
font-size: 12px; |
||||
&.ans{ |
||||
display: flex; |
||||
.info{ |
||||
margin-right: 20px; |
||||
} |
||||
} |
||||
.key{ |
||||
margin-bottom: 5px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.btns{ |
||||
display: flex; |
||||
justify-content: center; |
||||
margin-top: 20px; |
||||
button{ |
||||
height: 30px; |
||||
padding: 0 30px; |
||||
margin: 0 15px; |
||||
font-size: 14px; |
||||
color: #333; |
||||
line-height: 30px; |
||||
background-color: #fff; |
||||
border: 1px solid #ededed; |
||||
border-radius: 4px; |
||||
cursor: pointer; |
||||
&.submit{ |
||||
color: #fff; |
||||
background-color: #e80909; |
||||
border-color: #e80909; |
||||
} |
||||
&:hover{ |
||||
opacity: .8; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,298 @@ |
||||
<template> |
||||
<div> |
||||
<el-card shadow="hover"> |
||||
<ul class="list"> |
||||
<li v-for="(item,index) in listData" :key="index"> |
||||
<div class="item"> |
||||
<div class="inner"> |
||||
<img class="avatar" src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" alt=""> |
||||
<div class="texts"> |
||||
<div class="title"> |
||||
<span class="username">{{item.userName}}</span> |
||||
<span class="publish">发表于</span> |
||||
<span class="date">{{item.createTime}}</span> |
||||
</div> |
||||
<div class="desc" v-html="item.content"></div> |
||||
</div> |
||||
<div class="right"> |
||||
<p class="index">[ {{index+1}} # ]</p> |
||||
</div> |
||||
</div> |
||||
<div class="action"> |
||||
<button v-if="item.userId != userId" class="btn" @click="showReply(item)">回复</button> |
||||
<button v-else class="btn" @click="delMsg(item)">删除</button> |
||||
</div> |
||||
<div class="reply" v-if="item.showReply"> |
||||
<quill :border="true" v-model="item.replyContent" :height="150" /> |
||||
<div class="m-t-10 text-right"> |
||||
<el-button type="primary" size="mini" @click="submitComment(item)">提交</el-button> |
||||
</div> |
||||
</div> |
||||
|
||||
<ul class="list children" v-if="item.showChildren"> |
||||
<li v-for="(reply,i) in item.children" :key="i"> |
||||
<div class="inner"> |
||||
<img class="avatar" src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" alt=""> |
||||
<div class="texts"> |
||||
<div class="title"> |
||||
<span class="username">{{reply.userName}}</span> |
||||
<span class="publish">发表于</span> |
||||
<span class="date">{{reply.commentTime}}</span> |
||||
</div> |
||||
<div class="desc" v-html="reply.content"></div> |
||||
</div> |
||||
</div> |
||||
<div class="action"> |
||||
<button v-if="reply.commentUserId != userId" class="btn" @click="showReply(reply)">回复</button> |
||||
<button v-else class="btn" @click="delReply(reply)">删除</button> |
||||
</div> |
||||
<div class="reply" v-if="reply.showReply"> |
||||
<quill :border="true" v-model="reply.replyContent" :height="150" /> |
||||
<div class="m-t-10 text-right"> |
||||
<el-button type="primary" size="mini" @click="submitReply(reply)">提交</el-button> |
||||
</div> |
||||
</div> |
||||
</li> |
||||
</ul> |
||||
<div v-if="item.getCommentReplyNum" class="toggle"><span @click="toggleReply(item)">{{item.showChildren ? '收起所有回复' : `查看所有${item.getCommentReplyNum}条回复`}} <i class="el-icon-arrow-down"></i></span></div> |
||||
</div> |
||||
</li> |
||||
</ul> |
||||
<div class="pagination"> |
||||
<el-pagination |
||||
background |
||||
@current-change="handleCurrentChange" |
||||
:current-page="page" |
||||
:page-size="pageSize" |
||||
layout="total,prev, pager, next" |
||||
:total="total" |
||||
></el-pagination> |
||||
</div> |
||||
<div class="input-wrap"> |
||||
<quill class="m-t-20" :border="true" v-model="content" :height="150" /> |
||||
<div class="m-t-10 text-right"> |
||||
<el-button type="primary" size="mini" @click="submitMsg">提交</el-button> |
||||
</div> |
||||
</div> |
||||
</el-card> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import { mapState } from 'vuex' |
||||
import quill from '@/components/quill' |
||||
export default { |
||||
data() { |
||||
return { |
||||
page: 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
listData: [], |
||||
content: '' |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapState('user', [ |
||||
'userId','clientId' |
||||
]) |
||||
}, |
||||
components: { |
||||
quill |
||||
}, |
||||
mounted() { |
||||
this.getData() |
||||
}, |
||||
methods: { |
||||
getData() { |
||||
this.$post(`${this.api.queryMessageBoard}?schoolId=${this.clientId}&pageNum=${this.page}&pageSize=${this.pageSize}`) |
||||
.then(res => { |
||||
this.listData = this.handleList(res.data.list.list) |
||||
this.total = res.data.list.totalCount |
||||
}) |
||||
.catch(err => {}) |
||||
}, |
||||
handleList(list){ |
||||
list.map(n => { |
||||
n.showReply = false |
||||
n.replyContent = '' |
||||
n.children = [] |
||||
n.showChildren = false |
||||
}) |
||||
return list |
||||
}, |
||||
handleCurrentChange(val) { |
||||
this.page = val |
||||
this.getData() |
||||
}, |
||||
toggleReply(row){ |
||||
if(row.showChildren) return row.showChildren = false |
||||
this.$post(`${this.api.queryMessageBoardDetail}?bid=${row.bid}`).then(res => { |
||||
let children = res.data.list |
||||
let replyList = [] |
||||
children.map(n => { |
||||
n.replyList.map(e => { |
||||
e.bid = n.bid |
||||
e.content = e.replyComment |
||||
e.commentTime = e.replyTime |
||||
e.commentUserId = e.userIdByReply |
||||
}) |
||||
replyList = replyList.concat(n.replyList) |
||||
}) |
||||
children = children.concat(replyList) |
||||
console.log(11,replyList,children) |
||||
row.children = this.handleList(children) |
||||
row.showChildren = true |
||||
}).catch(res => {}) |
||||
}, |
||||
showReply(row){ |
||||
row.showReply = !row.showReply |
||||
}, |
||||
delMsg(row){ |
||||
this.$post(`${this.api.delMessageBoard}?bid=${row.bid}`).then(res => { |
||||
this.$message.success('删除成功') |
||||
this.getData() |
||||
}).catch(res => {}) |
||||
}, |
||||
submitComment(row){ |
||||
let data = { |
||||
bid: row.bid, |
||||
content: row.replyContent, |
||||
commentUserId: this.userId, |
||||
schoolId: this.clientId, |
||||
} |
||||
this.$post(this.api.saveComment,data).then(res => { |
||||
this.$message.success('提交成功') |
||||
row.replyContent = '' |
||||
this.getData() |
||||
}).catch(res => {}) |
||||
}, |
||||
delReply(row){ |
||||
if(row.identification == 1){ |
||||
this.$post(`${this.api.delComment}?commentId=${row.commentId}`).then(res => { |
||||
this.$message.success('删除成功') |
||||
this.getData() |
||||
}).catch(res => {}) |
||||
}else{ |
||||
this.$post(`${this.api.delReply}?replyId=${row.replyId}`).then(res => { |
||||
this.$message.success('删除成功') |
||||
this.getData() |
||||
}).catch(res => {}) |
||||
} |
||||
}, |
||||
submitReply(row){ |
||||
let data = { |
||||
bid: row.bid, |
||||
commentId: row.commentId, |
||||
replyComment: row.replyContent, |
||||
replyUserId: row.commentUserId ? row.commentUserId : row.userIdByReply, |
||||
userId: this.userId, |
||||
} |
||||
this.$post(this.api.saveReply,data).then(res => { |
||||
this.$message.success('提交成功') |
||||
row.replyContent = '' |
||||
this.getData() |
||||
}).catch(res => {}) |
||||
}, |
||||
submitMsg(){ |
||||
let data = { |
||||
content: this.content, |
||||
schoolId: this.clientId, |
||||
userId: this.userId |
||||
} |
||||
this.$post(this.api.saveMessageBoard,data).then(res => { |
||||
this.$message.success('提交成功') |
||||
this.content = '' |
||||
this.getData() |
||||
}).catch(res => {}) |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
$mainColor: #cc201c; |
||||
.list{ |
||||
li{ |
||||
padding-bottom: 10px; |
||||
border-top: 1px solid #f1f1f1; |
||||
&:first-child{ |
||||
border-top: 0; |
||||
} |
||||
.inner{ |
||||
position: relative; |
||||
display: flex; |
||||
justify-content: space-between; |
||||
padding: 10px 0 20px; |
||||
.avatar{ |
||||
width: 40px; |
||||
height: 40px; |
||||
border-radius: 50%; |
||||
} |
||||
.texts{ |
||||
flex: 1; |
||||
margin-left: 10px; |
||||
.title{ |
||||
margin-bottom: 5px; |
||||
font-size: 14px; |
||||
.username{ |
||||
color: $mainColor; |
||||
} |
||||
.publish{ |
||||
margin: 0 5px; |
||||
color: #d6d6d6; |
||||
} |
||||
.date{ |
||||
color: #b5b5b5; |
||||
} |
||||
} |
||||
} |
||||
.right{ |
||||
.index{ |
||||
font-size: 12px; |
||||
color: #ccc; |
||||
} |
||||
} |
||||
} |
||||
.action{ |
||||
text-align: right; |
||||
.btn{ |
||||
padding: 2px 4px; |
||||
color: $mainColor; |
||||
font-size: 12px; |
||||
background-color: #fff; |
||||
border: 1px solid; |
||||
border-radius: 4px; |
||||
cursor: pointer; |
||||
&:hover{ |
||||
opacity: .8; |
||||
} |
||||
&:first-child{ |
||||
margin-right: 5px; |
||||
} |
||||
} |
||||
} |
||||
.reply{ |
||||
margin-top: 20px; |
||||
} |
||||
} |
||||
&.children{ |
||||
padding: 0 10px 10px; |
||||
margin: 10px 0 0 30px; |
||||
background-color: #f3f4f6; |
||||
li{ |
||||
border-top-color: #fff; |
||||
} |
||||
} |
||||
} |
||||
.toggle{ |
||||
margin: 10px 0; |
||||
text-align: center; |
||||
color: $mainColor; |
||||
font-size: 12px; |
||||
span{ |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
/deep/.quill{ |
||||
background-color: #fff; |
||||
} |
||||
</style> |
@ -0,0 +1,279 @@ |
||||
<template> |
||||
<div class="box"> |
||||
<h1 class="title">{{paperName }}</h1> |
||||
<div class="metas"> |
||||
<div style="margin-right: 20px;"> |
||||
<span class="name">总分:</span> |
||||
<span class="val">100分</span> |
||||
</div> |
||||
<div> |
||||
<span class="name">考试时长:</span> |
||||
<span class="val">{{duration}}</span> |
||||
</div> |
||||
</div> |
||||
|
||||
<ul class="tab"> |
||||
<li v-for="(item,index) in tabs" :key="index" :class="{active: active == item.id}" @click="tabChange(item.id)">{{item.name}}</li> |
||||
</ul> |
||||
|
||||
<div class="wrap"> |
||||
<div class="item" v-for="(item,index) in curType" :key="index"> |
||||
<div class="answer"> |
||||
<div class="info"> |
||||
<p class="key">序号:</p> |
||||
<p class="val">{{index+1}}</p> |
||||
</div> |
||||
<div class="info"> |
||||
<p class="key">得分:</p> |
||||
<p class="val">{{item.questionScore}}</p> |
||||
</div> |
||||
</div> |
||||
<div class="meta"> |
||||
<p class="key">题干:</p> |
||||
<p class="val" v-html="item.questionStem"></p> |
||||
</div> |
||||
<div class="meta"> |
||||
<p class="key">选项:</p> |
||||
<div class="val"> |
||||
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p> |
||||
</div> |
||||
</div> |
||||
<div class="meta ans"> |
||||
<div class="info"> |
||||
<p class="key">正确答案:</p> |
||||
<p class="val">{{item.answer}}</p> |
||||
</div> |
||||
<div class="info"> |
||||
<p class="key">学生答案:</p> |
||||
<p class="val">{{item.userAnswer}}</p> |
||||
</div> |
||||
</div> |
||||
<div class="meta"> |
||||
<p class="key">答案解析:</p> |
||||
<p class="val" v-html="item.answerAnalysis"></p> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import mixins from '@/mixins/setBackground' |
||||
import { mapState } from 'vuex' |
||||
export default { |
||||
mixins: [ mixins ], |
||||
data() { |
||||
return { |
||||
paperName: '', |
||||
duration: 0, |
||||
selectVisible: false, |
||||
tabs: [ |
||||
{ |
||||
id: 1, |
||||
name: '单选题' |
||||
},{ |
||||
id: 2, |
||||
name: '多选题' |
||||
},{ |
||||
id: 3, |
||||
name: '判断题' |
||||
},{ |
||||
id: 4, |
||||
name: '简答题' |
||||
},{ |
||||
id: 5, |
||||
name: '填空题' |
||||
} |
||||
], |
||||
typeNameList: ['单项选择','多项选择','判断题','简答题','填空题'], |
||||
active: 1, |
||||
list: [], |
||||
curType: [] |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapState('user', [ |
||||
'userId' |
||||
]), |
||||
...mapState('achievement', [ |
||||
'practiseId','stuId' |
||||
]) |
||||
}, |
||||
mounted() { |
||||
this.getData() |
||||
}, |
||||
methods: { |
||||
getData() { |
||||
this.$post(`${this.api.reviewDetail}?id=${this.practiseId}`) |
||||
.then(res => { |
||||
let data = res.data |
||||
data.list.forEach(n => { |
||||
n.isCorrecting == 0 && (n.questionScore = '') |
||||
n.isSub = n.typeName == '简答题' |
||||
if(n.typeName == '填空题'){ |
||||
let answer = [] |
||||
for(let i in n){ |
||||
if(i.includes('option')) answer.push(n[i]) |
||||
} |
||||
n.answer = answer.join('|') |
||||
n.userAnswer = n.userAnswer.replace(/<>/g,'|') |
||||
} |
||||
}) |
||||
this.list = data.list |
||||
this.handleOptions() |
||||
this.paperName = data.paperName |
||||
this.userName = data.stuName |
||||
this.this_score = data.score |
||||
this.duration = data.timeCost |
||||
}) |
||||
.catch(err => {}) |
||||
}, |
||||
tabChange(id){ |
||||
this.active = id |
||||
this.handleOptions() |
||||
}, |
||||
handleOptions(){ |
||||
let list = this.list |
||||
let typeName = this.typeNameList[this.active-1] |
||||
list = list.filter(n => n.typeName == typeName) |
||||
list.forEach(n => { |
||||
if(!n.options){ |
||||
let options = {} |
||||
let answer = [] |
||||
for(let i in n){ |
||||
if(i.includes('option') && n[i]){ |
||||
options[i.replace('option','')] = n[i] |
||||
if(n.typeName == '填空题') answer.push(n[i]) |
||||
} |
||||
} |
||||
if(n.typeName == '填空题') n.answer = answer.join('|') |
||||
n.options = options |
||||
} |
||||
}) |
||||
this.curType = list |
||||
} |
||||
}, |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.box{ |
||||
width: 90%; |
||||
margin: 0 auto; |
||||
} |
||||
.title{ |
||||
text-align: center; |
||||
font-size: 18px; |
||||
font-weight: 600; |
||||
} |
||||
.metas{ |
||||
display: flex; |
||||
justify-content: center; |
||||
margin: 20px 0 30px; |
||||
.name{ |
||||
font-size: 12px; |
||||
color: #717171; |
||||
} |
||||
.val{ |
||||
font-size: 12px; |
||||
color: #929292; |
||||
} |
||||
} |
||||
.tab{ |
||||
display: flex; |
||||
align-items: center; |
||||
margin-bottom: 10px; |
||||
li{ |
||||
position: relative; |
||||
padding: 0 44px; |
||||
margin-right: 7px; |
||||
font-size: 13px; |
||||
line-height: 46px; |
||||
text-align: center; |
||||
color: #444; |
||||
border: 1px solid #ececec; |
||||
cursor: pointer; |
||||
&:hover{ |
||||
opacity: .8; |
||||
} |
||||
&.active:after{ |
||||
content: ''; |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
height: 4px; |
||||
background-color: #e80909; |
||||
} |
||||
} |
||||
} |
||||
.wrap{ |
||||
.item{ |
||||
padding-bottom: 30px; |
||||
margin-bottom: 30px; |
||||
border-bottom: 1px dashed #f4f4f4; |
||||
|
||||
.key{ |
||||
font-weight: bold; |
||||
color: #333; |
||||
font-size: 14px; |
||||
} |
||||
.val{ |
||||
color: #757575; |
||||
font-size: 14px; |
||||
} |
||||
.answer{ |
||||
display: flex; |
||||
align-items: center; |
||||
padding: 15px; |
||||
margin: 15px 0; |
||||
font-size: 12px; |
||||
border: 1px solid #e8e8e8; |
||||
background-color: #f3f2f2; |
||||
.info{ |
||||
display: inline-flex; |
||||
align-items: center; |
||||
margin-right: 30px; |
||||
} |
||||
} |
||||
.meta{ |
||||
padding-left: 10px; |
||||
margin: 20px 0; |
||||
font-size: 12px; |
||||
&.ans{ |
||||
display: flex; |
||||
.info{ |
||||
margin-right: 20px; |
||||
} |
||||
} |
||||
.key{ |
||||
margin-bottom: 5px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.btns{ |
||||
display: flex; |
||||
justify-content: center; |
||||
margin-top: 20px; |
||||
button{ |
||||
height: 30px; |
||||
padding: 0 30px; |
||||
margin: 0 15px; |
||||
font-size: 14px; |
||||
color: #333; |
||||
line-height: 30px; |
||||
background-color: #fff; |
||||
border: 1px solid #ededed; |
||||
border-radius: 4px; |
||||
cursor: pointer; |
||||
&.submit{ |
||||
color: #fff; |
||||
background-color: #e80909; |
||||
border-color: #e80909; |
||||
} |
||||
&:hover{ |
||||
opacity: .8; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,274 @@ |
||||
<template> |
||||
<div class="box"> |
||||
<h1 class="title">{{paperName}}</h1> |
||||
<div class="metas"> |
||||
<div> |
||||
<span class="name">学生姓名:</span> |
||||
<span class="val">{{userName}}</span> |
||||
</div> |
||||
<div> |
||||
<span class="name">学生得分:</span> |
||||
<span class="val">{{(reviewStatus == 2 || reviewStatus == 3) ? this_score : '--'}}</span> |
||||
</div> |
||||
<div> |
||||
<span class="name">试卷总分:</span> |
||||
<span class="val">100</span> |
||||
</div> |
||||
<div> |
||||
<span class="name">练习时长:</span> |
||||
<span class="val">{{duration}}</span> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="wrap"> |
||||
<div class="select"> |
||||
<el-radio v-model="look" label="1">查看全部</el-radio> |
||||
<el-radio v-model="look" label="2" v-if="reviewStatus == 2 || reviewStatus == 3">只看错题</el-radio> |
||||
</div> |
||||
|
||||
<div class="item" v-for="(item,index) in list" :key="index"> |
||||
<div class="status" :class="{done: item.isCorrecting}">{{item.isSub ? '简答题' : '客观题'}}:{{getCorrectingName(item.isCorrecting)}}</div> |
||||
<div class="name" v-html="item.questionStem"></div> |
||||
<div class="answer"> |
||||
<div class="info" v-if="!item.isSub"> |
||||
<p class="key">正确答案:</p> |
||||
<p class="val">{{item.answer}}</p> |
||||
</div> |
||||
<div class="info"> |
||||
<p class="key">学生答案:</p> |
||||
<p class="val">{{item.userAnswer}}</p> |
||||
</div> |
||||
</div> |
||||
<div class="meta"> |
||||
<span class="key">知识点:</span> |
||||
<span class="val">{{item.knowledgePoints}}</span> |
||||
</div> |
||||
<div class="meta"> |
||||
<span class="key">答案解析:</span> |
||||
<span class="val">{{item.answerAnalysis}}</span> |
||||
</div> |
||||
<div class="meta"> |
||||
<span class="key">考试得分:</span> |
||||
<div class="val"> |
||||
<input type="text" v-model.number="item.questionScore" :disabled="!isReview || !item.isSub"> 分 |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="btns" v-if="isReview"> |
||||
<button type="button" class="submit" @click="save(1)">提交</button> |
||||
<button type="button" @click="save(0)">保存</button> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import mixins from '@/mixins/setBackground' |
||||
import { mapState,mapGetters,mapActions } from 'vuex' |
||||
export default { |
||||
mixins: [ mixins ], |
||||
data() { |
||||
return { |
||||
paperName: '', |
||||
userName: '', |
||||
this_score: '', |
||||
duration: '', |
||||
list: [], |
||||
look: '1', |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapState('user', [ |
||||
'userId','clientId' |
||||
]), |
||||
...mapState('practice', [ |
||||
'id','paperId','isReview','reviewStatus','stuId','identification','practiseId' |
||||
]), |
||||
...mapGetters('practice', [ |
||||
'getCorrectingName' |
||||
]) |
||||
}, |
||||
watch: { |
||||
look(val,oldVal){ |
||||
val == 1 ? this.getData() : this.getWrong() |
||||
} |
||||
}, |
||||
mounted() { |
||||
this.getData() |
||||
}, |
||||
methods: { |
||||
getData() { |
||||
this.$post(`${this.api.reviewDetail}?id=${this.id}`) |
||||
.then(res => { |
||||
let data = res.data |
||||
data.list.forEach(n => { |
||||
n.isCorrecting == 0 && (n.questionScore = '') |
||||
n.isSub = n.typeName == '简答题' |
||||
if(n.typeName == '填空题'){ |
||||
let answer = [] |
||||
for(let i in n){ |
||||
if(i.includes('option')) answer.push(n[i]) |
||||
} |
||||
n.answer = answer.join('|') |
||||
n.userAnswer = n.userAnswer.replace(/<>/g,'|') |
||||
} |
||||
}) |
||||
this.list = data.list |
||||
this.paperName = data.paperName |
||||
this.userName = data.stuName |
||||
this.this_score = data.score |
||||
this.duration = data.timeCost |
||||
}) |
||||
.catch(err => {}) |
||||
}, |
||||
getWrong(){ |
||||
this.$post(`${this.api.getWrong}?assessmentId=${this.id}&userId=${this.stuId}&paperId=${this.paperId}`) |
||||
.then(res => { |
||||
this.list = res.data.list |
||||
}) |
||||
.catch(err => {}) |
||||
}, |
||||
save(status) { |
||||
let isEmpty = false |
||||
let isNotNum = false |
||||
let invalid = false |
||||
this.list.map(n => { |
||||
if(n.questionScore === '') isEmpty = true |
||||
if(isNaN(n.questionScore)) isNotNum = true |
||||
if(Number(n.questionScore) > Number(n.question_points)) invalid = true |
||||
}) |
||||
if(status){ |
||||
if(isEmpty) return this.$message.warning('请批阅完所有题目') |
||||
if(isNotNum) return this.$message.warning('考试得分请输入数字') |
||||
} |
||||
if(invalid) return this.$message.warning('考试得分不得大于题目分数') |
||||
let data = { |
||||
identification: this.identification, |
||||
review: [], |
||||
practiseId: this.practiseId, |
||||
paperId: this.paperId, |
||||
} |
||||
let totalScore = 0 |
||||
this.list.map(n => { |
||||
n.questionScore !== '' && n.isSub && data.review.push({ |
||||
detailId: Number(n.detailId) , |
||||
score: Number(n.questionScore) |
||||
}) |
||||
totalScore += Number(n.questionScore) |
||||
}) |
||||
if(!data.review.length) return this.$message.warning('请至少批阅一道题目') |
||||
|
||||
if(status || this.list.filter(n => n.isSub).length == data.review.length){ |
||||
data.totalScore = totalScore |
||||
} |
||||
this.$post(this.api.reviewByidPractice,data).then(res => { |
||||
this.$message.success(status ? '提交成功' : '保存成功') |
||||
this.$router.back() |
||||
}).catch(err => {}) |
||||
}, |
||||
}, |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.title{ |
||||
text-align: center; |
||||
font-size: 18px; |
||||
font-weight: 600; |
||||
} |
||||
.metas{ |
||||
display: flex; |
||||
justify-content: space-between; |
||||
margin: 20px 0 30px; |
||||
.name{ |
||||
font-size: 12px; |
||||
color: #717171; |
||||
} |
||||
.val{ |
||||
font-size: 12px; |
||||
color: #929292; |
||||
} |
||||
} |
||||
.wrap{ |
||||
padding: 20px; |
||||
background-color: #fbfbfb; |
||||
|
||||
.select{ |
||||
padding: 10px; |
||||
margin-bottom: 20px; |
||||
border-bottom: 1px solid #f4f4f4; |
||||
} |
||||
|
||||
.item{ |
||||
padding-bottom: 30px; |
||||
margin-bottom: 30px; |
||||
border-bottom: 1px dashed #d2d2d2; |
||||
&:last-child{ |
||||
border-bottom: 0; |
||||
} |
||||
|
||||
.status{ |
||||
color: #cb221c; |
||||
&.done{ |
||||
color: #56d5bf; |
||||
} |
||||
} |
||||
.name{ |
||||
margin-top: 15px; |
||||
font-size: 14px; |
||||
color: #555555; |
||||
} |
||||
.key{ |
||||
font-weight: bold; |
||||
color: #333; |
||||
} |
||||
.val{ |
||||
color: #757575; |
||||
} |
||||
.answer{ |
||||
display: flex; |
||||
align-items: center; |
||||
padding: 15px; |
||||
margin: 15px 0; |
||||
font-size: 12px; |
||||
border: 1px solid #e8e8e8; |
||||
background-color: #f3f2f2; |
||||
.info{ |
||||
display: inline-flex; |
||||
align-items: center; |
||||
margin-right: 30px; |
||||
} |
||||
} |
||||
.meta{ |
||||
display: flex; |
||||
align-items: center; |
||||
padding-left: 10px; |
||||
margin: 10px 0; |
||||
font-size: 12px; |
||||
.key{ |
||||
width: 80px; |
||||
margin-right: 10px; |
||||
text-align: right; |
||||
white-space: nowrap; |
||||
} |
||||
input{ |
||||
width: 60px; |
||||
height: 28px; |
||||
padding: 0 5px; |
||||
margin-right: 5px; |
||||
color: #444; |
||||
background-color: #fff; |
||||
border: 1px solid #ebebeb; |
||||
box-sizing: border-box; |
||||
&:focus{ |
||||
outline: none; |
||||
} |
||||
&:disabled{ |
||||
background-color: #e8e8e8; |
||||
cursor: not-allowed; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,487 @@ |
||||
<template> |
||||
<div> |
||||
<el-card shadow="hover" class="m-b-20"> |
||||
<div> |
||||
<div class="flex a-center m-b-20"> |
||||
<p class="hr_tag"></p> |
||||
<span>筛选</span> |
||||
</div> |
||||
<div> |
||||
<div class="flex"> |
||||
<div> |
||||
<el-input placeholder="请输入练习名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</el-card> |
||||
|
||||
<el-card shadow="hover"> |
||||
<div class="flex j-between m-b-20"> |
||||
<div class="flex a-center"> |
||||
<p class="hr_tag"></p> |
||||
<span>练习列表</span> |
||||
</div> |
||||
<div> |
||||
<el-button type="primary" size="small" round @click="addAss" v-auth>创建练习</el-button> |
||||
</div> |
||||
</div> |
||||
<el-table :data="listData" class="table" stripe header-align="center" row-key="id"> |
||||
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> |
||||
<el-table-column prop="practiseName" label="练习名称" align="center"></el-table-column> |
||||
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column> |
||||
<el-table-column prop="className" label="练习班级" align="center"></el-table-column> |
||||
<el-table-column label="操作" width="250"> |
||||
<template slot-scope="scope"> |
||||
<el-popover |
||||
placement="bottom" |
||||
width="400" |
||||
trigger="click"> |
||||
<div class="details"> |
||||
<div class="line"> |
||||
<span class="key">练习内容:</span> |
||||
<p class="val">{{assContent}}</p> |
||||
</div> |
||||
<div class="line"> |
||||
<span class="key">练习题数:</span> |
||||
<p class="val">{{quesNum}}道</p> |
||||
</div> |
||||
<div class="line"> |
||||
<span class="key">练习人数:</span> |
||||
<p class="val">{{assPeopleNum}}人</p> |
||||
</div> |
||||
<div class="line"> |
||||
<span class="key">练习总分:</span> |
||||
<p class="val">100分</p> |
||||
</div> |
||||
</div> |
||||
<el-button type="text" slot="reference" @click="show(scope.row)" v-auth>查看</el-button> |
||||
</el-popover> |
||||
<el-button type="text" @click="edit(scope.row)" v-auth>修改</el-button> |
||||
<el-button type="text" @click="delData(scope.row)" v-auth>取消</el-button> |
||||
<el-button type="text" @click="review(scope.row)" v-auth>批阅</el-button> |
||||
<el-button type="text" @click="scoreQuery(scope.row)" v-auth>成绩查询</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total"> |
||||
</el-pagination> |
||||
</div> |
||||
</el-card> |
||||
|
||||
<el-dialog :title="isAdd ? '创建练习' : '修改练习'" :visible.sync="addVisible" width="50%" @close="closeAdd" :close-on-click-modal="false"> |
||||
<el-form ref="form" label-width="100px"> |
||||
<el-form-item label="练习名称"> |
||||
<el-input v-model="form.practiseName" size="small" placeholder="请输入练习名称"></el-input> |
||||
</el-form-item> |
||||
<el-form-item label="试卷选择"> |
||||
<el-button type="primary" size="small" @click="openSelect">试卷选择</el-button> |
||||
<el-tag |
||||
class="m-l-10" |
||||
v-if="testPaperName" |
||||
closable |
||||
@close="removeTestPaper"> |
||||
{{testPaperName}} |
||||
</el-tag> |
||||
</el-form-item> |
||||
<el-form-item label="发布班级"> |
||||
<studentSide ref="getSelectData" :classId="form.classId" :key="stuCompKey" @fircheck="fircheck" @twocheck="twocheck" @threecheck="threecheck"></studentSide> |
||||
</el-form-item> |
||||
</el-form> |
||||
|
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="addVisible = false">取消</el-button> |
||||
<el-button type="primary" @click="save">确定</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
|
||||
<el-dialog title="试卷选择" :visible.sync="selectVisible" width="40%" @close="closeSelect" :close-on-click-modal="false"> |
||||
<div class="flex j-end m-b-20"> |
||||
<el-form label-width="80px" inline> |
||||
<el-form-item class="no-mb" label="所属课程"> |
||||
<el-select v-model="cid" clearable placeholder="请选择所属课程" > |
||||
<el-option v-for="(item,index) in coursesList" :key="index" :label="item.typeName" :value="item.cid"></el-option> |
||||
</el-select> |
||||
</el-form-item> |
||||
<el-form-item class="no-mb"> |
||||
<el-input |
||||
placeholder="请输入试卷名称" |
||||
prefix-icon="el-icon-search" |
||||
v-model="keywordPaper" |
||||
clearable |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-form> |
||||
</div> |
||||
|
||||
<el-table |
||||
:data="testPaperData" |
||||
max-height="400" |
||||
ref="table" |
||||
row-key="id" |
||||
class="table" |
||||
stripe |
||||
header-align="center" |
||||
> |
||||
<el-table-column width="60" label="选择" align="center"> |
||||
<template slot-scope="scope"> |
||||
<el-radio v-model="testPaperId" :label="scope.row.id"> </el-radio> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column type="index" width="100" label="序号" align="center"> |
||||
<template |
||||
slot-scope="scope" |
||||
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||
</el-table-column> |
||||
<el-table-column prop="name" label="试卷名称" align="center"></el-table-column> |
||||
<el-table-column label="操作" align="center"> |
||||
<template slot-scope="scope"> |
||||
<el-button type="text" @click="preview(scope.row)">预览</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<!-- <div class="pagination"> |
||||
<el-pagination |
||||
background |
||||
@current-change="handleCurrentChange" |
||||
:current-page="pagePaper" |
||||
:page-size="pageSizePaper" |
||||
layout="total,prev, pager, next" |
||||
:total="totalPaper" |
||||
></el-pagination> |
||||
</div> --> |
||||
|
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="selectVisible = false">取消</el-button> |
||||
<el-button type="primary" @click="savePaper">确定</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
|
||||
<el-dialog title="试卷详情" :visible.sync="previewVisible" width="40%" fullscreen> |
||||
<test-paper-detail :key="previewId"></test-paper-detail> |
||||
</el-dialog> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { mapState,mapGetters,mapActions } from 'vuex' |
||||
import studentSide from './studentSide' |
||||
import testPaperDetail from '@/components/testPaperDetail' |
||||
import util from '@/libs/util' |
||||
export default { |
||||
data() { |
||||
return { |
||||
keyword: '', |
||||
type: '', |
||||
state: '', |
||||
listData: [], |
||||
page: 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
searchTimer: null, |
||||
isAdd: false, |
||||
addVisible: false, |
||||
selectVisible: false, |
||||
detailVisible: false, |
||||
form: { |
||||
classId: '', |
||||
practiseName: '', |
||||
testPaperId: '', |
||||
}, |
||||
permissions: [], |
||||
classList: [], |
||||
checkedIds: [], |
||||
defaultProps: { |
||||
children: 'children', |
||||
label: 'className' |
||||
}, |
||||
keywordPaper: '', |
||||
cid: '', |
||||
coursesList: [], |
||||
pagePaper: 1, |
||||
pageSizePaper: 10, |
||||
totalPaper: 0, |
||||
testPaperData: [], |
||||
testPaperId: '', |
||||
testPaperName: '', |
||||
quesNum: 0, |
||||
assPeopleNum: 0, |
||||
assContent: '', |
||||
stuCompKey: 1, |
||||
previewVisible: false, |
||||
previewId: '' |
||||
}; |
||||
}, |
||||
components: { |
||||
studentSide,testPaperDetail |
||||
}, |
||||
computed: { |
||||
...mapState('user', [ |
||||
'userId','clientId' |
||||
]), |
||||
...mapState('practice', [ |
||||
'typeList','stateList' |
||||
]), |
||||
...mapGetters('practice', [ |
||||
'getStateName' |
||||
]) |
||||
}, |
||||
mounted() { |
||||
this.getData() |
||||
}, |
||||
watch: { |
||||
keyword: function(val) { |
||||
clearTimeout(this.searchTimer) |
||||
this.searchTimer = setTimeout(() => { |
||||
this.getData() |
||||
},500) |
||||
}, |
||||
keywordPaper: function(val) { |
||||
clearTimeout(this.searchTimer) |
||||
this.searchTimer = setTimeout(() => { |
||||
this.getPapers() |
||||
},500) |
||||
} |
||||
}, |
||||
methods: { |
||||
...mapActions('testpaper', [ |
||||
'setInfo' |
||||
]), |
||||
...mapActions('practice', [ |
||||
'setPracInfo' |
||||
]), |
||||
...mapActions('achievement', [ |
||||
'setPracListInfo' |
||||
]), |
||||
getData() { |
||||
this.$post(`${this.api.pageByName}?pageNum=${this.page}&pageSize=${this.pageSize}&practiseName=${this.keyword}&userId=${this.userId}`) |
||||
.then(res => { |
||||
this.listData = res.data.list.list |
||||
this.total = res.data.list.totalCount |
||||
}) |
||||
.catch(err => {}) |
||||
}, |
||||
handleCheck(data){ |
||||
let professionalStudentIds = [] |
||||
let gradeIds = [] |
||||
let classIds = [] |
||||
|
||||
data.forEach( e => { |
||||
if(e.ischeck){ |
||||
professionalStudentIds.push(e.stuProfessionalArchitectureId) |
||||
}else{ |
||||
util.removeByValue(professionalStudentIds, e.stuProfessionalArchitectureId); |
||||
} |
||||
e.children.forEach( r => { |
||||
if(r.ischeck){ |
||||
gradeIds.push(r.gradeId) |
||||
}else{ |
||||
util.removeByValue(gradeIds, r.gradeId); |
||||
} |
||||
|
||||
r.children.forEach( n => { |
||||
if(n.ischeck){ |
||||
classIds.push(n.classId) |
||||
}else{ |
||||
util.removeByValue(classIds, n.classId); |
||||
} |
||||
}) |
||||
}) |
||||
}) |
||||
this.form.classId = classIds.toString() |
||||
}, |
||||
fircheck(val,val2){ |
||||
val.ischeck = !val.ischeck |
||||
val.children.map( e => e.ischeck = val.ischeck) |
||||
val.children.map( e => e.children.map(n => n.ischeck = e.ischeck)) |
||||
this.handleCheck(val2) |
||||
}, |
||||
twocheck(val,val2){ |
||||
val.ischeck = !val.ischeck |
||||
val.children.map( e => e.ischeck = val.ischeck) |
||||
val.children.map( e => e.children && e.children.map(n => n.ischeck = e.ischeck)) |
||||
val2.forEach( e => { |
||||
e.children.forEach( r => { |
||||
if(r.gradeId == val.gradeId){ |
||||
if(e.children.every(i => i.ischeck)){ |
||||
e.ischeck = true |
||||
}else{ |
||||
e.ischeck = false |
||||
} |
||||
} |
||||
}) |
||||
}) |
||||
this.handleCheck(val2) |
||||
}, |
||||
threecheck(val,val2){ |
||||
val.ischeck = !val.ischeck |
||||
this.handleCheck(val2) |
||||
}, |
||||
handleCurrentChange(val) { |
||||
this.page = val; |
||||
this.getData(); |
||||
}, |
||||
delData(row) { |
||||
this.$confirm('确定要删除吗?', '提示', { |
||||
type: 'warning' |
||||
}) |
||||
.then(() => { |
||||
this.$post(`${this.api.cancelPractise}?practiseId=${row.practiseId}`).then(res => { |
||||
this.$message.success('删除成功') |
||||
this.getData() |
||||
}).catch(res => {}) |
||||
}) |
||||
.catch(() => {}) |
||||
}, |
||||
edit(row){ |
||||
this.form = JSON.parse(JSON.stringify(row)) |
||||
this.testPaperName = row.name |
||||
this.addVisible = true |
||||
this.isAdd = false |
||||
}, |
||||
scoreQuery(row){ |
||||
this.setPracListInfo({ |
||||
practiceIdAss: row.practiseId, |
||||
practiceNameAss: row.practiseName, |
||||
classIdAss: row.classId, |
||||
classNameAss: row.className |
||||
}) |
||||
this.$router.push('scoreQuery') |
||||
}, |
||||
review(row){ |
||||
this.setPracInfo({ |
||||
practiseId: row.practiseId |
||||
}) |
||||
this.$router.push('review') |
||||
}, |
||||
addAss(){ |
||||
this.isAdd = true |
||||
this.addVisible = true |
||||
}, |
||||
save(){ |
||||
let form = this.form |
||||
if(form.practiseName === '') return this.$message.warning('请填写练习名称') |
||||
if(form.testPaperId === '') return this.$message.warning('请选择试卷') |
||||
if(form.classId === '') return this.$message.warning('请选择发布班级') |
||||
|
||||
let data = { |
||||
practiseId: form.practiseId, |
||||
userId: this.userId, |
||||
practiseName: form.practiseName, |
||||
classId: form.classId, |
||||
testPaperId: form.testPaperId, |
||||
} |
||||
if(this.form.practiseId){ |
||||
this.$post(this.api.updatePractise, data).then(res => { |
||||
this.$message.success('修改成功') |
||||
this.addVisible = false |
||||
this.getData() |
||||
}) |
||||
.catch(err => {}) |
||||
}else{ |
||||
this.$post(this.api.createPractise, data).then(res => { |
||||
this.$message.success('创建成功') |
||||
this.addVisible = false |
||||
this.getData() |
||||
}) |
||||
.catch(err => {}) |
||||
} |
||||
}, |
||||
closeAdd(){ |
||||
this.form = { |
||||
classId: '', |
||||
practiseName: '', |
||||
testPaperId: '', |
||||
} |
||||
this.time = [] |
||||
this.testPaperName = '' |
||||
this.testPaperId = '' |
||||
this.cid = '' |
||||
this.keywordPaper = '' |
||||
this.stuCompKey++ |
||||
}, |
||||
openSelect(){ |
||||
this.selectVisible = true |
||||
this.getCourses() |
||||
this.getPapers() |
||||
}, |
||||
removeTestPaper(){ |
||||
this.form.testPaperId = '' |
||||
this.testPaperName = '' |
||||
}, |
||||
getCourses() { |
||||
this.$get(this.api.getTypeByOneLever) |
||||
.then(res => { |
||||
this.coursesList = res.data.list |
||||
}) |
||||
.catch(err => {}) |
||||
}, |
||||
getPapers() { |
||||
this.$post(`${this.api.schoolTestPaperByRelease}?schoolId=${this.clientId}&effect=1`) |
||||
.then(res => { |
||||
this.testPaperData = res.data.list |
||||
// this.totalPaper = res.data.list.totalCount |
||||
}) |
||||
.catch(err => {}) |
||||
}, |
||||
preview(row){ |
||||
this.previewId = row.id |
||||
this.setInfo({ |
||||
id: row.id, |
||||
paperName: row.name, |
||||
totalDuration: row.duration |
||||
}) |
||||
// this.$router.push('/testPaper/show') |
||||
this.previewVisible = true |
||||
}, |
||||
savePaper(){ |
||||
if(this.testPaperId === '') return this.$message.error('请选择试卷') |
||||
this.form.testPaperId = this.testPaperId |
||||
this.testPaperName = this.testPaperData.find(n => n.id == this.testPaperId).name |
||||
this.selectVisible = false |
||||
}, |
||||
closeSelect(){ |
||||
|
||||
}, |
||||
show(row){ |
||||
this.$post(`${this.api.seeDetails}?id=${row.practiseId}`) |
||||
.then(res => { |
||||
let data = res.data.list |
||||
this.assContent = data.paperName |
||||
this.quesNum = data.questionsNum |
||||
this.assPeopleNum = data.peopleNum |
||||
}) |
||||
.catch(err => {}) |
||||
}, |
||||
closeDetail(){ |
||||
|
||||
}, |
||||
} |
||||
} |
||||
</script> |
||||
<style lang="scss" scoped> |
||||
/deep/.no-mb.el-form-item{ |
||||
margin-bottom: 0; |
||||
} |
||||
.details{ |
||||
.line{ |
||||
display: flex; |
||||
align-items: center; |
||||
margin: 10px 0; |
||||
&:first-child{ |
||||
margin-top: 0; |
||||
} |
||||
.key{ |
||||
font-weight: bold; |
||||
color: #333; |
||||
font-size: 14px; |
||||
} |
||||
.val{ |
||||
color: #757575; |
||||
font-size: 14px; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,121 @@ |
||||
<template> |
||||
<div> |
||||
<div> |
||||
<lctree :data="majorList" @fircheckitem="fircheckitem" @twocheckitem="twocheckitem" @threecheckitem="threecheckitem"></lctree> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import lctree from './studentTree' |
||||
import { mapState } from 'vuex' |
||||
export default { |
||||
props:["Data",'classId'], |
||||
data() { |
||||
return { |
||||
majorList: [], |
||||
firactive: 0, |
||||
twoactive: 0, |
||||
threeactive: 0, |
||||
isaddClassMajor: false, |
||||
isAddDepartment: false, |
||||
isAddClass: false, |
||||
Form: { |
||||
classmajorId: '', |
||||
classmajorName: '', |
||||
}, |
||||
Form2: { |
||||
departmentId: '', |
||||
departmentName: '', |
||||
}, |
||||
Form3: { |
||||
classId: '', |
||||
className: '' |
||||
}, |
||||
majorNoAdd: true, |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapState('user', [ |
||||
'userId','clientId' |
||||
]) |
||||
}, |
||||
components: { |
||||
lctree |
||||
}, |
||||
mounted(){ |
||||
this.getStaff() |
||||
}, |
||||
methods: { |
||||
getStaff(){ |
||||
let data = { |
||||
schoolId: this.clientId |
||||
} |
||||
let classId = this.classId ? this.classId.split(',') : [] |
||||
this.$get(this.api.queryStudentProfessionalArchitecture,data).then(res => { |
||||
let StaffProfessionalArchitectureList = res.data.StaffProfessionalArchitectureList |
||||
StaffProfessionalArchitectureList.map(n => { |
||||
(n.ifVisible = false), (n.ischeck = false), (n.label = n.stuProfessionalArchitectureName); |
||||
let data = { |
||||
stuProfessionalArchitectureId: n.stuProfessionalArchitectureId |
||||
} |
||||
this.$get(this.api.queryGrade,data).then(res => { |
||||
n.children = res.data.Grade |
||||
n.children.map(j => { |
||||
(j.ifVisible = false), (j.ischeck = false), (j.label = j.gradeName); |
||||
let data = { |
||||
gradeId: j.gradeId |
||||
} |
||||
this.$get(this.api.queryClass,data).then(res => { |
||||
res.data.Class.map(e => { |
||||
(e.ifVisible = false), (e.ischeck = false), (e.label = e.className) |
||||
let data = { |
||||
searchContent: '', |
||||
professionalIds: n.stuProfessionalArchitectureId, |
||||
gradeIds: j.gradeId, |
||||
classIds: e.classId, |
||||
schoolId: this.clientId |
||||
} |
||||
if(classId.includes(String(e.classId))){ |
||||
e.ischeck = true |
||||
j.ifVisible = true |
||||
n.ifVisible = true |
||||
} |
||||
}) |
||||
j.children = res.data.Class |
||||
if(j.children.every(i => i.ischeck)){ |
||||
j.ischeck = true |
||||
} |
||||
if(n.children.every(i => i.ischeck)){ |
||||
n.ischeck = true |
||||
} |
||||
}).catch(res => {}); |
||||
}) |
||||
}).catch(res => {}); |
||||
}) |
||||
setTimeout(() => { |
||||
this.majorList = StaffProfessionalArchitectureList |
||||
this.majorList[0].ifVisible = true |
||||
}, 500); |
||||
}).catch(res => {}); |
||||
}, |
||||
// 选择专业 |
||||
fircheckitem(item){ |
||||
this.$emit("fircheck",item,this.majorList) |
||||
}, |
||||
// 选择年级 |
||||
twocheckitem(item){ |
||||
this.$emit("twocheck",item,this.majorList) |
||||
}, |
||||
threeClick(index){ |
||||
this.threeactive = index |
||||
}, |
||||
// 选择班级 |
||||
threecheckitem(three){ |
||||
this.$emit("threecheck",three,this.majorList) |
||||
}, |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss" scoped> |
||||
|
||||
</style> |
@ -0,0 +1,135 @@ |
||||
<template> |
||||
<div class="side_view"> |
||||
<div class="side_tree" @click.stop="open(item)" v-for="(item,index) in data" :key="index"> |
||||
<div class="item" @click.stop="open(item)"> |
||||
<img |
||||
v-if="item.children&&item.children.length!=0" |
||||
:class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}" |
||||
src="../../../assets/img/icon-xiangyou.png" |
||||
alt |
||||
/> |
||||
<i v-else class="empty"></i> |
||||
<i :class="item.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="fircheckitem(item)"></i> |
||||
<span>{{item.label}}</span> |
||||
</div> |
||||
|
||||
<div v-show="item.ifVisible" v-if="item.children&&item.children.length!=0"> |
||||
<div v-for="(item1,index1) in item.children" :key="index1"> |
||||
<div class="item1" @click.stop="open(item1)"> |
||||
<img |
||||
v-if="item1.children&&item1.children.length!=0" |
||||
:class="{ 'arrowTransform': !item1.ifVisible, 'arrowTransformReturn': item1.ifVisible}" |
||||
src="../../../assets/img/icon-xiangyou.png" |
||||
alt |
||||
/> |
||||
<i v-else class="empty"></i> |
||||
<i :class="item1.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="twocheckitem(item1)"></i> |
||||
<span>{{item1.label}}年级</span> |
||||
</div> |
||||
|
||||
<div v-show="item1.ifVisible" v-if="item1.children&&item1.children.length!=0"> |
||||
<div v-for="(item2,index2) in item1.children" :key="index2"> |
||||
<div class="item2" @click.stop="open(item2)"> |
||||
<i :class="item2.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="threecheckitem(item2)"></i> |
||||
<span>{{item2.label}}班</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
Array.prototype.removeByValue = function (val) { |
||||
for (var i = 0; i < this.length; i++) { |
||||
if (JSON.stringify(this[i]).indexOf(JSON.stringify(val)) != -1) { |
||||
this.splice(i, 1); |
||||
break; |
||||
} |
||||
} |
||||
}; |
||||
export default { |
||||
data() { |
||||
return { |
||||
chooseList: [] |
||||
}; |
||||
}, |
||||
watch: { |
||||
chooseList(n, o) { |
||||
this.$emit('chooseNode', n); |
||||
} |
||||
}, |
||||
|
||||
props: { |
||||
data: { |
||||
type: Array |
||||
} |
||||
}, |
||||
methods: { |
||||
//点击节点时伸展或收缩列表 |
||||
open(item) { |
||||
item.ifVisible = !item.ifVisible; |
||||
}, |
||||
|
||||
//选中叶子节点时将选中的叶子节点添加进数组,如果叶子节点存在则删除,removeByvalue函数定义在main.js中 |
||||
choose(item) { |
||||
item.ifVisible = !item.ifVisible; |
||||
if (item.ifVisible) { |
||||
this.chooseList.push(item); |
||||
} else { |
||||
this.chooseList.removeByValue(item); |
||||
} |
||||
}, |
||||
fircheckitem(item){ |
||||
this.$emit('fircheckitem',item); |
||||
}, |
||||
twocheckitem(item){ |
||||
console.log(22,item) |
||||
this.$emit('twocheckitem',item); |
||||
}, |
||||
threecheckitem(item){ |
||||
this.$emit('threecheckitem',item); |
||||
}, |
||||
//判断数组中是否包含某个对象 |
||||
isHasObj(arr, val) { |
||||
var flag = 0; //1为有 0为没有 |
||||
for (var i = 0; i < arr.length; i++) { |
||||
if (JSON.stringify(arr[i]).indexOf(JSON.stringify(val)) != -1) { |
||||
flag = 1; |
||||
} |
||||
} |
||||
if (flag == 1) { |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
@import '../../../styles/pages/tree.scss'; |
||||
|
||||
.side_view{ |
||||
max-height: 300px; |
||||
overflow: auto;; |
||||
padding: 10px 20px; |
||||
i { |
||||
color: #cb221c; |
||||
} |
||||
} |
||||
.item{ |
||||
padding: 5px 0; |
||||
margin-top: 10px; |
||||
} |
||||
.item2 { |
||||
margin-left: 80px |
||||
} |
||||
.item1,.item2{ |
||||
padding: 0; |
||||
margin-top: 0; |
||||
} |
||||
</style> |
@ -0,0 +1,142 @@ |
||||
<template> |
||||
<div> |
||||
<el-card shadow="hover" class="m-b-20"> |
||||
<div class="flex a-center m-b-20"> |
||||
<p class="hr_tag"></p> |
||||
<span>筛选</span> |
||||
</div> |
||||
<div class="flex j-between"> |
||||
<el-form label-width="80px" inline> |
||||
<el-form-item class="no-mb" label="批阅状态"> |
||||
<el-select v-model="state" clearable placeholder="请选择批阅状态" @change="getData"> |
||||
<el-option label="不限" value="3"></el-option> |
||||
<el-option v-for="(item,index) in reviewStatusList" :key="index" :label="item.name" :value="item.id"></el-option> |
||||
|
||||
</el-select> |
||||
</el-form-item> |
||||
</el-form> |
||||
</div> |
||||
</el-card> |
||||
|
||||
<el-card shadow="hover" class="m-b-20"> |
||||
<el-table |
||||
:data="listData" |
||||
ref="table" |
||||
row-key="id" |
||||
class="table" |
||||
stripe |
||||
header-align="center" |
||||
> |
||||
<el-table-column type="index" width="100" label="序号" align="center"> |
||||
<template |
||||
slot-scope="scope" |
||||
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||
</el-table-column> |
||||
<el-table-column prop="userName" label="真实姓名" align="center"></el-table-column> |
||||
<el-table-column prop="workNumber" label="学号" align="center"></el-table-column> |
||||
<el-table-column prop="examTime" label="开始时间" align="center"></el-table-column> |
||||
<el-table-column prop="timeCost" label="答题用时(分钟)" align="center"></el-table-column> |
||||
<el-table-column prop="workNumber" label="考试状态" align="center"> |
||||
<template slot-scope="scope"> |
||||
{{getExamStatusName(scope.row.state)}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="批阅状态" align="center"> |
||||
<template slot-scope="scope"> |
||||
{{getReviewStatusName(scope.row.reviewStatus)}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" align="center"> |
||||
<template slot-scope="scope"> |
||||
<el-button type="text" @click="review(scope.row,false)">查看</el-button> |
||||
<el-button type="text" @click="review(scope.row,true)" v-if="(scope.row.reviewStatus == 0 || scope.row.reviewStatus == 1) && scope.row.state == 2">批阅</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination |
||||
background |
||||
@current-change="handleCurrentChange" |
||||
:current-page="page" |
||||
:page-size="pageSize" |
||||
layout="total,prev, pager, next" |
||||
:total="total" |
||||
></el-pagination> |
||||
</div> |
||||
</el-card> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import { mapState,mapGetters,mapActions } from 'vuex' |
||||
export default { |
||||
data() { |
||||
return { |
||||
state: '3', |
||||
reviewStatusList: [ |
||||
{ |
||||
id: 0, |
||||
name: '未批阅' |
||||
},{ |
||||
id: 1, |
||||
name: '批阅部分' |
||||
},{ |
||||
id: 2, |
||||
name: '已批阅' |
||||
} |
||||
], |
||||
keyword: '', |
||||
listData: [], |
||||
page: 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
searchTimer: null, |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapState('practice', [ |
||||
'practiseId','userId' |
||||
]), |
||||
...mapGetters('practice', [ |
||||
'getReviewStatusName','getExamStatusName' |
||||
]) |
||||
}, |
||||
mounted() { |
||||
this.getData() |
||||
}, |
||||
methods: { |
||||
...mapActions('practice', [ |
||||
'setReviewInfo' |
||||
]), |
||||
getData() { |
||||
this.$post(`${this.api.reviewListByStudent}?pageNum=${this.page}&pageSize=${this.pageSize}&practiseId=${this.practiseId}&userId=${this.userId}&state=${this.state}`) |
||||
.then(res => { |
||||
this.listData = res.data.list.list |
||||
this.total = res.data.list.totalCount |
||||
}) |
||||
.catch(err => {}) |
||||
}, |
||||
handleCurrentChange(val) { |
||||
this.page = val |
||||
this.getData() |
||||
}, |
||||
review(row,isReview){ |
||||
this.setReviewInfo({ |
||||
isReview, |
||||
id: row.id, |
||||
practiseId: row.practiseId, |
||||
paperId: row.testPaperId, |
||||
stuId: row.userId, |
||||
reviewStatus: row.reviewStatus, |
||||
identification: row.identification |
||||
}) |
||||
this.$router.push('doReview') |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
/deep/.no-mb.el-form-item{ |
||||
margin-bottom: 0; |
||||
} |
||||
</style> |
@ -0,0 +1,155 @@ |
||||
<template> |
||||
<div> |
||||
<el-card shadow="hover" class="m-b-20"> |
||||
<div class="flex a-center m-b-20"> |
||||
<p class="hr_tag"></p> |
||||
<span>筛选</span> |
||||
</div> |
||||
<div class="flex j-between"> |
||||
<el-form label-width="80px" inline> |
||||
<el-form-item class="no-mb" label="批阅状态"> |
||||
<el-select v-model="state" clearable placeholder="请选择批阅状态" @change="getData"> |
||||
<el-option label="不限" value="3"></el-option> |
||||
<el-option v-for="(item,index) in reviewStatusList" :key="index" :label="item.name" :value="item.id"></el-option> |
||||
|
||||
</el-select> |
||||
</el-form-item> |
||||
</el-form> |
||||
<div> |
||||
<el-input |
||||
placeholder="请输入真实姓名/学号" |
||||
prefix-icon="el-icon-search" |
||||
v-model="keyword" |
||||
clearable |
||||
></el-input> |
||||
</div> |
||||
</div> |
||||
</el-card> |
||||
|
||||
<el-card shadow="hover" class="m-b-20"> |
||||
<div class="flex j-between m-b-20"> |
||||
<div class="flex a-center"> |
||||
<p class="hr_tag"></p> |
||||
<span>练习批阅</span> |
||||
</div> |
||||
</div> |
||||
|
||||
<el-table |
||||
:data="listData" |
||||
ref="table" |
||||
row-key="id" |
||||
class="table" |
||||
stripe |
||||
header-align="center" |
||||
> |
||||
<el-table-column type="index" width="100" label="序号" align="center"> |
||||
<template |
||||
slot-scope="scope" |
||||
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||
</el-table-column> |
||||
<el-table-column prop="userName" label="真实姓名" align="center"></el-table-column> |
||||
<el-table-column prop="workNumber" label="学号" align="center"></el-table-column> |
||||
<el-table-column label="批阅状态" align="center"> |
||||
<template slot-scope="scope"> |
||||
{{getReviewStatusName(scope.row.reviewStatus)}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" align="center"> |
||||
<template slot-scope="scope"> |
||||
<el-button type="text" @click="review(scope.row,false)">查看</el-button> |
||||
<el-button type="text" @click="review(scope.row,true)" v-if="(scope.row.reviewStatus == 0 || scope.row.reviewStatus == 1) && scope.row.examinationStatus == 2">批阅</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination |
||||
background |
||||
@current-change="handleCurrentChange" |
||||
:current-page="page" |
||||
:page-size="pageSize" |
||||
layout="total,prev, pager, next" |
||||
:total="total" |
||||
></el-pagination> |
||||
</div> |
||||
</el-card> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import { mapState,mapGetters,mapActions } from 'vuex' |
||||
export default { |
||||
data() { |
||||
return { |
||||
state: '3', |
||||
reviewStatusList: [ |
||||
{ |
||||
id: 0, |
||||
name: '未批阅' |
||||
},{ |
||||
id: 1, |
||||
name: '批阅部分' |
||||
},{ |
||||
id: 2, |
||||
name: '已批阅' |
||||
} |
||||
], |
||||
keyword: '', |
||||
listData: [], |
||||
page: 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
searchTimer: null, |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapState('user', [ |
||||
'userId','clientId' |
||||
]), |
||||
...mapState('practice', [ |
||||
'practiseId' |
||||
]), |
||||
...mapGetters('practice', [ |
||||
'getReviewStatusName' |
||||
]) |
||||
}, |
||||
mounted() { |
||||
this.getData() |
||||
}, |
||||
watch: { |
||||
keyword: function(val) { |
||||
clearTimeout(this.searchTimer) |
||||
this.searchTimer = setTimeout(() => { |
||||
this.getData() |
||||
},500) |
||||
} |
||||
}, |
||||
methods: { |
||||
...mapActions('practice', [ |
||||
'setReviewByStudentInfo' |
||||
]), |
||||
getData() { |
||||
this.$post(`${this.api.practiceReviewList}?pageNum=${this.page}&pageSize=${this.pageSize}&practiseId=${this.practiseId}&keyword=${this.keyword}&state=${this.state}`) |
||||
.then(res => { |
||||
this.listData = res.data.list.list |
||||
this.total = res.data.list.totalCount |
||||
}) |
||||
.catch(err => {}) |
||||
}, |
||||
handleCurrentChange(val) { |
||||
this.page = val |
||||
this.getData() |
||||
}, |
||||
review(row,isReview){ |
||||
this.setReviewByStudentInfo({ |
||||
userId: row.userId |
||||
}) |
||||
this.$router.push('result') |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
/deep/.no-mb.el-form-item{ |
||||
margin-bottom: 0; |
||||
} |
||||
</style> |
@ -0,0 +1,269 @@ |
||||
<template> |
||||
<div> |
||||
<el-row :gutter="20"> |
||||
<el-col :span="24"> |
||||
<el-card shadow="hover" class="m-b-20"> |
||||
<div class="flex a-center m-b-20"> |
||||
<p class="hr_tag"></p> |
||||
<span>筛选</span> |
||||
</div> |
||||
<div class="flex j-between"> |
||||
<el-form label-width="80px" inline> |
||||
<el-form-item class="no-mb" label="教学班级"> |
||||
<el-select v-model="classId" clearable placeholder="请选择教学班级" @change="getData"> |
||||
<el-option v-for="(item,index) in classList" :key="index" :label="item.className" :value="item.classId"></el-option> |
||||
</el-select> |
||||
</el-form-item> |
||||
<el-form-item class="no-mb" label="练习名称"> |
||||
<el-select v-model="practiseId" clearable placeholder="请选择练习名称" @change="getData" :disabled="classIdAss ? true : classId == ''"> |
||||
<el-option v-for="(item,index) in practiceNameList" :key="index" :label="item.practiseName" :value="item.practiseId"></el-option> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-form> |
||||
<div> |
||||
<el-input |
||||
placeholder="请输入学生姓名或学号" |
||||
prefix-icon="el-icon-search" |
||||
v-model="keyword" |
||||
clearable |
||||
></el-input> |
||||
</div> |
||||
</div> |
||||
</el-card> |
||||
</el-col> |
||||
|
||||
<el-col :span="24"> |
||||
<el-card shadow="hover" class="m-b-20"> |
||||
<div class="flex j-between m-b-20"> |
||||
<div class="flex a-center"> |
||||
<p class="hr_tag"></p> |
||||
<span>练习成绩</span> |
||||
</div> |
||||
<div> |
||||
<el-button |
||||
type="primary" |
||||
size="small" |
||||
round |
||||
@click="exportData" |
||||
>导出</el-button> |
||||
</div> |
||||
</div> |
||||
|
||||
<el-table |
||||
:data="listData" |
||||
ref="table" |
||||
row-key="id" |
||||
class="table" |
||||
stripe |
||||
header-align="center" |
||||
@selection-change="handleSelectionChange" |
||||
> |
||||
<el-table-column |
||||
type="selection" |
||||
width="55" |
||||
align="center" |
||||
:reserve-selection="true" |
||||
></el-table-column> |
||||
<el-table-column type="index" width="100" label="序号" align="center"> |
||||
<template |
||||
slot-scope="scope" |
||||
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||
</el-table-column> |
||||
<el-table-column prop="userName" label="真实姓名" align="center"></el-table-column> |
||||
<el-table-column prop="workNumber" label="学号" align="center"></el-table-column> |
||||
<el-table-column prop="max" label="最高分" align="center"></el-table-column> |
||||
<el-table-column prop="min" label="最低分" align="center"></el-table-column> |
||||
<el-table-column prop="avg" label="平均分" align="center"></el-table-column> |
||||
<el-table-column label="操作" align="center"> |
||||
<template slot-scope="scope"> |
||||
<el-button type="text" @click="showDetail(scope.row)">查看详情</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination |
||||
background |
||||
@current-change="handleCurrentChange" |
||||
:current-page="page" |
||||
:page-size="pageSize" |
||||
layout="total,prev, pager, next" |
||||
:total="total" |
||||
></el-pagination> |
||||
</div> |
||||
</el-card> |
||||
</el-col> |
||||
</el-row> |
||||
|
||||
<el-dialog title="练习成绩详情" :visible.sync="detailVisible" width="40%" :close-on-click-modal="false"> |
||||
<div class="flex flex-j-e"> |
||||
<div class="m-b-20"> |
||||
<el-input |
||||
placeholder="请输入练习项目名称" |
||||
prefix-icon="el-icon-search" |
||||
v-model="keywordAch" |
||||
clearable |
||||
></el-input> |
||||
</div> |
||||
</div> |
||||
|
||||
<el-table |
||||
:data="achiList" |
||||
ref="table" |
||||
row-key="id" |
||||
class="table" |
||||
stripe |
||||
header-align="center" |
||||
> |
||||
<el-table-column type="index" width="100" label="序号" align="center"> |
||||
<template |
||||
slot-scope="scope" |
||||
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||
</el-table-column> |
||||
<el-table-column prop="paperName" label="练习试卷名称" align="center"></el-table-column> |
||||
<el-table-column prop="examTime" label="开始时间" align="center"></el-table-column> |
||||
<el-table-column prop="score" label="得分" align="center"></el-table-column> |
||||
<el-table-column label="操作" align="center"> |
||||
<template slot-scope="scope"> |
||||
<el-button type="text" @click="show(scope.row)">查看</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination |
||||
background |
||||
@current-change="handleAchCurrentChange" |
||||
:current-page="pageAch" |
||||
:page-size="pageSizeAch" |
||||
layout="total,prev, pager, next" |
||||
:total="totalAch" |
||||
></el-pagination> |
||||
</div> |
||||
|
||||
<span slot="footer" class="dialog-footer"> |
||||
<el-button @click="detailVisible = false">取消</el-button> |
||||
<el-button type="primary">确定</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import { mapState,mapActions } from 'vuex' |
||||
import Setting from '@/setting' |
||||
export default { |
||||
data() { |
||||
return { |
||||
classId: '', |
||||
classList: [], |
||||
practiseId: '', |
||||
practiceNameList: [], |
||||
keyword: '', |
||||
listData: [], |
||||
page: 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
searchTimer: null, |
||||
detailVisible: false, |
||||
keywordAch: '', |
||||
achiList: [], |
||||
multipleSelectionAch: [], |
||||
pageAch: 1, |
||||
pageSizeAch: 10, |
||||
totalAch: 0, |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapState('user', [ |
||||
'userId' |
||||
]), |
||||
...mapState('achievement', [ |
||||
'practiceIdAss','practiceNameAss','classIdAss','classNameAss' |
||||
]), |
||||
}, |
||||
mounted() { |
||||
this.getClass() |
||||
}, |
||||
watch: { |
||||
keyword: function(val) { |
||||
clearTimeout(this.searchTimer) |
||||
this.searchTimer = setTimeout(() => { |
||||
this.getData() |
||||
},500) |
||||
}, |
||||
keywordAch: function(val) { |
||||
clearTimeout(this.searchTimer) |
||||
this.searchTimer = setTimeout(() => { |
||||
this.getData() |
||||
},500) |
||||
} |
||||
}, |
||||
methods: { |
||||
...mapActions('achievement', [ |
||||
'setPracDetailInfo' |
||||
]), |
||||
getData() { |
||||
this.$post(`${this.api.AchievementList}?pageNum=${this.page}&pageSize=${this.pageSize}&keyword=${this.keyword}&practiseId=${this.practiseId}&classId=${this.classId}`) |
||||
.then(res => { |
||||
this.listData = res.data.list.list |
||||
this.total = res.data.list.totalCount |
||||
}) |
||||
.catch(err => {}) |
||||
}, |
||||
getClass() { |
||||
let classId = this.classIdAss.split(',') |
||||
let className = this.classNameAss.split(',') |
||||
let classList = [] |
||||
classId.map((n,i) => { |
||||
classList.push({ |
||||
classId: n, |
||||
className: className[i] |
||||
}) |
||||
}) |
||||
this.classId = classId[0] |
||||
this.classList = classList |
||||
this.practiceNameList = [{ |
||||
practiseId: this.practiceIdAss, |
||||
practiseName: this.practiceNameAss |
||||
}] |
||||
this.practiseId = this.practiceIdAss |
||||
this.getData() |
||||
}, |
||||
handleCurrentChange(val) { |
||||
this.page = val |
||||
this.getData() |
||||
}, |
||||
showDetail(row){ |
||||
this.getDetail(row) |
||||
this.detailVisible = true |
||||
}, |
||||
getDetail(row){ |
||||
this.$post(`${this.api.AchievementDetail}?userId=${row.userId}&practiseId=${this.practiseId}&pageNum=${this.page}&pageSize=${this.pageSize}`) |
||||
.then(res => { |
||||
this.achiList = res.data.list.list |
||||
this.totalAch = res.data.list.totalCount |
||||
}).catch(err => {}) |
||||
}, |
||||
handleSelectionChange(val) { |
||||
this.multipleSelection = val |
||||
}, |
||||
show(row){ |
||||
this.setPracDetailInfo({ |
||||
practiseId: this.practiseId, |
||||
}) |
||||
this.$router.push('detail') |
||||
}, |
||||
handleAchCurrentChange(val) { |
||||
this.page = val |
||||
this.getData() |
||||
}, |
||||
exportData(){ |
||||
location.href = `${Setting.apiBaseURL}${this.api.exportPractice}?practiseId=${this.practiseId}&classId=${this.classId}` |
||||
}, |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
/deep/.no-mb.el-form-item{ |
||||
margin-bottom: 0; |
||||
} |
||||
</style> |
@ -0,0 +1,23 @@ |
||||
import BasicLayout from '@/layouts/home'; |
||||
|
||||
const meta = {}; |
||||
|
||||
const pre = 'messageBoard-'; |
||||
|
||||
export default { |
||||
path: '/messageBoard', |
||||
name: 'messageBoard', |
||||
redirect: { |
||||
name: `${pre}list` |
||||
}, |
||||
meta, |
||||
component: BasicLayout, |
||||
children: [ |
||||
{ |
||||
name: `${pre}list`, |
||||
path: `list`, |
||||
component: () => import('@/pages/messageBoard/list'), |
||||
meta: { title: '交流互动' } |
||||
}, |
||||
] |
||||
}; |
@ -0,0 +1,52 @@ |
||||
import BasicLayout from '@/layouts/home'; |
||||
|
||||
const meta = {}; |
||||
|
||||
const pre = 'practice-'; |
||||
|
||||
export default { |
||||
path: '/practice', |
||||
name: 'practice', |
||||
redirect: { |
||||
name: `${pre}list` |
||||
}, |
||||
meta, |
||||
component: BasicLayout, |
||||
children: [ |
||||
{ |
||||
name: `${pre}list`, |
||||
path: `list`, |
||||
component: () => import('@/pages/practice/list'), |
||||
meta: { title: '练习管理' } |
||||
}, |
||||
{ |
||||
name: `${pre}review`, |
||||
path: `review`, |
||||
component: () => import('@/pages/practice/review'), |
||||
meta: { title: '练习批阅' } |
||||
}, |
||||
{ |
||||
name: `${pre}scoreQuery`, |
||||
path: `scoreQuery`, |
||||
component: () => import('@/pages/practice/scoreQuery/index.vue'), |
||||
meta: { title: '成绩查询' } |
||||
}, |
||||
{ |
||||
name: `${pre}result`, |
||||
path: `result`, |
||||
component: () => import('@/pages/practice/result'), |
||||
meta: { title: '查看成绩' } |
||||
}, |
||||
{ |
||||
name: `${pre}detail`, |
||||
path: `detail`, |
||||
component: () => import('@/pages/practice/detail'), |
||||
meta: { title: '答题详情' } |
||||
},{ |
||||
name: `${pre}doReview`, |
||||
path: `doReview`, |
||||
component: () => import('@/pages/practice/doReview'), |
||||
meta: { title: '批阅' } |
||||
}, |
||||
] |
||||
}; |
@ -0,0 +1,107 @@ |
||||
/** |
||||
* 考核管理 |
||||
* */ |
||||
export default { |
||||
namespaced: true, |
||||
state: { |
||||
practiseId: '', |
||||
endTime: '', |
||||
id: '', |
||||
paperId: '', |
||||
stuId: '', |
||||
isReview: false, |
||||
reviewStatus: '', |
||||
userId: '', |
||||
stateList: [ |
||||
{ |
||||
id: 1, |
||||
name: '待开始' |
||||
},{ |
||||
id: 2, |
||||
name: '进行中' |
||||
},{ |
||||
id: 3, |
||||
name: '已结束' |
||||
}
|
||||
], |
||||
reviewStatusList: [ |
||||
{ |
||||
id: 0, |
||||
name: '未批阅' |
||||
},{ |
||||
id: 1, |
||||
name: '批阅部分' |
||||
},{ |
||||
id: 2, |
||||
name: '已批阅' |
||||
},{ |
||||
id: 3, |
||||
name: '没有主观题,不需要批阅' |
||||
} |
||||
], |
||||
examStatusList: [ |
||||
{ |
||||
id: 0, |
||||
name: '未考' |
||||
},{ |
||||
id: 1, |
||||
name: '在考' |
||||
},{ |
||||
id: 2, |
||||
name: '已考' |
||||
} |
||||
], |
||||
correctingList: [ |
||||
{ |
||||
id: 0, |
||||
name: '待阅' |
||||
},{ |
||||
id: 1, |
||||
name: '已阅' |
||||
} |
||||
], |
||||
}, |
||||
getters: { |
||||
getStateName: state => id => { |
||||
return state.stateList.find(n => n.id == id).name |
||||
}, |
||||
getReviewStatusName: state => id => { |
||||
return state.reviewStatusList.find(n => n.id == id).name |
||||
}, |
||||
getExamStatusName: state => id => { |
||||
return state.examStatusList.find(n => n.id == id).name |
||||
}, |
||||
getCorrectingName: state => id => { |
||||
return state.correctingList.find(n => n.id == id).name |
||||
}, |
||||
}, |
||||
mutations: { |
||||
SET_INFO: (state, info) => { |
||||
state.practiseId = info.practiseId |
||||
state.endTime = info.endTime |
||||
}, |
||||
SET_REVIEW_INFO: (state, info) => { |
||||
state.id = info.id |
||||
state.practiseId = info.practiseId |
||||
state.paperId = info.paperId |
||||
state.stuId = info.stuId |
||||
state.isReview = info.isReview |
||||
state.reviewStatus = info.reviewStatus |
||||
state.identification = info.identification |
||||
}, |
||||
SET_REVIEW_BY_STUDENT_INFO: (state, info) => { |
||||
state.userId = info.userId |
||||
}, |
||||
}, |
||||
actions: { |
||||
setPracInfo({ commit },info) { |
||||
commit('SET_INFO',info) |
||||
}, |
||||
setReviewByStudentInfo({ commit },info) { |
||||
commit('SET_REVIEW_BY_STUDENT_INFO',info) |
||||
}, |
||||
setReviewInfo({ commit },info) { |
||||
commit('SET_REVIEW_INFO',info) |
||||
}, |
||||
} |
||||
} |
@ -0,0 +1,9 @@ |
||||
@mixin ellipsis { |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
white-space: nowrap; |
||||
} |
||||
|
||||
.ellipsis{ |
||||
@include ellipsis(); |
||||
} |
Loading…
Reference in new issue