<!-- 考试情况统计 -->
<template>
  <div class="exam-situation-card">
    <div class="card-header">
      <span class="card-title">考试情况统计</span>
      <div class="header-right">
        <el-select v-model="valueYear" @change="topChange()" size="small" style="width:220px">
          <el-option
            v-for="dict in optionList"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
        <!-- 分组按钮 -->
        <div class="table-top-button-box">
          <div>
            <p @click="checkButton(2)" :class="checkIndex == 2?'check-table-button':''">研究生</p>
            <p @click="checkButton(3)" :class="checkIndex == 3?'check-table-button':''">本科生</p>
            <p @click="checkButton(1)" :class="checkIndex == 1?'check-table-button':''">教职工</p>
          </div>
        </div>
        <!-- 导出按钮 -->
        <p class="export-btn" @click="exportButton()">
          <i class="el-icon-download"></i> 导出数据
        </p>
      </div>
    </div>

    <!-- 图表区 -->
    <div class="chart-area">
      <!-- 堆叠柱状图 -->
      <p class="bar-chart-wrap" v-if="!chartData.deptStats[0]" style="color:#999;font-size:14px;line-height:260px;text-align: center;">暂无数据</p>
      <div class="bar-chart-wrap" v-if="chartData.deptStats[0]" id="bar-chart-wrap" ref="barChart"></div>
      <!-- 环形图 -->
      <p class="pie-chart-wrap" v-if="!chartData.deptStats[0]" style="color:#999;font-size:14px;line-height:260px;text-align: center;">暂无数据</p>
      <div class="pie-chart-wrap" v-if="chartData.deptStats[0]" id="pie-chart-wrap" ref="pieChart"></div>
    </div>

    <!-- 筛选 -->
    <div class="filter-row">
      <el-cascader
        style="width: 180px"
        clearable
        v-model="queryParams.deptId"
        :options="optionListA"
        :props="{
                    emitPath:false,
                    checkStrictly: true,
                    value: 'deptId',
                    label: 'deptName',
                    children: 'child',
                  }"
        :show-all-levels="false"
        filterable
        placeholder="筛选学院"
        @change="queryParamsChange"
      ></el-cascader>
      <el-select
        @change="queryParamsChange"
        v-model="queryParams.examTypeId" clearable placeholder="考试类型" style="width: 160px">
        <el-option
          v-for="dict in optionListB"
          :key="dict.id"
          :label="dict.examTypeName"
          :value="dict.id"
        />
      </el-select>
    </div>

    <!-- 统计表格 -->

    <div class="page-content-box">
      <el-table class="table-box" :data="dataList" border :span-method="objectSpanMethod">
        <el-table-column prop="deptName" label="学院" />
        <el-table-column prop="examTypeName" label="考试类型" width="200" />
        <el-table-column prop="examCount" label="应考人数" width="160" align="center" />
        <el-table-column prop="passedCount" label="通过人数" width="160" align="center" />
        <el-table-column prop="notPassedCount" label="未通过人数" width="160" align="center"/>
        <el-table-column prop="absentCount" label="未考人数" width="160" align="center" />
        <el-table-column prop="passRate" label="通过率" width="160" align="center" />
      </el-table>
    </div>
  </div>
</template>

