Compare commits

...

8 Commits

8 changed files with 226 additions and 131 deletions

View File

@ -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()}`,

View File

@ -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)
} }
@ -122,7 +122,7 @@ const initData = () => {
const res = isSame((f.feedcontent||'').split(','), workanswer); const res = isSame((f.feedcontent||'').split(','), workanswer);
return f.entpcourseworkid == o.id && f.finishtimelength!='0' && res; return f.entpcourseworkid == o.id && f.finishtimelength!='0' && res;
}); });
const list = workdesc.includes('#&') ? workdesc.split('#&') : isJson(workdesc)?JSON.parse(workdesc):[]; const list = workdesc.includes('#&') ? workdesc.split('#&') : isJson(workdesc)?JSON.parse(workdesc):[];
children = list.map((v,i) => { children = list.map((v,i) => {
const isOne = o.worktype == '单选题' const isOne = o.worktype == '单选题'
@ -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])

View File

@ -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, () => {
hasStudents.value = useOverview.tableList.filter(item => useOverview.allData[0].hasAnswers.includes(item.studentid)).map(item => item); //
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);
}
showEcharts(); showEcharts();
nextTick(() => { nextTick(() => {
initChart(); initChart();

View File

@ -81,7 +81,18 @@ const showStudents = (index) => {
}) })
} }
watch(() => useOverview.tableList, () => { watch(() => useOverview.tableList, () => {
hasStudents.value = useOverview.tableList.filter(item => useOverview.allData[0].hasAnswers.includes(item.studentid)).map(item => item); //
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);
}
showStudents(0) showStudents(0)
},{deep: true}) },{deep: true})
</script> </script>

View File

@ -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)
@ -71,7 +76,23 @@ 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>

View File

@ -9,134 +9,155 @@ 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 = { //
tooltip: { let option = {
trigger: "axis", tooltip: {
axisPointer: { trigger: "axis",
type: "shadow", // 线'line' | 'shadow' axisPointer: {
}, type: "shadow", // 线'line' | 'shadow'
formatter: function(parms) { },
let str = formatter: function (parms) {
parms[0].axisValue + let str = "";
"</br>" + parms.forEach(param => {
parms[0].marker + if (param.seriesType === 'bar') {
"平均用时:" + str += param.axisValue + "</br>" + param.marker + "平均用时:" + param.value + 's' + "</br>";
parms[0].value + 's' } else if (param.seriesType === 'line') {
return str; str += param.marker + "预计用时:" + param.value + 's';
}, }
});
}, return str;
textStyle: { },
},
textStyle: {
color: "#333",
},
color: ["#7BA9FA", "#4690FA"],
grid: {
containLabel: true,
left: "10%",
top: "20%",
bottom: "10%",
right: "10%",
},
xAxis: {
type: "category",
data: getXValue(),
axisLine: {
lineStyle: {
color: "#333", color: "#333",
}, },
color: ["#7BA9FA", "#4690FA"], },
grid: { axisTick: {
containLabel: true, show: false,
left: "10%", },
top: "20%", axisLabel: {
bottom: "10%", margin: 20, //线
right: "10%", textStyle: {
color: "#000",
}, },
xAxis: { },
type: "category", name: '题目编号'
data: getXValue(), },
axisLine: { yAxis: {
lineStyle: { type: "value",
color: "#333", axisLine: {
}, show: true,
}, lineStyle: {
axisTick: { color: "#B5B5B5",
show: false,
},
axisLabel: {
margin: 20, //线
textStyle: {
color: "#000",
},
},
name:'题目编号'
}, },
yAxis: { },
type: "value", name: '平均时长',
axisLine: { splitLine: {
show: true, lineStyle: {
lineStyle: { // 使
color: "#B5B5B5", color: ["#B5B5B5"],
}, type: "dashed",
}, opacity: 0.5,
name:'平均时长',
splitLine: {
lineStyle: {
// 使
color: ["#B5B5B5"],
type: "dashed",
opacity: 0.5,
},
},
axisLabel: {},
}, },
series: [{ },
data: getYValue(), axisLabel: {},
stack: "zs", },
type: "bar", series: [
barMaxWidth: "auto", {
barWidth: 60, data: getYValue(),
itemStyle: { stack: "zs",
color: { type: "bar",
x: 0, barMaxWidth: "auto",
y: 0, barWidth: 60,
x2: 0, itemStyle: {
y2: 1, color: {
type: "linear", x: 0,
global: false, y: 0,
colorStops: [{ x2: 0,
offset: 0, y2: 1,
color: "#5EA1FF", type: "linear",
}, global: false,
{ colorStops: [
offset: 1, { offset: 0, color: "#5EA1FF" },
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 => { return arr.map(item => (item ? (item / num).toFixed(2) : 0));
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>

View File

@ -90,7 +90,7 @@
<span>学生答案 <span>学生答案
<span <span
v-if="stuItem.feedcontent !=''" v-if="stuItem.feedcontent !=''"
style="background-color: red; color: white; padding: 0 5px; border-radius: 5px;" :style="{backgroundColor: `${formatWorkAnswer(quItem) == formatFeedContent(stuItem, quItem)? '#0ed116' : 'red'}`,color: 'white', padding: '0 5px', borderRadius: '5px'}"
v-html="formatFeedContent(stuItem, quItem)" v-html="formatFeedContent(stuItem, quItem)"
> >
</span> </span>

View File

@ -390,17 +390,29 @@ const getClassWorkStudentList = (rowId) => {
tableRadio.value = '1' tableRadio.value = '1'
tableRadio.num0 = classWorkAnalysis.classworkdata.length - tableRadio.list.length tableRadio.num0 = classWorkAnalysis.classworkdata.length - tableRadio.list.length
tableRadio.num1 = tableRadio.list.length tableRadio.num1 = tableRadio.list.length
tableRadio.list = tableRadio.list.map((item) => { //
return { teacherCriticism();
...item,
teacherRating : checkWorkType(item)
}
})
}) })
.catch(() => { .catch(() => {
loading_dt_table.value = false loading_dt_table.value = false
}) })
} }
/**
* 自动批阅判断
* 已交 作业类型为习题训练
*/
const teacherCriticism = ()=>{
// list
if(tableRadio.value == '1'&& classWorkAnalysis.worktype == '习题训练'){
//
tableRadio.list = tableRadio.list.map((item) => {
return {
...item,
teacherRating : item.teacherRating || checkWorkType(item)
}
})
}
}
const checkWorkType = (item) => { const checkWorkType = (item) => {
// //
const subType = classWorkActiveData.quizlist.map(item => item.worktype) const subType = classWorkActiveData.quizlist.map(item => item.worktype)
@ -408,7 +420,7 @@ const checkWorkType = (item) => {
let rating = 0 let rating = 0
// //
if(subType.every(item => objectiveQuestion.includes(item))){ if(subType.every(item => objectiveQuestion.includes(item))){
// // scoingRate
const score = extractedNumber(item.scoingRate) const score = extractedNumber(item.scoingRate)
if(0<=score && score<=59){ if(0<=score && score<=59){
rating = 5 rating = 5
@ -551,6 +563,8 @@ const tableRadioChange = (e) => {
tableRadio.value = '1'; tableRadio.value = '1';
tableRadio.num0 = classWorkAnalysis.classworkdata.length - tableRadio.list.length; tableRadio.num0 = classWorkAnalysis.classworkdata.length - tableRadio.list.length;
tableRadio.num1 = tableRadio.list.length; tableRadio.num1 = tableRadio.list.length;
//
teacherCriticism();
}else if(e=='0'){ }else if(e=='0'){
tableRadio.list = classWorkAnalysis.classworkdata.filter(item => item.finishtimelength == '0') tableRadio.list = classWorkAnalysis.classworkdata.filter(item => item.finishtimelength == '0')
tableRadio.value = '0'; tableRadio.value = '0';