|
@@ -1,5 +1,5 @@
|
|
|
<template>
|
|
|
- <div class="pb_content" style="background: unset">
|
|
|
+ <div class="pb_content" style="background: unset" v-loading="ExcelLoading">
|
|
|
<div
|
|
|
class="pb_content_body"
|
|
|
style="
|
|
@@ -72,6 +72,11 @@
|
|
|
>查询</el-button
|
|
|
>
|
|
|
</div>
|
|
|
+ <div>
|
|
|
+ <el-button type="primary" class="student_button" @click="downloadData"
|
|
|
+ >下载数据</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="pb_content_body">
|
|
@@ -94,6 +99,12 @@
|
|
|
</el-table-column>
|
|
|
<el-table-column prop="rcount" label="观察记录总数" align="center">
|
|
|
</el-table-column>
|
|
|
+ <el-table-column prop="oneScore" label="学期前" align="center">
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="twoScore" label="学期中" align="center">
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="threeScore" label="学期末" align="center">
|
|
|
+ </el-table-column>
|
|
|
<el-table-column prop="sum" label="综合评分" align="center">
|
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" width="400px">
|
|
@@ -147,6 +158,7 @@ export default {
|
|
|
return {
|
|
|
tableHeight: "500px",
|
|
|
isLoading: false,
|
|
|
+ ExcelLoading: false,
|
|
|
formLabelWidth: "100px",
|
|
|
userid: this.$route.query.userid,
|
|
|
org: this.$route.query.org,
|
|
@@ -159,7 +171,7 @@ export default {
|
|
|
classJuri: [],
|
|
|
yearJuri: [],
|
|
|
page: 1,
|
|
|
- total: 0,
|
|
|
+ total: 0
|
|
|
};
|
|
|
},
|
|
|
methods: {
|
|
@@ -177,15 +189,16 @@ export default {
|
|
|
getClass() {
|
|
|
this.isLoading = true;
|
|
|
let params = {
|
|
|
- oid: this.oid,
|
|
|
+ oid: this.oid
|
|
|
};
|
|
|
this.ajax
|
|
|
.get(this.$store.state.api + "selectClassBySchool", params)
|
|
|
- .then((res) => {
|
|
|
+ .then(res => {
|
|
|
this.isLoading = false;
|
|
|
this.classJuri = res.data[0];
|
|
|
+ // console.log( this.classJuri);
|
|
|
})
|
|
|
- .catch((err) => {
|
|
|
+ .catch(err => {
|
|
|
this.isLoading = false;
|
|
|
console.error(err);
|
|
|
});
|
|
@@ -194,7 +207,7 @@ export default {
|
|
|
this.isLoading = true;
|
|
|
this.ajax
|
|
|
.get(this.$store.state.api + "selectTerm")
|
|
|
- .then((res) => {
|
|
|
+ .then(res => {
|
|
|
this.isLoading = false;
|
|
|
var yearJuri = res.data[0];
|
|
|
for (var i = 0; i < yearJuri.length; i++) {
|
|
@@ -203,9 +216,10 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
this.yearJuri = yearJuri;
|
|
|
+ // console.log(this.yearJuri);
|
|
|
this.searchStudent();
|
|
|
})
|
|
|
- .catch((err) => {
|
|
|
+ .catch(err => {
|
|
|
this.isLoading = false;
|
|
|
console.error(err);
|
|
|
});
|
|
@@ -214,6 +228,131 @@ export default {
|
|
|
this.page = val;
|
|
|
this.searchStudent();
|
|
|
},
|
|
|
+ // 导出数据提示
|
|
|
+ downloadData() {
|
|
|
+ // console.log('导出数据');
|
|
|
+ this.$confirm("是否导出Excel?", "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ cancelButtonText: "取消"
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ this.ExcelLoading = true;
|
|
|
+ let params = {
|
|
|
+ id: this.year
|
|
|
+ };
|
|
|
+ this.ajax
|
|
|
+ .get(this.$store.state.api + "selectClassAllRecord", params)
|
|
|
+ .then(res => {
|
|
|
+ this.exportExcel(res.data[0]);
|
|
|
+ });
|
|
|
+ })
|
|
|
+ .catch(() => {});
|
|
|
+ },
|
|
|
+ // 导出数据
|
|
|
+ exportExcel(val) {
|
|
|
+ let resList = val;
|
|
|
+
|
|
|
+ let termName = "";
|
|
|
+ let className = "";
|
|
|
+
|
|
|
+ this.yearJuri.forEach(i => {
|
|
|
+ if (i.id == this.year) {
|
|
|
+ termName = i.name;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ this.classJuri.forEach(i => {
|
|
|
+ if (i.id == this.cid) {
|
|
|
+ className = i.name;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // console.log('导出数据',res);
|
|
|
+ //如果value的json字段的key值和想要的headers值不一致时,可做如下更改
|
|
|
+ //将和下面的Object.fromEntries结合,将json字段的key值改变为要求的excel的header值
|
|
|
+ var array = [];
|
|
|
+ for (var i = 0; i < resList.length; i++) {
|
|
|
+ var _json = {};
|
|
|
+ _json["姓名"] = resList[i].name;
|
|
|
+ _json["班级"] = resList[i].cname;
|
|
|
+ _json["记录时间"] = resList[i].recordDate;
|
|
|
+ _json["学期"] = resList[i].tName;
|
|
|
+ _json["关联"] = resList[i].constus;
|
|
|
+ _json["维度"] = resList[i].VeidooList;
|
|
|
+ _json["观察地点"] = resList[i].place;
|
|
|
+ _json["观察内容"] = resList[i].recordTit;
|
|
|
+ _json["内容"] = resList[i].recordContent;
|
|
|
+ // _json["创建时间"] = res[i].create_at;
|
|
|
+
|
|
|
+ array.push(_json);
|
|
|
+ }
|
|
|
+
|
|
|
+ var XLSX = require("xlsx");
|
|
|
+ const workbook = XLSX.utils.book_new(); //创建一个新的工作簿对象
|
|
|
+ let ws = XLSX.utils.json_to_sheet(array); //将json对象数组转化成工作表
|
|
|
+ ws["!cols"] = [
|
|
|
+ //设置每一列的宽度
|
|
|
+ { wch: 20 },
|
|
|
+ { wch: 30 },
|
|
|
+ { wch: 30 },
|
|
|
+ { wch: 30 },
|
|
|
+ { wch: 30 },
|
|
|
+ { wch: 30 },
|
|
|
+ { wch: 30 },
|
|
|
+ { wch: 30 },
|
|
|
+ { wch: 30 }
|
|
|
+ ];
|
|
|
+ XLSX.utils.book_append_sheet(workbook, ws, "sheet1"); //把sheet添加到workbook里,第三个参数是sheet名
|
|
|
+ XLSX.writeFile(workbook, className + termName + "观察记录.xlsx");
|
|
|
+ // const wopts = { bookType: "xlsx", bookSST: false, type: "array" };//写入的样式bookType:输出的文件类型,type:输出的数据类型,bookSST: 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
|
|
|
+ // const wbout = XLSX.write(workbook, wopts);// 浏览器端和node共有的API,实际上node可以直接使用xlsx.writeFile来写入文件,但是浏览器没有该API
|
|
|
+ // FileSaver.saveAs(new Blob([wbout], { type: "application/octet-stream" }), `${title} demo.xlsx`);//保存文件
|
|
|
+ this.ExcelLoading = false;
|
|
|
+
|
|
|
+ this.$message({
|
|
|
+ message: "下载成功",
|
|
|
+ type: "success"
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 数据相同下标相加组成一个新数组
|
|
|
+ combineArrays(arrays) {
|
|
|
+ const result = [];
|
|
|
+
|
|
|
+ // 获取数组中的最大长度
|
|
|
+ const maxLength = Math.max(...arrays.map(arr => arr.length));
|
|
|
+
|
|
|
+ // 遍历每个下标
|
|
|
+ for (let i = 0; i < maxLength; i++) {
|
|
|
+ const combinedItem = [];
|
|
|
+
|
|
|
+ // 遍历每个数组
|
|
|
+ for (let j = 0; j < arrays.length; j++) {
|
|
|
+ const array = arrays[j];
|
|
|
+
|
|
|
+ // 检查当前下标是否存在于数组中
|
|
|
+ if (i < array.length) {
|
|
|
+ const item = array[i];
|
|
|
+
|
|
|
+ // 将当前下标的字段添加到组合数组中
|
|
|
+ combinedItem.push(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将组合数组添加到结果数组中
|
|
|
+ result.push(combinedItem);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ },
|
|
|
+ // 数组相加
|
|
|
+ addArrays(array1, array2) {
|
|
|
+ const result = [];
|
|
|
+
|
|
|
+ for (let i = 0; i < array2.length; i++) {
|
|
|
+ const sum = (array1[i] || 0) + array2[i];
|
|
|
+ result.push(sum);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ },
|
|
|
searchStudent() {
|
|
|
this.isLoading = true;
|
|
|
let params = {
|
|
@@ -222,14 +361,15 @@ export default {
|
|
|
cn: this.year,
|
|
|
oid: this.oid,
|
|
|
org: this.org,
|
|
|
- page: this.page,
|
|
|
+ page: this.page
|
|
|
};
|
|
|
this.ajax
|
|
|
.get(this.$store.state.api + "selectStudentAndRecord", params)
|
|
|
- .then((res) => {
|
|
|
+ .then(res => {
|
|
|
this.isLoading = false;
|
|
|
this.total = res.data[0].length > 0 ? res.data[0][0].num : 0;
|
|
|
var tableData = res.data[0];
|
|
|
+ // console.log('tableData',tableData);
|
|
|
var ftype = res.data[1]; //公共父级分类
|
|
|
var stype = res.data[2]; //公共子级分类
|
|
|
var sctype = res.data[3]; //该学校子级分类
|
|
@@ -267,36 +407,86 @@ export default {
|
|
|
if (json) {
|
|
|
var count = 0;
|
|
|
var sum = 0;
|
|
|
+ // console.log("json", json);
|
|
|
+
|
|
|
+
|
|
|
+ allfType.forEach(e => {
|
|
|
+ // console.log(e);
|
|
|
+ let fid = e.id;
|
|
|
+ e.child = json[fid];
|
|
|
+ });
|
|
|
+ // 将每个大分类下的小分类数据提取出来,在大分类下创建一个child2来存储
|
|
|
+ allfType.forEach((e, k) => {
|
|
|
+ e.child2 = [];
|
|
|
+ e.child.forEach((i, index) => {
|
|
|
+ e.child2.push(i[i.id]);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // 不按分类储存所有分数在allScore里
|
|
|
+ let allScore = [];
|
|
|
+ // 最后平均分
|
|
|
+ let croMapData = [];
|
|
|
+
|
|
|
+ // 将所有分数添加到allScore里
|
|
|
+ allfType.forEach((e, k) => {
|
|
|
+ allScore = [...allScore, ...e.child2];
|
|
|
+ });
|
|
|
+ // 计算每个小分类的平均分,并添加到croMapData里
|
|
|
+ allScore.forEach(e => {
|
|
|
+ // console.log(e);
|
|
|
+ croMapData = this.addArrays(croMapData, e);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 最后除以小分类长度得出分数
|
|
|
+ croMapData = croMapData.map(function(item) {
|
|
|
+ return (item / allScore.length).toFixed(1);
|
|
|
+ });
|
|
|
+ tableData[i].oneScore = croMapData[0];
|
|
|
+ tableData[i].twoScore = croMapData[1];
|
|
|
+ tableData[i].threeScore = croMapData[2];
|
|
|
+
|
|
|
+ // let aaa = this.combineArrays(allScore);
|
|
|
+
|
|
|
+ console.log("tableData", tableData[i]);
|
|
|
+
|
|
|
+ // console.log("allfType", allfType);
|
|
|
+
|
|
|
for (var k = 0; k < allfType.length; k++) {
|
|
|
for (var j = 0; j < json[allfType[k].id].length; j++) {
|
|
|
for (
|
|
|
var q = 0;
|
|
|
- q < json[allfType[k].id][j][json[allfType[k].id][j].id].length;
|
|
|
+ q <
|
|
|
+ json[allfType[k].id][j][json[allfType[k].id][j].id].length;
|
|
|
q++
|
|
|
) {
|
|
|
- count += json[allfType[k].id][j][json[allfType[k].id][j].id][q];
|
|
|
+ count +=
|
|
|
+ json[allfType[k].id][j][json[allfType[k].id][j].id][q];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
sum = parseFloat((count / (allsType.length * 3)).toFixed(1));
|
|
|
tableData[i].sum = sum;
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
tableData[i].sum = 0;
|
|
|
+ tableData[i].oneScore = 0;
|
|
|
+ tableData[i].twoScore = 0;
|
|
|
+ tableData[i].threeScore = 0;
|
|
|
}
|
|
|
}
|
|
|
this.tableData = tableData;
|
|
|
})
|
|
|
- .catch((err) => {
|
|
|
+ .catch(err => {
|
|
|
this.isLoading = false;
|
|
|
console.error(err);
|
|
|
});
|
|
|
- },
|
|
|
+ }
|
|
|
},
|
|
|
created() {
|
|
|
this.page = 1;
|
|
|
this.getClass();
|
|
|
this.getYear();
|
|
|
- },
|
|
|
+ }
|
|
|
};
|
|
|
</script>
|
|
|
|
|
@@ -304,6 +494,7 @@ export default {
|
|
|
.pb_head {
|
|
|
margin: 0 !important;
|
|
|
width: 100% !important;
|
|
|
+ padding: 10px 0 !important;
|
|
|
}
|
|
|
|
|
|
.top {
|
|
@@ -376,4 +567,4 @@ export default {
|
|
|
.student_table >>> .el-table__body-wrapper {
|
|
|
height: auto !important;
|
|
|
}
|
|
|
-</style>
|
|
|
+</style>
|