<script>
import echarts from 'echarts'
import {
  examElStatisticsGetAcademicYear,examElStatisticsExamList,examElStatisticsExamChart,
  examElExamTypeList,systemDeptCurrentDept,
} from "@/api/safetyEducationExaminationNew/index";
export default {
  name: 'ExamSituation',
  data() {
    return {
      chartData: {
        barGroups: [
          { label: '化学与化工', pass: 106, fail: 8, notExam: 6 },
          { label: '生命科学',   pass: 84,  fail: 7, notExam: 4 },
          { label: '物理',       pass: 67,  fail: 6, notExam: 5 },
          { label: '电气工程',   pass: 98,  fail: 7, notExam: 5 },
          { label: '材料科学',   pass: 78,  fail: 5, notExam: 5 },
          { label: '机械工程',   pass: 63,  fail: 5, notExam: 4 },
          { label: '自动化',     pass: 59,  fail: 3, notExam: 3 },
          { label: '资源环境',   pass: 49,  fail: 4, notExam: 3 },
        ]
      },
      chartList:[],
      spanMap: {},
      optionList:[],
      optionListA:[],
      optionListB:[],
      valueYear:'',
      checkIndex:2,
      queryParams:{
        deptId:'',
        examTypeId:'',
      },
      dataList:[
        {
          deptName:'学院1',
          examType:'类型1',
          total:'1',
          pass:'2',
          fail:'3',
          notExam:'4',
          rate:'5',
        },
        {
          deptName:'学院12',
          examType:'类型1',
          total:'1',
          pass:'2',
          fail:'3',
          notExam:'4',
          rate:'5',
        },
        {
          deptName:'学院1',
          examType:'类型2',
          total:'1',
          pass:'2',
          fail:'3',
          notExam:'4',
          rate:'5',
        },
      ],
    }
  },
  created() {

  },
  mounted() {
    this.examElExamTypeList();
    this.systemDeptCurrentDept();
    this.examElStatisticsGetAcademicYear();
  },
  beforeDestroy() {
    if (this._barChart) this._barChart.dispose()
    if (this._pieChart) this._pieChart.dispose()
  },
  methods: {
    //导出
    exportButton(){
      let self = this;
      self.$confirm(`确认导出数据?`, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(async () => {
        let obj = {
          academicYear:this.valueYear,
          personType:this.checkIndex,
          deptId:this.queryParams.deptId,
          examTypeId:this.queryParams.examTypeId,
        };
        self.download('/exam/elStatistics/exam/export', {...obj}, '考试情况统计.xlsx')
      }).catch(() => {})
    },
    //图表
    initBarChart() {
      const groups = this.chartData.deptStats
      const chart = echarts.init(this.$refs.barChart)
      this._barChart = chart
      chart.setOption({
        legend: {
          data: ['通过', '未通过', '未考'],
          top: 10,
          itemWidth: 14,
          itemHeight: 14,
          textStyle: { fontSize: 12, color: '#555' },
        },
        grid: { top: 60, bottom: 60, left: 40, right: 10, containLabel: false },
        xAxis: {
          type: 'category',
          data: groups.map(g => g.deptName),
          axisLine: { lineStyle: { color: '#ddd' } },
          axisLabel: { fontSize: 11, color: '#666', rotate: 25 },
          axisTick: { show: false },
        },
        yAxis: {
          type: 'value',
          splitLine: { lineStyle: { color: '#f0f0f0' } },
          axisLabel: { fontSize: 11, color: '#aaa' },
          axisLine: { show: false },
          axisTick: { show: false },
        },
        series: [
          {
            name: '通过',
            type: 'bar',
            stack: 'total',
            data: groups.map(g => g.passedCount),
            itemStyle: { color: '#4fbe7e' },
            label: { show: true, position: 'inside', fontSize: 11, color: '#fff',
              formatter: (p) => p.value > 0 ? p.value : '' },
          },
          {
            name: '未通过',
            type: 'bar',
            stack: 'total',
            data: groups.map(g => g.notPassedCount),
            itemStyle: { color: '#f56c6c' },
            label: { show: true, position: 'inside', fontSize: 10, color: '#fff',
              formatter: (p) => p.value > 0 ? p.value : '' },
          },
          {
            name: '未考',
            type: 'bar',
            stack: 'total',
            data: groups.map(g => g.absentCount),
            itemStyle: { color: '#c0c4cc' },
            label: { show: true, position: 'inside', fontSize: 10, color: '#fff',
              formatter: (p) => p.value > 0 ? p.value : '' },
          },
        ],
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'shadow' },
        },
      })
    },
    //图表
    initPieChart() {
      const pass    = this.chartData.totalPassed
      const fail    = this.chartData.totalNotPassed
      const notExam = this.chartData.totalAbsent
      const chart = echarts.init(this.$refs.pieChart)
      this._pieChart = chart
      chart.setOption({
        legend: {
          orient: 'horizontal',
          bottom: 0,
          data: ['通过', '未通过', '未考'],
          itemWidth: 12,
          itemHeight: 12,
          textStyle: { fontSize: 12, color: '#555' },
        },
        series: [
          {
            type: 'pie',
            radius: ['45%', '68%'],
            center: ['50%', '45%'],
            label: {
              formatter: '{b}',
              fontSize: 12,
              color: '#555',
            },
            labelLine: { length: 12, length2: 8 },
            data: [
              { value: pass,    name: '通过',  itemStyle: { color: '#4fbe7e' } },
              { value: fail,    name: '未通过', itemStyle: { color: '#f56c6c' } },
              { value: notExam, name: '未考',   itemStyle: { color: '#c0c4cc' } },
            ],
            emphasis: {
              itemStyle: { shadowBlur: 6, shadowOffsetX: 0, shadowColor: 'rgba(0,0,0,0.2)' }
            },
          },
        ],
        tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
      })
    },
    //顶部学年切换
    topChange(){
      this.examElStatisticsExamChart();
      this.examElStatisticsExamList();
    },
    //身份切换
    checkButton(val){
      if(this.checkIndex!=val){
        this.$set(this,'checkIndex',val);
        this.examElStatisticsExamChart();
        this.examElStatisticsExamList();
      }
    },
    //条件变更
    queryParamsChange(){
      this.examElStatisticsExamList();
    },
    //数据合并
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 只对第一列（学院列，columnIndex === 0）进行合并
      if (columnIndex === 0) {
        const list = this.dataList;

        // 如果是第一行，或者当前行的学院与上一行的学院不同，则开始合并计算
        if (rowIndex === 0 || row.deptName !== list[rowIndex - 1].deptName) {
          let rowspan = 1;
          // 向下遍历，统计有多少行是相同的学院
          for (let i = rowIndex + 1; i < list.length; i++) {
            if (list[i].deptName === row.deptName) {
              rowspan++;
            } else {
              break; // 遇到不同的学院，停止计算
            }
          }
          return { rowspan, colspan: 1 };
        } else {
          // 如果当前行的学院与上一行相同，则隐藏当前单元格（被合并了）
          return { rowspan: 0, colspan: 0 };
        }
      }
      // 其他列正常显示
      return { rowspan: 1, colspan: 1 };
    },
    //考试统计图表
    examElStatisticsExamChart(){
      let obj = {
        academicYear:this.valueYear,
        personType:this.checkIndex,
      }
      examElStatisticsExamChart(obj).then(response => {
        this.$set(this,'chartData',response.data);
        this.$nextTick(() => {
          if(response.data.deptStats[0]){
            this.$nextTick(() => {
              this.initBarChart()
              this.initPieChart()
            })
          }
        })
      });
    },
    //考试统计列表
    examElStatisticsExamList(){
      let obj = {
        academicYear:this.valueYear,
        personType:this.checkIndex,
        deptId:this.queryParams.deptId,
        examTypeId:this.queryParams.examTypeId,
      }
      examElStatisticsExamList(obj).then(response => {
        this.$set(this,'dataList',response.data);
      });
    },
    //查询全部考试类型
    examElExamTypeList(){
      examElExamTypeList({}).then(response => {
        this.$set(this,'optionListB',response.data);
      });
    },
    //学院列表
    systemDeptCurrentDept(){
      systemDeptCurrentDept({}).then(response => {
        const list = response.data || [];
        this.formatTreeData(list);
        this.$set(this,'optionListA',list);
      });
    },
    //学年列表
    examElStatisticsGetAcademicYear(){
      examElStatisticsGetAcademicYear({}).then(response => {
        this.$set(this,'optionList',response.data);
        this.$set(this,'valueYear',response.data[0].value);
        this.examElStatisticsExamList();
        this.examElStatisticsExamChart();
      });
    },
  }
}
</script>

