testSummaryReport.vue 10.6 KB
<template>
    <div style="margin-right: 20px;width: 100%">
        <el-row class="row-type">
            <div style="float: right;">
                <el-button type="primary" @click="_export" icon="el-icon-upload2" class="opration-btn">导出报表</el-button>
                <el-button type="primary" @click="_print" icon="el-icon-printer" class="opration-btn">打印报表</el-button>
            </div>
        </el-row>
        <div id="print-content">
            <el-row class="row-table">
                <el-table border class="default-table" :data="stageReport" style="width: 100%">
                    <el-table-column prop="studentCode" label="学号" fixed></el-table-column>
                    <el-table-column prop="studentName" label="姓名" fixed>
                        <template slot-scope="scoped">
                            {{ scoped.row.studentName }}
                        </template>
                    </el-table-column>
                    <el-table-column v-if="answerList" v-for="(item, index) in answerList" :key="index"
                        :label="item.title">
                        <template slot='header' slot-scope="scope" label="use show-overflow-tooltip"
                            show-overflow-tooltip>
                            <el-tooltip v-if="item.title != '阶段汇总'" effect="dark" :content="item.title"
                                placement="left">
                                <span class="overflowText overClick" @click="_headerClick(item)"
                                    style="color:rgb(121,138,245);width: 100%;height: 100%;">
                                    {{ item.title }}
                                </span>
                            </el-tooltip>
                            <span v-else>
                                {{ item.title }}
                            </span>
                        </template>
                        <el-table-column :prop="'score' + index" :label="index == 0 ? '总分' : '总分'"
                            :class-name="index % 2 == 0 ? 'bg' : ''">
                            <template slot-scope="scoped">
                                {{
                    scoped.row["score" + index] ||
                        Number(scoped.row["score" + index]) === 0
                        ? scoped.row["score" + index]
                        : "-"
                }}
                            </template>
                        </el-table-column>
                        <el-table-column :prop="'classRank' + index" label="排名"
                            :class-name="index % 2 == 0 ? 'bg' : ''">
                            <template slot-scope="scoped">{{
                    scoped.row["classRank" + index] ||
                        Number(scoped.row["classRank" + index]) === 0
                        ? scoped.row["classRank" + index]
                        : "-"
                }}</template>
                        </el-table-column>
                    </el-table-column>
                    <el-table-column label="查看折线图" class-name="print-hidden" fixed="right" align="center" width="120">
                        <template slot-scope="scoped">
                            <el-button type="text" @click="_openLineChart(scoped.row)">查看</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-row>
        </div>
        <!-- 折线图 -->
        <el-dialog class="chart-dia" :visible.sync="lineChart.visible" :title="lineChart.title" width="800"
            :append-to-body="true">
            <div class="chart-box">
                <LineChart id="askLineChart" :params="lineChart.data" :xAxis="lineChart.xAxis" />
            </div>
        </el-dialog>
        <ExportDia :exportStudent="exportStudent" :diaShow="diaShow" @cancel="cancel" @exportData="exportData"
            :type="'折线图'" />
    </div>
