From e9af0bb1783e3e1ad33a645db15bffe86edd254f Mon Sep 17 00:00:00 2001
From: yujialong <479214531@qq.com>
Date: Wed, 6 Dec 2023 10:42:08 +0800
Subject: [PATCH] fix

---
 src/layouts/home/index.vue              |  2 +-
 src/libs/util.js                        | 11 ++++
 src/pages/activity/manage/add/index.vue |  2 +
 src/pages/match/details/index.vue       | 76 +++++++++++++++++--------
 src/pages/match/list/index.vue          | 48 ++++++++++++----
 src/pages/touristMatch/list/index.vue   | 65 +++++++++++----------
 src/setting.js                          |  6 +-
 7 files changed, 138 insertions(+), 72 deletions(-)

diff --git a/src/layouts/home/index.vue b/src/layouts/home/index.vue
index 2c88771..2516fde 100644
--- a/src/layouts/home/index.vue
+++ b/src/layouts/home/index.vue
@@ -161,7 +161,7 @@ export default {
 
       setInterval(() => {
         if (util.local.get(Setting.tokenKey) && (new Date().getTime() - lastTime) > Setting.autoLogoutTime) {
-          util.errorMsg("由于您已经有一个小时没有操作,系统自动登出,请重新登录。页面刷新到登录页。");
+          util.errorMsg("由于您已经有三个小时没有操作,系统自动登出,请重新登录。页面刷新到登录页。");
           setTimeout(this.logout, 1500);
         }
       }, 1000);
diff --git a/src/libs/util.js b/src/libs/util.js
index 4f1351d..f24a113 100644
--- a/src/libs/util.js
+++ b/src/libs/util.js
@@ -182,6 +182,17 @@ const util = {
             }
         }
     },
+    // 获取当前时间
+    getNow () {
+      return new Promise(async (resolve, reject) => {
+        const { data } = await axios.get(Setting.apiBaseURL + api.getCurrentTime, {
+					headers: {
+						token: _local.get(Setting.tokenKey)
+					}
+				})
+        resolve(new Date(data.currentTime))
+      })
+    },
 };
 
 export default util;
