fix:作业统计相关问题以及优化;
This commit is contained in:
parent
13f7398d79
commit
c8aae6f408
|
@ -373,7 +373,7 @@ const eventHandles = (type, win) => {
|
||||||
export const toLinkWeb = (path) => {
|
export const toLinkWeb = (path) => {
|
||||||
const config = baseConfig()
|
const config = baseConfig()
|
||||||
// console.log(config)
|
// console.log(config)
|
||||||
const fullPath = config.url + path
|
const fullPath = 'https://localhost:7860/' + path
|
||||||
// 通知主进程
|
// 通知主进程
|
||||||
ipcRenderer.send('openWindow', {
|
ipcRenderer.send('openWindow', {
|
||||||
key: `win-${Date.now()}`,
|
key: `win-${Date.now()}`,
|
||||||
|
|
|
@ -75,12 +75,12 @@ let studentList = ref([]) // 学生数据
|
||||||
|
|
||||||
// 初始-数据处理
|
// 初始-数据处理
|
||||||
const initData = () => {
|
const initData = () => {
|
||||||
console.log('xxx', props)
|
|
||||||
// window.test = activeCourse
|
// window.test = activeCourse
|
||||||
studentList.value = props.activeData.studentList || []
|
studentList.value = props.activeData.studentList || []
|
||||||
const activeWorkFeedList = props.activeData.workFeedList || []
|
const activeWorkFeedList = props.activeData.workFeedList || []
|
||||||
const quizlist = props.activeData.quizlist || []
|
const quizlist = props.activeData.quizlist || []
|
||||||
const timeArr = groupByField(props.activeData.workFeedList,'entpcourseworkid')
|
console.log(quizlist,'quizlist');
|
||||||
|
|
||||||
// 习题特殊处理
|
// 习题特殊处理
|
||||||
let data = quizlist.map(o => {
|
let data = quizlist.map(o => {
|
||||||
// 解析题选项
|
// 解析题选项
|
||||||
|
@ -90,14 +90,9 @@ const initData = () => {
|
||||||
let rightIds = [] // 正确学生
|
let rightIds = [] // 正确学生
|
||||||
let hasAnswers= [] // 答过题的学生
|
let hasAnswers= [] // 答过题的学生
|
||||||
let timeAnalyse = [] // 平均时长和编号
|
let timeAnalyse = [] // 平均时长和编号
|
||||||
|
// let subjectCourese = [] // 题目编号
|
||||||
const quizFeedList = activeWorkFeedList.filter(f => f.entpcourseworkid == o.id) // 做该题的列表
|
const quizFeedList = activeWorkFeedList.filter(f => f.entpcourseworkid == o.id) // 做该题的列表
|
||||||
// 获取所有的做题时间
|
|
||||||
timeArr.forEach((item,index) => {
|
|
||||||
const arr = item.reduce((acc, cur) => {
|
|
||||||
return acc + (cur.timelength ? Number(cur.timelength) : 0);
|
|
||||||
},0)
|
|
||||||
timeAnalyse.push(arr)
|
|
||||||
})
|
|
||||||
let children = []
|
let children = []
|
||||||
const allStudents = [];
|
const allStudents = [];
|
||||||
if (o.worktype == '单选题') { // '单选题','多选题'
|
if (o.worktype == '单选题') { // '单选题','多选题'
|
||||||
|
@ -108,6 +103,11 @@ const initData = () => {
|
||||||
// 改选项的学生id
|
// 改选项的学生id
|
||||||
const studentIds = quizFeedList.filter(f => f.feedcontent==v&&f.finishtimelength!='0').map(f => f.studentid)||[];
|
const studentIds = quizFeedList.filter(f => f.feedcontent==v&&f.finishtimelength!='0').map(f => f.studentid)||[];
|
||||||
accSum += studentIds.length;
|
accSum += studentIds.length;
|
||||||
|
// 该到题的用时时间
|
||||||
|
timeAnalyse = quizFeedList.reduce((acc, cur) => {
|
||||||
|
return acc + (cur.timelength ? Number(cur.timelength) : 0);
|
||||||
|
},0)
|
||||||
|
|
||||||
if (isOk) {
|
if (isOk) {
|
||||||
activeIds.push(...studentIds)
|
activeIds.push(...studentIds)
|
||||||
}
|
}
|
||||||
|
@ -135,6 +135,10 @@ const initData = () => {
|
||||||
if (studentIds.length>0) {
|
if (studentIds.length>0) {
|
||||||
allStudents.push(...studentIds);
|
allStudents.push(...studentIds);
|
||||||
}
|
}
|
||||||
|
// 该到题的用时时间
|
||||||
|
timeAnalyse = quizFeedList.reduce((acc, cur) => {
|
||||||
|
return acc + (cur.timelength ? Number(cur.timelength) : 0);
|
||||||
|
},0)
|
||||||
if(isOk) {
|
if(isOk) {
|
||||||
activeIds=[...new Set(activeIds.concat(studentIds))] // 多选去重
|
activeIds=[...new Set(activeIds.concat(studentIds))] // 多选去重
|
||||||
}
|
}
|
||||||
|
@ -153,6 +157,10 @@ const initData = () => {
|
||||||
activeIds=[...new Set(activeIds.concat(studentIds))] // 多选去重
|
activeIds=[...new Set(activeIds.concat(studentIds))] // 多选去重
|
||||||
hasAnswers=[...new Set(hasAnswers.concat(studentIds))]
|
hasAnswers=[...new Set(hasAnswers.concat(studentIds))]
|
||||||
accSum = activeIds.length
|
accSum = activeIds.length
|
||||||
|
// 该到题的用时时间
|
||||||
|
timeAnalyse = quizFeedList.reduce((acc, cur) => {
|
||||||
|
return acc + (cur.timelength ? Number(cur.timelength) : 0);
|
||||||
|
},0)
|
||||||
return { def, code, txt, isOk:true, studentIds }
|
return { def, code, txt, isOk:true, studentIds }
|
||||||
})
|
})
|
||||||
} else if (o.worktype == '判断题') { // 判断题
|
} else if (o.worktype == '判断题') { // 判断题
|
||||||
|
@ -194,6 +202,10 @@ const initData = () => {
|
||||||
accSum += studentIds.length;
|
accSum += studentIds.length;
|
||||||
if(isOk) activeIds.push(...studentIds)
|
if(isOk) activeIds.push(...studentIds)
|
||||||
hasAnswers.push(...studentIds)
|
hasAnswers.push(...studentIds)
|
||||||
|
// 该到题的用时时间
|
||||||
|
timeAnalyse = quizFeedList.reduce((acc, cur) => {
|
||||||
|
return acc + (cur.timelength ? Number(cur.timelength) : 0);
|
||||||
|
},0)
|
||||||
return { def: v, code: v, isOk, studentIds }
|
return { def: v, code: v, isOk, studentIds }
|
||||||
})
|
})
|
||||||
} else { // 论述题
|
} else { // 论述题
|
||||||
|
@ -203,6 +215,10 @@ const initData = () => {
|
||||||
activeIds=[...new Set(activeIds.concat(studentIds))] // 多选去重
|
activeIds=[...new Set(activeIds.concat(studentIds))] // 多选去重
|
||||||
hasAnswers=[...new Set(hasAnswers.concat(studentIds))]
|
hasAnswers=[...new Set(hasAnswers.concat(studentIds))]
|
||||||
accSum = activeIds.length
|
accSum = activeIds.length
|
||||||
|
// 该到题的用时时间
|
||||||
|
timeAnalyse = quizFeedList.reduce((acc, cur) => {
|
||||||
|
return acc + (cur.timelength ? Number(cur.timelength) : 0);
|
||||||
|
},0)
|
||||||
children = [{ def, code, isOk:true, studentIds }]
|
children = [{ def, code, isOk:true, studentIds }]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +238,7 @@ const initData = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// def: 原始题数据 type 类型 active: 选中 points: 得分率, accSum 题解答人数
|
// def: 原始题数据 type 类型 active: 选中 points: 得分率, accSum 题解答人数
|
||||||
return { def: o, id: o.id, type: o.worktype, active: [], points, accSum, rightSum, children,hasAnswers,timeAnalyse }
|
return { def: o, id: o.id, type: o.worktype, active: [], points, accSum, rightSum, children,hasAnswers,timeAnalyse,score:o.score }
|
||||||
})
|
})
|
||||||
if (data.length === 0) return
|
if (data.length === 0) return
|
||||||
useOverview.getAllData([...data])
|
useOverview.getAllData([...data])
|
||||||
|
|
|
@ -24,6 +24,7 @@ const dataList = ref([
|
||||||
// 答过题的学生才进行统计
|
// 答过题的学生才进行统计
|
||||||
const hasStudents = ref([])
|
const hasStudents = ref([])
|
||||||
|
|
||||||
|
|
||||||
// 根据数据生成不同的颜色
|
// 根据数据生成不同的颜色
|
||||||
function getColor(name) {
|
function getColor(name) {
|
||||||
const colorMap = {
|
const colorMap = {
|
||||||
|
@ -104,7 +105,18 @@ const showEcharts = () => {
|
||||||
}
|
}
|
||||||
//执行
|
//执行
|
||||||
watch(() => useOverview.tableList, () => {
|
watch(() => useOverview.tableList, () => {
|
||||||
|
// 判断是不是客观题
|
||||||
|
const subType = useOverview.allData.map(item => item.type)
|
||||||
|
const objectiveQuestion = ['单选题','多选题','判断题']
|
||||||
|
if( !subType.every(item => objectiveQuestion.includes(item)) ){
|
||||||
|
hasStudents.value = useOverview.tableList.filter(item => {
|
||||||
|
if(item.rating > 0 && useOverview.allData[0].hasAnswers.includes(item.studentid)){
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
hasStudents.value = useOverview.tableList.filter(item => useOverview.allData[0].hasAnswers.includes(item.studentid)).map(item => item);
|
hasStudents.value = useOverview.tableList.filter(item => useOverview.allData[0].hasAnswers.includes(item.studentid)).map(item => item);
|
||||||
|
}
|
||||||
showEcharts();
|
showEcharts();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
initChart();
|
initChart();
|
||||||
|
|
|
@ -81,7 +81,18 @@ const showStudents = (index) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
watch(() => useOverview.tableList, () => {
|
watch(() => useOverview.tableList, () => {
|
||||||
|
// 判断是不是客观题
|
||||||
|
const subType = useOverview.allData.map(item => item.type)
|
||||||
|
const objectiveQuestion = ['单选题','多选题','判断题']
|
||||||
|
if( !subType.every(item => objectiveQuestion.includes(item)) ){
|
||||||
|
hasStudents.value = useOverview.tableList.filter(item => {
|
||||||
|
if(item.rating > 0 && useOverview.allData[0].hasAnswers.includes(item.studentid)){
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
hasStudents.value = useOverview.tableList.filter(item => useOverview.allData[0].hasAnswers.includes(item.studentid)).map(item => item);
|
hasStudents.value = useOverview.tableList.filter(item => useOverview.allData[0].hasAnswers.includes(item.studentid)).map(item => item);
|
||||||
|
}
|
||||||
showStudents(0)
|
showStudents(0)
|
||||||
},{deep: true})
|
},{deep: true})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -25,19 +25,23 @@ const useOverview = overviewStore()
|
||||||
const tableData = ref([])
|
const tableData = ref([])
|
||||||
//用来获取所有知识点
|
//用来获取所有知识点
|
||||||
const konwledge = ref([])
|
const konwledge = ref([])
|
||||||
|
const hasStudents = ref([])
|
||||||
|
// 获取的所有得分
|
||||||
|
const allScore = ref([])
|
||||||
//所有题目的知识点
|
//所有题目的知识点
|
||||||
const getKonwledge = () => {
|
const getKonwledge = () => {
|
||||||
const getScoreRate = []
|
const getScoreRate = []
|
||||||
// 获取知识点的种数
|
// 获取知识点的种数
|
||||||
const ledges = []
|
const ledges = []
|
||||||
useOverview.tableList.forEach(item => {
|
hasStudents.value.forEach((item,index) => {
|
||||||
//判断是否存在知识点
|
//判断是否存在知识点
|
||||||
if(item.knowledgePoint){
|
if(item.knowledgePoint){
|
||||||
const title = JSON.parse(item.knowledgePoint)
|
const title = JSON.parse(item.knowledgePoint)
|
||||||
//判断知识点是否重复
|
//判断知识点是否重复
|
||||||
if(!ledges.includes(title.id)){
|
if(!ledges.includes(title.id)){
|
||||||
ledges.push(title.id)
|
ledges.push(title.id)
|
||||||
konwledge.value.push({title:title.title,allPoint:item.point,id:title.id})
|
// 假如分数是0 或者 得分率为空
|
||||||
|
konwledge.value.push({title:title.title,allPoint:allScore.value,id:title.id})
|
||||||
}
|
}
|
||||||
// 判断学生是否答过题
|
// 判断学生是否答过题
|
||||||
if(useOverview.allData[0].hasAnswers.includes(item.studentid))
|
if(useOverview.allData[0].hasAnswers.includes(item.studentid))
|
||||||
|
@ -50,6 +54,7 @@ const getKonwledge = () => {
|
||||||
let sunRate = 0
|
let sunRate = 0
|
||||||
let num = 0
|
let num = 0
|
||||||
if(getScoreRate.length === 0) return
|
if(getScoreRate.length === 0) return
|
||||||
|
|
||||||
getScoreRate.forEach(item2 => {
|
getScoreRate.forEach(item2 => {
|
||||||
if(item.id === item2.id){
|
if(item.id === item2.id){
|
||||||
sunRate += extractedNumber(item2.rate)
|
sunRate += extractedNumber(item2.rate)
|
||||||
|
@ -72,6 +77,22 @@ const extractedNumber = (score) => {
|
||||||
//组装tableList表格
|
//组装tableList表格
|
||||||
|
|
||||||
watch(() => useOverview.tableList,() => {
|
watch(() => useOverview.tableList,() => {
|
||||||
|
// 判断是不是客观题
|
||||||
|
const subType = useOverview.allData.map(item => item.type)
|
||||||
|
const objectiveQuestion = ['单选题','多选题','判断题']
|
||||||
|
if( !subType.every(item => objectiveQuestion.includes(item)) ){
|
||||||
|
hasStudents.value = useOverview.tableList.filter(item => {
|
||||||
|
if(item.rating > 0 && useOverview.allData[0].hasAnswers.includes(item.studentid)){
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
hasStudents.value = useOverview.tableList.filter(item => useOverview.allData[0].hasAnswers.includes(item.studentid)).map(item => item);
|
||||||
|
}
|
||||||
|
// 这里获取所有知识点的总分
|
||||||
|
allScore.value = useOverview.allData.reduce((acc, cur) => {
|
||||||
|
return acc + Number(cur.score)
|
||||||
|
},0)
|
||||||
getKonwledge()
|
getKonwledge()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -9,14 +9,17 @@ import * as echarts from 'echarts';
|
||||||
import {ref, nextTick, watch} from 'vue'
|
import {ref, nextTick, watch} from 'vue'
|
||||||
import overviewStore from '@/store/modules/overview'
|
import overviewStore from '@/store/modules/overview'
|
||||||
|
|
||||||
const useOverview = overviewStore()
|
const useOverview = overviewStore();
|
||||||
|
|
||||||
// 获取图表容器的引用
|
// 获取图表容器的引用
|
||||||
const chartRef = ref(null);
|
const chartRef = ref(null);
|
||||||
|
// 预计用时
|
||||||
|
const expectedDuration = ref([]);
|
||||||
|
|
||||||
// 初始化图表
|
// 初始化图表
|
||||||
function initChart() {
|
function initChart() {
|
||||||
const myChart = echarts.init(chartRef.value);
|
const myChart = echarts.init(chartRef.value);
|
||||||
|
|
||||||
// 指定图表的配置项和数据
|
// 指定图表的配置项和数据
|
||||||
let option = {
|
let option = {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
@ -24,16 +27,17 @@ function initChart() {
|
||||||
axisPointer: {
|
axisPointer: {
|
||||||
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||||
},
|
},
|
||||||
formatter: function(parms) {
|
formatter: function (parms) {
|
||||||
let str =
|
let str = "";
|
||||||
parms[0].axisValue +
|
parms.forEach(param => {
|
||||||
"</br>" +
|
if (param.seriesType === 'bar') {
|
||||||
parms[0].marker +
|
str += param.axisValue + "</br>" + param.marker + "平均用时:" + param.value + 's' + "</br>";
|
||||||
"平均用时:" +
|
} else if (param.seriesType === 'line') {
|
||||||
parms[0].value + 's'
|
str += param.marker + "预计用时:" + param.value + 's';
|
||||||
|
}
|
||||||
|
});
|
||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: "#333",
|
color: "#333",
|
||||||
|
@ -63,7 +67,7 @@ function initChart() {
|
||||||
color: "#000",
|
color: "#000",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
name:'题目编号'
|
name: '题目编号'
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: "value",
|
type: "value",
|
||||||
|
@ -73,7 +77,7 @@ function initChart() {
|
||||||
color: "#B5B5B5",
|
color: "#B5B5B5",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
name:'平均时长',
|
name: '平均时长',
|
||||||
splitLine: {
|
splitLine: {
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
// 使用深浅的间隔色
|
// 使用深浅的间隔色
|
||||||
|
@ -84,7 +88,8 @@ function initChart() {
|
||||||
},
|
},
|
||||||
axisLabel: {},
|
axisLabel: {},
|
||||||
},
|
},
|
||||||
series: [{
|
series: [
|
||||||
|
{
|
||||||
data: getYValue(),
|
data: getYValue(),
|
||||||
stack: "zs",
|
stack: "zs",
|
||||||
type: "bar",
|
type: "bar",
|
||||||
|
@ -98,45 +103,61 @@ function initChart() {
|
||||||
y2: 1,
|
y2: 1,
|
||||||
type: "linear",
|
type: "linear",
|
||||||
global: false,
|
global: false,
|
||||||
colorStops: [{
|
colorStops: [
|
||||||
offset: 0,
|
{ offset: 0, color: "#5EA1FF" },
|
||||||
color: "#5EA1FF",
|
{ offset: 1, color: "#90BEFF" },
|
||||||
},
|
|
||||||
{
|
|
||||||
offset: 1,
|
|
||||||
color: "#90BEFF",
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'top',
|
||||||
|
formatter: '{c}s',
|
||||||
|
color: '#333',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
//折线的加入
|
||||||
|
{
|
||||||
|
data: expectedDuration.value,
|
||||||
|
type: "line",
|
||||||
|
smooth: true,
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: 8,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#FF7F50',
|
||||||
|
width: 2,
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: '#FF7F50',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
myChart.setOption(option);
|
myChart.setOption(option);
|
||||||
}
|
}
|
||||||
//获取平均时长纵坐标
|
|
||||||
|
// 获取平均时长纵坐标
|
||||||
const getYValue = () => {
|
const getYValue = () => {
|
||||||
const arr = [...useOverview.allData[0].timeAnalyse]
|
const arr = useOverview.allData.map(item => item.timeAnalyse)
|
||||||
const num = useOverview.allData[0].hasAnswers.length
|
const num = useOverview.allData[0].hasAnswers.length;
|
||||||
|
if (arr.length === 0) return [];
|
||||||
|
return arr.map(item => (item ? (item / num).toFixed(2) : 0));
|
||||||
|
};
|
||||||
|
|
||||||
return arr.map(item => {
|
// 获取横纵轴坐标数据
|
||||||
return item ? (item / num).toFixed(2) : 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 获取横纵轴坐标数据
|
|
||||||
const getXValue = () => {
|
const getXValue = () => {
|
||||||
return useOverview.allData.map(item => item.id)
|
return useOverview.allData.map((item, index) => `第${index + 1}题`);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
watch(() => useOverview.tableList, () => {
|
||||||
|
expectedDuration.value = useOverview.tableList.map(item => (Number(item.timelength) * 60 / useOverview.allData.length).toFixed(2));
|
||||||
|
|
||||||
|
// 获取横纵坐标
|
||||||
watch(() => useOverview.tableList,() => {
|
|
||||||
//获取横纵坐标
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
initChart();
|
initChart();
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
@ -408,7 +408,7 @@ const teacherCriticism = ()=>{
|
||||||
tableRadio.list = tableRadio.list.map((item) => {
|
tableRadio.list = tableRadio.list.map((item) => {
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
teacherRating : checkWorkType(item)
|
teacherRating : item.teacherRating || checkWorkType(item)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue