<template>
  <div>
    <el-card shadow="hover"
             class="m-b-20 head-card">
      <div class="flex-between m-b-20">
        <el-page-header @back="$router.push('list?tab=tab1')"
                        :content="goodsName"></el-page-header>
      </div>

    </el-card>

    <el-card shadow="hover"
             class="m-b-20">
      <el-tabs v-model="curTab"
               @tab-click="tabChange">
        <el-tab-pane v-for="(item) in tabs"
                     :label="item.name"
                     :name="item.id"
                     :key="item.id"></el-tab-pane>
      </el-tabs>
      <div class="stat">
        <div class="nums">
          <div class="item">
            <p class="name">实验总人数</p>
            <p class="val">{{ peopleNum }}</p>
          </div>
          <div class="item item2">
            <p class="name">实验平均分</p>
            <p class="val">{{ avgScore }}</p>
          </div>
          <div class="item item3">
            <p class="name">实验最高分</p>
            <p class="val">{{ maxScore || 0 }}</p>
          </div>
          <div class="item item4">
            <p class="name">实验最低分</p>
            <p class="val">{{ minScore || 0 }}</p>
          </div>
        </div>
        <div class="chart"
             id="chart"></div>
      </div>
    </el-card>

    <el-card shadow="hover"
             class="m-b-20">
      <h6 style="font-size: 16px">错误率分析</h6>
      <div class="wrong">
        <div class="line">
          <span class="jud-name">错误率最高：{{ max.projectName }}</span>
          <span>参加考试{{ max.numberOfParticipants || 0 }}人&emsp;｜&emsp;{{ curTab == 1 ? `共${max.itemErrorCount || 0}人做错，` : '' }}错误率{{ max.errorRate || 0 }}%</span>
        </div>
        <div class="line">
          <span class="jud-name">错误率最低：{{ min.projectName }}</span>
          <span>参加考试{{ min.numberOfParticipants || 0 }}人&emsp;｜&emsp;{{ curTab == 1 ? `共${min.itemErrorCount || 0}人做错，` : '' }}错误率{{ min.errorRate || 0 }}%</span>
        </div>
      </div>
      <div class="chart"
           id="chart1"></div>
    </el-card>

    <el-card shadow="hover">
      <div class="flex-between m-b-20">
        <div>
          <el-input placeholder="请输入姓名/学号"
                    prefix-icon="el-icon-search"
                    v-model="keyword"
                    clearable></el-input>
        </div>
        <div>
          <el-button type="primary"
                     @click="exportData">导出成绩列表</el-button>
          <!-- <el-button type="primary"
                     @click="exportReport">导出成绩详情</el-button> -->
        </div>
      </div>
      <el-table :data="listData"
                class="table"
                ref="table"
                :key="curTab"
                stripe
                header-align="center"
                @selection-change="handleSelectionChange"
                row-key="reportId">
        <el-table-column type="selection"
                         width="55"
                         align="center"
                         :reserve-selection="true"></el-table-column>
        <el-table-column type="index"
                         width="60"
                         label="序号"
                         align="center">
          <template slot-scope="scope">
            {{ scope.$index + (page - 1) * pageSize + 1 }}
          </template>
        </el-table-column>
        <el-table-column prop="userName"
                         label="姓名"
                         align="center"></el-table-column>
        <el-table-column prop="workNumber"
                         label="学号"
                         align="center"></el-table-column>
        <template v-if="curTab == 0">
          <el-table-column label="练习项目数"
                           align="center">
            <template slot-scope="scope">
              {{ scope.row.totalNumberOfPractices }}
            </template>
          </el-table-column>
          <el-table-column prop="numberOfExercises"
                           label="练习次数"
                           width="90"
                           align="center"></el-table-column>
          <el-table-column label="累计练习时长"
                           align="center">
            <template slot-scope="scope">
              {{ scope.row.cumulativePracticeTime }}min
            </template>
          </el-table-column>
        </template>
        <template v-else>
          <el-table-column prop="totalNumberOfParticipants"
                           label="参加考核次数"
                           align="center">
          </el-table-column>
          <el-table-column prop="averageTimeSpent"
                           label="平均用时"
                           align="center">
            <template slot-scope="scope">
              {{ scope.row.averageTimeSpent }}min
            </template>
          </el-table-column>
        </template>
        <el-table-column prop="avgScore"
                         label="平均分"
                         align="center">
          <template slot-scope="scope">
            {{ curTab == 0 ? scope.row.avgScore : scope.row.averageScore }}
          </template>
        </el-table-column>
        <el-table-column prop="maxScore"
                         label="最高分"
                         align="center"></el-table-column>
        <el-table-column prop="minScore"
                         label="最低分"
                         align="center"></el-table-column>
        <el-table-column label="操作"
                         align="center"
                         width="140">
          <template slot-scope="scope">
            <el-button type="text"
                       @click="show(scope.row)">查看成绩详情</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="pagination">
        <el-pagination background
                       layout="total, prev, pager, next"
                       :total="total"
                       @current-change="handleCurrentChange"
                       :current-page="page">
        </el-pagination>
      </div>
    </el-card>

    <el-dialog title="成绩详情"
               :visible.sync="detailVisible"
               width="900px"
               :key="curTab"
               :close-on-click-modal="false">
      <div class="m-b-10 text-right">
        <el-button type="primary"
                   @click="exportDetail">导出</el-button>
      </div>
      <el-table :data="details"
                stripe
                :key="curTab"
                header-align="center"
                row-key="id">
        <el-table-column type="index"
                         width="60"
                         label="序号"
                         align="center">
          <template slot-scope="scope">
            {{ scope.$index + (pageDetail - 1) * pageSizeDetail + 1 }}
          </template>
        </el-table-column>
        <el-table-column prop="userName"
                         label="姓名"
                         width="100"
                         align="center">
        </el-table-column>
        <el-table-column prop="workNumber"
                         label="学号"
                         width="100"
                         align="center"></el-table-column>
        <template v-if="curTab == 0">
          <el-table-column prop="projectName"
                           label="项目名称"
                           min-width="200"
                           align="center"></el-table-column>
          <el-table-column prop="averageDuration"
                           label="平均练习时长"
                           width="110"
                           align="center">
            <template slot-scope="scope">
              {{ scope.row.averageDuration }}min
            </template>
          </el-table-column>
          <el-table-column prop="averageScore"
                           label="平均分"
                           min-width="100"
                           align="center"></el-table-column>
        </template>
        <template v-else>
          <el-table-column prop="experimentalName"
                           label="考核名称"
                           min-width="200"
                           align="center"></el-table-column>
          <el-table-column prop="averageDuration"
                           label="用时"
                           width="100"
                           align="center">
            <template slot-scope="scope">
              {{ scope.row.timeSum }}min
            </template>
          </el-table-column>
          <el-table-column prop="score"
                           label="分数"
                           min-width="100"
                           align="center"></el-table-column>
        </template>
        <el-table-column label="成绩报告"
                         align="center"
                         width="90">
          <template slot-scope="scope">
            <el-button type="text"
                       @click="toReport(scope.row)">查看</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="pagination">
        <el-pagination background
                       layout="total, prev, pager, next"
                       :total="totalDetail"
                       :page-size="pageSizeDetail"
                       @current-change="handleCurrentDetailChange"
                       :current-page="pageDetail">
        </el-pagination>
      </div>
      <span slot="footer"
            class="dialog-footer">
        <el-button size="small"
                   type="primary"
                   @click="detailVisible = false">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { Loading } from "element-ui";
