|
|
@@ -312,6 +312,25 @@
|
|
|
</el-table>
|
|
|
</template>
|
|
|
</ReportModule>
|
|
|
+ <StudentList
|
|
|
+ :showDialog.sync="state.dialogData.showDialog"
|
|
|
+ :title="state.dialogData.title"
|
|
|
+ :tableTitle="state.dialogData.tableTitle"
|
|
|
+ :isStudentRegistrationCode="false"
|
|
|
+ apiName="contrastStudentInfo"
|
|
|
+ :studentParam="{
|
|
|
+ fiveRateName: state.dialogData.fiveRateName, //当前选择的五率的名称
|
|
|
+ selectSubjectName: state.dialogData.selectSubjectName, //当前选择的科目名称
|
|
|
+ selectSchoolLevel: state.dialogData.selectSchoolLevel, //当前选择的学校级别:0-联考 1-学校分组 2-具体学校
|
|
|
+ selectSchoolName: state.dialogData.selectSchoolName, //当前选择的学校名称:联校 组合学校 单校名称
|
|
|
+ selectClassLevel: state.dialogData.selectClassLevel, //当前选择的班级级别:0-年级 1-组合班级 2-具体班级
|
|
|
+ selectClassName: state.dialogData.selectClassName, //当前选择的班级名称:年级 组合班级 单班
|
|
|
+ titleType: 0,
|
|
|
+ paperTypeName: '',
|
|
|
+ }"
|
|
|
+ @CloseDialog="CloseDialog"
|
|
|
+ >
|
|
|
+ </StudentList>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
@@ -326,6 +345,7 @@ import BarScoringRateHorzontal from "@/components/echarts/barScoringRate_horzont
|
|
|
import BarStackChartVertical from "@/components/echarts/barStackChart_vertical.vue"; //竖向堆叠条形图
|
|
|
import BarStackChartHorizontal from "@/components/echarts/barStackChart_horzontal.vue"; //横向堆叠条形图
|
|
|
import DifferenceChart from "@/components/echarts/differenceChart.vue"; //率差图
|
|
|
+import StudentList from "@/components/studentList.vue"; //学生列表弹窗组件
|
|
|
import { onMounted, reactive, computed, watch, ref } from "vue";
|
|
|
import { useAnalysisStore } from "@/store/analysis";
|
|
|
import { classContrastSubjectTable, publicExportFive } from "@/api/analysis";
|
|
|
@@ -452,6 +472,7 @@ interface PageState {
|
|
|
|
|
|
const reportModuleRef = ref<InstanceType<typeof ReportModule> | null>(null);
|
|
|
const analysisStore = useAnalysisStore();
|
|
|
+const filterObject = computed(() => analysisStore.filterObject || {});
|
|
|
const schoolLevel = computed(() => analysisStore.filterObject.schoolLevel);
|
|
|
|
|
|
/** 考试名称计算属性 */
|
|
|
@@ -526,6 +547,18 @@ const state = reactive<PageState>({
|
|
|
{ value: "2", label: "升序" },
|
|
|
{ value: "3", label: "降序" },
|
|
|
],
|
|
|
+ dialogData: {
|
|
|
+ showDialog: false,
|
|
|
+ studentRegistrationCode: [],
|
|
|
+ title: "",
|
|
|
+ tableTitle: "",
|
|
|
+ fiveRateName: "", //当前选择的五率的名称
|
|
|
+ selectSubjectName: "", //当前选择的科目名称
|
|
|
+ selectSchoolLevel: "", //当前选择的学校级别:0-联考 1-学校分组 2-具体学校
|
|
|
+ selectSchoolName: "", //当前选择的学校名称:联校 组合学校 单校名称
|
|
|
+ selectClassLevel: "", //当前选择的班级级别:0-年级 1-组合班级 2-具体班级
|
|
|
+ selectClassName: "", //当前选择的班级名称:年级 组合班级 单班
|
|
|
+ }, // 弹框的数据
|
|
|
});
|
|
|
|
|
|
// ================= 计算属性 =================
|
|
|
@@ -557,23 +590,17 @@ const TabChange = (item: TabItem) => {
|
|
|
/** 切换图表类型 */
|
|
|
const ChangeEchartType = (
|
|
|
val: string | number,
|
|
|
- prop: "fiveRateData" | "analysisData"
|
|
|
+ prop: "fiveRateData" | "analysisData",
|
|
|
) => {
|
|
|
state[prop].chartType = String(val);
|
|
|
};
|
|
|
|
|
|
-/** 打开学生详情弹窗(需根据实际业务补充实现) */
|
|
|
-const OpenStudentDialog = (row: any, header: HeaderItem, child: HeaderItem) => {
|
|
|
- // TODO: 实现打开学生详情弹窗的逻辑
|
|
|
- console.log("打开学生详情弹窗", row, header, child);
|
|
|
-};
|
|
|
-
|
|
|
// ================= 数据获取与处理 =================
|
|
|
|
|
|
/** 获取班级分析数据 */
|
|
|
const GetSingleClassAnalysisData = () => {
|
|
|
const params = {
|
|
|
- ...analysisStore.filterObject,
|
|
|
+ ...filterObject.value,
|
|
|
titleType: 0,
|
|
|
};
|
|
|
state.analysisLoading = true;
|
|
|
@@ -609,7 +636,7 @@ const GetSingleClassAnalysisData = () => {
|
|
|
chartData.push({
|
|
|
...item,
|
|
|
isLine: true,
|
|
|
- isShow: analysisStore.filterObject.classLevel != 1,
|
|
|
+ isShow: filterObject.value.classLevel != 1,
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
@@ -617,19 +644,21 @@ const GetSingleClassAnalysisData = () => {
|
|
|
res.data.classGroupDataList?.forEach((item: ChartDataItem) => {
|
|
|
chartData.push({
|
|
|
...item,
|
|
|
- isLine: analysisStore.filterObject.classLevel == 1,
|
|
|
- isShow: analysisStore.filterObject.classLevel == 1,
|
|
|
+ isLine: filterObject.value.classLevel == 1,
|
|
|
+ isShow: filterObject.value.classLevel == 1,
|
|
|
});
|
|
|
});
|
|
|
// 单班
|
|
|
- res.data.classDataList?.forEach((item: ChartDataItem, index: number) => {
|
|
|
- chartData.push(item);
|
|
|
- item.subjectList?.forEach((i: any, key: number) => {
|
|
|
- if (key == 0) i.index = index + 1;
|
|
|
- tableData.push(i);
|
|
|
- tableDatas.push(i);
|
|
|
- });
|
|
|
- });
|
|
|
+ res.data.classDataList?.forEach(
|
|
|
+ (item: ChartDataItem, index: number) => {
|
|
|
+ chartData.push(item);
|
|
|
+ item.subjectList?.forEach((i: any, key: number) => {
|
|
|
+ if (key == 0) i.index = index + 1;
|
|
|
+ tableData.push(i);
|
|
|
+ tableDatas.push(i);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ );
|
|
|
// 组合班级
|
|
|
res.data.classGroupDataList?.forEach((item: ChartDataItem) => {
|
|
|
item.subjectList?.forEach((i: any, key: number) => {
|
|
|
@@ -718,11 +747,11 @@ const GetSingleClassAnalysisData = () => {
|
|
|
child: childHeaderList,
|
|
|
},
|
|
|
staticHeader: (res.data.headerList || []).filter(
|
|
|
- (header: HeaderItem) => header.display === true
|
|
|
+ (header: HeaderItem) => header.display === true,
|
|
|
),
|
|
|
dynamicsHeader: dynamicsHeader,
|
|
|
childHeader: (res.data.childHeaderList || []).filter(
|
|
|
- (child: HeaderItem) => child.display === true
|
|
|
+ (child: HeaderItem) => child.display === true,
|
|
|
),
|
|
|
pageSize: 10,
|
|
|
total: tableDatas.length,
|
|
|
@@ -743,7 +772,11 @@ const ChangeChartBarData = () => {
|
|
|
let datay: (string | number)[] = [];
|
|
|
let dataLoseRate: (string | number)[] = [];
|
|
|
let average: number | string = 0;
|
|
|
- let markLineData: Array<{ legendName: string; value: any; isShow?: boolean }> = [];
|
|
|
+ let markLineData: Array<{
|
|
|
+ legendName: string;
|
|
|
+ value: any;
|
|
|
+ isShow?: boolean;
|
|
|
+ }> = [];
|
|
|
let color = "#5470C6";
|
|
|
let maxClassName = "";
|
|
|
let minClassName = "";
|
|
|
@@ -764,10 +797,18 @@ const ChangeChartBarData = () => {
|
|
|
});
|
|
|
}
|
|
|
item.mergeSubjects?.forEach((i) => {
|
|
|
- chartData.push({ ...i, isLine: item.isLine, isShow: item.isShow ? true : false });
|
|
|
+ chartData.push({
|
|
|
+ ...i,
|
|
|
+ isLine: item.isLine,
|
|
|
+ isShow: item.isShow ? true : false,
|
|
|
+ });
|
|
|
});
|
|
|
item.subjectList?.forEach((i) => {
|
|
|
- chartData.push({ ...i, isLine: item.isLine, isShow: item.isShow ? true : false });
|
|
|
+ chartData.push({
|
|
|
+ ...i,
|
|
|
+ isLine: item.isLine,
|
|
|
+ isShow: item.isShow ? true : false,
|
|
|
+ });
|
|
|
});
|
|
|
});
|
|
|
chartData = chartData.filter((item) => item.showCharts);
|
|
|
@@ -790,14 +831,22 @@ const ChangeChartBarData = () => {
|
|
|
switch (state.tabActive) {
|
|
|
case "0":
|
|
|
average = item.fiveRateResultVo?.avgScore ?? 0;
|
|
|
- markLineData.push({ legendName: item.keyName, value: average, isShow: item.isShow });
|
|
|
+ markLineData.push({
|
|
|
+ legendName: item.keyName,
|
|
|
+ value: average,
|
|
|
+ isShow: item.isShow,
|
|
|
+ });
|
|
|
break;
|
|
|
case "1":
|
|
|
average = 0;
|
|
|
break;
|
|
|
case "2":
|
|
|
average = item.fiveRateResultVo?.rateScore ?? 0;
|
|
|
- markLineData.push({ legendName: item.keyName, value: average, isShow: item.isShow });
|
|
|
+ markLineData.push({
|
|
|
+ legendName: item.keyName,
|
|
|
+ value: average,
|
|
|
+ isShow: item.isShow,
|
|
|
+ });
|
|
|
break;
|
|
|
case "3":
|
|
|
case "4":
|
|
|
@@ -805,7 +854,11 @@ const ChangeChartBarData = () => {
|
|
|
break;
|
|
|
default:
|
|
|
average = item.fiveRateResultVo?.[`${state.tabActive}Rate`] ?? 0;
|
|
|
- markLineData.push({ legendName: item.keyName, value: average, isShow: item.isShow });
|
|
|
+ markLineData.push({
|
|
|
+ legendName: item.keyName,
|
|
|
+ value: average,
|
|
|
+ isShow: item.isShow,
|
|
|
+ });
|
|
|
break;
|
|
|
}
|
|
|
} else {
|
|
|
@@ -823,12 +876,20 @@ const ChangeChartBarData = () => {
|
|
|
maxClassName = item.keyName;
|
|
|
minClassName = item.keyName;
|
|
|
} else {
|
|
|
- if (score > maxScore) { maxScore = score; maxClassName = item.keyName; }
|
|
|
- else if (score < minScore) { minScore = score; minClassName = item.keyName; }
|
|
|
+ if (score > maxScore) {
|
|
|
+ maxScore = score;
|
|
|
+ maxClassName = item.keyName;
|
|
|
+ } else if (score < minScore) {
|
|
|
+ minScore = score;
|
|
|
+ minClassName = item.keyName;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- if (analysisStore.filterObject.examLevel == 1) {
|
|
|
- list.push({ name: "均分联排", value: item.fiveRateResultVo?.avgExamRank || "-" });
|
|
|
+ if (filterObject.value.examLevel == 1) {
|
|
|
+ list.push({
|
|
|
+ name: "均分联排",
|
|
|
+ value: item.fiveRateResultVo?.avgExamRank || "-",
|
|
|
+ });
|
|
|
}
|
|
|
list.push(
|
|
|
{ name: "均分校排", value: item.fiveRateResultVo?.avgRank || "-" },
|
|
|
@@ -836,29 +897,39 @@ const ChangeChartBarData = () => {
|
|
|
{ name: "最低分", value: item.fiveRateResultVo?.minScore },
|
|
|
{ name: "标准差", value: item.fiveRateResultVo?.stdScore },
|
|
|
{ name: "实考人数", value: item.fiveRateResultVo?.effectiveNum },
|
|
|
- { name: "教师", value: item.teacherName || "-" }
|
|
|
+ { name: "教师", value: item.teacherName || "-" },
|
|
|
);
|
|
|
tooltipData.push({ list, name: item.keyName });
|
|
|
break;
|
|
|
|
|
|
case "1": // 标准分
|
|
|
if (item.classLevel == 2) {
|
|
|
- const score = parseFloat(item.fiveRateResultVo?.standardAvgScore) || 0;
|
|
|
+ const score =
|
|
|
+ parseFloat(item.fiveRateResultVo?.standardAvgScore) || 0;
|
|
|
if (!maxClassName && !minClassName) {
|
|
|
- maxScore = score; minScore = score;
|
|
|
- maxClassName = item.keyName; minClassName = item.keyName;
|
|
|
+ maxScore = score;
|
|
|
+ minScore = score;
|
|
|
+ maxClassName = item.keyName;
|
|
|
+ minClassName = item.keyName;
|
|
|
} else {
|
|
|
- if (score > maxScore) { maxScore = score; maxClassName = item.keyName; }
|
|
|
- else if (score < minScore) { minScore = score; minClassName = item.keyName; }
|
|
|
+ if (score > maxScore) {
|
|
|
+ maxScore = score;
|
|
|
+ maxClassName = item.keyName;
|
|
|
+ } else if (score < minScore) {
|
|
|
+ minScore = score;
|
|
|
+ minClassName = item.keyName;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- const zscore = parseFloat(item.fiveRateResultVo?.standardAvgScore).toFixed(2);
|
|
|
+ const zscore = parseFloat(
|
|
|
+ item.fiveRateResultVo?.standardAvgScore,
|
|
|
+ ).toFixed(2);
|
|
|
datay.push(isNaN(Number(zscore)) ? 0 : zscore);
|
|
|
list.push(
|
|
|
{ name: "标准分", value: item.fiveRateResultVo?.standardAvgScore },
|
|
|
{ name: "平均分", value: item.fiveRateResultVo?.avgScore },
|
|
|
{ name: "实考人数", value: item.fiveRateResultVo?.effectiveNum },
|
|
|
- { name: "教师", value: item.teacherName || "-" }
|
|
|
+ { name: "教师", value: item.teacherName || "-" },
|
|
|
);
|
|
|
tooltipData.push({ list, name: item.keyName });
|
|
|
break;
|
|
|
@@ -867,19 +938,29 @@ const ChangeChartBarData = () => {
|
|
|
if (item.classLevel == 2) {
|
|
|
const score = parseFloat(item.fiveRateResultVo?.rateScore) || 0;
|
|
|
if (!maxClassName && !minClassName) {
|
|
|
- maxScore = score; minScore = score;
|
|
|
- maxClassName = item.keyName; minClassName = item.keyName;
|
|
|
+ maxScore = score;
|
|
|
+ minScore = score;
|
|
|
+ maxClassName = item.keyName;
|
|
|
+ minClassName = item.keyName;
|
|
|
} else {
|
|
|
- if (score > maxScore) { maxScore = score; maxClassName = item.keyName; }
|
|
|
- else if (score < minScore) { minScore = score; minClassName = item.keyName; }
|
|
|
+ if (score > maxScore) {
|
|
|
+ maxScore = score;
|
|
|
+ maxClassName = item.keyName;
|
|
|
+ } else if (score < minScore) {
|
|
|
+ minScore = score;
|
|
|
+ minClassName = item.keyName;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
datay.push(item.fiveRateResultVo?.rateScore ?? 0);
|
|
|
dataLoseRate.push(item.fiveRateResultVo?.lostRate ?? 0);
|
|
|
list.push(
|
|
|
- { name: "失分率", value: (item.fiveRateResultVo?.lostRate ?? 0) + "%" },
|
|
|
+ {
|
|
|
+ name: "失分率",
|
|
|
+ value: (item.fiveRateResultVo?.lostRate ?? 0) + "%",
|
|
|
+ },
|
|
|
{ name: "实考人数", value: item.fiveRateResultVo?.effectiveNum },
|
|
|
- { name: "教师", value: item.teacherName || "-" }
|
|
|
+ { name: "教师", value: item.teacherName || "-" },
|
|
|
);
|
|
|
tooltipData.push({ list, name: item.keyName });
|
|
|
break;
|
|
|
@@ -887,24 +968,35 @@ const ChangeChartBarData = () => {
|
|
|
case "3": // 超均分
|
|
|
case "4": // 超均率
|
|
|
{
|
|
|
- const exceedAvgScore = state.rankType == 2
|
|
|
- ? item.fiveRateResultVo?.exceedAvgScore
|
|
|
- : item.fiveRateResultVo?.examExceedAvgScore;
|
|
|
- const exceedAvgScoreRate = state.rankType == 2
|
|
|
- ? item.fiveRateResultVo?.exceedAvgScoreRate
|
|
|
- : item.fiveRateResultVo?.examExceedAvgScoreRate;
|
|
|
-
|
|
|
- const shouldProcess = schoolLevel.value == 2 || item.keyName != "年级";
|
|
|
+ const exceedAvgScore =
|
|
|
+ state.rankType == 2
|
|
|
+ ? item.fiveRateResultVo?.exceedAvgScore
|
|
|
+ : item.fiveRateResultVo?.examExceedAvgScore;
|
|
|
+ const exceedAvgScoreRate =
|
|
|
+ state.rankType == 2
|
|
|
+ ? item.fiveRateResultVo?.exceedAvgScoreRate
|
|
|
+ : item.fiveRateResultVo?.examExceedAvgScoreRate;
|
|
|
+
|
|
|
+ const shouldProcess =
|
|
|
+ schoolLevel.value == 2 || item.keyName != "年级";
|
|
|
if (shouldProcess) {
|
|
|
- const targetValue = state.tabActive == "3" ? exceedAvgScore : exceedAvgScoreRate;
|
|
|
+ const targetValue =
|
|
|
+ state.tabActive == "3" ? exceedAvgScore : exceedAvgScoreRate;
|
|
|
const score = parseFloat(targetValue) || 0;
|
|
|
if (item.classLevel == 2 || schoolLevel.value == 2) {
|
|
|
if (!maxClassName && !minClassName) {
|
|
|
- maxScore = score; minScore = score;
|
|
|
- maxClassName = item.keyName; minClassName = item.keyName;
|
|
|
+ maxScore = score;
|
|
|
+ minScore = score;
|
|
|
+ maxClassName = item.keyName;
|
|
|
+ minClassName = item.keyName;
|
|
|
} else {
|
|
|
- if (score > maxScore) { maxScore = score; maxClassName = item.keyName; }
|
|
|
- else if (score < minScore) { minScore = score; minClassName = item.keyName; }
|
|
|
+ if (score > maxScore) {
|
|
|
+ maxScore = score;
|
|
|
+ maxClassName = item.keyName;
|
|
|
+ } else if (score < minScore) {
|
|
|
+ minScore = score;
|
|
|
+ minClassName = item.keyName;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
const formatted = parseFloat(targetValue).toFixed(2);
|
|
|
@@ -913,32 +1005,46 @@ const ChangeChartBarData = () => {
|
|
|
{ name: "超均分", value: exceedAvgScore },
|
|
|
{ name: "超均率", value: (exceedAvgScoreRate ?? 0) + "%" },
|
|
|
{ name: "平均分", value: item.fiveRateResultVo?.avgScore },
|
|
|
- { name: "实考人数", value: item.fiveRateResultVo?.effectiveNum },
|
|
|
- { name: "教师", value: item.teacherName || "-" }
|
|
|
+ {
|
|
|
+ name: "实考人数",
|
|
|
+ value: item.fiveRateResultVo?.effectiveNum,
|
|
|
+ },
|
|
|
+ { name: "教师", value: item.teacherName || "-" },
|
|
|
);
|
|
|
tooltipData.push({ list, name: item.keyName });
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
- default: // 五率(优秀率/良好率/及格率/低分率等)
|
|
|
+ default:
|
|
|
{
|
|
|
+ // 五率(优秀率/良好率/及格率/低分率等)
|
|
|
const rate = item.fiveRateResultVo?.[`${state.tabActive}Rate`];
|
|
|
datay.push(rate ?? 0);
|
|
|
- list.push({ name: state.groupTitle + "人数", value: item.fiveRateResultVo?.[`${state.tabActive}RateNum`] });
|
|
|
+ list.push({
|
|
|
+ name: state.groupTitle + "人数",
|
|
|
+ value: item.fiveRateResultVo?.[`${state.tabActive}RateNum`],
|
|
|
+ });
|
|
|
if (item.classLevel == 2) {
|
|
|
const score = parseFloat(rate) || 0;
|
|
|
if (!maxClassName && !minClassName) {
|
|
|
- maxScore = score; minScore = score;
|
|
|
- maxClassName = item.keyName; minClassName = item.keyName;
|
|
|
+ maxScore = score;
|
|
|
+ minScore = score;
|
|
|
+ maxClassName = item.keyName;
|
|
|
+ minClassName = item.keyName;
|
|
|
} else {
|
|
|
- if (score > maxScore) { maxScore = score; maxClassName = item.keyName; }
|
|
|
- else if (score < minScore) { minScore = score; minClassName = item.keyName; }
|
|
|
+ if (score > maxScore) {
|
|
|
+ maxScore = score;
|
|
|
+ maxClassName = item.keyName;
|
|
|
+ } else if (score < minScore) {
|
|
|
+ minScore = score;
|
|
|
+ minClassName = item.keyName;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
list.push(
|
|
|
{ name: "实考人数", value: item.fiveRateResultVo?.effectiveNum },
|
|
|
- { name: "教师", value: item.teacherName || "-" }
|
|
|
+ { name: "教师", value: item.teacherName || "-" },
|
|
|
);
|
|
|
tooltipData.push({ list, name: item.keyName });
|
|
|
}
|
|
|
@@ -965,11 +1071,13 @@ const ChangeChartBarData = () => {
|
|
|
break;
|
|
|
case "1":
|
|
|
unit = "";
|
|
|
- expandableText = "说明:标准分,也称为标准分数或Z分数,是一种由原始分数推导出来的相对地位量数,用于说明原始分数在所属分数群体中的相对位置。其计算公式为:Z = (x - μ)/σ(Z是标准分,X是原始数据的值,μ是该组数据的平均数,σ是该组数据的标准差)。标准分的分数区间通常在-3到+3之间,标准分大于0,表示成绩在平均数之上;标准分数小于0,表示成绩在平均分数之下。与原始分相比,标准分最直接的意义是它给出离平均数的距离。柱图的颜色可直接区分出各班级标准分的差异,标准分越高说明该班的表现越优异。";
|
|
|
+ expandableText =
|
|
|
+ "说明:标准分,也称为标准分数或Z分数,是一种由原始分数推导出来的相对地位量数,用于说明原始分数在所属分数群体中的相对位置。其计算公式为:Z = (x - μ)/σ(Z是标准分,X是原始数据的值,μ是该组数据的平均数,σ是该组数据的标准差)。标准分的分数区间通常在-3到+3之间,标准分大于0,表示成绩在平均数之上;标准分数小于0,表示成绩在平均分数之下。与原始分相比,标准分最直接的意义是它给出离平均数的距离。柱图的颜色可直接区分出各班级标准分的差异,标准分越高说明该班的表现越优异。";
|
|
|
break;
|
|
|
case "2":
|
|
|
unit = "%";
|
|
|
- expandableText = "说明:得分率是指实际得分除以考核分的比值,换算成的百分数。公式:得分率=得分/满分*100%。得分率是评估考试表现的重要指标。较高的得分率通常代表更好的完成度或掌握程度,而较低的得分率则可能提示需要改进或加强。红色柱代表班级得分率低于年级得分率,反之,绿色柱代表班级得分率高于年级得分率。";
|
|
|
+ expandableText =
|
|
|
+ "说明:得分率是指实际得分除以考核分的比值,换算成的百分数。公式:得分率=得分/满分*100%。得分率是评估考试表现的重要指标。较高的得分率通常代表更好的完成度或掌握程度,而较低的得分率则可能提示需要改进或加强。红色柱代表班级得分率低于年级得分率,反之,绿色柱代表班级得分率高于年级得分率。";
|
|
|
break;
|
|
|
case "3":
|
|
|
unit = "";
|
|
|
@@ -981,7 +1089,13 @@ const ChangeChartBarData = () => {
|
|
|
break;
|
|
|
default:
|
|
|
unit = "%";
|
|
|
- const percent: Record<string, string> = { high: "", good: "", fine: "", pass: "", low: "" };
|
|
|
+ const percent: Record<string, string> = {
|
|
|
+ high: "",
|
|
|
+ good: "",
|
|
|
+ fine: "",
|
|
|
+ pass: "",
|
|
|
+ low: "",
|
|
|
+ };
|
|
|
state.analysisData.dynamicsHeader.forEach((item) => {
|
|
|
percent[item.prop] = `${item.value}%`;
|
|
|
});
|
|
|
@@ -1054,7 +1168,10 @@ const GetAnalysisFiveRateData = () => {
|
|
|
rowData.push(item.fiveRateResultVo?.[`${rateItem.value}Rate`] ?? 0);
|
|
|
rowTooltip.push({
|
|
|
list: [
|
|
|
- { label: "实考人数", value: item?.fiveRateResultVo?.effectiveNum ?? "-" },
|
|
|
+ {
|
|
|
+ label: "实考人数",
|
|
|
+ value: item?.fiveRateResultVo?.effectiveNum ?? "-",
|
|
|
+ },
|
|
|
{ label: "教师", value: item?.teacherName ?? "-" },
|
|
|
],
|
|
|
rateNum: item?.fiveRateResultVo?.[`${rateItem.value}RateNum`] ?? "-",
|
|
|
@@ -1080,7 +1197,39 @@ const GetAnalysisFiveRateData = () => {
|
|
|
const fiveRateNames = state.fiveRateList.map((item) => item.title).join("、");
|
|
|
state.analysisData.expandableText = `说明:班级<span class="normal_color">${state.rateName}</span>指班级的<span class="normal_color">${fiveRateNames}。${state.rateName}</span>综合展示,可以全面了解班级的成绩水平情况。点击班级的柱可在下方查看该班除总分外其他科目的<span class="normal_color">${state.rateName}</span>占比情况。`;
|
|
|
};
|
|
|
+//展开学生弹窗
|
|
|
+const OpenStudentDialog = (row, header, child) => {
|
|
|
+ state.dialogData.title = `${header.name}`;
|
|
|
+ state.dialogData.tableTitle = row.keyName;
|
|
|
+ state.dialogData.fiveRateName = (child.label || "").replace(/人数/g, ""); //当前选择的五率的名称
|
|
|
+ state.dialogData.selectSubjectName = row.subjectName; //当前选择的科目名称
|
|
|
+ state.dialogData.selectSchoolLevel = row.schoolLevel; //当前选择的学校级别:0-联考 1-学校分组 2-具体学校
|
|
|
+
|
|
|
+ state.dialogData.selectClassLevel = row.classLevel; //当前选择的班级级别:0-年级 1-组合班级 2-具体班级
|
|
|
+ if (row.schoolLevel == 2) {
|
|
|
+ //单校 班级
|
|
|
+ const keyName = row.keyName ?? "";
|
|
|
+ if (filterObject.value.schoolLevel == 2) {
|
|
|
+ state.dialogData.selectClassName = keyName;
|
|
|
+ } else {
|
|
|
+ state.dialogData.selectClassName = keyName.split("-")?.[1] ?? ""; //当前选择的班级名称:年级 组合班级 单班
|
|
|
+ }
|
|
|
+ state.dialogData.selectSchoolName = row?.schoolName ?? "";
|
|
|
+ } else if (row.schoolLevel == 1) {
|
|
|
+ //组合学校
|
|
|
+ state.dialogData.selectClassName = "";
|
|
|
+ state.dialogData.selectSchoolName = row.keyName; //当前选择的学校名称:联校 组合学校 单校名称
|
|
|
+ } else {
|
|
|
+ state.dialogData.selectClassName = "";
|
|
|
+ state.dialogData.selectSchoolName = "";
|
|
|
+ }
|
|
|
+ state.dialogData.showDialog = true;
|
|
|
+};
|
|
|
|
|
|
+// 关闭学生列表弹窗
|
|
|
+const CloseDialog = (val: boolean) => {
|
|
|
+ state.dialogData.showDialog = val;
|
|
|
+};
|
|
|
// ================= 导出功能 =================
|
|
|
|
|
|
/** 导出 Excel */
|
|
|
@@ -1088,17 +1237,25 @@ const ExportExcel = () => {
|
|
|
reportModuleRef.value?.SetExportLoading?.(true);
|
|
|
const examName = getExamName.value;
|
|
|
let params: Record<string, any> = {
|
|
|
- fileName: GetExcelFileName(examName, analysisStore.filterObject, `${state.groupTitle}分析表`),
|
|
|
+ fileName: GetExcelFileName(
|
|
|
+ examName,
|
|
|
+ filterObject.value,
|
|
|
+ `${state.groupTitle}分析表`,
|
|
|
+ ),
|
|
|
examName: examName,
|
|
|
sheetName: `${state.groupTitle}分析表`,
|
|
|
chooseType: 1,
|
|
|
lastExamName: "",
|
|
|
};
|
|
|
|
|
|
- const staticHeaderData = state.analysisData.headerData.static.filter((item) => item.display);
|
|
|
+ const staticHeaderData = state.analysisData.headerData.static.filter(
|
|
|
+ (item) => item.display,
|
|
|
+ );
|
|
|
params.staticHeaderData = staticHeaderData;
|
|
|
|
|
|
- const childHeaderData = state.analysisData.headerData.child.filter((item) => item.display);
|
|
|
+ const childHeaderData = state.analysisData.headerData.child.filter(
|
|
|
+ (item) => item.display,
|
|
|
+ );
|
|
|
params.fiveRateHeaderList = state.analysisData.dynamicsHeader;
|
|
|
|
|
|
let dataList: string[][] = [];
|
|
|
@@ -1108,9 +1265,13 @@ const ExportExcel = () => {
|
|
|
let propVal = "";
|
|
|
const isRate = header.label.includes("率");
|
|
|
if (item.hasOwnProperty(header.prop)) {
|
|
|
- const value = header.prop == "index" ? item[header.prop] : item[header.prop] || "-";
|
|
|
+ const value =
|
|
|
+ header.prop == "index" ? item[header.prop] : item[header.prop] || "-";
|
|
|
propVal = `${value}${isRate && value != "-" ? "%" : ""}`;
|
|
|
- } else if (item.fiveRateResultVo && item.fiveRateResultVo.hasOwnProperty(header.prop)) {
|
|
|
+ } else if (
|
|
|
+ item.fiveRateResultVo &&
|
|
|
+ item.fiveRateResultVo.hasOwnProperty(header.prop)
|
|
|
+ ) {
|
|
|
const value = item.fiveRateResultVo[header.prop] || "-";
|
|
|
propVal = `${value}${isRate && value != "-" ? "%" : ""}`;
|
|
|
}
|
|
|
@@ -1118,7 +1279,10 @@ const ExportExcel = () => {
|
|
|
});
|
|
|
childHeaderData.forEach((child) => {
|
|
|
let propVal = "-";
|
|
|
- if (item.fiveRateResultVo && item.fiveRateResultVo.hasOwnProperty(child.prop)) {
|
|
|
+ if (
|
|
|
+ item.fiveRateResultVo &&
|
|
|
+ item.fiveRateResultVo.hasOwnProperty(child.prop)
|
|
|
+ ) {
|
|
|
const reg = /Rate$/;
|
|
|
const isRate = reg.test(child.prop);
|
|
|
const value = item.fiveRateResultVo[child.prop] ?? "-";
|
|
|
@@ -1154,11 +1318,11 @@ const pageInit = () => {
|
|
|
|
|
|
// 监听筛选条件变化
|
|
|
watch(
|
|
|
- () => analysisStore.filterObject,
|
|
|
+ () => filterObject.value,
|
|
|
() => {
|
|
|
pageInit();
|
|
|
},
|
|
|
- { deep: true }
|
|
|
+ { deep: true },
|
|
|
);
|
|
|
|
|
|
onMounted(() => {
|
|
|
@@ -1176,4 +1340,4 @@ onMounted(() => {
|
|
|
});
|
|
|
</script>
|
|
|
|
|
|
-<style lang="scss" scoped></style>
|
|
|
+<style lang="scss" scoped></style>
|