<template>
  <div class="wrap index">

    <div class="banner"
      :style="{ backgroundImage: 'url(' + (form.carouselUrl || 'https://huoran.oss-cn-shenzhen.aliyuncs.com/20220613/png/1536269450851409920.png') + ')' }">
    </div>
    <div class="center-con">
      <div class="center-wrap">
        <breadcrumb :routes.sync="routes" />
        <div class="content">
          <div :class="['tool flex-between', { logView: !logView }]">
            <el-tabs v-model="curType" @tab-click="typeChange">
              <el-tab-pane v-for="(item, index) in typeList" :key="index" :label="item.name"
                :name="item.id"></el-tab-pane>
            </el-tabs>
            <div class="action">
              <p class="end-text" v-if="end">
                距离{{ endList[status] }}还有
                <em>{{ end }}</em>
              </p>
              <div class="m-l-20">
                <p v-if="status"
                  :class="['sign-status', { signing: status == 2, signed: status == 1, playing: status == 4 }]">{{
                    form.competitionRegistration ? '已报名' : '未报名' }}</p>
                <el-dropdown v-if="playingStages.length > 1" @command="chooseStage">
                  <el-button type="primary" style="background-color: #f96d6d;border: 0;">
                    选择竞赛<i class="el-icon-arrow-down el-icon--right"></i>
                  </el-button>
                  <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item v-for="(item, i) in playingStages" :key="i" :command="item">进入{{ item.stageName
                      }}</el-dropdown-item>
                  </el-dropdown-menu>
                </el-dropdown>
                <div v-else-if="status != 4 || (status == 4 && curStage)" class="status"
                  :class="{ wait: status == 0, signing: status == 2, signed: status == 1, playing: status == 4, finish: status == 3 || status == 5 }"
                  :title="statusList[status]" @click.stop="signup">{{ statusList[status] }}</div>
              </div>
            </div>
          </div>
          <div class="info">
            <h6 class="title">{{ form.name }}</h6>
            <div class="meta">最近编辑时间：{{ form.updateTime }}</div>
          </div>

          <div v-show="curType < 4">
            <div class="l-title" id="part1"><img src="@/assets/img/label.png" alt=""> 竞赛信息</div>
            <div v-if="form.description" class="texts ql-editor" v-html="form.description"></div>
            <template v-if="form.competitionAnnexList">
              <h6 class="p-title">附件下载</h6>
              <ul class="files">
                <li v-for="(item, i) in form.competitionAnnexList" :key="i">
                  <el-link v-if="item.canPreview" class="m-r-10" type="primary" @click="preview(item)">{{ item.fileName
                    }}</el-link>
                  <span v-else class="fileName">{{ item.fileName }}</span>
                  <el-link type="primary" :underline="false" @click="download(item)">下载</el-link>
                </li>
              </ul>
            </template>

            <template v-if="form.releaseType">
              <div class="l-title"><img src="@/assets/img/label.png" alt=""> 赛程、规则与内容</div>
              <h6 class="rule-title">共{{ form.competitionStage.length }}个竞赛阶段<template
                  v-if="info.teamLimit">，同一个团队每个成员只能参加一个阶段赛项</template>
              </h6>
              <div v-for="(rule, i) in form.competitionStage" :key="i" class="rule">
                <p style="font-size: 16px;color: #333;">{{ rule.stageName }}</p>
                <p>比赛时间：{{ rule.startTime && rule.startTime + ' ~ ' + rule.endTime }}</p>
                <p>比赛方式：{{ methods.find(e => e.id == rule.method) && methods.find(e => e.id == rule.method).name }}</p>
                <p v-if="rule.method != 2">课程系统：{{ rule.systemName }}</p>
                <p v-if="rule.onlineButton && rule.method != 2">线上地点：{{ rule.onlineAddress }}</p>
                <p v-if="rule.offlineButton">线下地点：{{ rule.offlineAddress }}</p>
                <template v-if="rule.method === 2">
                  <p>比赛地点：{{ rule.offlineAddress }}</p>
                  <p>比赛内容：{{ rule.contentDescription }}</p>
                  <p>评分规则：{{ rule.scoreRule }}</p>
                </template>

                <template v-if="form.completeCompetitionSetup.competitionType">
                  <p>每个团队参赛人数限制：{{ rule.teamNumLimit ? rule.customNumber : '不限制' }}</p>
                  <p>团队成绩计算方式：{{ teamCalculationMethods.find(e => e.id == rule.teamCalculationMethod) &&
                    teamCalculationMethods.find(e => e.id == rule.teamCalculationMethod).name }}</p>
                </template>
                <!-- <p v-if="rule.resultAnnouncementTime != 0">阶段比赛结束后{{ rule.resultAnnouncementTime }}小时，公布阶段比赛成绩。</p> -->
                <div v-if="form.rule === 1 && i !== form.competitionStage.length - 1" class="flex">
                  <p>晋级规则：</p>
                  <div>
                    <p v-if="rule.peopleLimit">本阶段成绩排名前{{ rule.peopleLimit }}队，可晋级下一阶段比赛</p>
                    <p v-if="rule.percentageLimit">本阶段成绩排名前{{ rule.percentageLimit }}%，可晋级下一阶段比赛</p>
                    <p v-if="rule.scoreLimit">本阶段成绩{{ rule.scoreLimit }}分，可晋级下一阶段比赛</p>
                  </div>
                </div>
              </div>
            </template>

            <!-- 进展 -->
            <div class="l-title" id="part2"><img src="@/assets/img/label.png" alt=""> 竞赛进展</div>
            <ul class="progress" v-if="progress.length">
              <li v-for="(item, index) in progress" :key="index"
                :class="item.status == 0 ? 'not' : (item.status == 1 ? 'ing' : 'done')">
                <i class="dot"></i>
                <p class="name">{{ item.title }}</p>
                <p class="desc">{{ item.description }}</p>
              </li>
              <img class="rocket" src="@/assets/img/rocket.png" alt="">
            </ul>
            <template v-else>
              <div class="empty">
                <div>
                  <img src="@/assets/img/none.png" alt="">
                  <p>暂无数据</p>
                </div>
              </div>
            </template>

            <!-- 公告 -->
            <div class="l-title" id="part3"><img src="@/assets/img/label.png" alt=""> 通知公告</div>
            <ul class="notice-list" v-if="notices.length">
              <li v-for="(item, i) in notices" :key="i" @click="toNotice(item)">
                <h6>{{ item.announcementTitle }}</h6>
                <p class="meta">{{ item.updateTime }}</p>
                <div class="des" v-html="item.announcementText"></div>
              </li>
            </ul>
            <template v-else>
              <div class="empty">
                <div>
                  <img src="@/assets/img/none.png" alt="">
                  <p>暂无通知公告</p>
                </div>
              </div>
            </template>
          </div>

          <!-- 竞赛排名 -->
          <template v-if="curType == 4">
            <div class="l-title"><img src="@/assets/img/label.png" alt=""> 竞赛排名</div>
            <el-tabs v-model="curArch" @tab-click="getRank">
              <el-tab-pane v-for="(item, index) in arches" :key="index" :label="item.stageName + '排名'"
                :name="item.stageId"></el-tab-pane>
            </el-tabs>
            <el-table ref="table" :data="ranks" stripe max-height="440px" header-align="center">
              <el-table-column type="index" width="60" label="排名" align="center"></el-table-column>
              <template v-if="form.completeCompetitionSetup.competitionType">
                <el-table-column prop="teamName" label="团队名称"></el-table-column>
                <el-table-column prop="leaderName" label="队长"></el-table-column>
              </template>
              <el-table-column v-else prop="userName" label="姓名"></el-table-column>
              <el-table-column prop="realSchool" label="学校"></el-table-column>
              <el-table-column prop="school" label="用时">
                <template slot-scope="scope">
                  {{ scope.row.timeSum }}min
                </template>
              </el-table-column>
              <el-table-column prop="score" label="分数"></el-table-column>
            </el-table>
          </template>

          <template v-if="curType == 5">
            <div class="l-title m-t-20"><img src="@/assets/img/label.png" alt=""> 参赛信息</div>
            <table v-if="form.completeCompetitionSetup.competitionType && info.team.captain === 0" class="table m-b-20">
              <tr>
                <th width="150">团队名称：</th>
                <td>
                  <el-input :disabled="!editing" v-model="info.team.teamName"></el-input>
                </td>
                <th width="150">团队邀请码：</th>
                <td>
                  <el-input :disabled="!editing" maxlength="6" v-model="info.team.invitationCode"></el-input>
                </td>
              </tr>
            </table>
            <div v-if="form.completeCompetitionSetup.competitionType && info.team.captain === 0 && status < 4"
              class="m-b-20 text-center">
              <el-button type="primary" @click="edit(1)">{{ editing ? '保存' : '编辑' }}</el-button>
            </div>
            <table class="table">
              <template v-if="!form.completeCompetitionSetup.competitionType || info.team.captain">
                <tr>
                  <th width="150">姓名：</th>
                  <td>{{ info.person.userName }}</td>
                </tr>
                <tr>
                  <th>学号：</th>
                  <td>{{ info.person.workNumber }}</td>
                </tr>
                <tr>
                  <th>学校：</th>
                  <td>{{ info.person.schoolName }}</td>
                </tr>
              </template>
              <template v-if="form.completeCompetitionSetup.competitionType">
                <tr v-if="info.team.captain">
                  <th width="150">团队名称：</th>
                  <td>
                    <span>{{ info.team.teamName }}</span>
                  </td>
                </tr>
                <template v-if="info.team.captain">
                  <tr>
                    <th>队长：</th>
                    <td>{{ info.caption.userName }}{{ info.caption.schoolName && '，' + info.caption.schoolName }}{{
                      info.caption.workNumber && '，' + info.caption.workNumber }}</td>
                  </tr>
                  <tr>
                    <th>团队成员：</th>
                    <td>
                      <el-tag v-for="(item, i) in info.teamDetail" :key="i" style="margin-right: 5px">{{ item.userName
                        }}</el-tag>
                    </td>
                  </tr>
                  <tr v-if="info.team.captain">
                    <th>团队邀请码：</th>
                    <td>
                      <span>{{ info.team.invitationCode }}</span>
                    </td>
                  </tr>
                </template>
              </template>
              <tr>
                <th width="130">指导老师：</th>
                <td v-if="info.team.captain === 0 || !form.completeCompetitionSetup.competitionType">
                  <div v-if="status != 5" class="plus">
                    <i class="el-icon-circle-plus-outline icon" @click="addAdvisor"></i>
                  </div>
                  <div v-for="(item, i) in info.teamInstructors" :key="i" class="line">
                    <el-input placeholder="请输入姓名" v-model="item.name" clearable size="mini"
                      :disabled="!item.edit"></el-input>
                    <el-input placeholder="请输入职务" maxlength="10" v-model="item.position" clearable size="mini"
                      :disabled="!item.edit"></el-input>
                    <el-input placeholder="请输入手机号" maxlength="11" v-model="item.phone" clearable size="mini"
                      :disabled="!item.edit"></el-input>
                    <template v-if="status < 5">
                      <i v-if="item.edit" class="el-icon-check icon" @click="submitAdvisor(item, i)"></i>
                      <i v-else class="el-icon-edit icon" @click="editAdvisor(item)"></i>
                      <i class="el-icon-delete icon" @click="delAdvisor(item, i)"></i>
                    </template>
                  </div>
                </td>
                <td v-else>
                  <table class="table tc">
                    <tr>
                      <th width="60">姓名</th>
                      <th width="100">职务</th>
                      <th width="100">手机号</th>
                    </tr>
                    <template v-if="info.teamInstructors.length">
                      <tr v-for="(item, i) in info.teamInstructors" :key="i">
                        <td width="60">{{ item.name }}</td>
                        <td width="100">{{ item.position }}</td>
                        <td width="100">{{ item.phone }}</td>
                      </tr>
                    </template>
                    <tr v-else>
                      <td colspan="3">暂无数据</td>
                    </tr>
                  </table>
                </td>
              </tr>
              <tr>
                <th>竞赛阶段：</th>
                <td>
                  <div v-if="showButton" class="m-b-10 text-right">
                    <el-button type="primary" :disabled="status > 3 || hasReport" :loading="allocating"
                      @click="automaticAllocationMember">{{
                        assignRecord.assignOrNot && status < 3 ? '取消' : '' }}自动分配阶段成员</el-button>
                  </div>
                  <table class="table tc">
                    <tr>
                      <th width="70">序号</th>
                      <th width="120">赛项阶段名称</th>
                      <template v-if="form.completeCompetitionSetup.competitionType">
                        <th width="110">参赛人数限制</th>
                        <th>
                          允许参赛人员
                          <el-tooltip v-if="stageTip" effect="dark" content="阶段参赛人员异常，请尽快按照阶段赛规则调整，否则可能影响比赛成绩！"
                            placement="bottom">
                            <i class="info el-icon-warning" style="margin-right: 10px;color: #ff1650;"></i>
                          </el-tooltip>
                        </th>
                      </template>
                      <th v-if="form.rule === 0" width="70">总分</th>
                      <th>竞赛成绩</th>
                    </tr>
                    <template v-if="info.stages.length">
                      <tr v-for="(item, i) in info.stages" :key="i">
                        <td>{{ i + 1 }}</td>
                        <td>{{ item.stageName || form.name }}</td>
                        <template v-if="form.completeCompetitionSetup.competitionType">
                          <td>{{ item.teamNumLimit ? item.customNumber : '不限制' }}</td>
                          <td>
                            <template v-if="item.participants">
                              <el-tag v-for="tag in item.participants" :key="tag.name" class="m-r-5 m-b-5"
                                :closable="info.team.captain === 0 && status < 4" @close="removePar(tag, item)">
                                {{ tag.name }}
                              </el-tag>
                            </template>
                            <span v-else class="m-r-5">无</span>
                            <i v-if="info.team.captain === 0 && status < 4" class="el-icon-edit icon"
                              @click="selectPar(item)"></i>
                            <el-tooltip v-if="stageTip && stageTip[i + 1]" effect="dark" :content="stageTip[i + 1]"
                              placement="bottom">
                              <el-tag type="danger" class="m-l-5">异常</el-tag>
                            </el-tooltip>
                          </td>
                        </template>
                        <!-- 积分赛才需要显示总分这个字段，直接第一行合并表格 -->
                        <td v-if="form.rule === 0 && !i" :rowspan="info.stages.length">{{ info.totalScore }}</td>
                        <td>
                          <!-- 成绩公布时间到了后，才显示下面的分数和查看详情按钮 -->
                          <template v-if="item.showDetail">
                            <span v-if="item.score >= 0" class="m-r-10">分数{{ item.score }}</span>
                            <!-- 团队赛 or （个人赛 并且 是否公布成绩详情勾选的是 并且 有reportId） -->
                            <el-button
                              v-if="form.completeCompetitionSetup.competitionType || (!form.completeCompetitionSetup.competitionType && item.resultsDetails === 0 && item.reportId)"
                              type="text" @click="show(item)">查看成绩详情</el-button>
                          </template>
                        </td>
                      </tr>
                    </template>
                    <tr v-else>
                      <td colspan="6">暂无数据</td>
                    </tr>
                  </table>
                  <!-- 团队&&队长才显示 -->
                  <el-alert v-if="form.completeCompetitionSetup.competitionType && info.team.captain === 0"
                    style="margin-top: 10px;"
                    :title="'注：请团长（团队创建人）设置各阶段参赛成员，只有被选择的允许参赛成员可进入对应阶段比赛' + (info.teamLimit ? '，每个团队成员只能参加一个赛项阶段' : '') + '！'"
                    type="warning" show-icon>
                  </el-alert>
                </td>
              </tr>
            </table>

            <!-- 团队&&队长才显示 -->
            <template v-if="form.completeCompetitionSetup.competitionType && info.team.captain === 0">
              <div class="flex a-center m-t-20 m-b-20">
                <div class="l-title" style="margin: 0 20px 0 0">团队成员</div>
                <el-tag v-for="(item, i) in teamErrors" :key="i" type="danger" style="margin-right: 5px">{{ item
                  }}</el-tag>
              </div>

              <div class="flex-center">
                <p>队长：{{ info.caption.userName }}</p>
                <el-button type="primary" @click="transfer">转让队长</el-button>
              </div>
              <el-alert style="margin: 10px 0;" title="请确保团队成员人数满足大赛要求，否则无法参加比赛" type="success" :closable="false">
              </el-alert>
              <el-table :data="info.teamDetail" stripe header-align="center">
                <el-table-column 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="workNumber" label="学号" min-width="100" align="center"></el-table-column>
                <el-table-column prop="createTime" label="加入时间" width="180" align="center"></el-table-column>
                <el-table-column label="操作" align="center" width="160">
                  <template slot-scope="scope">
                    <el-button v-if="scope.row.captain" type="text" @click="removeLine(scope.row)">踢出团队</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </template>
          </template>
        </div>
      </div>
    </div>

    <el-dialog title="报名" :visible.sync="peopleSignupVisible" :close-on-click-modal="false" width="300px">
      <el-form class="dia-form">
        <el-form-item>
          <el-input placeholder="请输入4位数大赛邀请码" maxlength="4"
            v-model="peopleSignupForm.registrationInvitationCode"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" type="primary" @click="peopleSignupSubmit">报名</el-button>
        <el-button size="small" @click="peopleSignupVisible = false">取消</el-button>
      </span>
    </el-dialog>
    <el-dialog title="报名" :visible.sync="enterVisible" :close-on-click-modal="false" width="300px" @close="enterClose">
      <el-form class="dia-form">
        <p style="margin-bottom: 5px">请选择要加入的团队</p>
        <el-form-item>
          <el-select class="w-100" v-model="enterForm.teamId" filterable>
            <el-option v-for="(item, i) in teams" :key="i" :label="item.teamName" :value="item.teamId"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-input placeholder="请输入团队邀请码" maxlength="6" v-model="enterForm.invitationCode"></el-input>
        </el-form-item>
        <el-form-item v-if="form.completeCompetitionSetup.isNeedCode">
          <el-input placeholder="请输入大赛邀请码" maxlength="6" v-model="enterForm.registrationInvitationCode"></el-input>
        </el-form-item>
        <p class="tips">
          查找不到团队？点击 <el-link :underline="false" type="primary" @click="toTeam">创建团队</el-link>
        </p>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" type="primary" @click="enterSubmit">报名</el-button>
        <el-button size="small" @click="enterVisible = false">取消</el-button>
      </span>
    </el-dialog>
    <el-dialog title="创建团队" :visible.sync="teamVisible" :close-on-click-modal="false" width="300px" @close="teamClose">
      <el-form class="dia-form">
        <el-form-item>
          <el-input placeholder="请输入团队名称" maxlength="10" v-model="teamForm.teamName"></el-input>
        </el-form-item>
        <el-form-item>
          <el-input placeholder="请设置团队邀请码" maxlength="6" v-model="teamForm.invitationCode"></el-input>
        </el-form-item>
        <el-form-item v-if="form.completeCompetitionSetup.isNeedCode">
          <el-input placeholder="请输入大赛邀请码" maxlength="6" v-model="teamForm.registrationInvitationCode"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" type="primary" @click="teamSubmit">创建并报名</el-button>
        <el-button size="small" @click="teamVisible = false">取消</el-button>
      </span>
    </el-dialog>

    <el-dialog title="选择参赛成员" :visible.sync="transferVisible" :close-on-click-modal="false" width="400px">
      <template v-for="(item, i) in info.teamDetail">
        <el-radio v-if="item.captain" :key="i" v-model="checkedPlayer" :label="item.teamId">{{ item.userName
          }}</el-radio>
      </template>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" type="primary" @click="transferSubmit">确定</el-button>
        <el-button size="small" @click="transferVisible = false">取消</el-button>
      </span>
    </el-dialog>
    <el-dialog title="选择参赛成员" :visible.sync="chooseVisible" :close-on-click-modal="false" width="400px">
      <el-checkbox-group v-model="checkedMembers">
        <el-checkbox v-for="(item, i) in chooses" :key="i" :label="item.accountId">{{ item.userName }}</el-checkbox>
      </el-checkbox-group>
      <p v-if="info.teamLimit && curRow.customNumber" style="margin-top: 15px;font-size: 12px;">注：当前阶段限制{{
        curRow.customNumber }}人参赛，且此竞赛每个成员只能参加一个阶段赛项。</p>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" type="primary" @click="chooseSubmit">确定</el-button>
        <el-button size="small" @click="chooseVisible = false">取消</el-button>
      </span>
    </el-dialog>

    <el-dialog title="团队得分详情" :visible.sync="memberVisible" width="900px" :close-on-click-modal="false">
      <h6 v-if="members.length" style="margin-bottom: 10px;font-size: 16px;">团队名称：{{ members[0].teamName }} 阶段名称：{{
        curRow.stageName }}</h6>
      <table class="table tc">
        <tr>
          <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="members.length">
          <tr v-for="(item, i) in members" :key="i">
            <td>{{ i + 1 }}</td>
            <td>{{ item.userName }}</td>
            <td>{{ item.schoolName }}</td>
            <td>{{ item.timeSum }}min</td>
            <td>{{ item.score }}</td>
            <td>
              <!-- 成绩公布时间到了后才显示该按钮 -->
              <el-button v-if="curRow.resultsDetails === 0 && item.reportId" type="text"
                @click="toReport(item)">查看</el-button>
            </td>
          </tr>
        </template>
        <tr v-else>
          <td colspan="6">暂无数据</td>
        </tr>
      </table>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" type="primary" @click="memberVisible = false">确定</el-button>
      </span>
    </el-dialog>

    <el-dialog :title="curStage ? curStage.stageName : ''" :visible.sync="stageVisible" :close-on-click-modal="false"
      width="600px" @close="stageClose">
      <template v-if="curStage && curStage.competitionStageContentSetting">
        <div v-if="curStage.competitionStageContentSetting.systemLink" class="m-b-20">
          <span class="fs-14">进入比赛：</span>
          <el-button type="danger" style="font-size: 13px" @click="toOffline">进入{{ curStage.stageName }}</el-button>
        </div>
        <div v-if="curStage.competitionStageContentSetting.fileUrl" class="flex m-b-20 fs-14">
          <span style="padding-top: 7px">文件下载：</span>
          <div>
            <div v-for="(file, i) in curStage.competitionStageContentSetting.fileList" :key="i">
              <span style="margin-right: 10px;color: #606266;">{{ file.name }}</span>
              <el-button type="text" style="font-size: 14px"
                @click="download({ fileName: file.name, filePath: file.url })">点击下载</el-button>
            </div>
          </div>
        </div>
        <div class="flex m-b-20">
          <span class="fs-14">文件上传：</span>
          <el-upload class="file-upload flex-1" :disabled="uploading" :before-upload="beforeUpload"
            :on-remove="handleRemove" :on-error="uploadError" :before-remove="beforeRemove" :on-preview="handlePreview"
            :limit="1" action="" :on-exceed="handleExceed" :file-list="fileList" :http-request="handleRequest"
            name="file">
            <el-button size="small" type="primary" :loading="uploading"
              :disabled="!!(fileList && fileList.length) || uploading">{{ uploading ? '正在上传' : fileList &&
                fileList.length ? '已上传' : '上传文件' }}</el-button>
            <div slot="tip" class="el-upload__tip relative">
              <el-progress v-if="uploading" class="m-b-5" :stroke-width="3" :percentage="uploadProgress"></el-progress>
              <p>请上传大小1G以内的文件，支持常见文件格式。</p>
              <p>只允许上传一个文件，如有多个文件则需打包再上传。</p>
              <div v-if="fileList.length" class="download" @click="downloadFile">下载</div>
            </div>
          </el-upload>
        </div>

        <div class="fs-14">说明：{{ curStage.competitionStageContentSetting.stageExplain }}</div>
      </template>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" @click="stageVisible = false">关闭</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { mapState, mapMutations } from "vuex";