import Setting from "@/setting";
import util from "@/libs/util";
import echarts from "echarts";
import axios from 'axios';
export default {
  data () {
    return {
      tabs: [
        {
          id: '0',
          name: '练习成绩'
        },
        {
          id: '1',
          name: '考核成绩'
        }
      ],
      curTab: this.$route.query.permissions || '0',
      permissions: +this.$route.query.permissions,
      goodsName: this.$route.query.curriculumName,
      accountId: this.$route.query.accountId,
      id: +this.$route.query.id,
      cid: +this.$route.query.cid,
      classId: +this.$route.query.classId,
      keyword: "",
      searchTimer: null,
      listDataAll: [],
      listData: [],
      multipleSelection: [],
      page: 1,
      pageSize: 10,
      total: 0,
      peopleNum: 0, // 总人数
      avgScore: 0, // 平均分
      maxScore: 0,
      minScore: 0,
      errorAnalysis: [],
      max: {},
      min: {},
      token: util.local.get(Setting.tokenKey),
      detailVisible: false,
      details: [],
      multipleSelectionActivation: [],
      pageDetail: 1,
      pageSizeDetail: 5,
      totalDetail: 0,
      curRow: {},
      stageNumber: [],
      loadIns: null
    };
  },
  watch: {
    keyword: function (val) {
      clearTimeout(this.searchTimer);
      this.searchTimer = setTimeout(() => {
        this.initData()
      }, 500)
    }
  },
  mounted () {
    // this.getClass()
    this.getData()
  },
  methods: {
    // 成绩
    async getData () {
      this.loadIns = Loading.service({
        background: "rgba(255,255,255,.6)"
      })
      const per = +this.curTab
      const res = await this.$post(this.api.productReadScore, {
        pageNum: this.page,
        pageSize: 10000,
        keyWord: this.keyword,
        mallId: this.id,
        cid: this.cid,
        permissions: per,
        classId: this.classId
      })
      this.listDataAll = per ? res.listOfAssessmentResults.records : res.userScoreList.records
      this.total = per ? res.listOfAssessmentResults.total : res.userScoreList.total
      const stat = res.experimentalStatistics
      this.avgScore = stat.averageScore
      this.peopleNum = stat.experimentalPopulation
      this.maxScore = stat.maxScore
      this.minScore = stat.minScore
      const err = (per ? res.testErrorRateUnderProduct : res.projectErrorRateAnalysisUnderProduct) || []
      err.forEach(e => {
        e.errorRate = (+e.errorRate).toFixed(2)
      })
      this.errorAnalysis = err || []
      this.max = err[0] || {}
      this.min = err[err.length - 1] || {}
      this.errorChart()
      const { row } = this.$store.state.achievement
      row && this.$nextTick(() => {
        window.scrollTo(0, document.documentElement.scrollHeight)
        this.show(row)
        this.$store.commit('achievement/setRow', null)
      })
      this.handlePage()
      this.getChart()
    },
    initData () {
      this.page = 1
      this.getData()
    },
    // 分页
    handlePage () {
      const list = this.listDataAll
      this.listData = list.slice((this.page - 1) * this.pageSize, this.page * this.pageSize)
    },
    // 练习考核切换
    tabChange () {
      this.$router.push({
        path: 'course',
        query: {
          ...this.$route.query,
          permissions: this.curTab
        }
      })
      this.initData()
    },
    // 导出(有勾选：就导勾选中的；没有勾选：就导全部)
    async exportData () {
      let list = this.multipleSelection
      const practice = this.curTab == 0 // 练习
      // 没勾选，则查询所有成绩
      if (!list.length) {
        const res = await this.$post(this.api.productReadScore, {
          pageNum: 1,
          pageSize: 10000,
          mallId: this.id,
          cid: this.cid,
          permissions: +this.curTab,
          classId: this.classId
        })
        list = practice ? res.userScoreList.records : res.listOfAssessmentResults.records
      }
      list.forEach(e => {
        e.goodsName = this.goodsName
        e.cid = this.cid
      })
      axios.post(this.api[practice ? 'exportProductPracticeResults' : 'exportProductAssessResults'], list, {
        headers: {
          token: this.token
        },
        responseType: 'blob'
      }).then((res) => {
        util.downloadFileDirect(`${practice ? '练习' : '考核'}成绩列表.xlsx`, new Blob([res.data]))
      }).catch(res => { })
    },
    // 导出实验报告
    exportReport () {
      // 没选择数据，则导出全部
      const list = this.multipleSelection.length ? this.multipleSelection : this.listDataAll
      list.forEach(async e => {
        const { report, userScores } = await this.$get(`${this.api.reportDetail}?reportId=${e.reportId}`)
        userScores.map((e, i) => {
          if (e.answer && typeof e.answer === 'string') e.answer = e.answer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
        })
        for (const i in report) {
          if (report[i] && typeof report[i] === 'string') report[i] = report[i].replace(/<[^>]+>/g, '')
        }
        report.purpose = report.purpose.replace(/<[^>]+>/g, '')
        this.$post(this.api[userScores.find(e => e.lcRuleRecords) ? 'exportBankExperimentReport' : 'exportLabReport'], {
          ...report,
          experimentalData: userScores
        }).then(res => {
          util.downloadFileDirect(`${e.userName}的实验报告.docx`, new Blob([res]))
        }).catch(res => { })
      })
    },
    handleDelete (row) { // 删除
      this.$confirm("确定要删除吗？", "提示", {
        type: "warning"
      }).then(() => {
        this.$post(this.api.deleteExperimentalReport, [row.reportId]).then(res => {
          util.successMsg("删除成功");
          this.getData();
        }).catch(res => {
        });
      }).catch(() => {
      });
    },
    delAllData () { // 批量删除
      if (this.multipleSelection.length) {
        this.$confirm("该项目下的所有成绩报告将会删除，是否继续？", "提示", {
          type: "warning"
        }).then(() => {
          let ids = this.multipleSelection.map(item => {
            return item.reportId;
          });
          this.$post(this.api.deleteExperimentalReport, ids).then(res => {
            this.multipleSelection = [];
            this.$refs.table.clearSelection();
            util.successMsg("删除成功");
            this.getData();
          }).catch(res => {
          });
        }).catch(() => {
        });
      } else {
        util.errorMsg("请先选择数据 ！");
      }
    },
    handleSelectionChange (val) { // 多选
      this.multipleSelection = val;
    },
    handleCurrentChange (val) { // 切换分页
      this.page = val
      this.handlePage()
    },

    // 打开成绩详情
    async show (row) {
      this.curRow = row
      this.detailVisible = true
      this.initDetailData()
    },
    // 查询成绩详情
    async getDetail () {
      const { data } = await this.$post(this.api.productReadGradeDetails, {
        pageNum: this.pageDetail,
        pageSize: this.pageSizeDetail,
        mallId: this.id,
        permissions: +this.curTab,
        studentAccountId: this.curRow.accountId
      })
      this.details = data.records
      this.totalDetail = data.total
    },
    initDetailData () {
      this.pageDetail = 1
      this.getDetail()
    },
    // 详情分页
    handleCurrentDetailChange (val) {
      this.pageDetail = val
      this.getDetail()
    },
    // 导出
    async exportDetail () {
      const practice = this.curTab == 0 // 练习
      if (this.details.length) {
        const res = await axios.post(this.api[practice ? 'exportDetailsOfStudentPracticeScores' : 'exportDetailsOfStudentAssessmentResults'], {
          pageNum: 1,
          pageSize: 1000,
          mallId: this.id,
          permissions: +this.curTab,
          studentAccountId: this.curRow.accountId,
          goodsName: this.curriculumgoodsNameName
        }, {
          headers: {
            token: this.token
          },
          responseType: 'blob'
        })
        util.downloadFileDirect(`${this.curRow.userName}_${practice ? '练习' : '考核'}成绩详情.xlsx`, new Blob([res.data]))
      }
    },
    // 查看成绩报告
    toReport (row) {
      this.$store.commit('achievement/setRow', this.curRow)
      // 考核跳实验报告，练习跳项目维度的成绩详情
      this.$router.push(this.curTab == 1 ? `show?reportId=${row.reportId}` : `project?id=${row.projectId}&projectName=${row.goodsName}&classId=${this.curRow.classId || ''}&workNumber=${row.workNumber || row.userName}&mallId=${this.id}`)
    },
    getChart () { // 初始化折线图
      const data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
      const list = this.listDataAll
      const prop = this.curTab == 0 ? 'avgScore' : 'averageScore'
      list.map(n => {
        const val = n[prop]
        if (val === 0) {
          data[0]++;
        } else if (val > 0 && val <= 10) {
          data[1]++;
        } else if (val > 10 && val <= 20) {
          data[2]++;
        } else if (val > 20 && val <= 30) {
          data[3]++;
        } else if (val > 30 && val <= 40) {
          data[4]++;
        } else if (val > 40 && val <= 50) {
          data[5]++;
        } else if (val > 50 && val <= 60) {
          data[6]++;
        } else if (val > 60 && val <= 70) {
          data[7]++;
        } else if (val > 70 && val <= 80) {
          data[8]++;
        } else if (val > 80 && val <= 90) {
          data[9]++;
        } else if (val > 90 && val <= 100) {
          data[10]++;
        }
      })

      let myChart = echarts.init(document.getElementById("chart"));
      myChart.setOption({
        title: { text: "实验分数分布图" },
        tooltip: {},
        xAxis: {
          name: this.curTab == 1 ? "分数" : "平均分",
          type: "category",
          boundaryGap: false,
          interval: 10,
          data: ["0", "10", "20", "30", "40", "50", "60", "70", "80", "90", '100']
        },
        yAxis: {
          name: "人数",
          type: "value",
          interval: 1
        },
        series: [{
          data,
          type: "line",
          areaStyle: {},
          color: ["#8191fd"]
        }]
      })
      this.loadIns.close()
    },
    // 错误率统计图
    errorChart () {
      const data = this.errorAnalysis
      console.log("🚀 ~ file: course.vue:585 ~ errorChart ~ data:", data)
      const maxFontLength = data.length > 13 ? 6 : 10
      const option = {
        tooltip: {
          trigger: 'axis',
        },
        grid: {
          left: '5%',
          right: '5%',
          top: '10%',
          bottom: '30%'
        },
        dataZoom: [//滑动条
          {
            // xAxisIndex: 0,//这里是从X轴的0刻度开始
            show: true,
            type: 'slider',
            start: 0,
            end: 150,
            xAxisIndex: [0],
            bottom: -10,
          },
          // {
          //   // xAxisIndex: 0,//这里是从X轴的0刻度开始
          //   type: 'inside',
          //   realtime: true,
          //   start: 0,
          //   end: 150,
          // }
        ],
        xAxis: [{
          type: 'category',
          axisLine: {
            lineStyle: {
              color: '#57617B'
            }
          },
          interval: 5,
          splitNumber: 5,
          axisLabel: {
            // interval: '',
            textStyle: {
              color: '#333',
            },
            formatter: function (value, index) {
              value = value.substring(0, maxFontLength) + (value.length > maxFontLength ? '...' : '')
              // if (index % 2 != 0) {
              //   return '\n\n' + value;
              // } else {
              //   return value;
              // }
              return value
            },
            rotate: data.length > 16 ? 45 : 0
          },
          data: data.map(e => e.projectName)
        }],
        yAxis: [
          {
            type: 'value',
            name: '错误率',
            nameGap: 10,
            axisLine: {
              lineStyle: {
                color: '#333'
              }
            },
            axisLabel: {
              margin: 10,
              textStyle: {
                fontSize: 12,
                color: '#333'
              },
              formatter: '{value}%'
            },
          }
        ],
        series: [{
          name: '错误率',
          type: 'bar',
          barWidth: 25,
          axisLabel: {
            margin: 10,
            textStyle: {
              fontSize: 12,
              color: '#333'
            },
            formatter: '{value}%'
          },
          itemStyle: {
            normal: {
              barBorderRadius: [10, 10, 0, 0],
              color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [{
                offset: 0,
                color: "#009AFD"
              }, {
                offset: 0.8,
                color: "#33DAFF"
              }], false),
              shadowColor: 'rgba(0, 0, 0, 0.1)',
            }
          },
          data: data.map(e => e.errorRate)
        }
        ]
      }
      echarts.init(document.querySelector(`#chart1`)).setOption(option)
    }
  }
};
</script>

