<template>
  <div>
    <el-card shadow="hover" class="m-b-20 head-card">
      <div class="flex-between m-b-20">
        <el-page-header v-if="grades.length" @back="back" :content="grades[index].stageName + '/排名'"></el-page-header>
      </div>

    </el-card>

    <el-card shadow="hover" v-loading="loading" class="m-b-20">
      <div class="tabs">
        <template v-for="(item, i) in grades">
          <a v-if="i === index || !item.stageId" :key="i" class="item" :class="{ active: item.stageId == active }"
            @click="tabChange(item.stageId)">{{ item.stageName }}排名</a>
        </template>
      </div>
      <div class="flex-between" style="margin: 20px 0">
        <div style="display: inline-flex;align-items: center">
          <el-radio v-model="type" :label="0" @change="typeChange">默认系统排序</el-radio>
          <el-radio v-model="type" :label="1" @change="typeChange">手动上传</el-radio>
          <el-button type="primary" :disabled="type === 0" class="ml20" @click="batchImport">上传文件</el-button>
        </div>
        <div style="display: inline-flex;align-items: center">
          <el-input style="margin-right: 15px" :placeholder="'请输入' + (competitionType ? '团队名称/队长' : '学生姓名') + '/学校'"
            prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
          <el-button v-if="!published" type="primary" @click="cancelPublish(1)">发布排名</el-button>
          <template v-else>
            <span style="margin-right: 10px;white-space: nowrap;">{{ publishTime }}发布排名</span>
            <el-button type="primary" @click="cancelPublish(0)">取消发布</el-button>
          </template>
          <el-button v-if="list.length" type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' :
            '批量导出'
            }}</el-button>
        </div>
      </div>
      <el-table :data="list" class="table" ref="table" stripe row-key="scoreId"
        @selection-change="handleSelectionChange" header-align="center">
        <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>
        <template v-if="competitionType == 1">
          <el-table-column prop="teamName" label="团队名称" min-width="150" align="center"></el-table-column>
          <el-table-column prop="leaderName" label="队长" min-width="150" align="center"></el-table-column>
        </template>
        <el-table-column v-else prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column>
        <el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column>
        <el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column>
        <el-table-column prop="timeSum" label="用时" width="90" align="center">
          <template slot-scope="scope">
            {{ scope.row.timeSum + (scope.row.timeSum === '—' ? '' : 'min') }}
          </template>
        </el-table-column>
        <el-table-column prop="score" label="分数" width="90" align="center"></el-table-column>
        <el-table-column label="得分详情" align="center" width="160">
          <template slot-scope="scope">
            <el-button v-if="(!competitionType && scope.row.reportId) || competitionType" type="text"
              @click="show(scope.row, scope.$index)">查看</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="teamVisible" width="900px" :close-on-click-modal="false">
      <h6 v-if="active" style="margin-bottom: 10px;font-size: 16px;">团队名称：{{ curRow.teamName }} 阶段名称：{{ stageName }}
      </h6>
      <table class="table tc">
        <tr>
          <template v-if="!active">
            <th width="100">阶段</th>
            <th width="100">团队成绩</th>
          </template>
          <th width="60">序号</th>
          <th width="100">姓名</th>
          <th width="100">学校</th>
          <th width="100">用时</th>
          <th width="100">分数</th>
          <th width="100">得分详情</th>
        </tr>
        <template v-if="teams.length">
          <tr v-for="(item, i) in teams" :key="i">
            <template v-if="!active && item.rowspan">
              <td :rowspan="item.rowspan">{{ item.stageName }}</td>
              <td class="scores" :rowspan="item.rowspan">
                <p class="score">{{ item.teamScore }}</p>
                <p>{{ item.teamCalculationMethodName }}</p>
                <template v-if="isPointWeight">
                  <p>权重：</p>
                  <p>{{ item.pointWeight }}%</p>
                </template>
              </td>
            </template>
            <template v-if="item.accountId">
              <td>{{ i + 1 }}</td>
              <td>{{ item.userName }}</td>
              <td>{{ item.realSchool }}</td>
              <td>{{ item.timeSum }}min</td>
              <td>{{ item.score }}</td>
              <td>
                <el-button v-if="item.reportId" type="text" @click="toReport(item)">查看</el-button>
              </td>
            </template>
            <td v-else colspan="6"></td>
          </tr>
        </template>
        <tr v-else>
          <td colspan="99">暂无数据</td>
        </tr>
        <tr v-if="!active && teams.length">
          <td>综合得分</td>
          <td>{{ curRow.score }}</td>
          <td colspan="6">总排名：第{{ curRow.index }}名</td>
        </tr>
      </table>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" type="primary" @click="teamVisible = false">确定</el-button>
      </span>
    </el-dialog>

    <el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false"
      @close="cancelUpload">
      <div style="text-align: center">
        <template v-if="!uploadFaild">
          <div style="margin-bottom: 10px;">
            <el-button type="primary" @click="download">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
          </div>
          <el-upload ref="upload" name="file" accept=".xls,.xlsx" class="import-file" :before-upload="beforeUpload"
            :on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove"
            :limit="1" :on-exceed="handleExceed" :action="this.api.batchImportRanking" :file-list="uploadList"
            :headers="headers" :disabled="uploading" :data="{
              competitionId: this.id,
              stageId: this.stageId,
              isOverallRanking: active ? 0 : 1,
              schoolId: ''
            }">
            <el-button type="primary" :loading="uploading" class="ml20">上传文件<i
                class="el-icon-upload2 el-icon--right"></i></el-button>
          </el-upload>
        </template>
        <template v-else>
          <p style="margin: -10px 0 13px;font-size: 14px;color: #e90000;">{{ faildData.tip }}</p>
          <p type="primary"
            style="margin-bottom: 10px;font-size: 14px;color: #9076FF;text-decoration: underline;cursor: pointer;"
            @click="showFaild">部分数据导入失败，查看失败原因</p>
        </template>
      </div>
      <span v-if="uploading" slot="footer" class="dialog-footer">
        <el-button @click="cancelUpload">停止导入</el-button>
      </span>
    </el-dialog>

    <el-dialog title="请选择发布排名时间" :visible.sync="publishVisible" width="260px" :close-on-click-modal="false"
      custom-class="publish-dia">
      <el-date-picker popper-class="no-atTheMoment" v-model="publishTime" placeholder="请选择结束时间" type="datetime"
        :picker-options="pickerOptions">
      </el-date-picker>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" @click="publishVisible = false">取 消</el-button>
        <el-button size="small" type="primary" @click="publishTimeSubmit">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import Util from '@/libs/util'