import breadcrumb from '@/components/breadcrumb'
import Util from '@/libs/util'
import Setting from "@/setting"
import Const from '@/const/match'
import OSS from 'ali-oss'
import OssConfig from '@/components/upload/config.js'
import Oss from '@/components/upload/upload.js'
export default {
  name: 'matchdetail',
  data () {
    return {
      routes: [],
      headers: {
        token: Util.local.get(Setting.tokenKey)
      },
      token: Util.local.get(Setting.tokenKey),
      id: +this.$route.query.id,
      end: '',
      status: '',
      statusList: ["等待报名", "取消报名", "立即报名", "报名截止", "进入竞赛", "已结束"],
      endList: ["报名开始", "报名截止", "报名截止", "竞赛开始", "竞赛结束", ""],
      rules: Const.rules,
      methods: Const.methods,
      teamCalculationMethods: Const.teamCalculationMethods,
      timerList: [],
      form: {
        name: '',
        coverUrl: '',
        description: '',
        signUpStartTime: '',
        signUpEndTime: '',
        playStartTime: '',
        playEndTime: '',
        competitionStage: [],
        completeCompetitionSetup: {},
        competitionRegistration: {}
      },
      curType: '1',
      typeList: [
        {
          id: '1',
          name: '竞赛信息'
        },
        {
          id: '2',
          name: '竞赛进展'
        },
        {
          id: '3',
          name: '通知公告'
        },
        {
          id: '4',
          name: '竞赛排名'
        },
      ],
      progress: [],
      timer: null,
      notices: [],
      noticeDetail: {},
      curArch: '0',
      arches: [],
      ranks: [],

      enterVisible: false,
      enterForm: {
        competitionId: this.$route.query.id,
        teamId: '',
        invitationCode: '',
        registrationInvitationCode: '',
        whetherSignUp: 1
      },

      teamVisible: false,
      teams: [],
      teamNameRepeat: false,
      teamForm: {
        competitionId: this.$route.query.id,
        registrationInvitationCode: '',
        teamName: '',
        invitationCode: '',
        whetherSignUp: 1
      },
      curStage: null,
      choosing: false,
      originInfo: {},
      info: {
        isCaption: 0,
        person: {},
        caption: {},
        team: {
          captain: 1,
          invitationCode: ''
        },
        stages: [],
        teamDetail: [],
        teamInstructors: []
      },
      originIns: {
        id: '',
        position: '',
        name: '',
        phone: '',
      },
      checkedPlayer: '',
      transferVisible: false,
      editing: false,
      memberVisible: false,
      members: [],
      curRow: {},
      chooseVisible: false,
      checkedMember: '',
      checkedMembers: [],
      chooses: [],
      lastType: 1,
      playingStages: [],
      peopleSignupVisible: false,
      peopleSignupForm: {
        registrationInvitationCode: ''
      },
      submiting: false,

      stageVisible: false,
      filesResult: {},
      fileList: [],
      curFileId: '',


      client: null,
      uploading: false,
      uploadProgress: 0,
      now: '',
      allocated: 0,
      teamErrors: [],
      stageTip: null,
      showButton: false,
      hasReport: false,
      assignRecord: {},
      allocating: false,
    };
  },
  computed: {
    ...mapState("user", [
      "userId", 'account', 'logView'
    ]),
  },
  components: {
    breadcrumb
  },
  mounted () {
    this.$once('hook:beforeDestroy', function () {
      clearInterval(this.timer)
      this.timerList.forEach(n => {
        clearTimeout(n)
      })
      this.timerList = []
    })
    this.getData()
    this.getProgress()
    this.getNotice()
    this.getTeam()
    this.getAutomaticAllocation()

    this.initOss()
  },
  methods: {
    ...mapMutations('match', [
      'SET_SOURCE'
    ]),
    getData () { // 获取竞赛信息
      clearInterval(this.timer)
      this.$post(`${this.api.getCompetition}?competitionId=${this.id}`).then(async ({ competition }) => {
        const list = competition.competitionAnnexList
        // 附件
        if (list) {
          list.map(e => {
            const { filePath } = e
            e.canPreview = Util.canPreview(filePath.substr(filePath.lastIndexOf('.') + 1))
          })
        }

        this.form = competition
        const reg = competition.competitionRegistration
        // 选择的赛事类型为设置完整比赛的才展示竞赛排名和参赛信息
        if (competition.releaseType) {
          const arches = []
          // 积分赛才有总分排名
          competition.rule === 0 ?
            arches.push({
              stageId: '0',
              stageName: '总分'
            }) :
            (this.curArch = competition.competitionStage[0].stageId + '')
          arches.push(...competition.competitionStage)
          arches.map(e => e.stageId = e.stageId + '')
          this.arches = arches

          // 报名后才显示参赛信息
          if (reg && !this.typeList.find(e => e.id == 5)) {
            this.typeList.push({
              id: '5',
              name: '参赛信息'
            })
            this.getInfo()
          }
          this.token && this.intervalRank()
        } else {
          this.typeList = this.typeList.slice(0, 3)
        }

        this.routes = [
          {
            name: '全部赛事',
            path: this.$store.state.match.referrer
          },
          {
            name: competition.name
          }
        ]

        this.now = await Util.getNow()
        this.handleStatus()
        this.timer = setInterval(() => {
          this.now = new Date(this.now.setSeconds(this.now.getSeconds() + 1))
          this.handleStatus()
        }, 1000)
      }).catch(err => { })
    },
    // 定时处理时间及状态
    handleStatus () {
      const { form } = this
      let total = ''
      let time = ''
      let status = ''
      let signUpStartTime = new Date(this.core.dateCompatible(form.signUpStartTime)) // 报名开始时间
      let signUpEndTime = new Date(this.core.dateCompatible(form.signUpEndTime)) // 报名结束时间
      let playStartTime = new Date(this.core.dateCompatible(form.playStartTime)) // 比赛开始时间
      let playEndTime = new Date(this.core.dateCompatible(form.playEndTime)) // 比赛结束时间
      const { now } = this
      if (now < signUpStartTime) { // 报名没开始
        status = 0
        total = signUpStartTime - now
      } else if (now > signUpStartTime && now < signUpEndTime) { // 报名进行中
        // 1已报名，2立即报名(没登录的情况下，直接显示立即报名，登录了则取报名信息，有则已报名，无则立即报名)
        status = this.token ?
          (form.competitionRegistration ?
            1 :
            2) :
          2
        total = signUpEndTime - now
      } else if (now > signUpEndTime && now < playStartTime) { // 报名结束了,但比赛没开始
        status = 3
        total = playStartTime - now
      } else if (now > playStartTime && now < playEndTime) { // 比赛进行中
        // 如果是完整比赛
        if (form.releaseType) {
          // 进行中的赛事，则遍历每个阶段的开始结束时间，看阶段比赛是否开始
          let curStage = null
          const stages = form.competitionStage
          if (stages) {
            this.playingStages = []
            form.competitionRegistration && stages.forEach(e => {
              if (now >= new Date(e.startTime) && now <= new Date(e.endTime) && (e.method !== 2 || this.offlineCanEntry(e))) this.playingStages.push(e)
            })
            let endText = ''
            for (const i in stages) {
              const e = stages[i]
              const startTime = new Date(e.startTime)
              const endTime = new Date(e.endTime)
              if (now < startTime) { // 阶段比赛未开始，不显示进入比赛按钮
                endText = '阶段开始'
                total = startTime - now
                break
              } else if (now >= startTime && now <= endTime) { // 阶段比赛进行中，显示进入比赛按钮
                // 非线下赛事
                if (e.method !== 2) {
                  if (form.competitionRegistration) { // 报名了才能进入比赛
                    this.statusList[4] = e.count ? '已提交' : '进入' + e.stageName
                    curStage = e
                  } else if (!this.token) {
                    this.statusList[4] = '进入' + e.stageName
                    curStage = e
                  }
                } else if (this.offlineCanEntry(e) && form.competitionRegistration) { // 线下(输入了系统链接或者上传文件选择了是，才需要显示进入按钮)
                  // 当系统链接为空，且上传文件为否时，无需展示入口
                  // 当系统链接不为空，且上传文件为否时，点击入口，直接跳转到链接页面，无需弹窗
                  // 当上传文件为是时，点击入口需弹窗，共两种样式
                  this.statusList[4] = '进入' + e.stageName
                  curStage = e
                }
                endText = '阶段结束'
                total = endTime - now
                break
              } else if (stages[i + 1] && now > endTime && now < new Date(stages[i + 1].startTime)) { // 过了该阶段的结束时间，但是没到下个阶段的开始时间，不显示进入比赛按钮
                endText = '阶段开始'
                total = new Date(stages[i + 1].startTime) - now
                break
              } else if (i === stages.length - 1) { // 当前时间在比赛开始结束时间之间，并且是最后一个阶段结束时间之后
                this.$set(form, 'stageName', '')
                endText = '竞赛结束'
                total = playEndTime - now
                break
              }
            }
            this.endList[4] = endText
          }
          if (!this.choosing) this.curStage = curStage
        } else { // 仅发布信息
          total = playEndTime - now
        }
        status = 4
      } else if (now > playEndTime) { // 比赛结束
        status = 5
      }
      this.status = status
      total = total / 1000
      --total
      if (total > 86400) { // 超过一天则显示天数
        // clearInterval(this.timer)
        this.end = Math.floor(total / 86400) + '天'
      } else if (total > 0) { // 一天之内，显示时分秒
        let hours = Math.floor(total / (60 * 60))
        let minutes = Math.floor(total % (60 * 60) / 60)
        let seconds = Math.floor(total % (60 * 60) % 60)
        time = `${this.core.formateTime(hours)}:${this.core.formateTime(minutes)}:${this.core.formateTime(seconds)}`
        if (total > 0) this.end = time
      } else if (this.status === 5) { // 竞赛结束，清除定时器
        clearInterval(this.timer)
      }
    },
    // 该阶段是否符合线下能进入比赛的条件
    offlineCanEntry (stage) {
      return stage.method === 2 && stage.competitionStageContentSetting && !!(stage.competitionStageContentSetting.systemLink || stage.competitionStageContentSetting.whetherToUploadFiles)
    },
    // 获取竞赛信息
    getInfo () {
      this.$post(`${this.api.entryInformation}?competitionId=${this.id}`).then(async res => {
        const info = res.entryInformation
        // 如果是队长，并且没有指导老师，默认添加一个空的
        if (info.team && !info.team.captain && !info.teamInstructors.length) info.teamInstructors.push(JSON.parse(JSON.stringify(this.originIns)))
        if (info.personalDetail) {
          info.team = {}
          info.teamDetail = []
        } else {
          info.isCaption = info.team.caption
        }
        const caption = info.teamDetail.find(e => !e.caption)
        info.caption = caption ? caption : {}
        info.person = info.personalDetail || info.teamDetail.find(e => e.accountId == info.team.accountId)
        this.originInfo = JSON.parse(JSON.stringify(info))
        // 把参赛人员的名字和accountId处理成一个数组
        info.stages && info.stages.map(e => {
          if (e.participantAccountIds && e.teamParticipantIds) {
            const accountIds = e.participantAccountIds.split(',').map(n => +n)
            const names = e.teamParticipantIds.split(',')
            const participants = []
            accountIds.map((n, i) => {
              participants.push({
                id: n,
                name: names[i]
              })
            })
            e.participants = participants
          }
        })
        // 设置定时器，阶段比赛结束后公布成绩，到时间后调本接口
        const now = await Util.getNow()
        this.form.competitionStage && this.form.competitionStage.map(e => {
          // 如果成绩公布时间输入的值大于0（输入的是0则直接公布；没输入值则不公布）
          const time = e.resultAnnouncementTime
          if (time >= 0) {
            const endTime = new Date(e.endTime).getTime() + time * 3600000 // 阶段结束时间+成绩公布时间（成绩公布时间单位是小时，所以要转化为毫秒）
            console.log("🚀 ~ this.$post ~ endTime:", time, endTime - now)
            if (now > endTime) { // 如果到了公布时间
              info.stages.find(n => n.stageId == e.stageId).showDetail = 1
            } else if (endTime - now < 86400000) { // 没有到公布时间，则加定时器，到点后调用
              this.timerList.push(setTimeout(this.getInfo, endTime - now))
            }
          }
        })
        this.info = info
        if (this.form.completeCompetitionSetup.competitionType) {
          this.getErrorInfo()
          this.getTeamAssign()
        }
      }).catch(err => { });
    },
    // 获取团队异常信息
    async getErrorInfo () {
      const res = await this.$get(this.api.checkTeamStatus, {
        competitionId: this.id,
        teamId: this.info.teamId
      })
      this.teamErrors = res.teamTip.split(';').filter(e => e)
      if (Object.keys(res.stageTip).length) {
        this.stageTip = res.stageTip
      }
    },
    // 编辑保存
    edit (showMsg) {
      if (this.editing || !showMsg) {
        const { teamId, teamName, invitationCode } = this.info.team
        this.$post(this.api.editCompetitionTeam, {
          competitionId: this.id,
          teamId,
          teamName,
          invitationCode,
          whetherSignUp: 0
        }).then(res => {
          this.editing = false
          this.getInfo()
          showMsg && Util.successMsg('保存成功')
        }).catch(res => { })
      } else {
        this.editing = !this.editing
      }
    },
    getProgress () { // 获取竞赛进展
      this.$get(this.api.getCompetitionProgress, {
        competitionId: this.id
      }).then(res => {
        this.progress = res.competitionProgressList.reverse()
      }).catch(err => { });
    },
    // 公告列表
    getNotice () {
      this.$post(`${this.api.queryAnnouncementByCompetitionId}?pageNum=1&pageSize=1000&competitionId=${this.id}`).then(({ data }) => {
        const records = data.records.filter(e => e.status) // 只显示已发布的（status 0草稿 1为已发布）
        records.map(e => {
          e.announcementText = e.announcementText.replace(/<img.*?(?:>|\/>)/gi, '')
        })
        this.notices = records
      }).catch(res => { })
    },
    // 预览附件
    preview (item) {
      const { filePath } = item
      const suffix = filePath.substr(filePath.lastIndexOf('.') + 1)
      window.open((Util.isDoc(suffix) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + item.filePath)
    },
    // 下载附件
    download (item) {
      Util.downloadFile(item.fileName, item.filePath)
    },
    // tab切换 前三个滚动，后两个切换
    typeChange () {
      const type = +this.curType
      // 如果上个选中的是参赛信息，则检查修改数据后有没保存(团队名称、邀请码、指导老师)
      if (this.lastType == 5) {
        const { team, teamInstructors } = this.info
        const { originInfo } = this
        let notSave = 0
        // 如果团队名称或者邀请码有修改
        if (team.teamName !== originInfo.team.teamName || team.invitationCode !== originInfo.team.invitationCode) {
          notSave = 1
        } else if (JSON.stringify(teamInstructors) !== JSON.stringify(originInfo.teamInstructors)) {
          notSave = 2
        }
        if (notSave) {
          this.$confirm('所填写内容暂未保存，是否保存？', "提示", {
            type: "warning",
            closeOnClickModal: false
          }).then(() => {
            // 保存团队名称和邀请码
            if (notSave === 1) {
              this.edit()
            } else { // 保存指导老师
              teamInstructors.map(e => {
                e.name && this.$post(this.api.addAnAdvisor, {
                  name: e.name,
                  competitionId: this.id,
                  id: e.id,
                  teamId: this.form.competitionRegistration ? this.form.competitionRegistration.teamId : '',
                  phone: e.phone,
                  position: e.position,
                }).then(res => { }).catch(res => { })
              })
            }
          }).catch(() => { })
        } else {
          type < 4 && document.querySelector(`#part${type}`).scrollIntoView()
        }
      } else {
        type == 5 && this.getInfo()
        type < 4 && document.querySelector(`#part${type}`).scrollIntoView()
      }
      this.editing = false
      this.lastType = type
    },
    // 跳转公告详情
    toNotice (item) {
      this.$router.push(`noticeDetail?id=${item.id}&matchId=${this.id}&name=${this.form.name}&end=${this.end}&status=${this.status}`)
    },
    // 获取排名
    getRank () {
      const cur = +this.curArch
      const data = {
        pageNum: 1,
        pageSize: 20,
        competitionId: this.id,
        isOverallRanking: cur ? 0 : 1
      }
      data.stageIds = cur ? cur : ''
      this.token && this.$post(this.api.frontOfficeCompetitionRanking, data).then(({ list }) => {
        this.ranks = list
      }).catch(res => { })
    },
    // 定时调获取排名接口
    intervalRank () {
      this.getRank()
    },

    // 删除指导老师
    delAdvisor (row, i) {
      if (row.id) {
        this.$confirm('确定要删除吗？', '提示', {
          type: 'warning'
        }).then(() => {
          this.$post(`${this.api.deleteAnAdvisor}?id=${row.id}`).then(res => {
            Util.successMsg('删除成功')
            this.info.teamInstructors.splice(i, 1)
          }).catch(res => { })
        }).catch(() => { })
      } else {
        this.info.teamInstructors.splice(i, 1)
      }
    },
    // 添加指导老师
    addAdvisor () {
      if (this.info.teamInstructors.length > 4) return Util.errorMsg('指导老师仅限添加5个！')
      const line = JSON.parse(JSON.stringify(this.originIns))
      line.edit = 1
      this.info.teamInstructors.push(line)
    },
    // 编辑导老师
    editAdvisor (row) {
      this.$set(row, 'edit', 1)
    },
    // 提交指导老师
    submitAdvisor (row, i) {
      if (!row.name) return Util.errorMsg('请输入姓名')
      const { phone } = row
      if (phone && !/^1[3456789]\d{9}$/.test(phone)) return Util.errorMsg('请输入正确手机号格式')
      this.$post(this.api.addAnAdvisor, {
        name: row.name,
        competitionId: this.id,
        id: row.id,
        teamId: this.form.competitionRegistration ? this.form.competitionRegistration.teamId : '',
        phone: row.phone,
        position: row.position,
      }).then(({ id }) => {
        Util.successMsg((row.id ? '修改' : '新增') + '成功')
        if (!row.id) {
          this.info.teamInstructors[i].id = id
        }
        this.info.teamInstructors[i].edit = 0
      }).catch(res => { })
    },
    // 显示转让队长
    async transfer () {
      // 取每个阶段的开始结束时间，有任何阶段开始了都不能转让队长和踢出队员
      const now = await Util.getNow()
      let start = 0
      for (const e of this.form.competitionStage) {
        if (now >= new Date(e.startTime) && now <= new Date(e.endTime)) {
          Util.errorMsg('比赛已经开始，无法转让队长！')
          start = 1
          break
        }
      }
      if (!start) this.transferVisible = true
    },
    // 转让队长提交
    transferSubmit () {
      if (!this.checkedPlayer) return Util.errorMsg('请选择成员')
      this.$post(this.api.captainOfTransfer, {
        captainId: this.info.caption.teamId,
        playerId: this.checkedPlayer
      }).then(res => {
        this.checkedPlayer = ''
        Util.successMsg('转让成功')
        this.transferVisible = false
        this.getInfo()
      }).catch(res => { })
    },
    // 踢出团队
    async removeLine (row) {
      // 取每个阶段的开始结束时间，有任何阶段开始了都不能转让队长和踢出队员
      const now = await Util.getNow()
      let start = 0
      for (const e of this.form.competitionStage) {
        if (now >= new Date(e.startTime) && now <= new Date(e.endTime)) {
          Util.errorMsg('比赛已经开始，无法踢出成员！')
          start = 1
          break
        }
      }
      if (!start) {
        let include
        for (const e of this.info.stages) {
          if (e.participantAccountIds) {
            const ids = e.participantAccountIds.split(',').map(n => +n)
            if (ids.includes(row.accountId)) {
              include = e.stageName
              break
            }
          }
        }
        this.$confirm(include ? `该成员已被指定参加${include}，踢出后需重新指定成员参加，是否确认踢出团队？` : '确定要踢出该成员吗？', '提示', {
          type: 'warning',
          closeOnClickModal: false
        }).then(() => {
          this.$post(`${this.api.removeTheLine}?teamId=${this.info.teamId}&competitionId=${this.id}&accountId=${row.accountId}`).then(res => {
            Util.successMsg('移除成功')
            this.getInfo()
          }).catch(res => { })
        }).catch(() => { })
      }
    },
    // 获取是否已分配
    async getAutomaticAllocation () {
      const res = await this.$post(`${this.api.viewEventAllocationInformation}?competitionId=${this.id}`)
      this.allocated = res.data && res.data.assignOrNot
    },
    // 获取团队分配按钮展示与否
    async getTeamAssign () {
      const param = `?competitionId=${this.id}&teamId=${this.info.teamId}`
      const res = await this.$post(this.api.teamAssignmentButtonDisplay + param)
      this.showButton = res.showButton // 自动分配按钮是否展示
      this.assignRecord = res.teamRecord || {} // 展示成自动分配 or 取消分配

      // 查询团队是否存在实验报告
      const res1 = await this.$post(this.api.whetherTheTeamHasReport + param)
      this.hasReport = res1.hasReport
      this.allocating = false
    },
    // 移除参赛人员
    async removePar (e, stage) {
      const item = this.form.competitionStage.find(e => e.stageId == stage.stageId)
      if (item) {
        // 该阶段已经开始比赛则不能修改
        const now = await Util.getNow()
        if (now >= new Date(item.startTime) && now <= new Date(item.endTime)) {
          return Util.errorMsg('该阶段比赛已经开始，无法修改允许参赛人员！')
        } else {
          this.$confirm('确定要移除该成员吗？', '提示', {
            type: 'warning'
          }).then(() => {
            this.$post(this.api.cancelParticipant, {
              accountId: e.id,
              competitionId: this.id,
              stageId: stage.stageId,
              teamId: this.info.teamId
            }).then(res => {
              Util.successMsg('移除成功')
              this.getInfo()
            }).catch(res => { })
          }).catch(() => { })
        }
      }
    },
    // 选择参赛人员
    async selectPar (row) {
      const item = this.form.competitionStage.find(e => e.stageId == row.stageId)
      if (item) {
        // 该阶段已经开始比赛则不能修改
        const now = await Util.getNow()
        if (now >= new Date(item.startTime) && now <= new Date(item.endTime)) {
          return Util.errorMsg('该阶段比赛已经开始，无法修改允许参赛人员！')
        } else {
          const { teamLimit, stages, teamDetail } = this.info
          // teamLimit=true，则每个成员只能参加一个阶段的比赛，要获取stages里返回的所有participantAccountIds（参赛人员的accountId），然后不显示这些参赛人员
          if (teamLimit) {
            const chooses = []
            let ids = []
            // 获取已经允许参赛的人员accountId
            stages.map(e => {
              const id = e.participantAccountIds
              if (e.stageId != row.stageId && id) ids.push(...id.split(',').map(n => +n))
            })
            ids = [...new Set(ids)]
            teamDetail.map(e => {
              ids.includes(e.accountId) || chooses.push(e) // 没有参赛的人员则显示出来
            })
            this.chooses = chooses
          } else {
            this.chooses = this.info.teamDetail
          }
          this.curRow = row
          this.checkedMembers = row.participantAccountIds ? row.participantAccountIds.split(',').map(e => +e) : [] // 选中了的人员要回显
          this.chooseVisible = true
        }
      }
    },
    // 选择参赛人员提交
    chooseSubmit () {
      const accountIds = this.checkedMembers
      if (!accountIds.length) return Util.errorMsg('请选择参赛成员！')
      const { customNumber, teamNumLimit } = this.curRow // 参赛人数限制
      if (teamNumLimit && accountIds.length > customNumber) return Util.errorMsg(`请选择${this.curRow.customNumber}个以下参赛成员！`) // 选择的参赛人员个数不能大于参赛人数限制
      this.$post(this.api.stageSelectParticipants, {
        accountIds,
        competitionId: this.id,
        stageId: this.curRow.stageId,
        teamId: this.info.teamId,
        platformId: 1
      }).then(res => {
        this.checkedMembers = []
        Util.successMsg('修改成功')
        this.getInfo()
        this.chooseVisible = false
      }).catch(res => { })
    },
    // 查看成绩详情
    show (row) {
      // 团队展示弹框，个人跳转实验报告
      if (this.form.completeCompetitionSetup.competitionType) { // 团队比赛则展示团队成员成绩详情
        this.memberVisible = true
        this.curRow = row
        const teamId = this.form.competitionRegistration.teamId
        if (teamId) {
          this.$post(this.api.stageTeamScoreDetails, {
            pageNum: 1,
            pageSize: 1000,
            competitionId: this.id,
            stageId: row.stageId,
            teamId
          }).then(({ page }) => {
            this.members = page.records
          }).catch(res => { })
        } else {
          this.members = []
        }
      } else if (row.reportId) { // 个人比赛，并且有reportId，则进入实验报告
        this.toReport(row)
      }
    },
    // 跳转实验报告
    toReport (row) {
      this.$store.commit('project/setReferrer', this.$route.fullPath)
      this.$router.push(`/record/show?reportId=${row.reportId}&matchId=${this.id}&matchName=${this.form.name}`)
    },

    // 个人报名提交
    peopleSignupSubmit () {
      this.$post(this.api.addCompetitionRegistration, {
        competitionId: this.id,
        registrationInvitationCode: this.peopleSignupForm.registrationInvitationCode
      }).then(res => {
        this.peopleSignupVisible = false
        this.getData()
        this.$message.success('报名成功')
      }).catch(res => { })
    },
    // 团队报名提交
    enterSubmit () {
      const form = this.enterForm
      if (!form.teamId) return Util.errorMsg('请选择团队')
      if (!form.invitationCode) return Util.errorMsg('请输入团队邀请码')
      if (this.form.completeCompetitionSetup.isNeedCode && !form.registrationInvitationCode) return Util.errorMsg('请输入大赛邀请码')
      this.$post(this.api.joinCompetitionTeam, form).then(res => {
        this.status = 1
        this.enterVisible = false
        this.getData()
        Util.successMsg('报名成功！')
      }).catch(res => { })
    },
    // 团队关闭
    enterClose () {
      this.enterForm = {
        competitionId: this.id,
        teamId: '',
        registrationInvitationCode: '',
        invitationCode: '',
        whetherSignUp: 1
      }
    },


    // 创建团队
    toTeam () {
      this.teamVisible = true
    },
    // 获取团队列表
    getTeam () {
      this.$get(this.api.searchTeam, {
        teamName: '',
        competitionId: this.id
      }).then(({ teamList }) => {
        this.teams = teamList
      }).catch(res => { })
    },
    // 团队提交
    teamSubmit () {
      const form = this.teamForm
      if (!form.teamName) return Util.errorMsg('请输入团队名称')
      if (this.teamNameRepeat) return Util.errorMsg('团队名称重复，请重新输入')
      if (form.invitationCode.length !== 6) return Util.errorMsg('请输入6位数团队邀请码')
      if (this.form.completeCompetitionSetup.isNeedCode && !form.registrationInvitationCode) return Util.errorMsg('请输入大赛邀请码')
      this.$post(this.api.addCompetitionTeam, form).then(async ({ status, data, message }) => {
        this.teamVisible = false
        this.enterVisible = false
        await this.getData()
        Util.successMsg('报名成功！')
        this.afterCreateTeam()
      }).catch(res => { })
    },
    // 队长创建团队后弹框
    afterCreateTeam () {
      // 赛事自动分配状态为开启，则直接提示；否则弹框询问是否要启用团队自动分配
      if (this.allocated) {
        Util.successMsg('团队创建成功，系统将在报名结束后自动帮您分配阶段参赛成员，您也可以到参数信息进行指定')
      } else {
        // 未分配
        this.$confirm('<p style="color: #007EFF;">报名成功！</p>您是否要启用自动分配阶段参赛人员功能？启用后，报名截止时系统将清空已有分配，并为团队所有成员重新自动分配。', '提示', {
          cancelButtonText: '否',
          confirmButtonText: '是',
          type: 'success',
          closeOnClickModal: false,
          dangerouslyUseHTMLString: true,
        }).then(() => {
          this.automaticAllocation(1)
        }).catch(() => { })
      }
    },
    // 团队创建成功后分配
    async automaticAllocation (state) {
      await this.$post(this.api.competitionTeamAutomaticAllocationRecordSave, {
        assignOrNot: state,
        competitionId: this.id,
        teamId: this.info.teamId
      })
    },
    // 自动分配
    automaticAllocationMember () {
      const whether = this.assignRecord.assignOrNot && this.status < 3
      const tips = this.status < 3 ?
        whether ?
          '您是否要取消自动分配阶段参赛人员？<p style="margin-top: 5px;font-size: 13px;color: #f00;">取消后，报名截止时将不再自动分配。</p>' :
          '您是否要启用自动分配阶段参赛人员功能？<p style="margin-top: 5px;font-size: 13px;color: #f00;">启用后，报名截止时系统将清空已有分配，并为团队所有成员重新自动分配。</p>'
        : '您是否要立即为团队所有成员自动分配阶段参赛人员？<p style="margin-top: 5px;font-size: 13px;color: #f00;">此操作将清除现有分配，并为团队所有成员重新分配。</p>'
      this.$confirm(tips, '提示', {
        cancelButtonText: '否',
        confirmButtonText: '是',
        type: 'success',
        closeOnClickModal: false,
        dangerouslyUseHTMLString: true,
      }).then(async () => {
        this.allocating = true
        // 报名结束之前则调修改接口，否则调自动分配接口
        if (this.status < 3) {
          await this.$post(this.api.competitionTeamAutomaticAllocationRecordSave, {
            id: this.assignRecord.id,
            assignOrNot: whether ? 0 : 1,
            competitionId: this.id,
            teamId: this.info.teamId
          })
        } else {
          await this.$post(`${this.api.assignedPlayer}?competitionId=${this.id}&teamId=${this.info.teamId} `)
        }

        this.getData()
        this.getInfo()
        Util.successMsg(`${whether ? '取消' : ''} 自动分配成功！`)
      }).catch(() => { })
    },
    // 团队关闭
    teamClose () {
      this.teamForm = {
        competitionId: this.id,
        teamName: '',
        invitationCode: '',
        registrationInvitationCode: '',
        whetherSignUp: 1
      }
    },

    initOss () {
      this.client = new OSS(OssConfig.config)
    },
    // 附件上传前
    beforeUpload (file) {
      const oversize = file.size / 1024 / 1024 < 1000
      if (!oversize) Util.warningMsg('请上传小于1GB的附件！')
      if (oversize) {
        return true
      } else {
        return false
      }
    },
    // 自定义进度条
    handleProgress (progress) {
      this.uploadProgress = Number((progress * 100).toFixed(2))
    },
    // 自定义上传
    async handleRequest ({ file }) {
      try {
        this.fileList = []
        this.uploadProgress = 0
        this.uploading = true
        // 先传到阿里云oss，再把url传给后端
        const { name } = await this.client.multipartUpload(Date.now() + '.' + Util.getFileExt(file.name), file, {
          progress: this.handleProgress
        });

        this.uploading = false
        const url = 'https://huoran.oss-cn-shenzhen.aliyuncs.com/' + name
        this.fileList = [{
          name: file.name,
          url
        }]

        // 把上传成功后的url存进文件表
        const res = await this.$post(this.api.cCompetitionStageFileSave, {
          competitionId: this.id,
          fileFormat: Util.getFileExt(file.name),
          fileName: file.name,
          filePath: url,
          fileSize: file.size,
          stageId: this.curStage.stageId,
          teamId: this.form.competitionRegistration.teamId
        })
        this.curFileId = res.message
        Util.successMsg(`上传成功！`);
      } catch (error) { }
    },

    downloadFile () {
      const { name, url } = this.fileList[0]
      Util.downloadFile(name, url)
    },
    handlePreview (file) {
      window.open((Util.isDoc(Util.getFileExt(file.name)) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + file.url)
    },
    uploadError (err, file, fileList) {
      this.$message({
        message: "上传出错，请重试！",
        type: "error",
        center: true
      })
    },
    beforeRemove (file, fileList) {
      return this.$confirm(`确定移除 ${file.name}？`);
    },
    handleExceed (files, fileList) {
      Util.warningMsg(`当前限制选择 1 个文件，如需更换，请删除上一个文件再重新选择！`);
    },
    // 删除文件表里的文件
    handleRemove (file) {
      Oss.del(file.url)
      this.fileList = []
      this.curFileId && this.$post(this.api.cCompetitionStageFileDel, [this.curFileId]).then(res => {
        this.curFileId = ''
      }).catch(res => { })
    },

    // 提交阶段内容
    stageSubmit () {
      if (this.submiting) return false
      this.submiting = true
    },
    // 阶段弹框关闭回调
    stageClose () {
      this.choosing = false
      this.fileList = []
      this.getData()
    },

    // 选择要进入的阶段
    chooseStage (e) {
      this.choosing = true
      this.curStage = e
      this.signup()
    },
    // 判断是否能进赛事
    getAllow () {
      // 是否允许参加赛事（淘汰赛制）
      if (this.form.rule === 1) {
        this.$post(this.api.allowedParticipateCompetition, {
          competitionId: this.id,
          number: this.curStage.number,
          stageId: this.curStage.stageId,
          teamId: this.form.competitionRegistration.teamId,
        }).then(res => {
          this.toSub()
        }).catch(res => { })
      } else {
        this.toSub()
      }
    },
    // 立即报名
    signup () {
      const { status, form } = this
      // 如果登录了
      if (Util.local.get(Setting.tokenKey)) {
        const { competitionType } = form.completeCompetitionSetup
        if (status == 4) { // 进入比赛
          // 线下(规则见handleStatus方法)
          if (this.curStage.method == 2) {
            // 直接打开系统链接
            if (!this.curStage.competitionStageContentSetting.whetherToUploadFiles) {
              window.open(this.curStage.competitionStageContentSetting.systemLink)
            } else { // 显示上传文件弹框
              this.stageVisible = true

              // 文件路径名称处理
              if (this.curStage.competitionStageContentSetting && this.curStage.competitionStageContentSetting.fileUrl) {
                const urls = this.curStage.competitionStageContentSetting.fileUrl.split('|')
                const names = this.curStage.competitionStageContentSetting.fileName.split('|')
                this.curStage.competitionStageContentSetting.fileList = []
                urls.map((n, i) => {
                  this.curStage.competitionStageContentSetting.fileList.push({
                    name: names[i],
                    url: n
                  })
                })
              }

              const file = this.curStage.competitionStageFile
              if (file) {
                this.curFileId = file.id
                this.fileList = [{
                  name: file.fileName,
                  url: file.filePath,
                }]
              }
            }
          } else {
            // 参加过比赛不让参加
            if (this.curStage && this.curStage.count) return Util.errorMsg('您已经参加过该阶段竞赛！')
            if (form.competitionRegistration.isDisable === 1) return Util.errorMsg('当前用户已被禁赛，如有疑问，请联系平台管理员。') // 被禁用的用户不能进入大赛
            // 团队赛，则判断是否为参赛人员
            if (competitionType) {
              this.$post(this.api.isParticipant, {
                competitionId: this.id,
                stageId: this.curStage.stageId,
                teamId: form.competitionRegistration.teamId,
              }).then(res => {
                this.getAllow()
              }).catch(res => { })
            } else {
              this.getAllow()
            }
          }
        } else if (status == 2) { // 报名
          // 团队赛报名
          if (competitionType) {
            this.enterVisible = true
          } else { // 个人赛报名
            if (form.completeCompetitionSetup.isNeedCode) {
              this.peopleSignupForm.registrationInvitationCode = ''
              this.peopleSignupVisible = true
            } else {
              this.$post(this.api.addCompetitionRegistration, {
                competitionId: this.id
              }).then(res => {
                this.getData()
                this.$message.success('报名成功')
              }).catch(res => { })
            }
          }
        } else if (status == 1) {
          // 已报名，点击取消报名
          this.$confirm('是否要取消报名？', '提示', {
            type: 'success',
            closeOnClickModal: false
          }).then(() => {
            this.$post(`${this.api.cancelRegistration}?competitionId=${this.id}`).then(res => {
              this.status = 2
              this.$message.success('取消报名成功')
              this.getData()
            }).catch(res => { })
          }).catch(() => { })
        }
      } else { // 如果没登录，提示去登录
        this.$confirm('请先登录，是否直接前往登录？', "提示", {
          type: 'success',
          closeOnClickModal: false
        }).then(() => {
          this.SET_SOURCE(this.id)
          this.$router.push('/login')
        }).catch(() => { })
      }
    },
    // 线下比赛方式点击进入跳转<比赛地点>
    toOffline () {
      window.open(this.curStage.competitionStageContentSetting.systemLink)
    },
    // 进入python系统
    toPython () {
      const form = this.curStage
      let token = Util.local.get(Setting.tokenKey);
      Util.cookies.set('assessmentId', '', -1)
      Util.cookies.set('startTime', '', -1)
      Util.cookies.set('stopTime', '', -1)
      Util.cookies.set('projectId', form.projectId)
      Util.cookies.set('token', token)
      Util.cookies.set('courseId', form.cid)
      Util.cookies.set('curriculumName', encodeURIComponent(form.systemName))
      Util.cookies.set('systemId', form.systemId)
      Util.cookies.set('isSubmit', '', -1)
      Util.cookies.set('className', '', -1)
      Util.cookies.set('competitionId', this.form.id)
      Util.cookies.set('stageId', form.stageId)
      Util.cookies.set('teamId', this.form.competitionRegistration.teamId)
      Util.cookies.set('stopTime', form.endTime)
      Util.cookies.set('resultsDetails', form.resultsDetails)
      Util.cookies.set('resultAnnouncementTime', isNaN(form.resultAnnouncementTime) ? '' : form.resultAnnouncementTime)
      Util.cookies.set('mallId', form.mallId)
      Util.cookies.set('fromManager', '', -1)
      Util.cookies.set('language', '', -1)
      // 8个python子系统都跳这个地址，子系统会通过cookie里的systemId识别展示哪套系统
      location.href = process.env.NODE_ENV === 'development' ?
        `http://${location.hostname}:8085/#/` :
        Setting.isPro ?
          `https://${location.hostname}/pyTrials` :
          `${location.origin}/pyTrials`
    },
    // 进入子系统
    toSub () {
      const { form } = this
      const { systemId, systemName, projectId, cid, stageId, startTime, endTime, mallId, resultAnnouncementTime, method } = this.curStage
      const competitionId = form.id
      const teamId = form.competitionRegistration.teamId || ''

      // 理论考试
      if (method === 1) {
        this.$router.push(`/match/theoryExam?id=${form.id}&stageId=${stageId}&teamId=${teamId}`)
      } else {
        let token = Util.local.get(Setting.tokenKey);
        if (systemId == 11) {
          // 银行系统
          location.href = `${Setting.systemPath}/#/index/list?curriculumName=${this.curriculumName}&token=${token}&cid=${cid}&systemId=${systemId}&projectId=${projectId}&competitionId=${competitionId}&stageId=${stageId}&teamId=${teamId}&assessmentId=&classId=&stopTime=&test=true`
        } else if (systemId == 12) {
          // 众筹系统
          window.open(`http://${Setting.zcPath}?systemId=${systemId}&courseId=${cid}&projectId=${projectId}&token=${token}&userId=${this.userId}&classId=1&competitionId=${competitionId}&stageId=${stageId}&teamId=${teamId}&startTime=${startTime}&endTime=${endTime}&mallId=${mallId}${Setting.isTest ? '&beta=1' : ''}`);
        } else if (systemId == 19) {
          // 沙盘
          location.href = `${Setting.sandPath}/#/?curriculumName=${systemName}&token=${token}&cid=${cid}&mallId=${mallId}&systemId=${systemId}&projectId=${projectId}&assessmentId=&classId=&startTime=&stopTime=${endTime}&competitionId=${competitionId}&stageId=${stageId}&teamId=${teamId}&resultAnnouncementTime=${isNaN(resultAnnouncementTime) ? '' : resultAnnouncementTime}&userId=${this.userId}&account=${this.account}&referrer=${encodeURIComponent(location.href)}`
        } else {
          // python系统
          this.toPython(this.curProject)
        }
      }
    }
  }
};
</script>

<style lang="scss" scoped>
.banner {
  width: 100%;
  height: 350px;
  padding: 120px 0 0 20%;
  color: #fff;
  background-size: 100% 350px;
  background-repeat: no-repeat;
}

.l-title {
  font-size: 18px;
}

.main .center-con {
  background: url(../../../assets/img/match-bg1.png) (0px 95px) / auto auto no-repeat,
    url(../../../assets/img/match-bg2.png) (98% 300px) / auto auto no-repeat;
}

.main .center-wrap {
  margin-top: 30px;
}

.rule-title {
  margin-bottom: 10px;
  font-size: 16px;
}

.rule {
  padding: 15px;
  margin-bottom: 15px;
  border: 1px solid #dfdfdf;

  p {
    font-size: 14px;
    line-height: 30px;
    color: #6e6e6e;
  }
}

/deep/.el-tabs__item {
  box-shadow: none !important;
}

.content {
  position: relative;
  padding: 20px 40px;
  margin-top: 30px;
  background-color: #fff;

  .title {
    width: 67%;
    margin: 0 auto;
    font-size: 28px;
    text-align: center;
    color: #0b1d30;
  }

  .tool {
    z-index: 100;
    position: sticky;
    top: 64px;
    margin-bottom: 20px;
    background-color: #fff;

    &.logView {
      z-index: 0;
    }
  }

  .info .meta {
    padding: 16px 0;
    font-size: 12px;
    color: #999;
    text-align: center;
  }

  .action {
    display: inline-flex;
    align-items: center;
  }

  .sign-status {
    margin-bottom: 10px;
    text-align: center;
    font-size: 14px;
    color: $main-color;

    &.signing {
      color: $main-color;
    }

    &.signed {
      color: #52c41a;
    }

    &.playing {
      color: #f96d6d;
    }

    &:last-child {
      margin-bottom: 0;
    }
  }

  .status {
    max-width: 120px;
    padding: 0 16px;
    line-height: 34px;
    font-size: 14px;
    color: #fff;
    background-color: #52c41a;
    border-radius: 4px;
    cursor: pointer;
    @include ellipsis();

    &.wait {
      background-color: #faad14;
    }

    &.signing {
      background-color: $main-color;
    }

    &.signed {
      background-color: #52c41a;
    }

    &.playing {
      background-color: #f96d6d;
    }

    &.finish {
      background-color: #ccc;
    }
  }

  .end-text {
    font-size: 12px;
    color: #666;

    em {
      font-style: normal;
      color: #f00;
    }
  }

  .texts {
    margin: 20px 0 50px;
    font-size: 14px;
    line-height: 1.6;
    text-indent: 2em;
    overflow: hidden;

    /deep/img {
      max-width: 100%;
    }
  }

  .progress {
    position: relative;
    width: 95%;
    padding: 50px 0;
    margin: 40px auto 80px;
    text-align: left;

    &:before {
      content: '';
      position: absolute;
      top: 0;
      left: 50%;
      width: 2px;
      height: 100%;
      background-color: #e1e6f2;
    }

    &:after {
      content: '';
      position: absolute;
      top: -10px;
      left: 430px;
      border: 8px solid transparent;
      border-bottom-color: #e1e6f2;
    }

    .rocket {
      position: absolute;
      bottom: -50px;
      left: 425px;
    }

    li {
      position: relative;
      width: 400px;
      margin-bottom: 42px;

      .dot {
        position: absolute;
        top: 12px;
        left: 431px;
        width: 15px;
        height: 15px;
        background-color: #dcdcdc;
        border-radius: 50%;
      }

      .name {
        display: inline-block;
        padding: 0 19px;
        margin-bottom: 16px;
        line-height: 40px;
        text-align: center;
        font-size: 16px;
        color: #fff;
        border-radius: 20px;
        background-color: #c4c4c4;
      }

      .desc {
        position: relative;
        color: #333;
        font-size: 14px;
      }

      &.ing,
      &.done {
        .dot {
          top: 8px;
          background-color: #007eff;
        }

        .name {
          background-color: #007eff;
        }
      }

      &.ing {
        .dot {
          width: 27px;
          height: 27px;
          border: 6px solid #e2f1fb;
        }
      }

      &:nth-child(odd) {
        text-align: right;

        &.ing {
          .dot {
            left: auto;
            right: -51px;
          }
        }

        .name {
          &:before {
            content: '';
            z-index: 2;
            position: absolute;
            top: 14px;
            right: -35px;
            border: 18px solid transparent;
            border-top-width: 6px;
            border-bottom-width: 6px;
            border-left-color: #c4c4c4;
          }
        }

        .desc {
          text-align: right;
        }

        &.ing,
        &.done {
          .name {
            &:before {
              border-left-color: #007eff;
            }
          }
        }
      }

      &:nth-child(even) {
        margin-left: 482px;

        .dot {
          left: -51px;
        }

        &.ing {
          .dot {
            left: -57px;
          }
        }

        .name {
          text-align: left;

          &:after {
            content: '';
            z-index: 2;
            position: absolute;
            top: 14px;
            left: -35px;
            border: 18px solid transparent;
            border-top-width: 6px;
            border-bottom-width: 6px;
            border-right-color: #c4c4c4;
          }
        }

        .desc {
          &:before {
            left: auto;
            right: -16px;
            border: 8px solid transparent;
            border-left-color: #fff;
          }

          &:after {
            left: auto;
            right: -18px;
            border: 9px solid transparent;
            border-left-color: #e6e6e6;
          }
        }

        &.ing,
        &.done {
          .name {
            &:after {
              border-right-color: #007eff;
            }
          }
        }
      }

      &:last-child {
        margin-bottom: 0;
      }
    }
  }
}

.files {
  margin-bottom: 30px;

  li {
    display: flex;
    align-items: center;
    margin: 10px 0;
  }

  .fileName {
    margin-right: 10px;
    font-size: 12px;
  }
}

.notice-list {
  text-align: left;

  li {
    padding: 16px;
    margin-bottom: 12px;
    transition: all 0.3s;
    cursor: pointer;
    border-radius: 6px;
    background-color: #fff;
    border-bottom: 1px dashed #ebebeb;

    &:last-child {
      border-bottom: 0;
    }
  }

  h6 {
    font-size: 20px;
    font-weight: 500;
    color: #0b1d30;

    &:hover {
      color: #007eff;
    }
  }

  .meta {
    margin: 10px 0;
    font-size: 14px;
    color: #666;
  }

  .des {
    font-size: 14px;
    color: #333;
    line-height: 24px;
    display: -webkit-box;
    display: -moz-box;
    -webkit-box-orient: vertical;
    -moz-box-orient: vertical;
    -webkit-line-clamp: 2;
    -moz-line-clamp: 2;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

.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;
  }

  .icon {
    margin-right: 10px;
    font-size: 16px;
    color: #7a7a7a;
    cursor: pointer;

    &:hover {
      color: #007eff;
    }
  }

  .plus {
    margin-bottom: 10px;
    text-align: right;
  }

  .line {
    display: flex;
    align-items: center;
    margin-bottom: 10px;

    .el-input {
      margin-right: 15px;
    }
  }
}

.flex-center {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

/deep/.dia-form {
  .w-100 {
    width: 100%;
  }

  .tips {
    display: flex;
    justify-content: center;
    align-items: center;
  }
}

/deep/.file-upload {
  .el-upload__tip {
    color: #727272;
  }

  .el-progress {
    white-space: nowrap;
  }

  .download {
    position: absolute;
    bottom: -25px;
    right: 0;
    font-size: 12px;
    color: #007eff;
    cursor: pointer;
  }

  .el-upload-list__item {
    width: 70%;

    &:first-child {
      margin-top: 5px;
    }
  }
}
</style>