提交 601547dc authored 作者: matian's avatar matian

Merge remote-tracking branch 'origin/vite' into vite

...@@ -82,3 +82,11 @@ export function getClassDetail(params) { ...@@ -82,3 +82,11 @@ export function getClassDetail(params) {
params params
}) })
} }
/**
* 考试数据-看板(题目数据)
*/
export function getQuestionsDetails(params) {
return httpRequest.get('/api/zy/v3-teacher/statistics/sheet-question-details', {
params
})
}
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
import * as echarts from 'echarts' import * as echarts from 'echarts'
export default { export default {
props: { props: {
dataInfo: { type: Object, default: () => ({}) } data: { type: Object, default: () => ({}) }
}, },
data() { data() {
return { return {
...@@ -43,10 +43,7 @@ export default { ...@@ -43,10 +43,7 @@ export default {
labelLine: { labelLine: {
show: false show: false
}, },
data: [ data: []
{ value: 0, name: '及格人数', itemStyle: { color: '#6C83CE' } },
{ value: 0, name: '不及格人数', itemStyle: { color: '#D96685' } }
]
} }
] ]
} }
...@@ -57,11 +54,16 @@ export default { ...@@ -57,11 +54,16 @@ export default {
}, },
methods: { methods: {
initEchart() { initEchart() {
const data = [ console.log(this.data, '=123data', this.data.answers)
{ value: '10', name: '及格人数', itemStyle: { color: '#6C83CE' } }, const changeData = this.data.answers.reduce((a, b) => {
{ value: '10', name: '不及格人数', itemStyle: { color: '#D96685' } } const findId = this.data.options.find(item => item.id === b.option_id)
] a.push({
this.option.series[0].data = data value: b.num,
name: findId ? findId.abc : ''
})
return a
}, [])
this.option.series[0].data = changeData
const myChart = echarts.init(document.getElementById('main')) const myChart = echarts.init(document.getElementById('main'))
myChart.setOption(this.option) myChart.setOption(this.option)
} }
......
...@@ -3,26 +3,16 @@ ...@@ -3,26 +3,16 @@
<img class="bg" src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/x-learning/data/bgc1.png" alt="" /> <img class="bg" src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/x-learning/data/bgc1.png" alt="" />
<div slot="header" style="display: flex; align-items: center"> <div slot="header" style="display: flex; align-items: center">
<h1 style="font-size: 16px">概述信息</h1> <h1 style="font-size: 16px">概述信息</h1>
<!-- <img class="logo" src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/x-learning/data/exam.png" alt="" /> -->
</div> </div>
<div class="location"> <div class="location">
<el-row :gutter="20" class="row-bg" justify="space-around"> <el-row :gutter="20" class="row-bg" justify="space-around">
<el-col :span="8"> <el-col :span="8" v-for="(item, index) in data" :key="index">
<div class="title">本题分数</div> <div class="title">{{ item.title }}</div>
<div> <div>
<span class="num">111</span> <span class="num">{{ item.value }}</span>
<span class="fen" v-if="index == 2">%</span>
</div> </div>
</el-col> </el-col>
<el-col :span="8">
<div class="title">平均得分</div>
<div>
<span class="num">111</span>
</div>
</el-col>
<el-col :span="8">
<div class="title">正确率</div>
<div><span class="num">111</span><span class="fen">%</span></div>
</el-col>
</el-row> </el-row>
</div> </div>
</el-card> </el-card>
...@@ -31,7 +21,7 @@ ...@@ -31,7 +21,7 @@
<script> <script>
export default { export default {
props: { props: {
dataInfo: { type: Object, default: () => ({}) } data: { type: Array, default: () => [] }
} }
} }
</script> </script>
......
<template>
<div class="question-list-item">
<div class="question-list-public__title" v-html="data.common_content" v-if="data.common_content"></div>
<div class="question-list-item-hd">
<div class="question-list-item-hd__title" v-html="data.title"></div>
</div>
<div class="question-list-item-bd">
<!-- 单选 -->
<template v-if="[1, 6].includes(questionType)">
<el-radio-group v-model="data.answer[0]" :disabled="disabled" @change="handleChange">
<div class="question-option-item" v-for="item in currentOptions" :key="item.id">
<el-radio :label="item.id">
<div class="question-option-item__text" v-html="item.option"></div>
</el-radio>
</div>
</el-radio-group>
</template>
<!-- 多选 -->
<template v-if="questionType === 2">
<el-checkbox-group v-model="data.answer" :disabled="disabled" @change="handleChange">
<div class="question-option-item" v-for="item in currentOptions" :key="item.id">
<el-checkbox :label="item.id">
<div class="question-option-item__text" v-html="item.option"></div>
</el-checkbox>
</div>
</el-checkbox-group>
</template>
</div>
<!-- 简答题 -->
<template v-if="questionType === 3">
<el-input
type="textarea"
v-model="data.answer"
placeholder="请输入答案内容"
:autosize="{ minRows: 4, maxRows: 6 }"
:disabled="disabled"
@blur="handleChange"
:maxlength="100"
:show-word-limit="true"
></el-input>
</template>
<!-- <div class="question-list-item-score">得分:{{ data.score }}</div> -->
<div class="question-list-item-ft" v-if="data.analysis">
<h3 class="question-list-item-ft__title">答案解析</h3>
<template v-if="questionType !== 3">
<div class="answer-item">
<div class="answer-item-label">正确答案:</div>
<div class="answer-item-content">{{ data.analysis }}</div>
</div>
</template>
<template v-else>
<div class="answer-item" v-if="data.comment">
<div class="answer-item-label">老师点评:</div>
<div class="answer-item-content">{{ data.comment }}</div>
</div>
</template>
</div>
<div class="answer-item" v-if="hasResult && data.question_analysis">
<div class="answer-item-label">解析:</div>
<div class="answer-item-content" v-html="data.question_analysis"></div>
</div>
</div>
</template>
<script>
export default {
props: {
data: { type: Object, default: () => ({}) }, // 小题
question: { type: Object, default: () => ({}) }, // 大题
disabled: { type: Boolean, default: true },
hasResult: { type: Boolean, default: false }
},
data() {
return {}
},
computed: {
questionType() {
// (1:单选题,2:多选题,3:问答题,5:案例题,6:判断题,7:实操题,8:情景题)
const questionType = parseInt(this.data.type)
return questionType
},
// 26个英文字母
A_Z() {
const result = []
for (let i = 0; i < 26; i++) {
result.push(String.fromCharCode(65 + i))
}
return result
},
// 处理后的options数据
currentOptions() {
if (!this.data.options) {
return []
}
return this.data.options.map((item, index) => {
// 英文字母 + 名称
item.abc = this.A_Z[index]
return item
})
}
},
methods: {
handleChange() {
this.$emit('change', this.data)
}
}
}
</script>
<style lang="scss" scoped>
.question-list-public__title{
font-size: 20px;
font-weight: bold;
color: #222;
line-height: 25px;
}
.question-list-item {
margin-bottom: 20px;
padding: 20px;
border-radius: 5px;
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
background: #fff;
margin-top: 20px;
}
.question-list-item-hd {
display: flex;
}
.question-list-item-hd__num {
font-size: 32px;
font-weight: bold;
color: #222;
line-height: 45px;
margin-top: 5px;
}
.question-list-item-hd__title {
margin-left: 5px;
padding-top: 10px;
font-size: 16px;
font-weight: bold;
color: #222;
line-height: 25px;
}
.question-list-item-hd__score{
margin-left: auto;
padding-top: 10px;
font-size: 16px;
// font-weight: bold;
color: #222;
line-height: 25px;
white-space:nowrap;
padding-left: 30px;
}
.question-option-item {
margin-top: 20px;
::v-deep .el-radio,
::v-deep .el-checkbox {
display: flex;
align-items: center;
}
}
.question-option-item__text {
display: inline-block;
font-size: 18px;
color: #222;
}
::v-deep .el-radio__inner,
::v-deep .el-checkbox__inner {
width: 18px;
height: 18px;
}
::v-deep .el-checkbox__inner::after {
width: 4px;
height: 9px;
left: 6px;
}
.question-list-item-ft {
margin-top: 20px;
}
.question-list-item-ft__title {
font-size: 18px;
font-weight: bold;
color: #222;
line-height: 25px;
}
.answer-item {
margin-top: 10px;
margin-left: 28px;
display: flex;
font-size: 18px;
color: #222;
line-height: 25px;
}
.answer-item-label {
white-space: nowrap;
}
.answer-item-content {
flex: 1;
overflow: hidden;
}
.question-list-item-score{
margin-left: auto;
padding-top: 10px;
font-size: 16px;
color: #222;
line-height: 25px;
white-space: nowrap;
}
</style>
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<script> <script>
import * as api from '../api.js' import * as api from '../api.js'
import ExamInfo from '@/components/data/ExamInfo.vue' import ExamInfo from '../components/detail/ExamInfo.vue'
import QuestionList from '@/components/data/QuestionList.vue' import QuestionList from '@/components/data/QuestionList.vue'
export default { export default {
components: { ExamInfo, QuestionList }, components: { ExamInfo, QuestionList },
......
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
<script> <script>
import { getExamDataInfo } from '../api' import { getExamDataInfo } from '../api'
import VueHtml2pdf from 'vue-html2pdf' import VueHtml2pdf from 'vue-html2pdf'
import ExamInfo from '../components/ExamInfo.vue' import ExamInfo from '../components/detail/ExamInfo.vue'
import Submission from '../components/Submission.vue' import Submission from '../components/Submission.vue'
import Score from '../components/Score.vue' import Score from '../components/Score.vue'
import ScoreRanking from '../components/ScoreRanking.vue' import ScoreRanking from '../components/ScoreRanking.vue'
......
<template> <template>
<div> <div v-if="Object.keys(examData).length">
<question-list class="exam" :examData="examData" v-if="examData.length"></question-list> <question-details class="exam" :data="examData"></question-details>
<div class="flex-box"> <div class="flex-box">
<topic-data-info class="flex"></topic-data-info> <topic-data-info :data="topicInfo" class="flex"></topic-data-info>
<topic-data-chart class="flex"></topic-data-chart> <topic-data-chart :data="examData" class="flex"></topic-data-chart>
</div> </div>
<el-card> <el-card>
<div slot="header" style="display: flex; align-items: center"> <div slot="header" style="display: flex; align-items: center">
...@@ -15,69 +15,78 @@ ...@@ -15,69 +15,78 @@
</template> </template>
<script> <script>
import * as api from '../api.js' import * as api from '../api.js'
import QuestionList from '@/components/data/QuestionList.vue' import QuestionDetails from '../components/detail/QuestionDetails.vue'
import TopicDataInfo from '../components/TopicDataInfo.vue' import TopicDataInfo from '../components/TopicDataInfo.vue'
import TopicDataChart from '../components/TopicDataChart.vue' import TopicDataChart from '../components/TopicDataChart.vue'
export default { export default {
components: { QuestionList, TopicDataInfo, TopicDataChart }, components: { QuestionDetails, TopicDataInfo, TopicDataChart },
data() { data() {
return { return {
examData: [] examData: {},
topicInfo: []
} }
}, },
computed: { computed: {
A_Z() {
const result = []
for (let i = 0; i < 26; i++) {
result.push(String.fromCharCode(65 + i))
}
return result
},
// 列表配置 // 列表配置
tableOptions() { tableOptions() {
return { return {
remote: { remote: {
httpRequest: api.getExamList, // httpRequest: api.getExamList,
params: { params: {
type: 'examination', type: 'examination',
course_id: '', course_id: '',
examination_id: '' examination_id: ''
} }
}, },
filters: [
// {
// type: 'select',
// prop: 'examination_id',
// placeholder: '考试名称',
// label: '考试名称',
// options: this.conditionList.examination_list,
// labelKey: 'paper_title',
// valueKey: 'id',
// filterable: true
// },
// {
// type: 'select',
// prop: 'course_id',
// placeholder: '所属课程',
// label: '所属课程',
// options: this.conditionList.course_list,
// labelKey: 'course_name',
// valueKey: 'id',
// filterable: true
// }
],
columns: [ columns: [
{ label: '学生ID', prop: 'examination_name', align: 'center' }, { label: '学生ID', prop: 'student_id', align: 'center' },
{ label: '学生姓名', prop: 'course_name', align: 'center' }, { label: '学生姓名', prop: 'personal_name', align: 'center' },
{ label: '所在班级', prop: 'join_num', align: 'center' }, { label: '所在班级', prop: 'class_name', align: 'center' },
{ label: '选择答案', prop: 'join_rate', align: 'center' }, { label: '选择答案', prop: 'answer', align: 'center' },
{ label: '本题得分', prop: 'average', align: 'center' } { label: '本题得分', prop: 'score', align: 'center' }
] ],
data: []
} }
} }
}, },
mounted() { mounted() {
// this.getTopic() this.getTopic()
}, },
methods: { methods: {
getTopic() { getTopic() {
api.getReviewDetails({ sheet_id: this.$route.query.id }).then(response => { const query = this.$route.query
this.data = JSON.parse(response.data).sheet const params = { type: 'examination', course_id: query.course_id, examination_id: query.examination_id, chapter_id: query.chapter_id, question_id: query.question_id }
this.setExamData() api.getQuestionsDetails(params).then(response => {
const data = response.data
data.options.map((item, index) => {
item.option = `${this.A_Z[index]}.${item.option}`
return item
})
this.examData = data
this.topicInfo = [
{ title: '本题分数', value: data.total_score },
{ title: '平均得分', value: data.average },
{ title: '正确率', value: data.rate }
]
this.tableOptions.data = data.user_list.reduce((a, b) => {
const answer = []
const opt = data.options
b.answer.forEach(item => {
const findOpt = opt.find(d => d.id === item)
findOpt && answer.push(findOpt.option)
})
b.answer = answer.join(',')
a.push(b)
return a
}, [])
}) })
}, },
setExamData() { setExamData() {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论