<style scoped lang="scss">
.exam-situation-card {
  background: #fff;
  /*border-radius: 6px;*/
  padding: 20px;
  margin-bottom: 12px;
  /*box-shadow: 0 1px 4px rgba(0,0,0,0.06);*/
  background: rgba(255, 255, 255, 0.95);
  border: 1px solid #e8edf5;
  border-radius: 16px;
  box-shadow: 0 4px 20px rgba(37, 50, 74, 0.06);

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
    .card-title { font-size: 16px; font-weight: 700; color: #222; }
    .header-right { width:610px;display: flex; align-items: center; gap: 20px; }
  }

  /* 分组筛选按钮 */
  .table-top-button-box {
    display: inline-block;
    vertical-align: top;
    div {
      display: flex;
      p {
        border: 1px solid #DCDFE6;
        width: 80px;
        text-align: center;
        height: 40px;
        line-height: 40px;
        cursor: pointer;
        font-size: 14px;
        &:nth-child(1) { border-top-left-radius: 4px; border-bottom-left-radius: 4px; }
        &:nth-child(2) { border-left: none; border-right: none; }
        &:nth-child(3) { border-top-right-radius: 4px; border-bottom-right-radius: 4px; }
      }
      .check-table-button{
        border: 1px solid #0183fa!important;
        background-color: #0183fa!important;;
        color:#fff!important;;
      }
    }
  }

  /* 导出按钮 */
  .export-btn {
    display: inline-block;
    padding: 0 16px;
    height: 40px;
    line-height: 40px;
    border-radius: 4px;
    font-size: 14px;
    cursor: pointer;
    background-color: #0183fa;
    color: #fff;
    border: 1px solid #0183fa;
  }

  .chart-area {
    display: flex;
    gap: 0;
    margin-bottom: 16px;
    border: 1px solid #eee;
    border-radius: 6px;
    overflow: hidden;

    .bar-chart-wrap {
      flex: 1;
      height: 280px;
      border-right: 1px solid #eee;
    }

    .pie-chart-wrap {
      width: 320px;
      height: 280px;
    }
  }

  .filter-row {
    display: flex;
    gap: 20px;
    margin-bottom: 12px;
  }
  .page-content-box{
    height:500px;
    padding:0;
    ::v-deep .el-table--medium td:nth-child(1){
      border-left:1px solid #dfe6ec!important;
    }
  }

  .link-blue { color: #409eff; }
}
</style>
