|
|
@@ -23,8 +23,11 @@
|
|
|
<v-card style="height: 100%">
|
|
|
<e-charts-component
|
|
|
:options="rankOption"
|
|
|
- v-if="rankOption"
|
|
|
+ v-if="examEnded && rankOption"
|
|
|
></e-charts-component>
|
|
|
+ <v-card-title v-else>
|
|
|
+ {{ loadingText }}
|
|
|
+ </v-card-title>
|
|
|
</v-card>
|
|
|
</v-col>
|
|
|
<v-col cols="6">
|
|
|
@@ -62,7 +65,7 @@ import Vue from 'vue'
|
|
|
import PageHeader from '@/views/components/PageHeader.vue'
|
|
|
import ExamQuestionsInfo from '@/views/components/ExamQuestionsInfo.vue'
|
|
|
import { TeacherQuestionSerializer, ReceivedData } from '@/api/types'
|
|
|
-import { getExamQuestions } from '@/api/exam'
|
|
|
+import { getExamById, getExamQuestions } from '@/api/exam'
|
|
|
import { AxiosResponse } from 'axios'
|
|
|
import { getQuestionInfo } from '@/api/question'
|
|
|
import EChartsComponent from '@/views/components/echarts/EChartsComponent.vue'
|
|
|
@@ -72,6 +75,8 @@ import {
|
|
|
GaugeChartOption
|
|
|
} from '@/views/components/echarts/echarts.type'
|
|
|
import { getPersonalReport } from '@/api/report'
|
|
|
+import dayjs from 'dayjs'
|
|
|
+import { TIME_FORMAT } from '@/utils/common'
|
|
|
|
|
|
export default Vue.extend({
|
|
|
name: 'PersonalResult',
|
|
|
@@ -90,7 +95,7 @@ export default Vue.extend({
|
|
|
href: '/student'
|
|
|
},
|
|
|
{
|
|
|
- text: '评测列表',
|
|
|
+ text: '我的评测',
|
|
|
disabled: false,
|
|
|
href: '/student/exams'
|
|
|
},
|
|
|
@@ -103,21 +108,32 @@ export default Vue.extend({
|
|
|
examQuestions: [] as Array<TeacherQuestionSerializer>,
|
|
|
skillOption: (null as unknown) as BarChartOption,
|
|
|
gradeOption: (null as unknown) as PieChartOption,
|
|
|
- rankOption: (null as unknown) as GaugeChartOption
|
|
|
+ rankOption: (null as unknown) as GaugeChartOption,
|
|
|
+ totalScore: 100,
|
|
|
+ examEnded: false,
|
|
|
+ loadingText: ''
|
|
|
}
|
|
|
},
|
|
|
mounted() {
|
|
|
const examId = this.$route.params.examId
|
|
|
- let rank = 0
|
|
|
- let score = 0
|
|
|
- getPersonalReport(examId).then(({ data }) => {
|
|
|
- rank = data.result.rank
|
|
|
- score = data.result.score
|
|
|
+
|
|
|
+ getExamById(examId).then(({ data }) => {
|
|
|
+ const curTime = dayjs()
|
|
|
+ const examEndTime = dayjs(data.result.endTime, TIME_FORMAT)
|
|
|
+ if (curTime.isAfter(examEndTime.add(1, 'minute'))) {
|
|
|
+ this.examEnded = true
|
|
|
+ } else {
|
|
|
+ this.loadingText = '考试进行中,请在考试结束后查看排名信息'
|
|
|
+ }
|
|
|
})
|
|
|
|
|
|
getExamQuestions(examId).then(({ data }) => {
|
|
|
this.fetching = true
|
|
|
-
|
|
|
+ this.totalScore = Object.values(data.result.questionAndScore).reduce(
|
|
|
+ (prev, cur) => {
|
|
|
+ return prev + cur
|
|
|
+ }
|
|
|
+ )
|
|
|
let questionsPromises: Promise<
|
|
|
AxiosResponse<ReceivedData<TeacherQuestionSerializer, 0>>
|
|
|
>[] = []
|
|
|
@@ -134,135 +150,140 @@ export default Vue.extend({
|
|
|
})
|
|
|
})
|
|
|
|
|
|
- this.skillOption = {
|
|
|
- title: {
|
|
|
- text: '知识点掌握情况'
|
|
|
- },
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- axisPointer: {
|
|
|
- type: 'shadow'
|
|
|
- }
|
|
|
- },
|
|
|
- legend: {
|
|
|
- data: ['个人正确率', '平均正确率']
|
|
|
- },
|
|
|
- grid: {
|
|
|
- left: '3%',
|
|
|
- right: '4%',
|
|
|
- bottom: '3%',
|
|
|
- containLabel: true
|
|
|
- },
|
|
|
- xAxis: [
|
|
|
- {
|
|
|
- type: 'category',
|
|
|
- data: ['数据结构', '网络', '操作系统', '测试', '设计模式']
|
|
|
- }
|
|
|
- ],
|
|
|
- yAxis: [
|
|
|
- {
|
|
|
- type: 'value'
|
|
|
- }
|
|
|
- ],
|
|
|
- series: [
|
|
|
- {
|
|
|
- name: '个人正确率',
|
|
|
- type: 'bar',
|
|
|
- data: [50, 33, 31, 34, 39]
|
|
|
- },
|
|
|
- {
|
|
|
- name: '平均正确率',
|
|
|
- type: 'bar',
|
|
|
- data: [12, 13, 10, 14, 90]
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
+ getPersonalReport(examId).then(({ data }) => {
|
|
|
+ let rank = data.result.rank
|
|
|
+ let score = data.result.score
|
|
|
|
|
|
- this.gradeOption = {
|
|
|
- tooltip: {
|
|
|
- trigger: 'item',
|
|
|
- formatter: '{a}{b}: {c} ({d}%)'
|
|
|
- },
|
|
|
- title: {
|
|
|
- text: '得分 ',
|
|
|
- left: 'right'
|
|
|
- },
|
|
|
- legend: {
|
|
|
- orient: 'vertical',
|
|
|
- left: 10,
|
|
|
- data: ['错误', '正确']
|
|
|
- },
|
|
|
- series: [
|
|
|
- {
|
|
|
- name: '',
|
|
|
- type: 'pie',
|
|
|
- radius: ['50%', '70%'],
|
|
|
- avoidLabelOverlap: false,
|
|
|
- label: {
|
|
|
- show: false
|
|
|
- },
|
|
|
- emphasis: {
|
|
|
- label: {
|
|
|
- show: true,
|
|
|
- fontSize: '15',
|
|
|
- fontWeight: 'bold'
|
|
|
- }
|
|
|
- },
|
|
|
- labelLine: {
|
|
|
- show: false
|
|
|
+ this.skillOption = {
|
|
|
+ title: {
|
|
|
+ text: '知识点掌握情况'
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ axisPointer: {
|
|
|
+ type: 'shadow'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ data: ['个人正确率', '平均正确率']
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ left: '3%',
|
|
|
+ right: '4%',
|
|
|
+ bottom: '3%',
|
|
|
+ containLabel: true
|
|
|
+ },
|
|
|
+ xAxis: [
|
|
|
+ {
|
|
|
+ type: 'category',
|
|
|
+ data: ['数据结构', '网络', '操作系统', '测试', '设计模式']
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ yAxis: [
|
|
|
+ {
|
|
|
+ type: 'value'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '个人正确率',
|
|
|
+ type: 'bar',
|
|
|
+ data: [50, 33, 31, 34, 39]
|
|
|
},
|
|
|
- data: [
|
|
|
- { value: 100 - score, name: '错误' },
|
|
|
- { value: score, name: '正确' }
|
|
|
- ]
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
+ {
|
|
|
+ name: '平均正确率',
|
|
|
+ type: 'bar',
|
|
|
+ data: [12, 13, 10, 14, 90]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
|
|
|
- this.rankOption = {
|
|
|
- series: [
|
|
|
- {
|
|
|
- type: 'gauge',
|
|
|
- startAngle: 180,
|
|
|
- endAngle: 0,
|
|
|
- min: 100,
|
|
|
- max: 0,
|
|
|
- splitNumber: 5,
|
|
|
- axisLabel: {
|
|
|
- distance: 15,
|
|
|
- fontSize: 10
|
|
|
- },
|
|
|
+ this.gradeOption = {
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item',
|
|
|
+ formatter: '{a}{b}: {c} ({d}%)'
|
|
|
+ },
|
|
|
+ title: {
|
|
|
+ text: '得分 ',
|
|
|
+ left: 'right'
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ orient: 'vertical',
|
|
|
+ left: 10,
|
|
|
+ data: ['错误', '正确']
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '',
|
|
|
+ type: 'pie',
|
|
|
+ radius: ['50%', '70%'],
|
|
|
+ avoidLabelOverlap: false,
|
|
|
+ label: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ fontSize: '15',
|
|
|
+ fontWeight: 'bold'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ data: [
|
|
|
+ { value: this.totalScore - score, name: '错误' },
|
|
|
+ { value: score, name: '正确' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
|
|
|
- progress: {
|
|
|
- show: true,
|
|
|
- roundCap: true,
|
|
|
- width: 10
|
|
|
- },
|
|
|
+ this.rankOption = {
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'gauge',
|
|
|
+ startAngle: 180,
|
|
|
+ endAngle: 0,
|
|
|
+ min: 100,
|
|
|
+ max: 0,
|
|
|
+ splitNumber: 5,
|
|
|
+ axisLabel: {
|
|
|
+ distance: 15,
|
|
|
+ fontSize: 10
|
|
|
+ },
|
|
|
|
|
|
- detail: {
|
|
|
- formatter: function(value) {
|
|
|
- return '排名前 {value|' + value.toFixed(0) + '}{unit|%}'
|
|
|
+ progress: {
|
|
|
+ show: true,
|
|
|
+ roundCap: true,
|
|
|
+ width: 10
|
|
|
},
|
|
|
- rich: {
|
|
|
- value: {
|
|
|
- fontSize: 20,
|
|
|
- fontWeight: 'bolder',
|
|
|
- color: '#777'
|
|
|
+
|
|
|
+ detail: {
|
|
|
+ formatter: function(value) {
|
|
|
+ return '排名前 {value|' + value.toFixed(0) + '}{unit|%}'
|
|
|
},
|
|
|
- unit: {
|
|
|
- fontSize: 20,
|
|
|
- color: '#999'
|
|
|
+ rich: {
|
|
|
+ value: {
|
|
|
+ fontSize: 20,
|
|
|
+ fontWeight: 'bolder',
|
|
|
+ color: '#777'
|
|
|
+ },
|
|
|
+ unit: {
|
|
|
+ fontSize: 20,
|
|
|
+ color: '#999'
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- },
|
|
|
- data: [
|
|
|
- {
|
|
|
- value: rank
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
+ },
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ value: rank
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
})
|
|
|
</script>
|