</template>
<script>
import { formatDate } from "utils";
import { downloadFile, tablePrint } from "@/utils";
import LineChart from "@/components/charts/lineChart";
export default {
    name: "testSummaryReport",
    components: {
        LineChart
    },
    props: {
        testReportIds: Array,
        queryParams: Object,
        role: "",
    },
    async created() {
        await this._phaseExamReport();
        // await this._changeType();
    },
    watch: {
        $props: {
            handler: async function (val) {
                await this._phaseExamReport();
            },
            deep: false,
        }
    },
    data() {
        return {
            page: 1,
            size: 10,
            total: 0,
            diaShow: false,
            stageReport: [],
            exportStudent: [],
            answerList: null,
            //折线图数据对象
            lineChart: {
                data: [],
                xAxis: [],
                title: "",
                visible: false
            },
        };
    },
    methods: {
        _headerClick(currentItem) {
            this.$emit("headerClick", currentItem);
        },
        async _export() {
            this.diaShow = true;
        },
        cancel() {
            this.diaShow = false;
        },
        async _phaseExamReport() {
            const phaseExamReport =
                this.role == "ROLE_PERSONAL"
                    ? this.$request.pPhaseExamReport
                    : this.$request.phaseExamReport;

            let query = {
                examIds: this.$props.testReportIds,
                classIds: [this.$props.queryParams.class],
                subjectName: [this.$props.queryParams.subject]
            };

            if (this.$props.queryParams.dateRange && this.$props.queryParams.dateRange.length >= 2) {
                query.startDay = this.$props.queryParams.dateRange[0];
                query.endDay = this.$props.queryParams.dateRange[1];
            }


            const { data, status, info } = await phaseExamReport({
                ...query
            });

            if (status != 0) {
                this.$message.error(info);
                return;
            }

            this.total = data.count;
            let dataIdsList = [],
                dataList = [];
            data?.list.map((item) => {
                item.examList.map((items) => {
                    if (!dataIdsList.includes(items.title)) {
                        dataIdsList.push(items.title);
                        dataList.push(items);
                    }
                });
            });

            this.stageReport = data?.list.map((item) => {
                let params = {};
                dataIdsList.map((ids, index) => {
                    params["score" + index] = "--";
                    params["classRank" + index] = "--";
                    item.examList.map((items) => {
                        if (items.title == ids) {
                            params["score" + index] = Number(items.score);
                            params["classRank" + index] = items.classRank;
                        }
                    });
                });
                return {
                    ...item,
                    ...params,
                };
            });

            this.answerList = dataList;

            this.exportStudent = [...this.stageReport];
        },
        async exportData(arr) {
            let studentIds = arr;
            let query = {};
            if (studentIds != null) {
                if (studentIds.length > 0) {
                    query.studentIds = studentIds;
                } else {
                    query.studentIds = [];
                }
            }

            const exportPhaseExamReport =
                this.role == "ROLE_PERSONAL"
                    ? this.$request.pExportPhaseExamReport
                    : this.$request.exportPhaseExamReport;


            const data = await exportPhaseExamReport({
                examIds: this.$props.testReportIds,
                classIds: [this.$props.queryParams.class],
                subjectName: [this.$props.queryParams.subject],
                startDay: this.$props.queryParams?.dateRange[0] ?? null,
                endDay: this.$props.queryParams?.dateRange[1] ?? null,
                ...query
            });


            if (data) {

                this.cancel();

                let blob = new Blob([data], {
                    type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                });

                let name = `即时测-${this.$props.queryParams.subject}-单科多卷报表.xlsx`;

                downloadFile(this.status ? "即时测-已归档单课时报表.xlsx" : name, blob);
            } else {
                this.$message.error("下载失败");
            }
        },
        _print() {
            tablePrint({
                id: "print-content",
                title: "即时测-阶段报表",
                splitParam: 18,
                fixedColumn: 2,
                diffNumber: 2,
                diffStNumber: 3
            });
        },
        _titleClick() { },
        _openLineChart(chartRow) {
            var subejct = this.$props.role == 'ROLE_BANZHUREN' ? this.$props.queryParams.subjects[0] : this.$props.queryParams.subject;
            this.lineChart.title = `${chartRow.studentName}-${subejct}-即时测-多卷作答表现图`;
            this.lineChart.visible = true;
            let score = [];
            let classRank = [];
            let avgScore = [];
            const examList = chartRow.examList.slice(1, chartRow.examList.length);
            this.lineChart.xAxis = examList.map((item) => {
                score.push(item.score);
                classRank.push(item.classRank);
                avgScore.push(item.avgScore);
                return item.title;
            });
            this.lineChart.data = [
                {
                    name: "班级排名",
                    value: classRank,
                },
                {
                    name: "班平均分",
                    value: avgScore,
                },
                {
                    name: "个人成绩",
                    value: score,
                },
            ];
        },
    }
};
</script>
<style scoped lang="scss">
.opration-btn {
    margin-right: 10px;
}

.opration-select {
    margin-left: 10px;
}

.row-line {
    width: calc(20% - 2px);
    border: 1px solid #ebeef5;
    background: #f5f7fa;
    display: inline-block;
    height: 40px;
    line-height: 40px;

    .line-subfix {
        margin-left: 10px;

    }
}

.row-table {
    margin-top: 20px;
}

.chart-dia {
    .chart-box {
        height: 300px;
    }

    :deep(.el-dialog__body) {
        padding: 0 0 20px 0;
    }
}

.overClick:hover {
    cursor: pointer;
}
</style>