import axios from 'axios'
export default {
  data () {
    return {
      id: +this.$route.query.id,
      stageId: +this.$route.query.stageId,
      index: +this.$route.query.index,
      method: +this.$route.query.method,
      competitionType: +this.$route.query.competitionType,
      rule: +this.$route.query.rule,
      searchTimer: null,
      keyword: this.$route.query.keyword || '',
      teamCalculationMethods: [
        {
          id: 0,
          name: '最高分'
        },
        {
          id: 1,
          name: '平均分'
        },
        {
          id: 2,
          name: '求和'
        }
      ],
      headers: {
        token: sessionStorage.getItem("token")
      },
      active: '',
      grades: [],
      list: [],
      page: +this.$route.query.page || 1,
      pageSize: 10,
      total: 0,
      type: 0,
      teamVisible: false,
      teams: [],
      memberVisible: false,
      members: [],
      importVisible: false,
      uploadList: [],
      uploadFaild: false,
      uploading: false,
      faildData: null,
      curRow: {},
      stageName: '',
      totalScore: 0,
      published: false,
      uploadData: [],
      sourceType: '',
      publishVisible: false,
      publishTime: '',
      timeId: '',
      pickerOptions: {
        // 控制过往日期不可选
        disabledDate (time) {
          return time.getTime() < Date.now() - 8.64e7;
        },
        // 控制过往时间不可选
        selectableRange: (() => {
          let data = new Date();
          let hour = data.getHours();
          let minute = data.getMinutes();
          let second = data.getSeconds();
          return [`${hour}:${minute}:${second} - 23:59:59`]
        })(),
      },
      uploaded: 0,
      multipleSelection: [],
      loading: false,
      exporting: false,
      isPointWeight: false
    };
  },
  watch: {
    keyword: function (val) {
      clearTimeout(this.searchTimer);
      this.searchTimer = setTimeout(() => {
        this.$router.push({
          path: '/matchRank',
          query: {
            ...this.$route.query,
            keyword: val
          }
        })
        this.getRank();
      }, 500);
    }
  },
  mounted () {
    this.getStage()
  },
  methods: {
    // 获排名
    getData () {
      this.$post(`${this.api.selectTheLastSortStatus}?competitionId=${this.id}&stageId=${this.active || this.stageId}&isOverallRanking=${this.active ? 0 : 1}`).then(({ source }) => {
        this.sourceType = source
        this.type = source == 1 ? 1 : 0
        this.getRank()
      }).catch(res => { })
    },
    // 查询排名
    getRank () {
      this.loading = true
      // 手动上传的排名接口
      if (this.type) {
        this.$post(this.api.manuallyUploadedRankings, {
          pageNum: this.page,
          pageSize: this.pageSize,
          competitionId: this.id,
          isOverallRanking: this.active ? 0 : 1,
          stageId: this.active || this.stageId,
          keyword: this.keyword
        }).then(({ message, publishStatus }) => {
          // isRelease 0未发布，1已发布
          this.published = publishStatus
          this.sourceType = message.total ? message.records[0].isRelease : 0
          this.list = message.records
          this.total = message.total
          this.getPublishTime()
          this.loading = false
        }).catch(res => {
          this.loading = false
        })
      } else { // 默认排名接口
        if (!this.active) {
          // 总分排名
          const ids = this.grades.map(e => e.stageId)
          this.$post(this.api.overallStandingsInThePointsRace, {
            pageNum: this.page,
            pageSize: this.pageSize,
            competitionId: this.id,
            publicationType: this.type,
            locationStageId: this.stageId,
            stageIds: ids.splice(0, ids.length - 1),
            keyword: this.keyword
          }).then(({ page, publishStatus, total }) => {
            this.published = publishStatus
            this.list = page || []
            this.total = total
            this.getPublishTime()
            this.loading = false
          }).catch(res => {
            this.loading = false
          })
        } else {
          // 阶段排名
          this.$post(`${this.api.stageRaceRanking}?competitionId=${this.id}&stageId=${this.active}&pageNum=${this.page}&pageSize=${this.pageSize}&publicationType=${this.type}&keyword=${this.keyword}`).then(({ page, total, publishStatus }) => {
            this.published = publishStatus
            this.list = page
            this.total = total
            this.getPublishTime()
            this.loading = false
          }).catch(res => {
            this.loading = false
          })
        }
      }
    },
    // 获取阶段
    async getStage () {
      this.loading = true
      try {
        const { page } = await this.$post(this.api.detailsOfCompetitionStage, {
          pageNum: 1,
          pageSize: 100,
          contestId: this.id,
        })
        this.grades = page.records.slice(0, this.index + 1)
        this.active = this.grades[this.index].stageId
        // 积分赛才显示总分
        this.rule == 0 && this.grades.push({
          stageId: 0,
          stageName: '总分'
        })
        this.getData()
      } catch (e) {
        this.loading = false
      }
    },
    // 排序类型切换回调
    async typeChange (val) {
      await this.$post(`${this.api.toggleTheSortingMode}?competitionId=${this.id}&stageId=${this.active || this.stageId}&isOverallRanking=${this.active ? 0 : 1}&whetherToManuallyPublish=${this.type}`)
      this.getRank()
    },
    initData () {
      this.page = 1
      this.getData()
    },
    // tab回调
    tabChange (i) {
      this.type = 0
      this.active = i
      this.initData()
    },
    // 查看详情
    show (row, i) {
      this.teams = []
      // 个人：跳转实验报告，团队：弹框显示成员列表
      if (this.competitionType == 1) {
        row.index = i + 1
        this.curRow = row
        this.teamVisible = true
        this.stageName = this.grades.find(e => e.stageId == this.active).stageName
        const data = {
          pageNum: 1,
          pageSize: 100,
          competitionId: this.id,
          teamId: row.teamId
        }
        // 阶段传当前阶段的id，总分传所有阶段的id
        if (this.active) {
          data.stageId = this.active
          this.$post(this.api.stageTeamScoreDetails, data).then(({ page }) => {
            this.teams = page.records
          }).catch(res => { })
        } else {
          const ids = this.grades.map(e => e.stageId)
          ids.pop()
          data.stageIds = ids.splice(0, this.index + 1)
          // 发布跟没发布调不同的接口
          // if (this.published) {
          this.$post(this.api.totalRankingScoreDetails, data).then(res => {
            this.isPointWeight = res.isPointWeight
            if (res.data.length) {
              const result = []
              // 合并数据
              res.data.map(e => {
                const team = e.stageTeamInformation
                if (team.length) {
                  const teamCItem = this.teamCalculationMethods.find(n => n.id == e.teamCalculationMethod)
                  if (teamCItem) team[0].teamCalculationMethodName = teamCItem.name
                  team[0].rowspan = team.length
                  team.map(n => {
                    n = Object.assign(n, e)
                  })
                  result.push(...team)
                } else {
                  e.rowspan = 1
                  result.push(e)
                }
              })
              this.teams = result
            }
          }).catch(res => { })
          // } else { // 没发布
          //   this.$post(this.api.totalRankingScoreDetails, data).then(({ page }) => {
          //     const list = page.records
          // page.records.map((e, i) => {
          //   if (!list.find(n => n.stageId == e.stageId && n.rowspan)) {
          //     e.rowspan = list.filter(n => n.stageId == e.stageId).length
          //     this.$post(this.api.stageTeamScoreDetails, {
          //       pageNum: 1,
          //       pageSize: 100,
          //       competitionId: this.id,
          //       teamId: row.teamId,
          //       stageId: e.stageId
          //     }).then(({ page }) => {

          //     }).catch(res => {})
          //   }
          // })
          //   let totalScore = 0
          //   this.totalScore = totalScore
          //   this.teams = list
          //   console.log("🚀 ~ file: matchRank.vue:346 ~ this.$post ~ list", list)

          // }).catch(res => {})
          // }

        }
      } else {
        this.toReport(row)
      }
    },
    // 跳转实验报告
    toReport (row) {
      this.$router.push(`/${this.method !== 1 ? 'trialReport' : 'theoryReport'}?reportId=${row.reportId}`)
    },
    handleSelectionChange (val) { // 多选
      this.multipleSelection = val;
    },
    handleCurrentChange (val) { // 切换分页
      this.$router.push({
        path: '/matchRank',
        query: {
          ...this.$route.query,
          page: val
        }
      })
      this.page = val;
      this.getData();
    },
    // 导出(有勾选：就导勾选中的；没有勾选：就导全部)
    async exportData () {
      this.exporting = true
      let { list } = this
      if (this.multipleSelection.length) {
        list = this.multipleSelection
      } else {
        // 没勾选的情况：先查询所有数据，pageSize传10000，再导出全部

        // 手动上传的排名接口
        if (this.type) {
          const res = await this.$post(this.api.manuallyUploadedRankings, {
            pageNum: 1,
            pageSize: 10000,
            competitionId: this.id,
            isOverallRanking: this.active ? 0 : 1,
            stageId: this.active || this.stageId
          })
          list = res.message.records
        } else { // 默认排名接口
          if (!this.active) {
            // 总分排名
            const ids = this.grades.map(e => e.stageId)
            const res = await this.$post(this.api.overallStandingsInThePointsRace, {
              pageNum: 1,
              pageSize: 10000,
              competitionId: this.id,
              publicationType: this.type,
              locationStageId: this.stageId,
              stageIds: ids.splice(0, ids.length - 1)
            })
            list = res.page
          } else { // 阶段排名
            const res = await this.$post(`${this.api.stageRaceRanking}?competitionId=${this.id}&stageId=${this.active}&pageNum=1&pageSize=10000&publicationType=${this.type}`)
            list = res.page
          }
        }
      }
      list.forEach((e, i) => {
        e.serialNumber = i + 1
        if (e.leaderName) e.userName = e.leaderName
      })
      axios.post(this.api[this.competitionType ? 'derivedRanking' : 'individualDerivedRanking'], list, {
        headers: this.headers,
        responseType: 'blob'
      }).then((res) => {
        Util.downloadFileDirect(`${this.grades.find(e => e.stageId == this.active).stageName}排名.xls`, new Blob([res.data]))
        this.exporting = false
      }).catch(res => { })
    },
    // 发布排名
    async publishSubmit () {
      await this.$post(this.api.publishRanking, {
        competitionId: this.id,
        isOverallRanking: this.active ? 0 : 1,
        publicationType: this.type,
        releaseTime: Util.formatDate("yyyy-MM-dd hh:mm:ss", this.publishTime),
        stageId: this.active || this.stageId,
      })
      this.uploadData = []
    },
    // 发布排名确认
    publish () {
      this.$post(`${this.api.whetherToPublish}?competitionId=${this.id}&stageId=${this.active || this.stageId}&isOverallRanking=${this.active ? 0 : 1}&publicationType=${this.type}`).then(({ whetherToPublish }) => {
        whetherToPublish ?
          this.$confirm('排名已经发布，是否直接覆盖？', '提示', {
            type: 'success',
            closeOnClickModal: false
          }).then(() => {
            this.publishSubmit()
          }).catch(() => { }) :
          this.publishSubmit()
      }).catch(res => { })
    },
    // 获取定时发布排名
    async getPublishTime () {
      const res = await this.$post(this.api.getCompetitionStageRankingTime, {
        competitionId: this.id,
        isOverallRanking: this.active ? 0 : 1,
        publicationType: this.type,
        stageId: this.active || this.stageId,
      })
      if (res.releaseTime) {
        this.published = true
        this.timeId = res.releaseTime.id
        this.publishTime = res.releaseTime.releaseTime
      } else {
        this.published = false
        this.timeId = ''
        this.publishTime = ''
      }
    },
    // 定时发布排名
    async publishTimeSubmit () {
      const { startTime, endTime } = this.grades[this.index]
      const now = await Util.getNow()
      if (now <= new Date(endTime)) return Util.errorMsg('当前阶段还在进行中,请在本阶段结束后再发布!')

      this.publishSubmit()
      // await this.$post(this.api.addCompetitionStageRankingTime, {
      //   competitionId: this.id,
      //   isOverallRanking: this.active ? 0 : 1,
      //   publicationType: this.type,
      //   stageId: this.active || this.stageId,
      //   releaseTime: Util.formatDate("yyyy-MM-dd hh:mm:ss", this.publishTime)
      // })

      Util.successMsg('发布成功')
      this.getData()
      this.uploaded = 0
      this.publishVisible = false
    },
    // 取消发布排名
    async cancelPublish (publish) {
      const ids = this.grades.map(e => e.stageId)
      const stageIds = ids.splice(0, ids.length - 1)
      const query = []
      stageIds.map(e => {
        query.push('stageIds=' + e)
      })
      // 如果是发布排名，则先删除已发布的排名，再调发布排名的接口
      // 如果是取消发布，则直接调取消发布的接口
      if (publish) {
        // 如果是手动发布，并且没有上传排名，则提示
        if (this.type && !this.uploaded && !this.list.length) {
          return Util.errorMsg('请先上传数据！')
        } else {
          this.publishTime = new Date()
          this.publishVisible = true
        }
      } else {
        try {
          // 取消定时发布的接口跟取消普通发布的接口不一样
          // if (this.timeId) {
          // await this.$post(`${this.api.cancelCompetitionStageRankingTime}?competitionId=${this.id}&releaseId=${this.timeId}&isOverallRanking=${this.active ? 0 : 1}&stageId=${this.active || this.stageId}`)
          // } else {
          await this.$post(`${this.api.cancelRanking}?competitionId=${this.id}&isOverallRanking=${this.active ? 0 : 1}&${this.active ? 'stageIds=' + this.active : query.join('&')}&releaseId=${this.timeId}&publicationType=${this.type}`)
          // }
          this.sourceType = ''
          this.type = 0
          this.getData()
          Util.successMsg('取消发布成功！')
        } catch (error) { }
      }
    },
    // 批量导入
    batchImport () {
      this.importVisible = true
      this.uploadList = []
      this.uploadFaild = false
    },
    // 模板下载
    download () {
      location.href = this.api[this.competitionType == 1 ? 'rankImportTeam' : 'rankImportPerson']
    },
    // 上传文件
    handleExceed (files, fileList) {
      Util.warningMsg(
        `当前限制选择 1 个文件，如需更换，请删除上一个文件再重新选择！`
      )
    },
    // 下载失败文件
    showFaild () {
      axios.get(`${this.api.rankExportFailure}?exportCode=${this.faildData.exportCode}&competitionId=${this.id}`, {
        headers: this.headers,
        responseType: 'blob'
      }).then((res) => {
        Util.downloadFileDirect(`批量导入排名管理失败数据导出.xls`, new Blob([res.data]))
      }).catch(res => { })
    },
    uploadSuccess (res) {
      this.uploading = false
      this.uploadFaild = false
      this.uploaded = 0
      if (res.status === 200) {
        this.getRank()
        const { data } = res
        if (data.exportCode) {
          this.faildData = data
          this.uploadFaild = true
        } else {
          this.uploaded = 1
          this.importVisible = false
          Util.successMsg(data.tip, 3000)
          // Util.successMsg('请检查数据后，点击发布排名以发布数据！')
        }
      } else {
        Util.errorMsg(res.message || "上传失败，请检查数据")
      }
    },
    uploadError (err, file, fileList) {
      this.uploading = false
      this.$message({
        message: "上传出错，请重试！",
        type: "error",
        center: true
      })
    },
    async beforeUpload (file) {
      this.uploading = true
      if (this.list.length) {
        await this.$post(`${this.api.cancelRanking}?competitionId=${this.id}&isOverallRanking=${this.active ? 0 : 1}&${this.active ? 'stageIds=' + this.active : query.join('&')}&releaseId=${this.timeId}&publicationType=${this.type}`)
      }
    },
    beforeRemove (file, fileList) {
      return this.$confirm(`确定移除 ${file.name}？`)
    },
    handleRemove (file, fileList) {
      this.uploadList = fileList
      this.uploadFaild = false
    },
    cancelUpload () {
      this.uploading = false
      if (this.$refs.upload) this.$refs.upload.abort()
      this.keyword = ''
      this.getRank()
      this.importVisible = false
    },
    back () {
      this.$router.push(this.$store.state.innerReferrer)
    }
  }
};
</script>

<style lang="scss" scoped>
.table {
  width: 100%;
  border-collapse: collapse;

  th,
  td {
    padding: 12px;
    border: 1px solid #ebeef5;
  }

  &.tc {
    text-align: center;
  }

  th {
    text-align: center;
    background-color: #f8faff;
  }

  .scores {
    line-height: 1.6;
  }

  .score {
    font-size: 16px;
    font-weight: 600;
    color: #9076ff;
  }
}

/deep/.import-file {
  .el-progress__text,
  .el-progress,
  .el-upload-list__item-status-label {
    display: none !important;
  }
}
</style>