提交 3dfd6d55 authored 作者: lihuihui's avatar lihuihui

update:添加批阅考试

上级 7b1fc8aa
...@@ -98,3 +98,17 @@ export function getCourseQuestion(params) { ...@@ -98,3 +98,17 @@ export function getCourseQuestion(params) {
export function setCourseCache(params) { export function setCourseCache(params) {
return httpRequest.post('/api/zy/v2/examination/course-papers', params) return httpRequest.post('/api/zy/v2/examination/course-papers', params)
} }
/**
* 老师批阅
*/
export function getReviewDetails(params) {
return httpRequest.get('/api/zy/v3-teacher/examination/sheet-details', { params })
}
/**
* 提交批阅
*/
export function submitReviewDetails(params) {
return httpRequest.post('/api/zy/v3-teacher/examination/sheet-submit', params)
}
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
<el-tabs v-model="activeName"> <el-tabs v-model="activeName">
<el-tab-pane :label="`全部(${students.length})`" name="0"> <el-tab-pane :label="`全部(${students.length})`" name="0">
<ul> <ul>
<li v-for="student in students" :key="student.id">{{ student.name }}</li> <li v-for="student in students" :key="student.id" @click="$emit('studentReview', student)">{{ student.name }}</li>
</ul> </ul>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="`未批阅(${unreviewedStudents.length})`" name="1"> <el-tab-pane :label="`未批阅(${unreviewedStudents.length})`" name="1">
<ul> <ul>
<li v-for="student in unreviewedStudents" :key="student.id">{{ student.name }}</li> <li v-for="student in unreviewedStudents" :key="student.id" @click="$emit('studentReview', student)">{{ student.name }}</li>
</ul> </ul>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="`已批阅(${reviewedStudents.length})`" name="2"> <el-tab-pane :label="`已批阅(${reviewedStudents.length})`" name="2">
<ul> <ul>
<li v-for="student in reviewedStudents" :key="student.id">{{ student.name }}</li> <li v-for="student in reviewedStudents" :key="student.id" @click="$emit('studentReview', student)">{{ student.name }}</li>
</ul> </ul>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
......
...@@ -65,7 +65,8 @@ export default { ...@@ -65,7 +65,8 @@ export default {
const refData = this.$refs.exam const refData = this.$refs.exam
const id = this.data.id const id = this.data.id
const answer = {} const answer = {}
refData.questionList.forEach(item => { console.log(refData.questionGroups)
refData.questionGroups.forEach(item => {
if (!answer[item.question_item_id]) answer[item.question_item_id] = {} if (!answer[item.question_item_id]) answer[item.question_item_id] = {}
item.question_list.forEach(cItem => { item.question_list.forEach(cItem => {
answer[item.question_item_id][cItem.id] = { answer[item.question_item_id][cItem.id] = {
......
<template> <template>
<app-container> <app-container>
<app-list v-bind="tableOptions" ref="list"> <app-list v-bind="tableOptions" ref="list" @row-click="handleRowClick">
<template v-slot:table-name="{ row }"> <template v-slot:table-name="{ row }">
<el-link type="primary">{{ row.paper_title }}</el-link> <el-link type="primary">{{ row.paper_title }}</el-link>
</template> </template>
</app-list> </app-list>
<review-students :visible.sync="visible" :students="currentClickRow.students"></review-students> <review-students @studentReview="studentReview" :visible.sync="visible" :students="currentClickRow.students"></review-students>
</app-container> </app-container>
</template> </template>
...@@ -45,7 +45,17 @@ export default { ...@@ -45,7 +45,17 @@ export default {
methods: { methods: {
handleRowClick(row) { handleRowClick(row) {
this.currentClickRow = row this.currentClickRow = row
window.localStorage.examStudentsList = JSON.stringify(row.students)
this.visible = true this.visible = true
},
studentReview(data) {
this.$router.push({
path: '/teacher/review',
query: {
sheet_id: data.sheet_id,
stu_id: data.id
}
})
} }
} }
} }
......
<template>
<div>
<exam-card
title="批阅考卷"
:hasSubmitBtn="false"
:hasCountdown="false"
:hasCollect="false"
:hasMark="false"
:data="data"
:disabled="false"
@submit="submitExam"
@back="handleBack"
@page-change="handlePageChange"
ref="exam"
v-if="Object.keys(data).length"
>
<template v-slot:question-item="{ item, data }">
<div class="review-box">
<div class="review-btn">
<el-button type="primary" @click="visible = true">点评</el-button>
</div>
<div ref='reviewCard' :scorenum="item.score" :questionid="item.id" :itemid="data.question_item_id"></div>
<div class="review-card" v-if="visible">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>本题{{ item.score }}</span>
<div class="score">
<span>学生得分:</span>
<input type="number" :disabled="isReviewFlag" v-model="scoreNum" placeholder="请输入分数">
</div>
</div>
<div class="textarea">
<el-input
:disabled="isReviewFlag"
type="textarea"
:rows="5"
placeholder="请输入本题点评"
max="2"
resize="none"
v-model="textarea">
</el-input>
</div>
<div class="submit-btn">
<el-button type="primary" @click="submitExam" v-if="!isReviewFlag">提交点评</el-button>
</div>
</el-card>
</div>
</div>
</template>
<template v-slot:students="{ data }">
<div class="stu-list">
<div class="title">
<span>学生列表</span>
<el-select @change="change" v-model="selectValue" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<ul>
<li :class="item.id === $route.query.stu_id ? 'active' : ''" v-for="(item, index) in studentList" :key="index">{{ item.name }}</li>
</ul>
</div>
</template>
</exam-card>
</div>
</template>
<script>
import * as api from '@/api/exam.js'
import ExamCard from '@/components/exam/examCard.vue'
export default {
components: { ExamCard },
data() {
return {
scoreNum: '',
textarea: '',
data: {
cacheAnswerTime: null // 缓存题计时器
},
isReviewFlag: false,
visible: false,
selectValue: 0,
studentList: [],
options: [
{
value: 0,
label: '全部'
},
{
value: 1,
label: '未批阅'
},
{
value: 2,
label: '已批阅'
}
]
}
},
computed: {
examId() {
return this.$route.query.exam_id
}
},
created() {
// 获取考卷
this.getTopic()
},
mounted() {
this.studentList = JSON.parse(window.localStorage.examStudentsList)
setTimeout(() => {
this.handlePageChange()
}, 1000)
},
beforeDestroy() {
clearInterval(this.cacheAnswerTime) // 停止缓存
},
methods: {
change() {
this.studentList = JSON.parse(window.localStorage.examStudentsList)
if (this.selectValue !== 0) {
this.studentList = this.studentList.filter(item => parseInt(item.status) === parseInt(this.selectValue))
}
},
// 获取考卷
getTopic() {
api.getReviewDetails({ sheet_id: this.$route.query.sheet_id }).then(response => {
this.data = JSON.parse(response.data).sheet
})
},
// 返回
handleBack() {
this.$router.push('/teacher/exam')
},
// 提交批阅
submitExam() {
const refReview = this.$refs.reviewCard
if (this.textarea === '' || this.scoreNum === '') {
this.$message('请填写')
return false
}
if (parseInt(this.scoreNum) > parseInt(refReview.getAttribute('scorenum'))) {
this.$message('请填写正确分值')
return false
}
const param = {
sheet_id: this.$route.query.sheet_id,
question_item_id: refReview.getAttribute('itemid'),
question_id: refReview.getAttribute('questionid'),
comment: this.textarea,
score: this.scoreNum
}
this.$confirm('确认评价后将不得再次修改', '请确认', {
confirmButtonText: '点评',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
api.submitReviewDetails(param).then(response => {
this.$message('批阅成功')
})
}).catch(() => {
})
},
handlePageChange() {
const refReview = this.$refs.reviewCard
const itemId = refReview.getAttribute('itemid')
const questionId = refReview.getAttribute('questionid')
this.visible = false
const isReview = this.data.score_items[itemId][questionId]
if (isReview.checked_flag) {
this.scoreNum = isReview.score
this.textarea = isReview.comment
this.isReviewFlag = true
this.visible = true
} else {
this.scoreNum = ''
this.textarea = ''
this.isReviewFlag = false
this.visible = false
}
}
}
}
</script>
<style lang="scss" scoped>
.review-btn{
display: flex;
justify-content: right;
padding: 20px 0;
}
.score{
float: right;
display: flex;
input{
width: 90px;
height: 100%;
outline: none;
}
}
.submit-btn{
display: flex;
justify-content: center;
padding-top: 20px;
}
.review-box{
// max-width: 500px;
}
.stu-list{
.title{
// text-align: center;
margin-bottom: 10px;
display: flex;
align-items: center;
justify-content: space-between;
::v-deep{
.el-select{
width: 120px;
}
}
}
ul{
li{
padding: 3px 0;
&.active{
color: #c01540;
}
}
}
}
</style>
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<el-link type="primary">{{ row.paper_title }}</el-link> <el-link type="primary">{{ row.paper_title }}</el-link>
</template> </template>
</app-list> </app-list>
<review-students :visible.sync="visible" :students="currentClickRow.students"></review-students> <review-students @studentReview="studentReview" :visible.sync="visible" :students="currentClickRow.students"></review-students>
</app-container> </app-container>
</template> </template>
...@@ -46,7 +46,17 @@ export default { ...@@ -46,7 +46,17 @@ export default {
methods: { methods: {
handleRowClick(row) { handleRowClick(row) {
this.currentClickRow = row this.currentClickRow = row
window.localStorage.testStudentsList = JSON.stringify(row.students)
this.visible = true this.visible = true
},
studentReview(data) {
this.$router.push({
path: '/teacher/testReview',
query: {
sheet_id: data.sheet_id,
stu_id: data.id
}
})
} }
} }
} }
......
<template>
<div>
<exam-card
title="批阅考卷"
:hasSubmitBtn="false"
:hasCountdown="false"
:hasCollect="false"
:hasMark="false"
:data="data"
:disabled="false"
@submit="submitExam"
@back="handleBack"
@page-change="handlePageChange"
ref="exam"
v-if="Object.keys(data).length"
>
<template v-slot:question-item="{ item, data }">
<div class="review-box">
<div class="review-btn">
<el-button type="primary" @click="visible = true">点评</el-button>
</div>
<div ref='reviewCard' :scorenum="item.score" :questionid="item.id" :itemid="data.question_item_id"></div>
<div class="review-card" v-if="visible">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>本题{{ item.score }}</span>
<div class="score">
<span>学生得分:</span>
<input type="number" :disabled="isReviewFlag" v-model="scoreNum" placeholder="请输入分数">
</div>
</div>
<div class="textarea">
<el-input
:disabled="isReviewFlag"
type="textarea"
:rows="5"
placeholder="请输入本题点评"
max="2"
resize="none"
v-model="textarea">
</el-input>
</div>
<div class="submit-btn">
<el-button type="primary" @click="submitExam" v-if="!isReviewFlag">提交点评</el-button>
</div>
</el-card>
</div>
</div>
</template>
<template v-slot:students="{ data }">
<div class="stu-list">
<div class="title">
<span>学生列表</span>
<el-select @change="change" v-model="selectValue" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<ul>
<li :class="item.id === $route.query.stu_id ? 'active' : ''" v-for="(item, index) in studentList" :key="index">{{ item.name }}</li>
</ul>
</div>
</template>
</exam-card>
</div>
</template>
<script>
import * as api from '@/api/exam.js'
import ExamCard from '@/components/exam/examCard.vue'
export default {
components: { ExamCard },
data() {
return {
scoreNum: '',
textarea: '',
data: {
cacheAnswerTime: null // 缓存题计时器
},
isReviewFlag: false,
visible: false,
selectValue: 0,
studentList: [],
options: [
{
value: 0,
label: '全部'
},
{
value: 1,
label: '未批阅'
},
{
value: 2,
label: '已批阅'
}
]
}
},
computed: {
examId() {
return this.$route.query.exam_id
}
},
created() {
// 获取考卷
this.getTopic()
},
mounted() {
this.studentList = JSON.parse(window.localStorage.testStudentsList)
setTimeout(() => {
this.handlePageChange()
}, 1000)
},
beforeDestroy() {
clearInterval(this.cacheAnswerTime) // 停止缓存
},
methods: {
change() {
this.studentList = JSON.parse(window.localStorage.testStudentsList)
if (this.selectValue !== 0) {
this.studentList = this.studentList.filter(item => parseInt(item.status) === parseInt(this.selectValue))
}
},
// 获取考卷
getTopic() {
api.getReviewDetails({ sheet_id: this.$route.query.sheet_id, type: 'chapter' }).then(response => {
this.data = JSON.parse(response.data).sheet
})
},
// 返回
handleBack() {
this.$router.push('/teacher/test')
},
// 提交批阅
submitExam() {
const refReview = this.$refs.reviewCard
if (this.textarea === '' || this.scoreNum === '') {
this.$message('请填写')
return false
}
if (parseInt(this.scoreNum) > parseInt(refReview.getAttribute('scorenum'))) {
this.$message('请填写正确分值')
return false
}
const param = {
sheet_id: this.$route.query.sheet_id,
question_item_id: refReview.getAttribute('itemid'),
question_id: refReview.getAttribute('questionid'),
comment: this.textarea,
score: this.scoreNum
}
this.$confirm('确认评价后将不得再次修改', '请确认', {
confirmButtonText: '点评',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
api.submitReviewDetails(param).then(response => {
this.$message('批阅成功')
})
}).catch(() => {
})
},
handlePageChange() {
const refReview = this.$refs.reviewCard
const itemId = refReview.getAttribute('itemid')
const questionId = refReview.getAttribute('questionid')
this.visible = false
const isReview = this.data.score_items[itemId][questionId]
if (isReview.checked_flag) {
this.scoreNum = isReview.score
this.textarea = isReview.comment
this.isReviewFlag = true
this.visible = true
} else {
this.scoreNum = ''
this.textarea = ''
this.isReviewFlag = false
this.visible = false
}
}
}
}
</script>
<style lang="scss" scoped>
.review-btn{
display: flex;
justify-content: right;
padding: 20px 0;
}
.score{
float: right;
display: flex;
input{
width: 90px;
height: 100%;
outline: none;
}
}
.submit-btn{
display: flex;
justify-content: center;
padding-top: 20px;
}
.review-box{
// max-width: 500px;
}
.stu-list{
.title{
// text-align: center;
margin-bottom: 10px;
display: flex;
align-items: center;
justify-content: space-between;
::v-deep{
.el-select{
width: 120px;
}
}
}
ul{
li{
padding: 3px 0;
&.active{
color: #c01540;
}
}
}
}
</style>
...@@ -67,6 +67,14 @@ const teacherRoutes = [ ...@@ -67,6 +67,14 @@ const teacherRoutes = [
{ {
path: '/teacher/practicalCourse', path: '/teacher/practicalCourse',
component: () => import(/* webpackChunkName: "teacher" */ '@/pages/teacher/practicalCourse/index') component: () => import(/* webpackChunkName: "teacher" */ '@/pages/teacher/practicalCourse/index')
},
{
path: '/teacher/review',
component: () => import(/* webpackChunkName: "teacher" */ '@/pages/teacher/examReview/review')
},
{
path: '/teacher/testReview',
component: () => import(/* webpackChunkName: "teacher" */ '@/pages/teacher/testReview/review')
} }
] ]
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论