<style lang="scss" scoped>
/deep/ .head-card {
    .el-card__body {
        padding-bottom: 0px;

        .el-tabs__header {
            margin-bottom: 1px;

            .el-tabs__nav-wrap::after {
                display: none;
            }

            .el-tabs__item {
                font-size: 18px;
            }
        }
    }
}

.chart {
    height: 300px;
}
.stat {
    display: flex;
    .nums {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        width: 640px;
        margin-right: 20px;

        .item {
            width: 300px;
            padding: 30px 30px;
            margin: 0 10px;
            box-sizing: border-box;
            border-radius: 8px;
            background: url('../../../assets/img/total.png') 0 0/100% 100% no-repeat;
            p {
                font-size: 18px;
                color: #ffffff;
            }
            .val {
                margin-top: 10px;
                color: #ffffff;
                font-size: 36px;
            }
        }
        .item:nth-child(2) {
            background-image: url('../../../assets/img/avg.png');
        }
        .item:nth-child(3) {
            background-image: url('../../../assets/img/ach1.png');
        }
        .item:nth-child(4) {
            background-image: url('../../../assets/img/ach2.png');
        }
    }
    .chart {
        width: calc(100% - 660px);
    }
}
.wrong {
    .line {
        display: flex;
        width: 920px;
        margin: 0 auto 10px;
        .jud-name {
            width: 500px;
            margin-right: 100px;
        }
    }
}
</style>