parent
35e94fcad8
commit
2ef4dc9f36
13 changed files with 571 additions and 704 deletions
After Width: | Height: | Size: 334 B |
@ -0,0 +1,172 @@ |
|||||||
|
<template> |
||||||
|
<div class="wrap"> |
||||||
|
<div class="breadcrumb"> |
||||||
|
<el-breadcrumb separator=">"> |
||||||
|
<template v-for="(item, i) in breadPath"> |
||||||
|
<el-breadcrumb-item |
||||||
|
v-if="!i" |
||||||
|
:key="i" |
||||||
|
:to="{ path: 'list' }"> |
||||||
|
{{item}} |
||||||
|
</el-breadcrumb-item> |
||||||
|
<el-breadcrumb-item |
||||||
|
v-else-if="breadPath.length > 2 && i === 1" |
||||||
|
:to="{ path: 'details', query: { end, status } }" |
||||||
|
:key="i"> |
||||||
|
{{item}} |
||||||
|
</el-breadcrumb-item> |
||||||
|
<el-breadcrumb-item |
||||||
|
v-else |
||||||
|
:key="i"> |
||||||
|
{{item}} |
||||||
|
</el-breadcrumb-item> |
||||||
|
</template> |
||||||
|
</el-breadcrumb> |
||||||
|
</div> |
||||||
|
<div class="page"> |
||||||
|
<h6 class="title">{{ form.announcementTitle }}</h6> |
||||||
|
<div class="metas"> |
||||||
|
<span>{{ form.updateTime }}</span> |
||||||
|
</div> |
||||||
|
<div class="content ql-editor" v-html="form.announcementText"></div> |
||||||
|
|
||||||
|
<template v-if="form.announcementAnnexList"> |
||||||
|
<h6 class="p-title">附件下载</h6> |
||||||
|
<ul class="files"> |
||||||
|
<li v-for="(item, i) in form.announcementAnnexList" :key="i"> |
||||||
|
<el-link class="m-r-10" type="primary" @click="preview(item)">{{ item.fileName }}</el-link> |
||||||
|
<el-link type="primary" :underline="false" @click="download(item)">下载</el-link> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import { Loading } from 'element-ui'; |
||||||
|
import 'quill/dist/quill.core.css'; |
||||||
|
import 'quill/dist/quill.snow.css'; |
||||||
|
import 'quill/dist/quill.bubble.css'; |
||||||
|
import breadcrumb from '@/components/breadcrumb' |
||||||
|
import util from '@/libs/util' |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
end: this.$route.query.end, |
||||||
|
status: this.$route.query.status, |
||||||
|
breadPath: ['全部赛事', this.$route.query.name], |
||||||
|
form: { |
||||||
|
id: this.$route.query.id, |
||||||
|
announcementText: '', |
||||||
|
announcementTitle: '', |
||||||
|
announcementAnnexList: [] |
||||||
|
}, |
||||||
|
loadIns: null |
||||||
|
} |
||||||
|
}, |
||||||
|
components: { |
||||||
|
breadcrumb |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 公告详情 |
||||||
|
getData() { |
||||||
|
this.loadIns = Loading.service() |
||||||
|
this.$post(`${this.api.queryAnnouncementDetails}?id=${this.form.id}`).then(({ data }) => { |
||||||
|
this.form = data |
||||||
|
this.breadPath.push(data.announcementTitle) |
||||||
|
this.loadIns.close() |
||||||
|
}).catch(err => { |
||||||
|
this.loadIns.close() |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 预览附件 |
||||||
|
preview(item) { |
||||||
|
const { filePath } = item |
||||||
|
const suffix = filePath.substr(filePath.lastIndexOf('.') + 1) |
||||||
|
window.open((util.isDoc(suffix) || suffix === 'pdf' ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + item.filePath) |
||||||
|
}, |
||||||
|
// 下载附件 |
||||||
|
download(item) { |
||||||
|
util.downloadFile(item.fileName, item.filePath) |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.breadcrumb { |
||||||
|
margin: 4px 0 16px; |
||||||
|
/deep/.el-breadcrumb__item { |
||||||
|
.is-link, .el-breadcrumb__separator { |
||||||
|
font-weight: 400; |
||||||
|
color: $main-color; |
||||||
|
} |
||||||
|
&:last-child { |
||||||
|
.is-link { |
||||||
|
color: #0B1D30; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.wrap { |
||||||
|
padding-bottom: 20px; |
||||||
|
.title{ |
||||||
|
margin-top: 30px; |
||||||
|
text-align: center; |
||||||
|
font-size: 28px; |
||||||
|
font-weight: 500; |
||||||
|
color: #0B1D30; |
||||||
|
} |
||||||
|
.metas{ |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
padding-bottom: 32px; |
||||||
|
margin: 16px 0 32px; |
||||||
|
span{ |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
color: #999; |
||||||
|
font-size: 12px; |
||||||
|
img{ |
||||||
|
width: 18px; |
||||||
|
margin-right: 5px; |
||||||
|
} |
||||||
|
} |
||||||
|
.el-divider { |
||||||
|
margin: 0 16px; |
||||||
|
} |
||||||
|
} |
||||||
|
.cover{ |
||||||
|
margin: 20px 0; |
||||||
|
text-align: center; |
||||||
|
img{ |
||||||
|
width: 800px; |
||||||
|
} |
||||||
|
} |
||||||
|
.content{ |
||||||
|
margin-bottom: 20px; |
||||||
|
line-height: 1.8; |
||||||
|
font-size: 16px; |
||||||
|
text-indent: 2em; |
||||||
|
/deep/img{ |
||||||
|
display: block; |
||||||
|
width: 600px; |
||||||
|
margin-left: auto; |
||||||
|
margin-right: auto; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.files { |
||||||
|
margin-bottom: 30px; |
||||||
|
li { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin: 10px 0; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
@ -1,433 +0,0 @@ |
|||||||
<template> |
|
||||||
<div class="wrap index"> |
|
||||||
<div class="banner" :style="{backgroundImage: coverUrlComputed}"></div> |
|
||||||
<div class="center-wrap"> |
|
||||||
<breadcrumb ref="breadcrumb" :data="'全部赛事/' + title"></breadcrumb> |
|
||||||
<div class="content"> |
|
||||||
<div class="flex-between"> |
|
||||||
<el-tabs v-model="curType"> |
|
||||||
<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="status != 5"> |
|
||||||
距离{{ endList[status] }}还有<em>{{ end }}</em>天 |
|
||||||
</p> |
|
||||||
<a class="status" :class="{wait: status == 0 || status == 4,signing: status == 2,signed: status == 1,finish: status == 3 || status == 5}" @click.stop="signup">{{ statusList[status] }}</a> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<h6 class="title">{{title}}</h6> |
|
||||||
<div class="meta">最近编辑时间:{{gmtModified}}</div> |
|
||||||
<div class="texts ql-editor" v-html="description" v-if="curType == 1"></div> |
|
||||||
<div v-else> |
|
||||||
<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> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import breadcrumb from '@/components/breadcrumb' |
|
||||||
export default { |
|
||||||
name: 'matchdetail', |
|
||||||
data() { |
|
||||||
return { |
|
||||||
id: this.$store.state.match.matchId, |
|
||||||
showSignup: this.$store.state.match.matchSignupStatus, |
|
||||||
end: this.$route.query.end, |
|
||||||
statusList: ["等待报名", "已报名", "立即报名", "报名截止", "比赛中", "已结束"], |
|
||||||
endList: ["报名开始", "报名截止", "报名截止", "竞赛开始", "竞赛结束", ""], |
|
||||||
coverUrl: '', |
|
||||||
title: '', |
|
||||||
curType: '1', |
|
||||||
typeList: [ |
|
||||||
{ |
|
||||||
id: '1', |
|
||||||
name: '竞赛信息' |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: '2', |
|
||||||
name: '竞赛进展' |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: '3', |
|
||||||
name: '通知公告' |
|
||||||
} |
|
||||||
], |
|
||||||
description: '', |
|
||||||
gmtModified: '', |
|
||||||
signUpStartTime: '', |
|
||||||
signUpEndTime: '', |
|
||||||
playStartTime: '', |
|
||||||
playEndTime: '', |
|
||||||
progress: [], |
|
||||||
status: this.$route.query.status, |
|
||||||
statusList: ["等待报名", "已报名", "立即报名", "报名截止", "比赛中", "已结束"], |
|
||||||
timer: null |
|
||||||
}; |
|
||||||
}, |
|
||||||
components: { |
|
||||||
breadcrumb |
|
||||||
}, |
|
||||||
directives: { |
|
||||||
countdown: { |
|
||||||
bind: function(el, binding, vnode) { |
|
||||||
let that = vnode.context; |
|
||||||
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(that.signUpStartTime)).getTime(); // 报名开始时间 |
|
||||||
let signUpEndTime = new Date(that.core.dateCompatible(that.signUpEndTime)).getTime(); // 报名结束时间 |
|
||||||
let playStartTime = new Date(that.core.dateCompatible(that.playStartTime)).getTime(); // 比赛开始时间 |
|
||||||
let playEndTime = new Date(that.core.dateCompatible(that.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) { |
|
||||||
--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 { |
|
||||||
clearInterval(that.timer); |
|
||||||
} |
|
||||||
el.innerHTML = time; |
|
||||||
}, 1000) |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
computed: { |
|
||||||
coverUrlComputed() { |
|
||||||
return this.coverUrl? 'url(' + this.coverUrl + ')' : "url('../../../assets/img/info-banner.png')" |
|
||||||
} |
|
||||||
}, |
|
||||||
mounted() { |
|
||||||
this.getData() |
|
||||||
this.getProgress() |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
getData() { // 获取竞赛信息 |
|
||||||
this.$get(this.api.getContest + '/' + this.id).then(res => { |
|
||||||
let data = res.contest |
|
||||||
this.coverUrl = data.carouselUrl |
|
||||||
this.description = data.description |
|
||||||
this.title = data.name |
|
||||||
this.gmtModified = data.gmtModified |
|
||||||
this.signUpStartTime = data.signUpStartTime |
|
||||||
this.signUpEndTime = data.signUpEndTime |
|
||||||
this.playStartTime = data.playStartTime |
|
||||||
this.playEndTime = data.playEndTime |
|
||||||
this.$forceUpdate() |
|
||||||
this.$refs.breadcrumb.update('全部赛事/' + data.name) |
|
||||||
}).catch(err => {}) |
|
||||||
}, |
|
||||||
getProgress() { // 获取竞赛进展 |
|
||||||
this.$get(this.api.getContestProgress + '/' + this.id).then(res => { |
|
||||||
this.progress = res.contestProgressList.reverse() |
|
||||||
}).catch(err => {}); |
|
||||||
}, |
|
||||||
signup(){ // 立即报名 |
|
||||||
if (this.status == 2) { |
|
||||||
let data = { |
|
||||||
contestId: this.id |
|
||||||
} |
|
||||||
this.$post(this.api.addApplicant,data).then(res => { |
|
||||||
this.$message.success('报名成功') |
|
||||||
this.status = 1; |
|
||||||
}).catch(res => {}) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
}; |
|
||||||
</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; |
|
||||||
h6 { |
|
||||||
margin-bottom: 30px; |
|
||||||
font-size: 42px; |
|
||||||
} |
|
||||||
.text { |
|
||||||
font-size: 20px; |
|
||||||
line-height: 30px; |
|
||||||
} |
|
||||||
} |
|
||||||
.main .center-wrap { |
|
||||||
margin-top: 30px; |
|
||||||
} |
|
||||||
.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; |
|
||||||
} |
|
||||||
.meta{ |
|
||||||
padding: 16px 0; |
|
||||||
font-size: 12px; |
|
||||||
color: #999; |
|
||||||
text-align: center; |
|
||||||
} |
|
||||||
.action { |
|
||||||
display: inline-flex; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
.status { |
|
||||||
padding: 0 16px; |
|
||||||
margin-left: 20px; |
|
||||||
line-height: 34px; |
|
||||||
font-size: 14px; |
|
||||||
color: #fff; |
|
||||||
background-color: #52C41A; |
|
||||||
border-radius: 4px; |
|
||||||
cursor: pointer; |
|
||||||
&.wait { |
|
||||||
background-color: #FAAD14; |
|
||||||
} |
|
||||||
&.signing { |
|
||||||
background-color: $main-color; |
|
||||||
} |
|
||||||
&.signed { |
|
||||||
background-color: #52C41A; |
|
||||||
} |
|
||||||
&.finish { |
|
||||||
background-color: #ccc; |
|
||||||
} |
|
||||||
} |
|
||||||
.end-text { |
|
||||||
font-size: 12px; |
|
||||||
color: #666; |
|
||||||
em { |
|
||||||
font-style: normal; |
|
||||||
color: #f00; |
|
||||||
} |
|
||||||
} |
|
||||||
.texts{ |
|
||||||
margin: 20px 0 50px; |
|
||||||
font-size: 16px; |
|
||||||
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 60px; |
|
||||||
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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
</style> |
|
Loading…
Reference in new issue