<template>
    <div class="app-container">
        <el-card class="box-card">
            <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="120px">
                <el-form-item label="报告" prop="relId">
                    <el-select v-model="queryParams.relId" placeholder="请选择报告">
                        <el-option v-for="item in relList" :key="item.relId" :label="item.reportName"
                            :value="item.relId"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label=" ">
                    <el-button type="primary" icon="el-icon-search" plain @click="queryData">查询</el-button>
                    <el-button type="success" icon="el-icon-view" plain @click="lookVClick">查看学生数据</el-button>
                </el-form-item>
                <el-form-item label="班级" prop="classId">
                    <el-select v-model="queryParams.classId" placeholder="请选择班级" filterable clearable>
                        <el-option v-for="(v, i) in search_class_list" :key="i" :label="v.className" :value="v.classId">
                        </el-option>
                    </el-select>
                </el-form-item>
            </el-form>
        </el-card>
        <el-row :gutter="20" class="mt20">
            <el-col :span="12">
                <el-card class="box-card">
                    <div slot="header" class="clearfix">
                        <span>报告达成率（报告的全部指标都达成的情况）</span>
                        <br />
                        <span style="font-size: 10px;color: red;">
                            当前数据:{{ isEmpty(searchRelName) ? "" : searchRelName }}--
                            {{ isEmpty(searchClassName) ? "" : searchClassName }}
                        </span>
                    </div>
                    <div class="chart-container">
                        <div ref="reportFinishChart" style="height: 400px"></div>
                    </div>
                </el-card>
            </el-col>
            <el-col :span="12">
                <el-card class="box-card">
                    <div slot="header" class="clearfix">
                        <span>指标达成率（学生达成了多少个指标）</span>
                        <br />
                        <span style="font-size: 10px;color: red;">
                            当前数据:{{ isEmpty(searchRelName) ? "" : searchRelName }}--
                            {{ isEmpty(searchClassName) ? "" : searchClassName }}
                        </span>
                    </div>
                    <div class="chart-container">
                        <div ref="itemFinishChart" style="height: 400px"></div>
                    </div>
                </el-card>
            </el-col>
        </el-row>


        <el-row :gutter="20" class="mt20">
            <el-col :span="12">
                <el-card class="box-card">
                    <div slot="header" class="clearfix">
                        <span>各班级报告达成率</span>
                        <el-button @click='exportClassFinishList()' style="float: right;" icon="el-icon-download"
                            type="text">导出</el-button>
                        <br />
                        <span style="font-size: 10px;color: red;">
                            当前数据:{{ isEmpty(searchRelName) ? "" : searchRelName }}
                        </span>
                    </div>
                    <div class="chart-container">
                        <el-table :data="pagedClassFinishList">
                            <el-table-column label="班级" width="140" align="center" prop="class_name" />
                            <el-table-column label="在校生数" align="center" prop="stu_num" />
                            <el-table-column label="达成数" align="center" prop="finish_num" />
                            <el-table-column label="达成率" align="center">
                                <template slot-scope="scope">
                                    {{
                                        scope.row.stu_num
                                            ? ((scope.row.finish_num / scope.row.stu_num) * 100).toFixed(4)
                                            : '0.0000'
                                    }}％
                                </template>
                            </el-table-column>
                        </el-table>
                        <el-pagination background layout="sizes, prev, pager, next"
                            :current-page="currentPageClassFinish" :page-size="pageSizeClassFinish"
                            :total="classFinishList.length" @current-change="handleClassFinishPageChange"
                            @size-change="handleClassFinishSizeChange" :page-sizes="[10, 20, 50, 100]" :pager-count="5"
                            style="text-align: right; margin-top: 20px;" />
                    </div>
                </el-card>
            </el-col>
            <el-col :span="12">
                <el-card class="box-card">
                    <div slot="header" class="clearfix">
                        <span>各班级指标达成率</span>
                        <el-button @click='exportClassItemFinishList()' style="float: right;" icon="el-icon-download"
                            type="text">导出</el-button>
                        <br />
                        <span style="font-size: 10px;color: red;">
                            当前数据:{{ isEmpty(searchRelName) ? "" : searchRelName }}
                        </span>
                    </div>
                    <div class="chart-container">
                        <el-table :data="pagedClassItemFinishList">
                            <el-table-column label="班级" width="140" align="center" prop="class_name" />
                            <el-table-column label="在校生数" align="center" prop="stu_num" />
                            <el-table-column label="总指标数" align="center" prop="total_num" />
                            <el-table-column label="达成数" align="center" prop="finish_num" />
                            <el-table-column label="达成率" align="center">
                                <template slot-scope="scope">
                                    {{
                                        scope.row.total_num
                                            ? ((scope.row.finish_num / scope.row.total_num) * 100).toFixed(4)
                                            : '0.0000'
                                    }}％
                                </template>
                            </el-table-column>
                        </el-table>
                        <el-pagination background layout="sizes, prev, pager, next"
                            :current-page="currentPageClassItemFinish" :page-size="pageSizeClassItemFinish"
                            :total="classItemFinishList.length" @current-change="handleClassItemFinishPageChange"
                            @size-change="handleClassItemFinishSizeChange" :page-sizes="[10, 20, 50, 100]"
                            :pager-count="5" style="text-align: right; margin-top: 20px;" />
                    </div>
                </el-card>
            </el-col>
        </el-row>

        <el-card class="box-card">
            <div slot="header" class="clearfix">
                <span>指标达成情况</span>
                <el-button @click='exportTable("TotalForm", searchRelName
                    + "--" + searchClassName + "指标达成情况")' style="float: right;" icon="el-icon-download"
                    type="text">导出</el-button>
                <br />
                <span style="font-size: 10px;color: red;">
                    当前数据:{{ isEmpty(searchRelName) ? "" : searchRelName }}--
                    {{ isEmpty(searchClassName) ? "" : searchClassName }}
                </span>
            </div>
            <TotalForm id="TotalForm" v-if="tableV" :tableData="tableData" />
        </el-card>

        <table id="tempTable">

        </table>

        <el-dialog :visible.sync="lookV" fullscreen append-to-body>
            <FdyList v-if="lookV" :reportData="lookData" />
        </el-dialog>

    </div>
