From 9e3d4f40db220e06903ce9c69db7836aaa416761 Mon Sep 17 00:00:00 2001
From: yujialong <479214531@qq.com>
Date: Sat, 28 Jan 2023 17:12:05 +0800
Subject: [PATCH] fix

---
 src/api/index.js                      |   1 +
 src/layouts/home/index.vue            |  16 +-
 src/pages/match/details/index.vue     | 357 ++++++++++++++++++--------
 src/pages/match/list/index.vue        | 122 ++++-----
 src/pages/touristMatch/list/index.vue | 118 ++++-----
 src/setting.js                        |   2 +-
 src/store/modules/match.js            |   6 +-
 7 files changed, 389 insertions(+), 233 deletions(-)

diff --git a/src/api/index.js b/src/api/index.js
index c2d26de..92e7dc7 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -101,6 +101,7 @@ export default {
     getCustomerBySchoolId: `nakadai/nakadai/customer/getCustomerBySchoolId`,
     isParticipant: `competition/competition/management/isParticipant`,
     editCompetitionTeam: `competition/competition/team/editCompetitionTeam`,
+    promptRemoval: `competition/competition/team/promptRemoval`,
     frontDeskOverallRanking: `${host1}competition/competition/rank/frontDeskOverallRanking`,
     frontOfficeCompetitionRanking: `${host1}competition/competition/rank/frontOfficeCompetitionRanking`,
     stageGradeManagementList: `${host1}competition/competition/performance/stageGradeManagementList`,
diff --git a/src/layouts/home/index.vue b/src/layouts/home/index.vue
index 14d7a89..8a55cde 100644
--- a/src/layouts/home/index.vue
+++ b/src/layouts/home/index.vue
@@ -77,19 +77,33 @@ export default {
     computed: {
         ...mapState("user", [
             'logView'
+        ]),
+        ...mapState("match", [
+            'noticed'
         ])
     },
     mounted() {
-        this.autoLogout();
+        this.autoLogout()
+        // this.noticed || this.getMatchStatus() // 0才要调用
         this.logView || this.getLogStatus() // logView为false才需要查询接口
     },
     methods: {
         ...mapMutations("user", [
             'SET_LOG'
         ]),
+        ...mapMutations("match", [
+            'SET_NOTICE'
+        ]),
         ...mapActions("user", [
             "logout"
         ]),
+        // 提示赛事状态(登录后调用一次)
+        getMatchStatus() {
+          util.local.get(Setting.tokenKey) && this.$post(this.api.promptRemoval).then(({ prompt }) => {
+            this.SET_NOTICE()
+            prompt && util.errorMsg(prompt)
+          }).catch(res => {})
+        },
         // 获取日志列表
         getLog() {
           this.$get(`${this.api.platformLogList}?platformId=${Setting.platformId}&port=1&versionName=`).then(({ logList }) => {
diff --git a/src/pages/match/details/index.vue b/src/pages/match/details/index.vue
index f13e4ed..67158f9 100644
--- a/src/pages/match/details/index.vue
+++ b/src/pages/match/details/index.vue
@@ -5,7 +5,7 @@
           <div class="center-wrap">
               <breadcrumb ref="breadcrumb" :data="'全部赛事/' + form.name"></breadcrumb>
               <div class="content">
-                  <div class="tool flex-between">
+                  <div class="tool flex-between">{{status}}
                       <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>
@@ -23,7 +23,7 @@
                     <div class="meta">最近编辑时间:{{ form.updateTime }}</div>
                   </div>
                   
-                  <div v-show="curType != 4 && curType != 5">
+                  <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.contestAnnexList">
@@ -45,17 +45,27 @@
                       <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">课程系统:{{ rule.systemName }}</p>
+                      <p v-if="rule.onlineButton">线上地点:{{ rule.onlineAddress }}</p>
+                      <p v-if="rule.offlineButton">线下地点:{{ rule.offlineAddress }}</p>
                       <template v-if="rule.method === 2">
-                        <p>比赛内容:</p>
-                        <div v-html="form.description"></div>
-                        <p class="m-t-10">评分规则:专家打分</p>
+                        <p>线下地点:{{ rule.offlineAddress }}</p>
+                        <p>比赛内容:{{ rule.contentDescription }}</p>
+                        <p class="m-t-10">评分规则:{{ rule.scoreRule }}</p>
                       </template>
                       
                       <template v-if="form.completeCompetitionSetup.competitionType">
-                        <p>团队参赛人数限制:{{ rule.teamNumLimit }}</p>
+                        <p>团队参赛人数限制:{{ rule.teamNumLimit || '不限制' }}</p>
                         <p>团队成绩计算方式:{{ teamCalculationMethods.find(e => e.id == rule.teamCalculationMethod) && teamCalculationMethods.find(e => e.id == rule.teamCalculationMethod).name }}</p>
                       </template>
                       <p>阶段比赛结束后{{ rule.resultAnnouncementTime }}小时,公布阶段比赛成绩。</p>
+                      <div v-if="form.rule === 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>
                     
                     <!-- 进展 -->
@@ -118,6 +128,21 @@
 
                   <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" 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>
@@ -134,11 +159,10 @@
                         </tr>
                       </template>
                       <template v-if="form.completeCompetitionSetup.competitionType">
-                        <tr>
+                        <tr v-if="info.team.captain">
                           <th width="150">团队名称:</th>
                           <td>
-                            <el-input v-if="info.team.captain === 0" :disabled="!editing" v-model="info.team.teamName"></el-input>
-                            <span v-else>{{ info.team.teamName }}</span>
+                            <span>{{ info.team.teamName }}</span>
                           </td>
                         </tr>
                         <template v-if="info.team.captain">
@@ -152,31 +176,49 @@
                               <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>指导老师:</th>
+                        <th width="130">指导老师:</th>
                         <td v-if="info.team.captain === 0 || !form.completeCompetitionSetup.competitionType">
                           <div 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"></el-input>
-                            <el-input placeholder="请输入职务" maxlength="10" v-model="item.position" clearable size="mini"></el-input>
-                            <el-input placeholder="请输入手机号" maxlength="11" v-model="item.phone" clearable size="mini"></el-input>
-                            <i class="el-icon-check icon" @click="submitAdvisor(item)"></i>
-                            <i class="el-icon-delete icon" @click="delAdvisor(item, i)"></i>
+                            <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 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>
-                          {{ info.teamInstructors.map(e => e.name).join(',')}}
-                        </td>
-                      </tr>
-                      <tr v-if="form.completeCompetitionSetup.competitionType">
-                        <th>团队邀请码:</th>
-                        <td>
-                          <el-input v-if="info.team.captain === 0" :disabled="!editing" v-model="info.team.invitationCode"></el-input>
-                          <span v-else>{{ info.team.invitationCode }}</span>
+                          <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>
@@ -198,16 +240,16 @@
                                 <td>{{ i + 1 }}</td>
                                 <td>{{ item.stageName }}</td>
                                 <template v-if="form.completeCompetitionSetup.competitionType">
-                                  <td>{{ item.teamNumLimit || 0 }}</td>
+                                  <td>{{ item.teamNumLimit || '不限制' }}</td>
                                   <td>
-                                    <span class="m-r-5">{{ item.teamParticipantIds }}</span>
-                                    <el-button type="danger" size="mini" @click="selectPar(item)">修改</el-button>
+                                    <span class="m-r-5">{{ item.teamParticipantIds || '无' }}</span>
+                                    <el-button v-if="info.team.captain === 0" type="danger" size="mini" @click="selectPar(item)">修改</el-button>
                                   </td>
                                   <td v-if="info.team.captain === 0 && form.rule === 0 && !i" :rowspan="info.stages.length">{{ info.totalScore }}</td>
                                 </template>
                                 <td>
                                   <span v-if="item.score" class="m-r-10">分数{{item.score}}</span>
-                                  <el-button type="text" :disabled="item.resultsDetails === 1" @click="show(item)">查看成绩详情</el-button>
+                                  <el-button type="text" :disabled="item.showDetail && item.resultsDetails === 1 || (form.completeCompetitionSetup.competitionType && !item.reportId) || (form.completeCompetitionSetup.competitionType === 0 && !item.reportId)" @click="show(item)">查看成绩详情</el-button>
                                 </td>
                               </tr>
                             </template>
@@ -218,16 +260,13 @@
                           <el-alert
                             v-if="form.completeCompetitionSetup.competitionType && info.team.captain === 0"
                             style="margin-top: 10px;"
-                            title="注:请团长(团队创建人)设置各阶段参赛成员,只有被选择的允许参赛成员可进入对应阶段比赛,每个团队成员只能参加一个赛项阶段!"
+                            :title="'注:请团长(团队创建人)设置各阶段参赛成员,只有被选择的允许参赛成员可进入对应阶段比赛' + (info.teamLimit ? ',每个团队成员只能参加一个赛项阶段' : '') + '!'"
                             type="warning"
                             show-icon>
                           </el-alert>
                         </td>
                       </tr>
                     </table>
-                    <div v-if="form.completeCompetitionSetup.competitionType && info.team.captain === 0" class="m-t-20 text-center">
-                      <el-button type="primary" @click="edit">{{ editing ? '保存' : '编辑' }}</el-button>
-                    </div>
                     
                     <template v-if="form.completeCompetitionSetup.competitionType && info.team.captain === 0">
                       <div class="l-title m-t-20">团队成员</div>
@@ -256,7 +295,7 @@
           <el-form class="dia-form">
             <p style="margin-bottom: 5px">请选择要加入的团队</p>
             <el-form-item>
-              <el-select class="w-100" v-model="enterForm.teamId">
+              <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>
@@ -303,11 +342,11 @@
           </span>
         </el-dialog>
         <el-dialog title="选择参赛成员" :visible.sync="chooseVisible" :close-on-click-modal="false" width="400px">
-          <template v-if="info.teamLimit">
+          <!-- <template v-if="curRow.teamNumLimit  === 1">
             <el-radio v-for="(item, i) in info.teamDetail" :key="i" v-model="checkedMember" :label="item.accountId">{{ item.userName }}</el-radio>
-          </template>
-          <el-checkbox-group v-else v-model="checkedMembers">
-            <el-checkbox v-for="(item, i) in info.teamDetail" :key="i" :label="item.accountId">{{ item.userName }}</el-checkbox>
+          </template> -->
+          <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" style="margin-top: 15px;font-size: 12px;">注:当前阶段限制1人参赛,且此竞赛每个成员只能参加一个阶段赛项。</p>
           <span slot="footer" class="dialog-footer">
@@ -367,6 +406,7 @@ export default {
             rules: Const.rules,
             methods: Const.methods,
             teamCalculationMethods: Const.teamCalculationMethods,
+            timerList: [],
             form: {
               name: '',
               coverUrl: '',
@@ -397,10 +437,6 @@ export default {
                     id: '4',
                     name: '竞赛排名'
                 },
-                {
-                    id: '5',
-                    name: '参赛信息'
-                }
             ],
             progress: [],
             timer: null,
@@ -430,6 +466,7 @@ export default {
               whetherSignUp: 1
             },
             curStage: null,
+            originInfo: {},
             info: {
               isCaption: 0,
               person: {},
@@ -455,7 +492,9 @@ export default {
             curRow: {},
             chooseVisible: false,
             checkedMember: '',
-            checkedMembers: []
+            checkedMembers: [],
+            chooses: [],
+            lastType: 1
         };
     },
     components: {
@@ -465,77 +504,83 @@ export default {
         countdown: {
             bind: function(el, binding, vnode) {
                 let that = vnode.context
+                clearInterval(that.timer)
                 const { form } = that
                 let time = ''
-                let second = 1000;
-                let minute = second * 60;
-                let hour = minute * 60;
-                let now = new Date().getTime();
                 let signUpStartTime = new Date(that.core.dateCompatible(form.signUpStartTime)).getTime(); // 报名开始时间
                 let signUpEndTime = new Date(that.core.dateCompatible(form.signUpEndTime)).getTime(); // 报名结束时间
                 let playStartTime = new Date(that.core.dateCompatible(form.playStartTime)).getTime(); // 比赛开始时间
                 let playEndTime = new Date(that.core.dateCompatible(form.playEndTime)).getTime(); // 比赛结束时间
-                switch (that.status) {
-                    // status每个值的解释请看getData方法
-                    case 0:
-                        if (now > signUpStartTime) {
-                            that.status = 1;
-                        } else {
-                            time = signUpStartTime - now;
-                        }
-                        break;
-                    case 1:
-                        if (now > signUpEndTime) {
-                            that.status = 3;
-                        } else {
-                            time = signUpEndTime - now;
-                        }
-                        break;
-                    case 2:
-                        if (now > signUpEndTime) {
-                            that.status = 3;
-                        } else {
-                            time = signUpEndTime - now;
-                        }
-                        break;
-                    case 3:
-                        if (now > playStartTime) {
-                            that.status = 4;
-                        } else {
-                            time = playStartTime - now;
-                        }
-                        break;
-                    case 4:
-                        if (now > playEndTime) {
-                            that.status = 5;
-                        } else {
-                            time = playEndTime - now;
-                        }
-                        break;
-                }
-                time = `${Math.floor(time / hour)}:${Math.floor(time % hour / minute)}:${Math.floor(time % hour % minute / second)}`;
                 that.timer = setInterval(() => {
-                    let timeList = time.split(":");
-                    let total = Number.parseInt(timeList[0] * 60 * 60) + Number.parseInt(timeList[1] * 60) + Number.parseInt(timeList[2]);
-                    if (total > 0) {
+                    let now = new Date().getTime();
+                    switch (that.status) {
+                        // status每个值的解释请看getData方法
+                        case 0:
+                            if (now > signUpStartTime) {
+                                that.status = 1;
+                            } else {
+                                time = signUpStartTime - now;
+                            }
+                            break;
+                        case 1:
+                            if (now > signUpEndTime) {
+                                that.status = 3;
+                            } else {
+                                time = signUpEndTime - now;
+                            }
+                            break;
+                        case 2:
+                            if (now > signUpEndTime) {
+                                that.status = 3;
+                            } else {
+                                time = signUpEndTime - now;
+                            }
+                            break;
+                        case 3:
+                            if (now > playStartTime) {
+                                that.status = 4;
+                            } else {
+                                time = playStartTime - now;
+                            }
+                            break;
+                        case 4:
+                            if (now > playEndTime) {
+                                that.status = 5;
+                            } else {
+                                time = playEndTime - now;
+                            }
+                            break;
+                    }
+                    let total = time / 1000
+                    if (total > 86400) { // 超过一天则显示天数
+                      clearInterval(that.timer)
+                      that.end = Math.floor(total / 86400)
+                    } else if (total > 0) {
                         --total;
                         let hours = Math.floor(total / (60 * 60));
                         let minutes = Math.floor(total % (60 * 60) / 60);
                         let seconds = Math.floor(total % (60 * 60) % 60);
                         time = `${that.core.formateTime(hours)}:${that.core.formateTime(minutes)}:${that.core.formateTime(seconds)}`;
-                    } else {
+                    } else if (that.status === 5) { // 竞赛结束直接停止定时器
                         clearInterval(that.timer);
                     }
-                    el.innerHTML = time;
+                    if (total > 0) el.innerHTML = time
                 }, 1000)
             }
         }
     },
     mounted() {
-        this.getData()
-        this.getProgress()
-        this.getNotice()
-        this.getTeam()
+      this.$once('hook:beforeDestroy', function() {
+        clearInterval(this.timer)
+        this.timerList.forEach(n => {
+          clearInterval(n)
+        })
+        this.timerList = []
+      })
+      this.getData()
+      this.getProgress()
+      this.getNotice()
+      this.getTeam()
     },
     methods: {
         ...mapMutations('match', [
@@ -562,11 +607,16 @@ export default {
               arches.map(e => e.stageId = e.stageId + '')
               this.arches = arches
               this.form = competition
-              const type = competition.completeCompetitionSetup.competitionType
               const reg = competition.competitionRegistration
-              reg || this.typeList.pop()
-              if (!type || (type && reg)) this.getInfo()
-              reg && reg.teamId && this.getRank()
+              // 报名后才显示参赛信息
+              if (reg) {
+                this.typeList.push({
+                  id: '5',
+                  name: '参赛信息'
+                })
+                this.getInfo()
+                reg.teamId && this.getRank()
+              }
               this.$refs.breadcrumb.update('全部赛事/' + competition.name)
             }).catch(err => {})
         },
@@ -612,14 +662,15 @@ export default {
           if (total > 0) {
               const day = Math.floor(total / (60 * 60 * 1000 * 24))
               const time = `${this.core.formateTime(Math.floor(total / hour))}:${this.core.formateTime(Math.floor(total % hour / minute))}:${this.core.formateTime(Math.floor(total % hour % minute / second))}`
-              this.end = day ? day + '天' : time
+              this.end = day || time
           }
         },
         // 获取竞赛信息
         getInfo() {
           this.$post(`${this.api.entryInformation}?competitionId=${this.id}`).then(res => {
             const info = res.entryInformation
-            if (!info.teamInstructors.length) info.teamInstructors.push(JSON.parse(JSON.stringify(this.originIns)))
+            // 如果是队长,并且没有指导老师,默认添加一个空的
+            if (!info.team.captain && !info.teamInstructors.length) info.teamInstructors.push(JSON.parse(JSON.stringify(this.originIns)))
             if (info.personalDetail) {
               info.team = {}
               info.teamDetail = []
@@ -629,12 +680,27 @@ export default {
             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))
+
+            // 设置定时器,阶段比赛结束后公布成绩,到时间后调本接口
+            const now = Date.now()
+            this.form.competitionStage.map(e => {
+              // 如果公布成绩详情勾选的是
+              if (!e.resultsDetails) {
+                const endTime = new Date(e.endTime).getTime() + e.resultAnnouncementTime * 3600000 // 阶段结束时间+成绩公布时间(成绩公布时间单位是小时,所以要转化为毫秒)
+                if (now > endTime) { // 如果到了公布时间
+                  info.stages.find(n => n.stageId === e.stageId).showDetail = 1
+                } else { // 没有到公布时间,则加定时器,到点后调用
+                  this.timerList.push(setTimeout(this.getInfo, endTime - now))
+                }
+              }
+            })
             this.info = info
           }).catch(err => {});
         },
         // 编辑保存
-        edit() {
-          if (this.editing) {
+        edit(showMsg) {
+          if (this.editing || !showMsg) {
             const { teamId, teamName, invitationCode } = this.info.team
             this.$post(this.api.editCompetitionTeam, {
               competitionId: this.id,
@@ -644,7 +710,7 @@ export default {
               whetherSignUp: 0
             }).then(res => {
               this.getInfo()
-              util.successMsg('保存成功')
+              showMsg && util.successMsg('保存成功')
             }).catch(res => {})
           } else {
             this.editing = !this.editing
@@ -677,15 +743,49 @@ export default {
         download(item) {
           util.downloadFile(item.fileName, item.filePath)
         },
-        // tab切换
+        // tab切换 前三个滚动,后两个切换
         typeChange() {
-          // 前三个滚动,后两个切换
           const type = +this.curType
-          if (type > 3) {
-            this.editing = false
+          // 如果上个选中的是参赛信息,则检查修改数据后有没保存(团队名称、邀请码、指导老师)
+          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"
+              }).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 {
-            document.querySelector(`#part${type}`).scrollIntoView()
+            type == 5 && this.getInfo()
+            type < 4 && document.querySelector(`#part${type}`).scrollIntoView()
           }
+          this.editing = false
+          this.lastType = type
         },
         // 跳转公告详情
         toNotice(item) {
@@ -735,6 +835,10 @@ export default {
           if (this.info.teamInstructors.length > 4) return util.errorMsg('指导老师仅限添加5个!')
           this.info.teamInstructors.push(JSON.parse(JSON.stringify(this.originIns)))
         },
+        // 编辑导老师
+        editAdvisor(row) {
+          this.$set(row, 'edit', 1)
+        },
         // 提交指导老师
         submitAdvisor(row) {
           if (!row.name) return util.errorMsg('请输入姓名')
@@ -763,6 +867,7 @@ export default {
             captainId: this.info.caption.teamId,
             playerId: this.checkedPlayer
           }).then(res => {
+            this.checkedPlayer = ''
             util.successMsg('转让成功')
             this.transferVisible = false
             this.getInfo()
@@ -770,7 +875,7 @@ export default {
         },
         // 踢出团队
         removeLine(row) {
-          this.$post(`${this.api.removeTheLine}?teamId=${row.teamId}`).then(res => {
+          this.$post(`${this.api.removeTheLine}?teamId=${this.info.teamId}&competitionId=${this.id}&accountId=${row.accountId}`).then(res => {
             util.successMsg('移除成功')
             this.getInfo()
           }).catch(res => {})
@@ -784,6 +889,24 @@ export default {
             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
+                  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.chooseVisible = true
             }
@@ -791,12 +914,17 @@ export default {
         },
         // 选择参赛人员提交
         chooseSubmit() {
+          const accountIds = this.checkedMembers
+          if (!accountIds.length) return util.errorMsg('请选择参赛成员!')
+          const limit = this.curRow.teamNumLimit // 参赛人数限制
+          if (accountIds.length > limit) return util.errorMsg(`请选择${limit}个以下参赛成员!`) // 选择的参赛人员个数不能大于参赛人数限制
           this.$post(this.api.stageSelectParticipants, {
-            accountIds: this.info.teamLimit ? [this.checkedMember] : this.checkedMembers,
+            accountIds,
             competitionId: this.id,
             stageId: this.curRow.stageId,
-            teamId: this.form.competitionRegistration.teamId
+            teamId: this.info.teamId
           }).then(res => {
+            this.checkedMembers = []
             util.successMsg('修改成功')
             this.getInfo()
             this.chooseVisible = false
@@ -805,7 +933,7 @@ export default {
         // 查看成绩详情
         show(row) {
           // 团队展示弹框,个人跳转实验报告
-          if (this.form.completeCompetitionSetup.competitionType && this.info.team.captain === 0) { // 团队比赛并且是团队,则展示团队成员成绩详情
+          if (this.form.completeCompetitionSetup.competitionType && this.info.team.captain === 0) { // 团队比赛并且是队长,则展示团队成员成绩详情
             this.curRow = row
             this.memberVisible = true
             const teamId = this.form.competitionRegistration.teamId
@@ -976,6 +1104,9 @@ export default {
           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', form.resultAnnouncementTime)
           util.cookies.set('fromManager', '', -1)
           // 8个python子系统都跳这个地址,子系统会通过cookie里的systemId识别展示哪套系统
           location.href = process.env.NODE_ENV === 'development' ?
@@ -1039,6 +1170,9 @@ export default {
     color: #6e6e6e;
   }
 }
+/deep/.el-tabs__item {
+  box-shadow: none !important;
+}
 .content{
     position: relative;
     padding: 20px 40px;
@@ -1052,6 +1186,7 @@ export default {
         color: #0B1D30;
     }
     .tool {
+      z-index: 100;
       position: sticky;
       top: 64px;
       margin-bottom: 20px;
diff --git a/src/pages/match/list/index.vue b/src/pages/match/list/index.vue
index 6c2fe98..5cde497 100644
--- a/src/pages/match/list/index.vue
+++ b/src/pages/match/list/index.vue
@@ -136,15 +136,15 @@
           <el-form class="dia-form">
             <p style="margin-bottom: 5px">请选择要加入的团队</p>
             <el-form-item>
-              <el-select class="w-100" v-model="enterForm.teamId">
+              <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-input placeholder="请输入6位数团队邀请码" maxlength="6" v-model="enterForm.invitationCode"></el-input>
             </el-form-item>
-            <el-form-item v-if="curItem.isNeedCode">
-              <el-input placeholder="请输入大赛邀请码" maxlength="6" v-model="enterForm.registrationInvitationCode"></el-input>
+            <el-form-item v-if="curItem.setup.isNeedCode">
+              <el-input placeholder="请输入4位数大赛邀请码" maxlength="4" v-model="enterForm.registrationInvitationCode"></el-input>
             </el-form-item>
             <p class="tips">
               查找不到团队?点击 <el-link :underline="false" type="primary" @click="toTeam">创建团队</el-link>
@@ -161,10 +161,10 @@
               <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-input placeholder="请输入6位数团队邀请码" maxlength="6" v-model="teamForm.invitationCode"></el-input>
             </el-form-item>
-            <el-form-item v-if="curItem.isNeedCode">
-              <el-input placeholder="请输入大赛邀请码" maxlength="6" v-model="teamForm.registrationInvitationCode"></el-input>
+            <el-form-item v-if="curItem.setup.isNeedCode">
+              <el-input placeholder="请输入4位数大赛邀请码" maxlength="4" v-model="teamForm.registrationInvitationCode"></el-input>
             </el-form-item>
           </el-form>
           <span slot="footer" class="dialog-footer">
@@ -286,7 +286,9 @@ export default {
               invitationCode: '',
               whetherSignUp: 1
             },
-            curItem: {}
+            curItem: {
+              setup: {}
+            }
         };
     },
     directives: {
@@ -295,67 +297,64 @@ export default {
                 let that = vnode.context;
                 let item = that.listData[binding.value];
                 let time = ''
-
-                let second = 1000;
-                let minute = second * 60;
-                let hour = minute * 60;
-                let now = new Date().getTime();
                 let signUpStartTime = new Date(that.core.dateCompatible(item.signUpStartTime)).getTime(); // 报名开始时间
                 let signUpEndTime = new Date(that.core.dateCompatible(item.signUpEndTime)).getTime(); // 报名结束时间
                 let playStartTime = new Date(that.core.dateCompatible(item.playStartTime)).getTime(); // 比赛开始时间
                 let playEndTime = new Date(that.core.dateCompatible(item.playEndTime)).getTime(); // 比赛结束时间
-                switch (item.status) {
-                    // status每个值的解释请看getData方法
-                    case 0:
-                        if (now > signUpStartTime) {
-                            item.status = item.whetherToSignUp ? 2 : 1 // 1已报名,2立即报名
-                        } else {
-                            time = signUpStartTime - now;
-                        }
-                        break;
-                    case 1:
-                        if (now > signUpEndTime) {
-                            item.status = 3;
-                        } else {
-                            time = signUpEndTime - now;
-                        }
-                        break;
-                    case 2:
-                        if (now > signUpEndTime) {
-                            item.status = 3;
-                        } else {
-                            time = signUpEndTime - now;
-                        }
-                        break;
-                    case 3:
-                        if (now > playStartTime) {
-                            item.status = 4;
-                        } else {
-                            time = playStartTime - now;
-                        }
-                        break;
-                    case 4:
-                        if (now > playEndTime) {
-                            item.status = 5;
-                        } else {
-                            time = playEndTime - now;
-                        }
-                        break;
-                }
-                time = `${Math.floor(time / hour)}:${Math.floor(time % hour / minute)}:${Math.floor(time % hour % minute / second)}`;
                 let timer = setInterval(() => {
-                    let timeList = time.split(":");
-                    let total = Number.parseInt(timeList[0] * 60 * 60) + Number.parseInt(timeList[1] * 60) + Number.parseInt(timeList[2]);
-                    if (total > 0) {
+                    let now = new Date().getTime();
+                    switch (item.status) {
+                        // status每个值的解释请看getData方法
+                        case 0:
+                            if (now > signUpStartTime) {
+                                item.status = item.whetherToSignUp ? 2 : 1 // 1已报名,2立即报名
+                            } else {
+                                time = signUpStartTime - now;
+                            }
+                            break;
+                        case 1:
+                            if (now > signUpEndTime) {
+                                item.status = 3;
+                            } else {
+                                time = signUpEndTime - now;
+                            }
+                            break;
+                        case 2:
+                            if (now > signUpEndTime) {
+                                item.status = 3;
+                            } else {
+                                time = signUpEndTime - now;
+                            }
+                            break;
+                        case 3:
+                            if (now > playStartTime) {
+                                item.status = 4;
+                            } else {
+                                time = playStartTime - now;
+                            }
+                            break;
+                        case 4:
+                            if (now > playEndTime) {
+                                item.status = 5;
+                            } else {
+                                time = playEndTime - now;
+                            }
+                            break;
+                    }
+                    let total = time / 1000
+                    if (total > 86400) { // 超过一天则显示天数
+                      clearInterval(timer)
+                      item.end = Math.floor(total / 86400)
+                    } else if (total > 0) {
                         --total;
                         let hours = Math.floor(total / (60 * 60));
                         let minutes = Math.floor(total % (60 * 60) / 60);
                         let seconds = Math.floor(total % (60 * 60) % 60);
                         time = `${that.core.formateTime(hours)}:${that.core.formateTime(minutes)}:${that.core.formateTime(seconds)}`;
-                    } else {
+                    } else if (that.status === 5) {
                         clearInterval(timer);
                     }
-                    el.innerHTML = time;
+                    if (total > 0) el.innerHTML = time;
                 }, 1000);
                 that.timerList.push(timer);
             }
@@ -451,7 +450,7 @@ export default {
               if (total > 0) {
                   const day = Math.floor(total / (60 * 60 * 1000 * 24))
                   const time = `${this.core.formateTime(Math.floor(total / hour))}:${this.core.formateTime(Math.floor(total % hour / minute))}:${this.core.formateTime(Math.floor(total % hour % minute / second))}`
-                  n.end = day ? day + '天' : time
+                  n.end = day || time
               }
 
               // 比赛范围
@@ -535,7 +534,7 @@ export default {
           const form = this.enterForm
           if (!form.teamId) return util.errorMsg('请选择团队')
           if (!form.invitationCode) return util.errorMsg('请输入团队邀请码')
-          if (this.curItem.isNeedCode && !form.registrationInvitationCode) return util.errorMsg('请输入大赛邀请码')
+          if (this.curItem.setup.isNeedCode && !form.registrationInvitationCode) return util.errorMsg('请输入大赛邀请码')
           this.$post(this.api.joinCompetitionTeam, form).then(res => {
             this.enterVisible = false
             this.getData()
@@ -570,7 +569,7 @@ export default {
           if (!form.teamName) return util.errorMsg('请输入团队名称')
           if (this.teamNameRepeat) return util.errorMsg('团队名称重复,请重新输入')
           if (form.invitationCode.length !== 6) return util.errorMsg('请输入6位数团队邀请码')
-          if (this.curItem.isNeedCode && !form.registrationInvitationCode) return util.errorMsg('请输入大赛邀请码')
+          if (this.curItem.setup.isNeedCode && !form.registrationInvitationCode) return util.errorMsg('请输入大赛邀请码')
           this.$post(this.api.addCompetitionTeam, form).then(res => {
             this.teamVisible = false
             this.enterVisible = false
@@ -669,6 +668,9 @@ export default {
           util.cookies.set('competitionId', this.curItem.id)
           util.cookies.set('stageId', form.stageId)
           util.cookies.set('teamId', this.curItem.teamId)
+          util.cookies.set('stopTime', form.endTime)
+          util.cookies.set('resultsDetails', form.resultsDetails)
+          util.cookies.set('resultAnnouncementTime', form.resultAnnouncementTime)
           util.cookies.set('fromManager', '', -1)
           // 8个python子系统都跳这个地址,子系统会通过cookie里的systemId识别展示哪套系统
           location.href = process.env.NODE_ENV === 'development' ?
diff --git a/src/pages/touristMatch/list/index.vue b/src/pages/touristMatch/list/index.vue
index 94f2436..f3af214 100644
--- a/src/pages/touristMatch/list/index.vue
+++ b/src/pages/touristMatch/list/index.vue
@@ -120,15 +120,15 @@
           <el-form class="dia-form">
             <p style="margin-bottom: 5px">请选择要加入的团队</p>
             <el-form-item>
-              <el-select class="w-100" v-model="enterForm.teamId">
+              <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-input placeholder="请输入6位数团队邀请码" maxlength="6" v-model="enterForm.invitationCode"></el-input>
             </el-form-item>
-            <el-form-item v-if="curItem.isNeedCode">
-              <el-input placeholder="请输入大赛邀请码" maxlength="6" v-model="enterForm.registrationInvitationCode"></el-input>
+            <el-form-item v-if="curItem.setup.isNeedCode">
+              <el-input placeholder="请输入4位数大赛邀请码" maxlength="4" v-model="enterForm.registrationInvitationCode"></el-input>
             </el-form-item>
             <p class="tips">
               查找不到团队?点击 <el-link :underline="false" type="primary" @click="toTeam">创建团队</el-link>
@@ -145,10 +145,10 @@
               <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-input placeholder="请输入6位数团队邀请码" maxlength="6" v-model="teamForm.invitationCode"></el-input>
             </el-form-item>
-            <el-form-item v-if="curItem.isNeedCode">
-              <el-input placeholder="请输入大赛邀请码" maxlength="6" v-model="teamForm.registrationInvitationCode"></el-input>
+            <el-form-item v-if="curItem.setup.isNeedCode">
+              <el-input placeholder="请输入4位数大赛邀请码" maxlength="4" v-model="teamForm.registrationInvitationCode"></el-input>
             </el-form-item>
           </el-form>
           <span slot="footer" class="dialog-footer">
@@ -251,7 +251,9 @@ export default {
               invitationCode: '',
               whetherSignUp: 1
             },
-            curItem: {}
+            curItem: {
+              setup: {}
+            }
         };
     },
     directives: {
@@ -260,67 +262,64 @@ export default {
                 let that = vnode.context;
                 let item = that.listData[binding.value];
                 let time = ''
-
-                let second = 1000;
-                let minute = second * 60;
-                let hour = minute * 60;
-                let now = new Date().getTime();
                 let signUpStartTime = new Date(that.core.dateCompatible(item.signUpStartTime)).getTime(); // 报名开始时间
                 let signUpEndTime = new Date(that.core.dateCompatible(item.signUpEndTime)).getTime(); // 报名结束时间
                 let playStartTime = new Date(that.core.dateCompatible(item.playStartTime)).getTime(); // 比赛开始时间
                 let playEndTime = new Date(that.core.dateCompatible(item.playEndTime)).getTime(); // 比赛结束时间
-                switch (item.status) {
-                    // status每个值的解释请看getData方法
-                    case 0:
-                        if (now > signUpStartTime) {
-                            item.status = item.whetherToSignUp ? 2 : 1 // 1已报名,2立即报名
-                        } else {
-                            time = signUpStartTime - now;
-                        }
-                        break;
-                    case 1:
-                        if (now > signUpEndTime) {
-                            item.status = 3;
-                        } else {
-                            time = signUpEndTime - now;
-                        }
-                        break;
-                    case 2:
-                        if (now > signUpEndTime) {
-                            item.status = 3;
-                        } else {
-                            time = signUpEndTime - now;
-                        }
-                        break;
-                    case 3:
-                        if (now > playStartTime) {
-                            item.status = 4;
-                        } else {
-                            time = playStartTime - now;
-                        }
-                        break;
-                    case 4:
-                        if (now > playEndTime) {
-                            item.status = 5;
-                        } else {
-                            time = playEndTime - now;
-                        }
-                        break;
-                }
-                time = `${Math.floor(time / hour)}:${Math.floor(time % hour / minute)}:${Math.floor(time % hour % minute / second)}`;
                 let timer = setInterval(() => {
-                    let timeList = time.split(":");
-                    let total = Number.parseInt(timeList[0] * 60 * 60) + Number.parseInt(timeList[1] * 60) + Number.parseInt(timeList[2]);
-                    if (total > 0) {
+                    let now = new Date().getTime();
+                    switch (item.status) {
+                        // status每个值的解释请看getData方法
+                        case 0:
+                            if (now > signUpStartTime) {
+                                item.status = item.whetherToSignUp ? 2 : 1 // 1已报名,2立即报名
+                            } else {
+                                time = signUpStartTime - now;
+                            }
+                            break;
+                        case 1:
+                            if (now > signUpEndTime) {
+                                item.status = 3;
+                            } else {
+                                time = signUpEndTime - now;
+                            }
+                            break;
+                        case 2:
+                            if (now > signUpEndTime) {
+                                item.status = 3;
+                            } else {
+                                time = signUpEndTime - now;
+                            }
+                            break;
+                        case 3:
+                            if (now > playStartTime) {
+                                item.status = 4;
+                            } else {
+                                time = playStartTime - now;
+                            }
+                            break;
+                        case 4:
+                            if (now > playEndTime) {
+                                item.status = 5;
+                            } else {
+                                time = playEndTime - now;
+                            }
+                            break;
+                    }
+                    let total = time / 1000
+                    if (total > 86400) { // 超过一天则显示天数
+                      clearInterval(timer)
+                      item.end = Math.floor(total / 86400)
+                    } else if (total > 0) {
                         --total;
                         let hours = Math.floor(total / (60 * 60));
                         let minutes = Math.floor(total % (60 * 60) / 60);
                         let seconds = Math.floor(total % (60 * 60) % 60);
                         time = `${that.core.formateTime(hours)}:${that.core.formateTime(minutes)}:${that.core.formateTime(seconds)}`;
-                    } else {
+                    } else if (that.status === 5) {
                         clearInterval(timer);
                     }
-                    el.innerHTML = time;
+                    if (total > 0) el.innerHTML = time;
                 }, 1000);
                 that.timerList.push(timer);
             }
@@ -500,7 +499,7 @@ export default {
           const form = this.enterForm
           if (!form.teamId) return util.errorMsg('请选择团队')
           if (!form.invitationCode) return util.errorMsg('请输入团队邀请码')
-          if (this.curItem.isNeedCode && !form.registrationInvitationCode) return util.errorMsg('请输入大赛邀请码')
+          if (this.curItem.setup.isNeedCode && !form.registrationInvitationCode) return util.errorMsg('请输入大赛邀请码')
           this.$post(this.api.joinCompetitionTeam, form).then(res => {
             this.enterVisible = false
             this.getData()
@@ -535,7 +534,7 @@ export default {
           if (!form.teamName) return util.errorMsg('请输入团队名称')
           if (this.teamNameRepeat) return util.errorMsg('团队名称重复,请重新输入')
           if (form.invitationCode.length !== 6) return util.errorMsg('请输入6位数团队邀请码')
-          if (this.curItem.isNeedCode && !form.registrationInvitationCode) return util.errorMsg('请输入大赛邀请码')
+          if (this.curItem.setup.isNeedCode && !form.registrationInvitationCode) return util.errorMsg('请输入大赛邀请码')
           this.$post(this.api.addCompetitionTeam, form).then(res => {
             this.teamVisible = false
             this.enterVisible = false
@@ -634,6 +633,7 @@ export default {
           util.cookies.set('competitionId', this.curItem.id)
           util.cookies.set('stageId', form.stageId)
           util.cookies.set('teamId', this.curItem.teamId)
+          util.cookies.set('stopTime', form.endTime)
           util.cookies.set('fromManager', '', -1)
           // 8个python子系统都跳这个地址,子系统会通过cookie里的systemId识别展示哪套系统
           location.href = process.env.NODE_ENV === 'development' ?
diff --git a/src/setting.js b/src/setting.js
index e8171ee..32def56 100644
--- a/src/setting.js
+++ b/src/setting.js
@@ -29,7 +29,7 @@ if (isPro) {
     host = "http://121.37.12.51/"; // 测试服
     // host = 'https://www.occupationlab.com/' // 正式服
     host = "http://192.168.31.51:9000/"; // 榕
-    host = "http://192.168.31.116:9000/"; // 赓
+    // host = "http://192.168.31.116:9000/"; // 赓
 }
 
 const Setting = {
diff --git a/src/store/modules/match.js b/src/store/modules/match.js
index c0ce517..cd46cb1 100644
--- a/src/store/modules/match.js
+++ b/src/store/modules/match.js
@@ -5,7 +5,8 @@ export default {
     namespaced: true,
     state: {
       toMatch: '',
-      eventType: 2 // 赛事类型
+      eventType: 2, // 赛事类型
+      noticed: 0 // 登录后会调一个接口提示是否有取消的赛事,提示完后置为1
     },
     mutations: {
       SET_SOURCE: (state, id) => {
@@ -13,6 +14,9 @@ export default {
       },
       SET_TYPE: (state, eventType) => {
         state.eventType = eventType
+      },
+      SET_NOTICE: (state) => {
+        state.noticed = 1
       }
     },
     actions: {