|
|
@@ -1,88 +1,1274 @@
|
|
|
<template>
|
|
|
- <!-- 成绩查询 成绩单 -->
|
|
|
- <ReportModule :showTitle="false" :showDescribe="false" tableOrChart="table">
|
|
|
- <template #title_left>
|
|
|
- <el-input v-model="state.keyWord" style="width: 200px" placeholder="请输入学号或姓名" class="input_with">
|
|
|
- <template #append>
|
|
|
- <el-button :icon="Search" />
|
|
|
- </template>
|
|
|
- </el-input>
|
|
|
- <span class="count_item">应考:293人</span>
|
|
|
- <span class="count_item">实考:280人</span>
|
|
|
- <span class="count_item orange">缺考:13人</span>
|
|
|
+ <ReportModule
|
|
|
+ :showTitle="true"
|
|
|
+ :titleList="[state.groupTitle]"
|
|
|
+ :showDescribe="true"
|
|
|
+ tableOrChart="chart"
|
|
|
+ :showPrintBtn="false"
|
|
|
+ :showExportBtn="false"
|
|
|
+ >
|
|
|
+ <template #title_right>
|
|
|
+ <EchartType
|
|
|
+ :chartTypeList="state.problemAnalysisData.chartTypeList"
|
|
|
+ :current="state.problemAnalysisData.chartType"
|
|
|
+ @ChangeEchartType="
|
|
|
+ (val) => ChangeEchartType(val, 'problemAnalysisData')
|
|
|
+ "
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template #module_table_chart>
|
|
|
+ <template v-if="state.problemAnalysisData.data.length > 0">
|
|
|
+ <BarLineCharts
|
|
|
+ v-if="state.problemAnalysisData.chartType == 'line_bar_chart'"
|
|
|
+ :legendList="state.problemAnalysisData.legendList"
|
|
|
+ :showBarLegendIndex="state.problemAnalysisData.showBarLegendIndex"
|
|
|
+ title="得分率"
|
|
|
+ :data="state.problemAnalysisData.data"
|
|
|
+ @HandleChartClick="HandleChartClick"
|
|
|
+ @ChangeChartOrder="
|
|
|
+ (sortType, legendData, barIndex) =>
|
|
|
+ ChangeChartOrder(sortType, legendData, barIndex, 1)
|
|
|
+ "
|
|
|
+ >
|
|
|
+ </BarLineCharts>
|
|
|
+ <BarsCharts
|
|
|
+ v-if="state.problemAnalysisData.chartType == 'vertical_bar'"
|
|
|
+ :key="state.chartKey"
|
|
|
+ :data="state.problemAnalysisData.data"
|
|
|
+ :legendList="state.problemAnalysisData.legendList"
|
|
|
+ :showSortSelectbox="true"
|
|
|
+ unit="%"
|
|
|
+ title="得分率"
|
|
|
+ :isClick="true"
|
|
|
+ @HandleChartClick="HandleChartClick"
|
|
|
+ @ChangeChartOrder="
|
|
|
+ (sortType, legendData, barIndex) =>
|
|
|
+ ChangeChartOrder(sortType, legendData, barIndex, 1)
|
|
|
+ "
|
|
|
+ >
|
|
|
+ </BarsCharts>
|
|
|
+ <RadarCharts
|
|
|
+ v-if="state.problemAnalysisData.chartType == 'radar_chart'"
|
|
|
+ :key="state.chartKey"
|
|
|
+ :data="state.problemAnalysisData.data"
|
|
|
+ :legendList="state.problemAnalysisData.legendList"
|
|
|
+ :showCheckBox="true"
|
|
|
+ :openShowAllLegend="true"
|
|
|
+ :isClick="true"
|
|
|
+ @HandleChartClick="HandleChartClick"
|
|
|
+ >
|
|
|
+ </RadarCharts>
|
|
|
+ </template>
|
|
|
+ <div
|
|
|
+ v-else
|
|
|
+ class="no_content_data"
|
|
|
+ v-loading="state.dataLoading"
|
|
|
+ :element-loading-text="state.loadingText"
|
|
|
+ element-loading-spinner="el-icon-loading"
|
|
|
+ element-loading-background="#ffffff"
|
|
|
+ >
|
|
|
+ <span>暂无数据</span>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
+ <template #module_describe>
|
|
|
+ 展示每道试题的得分率图。得分率指实际得分/考核分的比值,换算成的百分数。可以用于分析每道试题的难易程度和质量,试题得分率高意味着试题难度低或者学生整体水平高;得分率低意味着试题难度较高或者考生整体水平较低。点击每道试题的柱或雷达图的题号可在下方查看该题每个班的得分率情况。
|
|
|
+ </template>
|
|
|
+ </ReportModule>
|
|
|
+ <ReportModule
|
|
|
+ :showTitle="true"
|
|
|
+ :titleList="[state.groupTitle, state.questionTitle]"
|
|
|
+ :showDescribe="true"
|
|
|
+ tableOrChart="chart"
|
|
|
+ :showPrintBtn="false"
|
|
|
+ :showExportBtn="false"
|
|
|
+ >
|
|
|
<template #title_right>
|
|
|
- <el-checkbox-group class="checkbox_group" v-model="state.checkList">
|
|
|
- <el-checkbox label="显示分组" value="group" />
|
|
|
- <el-checkbox label="显示小题" value="question" />
|
|
|
- </el-checkbox-group>
|
|
|
+ <EchartType
|
|
|
+ :chartTypeList="state.questionScoreStatsData.chartTypeList"
|
|
|
+ :current="state.questionScoreStatsData.chartType"
|
|
|
+ @ChangeEchartType="
|
|
|
+ (val) => ChangeEchartType(val, 'questionScoreStatsData')
|
|
|
+ "
|
|
|
+ />
|
|
|
</template>
|
|
|
<template #module_table_chart>
|
|
|
- <el-table :data="tableData" border style="width: 100%">
|
|
|
- <el-table-column prop="date" label="Date" width="180" />
|
|
|
- <el-table-column prop="name" label="Name" width="180" />
|
|
|
- <el-table-column prop="address" label="Address" />
|
|
|
+ <template v-if="state.questionScoreStatsData.datax.length > 0">
|
|
|
+ <BarScoringRateVertical
|
|
|
+ v-if="state.questionScoreStatsData.chartType == 'vertical_bar'"
|
|
|
+ :datax="state.questionScoreStatsData.datax"
|
|
|
+ :datay="state.questionScoreStatsData.dataStackY"
|
|
|
+ :tooltipData="state.questionScoreStatsData.tooltipData"
|
|
|
+ :isShowMarkLine="true"
|
|
|
+ :average="state.questionScoreStatsData.rate"
|
|
|
+ :markLineData="state.questionScoreStatsData.markLineData"
|
|
|
+ :color="['#3BA272', '#EE6666']"
|
|
|
+ typeName="得分率"
|
|
|
+ :isClick="true"
|
|
|
+ @HandleChartClick="HandleQuestionScoreChartClick"
|
|
|
+ ></BarScoringRateVertical>
|
|
|
+ <DifferenceChart
|
|
|
+ v-if="state.questionScoreStatsData.chartType == 'difference_chart'"
|
|
|
+ :datax="state.questionScoreStatsData.datax"
|
|
|
+ :datay="state.questionScoreStatsData.datay"
|
|
|
+ unit="%"
|
|
|
+ type="1"
|
|
|
+ title="得分率"
|
|
|
+ :rate="state.questionScoreStatsData.rate"
|
|
|
+ @HandleChartClick="HandleQuestionScoreChartClick"
|
|
|
+ >
|
|
|
+ </DifferenceChart>
|
|
|
+ </template>
|
|
|
+ <div
|
|
|
+ v-else
|
|
|
+ class="no_content_data"
|
|
|
+ v-loading="state.dataLoading"
|
|
|
+ :element-loading-text="state.loadingText"
|
|
|
+ element-loading-spinner="el-icon-loading"
|
|
|
+ element-loading-background="#ffffff"
|
|
|
+ >
|
|
|
+ <span>暂无数据</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #module_describe>
|
|
|
+ 说明:通过上面图形,可查看该题每个班的得分率情况,由图中可以看出,得分率最高为<span
|
|
|
+ style="color: #3ba272"
|
|
|
+ >{{ state.questionScoreStatsData.maxClass }}</span
|
|
|
+ >,最低为<span style="color: #ee6666">{{
|
|
|
+ state.questionScoreStatsData.minClass
|
|
|
+ }}</span
|
|
|
+ >。点击每个班级的柱可在下方查看该班各个选项/得分的人数分布。
|
|
|
+ </template>
|
|
|
+ </ReportModule>
|
|
|
+ <ReportModule
|
|
|
+ :showTitle="true"
|
|
|
+ :titleList="[state.groupTitle, state.questionTitle, state.classTitle]"
|
|
|
+ :showDescribe="true"
|
|
|
+ tableOrChart="qita"
|
|
|
+ :showPrintBtn="false"
|
|
|
+ :showExportBtn="false"
|
|
|
+ >
|
|
|
+ <template #module_qita>
|
|
|
+ <div class="content_left answer">
|
|
|
+ <BarChart
|
|
|
+ v-if="state.questionAnswerData.datax.length"
|
|
|
+ :datax="state.questionAnswerData.datax"
|
|
|
+ :datay="state.questionAnswerData.datay"
|
|
|
+ typeName="人数"
|
|
|
+ :showNuitY="false"
|
|
|
+ unit="人"
|
|
|
+ :unitX="
|
|
|
+ state.questionAnswerData.questionType == '单选题' ||
|
|
|
+ state.questionAnswerData.questionType == '多选题' ||
|
|
|
+ state.questionAnswerData.questionType == '判断题'
|
|
|
+ ? ''
|
|
|
+ : '分'
|
|
|
+ "
|
|
|
+ :showMarkPoint="false"
|
|
|
+ :isShowMarkLine="false"
|
|
|
+ :color="state.questionAnswerData.color"
|
|
|
+ :answerValue="state.questionAnswerData.answerValue"
|
|
|
+ :answerScore="state.questionAnswerData.answerScore"
|
|
|
+ :fullMark="state.questionAnswerData.fullMark"
|
|
|
+ :isClick="true"
|
|
|
+ @HandleChartClick="HandleQuestionAnswerChartClick"
|
|
|
+ style="height: 300px"
|
|
|
+ ></BarChart>
|
|
|
+ <div
|
|
|
+ v-else
|
|
|
+ class="module_chart no_content_data"
|
|
|
+ v-loading="state.dataLoading"
|
|
|
+ :element-loading-text="state.loadingText"
|
|
|
+ element-loading-spinner="el-icon-loading"
|
|
|
+ element-loading-background="#ffffff"
|
|
|
+ >
|
|
|
+ <span>暂无数据</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="content_right answer table_42">
|
|
|
+ <el-table
|
|
|
+ border
|
|
|
+ :data="state.questionAnswerData.tableData"
|
|
|
+ stripe
|
|
|
+ align="left"
|
|
|
+ :header-row-style="HeaderRowStyle"
|
|
|
+ >
|
|
|
+ <el-table-column :label="state.classTitle" align="center">
|
|
|
+ <el-table-column
|
|
|
+ prop="title"
|
|
|
+ align="center"
|
|
|
+ label="名称"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="value"
|
|
|
+ align="center"
|
|
|
+ label="数值"
|
|
|
+ ></el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #module_describe>
|
|
|
+ 说明:通过柱图,可查看该题下该班所有学生的选项或试题得分情况。点击每个柱可查看该选项或分数的学生明细和答题卡答题情况。
|
|
|
+ </template>
|
|
|
+ </ReportModule>
|
|
|
+ <ReportModule
|
|
|
+ :showTitle="true"
|
|
|
+ :titleList="[
|
|
|
+ state.groupTitle,
|
|
|
+ state.questionTitle,
|
|
|
+ state.classTitle,
|
|
|
+ state.optionTitle,
|
|
|
+ ]"
|
|
|
+ :showDescribe="true"
|
|
|
+ tableOrChart="qita"
|
|
|
+ :showPrintBtn="false"
|
|
|
+ :showExportBtn="false"
|
|
|
+ >
|
|
|
+ <template #title_right>
|
|
|
+ <el-button class="default_button" @click="VisibleQuestionCard">
|
|
|
+ <img src="@/assets/icon/card_view.webp" />批量查看
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ <template #module_qita>
|
|
|
+ <div class="content_left card"></div>
|
|
|
+ <div class="content_right card table_42">
|
|
|
+ <el-table
|
|
|
+ border
|
|
|
+ :data="state.majorAnswerData.tableData"
|
|
|
+ stripe
|
|
|
+ highlight-current-row
|
|
|
+ align="left"
|
|
|
+ height="401px"
|
|
|
+ row-key="studentRegistrationCode"
|
|
|
+ :row-style="{ cursor: 'pointer' }"
|
|
|
+ :row-class-name="TableRowClassName"
|
|
|
+ @row-click="HandleRowClick"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ prop="studentUserName"
|
|
|
+ align="center"
|
|
|
+ label="学生"
|
|
|
+ show-overflow-tooltip
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ label="班级"
|
|
|
+ prop="className"
|
|
|
+ align="center"
|
|
|
+ min-width="70"
|
|
|
+ show-overflow-tooltip
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="questionScore"
|
|
|
+ align="center"
|
|
|
+ label="得分"
|
|
|
+ width="70"
|
|
|
+ show-overflow-tooltip
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="paperScore"
|
|
|
+ align="center"
|
|
|
+ label="成绩"
|
|
|
+ width="70"
|
|
|
+ show-overflow-tooltip
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column align="center" label="操作">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-button type="text" @click.stop="handleClick(scope.row)"
|
|
|
+ >查看答题卡</el-button
|
|
|
+ >
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #module_describe>
|
|
|
+ 说明:点击左侧表格列可切换学生查看具体学生答题图片,点击学生姓名可在下方查看学生均衡分析,点击学生成绩可查看学生答题卡原卷。
|
|
|
+ </template>
|
|
|
+ </ReportModule>
|
|
|
+ <ReportModule
|
|
|
+ :showTitle="true"
|
|
|
+ :titleList="[state.groupTitle]"
|
|
|
+ :showDescribe="true"
|
|
|
+ tableOrChart="table"
|
|
|
+ :showPrintBtn="false"
|
|
|
+ :showExportBtn="true"
|
|
|
+ :currentPage="state.majorTableData.currentPage"
|
|
|
+ :pageSize="state.majorTableData.pageSize"
|
|
|
+ :total="state.majorTableData.total"
|
|
|
+ @update:pageSize="handleSizeChange"
|
|
|
+ @update:currentPage="handleCurrentChange"
|
|
|
+ >
|
|
|
+ <template #title_right></template>
|
|
|
+ <template #module_table_chart>
|
|
|
+ <el-table
|
|
|
+ :data="state.majorTableData.tableData"
|
|
|
+ ref="majorTable"
|
|
|
+ border
|
|
|
+ stripe
|
|
|
+ align="left"
|
|
|
+ :key="state.majorTableData.tableKey"
|
|
|
+ >
|
|
|
+ <template v-for="item in state.majorTableData.headerData">
|
|
|
+ <el-table-column
|
|
|
+ v-if="item.display"
|
|
|
+ :key="item.prop"
|
|
|
+ align="center"
|
|
|
+ :prop="item.prop"
|
|
|
+ :min-width="item.label.length > 4 ? 110 : 90"
|
|
|
+ :label="item.label"
|
|
|
+ fixed="left"
|
|
|
+ show-overflow-tooltip
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ {{ scope.row[item.prop] || "-"
|
|
|
+ }}{{
|
|
|
+ item.prop == "estimatedScoreRate" && scope.row[item.prop]
|
|
|
+ ? "%"
|
|
|
+ : ""
|
|
|
+ }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </template>
|
|
|
+ <template v-for="parent in state.majorTableData.changeHeaderData">
|
|
|
+ <el-table-column
|
|
|
+ v-if="parent.display"
|
|
|
+ align="center"
|
|
|
+ :prop="parent.prop"
|
|
|
+ :label="parent.label"
|
|
|
+ :key="parent.prop"
|
|
|
+ >
|
|
|
+ <template v-for="item in state.majorTableData.childHeaderData">
|
|
|
+ <el-table-column
|
|
|
+ v-if="item.display"
|
|
|
+ :prop="`${parent.prop}_${item.prop}`"
|
|
|
+ :key="`${parent.prop}_${item.prop}`"
|
|
|
+ align="center"
|
|
|
+ :label="item.label"
|
|
|
+ :min-width="item.label.length > 4 ? 100 : 80"
|
|
|
+ show-overflow-tooltip
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ <span v-if="item.prop.indexOf('Rate') > -1">{{
|
|
|
+ scope.row[`${parent.prop}_${item.prop}`]
|
|
|
+ ? `${scope.row[`${parent.prop}_${item.prop}`]}%`
|
|
|
+ : "-"
|
|
|
+ }}</span>
|
|
|
+ <span
|
|
|
+ v-else
|
|
|
+ @click="OpenStudentDialog(item, parent, scope.row)"
|
|
|
+ :class="{
|
|
|
+ table_row_blue:
|
|
|
+ (item.prop.indexOf('Count') > -1 ||
|
|
|
+ item.prop.indexOf('Number') > -1) &&
|
|
|
+ scope.row?.[`${parent.prop}_${item.prop}`] > 0,
|
|
|
+ }"
|
|
|
+ >{{
|
|
|
+ scope.row?.[`${parent.prop}_${item.prop}`] ?? "-"
|
|
|
+ }}</span
|
|
|
+ >
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </template>
|
|
|
</el-table>
|
|
|
</template>
|
|
|
</ReportModule>
|
|
|
+ <!-- 批量查看小题答题卡 -->
|
|
|
+ <!-- <QuestionCard :subjectId="state.analysisStore.filterObject.subjectId" :questionId="state.cardQuestionId" :platformNumbers="cardRegistrationCodeList" :groupTitle="groupTitle" :groupName="groupName" :questionTitle="questionTitle" :classTitle="classTitle" :optionTitle="optionTitle" :tagActive="tagActive" :showDialog="showQuestionCardDialog" @CloseDialog="CloseQuestionCardDialog"></QuestionCard> -->
|
|
|
</template>
|
|
|
<script lang="ts" setup>
|
|
|
-import ReportModule from '@/components/ReportModule.vue';
|
|
|
-import { Search } from '@element-plus/icons-vue'
|
|
|
-import { onMounted, reactive, ref } from "vue";
|
|
|
-const tableData = [
|
|
|
- {
|
|
|
- date: '2016-05-03',
|
|
|
- name: 'Tom',
|
|
|
- address: 'No. 189, Grove St, Los Angeles',
|
|
|
+import ReportModule from "@/components/ReportModule.vue";
|
|
|
+import EchartType from "@/components/EchartType.vue";
|
|
|
+import { useAnalysisStore } from "@/store/analysis";
|
|
|
+import {
|
|
|
+ questionAnalysis,
|
|
|
+ queryAnswerListByAnswerAndScore,
|
|
|
+} from "@/api/analysis";
|
|
|
+import BarLineCharts from "@/components/echarts/barLineCharts.vue"; //柱状图折线图组合图组件
|
|
|
+import RadarCharts from "@/components/echarts/radarCharts.vue"; //雷达图
|
|
|
+import BarsCharts from "@/components/echarts/barsCharts.vue"; //多柱状图组件
|
|
|
+import BarScoringRateVertical from "@/components/echarts/barScoringRate_vertical.vue"; //得分率 纵向柱状图
|
|
|
+import DifferenceChart from "@/components/echarts/differenceChart.vue"; //率差图
|
|
|
+import BarChart from "@/components/echarts/barChart_answer.vue"; //单柱状图
|
|
|
+import { onMounted, reactive, watch, ref, nextTick } from "vue";
|
|
|
+import { cloneDeep } from "lodash-es";
|
|
|
+const analysisStore = useAnalysisStore();
|
|
|
+const state = reactive({
|
|
|
+ questionGroupDefault: [
|
|
|
+ {
|
|
|
+ name: "小题分析",
|
|
|
+ code: "problem",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "题型分析",
|
|
|
+ code: 11,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "错题分析",
|
|
|
+ code: "errors",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "客观题分析",
|
|
|
+ code: "selectQuestion",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "命题分析",
|
|
|
+ code: "proposition",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ questionGroupList: [], //试题分组标签 动态接口获取
|
|
|
+ tagActive: "problem", //选择的试题分组标签
|
|
|
+ groupTitle: "小题分析",
|
|
|
+ groupPreviousTitle: "",
|
|
|
+ knowledgeLayeredTitle: "", //知识点分层标题
|
|
|
+ groupName: "", // 分组名称
|
|
|
+ questionTitle: "", //题目名称
|
|
|
+ classTitle: "", //班级名称
|
|
|
+ optionTitle: "", //选项名称
|
|
|
+ studentUserName: "", //学生名称
|
|
|
+ studentRegistrationCode: "", //学生code
|
|
|
+ questionTypesData: {
|
|
|
+ chartKey: 0,
|
|
|
+ refresh: false,
|
|
|
+ data: [],
|
|
|
+ tableData: [],
|
|
|
},
|
|
|
- {
|
|
|
- date: '2016-05-02',
|
|
|
- name: 'Tom',
|
|
|
- address: 'No. 189, Grove St, Los Angeles',
|
|
|
+ problemAnalysisData: {
|
|
|
+ chartType: "line_bar_chart", //默认显示折线图柱状图line_bar_chart
|
|
|
+ chartTypeList: [
|
|
|
+ {
|
|
|
+ label: "组合图",
|
|
|
+ value: "line_bar_chart",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "柱状图",
|
|
|
+ value: "vertical_bar",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "雷达图",
|
|
|
+ value: "radar_chart",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ legendList: [],
|
|
|
+ defaultLegendList: [],
|
|
|
+ showBarLegendIndex: 1,
|
|
|
+ questionList: [], // 题目列表
|
|
|
+ questionTableList: [], // 小题分析table
|
|
|
+ groupList: [], // 分组题目列表
|
|
|
+ groupTableList: [], // 分组table
|
|
|
+ headerList: [],
|
|
|
+ changeHeaderList: [],
|
|
|
+ childHeaderList: [],
|
|
|
+ questionListIndex: 0, //题目 索引
|
|
|
+ data: [], //柱状图
|
|
|
+ }, //小题分析数据
|
|
|
+ majorQuestionData: {
|
|
|
+ chartType: "line_bar_chart", //默认显示折线图柱状图line_bar_chart
|
|
|
+ legendList: [],
|
|
|
+ defaultLegendList: [],
|
|
|
+ showBarLegendIndex: 1,
|
|
|
+ questionListIndex: 0, //题目 索引
|
|
|
+ data: [], //柱状图
|
|
|
+ }, //分组题目 对应的题目列表
|
|
|
+ questionScoreStatsData: {
|
|
|
+ checked: false,
|
|
|
+ isIndeterminate: true,
|
|
|
+ markLineData: [], //平均分
|
|
|
+ chartTypeList: [
|
|
|
+ {
|
|
|
+ label: "柱状图",
|
|
|
+ value: "vertical_bar",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "率差图",
|
|
|
+ value: "difference_chart",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ chartType: "vertical_bar", //默认显示率差图vertical_bar
|
|
|
+ datax: [], //x轴数据
|
|
|
+ datay: [], //Y轴数据
|
|
|
+ dataStackY: [], //Y轴数据
|
|
|
+ tooltipData: [], //
|
|
|
+ rate: 60, //中间x的刻度线的值 数字类型
|
|
|
+ maxClass: "", // 得分率最高班
|
|
|
+ minClass: "", // 得分率最低班
|
|
|
+ }, //小题分析 /第N题
|
|
|
+ questionAnswerData: {
|
|
|
+ datax: [], //x轴数据
|
|
|
+ datay: [], //Y轴数据
|
|
|
+ color: "#5470C6",
|
|
|
+ answerValue: "", //正确答案 柱状图显示绿色
|
|
|
+ answerScore: [], //答案所能得的分数
|
|
|
+ questionType: "", //类型
|
|
|
+ fullMark: "", //满分
|
|
|
+ // average:0,//平均分辅助线
|
|
|
+ tableData: [],
|
|
|
+ classListIndex: 0, // 索引
|
|
|
+ }, //小题分析 /第N题 / N班
|
|
|
+ majorAnswerData: {
|
|
|
+ paperUrl: "", //试卷地址
|
|
|
+ tableData: [], //表格数据
|
|
|
+ rowIndex: 0,
|
|
|
+ }, // 通过答案或者分数查询某题作答情况
|
|
|
+ majorStudentData: {
|
|
|
+ tableData: [],
|
|
|
+ legendList: [],
|
|
|
+ radarChartData: [],
|
|
|
+ excellentCourseList: "", //优秀科目
|
|
|
+ inferiorCourseList: "", //弱势科目
|
|
|
+ }, //科目得分率
|
|
|
+ majorTableData: {
|
|
|
+ tableKey: 0,
|
|
|
+ tableData: [], //小题分析表数据
|
|
|
+ allTableData: [],
|
|
|
+ headerData: [], //固定表头数据
|
|
|
+ changeHeaderData: [], //动态表头数据
|
|
|
+ childHeaderData: [], //子级表头数据
|
|
|
+ pageSize: 10, //每页显示数据
|
|
|
+ total: 0, //总数
|
|
|
+ currentPage: 1, //当前页
|
|
|
+ }, //小题分析表 + 题目分组分析
|
|
|
+ errorQuestionData: {
|
|
|
+ tableKey: 0,
|
|
|
+ allData: [], //
|
|
|
+ gradeValue: "", //选中的年级
|
|
|
+ className: "", //选中的年级名称
|
|
|
+ type: "",
|
|
|
+ gradeData: [], //年级下拉选项
|
|
|
+ tableData: [], //错题分析表数据
|
|
|
+ }, //错题分析表
|
|
|
+ studentPreviousExamData: {
|
|
|
+ data: null,
|
|
|
+ chartType: "line_chart",
|
|
|
+ selectList: [
|
|
|
+ {
|
|
|
+ value: "standardScore",
|
|
|
+ name: "标准分",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: "scoreRate",
|
|
|
+ name: "得分率",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: "classRank",
|
|
|
+ name: "班排",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: "schoolRank",
|
|
|
+ name: "校排",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: "examRank",
|
|
|
+ name: "联排",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ selectVal: "standardScore",
|
|
|
+ selectName: "标准分",
|
|
|
+ lineChartData: {
|
|
|
+ datax: [],
|
|
|
+ datay: [],
|
|
|
+ title: [],
|
|
|
+ tooltipData: [],
|
|
|
+ },
|
|
|
+ barChartData: {
|
|
|
+ //柱状图
|
|
|
+ legendList: [],
|
|
|
+ data: [],
|
|
|
+ },
|
|
|
+ }, //学生成绩历次考试分析数据
|
|
|
+ groupPrevious: {
|
|
|
+ loading: false,
|
|
|
+ examNameList: [],
|
|
|
+ examChartList: [],
|
|
|
+ selectedLegendList: [],
|
|
|
+ examChartIndex: [],
|
|
|
+ headerList: [],
|
|
|
+ dataList: [],
|
|
|
+ }, //题目分组历次分析(图表数据)
|
|
|
+ stuGroupPreviousChart: {
|
|
|
+ examNameList: [],
|
|
|
+ examChartList: [],
|
|
|
+ examChartIndex: [],
|
|
|
+ }, //学生组块历次图
|
|
|
+ stuGroupPreviousChartStuInfo: {
|
|
|
+ studentName: "", //学生姓名搜索条件
|
|
|
+ studentCodeList: [],
|
|
|
+ }, //学生历次分析图 搜索学生信息
|
|
|
+ stuGroupPrevious: {
|
|
|
+ total: 0,
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ headerList: [],
|
|
|
+ tableList: [],
|
|
|
+ }, //题目分组历次分析学生数据表(分页)
|
|
|
+ classNameList: [],
|
|
|
+ showHeaderSet: false, //是否显示设置表头
|
|
|
+ showBenchTaskSelect: false, //历次考试弹框
|
|
|
+ exportLoading: false, // 题型导出loading
|
|
|
+ exportErrorLoading: false, // 错题导出loading
|
|
|
+ chartKey: 0,
|
|
|
+
|
|
|
+ dataLoading: false,
|
|
|
+ loadingText: "加载中,请稍后……",
|
|
|
+
|
|
|
+ errorPdfLoading: false, //错题导出PDF loading
|
|
|
+ paperInfo: {
|
|
|
+ examPaperId: "", //考试科目id
|
|
|
+ platformNumber: "", //学籍号平台号
|
|
|
+ questionId: "", //题目id
|
|
|
+ }, //学生试卷信息
|
|
|
+ paperTitle: "", //学生试卷标题
|
|
|
+ showStudentPaperDialog: false, //是否显示学生答题卡弹窗
|
|
|
+ paperInfos: {
|
|
|
+ examPaperId: "", //考试科目id
|
|
|
+ platformNumber: "", //学籍号平台号
|
|
|
+ questionId: "", //题目id
|
|
|
},
|
|
|
- {
|
|
|
- date: '2016-05-04',
|
|
|
- name: 'Tom',
|
|
|
- address: 'No. 189, Grove St, Los Angeles',
|
|
|
+ knowledgeInputDialog: false,
|
|
|
+ dialogData: {
|
|
|
+ apiName: "",
|
|
|
+ showDialog: false,
|
|
|
+ title: "",
|
|
|
+ tableTitle: "",
|
|
|
+ fiveRateName: "", //当前选择的五率的名称
|
|
|
+ selectSubjectName: "", //当前选择的科目名称
|
|
|
+ selectSchoolLevel: "", //当前选择的学校级别:0-联考 1-学校分组 2-具体学校
|
|
|
+ selectSchoolName: "", //当前选择的学校名称:联校 组合学校 单校名称
|
|
|
+ selectClassLevel: "", //当前选择的班级级别:0-年级 1-组合班级 2-具体班级
|
|
|
+ selectClassName: "", //当前选择的班级名称:年级 组合班级 单班
|
|
|
+ questionId: "", //试题ID
|
|
|
+ isPaper: "", //是否为全卷0-非1-是全卷
|
|
|
+ quesScoreType: "", //选择的类型0-满分人数 1-0分人数 3-优秀率、良好率等
|
|
|
+ knowledgeId: "", //如果选择的是知识点,则需要返回知识点ID
|
|
|
+ questionGroupName: "", //试题分组的名称
|
|
|
+ groupTitle: "",
|
|
|
},
|
|
|
- {
|
|
|
- date: '2016-05-01',
|
|
|
- name: 'Tom',
|
|
|
- address: 'No. 189, Grove St, Los Angeles',
|
|
|
+ showQuestionCardDialog: false,
|
|
|
+ cardQuestionId: "", // 批量查看答题卡试题id
|
|
|
+ cardRegistrationCodeList: [], // 批量查看答题卡学生账号数组
|
|
|
+});
|
|
|
+const majorTable = ref(null);
|
|
|
+//排序
|
|
|
+const ChangeChartOrder = (sortType, legendData, barIndex, number) => {
|
|
|
+ const isHasEstimatedScore = state.problemAnalysisData.headerList.find(
|
|
|
+ (item) => item.prop == "estimatedScore",
|
|
|
+ ); //是否存在预估满分
|
|
|
+ const fullVolume = state.problemAnalysisData.questionList.filter(
|
|
|
+ (item) => item.showCode == 999,
|
|
|
+ ); //全卷
|
|
|
+ const questionList = state.problemAnalysisData.questionList.filter(
|
|
|
+ (item) => item.showCode != 999,
|
|
|
+ );
|
|
|
+ const newBarIndex = isHasEstimatedScore ? barIndex - 1 : barIndex;
|
|
|
+ if (sortType == "2") {
|
|
|
+ //从低到高
|
|
|
+ questionList.sort(function (a, b) {
|
|
|
+ return (
|
|
|
+ (a?.classList?.[newBarIndex]?.questionStats?.scoreRate || 0) -
|
|
|
+ (b?.classList?.[newBarIndex]?.questionStats?.scoreRate || 0)
|
|
|
+ );
|
|
|
+ });
|
|
|
+ } else if (sortType == "3") {
|
|
|
+ //从高到低
|
|
|
+ questionList.sort(function (a, b) {
|
|
|
+ return (
|
|
|
+ (b?.classList?.[newBarIndex]?.questionStats?.scoreRate || 0) -
|
|
|
+ (a?.classList?.[newBarIndex]?.questionStats?.scoreRate || 0)
|
|
|
+ );
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ //默认排序 按题号排序
|
|
|
+ questionList.sort(function (a, b) {
|
|
|
+ return (a?.showCode || 0) - (b.showCode || 0);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ state.problemAnalysisData.questionList = [...questionList, ...fullVolume];
|
|
|
+ let chartData = [],
|
|
|
+ chartTitle = [];
|
|
|
+ state.problemAnalysisData.questionList.forEach((ques) => {
|
|
|
+ const scoreRateArr = ques.classList.map(
|
|
|
+ (item) => item?.questionStats?.scoreRate || 0,
|
|
|
+ );
|
|
|
+ if (isHasEstimatedScore) {
|
|
|
+ chartData.push([
|
|
|
+ ques.questionName,
|
|
|
+ ques.estimatedScoreRate,
|
|
|
+ ...scoreRateArr,
|
|
|
+ ]);
|
|
|
+ } else {
|
|
|
+ chartData.push([ques.questionName, ...scoreRateArr]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const newChangeHeaderList = isHasEstimatedScore
|
|
|
+ ? [
|
|
|
+ { ...isHasEstimatedScore, isG: false, type: 1 },
|
|
|
+ ...state.problemAnalysisData.changeHeaderList,
|
|
|
+ ]
|
|
|
+ : [...state.problemAnalysisData.changeHeaderList];
|
|
|
+ newChangeHeaderList.forEach((item) => {
|
|
|
+ chartTitle.push(item.label);
|
|
|
+ });
|
|
|
+ chartTitle.unshift("group");
|
|
|
+ chartData.unshift(chartTitle); // 柱状图 图例标题
|
|
|
+ chartData.pop(); // 删除最后一行 全卷
|
|
|
+ state.problemAnalysisData.data = chartData;
|
|
|
+ state.problemAnalysisData.legendList = legendData;
|
|
|
+ //小题分析 /第N题
|
|
|
+ GetQuestionStatsData(0);
|
|
|
+};
|
|
|
+//试题图表切换公共方法
|
|
|
+const ChangeEchartType = (value, prop) => {
|
|
|
+ if (prop == "problemAnalysisData") {
|
|
|
+ ChangeChartOrder("1", state.problemAnalysisData.defaultLegendList, "", 1);
|
|
|
+ }
|
|
|
+ state[prop].chartType = value;
|
|
|
+};
|
|
|
+//获取小题分析数据
|
|
|
+const GetQuestionAnalysisData = () => {
|
|
|
+ state.problemAnalysisData.data = []; //柱状图折线图 X轴
|
|
|
+ state.dataLoading = true;
|
|
|
+ questionAnalysis({
|
|
|
+ ...analysisStore.filterObject,
|
|
|
+ analysisType: 0, //0-小题分析 1大题分析 2-知识点 3-能力点 question_group_code(4,5,6,7,8) 11-题型分析
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ if (
|
|
|
+ res.code == 200 &&
|
|
|
+ res.data &&
|
|
|
+ res.data.questionList &&
|
|
|
+ res.data.questionList.length
|
|
|
+ ) {
|
|
|
+ const { data } = res;
|
|
|
+ const questionList = data.questionList || [];
|
|
|
+ const changeHeaderList = data.changeHeaderList || []; //柱状图折线图 班级名称
|
|
|
+ state.problemAnalysisData.groupList = [];
|
|
|
+ state.problemAnalysisData.groupTableList = [];
|
|
|
+ state.problemAnalysisData.questionList = questionList;
|
|
|
+ state.problemAnalysisData.questionTableList = cloneDeep(questionList);
|
|
|
+ state.problemAnalysisData.headerList = data.headerList || [];
|
|
|
+ state.problemAnalysisData.changeHeaderList = changeHeaderList;
|
|
|
+ state.problemAnalysisData.childHeaderList = data.childHeaderList || [];
|
|
|
+
|
|
|
+ state.chartKey++;
|
|
|
+ //Y轴数据
|
|
|
+ let chartData = [];
|
|
|
+ let legendList = [];
|
|
|
+ const isHasEstimatedScore = state.problemAnalysisData.headerList.find(
|
|
|
+ (item) => item.prop == "estimatedScore",
|
|
|
+ ); //是否存在预估满分
|
|
|
+ chartData = questionList.map((item) => {
|
|
|
+ return isHasEstimatedScore
|
|
|
+ ? [item.questionName, item.estimatedScoreRate]
|
|
|
+ : [item.questionName];
|
|
|
+ });
|
|
|
+ questionList.forEach((ques, key) => {
|
|
|
+ const scoreRateArr = ques.classList.map(
|
|
|
+ (item) => item?.questionStats?.scoreRate || 0,
|
|
|
+ );
|
|
|
+ chartData[key].push(...scoreRateArr);
|
|
|
+ });
|
|
|
+ let chartTitle = [],
|
|
|
+ titleType = [],
|
|
|
+ classSelectLegend = [];
|
|
|
+ const newChangeHeaderList = isHasEstimatedScore
|
|
|
+ ? [
|
|
|
+ { ...isHasEstimatedScore, isG: false, type: 1 },
|
|
|
+ ...changeHeaderList,
|
|
|
+ ]
|
|
|
+ : [...changeHeaderList];
|
|
|
+ newChangeHeaderList.forEach((item) => {
|
|
|
+ chartTitle.push(item.label);
|
|
|
+ titleType.push(item.type ? item.type : ""); //1柱状图 2折线
|
|
|
+ if (
|
|
|
+ item.prop != "0" &&
|
|
|
+ item.prop != "estimatedScore" &&
|
|
|
+ item.prop.indexOf("school_group") == -1
|
|
|
+ ) {
|
|
|
+ classSelectLegend.push(item.label);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ chartTitle.unshift("group");
|
|
|
+ if (analysisStore.filterObject.classLevel != 2) {
|
|
|
+ //0 年级 1 组合班级 2具体班级
|
|
|
+ let startIndex = 1,
|
|
|
+ endIndex = 3;
|
|
|
+ if (analysisStore.filterObject.schoolLevel == 2) {
|
|
|
+ //0-联考 1-学校分组 2-具体学校
|
|
|
+ startIndex =
|
|
|
+ titleType.lastIndexOf(1) > -1 ? titleType.lastIndexOf(1) + 1 : 1;
|
|
|
+ endIndex = titleType.indexOf(2) > -1 ? titleType.indexOf(2) + 2 : 3; //单校时显示联校、组合校、年级是柱子;班级组合、班级是折线。
|
|
|
+ } else {
|
|
|
+ //联校 组合学校 默认当前的为第一个选中的柱子
|
|
|
+ const barFirtIndex =
|
|
|
+ titleType.lastIndexOf(1) > -1 ? titleType.lastIndexOf(1) + 1 : 1;
|
|
|
+ startIndex = barFirtIndex;
|
|
|
+ endIndex = barFirtIndex + 2;
|
|
|
+ }
|
|
|
+ legendList =
|
|
|
+ chartTitle.length > 1 ? chartTitle.slice(startIndex, endIndex) : [];
|
|
|
+ state.problemAnalysisData.showBarLegendIndex = endIndex - 2;
|
|
|
+ } else {
|
|
|
+ //单班 联校和组合学校不默认显示
|
|
|
+ legendList = classSelectLegend;
|
|
|
+ state.problemAnalysisData.showBarLegendIndex =
|
|
|
+ changeHeaderList.length - 1;
|
|
|
+ }
|
|
|
+ chartData.unshift(chartTitle); // 柱状图 图例标题
|
|
|
+ chartData.pop(); // 删除最后一行 全卷
|
|
|
+ state.problemAnalysisData.data = chartData;
|
|
|
+ state.problemAnalysisData.legendList = legendList;
|
|
|
+ state.problemAnalysisData.defaultLegendList = cloneDeep(legendList);
|
|
|
+ //小题分析 /第N题
|
|
|
+ GetQuestionStatsData(0);
|
|
|
+ // 获取项目分析表
|
|
|
+ GetMajorTableData();
|
|
|
+ } else {
|
|
|
+ state.problemAnalysisData.groupList = [];
|
|
|
+ state.problemAnalysisData.groupTableList = [];
|
|
|
+ state.problemAnalysisData.questionList = [];
|
|
|
+ state.problemAnalysisData.questionTableList = [];
|
|
|
+ state.problemAnalysisData.showBarLegendIndex = 1;
|
|
|
+ state.problemAnalysisData.headerList = [];
|
|
|
+ state.problemAnalysisData.changeHeaderList = [];
|
|
|
+ state.problemAnalysisData.childHeaderList = [];
|
|
|
+
|
|
|
+ state.majorQuestionData.data = [];
|
|
|
+ state.majorQuestionData.legendList = [];
|
|
|
+
|
|
|
+ state.questionScoreStatsData.datax = [];
|
|
|
+ state.questionScoreStatsData.datay = [];
|
|
|
+ state.questionScoreStatsData.dataStackY = [];
|
|
|
+ state.questionScoreStatsData.tooltipData = [];
|
|
|
+ state.questionScoreStatsData.rate = 0;
|
|
|
+ state.questionScoreStatsData.maxClass = "";
|
|
|
+ state.questionScoreStatsData.minClass = "";
|
|
|
+
|
|
|
+ state.questionAnswerData.datax = [];
|
|
|
+ state.questionAnswerData.datay = [];
|
|
|
+ state.questionAnswerData.answerValue = "";
|
|
|
+ state.questionAnswerData.answerScore = [];
|
|
|
+ state.questionAnswerData.questionType = "";
|
|
|
+ state.questionAnswerData.fullMark = "";
|
|
|
+ state.questionAnswerData.tableData = [];
|
|
|
+ state.questionAnswerData.classListIndex = 0;
|
|
|
+
|
|
|
+ state.majorAnswerData.tableData = [];
|
|
|
+ state.majorAnswerData.paperUrl = "";
|
|
|
+ state.majorAnswerData.rowIndex = 0;
|
|
|
+
|
|
|
+ state.majorStudentData.tableData = [];
|
|
|
+ state.majorStudentData.legendList = [];
|
|
|
+ state.majorStudentData.radarChartData = [];
|
|
|
+ state.majorStudentData.excellentCourseList = "";
|
|
|
+ state.majorStudentData.inferiorCourseList = "";
|
|
|
+
|
|
|
+ state.majorTableData.tableData = [];
|
|
|
+ state.majorTableData.headerData = [];
|
|
|
+ state.majorTableData.changeHeaderData = [];
|
|
|
+ state.majorTableData.childHeaderData = [];
|
|
|
+ state.majorTableData.pageSize = 10;
|
|
|
+ state.majorTableData.total = 0;
|
|
|
+ state.majorTableData.currentPage = 1;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ state.dataLoading = false;
|
|
|
+ });
|
|
|
+};
|
|
|
+// 点击柱状图折线图
|
|
|
+const HandleChartClick = (index, name) => {
|
|
|
+ GetQuestionStatsData(index); //小题分析
|
|
|
+};
|
|
|
+// 获取小题分析 /第N题
|
|
|
+const GetQuestionStatsData = (index) => {
|
|
|
+ const questionData = cloneDeep(state.problemAnalysisData.questionList[index]);
|
|
|
+ state.problemAnalysisData.questionListIndex = index;
|
|
|
+ state.questionTitle = questionData?.questionName || "";
|
|
|
+ if (questionData) {
|
|
|
+ state.questionScoreStatsData.datax = []; // x轴数据
|
|
|
+ state.questionScoreStatsData.datay = []; // Y轴数据
|
|
|
+ state.questionScoreStatsData.dataStackY = []; // Y轴数据
|
|
|
+ state.questionScoreStatsData.tooltipData = []; // 提示框内容
|
|
|
+ let dataStackY = [];
|
|
|
+ const isHasEstimatedScore = state.problemAnalysisData.headerList.find(
|
|
|
+ (item) => item.prop == "estimatedScore",
|
|
|
+ ); //是否存在预估满分
|
|
|
+ if (questionData.classList.length > 1) {
|
|
|
+ const key = state.problemAnalysisData.showBarLegendIndex;
|
|
|
+ state.questionScoreStatsData.markLineData = []; //辅助线
|
|
|
+ const classList = questionData?.classList || [];
|
|
|
+ if (
|
|
|
+ analysisStore.filterObject.classLevel == 0 ||
|
|
|
+ analysisStore.filterObject.classLevel == 1
|
|
|
+ ) {
|
|
|
+ //0 年级 1 组合班级 2具体班级
|
|
|
+ state.questionScoreStatsData.rate = Number(
|
|
|
+ classList?.[key - 1]?.questionStats?.scoreRate || 0,
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ state.questionScoreStatsData.rate = Number(
|
|
|
+ classList?.[key]?.questionStats?.scoreRate || 0,
|
|
|
+ );
|
|
|
+ }
|
|
|
+ //辅助线
|
|
|
+ classList.forEach((item, index) => {
|
|
|
+ const keyIndex =
|
|
|
+ analysisStore.filterObject.classLevel == 0 ||
|
|
|
+ analysisStore.filterObject.classLevel == 1
|
|
|
+ ? key - (isHasEstimatedScore ? 2 : 1)
|
|
|
+ : key;
|
|
|
+ if (index <= keyIndex) {
|
|
|
+ const rate = Number(item?.questionStats?.scoreRate || 0);
|
|
|
+ state.questionScoreStatsData.markLineData.push({
|
|
|
+ legendName: item.groupName,
|
|
|
+ value: rate,
|
|
|
+ isShow: index == keyIndex ? true : false, //是否显示
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ questionData.classList = questionData.classList.slice(
|
|
|
+ isHasEstimatedScore ? key - 1 : key,
|
|
|
+ ); // 取折线图数据
|
|
|
+ } else {
|
|
|
+ state.questionScoreStatsData.rate = 60;
|
|
|
+ }
|
|
|
+
|
|
|
+ questionData.classList.forEach((item) => {
|
|
|
+ state.questionScoreStatsData.datax.push(item.groupName);
|
|
|
+ state.questionScoreStatsData.datay.push(item.questionStats.scoreRate);
|
|
|
+ dataStackY.push(item.questionStats.lossRate);
|
|
|
+ state.questionScoreStatsData.tooltipData.push({
|
|
|
+ list: [
|
|
|
+ {
|
|
|
+ name: "失分率",
|
|
|
+ value: `${item.questionStats.lossRate}%`,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ });
|
|
|
+ });
|
|
|
+ // 获取最大值
|
|
|
+ const max = Math.max(...state.questionScoreStatsData.datay);
|
|
|
+ // 获取最小值
|
|
|
+ const min = Math.min(...state.questionScoreStatsData.datay);
|
|
|
+ const maxValue = max.toFixed(2);
|
|
|
+ const minValue = min.toFixed(2);
|
|
|
+
|
|
|
+ let maxClass = [],
|
|
|
+ minClass = [];
|
|
|
+ state.questionScoreStatsData.datay.forEach((item, index) => {
|
|
|
+ if (Number(item) == Number(maxValue)) {
|
|
|
+ maxClass.push(state.questionScoreStatsData.datax[index]);
|
|
|
+ }
|
|
|
+ if (Number(item) == Number(minValue)) {
|
|
|
+ minClass.push(state.questionScoreStatsData.datax[index]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ state.questionScoreStatsData.minClass = minClass.join("、");
|
|
|
+ state.questionScoreStatsData.maxClass = maxClass.join("、");
|
|
|
+ state.questionScoreStatsData.dataStackY = [
|
|
|
+ state.questionScoreStatsData.datay,
|
|
|
+ dataStackY,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ console.log("打印questionScoreStatsData1111", state.questionScoreStatsData);
|
|
|
+ // 获取小题分析 /第N题 / 第N班
|
|
|
+ GetQuestionAnswerData(state.problemAnalysisData.showBarLegendIndex);
|
|
|
+};
|
|
|
+//切换 获取小题分析 /第N题 获取第N班答题列表
|
|
|
+const HandleQuestionScoreChartClick = (index) => {
|
|
|
+ GetQuestionAnswerData(index + state.problemAnalysisData.showBarLegendIndex);
|
|
|
+};
|
|
|
+// 获取小题分析 /第N题 / 第N班 选项
|
|
|
+const GetQuestionAnswerData = (index) => {
|
|
|
+ const isHasEstimatedScore = state.problemAnalysisData.headerList.find(
|
|
|
+ (item) => item.prop == "estimatedScore",
|
|
|
+ ); //是否存在预估满分
|
|
|
+ const newINdex = isHasEstimatedScore ? index - 1 : index;
|
|
|
+ const classList =
|
|
|
+ state.problemAnalysisData.questionList?.[
|
|
|
+ state.problemAnalysisData.questionListIndex
|
|
|
+ ]?.classList?.[newINdex];
|
|
|
+ // console.log("打印获取小题分析班级列表",classList)
|
|
|
+ state.questionAnswerData.answerValue =
|
|
|
+ state.problemAnalysisData.questionList[
|
|
|
+ state.problemAnalysisData.questionListIndex
|
|
|
+ ].answerValue; //正确答案
|
|
|
+
|
|
|
+ state.questionAnswerData.questionType =
|
|
|
+ state.problemAnalysisData.questionList[
|
|
|
+ state.problemAnalysisData.questionListIndex
|
|
|
+ ].questionType; //类型
|
|
|
+ state.questionAnswerData.fullMark =
|
|
|
+ state.problemAnalysisData.questionList[
|
|
|
+ state.problemAnalysisData.questionListIndex
|
|
|
+ ].fullMark; //满分
|
|
|
+
|
|
|
+ state.questionAnswerData.classListIndex = newINdex;
|
|
|
+ if (classList) {
|
|
|
+ const answerList = classList.questionStats.answerList || [];
|
|
|
+ state.classTitle = classList.groupName;
|
|
|
+ state.questionAnswerData.datax = []; // x轴数据
|
|
|
+ state.questionAnswerData.datay = []; // Y轴数据
|
|
|
+ let sum = 0;
|
|
|
+ answerList.forEach((item) => {
|
|
|
+ sum += item.studentNum;
|
|
|
+ state.questionAnswerData.datax.push(item.name);
|
|
|
+ state.questionAnswerData.datay.push(item.studentNum);
|
|
|
+ state.questionAnswerData.answerScore.push(item.score);
|
|
|
+ });
|
|
|
+ state.questionAnswerData.tableData = [
|
|
|
+ {
|
|
|
+ title: "得分率",
|
|
|
+ value: `${classList.questionStats.scoreRate}%`,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "平均分",
|
|
|
+ value: `${classList.questionStats.averageScore}`,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "最高分",
|
|
|
+ value: `${classList.questionStats.maxScore}`,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "最低分",
|
|
|
+ value: `${classList.questionStats.minScore}`,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "人数",
|
|
|
+ value: `${sum}人`,
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ if (analysisStore.filterObject.schoolLevel == 2) {
|
|
|
+ //单校时展示
|
|
|
+ // 获取答题情况
|
|
|
+ GetAnswerListByAnswerAndScore(
|
|
|
+ 0,
|
|
|
+ answerList && answerList[0] ? answerList[0].name : "",
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+// 点击柱状图小题分析 /第N题 / 第N班 选项 获取答题情况
|
|
|
+const HandleQuestionAnswerChartClick = (index, name) => {
|
|
|
+ if (analysisStore.filterObject.schoolLevel == 2) {
|
|
|
+ //单校时展示
|
|
|
+ GetAnswerListByAnswerAndScore(index, name);
|
|
|
+ }
|
|
|
+};
|
|
|
+//通过答案或者分数查询某题作答情况
|
|
|
+const GetAnswerListByAnswerAndScore = (index, name) => {
|
|
|
+ state.optionTitle = name; //选项名称
|
|
|
+ const question =
|
|
|
+ state.problemAnalysisData.questionList[
|
|
|
+ state.problemAnalysisData.questionListIndex
|
|
|
+ ];
|
|
|
+ const classItem = question.classList[state.questionAnswerData.classListIndex];
|
|
|
+ const classItemKeys = Object.keys(classItem);
|
|
|
+ const reportParam = {
|
|
|
+ ...analysisStore.filterObject,
|
|
|
+ };
|
|
|
+ Object.keys(analysisStore.filterObject).forEach((item) => {
|
|
|
+ if (classItemKeys.indexOf(item) > -1) {
|
|
|
+ reportParam[item] = classItem[item];
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const answer =
|
|
|
+ question.classList[state.questionAnswerData.classListIndex].questionStats
|
|
|
+ .answerList[index];
|
|
|
+ const params = {
|
|
|
+ ...reportParam,
|
|
|
+ questionId: question.questionId, // 试题id
|
|
|
+ registrationCodeList: answer?.registrationCodeList || [], // 学生账号数组
|
|
|
+ };
|
|
|
+ state.cardQuestionId = params.questionId; // 批量查看答题卡试题id
|
|
|
+ state.cardRegistrationCodeList = params.registrationCodeList; // 批量查看答题卡学生账号数组
|
|
|
+ queryAnswerListByAnswerAndScore(params).then((res) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ state.majorAnswerData.tableData = res.data || [];
|
|
|
+ } else {
|
|
|
+ state.majorAnswerData.tableData = [];
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+// 获取项目分析表
|
|
|
+const GetMajorTableData = () => {
|
|
|
+ state.majorTableData.tableKey += 1;
|
|
|
+ state.majorTableData.headerData = state.problemAnalysisData.headerList;
|
|
|
+ state.majorTableData.changeHeaderData =
|
|
|
+ state.problemAnalysisData.changeHeaderList;
|
|
|
+ state.majorTableData.childHeaderData =
|
|
|
+ state.problemAnalysisData.childHeaderList;
|
|
|
+ const headerPropData = state.problemAnalysisData.headerList.map(
|
|
|
+ (item) => item.prop,
|
|
|
+ ); //表头字段名
|
|
|
+ const childHeaderPropData = state.problemAnalysisData.childHeaderList.map(
|
|
|
+ (item) => item.prop,
|
|
|
+ ); //动态表头字段名
|
|
|
+ let allTableData = [];
|
|
|
+ const allList = state.problemAnalysisData.questionTableList;
|
|
|
+ allList.forEach((item) => {
|
|
|
+ let itemObj = {
|
|
|
+ questionId: item?.questionId || "",
|
|
|
+ knowledgeId: item?.knowledgeId || "",
|
|
|
+ };
|
|
|
+ const classList = item.classList;
|
|
|
+ headerPropData.forEach((title) => {
|
|
|
+ itemObj[title] = Array.isArray(item[title])
|
|
|
+ ? item[title].join("、")
|
|
|
+ : item[title];
|
|
|
+ });
|
|
|
+
|
|
|
+ classList.forEach((el) => {
|
|
|
+ if (
|
|
|
+ el.questionStats?.headDataBOList &&
|
|
|
+ el.questionStats.headDataBOList.length > 0
|
|
|
+ ) {
|
|
|
+ el.questionStats.headDataBOList.forEach((bo) => {
|
|
|
+ el.questionStats[`${bo.name}Rate`] = bo.rate;
|
|
|
+ el.questionStats[`${bo.name}StudentNumber`] = bo.studentNumber;
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ el.questionStats = [];
|
|
|
+ }
|
|
|
+ childHeaderPropData.forEach((field) => {
|
|
|
+ itemObj[`${el.groupId}_${field}`] = el.questionStats[field];
|
|
|
+ });
|
|
|
+ });
|
|
|
+ allTableData.push(itemObj);
|
|
|
+ });
|
|
|
+ state.majorTableData.total = allTableData.length; //总条数
|
|
|
+ state.majorTableData.allTableData = allTableData;
|
|
|
+ GetPageMajorTableData();
|
|
|
+ //重置表格滚动条位置
|
|
|
+ ResetTableScroll(); //重置表格滚动条位置
|
|
|
+};
|
|
|
+const GetPageMajorTableData = () => {
|
|
|
+ const start =
|
|
|
+ (state.majorTableData.currentPage - 1) * state.majorTableData.pageSize;
|
|
|
+ const end = start + state.majorTableData.pageSize;
|
|
|
+ state.majorTableData.tableData = state.majorTableData.allTableData.slice(
|
|
|
+ start,
|
|
|
+ end,
|
|
|
+ );
|
|
|
+};
|
|
|
+//重置表格滚动条位置
|
|
|
+const ResetTableScroll = () => {
|
|
|
+ nextTick(() => {
|
|
|
+ if (majorTable.value) {
|
|
|
+ const tableBody = majorTable.value.querySelector(
|
|
|
+ ".el-table__body-wrapper",
|
|
|
+ );
|
|
|
+ if (tableBody) {
|
|
|
+ tableBody.scrollTop = 0; //清除纵向滚动条位置
|
|
|
+ tableBody.scrollLeft = 0; // 清除横向滚动条位置
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+const handleCurrentChange = (val) => {
|
|
|
+ state.majorTableData.currentPage = val;
|
|
|
+ GetMajorTableData(); //加载分析表格数据
|
|
|
+};
|
|
|
+const handleSizeChange = (val: number) => {
|
|
|
+ state.majorTableData.pageSize = val;
|
|
|
+ state.majorTableData.currentPage = 1;
|
|
|
+ GetMajorTableData(); //加载分析表格数据
|
|
|
+}
|
|
|
+//设置表头样式
|
|
|
+const HeaderRowStyle = ({ row, rowIndex }) => {
|
|
|
+ if (rowIndex === 1) {
|
|
|
+ return {
|
|
|
+ display: "none",
|
|
|
+ };
|
|
|
+ }
|
|
|
+};
|
|
|
+const pageInit = () => {
|
|
|
+ state.problemAnalysisData.chartTypeList =
|
|
|
+ analysisStore.filterObject.classLevel != 2
|
|
|
+ ? [
|
|
|
+ {
|
|
|
+ label: "组合图",
|
|
|
+ value: "line_bar_chart",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "柱状图",
|
|
|
+ value: "vertical_bar",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "雷达图",
|
|
|
+ value: "radar_chart",
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ : [
|
|
|
+ {
|
|
|
+ label: "柱状图",
|
|
|
+ value: "vertical_bar",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "雷达图",
|
|
|
+ value: "radar_chart",
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ state.problemAnalysisData.chartType =
|
|
|
+ analysisStore.filterObject.classLevel != 2
|
|
|
+ ? "line_bar_chart"
|
|
|
+ : "vertical_bar";
|
|
|
+ state.questionScoreStatsData.chartType = "vertical_bar";
|
|
|
+ state.majorTableData.currentPage = 1;
|
|
|
+ state.majorAnswerData.rowIndex = 0;
|
|
|
+ state.studentPreviousExamData.selectVal = "standardScore";
|
|
|
+ state.studentPreviousExamData.selectName = "标准分";
|
|
|
+ GetQuestionAnalysisData(); //获取小题分析数据
|
|
|
+};
|
|
|
+// 监听筛选条件
|
|
|
+watch(
|
|
|
+ () => analysisStore.filterObject,
|
|
|
+ async () => {
|
|
|
+ pageInit();
|
|
|
},
|
|
|
-]
|
|
|
-const state = reactive({
|
|
|
- keyWord: '',
|
|
|
- checkList: ['group']
|
|
|
+ { deep: true },
|
|
|
+);
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ pageInit();
|
|
|
});
|
|
|
-onMounted(() => { });
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.input_with {
|
|
|
- margin-right: 10px;
|
|
|
+.content_left {
|
|
|
+ &.answer {
|
|
|
+ width: calc(100% - 220px);
|
|
|
+ }
|
|
|
+
|
|
|
+ &.card {
|
|
|
+ width: calc(100% - 480px);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-.count_item {
|
|
|
- font-weight: 400;
|
|
|
- font-size: 16px;
|
|
|
- color: #333333;
|
|
|
- line-height: 24px;
|
|
|
- margin-left: 10px;
|
|
|
+.content_right {
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin: auto;
|
|
|
+ padding-bottom: 0;
|
|
|
|
|
|
- &.orange {
|
|
|
- color: #FB9F34;
|
|
|
+ &.answer {
|
|
|
+ width: 200px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.card {
|
|
|
+ width: 460px;
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-.checkbox_group {
|
|
|
- :deep(.el-checkbox) {
|
|
|
- margin-right: 10px;
|
|
|
+ :deep(.el-table) {
|
|
|
+ border-left: 0px;
|
|
|
+ border-right: 0px;
|
|
|
|
|
|
- &:nth-child(1) {
|
|
|
- margin-right: 20px;
|
|
|
+ .el-table__cell {
|
|
|
+ height: 44px;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-</style>
|
|
|
+</style>
|