</template>
<script>
import {
    countFdyItemFinishByRelId as countItemFinishByRelId,
    countFdyFinishNumByRelId as countFinishNumByRelId,
    countFdyItemFinishNumByRelId as countItemFinishNumByRelId,
    countFdyClassFinishNumByRelId as countClassFinishNumByRelId,
    countFdyClassItemFinishNumByRelId as countClassItemFinishNumByRelId
} from "@/api/diagnostic/reportStandards";

import { listAllRelease } from '@/api/diagnostic/DiaReportRelease';

import { listOwnClass as listClass } from "@/api/stuCQS/info-fill/stu_eva_task";

import { isEmpty, fullLoading } from '@/api/helpFunc';

import TotalForm from './cpnt/TotalForm';
import FdyList from "./cpnt/FdyList.vue";

import * as echarts from 'echarts';
import XLSX from 'xlsx';

export default {
    name: "DataView",
    components: {
        TotalForm,
        FdyList
    },

    data() {
        return {
            isEmpty,

            queryParams: {
                relId: null
            },
            relList: [],
            gradeList: [],
            search_major_list: [],
            search_class_list: [],


            tableData: [],
            tableV: false,

            reportFinishChart: null,
            itemFinishChart: null,

            majorItemFinishList: [],
            majorFinishList: [],

            gradeItemFinishList: [],
            gradeFinishList: [],

            classItemFinishList: [],
            classFinishList: [],

            searchRelName: "",
            searchMajorName: "",
            searchClassName: "",
            searchGradeName: "",

            currentPageMajorFinish: 1,
            pageSizeMajorFinish: 10,

            currentPageMajorItemFinish: 1,
            pageSizeMajorItemFinish: 10,

            currentPageClassFinish: 1,
            pageSizeClassFinish: 10,

            currentPageClassItemFinish: 1,
            pageSizeClassItemFinish: 10,

            lookV: false,
            lookData: {},

        }
    },
    created() {
        this.listAllRelease();
        this.listClass();
    },
    mounted() {
        this.initCharts();
    },
    computed: {
        pagedClassFinishList() {
            const start = (this.currentPageClassFinish - 1) * this.pageSizeClassFinish;
            const end = start + this.pageSizeClassFinish;
            return this.classFinishList.slice(start, end);
        },
        pagedClassItemFinishList() {
            const start = (this.currentPageClassItemFinish - 1) * this.pageSizeClassItemFinish;
            const end = start + this.pageSizeClassItemFinish;
            return this.classItemFinishList.slice(start, end);
        },
    },
    methods: {
        lookVClick() {
            if (isEmpty(this.queryParams.relId)) {
                this.$message.warning("请先选择报告");
                return;
            }
            this.lookData = {};
            let reportName = this.relList.find(item => item.relId == this.queryParams.relId).reportName;
            let reportId = this.relList.find(item => item.relId == this.queryParams.relId).reportId;
            let sdata = {
                relId: this.queryParams.relId,
                reportName,
                reportId
            }
            this.lookData = sdata;
            this.lookV = true;
        },
        exportClassFinishList() {
            let classFinishList = [...this.classFinishList];
            const data = [
                ['学院', '专业', '班级', '在校生数', '达成数', '达成率']
            ];

            classFinishList.forEach(row => {
                data.push([
                    row.dept_name,
                    row.major_name,
                    row.class_name,
                    row.stu_num,
                    row.finish_num,
                    row.stu_num
                        ? ((row.finish_num / row.stu_num) * 100).toFixed(4) + '%'
                        : '0.0000%'
                ]);
            });
            const worksheet = XLSX.utils.aoa_to_sheet(data);
            const workbook = XLSX.utils.book_new();
            XLSX.utils.book_append_sheet(workbook, worksheet, '各班级报告达成统计');

            let title = this.searchRelName + "--" + this.searchMajorName;
            XLSX.writeFile(workbook, title + '各班级报告达成统计.xlsx');
        },
        exportClassItemFinishList() {
            let classItemFinishList = [...this.classItemFinishList];
            const data = [
                ['学院', '专业', '班级', '在校生数', '总指标数', '达成数', '达成率']
            ];

            classItemFinishList.forEach(row => {
                data.push([
                    row.dept_name,
                    row.major_name,
                    row.class_name,
                    row.stu_num,
                    row.total_num,
                    row.finish_num,
                    row.total_num
                        ? ((row.finish_num / row.total_num) * 100).toFixed(4) + '%'
                        : '0.0000%'
                ]);
            });
            const worksheet = XLSX.utils.aoa_to_sheet(data);
            const workbook = XLSX.utils.book_new();
            XLSX.utils.book_append_sheet(workbook, worksheet, '各班级指标达成统计');

            let title = this.searchRelName + "--" + this.searchMajorName;
            XLSX.writeFile(workbook, title + '各班级指标达成统计.xlsx');
        },

        exportTable(id, title) {
            let thead = document.getElementById(id).getElementsByTagName('thead')[0];
            let tbody = document.getElementById(id).getElementsByTagName('tbody')[0];
            let tempTable = document.getElementById('tempTable');
            if (thead) {
                tempTable.appendChild(thead.cloneNode(true))
            }
            if (tbody) {
                Array.from(tbody.getElementsByTagName('td')).forEach(td => {
                    if (td.innerText.trim().endsWith('%')) {
                        td.innerHTML = `<span style="mso-number-format:'\\@';">${td.innerText}</span>`;
                    }
                });
                tempTable.appendChild(tbody.cloneNode(true))
            }
            const wb = XLSX.utils.table_to_book(tempTable, { sheet: 'Sheet1', cellText: true })
            XLSX.writeFile(wb, title + ".xlsx");
            tempTable.innerHTML = '';
        },

        handleClassItemFinishPageChange(page) {
            this.currentPageClassItemFinish = page;
        },
        handleClassItemFinishSizeChange(size) {
            this.pageSizeClassItemFinish = size;
            this.currentPageClassItemFinish = 1;
        },
        handleClassFinishPageChange(page) {
            this.currentPageClassFinish = page;
        },
        handleClassFinishSizeChange(size) {
            this.pageSizeClassFinish = size;
            this.currentPageClassFinish = 1;
        },

        async queryData() {
            let sdata = { ...this.queryParams };
            if (isEmpty(sdata.relId)) {
                this.$message.info("请选择报告");
                return;
            }

            this.searchRelName = this.relList.find(item => item.relId == sdata.relId).reportName;

            if (!isEmpty(sdata.classId)) {
                this.searchClassName = this.search_class_list.find(item => item.classId == sdata.classId).className;
            }

            // 只开一次 loading
            let loading = fullLoading(this);
            // 并行等待接口
            try {
                await Promise.all([
                    this.countFinishNumByRelId(true), // 传入参数表示不在内部开loading
                    this.countItemFinishByRelId(true),
                    this.countItemFinishNumByRelId(true),
                    this.countClassFinishNumByRelId(true),
                    this.countClassItemFinishNumByRelId(true),
                ]);
            } finally {
                loading.close();
            }
        },
        async countClassFinishNumByRelId(noLoading) {
            let loading;
            if (!noLoading) loading = fullLoading(this);
            let res = await countClassFinishNumByRelId(this.queryParams);
            if (loading) loading.close();
            if (res.code == 200) {
                this.classFinishList = [...res.data];
            }
        },
        async countClassItemFinishNumByRelId(noLoading) {
            let loading;
            if (!noLoading) loading = fullLoading(this);
            let res = await countClassItemFinishNumByRelId(this.queryParams);
            if (loading) loading.close();
            if (res.code == 200) {
                this.classItemFinishList = [...res.data];
            }
        },


        async countItemFinishNumByRelId(noLoading) {
            let loading;
            if (!noLoading) loading = fullLoading(this);
            let res = await countItemFinishNumByRelId(this.queryParams);
            if (loading) loading.close();
            if (res.code == 200) {
                let temp = { ...res.data };
                let data = [];
                data.push({ value: temp.finish_num, name: '已达成' });
                data.push({ value: temp.total_num - temp.finish_num, name: '未达成' });
                this.renderPieChart(this.itemFinishChart, '指标达成率', data);
            }
        },
        async countFinishNumByRelId(noLoading) {
            let loading;
            if (!noLoading) loading = fullLoading(this);
            let res = await countFinishNumByRelId(this.queryParams);
            if (loading) loading.close();
            if (res.code == 200) {
                let temp = { ...res.data };
                let data = [];
                data.push({ value: temp.finish_num, name: '已达成' });
                data.push({ value: temp.stu_num - temp.finish_num, name: '未达成' });
                this.renderPieChart(this.reportFinishChart, '报告达成率', data);
            }
        },

        async countItemFinishByRelId(noLoading) {
            let loading;
            if (!noLoading) loading = fullLoading(this);
            let sdata = { ...this.queryParams };
            this.tableV = false;
            let res = await countItemFinishByRelId(sdata);
            if (loading) loading.close();
            if (res.code == 200) {
                this.tableV = true;
                this.tableData = [...res.data];
            }
        },
        renderPieChart(chart, title, data) {
            // 添加数据检查
            if (!data || !Array.isArray(data)) {
                console.warn('数据格式不正确或为空:', data);
                data = []; // 设置为空数组，避免报错
            }

            const option = {
                title: {
                    text: title,
                    left: 'center'
                },
                tooltip: {
                    trigger: 'item',
                    formatter: '{a} <br/>{b}: {c} ({d}%)'
                },
                legend: {
                    orient: 'vertical',
                    left: 'left',
                },
                series: [
                    {
                        name: '达成情况',
                        type: 'pie',
                        radius: '50%',
                        center: ['70%', '50%'],
                        data: [...data],
                        emphasis: {
                            itemStyle: {
                                shadowBlur: 10,
                                shadowOffsetX: 0,
                                shadowColor: 'rgba(0, 0, 0, 0.5)'
                            }
                        }
                    }
                ]
            }

            // 如果数据为空，显示暂无数据
            if (data.length === 0) {
                option.title.subtext = '暂无数据';
            }

            chart.setOption(option);
        },
        initCharts() {
            if (this.$refs.reportFinishChart && this.$refs.itemFinishChart) {
                this.reportFinishChart = echarts.init(this.$refs.reportFinishChart);
                this.itemFinishChart = echarts.init(this.$refs.itemFinishChart);
            }
        },
        async listClass() {
            let res = await listClass();
            if (res.code == 200) {
                this.search_class_list = [...res.data];
            }
        },

        async listAllRelease() {
            let res = await listAllRelease();
            if (res.code == 200) {
                this.relList = [...res.data];
            }
        },

    }
}
</script>
<style scoped lang="scss">
.box-card {
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.chart-container {
    background: #fff;
    padding: 10px;
    border-radius: 5px;
}

.mt20 {
    margin-top: 20px;
}

.clearfix:before,
.clearfix:after {
    display: table;
    content: '';
}

.clearfix:after {
    clear: both;
}
</style>