\ No newline at end of file
diff --git a/src/pages/activity/manage/add/index.vue b/src/pages/activity/manage/add/index.vue
index 898188c..862a620 100644
--- a/src/pages/activity/manage/add/index.vue
+++ b/src/pages/activity/manage/add/index.vue
@@ -323,12 +323,14 @@ export default {
     },
     // 封面自定义上传
     async handleRequest ({ file }) {
+      this.form.coverUrl && Oss.del(this.form.coverUrl)
       Oss.upload(file).then(res => {
         this.form.coverUrl = res.url
       })
     },
     // 封面自定义上传
     async handleRequestLg ({ file }) {
+      this.form.carouselUrl && Oss.del(this.form.carouselUrl)
       Oss.upload(file).then(res => {
         this.form.carouselUrl = res.url
       })
diff --git a/src/pages/match/details/index.vue b/src/pages/match/details/index.vue
index bcb8320..73194a7 100644
--- a/src/pages/match/details/index.vue
+++ b/src/pages/match/details/index.vue
@@ -99,7 +99,7 @@
                   <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"
+                <div v-if="form.rule === 1 && i !== form.competitionStage.length - 1"
                      class="flex">
                   <p>晋级规则:</p>
                   <div>
@@ -359,14 +359,14 @@
                               <el-tag v-for="tag in item.participants"
                                       :key="tag.name"
                                       class="m-r-5 m-b-5"
-                                      :closable="info.team.captain === 0"
+                                      :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"
+                            <i v-if="info.team.captain === 0 && status < 4"
                                class="el-icon-edit icon"
                                @click="selectPar(item)"></i>
                           </td>
@@ -649,11 +649,13 @@
         </div>
         <div class="flex m-b-20">
           <span class="fs-14">文件上传:</span>
-          <el-upload :disabled="uploading"
+          <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"
@@ -665,13 +667,16 @@
                        :loading="uploading"
                        :disabled="!!(fileList && fileList.length) || uploading">{{ uploading ? '正在上传' : fileList && fileList.length ? '已上传' : '上传文件' }}</el-button>
             <div slot="tip"
-                 class="el-upload__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>
@@ -892,8 +897,7 @@ export default {
         }
         this.$refs.breadcrumb.update('全部赛事/' + competition.name)
 
-        const res = await this.$get(this.api.getCurrentTime)
-        this.now = new Date(res.currentTime)
+        this.now = await Util.getNow()
         this.handleStatus()
         this.timer = setInterval(() => {
           this.now = new Date(this.now.setSeconds(this.now.getSeconds() + 1))
@@ -1009,7 +1013,7 @@ export default {
     },
     // 获取竞赛信息
     getInfo () {
-      this.$post(`${this.api.entryInformation}?competitionId=${this.id}`).then(res => {
+      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)))
@@ -1039,7 +1043,7 @@ export default {
           }
         })
         // 设置定时器,阶段比赛结束后公布成绩,到时间后调本接口
-        const now = Date.now()
+        const now = await Util.getNow()
         this.form.competitionStage && this.form.competitionStage.map(e => {
           // 如果公布成绩详情勾选的是
           if (!e.resultsDetails) {
@@ -1210,9 +1214,9 @@ export default {
       }).catch(res => { })
     },
     // 显示转让队长
-    transfer () {
+    async transfer () {
       // 取每个阶段的开始结束时间,有任何阶段开始了都不能转让队长和踢出队员
-      const now = new Date()
+      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)) {
@@ -1237,9 +1241,9 @@ export default {
       }).catch(res => { })
     },
     // 踢出团队
-    removeLine (row) {
+    async removeLine (row) {
       // 取每个阶段的开始结束时间,有任何阶段开始了都不能转让队长和踢出队员
-      const now = new Date()
+      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)) {
@@ -1270,11 +1274,11 @@ export default {
       }
     },
     // 移除参赛人员
-    removePar (e, stage) {
+    async removePar (e, stage) {
       const item = this.form.competitionStage.find(e => e.stageId == stage.stageId)
       if (item) {
         // 该阶段已经开始比赛则不能修改
-        const now = new Date()
+        const now = await Util.getNow()
         if (now >= new Date(item.startTime) && now <= new Date(item.endTime)) {
           return Util.errorMsg('该阶段比赛已经开始,无法修改允许参赛人员!')
         } else {
@@ -1295,11 +1299,11 @@ export default {
       }
     },
     // 选择参赛人员
-    selectPar (row) {
+    async selectPar (row) {
       const item = this.form.competitionStage.find(e => e.stageId == row.stageId)
       if (item) {
         // 该阶段已经开始比赛则不能修改
-        const now = new Date()
+        const now = await Util.getNow()
         if (now >= new Date(item.startTime) && now <= new Date(item.endTime)) {
           return Util.errorMsg('该阶段比赛已经开始,无法修改允许参赛人员!')
         } else {
@@ -1337,7 +1341,8 @@ export default {
         accountIds,
         competitionId: this.id,
         stageId: this.curRow.stageId,
-        teamId: this.info.teamId
+        teamId: this.info.teamId,
+        platformId: 1
       }).then(res => {
         this.checkedMembers = []
         Util.successMsg('修改成功')
@@ -1479,7 +1484,7 @@ export default {
         this.uploading = false
         const url = 'https://huoran.oss-cn-shenzhen.aliyuncs.com/' + name
         this.fileList = [{
-          name: name,
+          name: file.name,
           url
         }]
 
@@ -1498,6 +1503,13 @@ export default {
       } 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: "上传出错,请重试!",
@@ -2099,10 +2111,26 @@ export default {
         align-items: center;
     }
 }
-/deep/.el-upload__tip {
-    color: #727272;
-}
-/deep/.el-progress {
-    white-space: nowrap;
+/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>
\ No newline at end of file
diff --git a/src/pages/match/list/index.vue b/src/pages/match/list/index.vue
index 5b648b9..24f632c 100644
--- a/src/pages/match/list/index.vue
+++ b/src/pages/match/list/index.vue
@@ -294,11 +294,13 @@
 
         <div class="flex m-b-20">
           <span class="fs-14">文件上传:</span>
-          <el-upload :disabled="uploading"
+          <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"
@@ -310,13 +312,16 @@
                        :loading="uploading"
                        :disabled="!!(fileList && fileList.length) || uploading">{{ uploading ? '正在上传' : fileList && fileList.length ? '已上传' : '上传文件' }}</el-button>
             <div slot="tip"
-                 class="el-upload__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>
@@ -527,8 +532,7 @@ export default {
         this.listData = data.records
         this.totals = data.total
 
-        const res = await this.$get(this.api.getCurrentTime)
-        this.now = new Date(res.currentTime)
+        this.now = await Util.getNow()
         this.statusInterval()
         this.timer = setInterval(() => {
           this.now = new Date(this.now.setSeconds(this.now.getSeconds() + 1))
@@ -615,7 +619,6 @@ export default {
       this.$set(item, 'status', status)
       total = total / 1000
       --total
-      console.log("🚀 ~ file: index.vue:621 ~ handleStatus ~ now.getSeconds():", now, now.getSeconds())
       if (total > 86400) { // 超过一天则显示天数
         this.$set(item, 'end', Math.floor(total / 86400) + '天')
       } else if (total > 0) { // 一天之内,显示时分秒
@@ -789,7 +792,7 @@ export default {
         this.uploading = false
         const url = 'https://huoran.oss-cn-shenzhen.aliyuncs.com/' + name
         this.fileList = [{
-          name: name,
+          name: file.name,
           url
         }]
 
@@ -808,6 +811,13 @@ export default {
       } 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: "上传出错,请重试!",
@@ -1342,10 +1352,26 @@ export default {
         align-items: center;
     }
 }
-/deep/.el-upload__tip {
-    color: #727272;
-}
-/deep/.el-progress {
-    white-space: nowrap;
+/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>
\ No newline at end of file
diff --git a/src/pages/touristMatch/list/index.vue b/src/pages/touristMatch/list/index.vue
index 3a78edf..0c43f3e 100644
--- a/src/pages/touristMatch/list/index.vue
+++ b/src/pages/touristMatch/list/index.vue
@@ -253,14 +253,14 @@
 import { mapState, mapMutations } from "vuex";
 import { Loading } from "element-ui";
 import Setting from "@/setting"
-import util from "@/libs/util"
+import Util from "@/libs/util"
 
 export default {
   name: "match",
   data () {
     return {
       timer: null,
-      token: util.local.get(Setting.tokenKey),
+      token: Util.local.get(Setting.tokenKey),
       way: 2,
       statusList: ["待报名", "取消报名", "马上报名", "报名截止", "进入初赛", "已结束"],
       endList: ["报名开始", "报名截止", "报名截止", "竞赛开始", "竞赛结束", ""],
@@ -388,12 +388,11 @@ export default {
         sequence: form.sequence || null,
         keyWord: this.keyword
       }
-      this.$post(this.api[util.local.get(Setting.tokenKey) ? 'competitionAfterLogin' : 'notLoggedInBeforeStudentEvents'], data).then(async ({ data }) => {
+      this.$post(this.api[Util.local.get(Setting.tokenKey) ? 'competitionAfterLogin' : 'notLoggedInBeforeStudentEvents'], data).then(async ({ data }) => {
         this.listData = data.records
         this.totals = data.total
 
-        const res = await this.$get(this.api.getCurrentTime)
-        this.now = new Date(res.currentTime)
+        this.now = await Util.getNow()
         this.statusInterval()
         this.timer = setInterval(() => {
           this.now = new Date(this.now.setSeconds(this.now.getSeconds() + 1))
@@ -455,7 +454,7 @@ export default {
                 total = startTime - now
                 break
               } else if (now >= startTime && now <= endTime) { // 阶段比赛进行中,显示进入比赛按钮
-                if ((item.whetherToSignUp === 0 || !util.local.get(Setting.tokenKey)) && (e.method !== 2 || this.offlineCanEntry(e))) this.$set(item, 'stageName', e.count ? '已提交' : '进入' + e.stageName) // 报名了并且没参加比赛才能进入比赛
+                if ((item.whetherToSignUp === 0 || !Util.local.get(Setting.tokenKey)) && (e.method !== 2 || this.offlineCanEntry(e))) this.$set(item, 'stageName', e.count ? '已提交' : '进入' + e.stageName) // 报名了并且没参加比赛才能进入比赛
                 this.$set(item, 'endText', '阶段结束')
                 curStage = e
                 total = endTime - now
@@ -561,13 +560,13 @@ export default {
     // 团队报名提交
     enterSubmit () {
       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 (!form.teamId) return Util.errorMsg('请选择团队')
+      if (!form.invitationCode) return Util.errorMsg('请输入团队邀请码')
+      if (this.curItem.isNeedCode && !form.registrationInvitationCode) return Util.errorMsg('请输入大赛邀请码')
       this.$post(this.api.joinCompetitionTeam, form).then(res => {
         this.enterVisible = false
         this.getData()
-        util.successMsg('报名成功!')
+        Util.successMsg('报名成功!')
       }).catch(res => { })
     },
 
@@ -599,15 +598,15 @@ export default {
     // 团队提交
     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.curItem.isNeedCode && !form.registrationInvitationCode) return util.errorMsg('请输入大赛邀请码')
+      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('请输入大赛邀请码')
       this.$post(this.api.addCompetitionTeam, form).then(res => {
         this.teamVisible = false
         this.enterVisible = false
         this.getData()
-        util.successMsg('报名成功!')
+        Util.successMsg('报名成功!')
       }).catch(res => { })
     },
     // 选择要进入的阶段
@@ -636,12 +635,12 @@ export default {
       const { status, id } = item
       const { competitionType } = item
       // 如果没登录,提示去登录
-      if (util.local.get(Setting.tokenKey)) {
+      if (Util.local.get(Setting.tokenKey)) {
         this.curItem = item
         if (status == 4) { // 进入比赛
           // 参加过比赛不让参加
-          if (item.curStage.count) return util.errorMsg('您已经参加过该阶段竞赛!')
-          if (item.isDisable === 1) return util.errorMsg('当前用户已被禁赛,如有疑问,请联系平台管理员。') // 被禁用的用户不能进入大赛
+          if (item.curStage.count) return Util.errorMsg('您已经参加过该阶段竞赛!')
+          if (item.isDisable === 1) return Util.errorMsg('当前用户已被禁赛,如有疑问,请联系平台管理员。') // 被禁用的用户不能进入大赛
           // 团队赛,则判断是否为参赛人员
           if (competitionType) {
             this.$post(this.api.isParticipant, {
@@ -702,20 +701,20 @@ export default {
     // 进入python系统
     toPython () {
       const form = this.curItem.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', escape(form.systemName))
-      util.cookies.set('systemId', form.systemId)
-      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)
+      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', escape(form.systemName))
+      Util.cookies.set('systemId', form.systemId)
+      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' ?
         `http://${location.hostname}:8085/#/` :
@@ -729,7 +728,7 @@ export default {
       const { systemId, projectId, cid, stageId } = form.curStage
       const competitionId = form.id
       const teamId = form.teamId
-      let token = util.local.get(Setting.tokenKey);
+      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`
diff --git a/src/setting.js b/src/setting.js
index 11c4460..9ce4976 100644
--- a/src/setting.js
+++ b/src/setting.js
@@ -31,8 +31,8 @@ if (isPro) {
     sandPath = `http://${location.hostname}:9520`
     uploadURL = `http://121.37.12.51/`
     host = "http://121.37.12.51/"; // 测试服
-    host = 'https://www.occupationlab.com/' // 正式服
-    // host = "http://192.168.31.217:9000/"; // 榕
+    // host = 'https://www.occupationlab.com/' // 正式服
+    host = "http://192.168.31.217:9000/"; // 榕
     // host = "http://192.168.31.51:9000/"; // 赓
 } else if (isSq) {
 	zcPath = `10.20.100.204:8883`
@@ -51,7 +51,7 @@ const Setting = {
     uploadURL, // 阿里云oss域名
     systemPath, // 子系统地址前缀
 		sandPath,
-    autoLogoutTime: 1000 * 60 * 60, // 长时间未操作,自动退出登录时间
+    autoLogoutTime: 1000 * 60 * 60 * 3, // 长时间未操作,自动退出登录时间
     modalDuration: 3, // 接口请求返回错误时,弹窗的持续时间,单位:秒
     errorModalType: "Message", // 接口请求返回错误时,弹窗的类型,可选值为 Message 或 Notice
     cookiesExpires: 1, // Cookies 默认保存时间,单位:天