parent
13d0e57d9a
commit
8d3b1e62f5
13 changed files with 2476 additions and 1 deletions
@ -0,0 +1,512 @@ |
||||
<template> |
||||
<div> |
||||
<el-card v-if="!id" shadow="hover" class="m-b-20"> |
||||
<div class="flex-between"> |
||||
<el-page-header @back="back" :content="'创建项目'"></el-page-header> |
||||
</div> |
||||
</el-card> |
||||
<div class="page"> |
||||
<div class="page-content"> |
||||
<el-form label-width="170px" label-suffix=":" size="small"> |
||||
<el-form-item label="项目封面(选填)"> |
||||
<el-upload |
||||
class="avatar-uploader" |
||||
accept=".jpg,.png,.jpeg,.gif" |
||||
:on-success="uploadSuccess" |
||||
:limit="1" |
||||
:action="this.api.fileupload" |
||||
:headers="headers" |
||||
name="file" |
||||
> |
||||
<img v-if="form.coverUrl" :src="form.coverUrl" class="avatar"> |
||||
<div class="uploader-default" v-else> |
||||
<i class="el-icon-plus"></i> |
||||
<p>上传封面</p> |
||||
</div> |
||||
<div slot="tip" class="el-upload__tip"> |
||||
<p>展示宽度为220,高度140,JPG/PNG/GIF,3MB以内</p> |
||||
</div> |
||||
</el-upload> |
||||
</el-form-item> |
||||
<el-form-item label="项目封面长图(选填)"> |
||||
<el-upload |
||||
class="avatar-uploader avatar-uploader-lg" |
||||
accept=".jpg,.png,.jpeg,.gif" |
||||
:on-success="uploadLgSuccess" |
||||
:limit="1" |
||||
:action="this.api.fileupload" |
||||
:headers="headers" |
||||
name="file" |
||||
> |
||||
<img v-if="form.carouselUrl" :src="form.carouselUrl" class="avatar-lg"> |
||||
<div class="uploader-default" v-else> |
||||
<i class="el-icon-plus"></i> |
||||
<p>上传封面</p> |
||||
</div> |
||||
<div slot="tip" class="el-upload__tip"> |
||||
<p>展示宽度为1920,高度300,JPG/PNG/GIF,3MB以内</p> |
||||
</div> |
||||
</el-upload> |
||||
</el-form-item> |
||||
<el-form-item class="req" label="项目名称"> |
||||
<div class="d-inline-block"> |
||||
<el-input placeholder="请输入项目名称" v-model="form.projectName" clearable></el-input> |
||||
</div> |
||||
</el-form-item> |
||||
<el-form-item class="req" label="发起方"> |
||||
<div class="inline-input"> |
||||
<div class="input-wrap" v-for="(item,index) in sponsorList" :key="index"> |
||||
<el-input placeholder="发起方名称" v-model="sponsorList[index]"></el-input> |
||||
<i v-if="sponsorList.length > 1" class="remove" @click="delSponsor(index)"></i> |
||||
<button v-if="index == 0" class="add-btn" type="button" @click="addSponsor"> |
||||
<i class="el-icon-plus"></i> |
||||
<span>添加</span> |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</el-form-item> |
||||
<el-form-item class="req" label="报名时间"> |
||||
<el-date-picker v-model="signupTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange" |
||||
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" |
||||
:picker-options="pickerOptions"></el-date-picker> |
||||
</el-form-item> |
||||
<el-form-item class="req" label="项目时间"> |
||||
<el-date-picker v-model="playTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange" |
||||
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" |
||||
:picker-options="pickerOptions"></el-date-picker> |
||||
</el-form-item> |
||||
<el-form-item class="req" label="发布范围"> |
||||
<div> |
||||
<el-radio v-model="scope" :label="0" disabled>本校内</el-radio> |
||||
</div> |
||||
</el-form-item> |
||||
<el-form-item class="req" label="报名人数上限"> |
||||
<div class="input-center"> |
||||
<el-input placeholder="请输入人数" v-model.number="form.maximumNumber" type="number"></el-input> 人 |
||||
</div> |
||||
</el-form-item> |
||||
<el-form-item class="req" label="报名邀请码"> |
||||
<div class="input-center" style="width: 550px;"> |
||||
<el-radio v-model="form.isNeedCode" :label="0">不需要</el-radio> |
||||
<el-radio v-model="form.isNeedCode" :label="1">需要</el-radio> |
||||
<el-input style="width: 250px" placeholder="请输入4位邀请码或点击随机生成" v-model="form.invitationCode" :disabled="form.isNeedCode === 0"></el-input> |
||||
<el-button v-if="form.isNeedCode === 1" @click="randomInv">随机</el-button> |
||||
</div> |
||||
</el-form-item> |
||||
<el-form-item class="req" label="项目详情"> |
||||
<quill ref="quill" :border="true" v-model="form.projectDescribe" :height="400" /> |
||||
</el-form-item> |
||||
<el-form-item label="附件"> |
||||
<el-upload |
||||
:before-upload="beforeUpload" |
||||
:on-success="uploadAnnexSuccess" |
||||
:limit="5" |
||||
:action="this.api.fileupload" |
||||
:headers="headers" |
||||
:file-list="fileList" |
||||
name="file" |
||||
> |
||||
<el-button size="small" type="primary">点击上传</el-button> |
||||
<div slot="tip" class="el-upload__tip"> |
||||
<p>支持扩展名:.rar .zip .doc .docx .pdf .jpg...</p> |
||||
</div> |
||||
</el-upload> |
||||
</el-form-item> |
||||
</el-form> |
||||
|
||||
<div class="btns"> |
||||
<el-button @click="save(0)">保存</el-button> |
||||
<el-button type="primary" @click="save(1)">发布</el-button> |
||||
<el-button type="danger" @click="preview" v-auth="'/activity/list:管理:大赛详情:预览'">预览</el-button> |
||||
<el-button @click="back">取消</el-button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import util from "@/libs/util"; |
||||
import quill from "@/components/quill"; |
||||
import Setting from "@/setting"; |
||||
export default { |
||||
data() { |
||||
return { |
||||
id: this.$route.query.id || '', |
||||
headers: { |
||||
token: util.local.get(Setting.tokenKey) |
||||
}, |
||||
scope: 0, |
||||
form: { |
||||
id: this.$route.query.id || '', |
||||
founder: 1, |
||||
isOpen: 0, // 职站是否开启(0开启 1未开启 默认0) |
||||
maximumNumber: '', |
||||
carouselUrl: '', |
||||
coverUrl: '', |
||||
activityFileList: [], // 赛事附件 |
||||
initiator: '', |
||||
isNeedCode: 0, |
||||
maximumNumber: 0, |
||||
signUpStartTime: '', |
||||
signUpEndTime: '', |
||||
playStartTime: '', |
||||
playEndTime: '', |
||||
projectDescribe: '', |
||||
projectName: '', |
||||
publishStatus: 0, |
||||
}, |
||||
pickerOptions: { |
||||
disabledDate: time => { |
||||
return this.$route.query.id ? false : time.getTime() < new Date().getTime() - 86400000; |
||||
} |
||||
}, |
||||
fileName: '', |
||||
signupTime: [], |
||||
playTime: [], |
||||
sponsorList: [""], |
||||
fileList: [], |
||||
submiting: false, |
||||
updateTime: 0, |
||||
}; |
||||
}, |
||||
components: { |
||||
quill, |
||||
}, |
||||
watch: { |
||||
// 监听信息是否有更改,有的话页面离开的时候要询问是否要保存 |
||||
form: { |
||||
handler(){ |
||||
this.updateTime++ |
||||
}, |
||||
deep:true |
||||
}, |
||||
signupTime: function(val) { |
||||
const { form } = this |
||||
if (val) { |
||||
form.signUpStartTime = val[0]; |
||||
form.signUpEndTime = val[1]; |
||||
} else { |
||||
form.signUpStartTime = '' |
||||
form.signUpEndTime = '' |
||||
} |
||||
}, |
||||
playTime: function(val) { |
||||
const { form } = this |
||||
if (val) { |
||||
form.playStartTime = val[0] |
||||
form.playEndTime = val[1] |
||||
} else { |
||||
form.playStartTime = '' |
||||
form.playEndTime = '' |
||||
} |
||||
} |
||||
}, |
||||
mounted() { |
||||
this.getData() |
||||
}, |
||||
methods: { |
||||
getData() { |
||||
const { id } = this.form |
||||
id && this.$post(`${this.api.findByIdActivity}?id=${id}`).then(({ data }) => { |
||||
if (data.signUpStartTime) this.signupTime = [data.signUpStartTime, data.signUpEndTime] |
||||
if (data.playStartTime) this.playTime = [data.playStartTime, data.playEndTime] |
||||
this.sponsorList = data.initiator.split(",") |
||||
// 附件 |
||||
const fileList = data.activityFileList |
||||
if (fileList) { |
||||
const files = [] |
||||
fileList.map(e => { |
||||
files.push({ |
||||
name: e.fileName, |
||||
url: e.filePath |
||||
}) |
||||
}) |
||||
this.fileList = files |
||||
} else { |
||||
data.activityFileList = [] |
||||
} |
||||
|
||||
this.form = data |
||||
this.$nextTick(() => { |
||||
this.updateTime = 0 |
||||
}) |
||||
}).catch(err => {}) |
||||
}, |
||||
uploadSuccess(res) { |
||||
this.form.coverUrl = res.data.filesResult.fileUrl |
||||
}, |
||||
uploadLgSuccess(res) { |
||||
this.form.carouselUrl = res.data.filesResult.fileUrl |
||||
}, |
||||
// 附件上传成功 |
||||
uploadAnnexSuccess(res) { |
||||
const file = res.data.filesResult |
||||
const { id } = this.form |
||||
const data = { |
||||
activityId: id || '', |
||||
fileName: this.fileName, |
||||
filePath: file.fileUrl || file.fileId |
||||
} |
||||
this.form.activityFileList.push(data) |
||||
}, |
||||
// 附件上传前 |
||||
beforeUpload(file) { |
||||
const isLt2M = file.size / 1024 / 1024 < 10 |
||||
if (!isLt2M) util.warningMsg('请上传小于10MB的附件!') |
||||
if (isLt2M) { |
||||
this.fileName = file.name |
||||
return true |
||||
} else { |
||||
return false |
||||
} |
||||
}, |
||||
handleAnnexRemove(file, fileList) { |
||||
|
||||
}, |
||||
// 随机邀请码 |
||||
randomInv() { |
||||
let result = '' |
||||
for (let i = 0; i < 4; i++) { |
||||
result += Math.floor(Math.random() * 10); |
||||
} |
||||
this.form.completeCompetitionSetup.invitationCode = result |
||||
}, |
||||
// 提交 |
||||
save(status) { |
||||
const { form } = this |
||||
form.initiator = this.sponsorList.filter(d => d).join(); |
||||
if (!form.projectName) return util.warningMsg("请填写项目名称"); |
||||
// 发布需要校验 |
||||
if (status) { |
||||
if (!form.initiator) return util.warningMsg("请填写发起方"); |
||||
if (!form.signUpStartTime) return util.warningMsg("请选择报名时间"); |
||||
let now = new Date().getTime(); |
||||
let signUpStartTime = new Date(form.signUpStartTime).getTime(); |
||||
let signUpEndTime = new Date(form.signUpEndTime).getTime(); |
||||
let playStartTime = new Date(form.playStartTime).getTime(); |
||||
// if (signUpStartTime && now > signUpStartTime) return util.warningMsg("报名时间不能早于当前时间"); |
||||
if (!form.playStartTime) return util.warningMsg("请选择项目时间"); |
||||
if (playStartTime && signUpEndTime && playStartTime < signUpEndTime) return util.warningMsg("项目时间不能早于报名结束时间"); |
||||
if (form.isNeedCode && (!form.invitationCode || form.invitationCode.length !== 4)) return util.warningMsg('请填写四位数邀请码') |
||||
if (!form.projectDescribe) return util.warningMsg("请填写项目详情"); |
||||
} |
||||
form.publishStatus = status |
||||
form.id = this.$route.query.id |
||||
if (form.id) { |
||||
this.$post(this.api.updateActivity, form).then(res => { |
||||
this.updateTime = 0 |
||||
this.$router.back() |
||||
util.successMsg("修改成功"); |
||||
}).catch(err => {}); |
||||
} else { |
||||
this.$post(this.api.saveActivity, form).then(res => { |
||||
this.updateTime = 0 |
||||
this.$router.back() |
||||
util.successMsg("创建成功"); |
||||
}).catch(err => {}); |
||||
} |
||||
}, |
||||
// 预览 |
||||
preview() { |
||||
util.local.set('activity', this.form) |
||||
window.open(this.$router.resolve('/matchPreview').href) |
||||
}, |
||||
addSponsor() { |
||||
this.sponsorList.push(""); |
||||
}, |
||||
delSponsor(index) { |
||||
this.sponsorList.splice(index, 1); |
||||
}, |
||||
back() { |
||||
// 更改了信息才需要提示 |
||||
const { updateTime } = this.$refs['step' + this.step] |
||||
console.log("🚀 ~ file: index.vue:142 ~ back ~ updateTime", updateTime) |
||||
if (this.step < 4 && updateTime) { |
||||
this.$confirm(`编辑的内容未保存,是否保存?`, '提示', { |
||||
type: 'warning' |
||||
}).then(() => { |
||||
this.save(0) |
||||
}).catch(() => { |
||||
this.backPage() |
||||
}) |
||||
} else { |
||||
this.backPage() |
||||
} |
||||
}, |
||||
backPage() { |
||||
this.$router.push(`/activity?page=${this.$store.state.activity.page}`) |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style scoped lang="scss"> |
||||
$upload-width: 220px; |
||||
$upload-height: 140px; |
||||
$upload-lg-height: 150px; |
||||
/deep/ .avatar-uploader { |
||||
.el-upload { |
||||
position: relative; |
||||
width: $upload-width; |
||||
height: $upload-height; |
||||
border: 1px dashed #d9d9d9; |
||||
border-radius: 6px; |
||||
cursor: pointer; |
||||
overflow: hidden; |
||||
|
||||
&:hover { |
||||
border-color: #cb221c; |
||||
} |
||||
|
||||
.uploader-default { |
||||
display: flex; |
||||
height: $upload-height; |
||||
flex-direction: column; |
||||
justify-content: center; |
||||
text-align: center; |
||||
background: rgba(0, 0, 0, 0.04); |
||||
|
||||
i { |
||||
font-size: 20px; |
||||
font-weight: bold; |
||||
color: #8c939d; |
||||
} |
||||
|
||||
p { |
||||
margin-top: 10px; |
||||
font-size: 14px; |
||||
color: rgba(0, 0, 0, 0.65); |
||||
line-height: 1; |
||||
} |
||||
} |
||||
} |
||||
|
||||
&.avatar-uploader-lg { |
||||
.el-upload { |
||||
width: 100%; |
||||
max-width: 960px; |
||||
height: $upload-lg-height; |
||||
|
||||
.uploader-default { |
||||
height: $upload-lg-height; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.avatar { |
||||
display: block; |
||||
width: $upload-width; |
||||
height: $upload-height; |
||||
} |
||||
|
||||
.avatar-lg { |
||||
display: block; |
||||
width: 100%; |
||||
height: $upload-lg-height; |
||||
} |
||||
|
||||
.el-upload__tip { |
||||
margin-top: 0; |
||||
|
||||
p { |
||||
font-size: 14px; |
||||
color: rgba(0, 0, 0, 0.45); |
||||
line-height: 1; |
||||
|
||||
&:first-child { |
||||
margin-bottom: 5px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/deep/ .d-inline-block { |
||||
width: 216px; |
||||
|
||||
.el-select, .el-input { |
||||
width: 100%; |
||||
} |
||||
} |
||||
.inline-input { |
||||
.input-wrap { |
||||
display: flex; |
||||
align-items: center; |
||||
margin-bottom: 10px; |
||||
|
||||
.el-input { |
||||
display: inline-block; |
||||
width: 216px; |
||||
margin-right: 8px; |
||||
} |
||||
|
||||
.remove { |
||||
width: 16px; |
||||
height: 16px; |
||||
background: url("../../../assets/img/close.png") 0 0/cover no-repeat; |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
|
||||
.add-btn { |
||||
margin-left: 32px; |
||||
} |
||||
} |
||||
|
||||
.add-btn { |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
width: 216px; |
||||
line-height: 32px; |
||||
font-size: 14px; |
||||
color: rgba(0, 0, 0, 0.65); |
||||
background-color: transparent; |
||||
border: 1px dashed rgba(0, 0, 0, 0.15); |
||||
border-radius: 4px; |
||||
cursor: pointer; |
||||
|
||||
i { |
||||
margin-right: 8px; |
||||
font-size: 14px; |
||||
font-weight: bold; |
||||
} |
||||
} |
||||
.range-check { |
||||
display: inline-block; |
||||
margin: 0 0 10px 10px; |
||||
} |
||||
/deep/.range-cas { |
||||
.el-tag { |
||||
display: none; |
||||
} |
||||
} |
||||
.input-center { |
||||
display: flex; |
||||
align-items: center; |
||||
width: 216px; |
||||
white-space: nowrap; |
||||
.el-input { |
||||
margin-right: 5px; |
||||
} |
||||
} |
||||
.el-steps { |
||||
justify-content: center; |
||||
} |
||||
/deep/.req { |
||||
.el-form-item__label { |
||||
&:before { |
||||
content: '*'; |
||||
margin-right: 5px; |
||||
font-size: 18px; |
||||
vertical-align: middle; |
||||
color: #f00; |
||||
} |
||||
} |
||||
} |
||||
.btns { |
||||
display: flex; |
||||
justify-content: center; |
||||
text-align: center; |
||||
} |
||||
</style> |
@ -0,0 +1,365 @@ |
||||
<template> |
||||
<div class="page"> |
||||
<h6 class="p-title">筛选</h6> |
||||
<div class="tool mul"> |
||||
<ul class="filter"> |
||||
<li> |
||||
<label>创建时间:</label> |
||||
<div class="single-choice"> |
||||
<dl> |
||||
<dd> |
||||
<el-radio-group v-model="form.month" @change="changeType"> |
||||
<el-radio v-for="(item,index) in dateList" :key="index" :label="item.id" border>{{ item.name }}</el-radio> |
||||
</el-radio-group> |
||||
</dd> |
||||
</dl> |
||||
</div> |
||||
</li> |
||||
<li> |
||||
<label>创建区间:</label> |
||||
<el-date-picker v-model="date" align="right" unlink-panels type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable></el-date-picker> |
||||
</li> |
||||
<li> |
||||
<label>搜索:</label> |
||||
<el-input placeholder="请输入项目名称/创建人" suffix-icon="el-icon-search" v-model="keyword" clearable></el-input> |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
<div class="tool mul"> |
||||
<ul class="filter"> |
||||
<li> |
||||
<label>状态:</label> |
||||
<dl> |
||||
<dd> |
||||
<el-radio-group v-model="form.publishStatus" @change="changeType"> |
||||
<el-radio v-for="(item,index) in statuses" :key="index" :label="item.id" border>{{ item.name }}</el-radio> |
||||
</el-radio-group> |
||||
</dd> |
||||
</dl> |
||||
</li> |
||||
</ul> |
||||
<div> |
||||
<el-button type="primary" round @click="add" v-auth>创建项目</el-button> |
||||
<el-button type="primary" round @click="delAllSelection" v-auth>批量删除</el-button> |
||||
</div> |
||||
</div> |
||||
|
||||
<el-table ref="table" :data="activityData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id"> |
||||
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||
<el-table-column type="index" width="60" label="序号" align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.$index + (page - 1) * pageSize + 1 }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column> |
||||
<el-table-column prop="applicantNum" label="报名人数" align="center" width="150"></el-table-column> |
||||
<el-table-column prop="status" label="状态" align="center" width="90"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.row.publishStatus ? '已发布' : '未发布' }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="time" label="项目时间" align="center" width="300"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.row.playStartTime }} ~ {{ scope.row.playEndTime }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="createTime" label="创建时间" align="center" width="160"></el-table-column> |
||||
<el-table-column prop="founderName" label="创建人" align="center" width="130"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.row.founderName || '学校超管' }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" align="center" width="170"> |
||||
<template slot-scope="scope"> |
||||
<el-button v-auth type="text" @click="manage(scope.row)">管理</el-button> |
||||
<el-button v-auth type="text" @click="delData(scope.row)">删除</el-button> |
||||
<!-- 列表展示中台的禁启用依据zt_open展示,职站的禁启用依据is_open展示 --> |
||||
<!-- 中台禁用了这个学校发布的学校这边还能看到,但是学校这边不能启用。 --> |
||||
<el-switch |
||||
v-if="scope.row.publishStatus" |
||||
v-auth="'禁用'" |
||||
v-model="scope.row.isOpen" |
||||
:active-value="0" |
||||
:inactive-value="1" |
||||
style="margin: 0 10px 0 5px" |
||||
:active-text="scope.row.isOpen ? '关' : '开'" |
||||
@change="switchOff($event,scope.row,scope.$index)" |
||||
></el-switch> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page"> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import util from "@/libs/util"; |
||||
import Setting from "@/setting"; |
||||
import { mapMutations } from "vuex"; |
||||
import { Loading } from 'element-ui' |
||||
export default { |
||||
data() { |
||||
return { |
||||
timer: null, |
||||
keyword: "", |
||||
activityData: [], |
||||
statuses: [ |
||||
{ |
||||
id: '', |
||||
name: '不限' |
||||
}, |
||||
{ |
||||
id: 0, |
||||
name: '待发布' |
||||
}, |
||||
{ |
||||
id: 1, |
||||
name: '已发布' |
||||
} |
||||
], |
||||
form: { |
||||
month: "", |
||||
publishStatus: "", |
||||
startTime: "", |
||||
endTime: "", |
||||
}, |
||||
multipleSelection: [], |
||||
dateList: [ |
||||
{ |
||||
id: "", |
||||
name: "不限" |
||||
}, |
||||
{ |
||||
id: 1, |
||||
name: "近一个月" |
||||
}, |
||||
{ |
||||
id: 3, |
||||
name: "近三个月" |
||||
}, |
||||
{ |
||||
id: 6, |
||||
name: "近六个月" |
||||
} |
||||
], |
||||
date: [], |
||||
page: +this.$route.query.page || 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
transferPublishStatus: [ "未发布", "已发布"], |
||||
modifyVisible: false, |
||||
curRow: { |
||||
playingStages: [] |
||||
}, |
||||
timer: null, |
||||
redisTimer: null, |
||||
pickerOptions: { |
||||
shortcuts: [{ |
||||
text: '此刻', |
||||
onClick(picker) { |
||||
picker.$emit('pick', new Date(Date.now() + 5000)) |
||||
} |
||||
}] |
||||
} |
||||
}; |
||||
}, |
||||
watch: { |
||||
"form.month": function(val) { |
||||
if (val) { |
||||
let unit = 24 * 60 * 60 * 1000; |
||||
this.date = [util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() - unit * 30 * val)), util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() + unit))]; |
||||
} else { |
||||
this.date = []; |
||||
} |
||||
}, |
||||
date: function(val) { |
||||
if (val) { |
||||
this.form.startTime = val[0]; |
||||
this.form.endTime = val[1]; |
||||
} else { |
||||
this.form.startTime = ""; |
||||
this.form.endTime = ""; |
||||
} |
||||
this.initData(); |
||||
}, |
||||
keyword: function(val) { |
||||
clearTimeout(this.searchTimer); |
||||
this.searchTimer = setTimeout(() => { |
||||
this.initData(); |
||||
}, 500); |
||||
} |
||||
}, |
||||
mounted() { |
||||
this.getData() |
||||
this.$once('hook:beforeDestroy', function() { |
||||
clearInterval(this.timer) |
||||
clearInterval(this.redisTimer) |
||||
}) |
||||
}, |
||||
methods: { |
||||
...mapMutations('activity', [ |
||||
'setPage' |
||||
]), |
||||
getList() { |
||||
// const load = Loading.service() |
||||
const { form } = this |
||||
this.$post(this.api.activityList, { |
||||
pageNum: this.page, |
||||
pageSize: this.pageSize, |
||||
endTime: form.endTime || null, |
||||
keyWords: this.keyword || null, |
||||
platformSource: 1, // 当前所属平台(0:中台,1:职站教师 2职站学生) |
||||
startTime: form.startTime || null, |
||||
publishStatus: form.publishStatus === '' ? null : form.publishStatus |
||||
}).then(({ data }) => { |
||||
// load.close() |
||||
const list = data.records |
||||
// 定时处理是否要显示修改结束时间按钮 |
||||
this.timer = setInterval(() => { |
||||
const now = new Date() |
||||
list.map(e => { |
||||
if (!e.playingStages) { |
||||
this.$set(e, 'playingStages', []) |
||||
} else { |
||||
e.playingStages = [] |
||||
} |
||||
// 如果当前时间在项目开始结束时间之间 |
||||
if (now >= new Date(e.playStartTime) && now <= new Date(e.playEndTime)) { |
||||
// 遍历赛事阶段 |
||||
if (e.competitionStageList) { |
||||
for (const n of e.competitionStageList) { |
||||
// 判断是否有开始了的阶段 |
||||
if (now >= new Date(n.startTime) && now <= new Date(n.endTime)) { |
||||
e.playingStages.push(n) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}) |
||||
}, 1000) |
||||
list.map(e => { |
||||
if (e.ztOpen) e.isOpen = 1 |
||||
}) |
||||
this.activityData = list |
||||
this.total = data.total |
||||
this.$refs.table.clearSelection() |
||||
if (!this.activityData.length && this.total) { |
||||
this.page-- |
||||
this.getData() |
||||
} |
||||
}).catch(res => { |
||||
// load.close() |
||||
}) |
||||
}, |
||||
getData() { |
||||
this.getList() |
||||
}, |
||||
initData() { |
||||
this.page = 1; |
||||
this.getData(); |
||||
}, |
||||
// 获取redis缓存 |
||||
getRedis() { |
||||
this.$post(this.api.getRedisCacheActivity).then(({ data }) => { |
||||
data && this.getList() |
||||
}).catch(res => {}) |
||||
}, |
||||
getData() { |
||||
this.getList() |
||||
if (!Setting.isDev) { |
||||
clearInterval(this.redisTimer) |
||||
this.redisTimer = setInterval(this.getRedis, 1000) |
||||
} |
||||
}, |
||||
add() { |
||||
this.$router.push("/activity/add"); |
||||
}, |
||||
manage(row) { |
||||
this.$router.push(`/activity/manage?id=${row.id}&name=${row.projectName}`) |
||||
}, |
||||
|
||||
changeType() { |
||||
this.$refs.table.clearSelection(); |
||||
this.initData(); |
||||
}, |
||||
delData(row) { |
||||
this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", { |
||||
type: "warning" |
||||
}) |
||||
.then(() => { |
||||
this.$post(`${this.api.batchDeletionActivity}?ids=${row.id}`).then(res => { |
||||
util.successMsg("删除成功"); |
||||
this.getData(); |
||||
}).catch(res => { |
||||
}); |
||||
}) |
||||
.catch(() => { |
||||
}); |
||||
}, |
||||
handleSelectionChange(val) { |
||||
this.multipleSelection = val; |
||||
}, |
||||
// 批量删除 |
||||
delAllSelection() { |
||||
if (this.multipleSelection.length) { |
||||
this.$confirm("确定要删除吗?", "提示", { |
||||
type: "warning" |
||||
}).then(() => { |
||||
let ids = this.multipleSelection.map(i => 'ids=' + i.id); |
||||
this.$post(`${this.api.batchDeletionActivity}?${ids.join('&')}`).then(res => { |
||||
this.getData(); |
||||
this.$message.success("删除成功"); |
||||
this.$refs.table.clearSelection() |
||||
}).catch(err => { |
||||
}); |
||||
}).catch(() => { |
||||
}); |
||||
} else { |
||||
this.$message.warning("请先选择赛事 !"); |
||||
} |
||||
}, |
||||
handleCurrentChange(val) { |
||||
this.page = val; |
||||
this.$router.push(`list?page=${val}`) |
||||
this.getData() |
||||
this.setPage(val) |
||||
}, |
||||
transferTime(date, type) { |
||||
if (date == "0000-00-00 00:00:00") return "---"; |
||||
return date; |
||||
}, |
||||
switchOff(val, row) { |
||||
this.$post(this.api.disabledEventsActivity, { |
||||
activityId: row.id, |
||||
isOpen: val, |
||||
type: 1 // 禁用平台来源(0中台,1职站) |
||||
}).then(res => {}).catch(err => {}) |
||||
}, |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
/deep/ .tool { |
||||
.filter { |
||||
.el-input { |
||||
min-width: 190px; |
||||
} |
||||
} |
||||
} |
||||
|
||||
@media(max-width: 1640px) { |
||||
.page .page-content .tool .filter { |
||||
flex-wrap: wrap; |
||||
margin-bottom: -15px; |
||||
|
||||
li { |
||||
min-width: 34%; |
||||
margin-bottom: 15px; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,129 @@ |
||||
<template> |
||||
<!-- 赛事管理 --> |
||||
<div> |
||||
<el-card shadow="hover" class="m-b-20"> |
||||
<div class="flex-between"> |
||||
<el-page-header @back="back" :content="name + '/管理'"></el-page-header> |
||||
</div> |
||||
</el-card> |
||||
<div class="page" style="margin-bottom: 24px"> |
||||
<div class="tabs"> |
||||
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{ item }}</a> |
||||
</div> |
||||
<MatchDetail v-if="active == 'tab1'" ref="detail" /> |
||||
<MatchProgress v-else-if="active == 'tab2'" /> |
||||
<notice v-else-if="active == 'tab3'" /> |
||||
<MatchSignup v-else-if="active == 'tab4'" /> |
||||
</div> |
||||
</div> |
||||
|
||||
</template> |
||||
|
||||
<script> |
||||
import Setting from "@/setting"; |
||||
import MatchDetail from "../add"; |
||||
import MatchProgress from "./matchProgress"; |
||||
import notice from "./notice"; |
||||
import MatchSignup from "./matchSignup"; |
||||
import { mapState } from "vuex"; |
||||
export default { |
||||
name: "matchManage", |
||||
data() { |
||||
return { |
||||
name: this.$route.query.name, |
||||
active: this.$route.query.tab || "tab1", |
||||
tabs: { |
||||
tab1: "项目详情", |
||||
tab2: "项目进展", |
||||
tab3: "公告通知", |
||||
tab4: "报名人员" |
||||
}, |
||||
}; |
||||
}, |
||||
components: { |
||||
MatchDetail, |
||||
MatchProgress, |
||||
notice, |
||||
MatchSignup |
||||
}, |
||||
computed: { |
||||
...mapState("user", [ |
||||
'page' |
||||
]), |
||||
...mapState('auth', [ |
||||
'btns' |
||||
]) |
||||
}, |
||||
mounted() { |
||||
Setting.dynamicRoute && this.initTabs() |
||||
}, |
||||
methods: { |
||||
initTabs() { |
||||
const { btns } = this |
||||
const tab1 = btns.includes('/activity/list:管理:大赛详情') |
||||
const tab3 = btns.includes('/activity/list:管理:竞赛进展') |
||||
const tab4 = btns.includes('/activity/list:管理:公告通知') |
||||
const tab5 = btns.includes('/activity/list:管理:报名人员') |
||||
|
||||
tab1 || this.$delete(this.tabs, 'tab1') |
||||
tab3 || this.$delete(this.tabs, 'tab3') |
||||
tab4 || this.$delete(this.tabs, 'tab4') |
||||
tab5 || this.$delete(this.tabs, 'tab5') |
||||
const type = this.$route.query.tab |
||||
const keys = Object.keys(this.tabs) |
||||
this.active = keys.includes(type) ? type : keys[0] |
||||
}, |
||||
// 移除成绩管理 |
||||
hideArch() { |
||||
this.$delete(this.tabs, 'tab2') |
||||
}, |
||||
back() { |
||||
this.handleSave(0) && this.backPage() |
||||
}, |
||||
// 判断是否需要confirm |
||||
handleSave(i) { |
||||
// 如果是赛事详情,则要判断是否已经保存,未保存则提示是否保存 |
||||
if (this.active === 'tab1') { |
||||
const detail = this.$refs.detail |
||||
if (detail.step < 4 && detail.$refs['step' + detail.step].updateTime) { |
||||
this.$confirm(`编辑的内容未保存,是否保存并且发布?`, '提示', { |
||||
type: 'warning' |
||||
}).then(() => { |
||||
detail.save(1, 1) |
||||
this.backOrTab(i) |
||||
}).catch(() => { |
||||
this.backOrTab(i) |
||||
}) |
||||
} else { |
||||
this.backOrTab(i) |
||||
} |
||||
return false |
||||
} else { |
||||
return true |
||||
} |
||||
}, |
||||
// 返回列表 |
||||
backPage(){ |
||||
console.log(444, this.$store.state) |
||||
this.$router.push(`/activity?page=${this.$store.state.activity.page}`) |
||||
}, |
||||
// tab切换 |
||||
tabSwitch(i) { |
||||
this.active = i |
||||
this.$router.push(`/activity/manage?id=${this.$route.query.id}&tab=${i}&name=${this.name}`) |
||||
}, |
||||
// 判断返回还是tab |
||||
backOrTab(i) { |
||||
i ? this.tabSwitch(i) : this.backPage() |
||||
}, |
||||
// tab回调 |
||||
tabChange(i) { |
||||
this.handleSave(i) && this.tabSwitch(i) |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style scoped> |
||||
|
||||
</style> |
@ -0,0 +1,240 @@ |
||||
<template> |
||||
<!-- 竞赛进展 --> |
||||
<div class="page-content" style="padding: 24px"> |
||||
<el-table ref="table" :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id"> |
||||
<el-table-column type="index" width="60" label="序号" align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.$index + (pageNo - 1) * pageSize + 1 }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="name" label="标题"> |
||||
<template slot-scope="scope"> |
||||
<el-input placeholder="请输入标题" :disabled="!scope.row.operate" v-model="scope.row.title"></el-input> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="name" label="详情描述"> |
||||
<template slot-scope="scope"> |
||||
<el-input placeholder="请输入详情描述" :disabled="!scope.row.operate" type="textarea" v-model="scope.row.description"></el-input> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="name" label="状态" width="150"> |
||||
<template slot-scope="scope"> |
||||
<el-select v-model="scope.row.status" :disabled="!scope.row.operate" clearable placeholder="请选择状态"> |
||||
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||
</el-select> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" align="center" width="170"> |
||||
<template slot-scope="scope"> |
||||
<el-button v-if="!scope.row.operate" type="text" @click="operateIt(scope.row)" v-auth="'/activity:管理:竞赛进展:编辑'">编辑</el-button> |
||||
<el-button v-else type="text" @click="saveData(scope.row)">保存</el-button> |
||||
<el-button type="text" @click="handleDelete(scope.row, scope.$index)" v-auth="'/activity/list:管理:竞赛进展:删除'">删除</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="plus" @click="addData" v-auth="'/activity/list:管理:竞赛进展:新增'"> |
||||
<i class="el-icon-circle-plus-outline"></i> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import util from "@/libs/util"; |
||||
export default { |
||||
name: "matchProgress", |
||||
data() { |
||||
return { |
||||
save: false, |
||||
id: this.$route.query.id, |
||||
statusList: [ |
||||
{ |
||||
value: 0, |
||||
name: "未完成" |
||||
}, |
||||
{ |
||||
value: 1, |
||||
name: "进行中" |
||||
}, |
||||
{ |
||||
value: 2, |
||||
name: "已完成" |
||||
} |
||||
], |
||||
listData: [], |
||||
multipleSelection: [], |
||||
pageNo: 1, |
||||
pageSize: 10, |
||||
totals: 0, |
||||
touchTime:0, |
||||
timeOut: {} |
||||
}; |
||||
}, |
||||
mounted() { |
||||
this.getData(); |
||||
}, |
||||
methods: { |
||||
operateIt(row) { |
||||
row.operate = true |
||||
}, |
||||
getData() { |
||||
this.$get(this.api.getCompetitionProgress, { |
||||
competitionId: this.id |
||||
}).then(res => { |
||||
this.listData = res.competitionProgressList; |
||||
for(let index=0; index<this.listData.length; index++) { |
||||
// 未点编辑时不可输入 |
||||
this.$set(this.listData, index, { operate: false, ...this.listData[index]}) |
||||
} |
||||
}).catch(res => { |
||||
}); |
||||
}, |
||||
saveData(row) { |
||||
// 有点编辑的时候就要等待确认 |
||||
let data = row; |
||||
if (data.title.length) { |
||||
if (row.id) { |
||||
this.$put(this.api.editCompetitionProgress, data).then(res => { |
||||
this.touchTime = this.touchTime-1 |
||||
util.successMsg("修改成功"); |
||||
this.getData(); |
||||
}).catch(res => { |
||||
}); |
||||
} else { |
||||
this.$post(this.api.addCompetitionProgress, data).then(res => { |
||||
this.touchTime = this.touchTime-1 |
||||
util.successMsg("创建成功"); |
||||
this.getData(); |
||||
}).catch(res => { |
||||
}); |
||||
} |
||||
} else { |
||||
util.warningMsg("请填写标题"); |
||||
} |
||||
}, |
||||
handleSelectionChange(val) { |
||||
this.multipleSelection = val; |
||||
}, |
||||
onSearch() { |
||||
this.pageNo = 1; |
||||
this.getData(); |
||||
}, |
||||
handleCurrentChange(val) { |
||||
this.pageNo = val; |
||||
this.getData(); |
||||
}, |
||||
handleDelete(row, index) { |
||||
this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", { |
||||
type: "warning" |
||||
}).then(() => { |
||||
if(row.id === "") { |
||||
this.listData.splice(index, 1) |
||||
util.successMsg("删除成功"); |
||||
}else { |
||||
this.touchTime = this.touchTime+1 |
||||
this.$del(`${this.api.deleteCompetitionProgress}?competitionProgressId=${row.id}`).then(res => { |
||||
util.successMsg("删除成功"); |
||||
this.getData(); |
||||
}).catch(res => { |
||||
}); |
||||
} |
||||
|
||||
}).catch(() => { |
||||
}); |
||||
}, |
||||
addData() { |
||||
// this.$store.commit("activity/setWait", 1); |
||||
this.touchTime = this.touchTime+1 |
||||
if (this.listData.length) { |
||||
if (this.listData[this.listData.length - 1].id) { |
||||
this.listData.push({ |
||||
competitionId: this.id, |
||||
id: "", |
||||
title: "", |
||||
description: "", |
||||
status: 0, |
||||
operate: true |
||||
}); |
||||
this.operateIt(this.listData[this.listData.length - 1]) |
||||
} else { |
||||
util.warningMsg("请先保存新数据"); |
||||
} |
||||
} else { |
||||
this.listData.push({ |
||||
competitionId: this.id, |
||||
id: "", |
||||
title: "", |
||||
description: "", |
||||
status: 1, // status为1时表示未保存的 |
||||
operate: true |
||||
}); |
||||
} |
||||
}, |
||||
waitSave() { |
||||
if(this.hasEdit) { |
||||
this.$confirm('暂未保存,是否保存本次编辑?', '提示', { |
||||
confirmButtonText: '确定', |
||||
cancelButtonText: '取消', |
||||
type: 'warning' |
||||
}).then(() => { |
||||
let num = 0; |
||||
for(var i=0;i<this.listData.length;i++){ |
||||
let data = this.listData[i]; |
||||
if (data.title) { |
||||
if (this.listData[i].id) { |
||||
this.$put(this.api.editContestProgress, data).then(res => { |
||||
|
||||
}).catch(res => { |
||||
}); |
||||
}else{ |
||||
num = num+1 |
||||
} |
||||
}else{ |
||||
num = num+1 |
||||
} |
||||
} |
||||
if (num >0){ |
||||
this.$message({ |
||||
type: 'error', |
||||
message: '保存失败,有未填项目' |
||||
}); |
||||
}else{ |
||||
this.$message({ |
||||
type: 'success', |
||||
message: '保存成功!' |
||||
}); |
||||
} |
||||
}).catch(() => { |
||||
this.$message({ |
||||
type: 'info', |
||||
message: '已取消保存' |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
} |
||||
}, |
||||
computed: { |
||||
hasEdit() { |
||||
return this.listData.some(item => item.operate) |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style scoped lang="scss"> |
||||
.box { |
||||
height: calc(100vh - 100px); |
||||
overflow: auto; |
||||
} |
||||
|
||||
.plus { |
||||
padding: 15px 0 0; |
||||
text-align: center; |
||||
cursor: pointer; |
||||
|
||||
i { |
||||
font-size: 24px; |
||||
color: #cb221c; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,171 @@ |
||||
<template> |
||||
<!-- 报名人员 --> |
||||
<div class="page-content" style="padding: 24px"> |
||||
<div class="tool"> |
||||
<ul class="filter"> |
||||
<li> |
||||
<label>搜索:</label> |
||||
<el-input placeholder="请输入姓名/手机号/学号" prefix-icon="el-icon-search" v-model="keyword" clearable size="mini" style="width: 250px"></el-input> |
||||
</li> |
||||
<li v-if="info.releaseType"> |
||||
<label>参赛人员状态:</label> |
||||
<el-select v-model="isDisable" @change="initData"> |
||||
<el-option v-for="(item, i) in statusList" :key="i" :label="item.name" :value="item.id"></el-option> |
||||
</el-select> |
||||
</li> |
||||
</ul> |
||||
<div> |
||||
<el-button type="primary" round @click="exportAll" v-auth="'/activity/list:管理:报名人员:批量导出'">批量导出</el-button> |
||||
</div> |
||||
</div> |
||||
|
||||
<el-table ref="table" :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange"> |
||||
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column> |
||||
<el-table-column type="index" width="60" label="序号" align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.$index + (page - 1) * pageSize + 1 }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="school" label="学校" sortable="custom"> |
||||
</el-table-column> |
||||
<el-table-column prop="username" label="学生姓名"> |
||||
</el-table-column> |
||||
<el-table-column prop="workNumber" label="学号"> |
||||
</el-table-column> |
||||
<el-table-column prop="phone" label="手机号"> |
||||
</el-table-column> |
||||
<el-table-column label="操作" align="center" width="320"> |
||||
<template slot-scope="scope"> |
||||
<el-switch |
||||
v-auth="'/activity/list:管理:报名人员:禁用'" |
||||
v-model="scope.row.isDisable" |
||||
:active-text="scope.row.isDisable ? '关' : '开'" |
||||
:active-value="0" |
||||
:inactive-value="1" |
||||
style="margin: 0 10px 0 5px" |
||||
@change="switchOff($event,scope.row,scope.$index)" |
||||
></el-switch> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page"> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import util from "@/libs/util"; |
||||
import axios from 'axios' |
||||
import Setting from "@/setting"; |
||||
export default { |
||||
name: "matchSignup", |
||||
data() { |
||||
return { |
||||
token: util.local.get(Setting.tokenKey), |
||||
id: +this.$route.query.id, |
||||
info: { |
||||
completeCompetitionSetup: {} |
||||
}, |
||||
isDisable: '', |
||||
statusList: [ |
||||
{ |
||||
id: '', |
||||
name: '不限' |
||||
}, |
||||
{ |
||||
id: 1, |
||||
name: '已禁用' |
||||
}, |
||||
{ |
||||
id: 0, |
||||
name: '未禁用' |
||||
} |
||||
], |
||||
keyword: "", |
||||
listData: [], |
||||
multipleSelection: [], |
||||
page: 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
}; |
||||
}, |
||||
watch: { |
||||
keyword: function(val) { |
||||
clearTimeout(this.searchTimer); |
||||
this.searchTimer = setTimeout(() => { |
||||
this.initData(); |
||||
}, 500); |
||||
} |
||||
}, |
||||
mounted() { |
||||
this.initData() |
||||
}, |
||||
methods: { |
||||
getData() { |
||||
this.$post(this.api.ApplicantsList, { |
||||
pageNum: this.page, |
||||
pageSize: this.pageSize, |
||||
activityId: this.id, |
||||
keyWords: this.keyword, |
||||
isDisable: this.isDisable, |
||||
}).then(({ data }) => { |
||||
this.listData = data.records; |
||||
this.total = data.total; |
||||
}).catch(res => { |
||||
}); |
||||
}, |
||||
initData() { |
||||
this.page = 1 |
||||
this.getData() |
||||
}, |
||||
handleSelectionChange(val) { |
||||
this.multipleSelection = val; |
||||
}, |
||||
handleCurrentChange(val) { |
||||
this.page = val; |
||||
this.getData(); |
||||
}, |
||||
switchOff(val, row, index) { |
||||
this.$put(`${this.api.disableRegistration}?competitionRegistrationId=${row.id}&isDisable=${val}`).then(res => {}).catch(err => {}); |
||||
}, |
||||
exportAll() { |
||||
const data = this.multipleSelection |
||||
if (data.length) { |
||||
data.map((e, i) => e.id = i + 1) |
||||
axios.post(this.api.exportDataInBatches, data, { |
||||
headers: { |
||||
token: this.token |
||||
}, |
||||
responseType: 'blob' |
||||
}).then((res) => { |
||||
util.downloadFileDirect(`报名人员.xls`, new Blob([res.data])) |
||||
}).catch(res => {}) |
||||
} else { |
||||
axios.get(`${this.api.excelExport}?activityId=${this.id}`, { |
||||
headers: { |
||||
token: this.token |
||||
}, |
||||
responseType: 'blob' |
||||
}).then((res) => { |
||||
util.downloadFileDirect(`报名人员.xls`, new Blob([res.data])) |
||||
}).catch(res => {}) |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
/deep/.dia-form { |
||||
.w-100 { |
||||
width: 100%; |
||||
} |
||||
.tips { |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,140 @@ |
||||
<template> |
||||
<!-- 报名人员 --> |
||||
<div class="page-content" style="padding: 24px"> |
||||
<div class="tool" style="justify-content: flex-end"> |
||||
<el-button type="primary" round @click="add" v-auth="'/activity/list:管理:公告通知:新增'">新增</el-button> |
||||
</div> |
||||
|
||||
<el-table ref="table" :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id"> |
||||
<el-table-column type="index" width="60" label="序号" align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.$index + (pageNo - 1) * pageSize + 1 }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="announcementTitle" label="标题名称"> |
||||
</el-table-column> |
||||
<el-table-column prop="createTime" label="创建时间"> |
||||
</el-table-column> |
||||
<el-table-column prop="updateTime" label="发布时间"> |
||||
</el-table-column> |
||||
<el-table-column prop="phone" label="状态"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.row.status ? '已发布' : '草稿' }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" align="center" width="250"> |
||||
<template slot-scope="scope"> |
||||
<el-button type="text" @click="edit(scope.row)" v-auth="'/activity/list:管理:公告通知:编辑'">编辑</el-button> |
||||
<el-button type="text" @click="del(scope.row)" v-auth="'/activity/list:管理:公告通知:删除'">删除</el-button> |
||||
<el-switch |
||||
v-auth="'/activity/list:管理:公告通知:启用'" |
||||
v-model="scope.row.isOpen" |
||||
:active-text="scope.row.isOpen ? '关' : '开'" |
||||
:active-value="0" |
||||
:inactive-value="1" |
||||
style="margin: 0 10px 0 5px" |
||||
@change="switchOff($event,scope.row,scope.$index)" |
||||
></el-switch> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination background layout="total, prev, pager, next" :total="totals" @current-change="handleCurrentChange" :current-page="pageNo"> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import util from "@/libs/util"; |
||||
import Setting from "@/setting"; |
||||
|
||||
export default { |
||||
name: "matchSignup", |
||||
data() { |
||||
return { |
||||
token: util.local.get(Setting.tokenKey), |
||||
id: this.$route.query.id, |
||||
keyword: "", |
||||
listData: [], |
||||
multipleSelection: [], |
||||
pageNo: 1, |
||||
pageSize: 10, |
||||
totals: 0 |
||||
}; |
||||
}, |
||||
watch: { |
||||
keyword: function(val) { |
||||
clearTimeout(this.searchTimer); |
||||
this.searchTimer = setTimeout(() => { |
||||
this.getData(); |
||||
}, 500); |
||||
} |
||||
}, |
||||
mounted() { |
||||
this.getData() |
||||
}, |
||||
methods: { |
||||
getData() { |
||||
this.$post(`${this.api.queryAnnouncementByCompetitionId}?pageNum=${this.pageNo}&pageSize=${this.pageSize}&competitionId=${this.id}`).then(({ data }) => { |
||||
this.listData = data.records |
||||
this.totals = data.total |
||||
this.$refs.table.clearSelection() |
||||
}).catch(res => {}) |
||||
}, |
||||
handleSelectionChange(val) { |
||||
this.multipleSelection = val; |
||||
}, |
||||
handleCurrentChange(val) { |
||||
this.pageNo = val; |
||||
this.getData(); |
||||
}, |
||||
del(row) { |
||||
this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", { |
||||
type: "warning" |
||||
}) |
||||
.then(() => { |
||||
this.$post(`${this.api.deleteAnnouncement}?id=${row.id}`).then(res => { |
||||
util.successMsg("删除成功"); |
||||
this.getData(); |
||||
}).catch(res => { |
||||
}); |
||||
}) |
||||
.catch(() => { |
||||
}); |
||||
}, |
||||
switchOff(val, row, index) { |
||||
if (val) { |
||||
this.$put(`${this.api.disableAnnouncement}?id=${row.id}&isDisable=${val}`).then(res => {}).catch(err => {}) |
||||
} else if (!row.status) { |
||||
this.$confirm('是否发布该公告?', '提示', { |
||||
type: 'success' |
||||
}).then(() => { |
||||
this.$put(`${this.api.disableAnnouncement}?id=${row.id}&isDisable=${val}`).then(res => { |
||||
this.$post(this.api.amendmentAnnouncement, { |
||||
id: row.id, |
||||
status: 1 |
||||
}).then(res => { |
||||
this.getData() |
||||
}).catch(err => {}) |
||||
}).catch(err => {}) |
||||
}).catch(() => { |
||||
row.isOpen = 1 |
||||
}) |
||||
} else { |
||||
this.$put(`${this.api.disableAnnouncement}?id=${row.id}&isDisable=${val}`).then(res => {}).catch(err => {}) |
||||
} |
||||
}, |
||||
add() { |
||||
this.$router.push(`noticeDetail?competitionId=${this.id}`) |
||||
}, |
||||
edit(row) { |
||||
this.$router.push(`noticeDetail?id=${row.id}&competitionId=${this.id}`) |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style scoped> |
||||
|
||||
</style> |
@ -0,0 +1,308 @@ |
||||
<template> |
||||
<!-- 大赛详情 --> |
||||
<div> |
||||
<el-card shadow="hover" style="margin-bottom: 20px"> |
||||
<div class="flex-between"> |
||||
<el-page-header @back="back" :content="(form.id ? '编辑' : '创建') + '公告'"></el-page-header> |
||||
</div> |
||||
</el-card> |
||||
<div class="page"> |
||||
<div class="page-content"> |
||||
<el-form label-width="170px" label-suffix=":" size="small"> |
||||
<el-form-item label="公告标题"> |
||||
<div class="d-inline-block"> |
||||
<el-input placeholder="请输入公告名称" v-model="form.announcementTitle" clearable></el-input> |
||||
</div> |
||||
</el-form-item> |
||||
<el-form-item label="正文"> |
||||
<quill :border="true" v-model="form.announcementText" :height="400" /> |
||||
</el-form-item> |
||||
<el-form-item label="附件"> |
||||
<el-upload |
||||
:on-remove="handleRemove" |
||||
:on-error="uploadError" |
||||
:on-success="uploadSuccess" |
||||
:before-upload="beforeUpload" |
||||
:before-remove="beforeRemove" |
||||
:limit="5" |
||||
:on-exceed="handleExceed" |
||||
:action="this.api.fileupload" |
||||
:headers="headers" |
||||
:file-list="fileList" |
||||
name="file" |
||||
> |
||||
<el-button size="small" type="primary">点击上传</el-button> |
||||
<div slot="tip" class="el-upload__tip"> |
||||
<p>支持扩展名:.rar .zip .doc .docx .pdf .jpg...</p> |
||||
</div> |
||||
</el-upload> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-button v-if="!form.id" @click="save(0)" v-auth="'/activity/list:管理:公告通知:草稿'">草稿</el-button> |
||||
<el-button type="primary" @click="save(1)" v-auth="'/activity/list:管理:公告通知:发布'">发布</el-button> |
||||
<el-button @click="back">取消</el-button> |
||||
</el-form-item> |
||||
</el-form> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import quill from "@/components/quill"; |
||||
import util from "@/libs/util"; |
||||
import Setting from "@/setting"; |
||||
export default { |
||||
name: "matchDetail", |
||||
data() { |
||||
return { |
||||
headers: { |
||||
token: util.local.get(Setting.tokenKey) |
||||
}, |
||||
form: { |
||||
id: this.$route.query.id, |
||||
competitionId: this.$route.query.competitionId, |
||||
announcementText: '', |
||||
announcementTitle: '', |
||||
announcementAnnexList: [], |
||||
isOpen: 1 |
||||
}, |
||||
updateTime: 0, |
||||
fileName: '', |
||||
fileList: [], |
||||
}; |
||||
}, |
||||
components: { |
||||
quill |
||||
}, |
||||
watch: { |
||||
// 监听信息是否有更改,有的话页面离开的时候要询问是否要保存 |
||||
form: { |
||||
handler(){ |
||||
this.updateTime++ |
||||
if(this.updateTime > 1) this.$store.commit('activity/setWait', 0) |
||||
}, |
||||
deep:true |
||||
}, |
||||
}, |
||||
mounted() { |
||||
this.form.id && this.getData() |
||||
}, |
||||
methods: { |
||||
getData() { |
||||
this.$post(`${this.api.queryAnnouncementDetails}?id=${this.form.id}`).then(({ data }) => { |
||||
this.form = data |
||||
// 附件 |
||||
const fileList = data.announcementAnnexList |
||||
if (fileList) { |
||||
const files = [] |
||||
fileList.map(e => { |
||||
files.push({ |
||||
name: e.fileName, |
||||
url: e.filePath |
||||
}) |
||||
}) |
||||
this.fileList = files |
||||
} else { |
||||
data.announcementAnnexList = [] |
||||
} |
||||
}).catch(err => {}) |
||||
}, |
||||
// 保存 |
||||
save(status) { |
||||
const form = this.form |
||||
if (!form.announcementTitle) return util.warningMsg('请填写公告标题') |
||||
if (!form.announcementText) return util.warningMsg('请填写正文') |
||||
form.status = status |
||||
if (form.id) { |
||||
form.isOpen = 0 |
||||
delete form.announcementAnnexList |
||||
this.$post(this.api.amendmentAnnouncement, form).then(res => { |
||||
util.successMsg("修改成功") |
||||
this.$router.back() |
||||
}).catch(err => {}) |
||||
} else { |
||||
form.isOpen = status ? 0 : 1 |
||||
this.$post(this.api.addAnnouncement, form).then(res => { |
||||
util.successMsg("创建成功") |
||||
this.$router.back() |
||||
}).catch(err => {}) |
||||
} |
||||
}, |
||||
handleExceed(files, fileList) { |
||||
util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`); |
||||
}, |
||||
// 附件上传成功 |
||||
uploadSuccess(res) { |
||||
const file = res.data.filesResult |
||||
const { id } = this.form |
||||
const data = { |
||||
announcementId: id || '', |
||||
fileName: this.fileName, |
||||
filePath: file.fileUrl || file.fileId |
||||
} |
||||
this.form.announcementAnnexList.push(data) |
||||
// 编辑的时候需要调新增附件接口 |
||||
id && this.$post(this.api.saveAnnouncementAnnex, data).then(res => {}).catch(res => {}) |
||||
}, |
||||
// 附件上传前 |
||||
beforeUpload(file) { |
||||
this.fileName = file.name |
||||
}, |
||||
uploadError(err, file, fileList) { |
||||
this.$message({ |
||||
message: "上传出错,请重试!", |
||||
type: "error", |
||||
center: true |
||||
}); |
||||
}, |
||||
beforeRemove(file, fileList) { |
||||
return this.$confirm(`确定移除 ${file.name}?`); |
||||
}, |
||||
handleRemove(file, fileList) { |
||||
if (file.url) { |
||||
this.$del(`${this.api.fileDeletion}?keys=${file.url}`).then(res => {}).catch(res => {}) |
||||
const id = this.form.announcementAnnexList.find(e => e.fileName === file.name).id |
||||
this.$post(`${this.api.delAnnex}?id=${id}`).then(res => {}).catch(res => {}) |
||||
} |
||||
}, |
||||
back() { |
||||
this.$router.back() |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style scoped lang="scss"> |
||||
$upload-width: 220px; |
||||
$upload-height: 140px; |
||||
$upload-lg-height: 150px; |
||||
/deep/ .avatar-uploader { |
||||
.el-upload { |
||||
position: relative; |
||||
width: $upload-width; |
||||
height: $upload-height; |
||||
border: 1px dashed #d9d9d9; |
||||
border-radius: 6px; |
||||
cursor: pointer; |
||||
overflow: hidden; |
||||
|
||||
&:hover { |
||||
border-color: #cb221c; |
||||
} |
||||
|
||||
.uploader-default { |
||||
display: flex; |
||||
height: $upload-height; |
||||
flex-direction: column; |
||||
justify-content: center; |
||||
text-align: center; |
||||
background: rgba(0, 0, 0, 0.04); |
||||
|
||||
i { |
||||
font-size: 20px; |
||||
font-weight: bold; |
||||
color: #8c939d; |
||||
} |
||||
|
||||
p { |
||||
margin-top: 10px; |
||||
font-size: 14px; |
||||
color: rgba(0, 0, 0, 0.65); |
||||
line-height: 1; |
||||
} |
||||
} |
||||
} |
||||
|
||||
&.avatar-uploader-lg { |
||||
.el-upload { |
||||
width: 100%; |
||||
max-width: 960px; |
||||
height: $upload-lg-height; |
||||
|
||||
.uploader-default { |
||||
height: $upload-lg-height; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.avatar { |
||||
display: block; |
||||
width: $upload-width; |
||||
height: $upload-height; |
||||
} |
||||
|
||||
.avatar-lg { |
||||
display: block; |
||||
width: 100%; |
||||
height: $upload-lg-height; |
||||
} |
||||
|
||||
.el-upload__tip { |
||||
margin-top: 0; |
||||
|
||||
p { |
||||
font-size: 14px; |
||||
color: rgba(0, 0, 0, 0.45); |
||||
line-height: 1; |
||||
|
||||
&:first-child { |
||||
margin-bottom: 5px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/deep/ .d-inline-block { |
||||
width: 216px; |
||||
|
||||
.el-select, .el-input { |
||||
width: 100%; |
||||
} |
||||
} |
||||
|
||||
.inline-input { |
||||
.input-wrap { |
||||
display: flex; |
||||
align-items: center; |
||||
margin-bottom: 10px; |
||||
|
||||
.el-input { |
||||
display: inline-block; |
||||
width: 216px; |
||||
margin-right: 8px; |
||||
} |
||||
|
||||
.remove { |
||||
width: 16px; |
||||
height: 16px; |
||||
background: url("../../../assets/img/close.png") 0 0/cover no-repeat; |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
|
||||
.add-btn { |
||||
margin-left: 32px; |
||||
} |
||||
} |
||||
|
||||
.add-btn { |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
width: 216px; |
||||
line-height: 32px; |
||||
font-size: 14px; |
||||
color: rgba(0, 0, 0, 0.65); |
||||
background-color: transparent; |
||||
border: 1px dashed rgba(0, 0, 0, 0.15); |
||||
border-radius: 4px; |
||||
cursor: pointer; |
||||
|
||||
i { |
||||
margin-right: 8px; |
||||
font-size: 14px; |
||||
font-weight: bold; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,533 @@ |
||||
<template> |
||||
<div class="activity"> |
||||
<div class="banner" :style="{backgroundImage: 'url(' + (form.carouselUrl || 'https://huoran.oss-cn-shenzhen.aliyuncs.com/20220613/png/1536269450851409920.png') + ')'}"></div> |
||||
<div class="center"> |
||||
<breadcrumb ref="breadcrumb" :data="'全部赛事/' + form.name" route="matchPreview"></breadcrumb> |
||||
<div class="activity-inner"> |
||||
<div class="flex-between"> |
||||
<el-tabs v-model="curType" @tab-click="typeChange"> |
||||
<el-tab-pane v-for="(item, index) in typeList" :key="index" :label="item.name" :name="item.id"></el-tab-pane> |
||||
</el-tabs> |
||||
<div class="status wait">等待报名</div> |
||||
</div> |
||||
<div class="info"> |
||||
<h6 class="title">{{ form.name }}</h6> |
||||
<div class="meta">最近编辑时间:{{ form.updateTime }}</div> |
||||
</div> |
||||
|
||||
<div class="l-title" id="part1"><img src="@/assets/img/label.png" alt=""> 竞赛信息</div> |
||||
<div v-if="form.description" class="texts ql-editor" v-html="form.description"></div> |
||||
<template v-if="form.competitionAnnexList && form.competitionAnnexList.length"> |
||||
<h6 class="p-title">附件下载</h6> |
||||
<ul class="files"> |
||||
<li v-for="(item, i) in form.competitionAnnexList" :key="i"> |
||||
<el-link v-if="item.canPreview" class="m-r-10" type="primary" @click="previewFile(item)">{{ item.fileName }}</el-link> |
||||
<span v-else class="file-name">{{ item.fileName }}</span> |
||||
<el-link type="primary" :underline="false" @click="download(item)">下载</el-link> |
||||
</li> |
||||
</ul> |
||||
</template> |
||||
<template v-if="!form.description && (!form.competitionAnnexList || !form.competitionAnnexList.length )"> |
||||
<div class="empty"> |
||||
<div> |
||||
<img src="@/assets/img/none.png" alt=""> |
||||
<p>暂无数据</p> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<template v-if="form.releaseType && form.competitionStage.length"> |
||||
<div class="l-title"><img src="@/assets/img/label.png" alt=""> 赛程、规则与内容</div> |
||||
<h6 class="rule-title">共{{ form.competitionStage.length }}个竞赛阶段,同一个团队每个成员只能参加一个阶段赛项</h6> |
||||
<div v-for="(rule, i) in form.competitionStage" :key="i" class="rule"> |
||||
<p style="font-size: 16px;color: #333;">{{ rule.stageName }}</p> |
||||
<p>比赛时间:{{ rule.startTime && rule.startTime + ' ~ ' + rule.endTime }}</p> |
||||
<p>比赛方式:{{ methods.find(e => e.id == rule.method) && methods.find(e => e.id == rule.method).name }}</p> |
||||
<p v-if="!rule.method">课程系统:{{ 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>线下地点:{{ rule.offlineAddress }}</p> |
||||
<p>比赛内容:{{ rule.contentDescription }}</p> |
||||
<p>评分规则:{{ rule.scoreRule }}</p> |
||||
</template> |
||||
|
||||
<template v-if="form.completeCompetitionSetup.competitionType"> |
||||
<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> |
||||
</template> |
||||
|
||||
<!-- 进展 --> |
||||
<div class="l-title" id="part2"><img src="@/assets/img/label.png" alt=""> 竞赛进展</div> |
||||
<ul class="progress" v-if="progress.length"> |
||||
<li v-for="(item,index) in progress" :key="index" :class="item.status == 0 ? 'not' : (item.status == 1 ? 'ing' : 'done')"> |
||||
<i class="dot"></i> |
||||
<p class="name">{{item.title}}</p> |
||||
<p class="desc">{{item.description}}</p> |
||||
</li> |
||||
<img class="rocket" src="@/assets/img/rocket.png" alt=""> |
||||
</ul> |
||||
<template v-else> |
||||
<div class="empty"> |
||||
<div> |
||||
<img src="@/assets/img/none.png" alt=""> |
||||
<p>暂无数据</p> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<!-- 公告 --> |
||||
<div class="l-title" id="part3"><img src="@/assets/img/label.png" alt=""> 通知公告</div> |
||||
<ul class="notice-list" v-if="notices.length"> |
||||
<li v-for="(item, i) in notices" :key="i" @click="toNotice(item)"> |
||||
<h6>{{ item.announcementTitle }}</h6> |
||||
<p class="meta">{{ item.updateTime }}</p> |
||||
<div class="des" v-html="item.announcementText"></div> |
||||
</li> |
||||
</ul> |
||||
<template v-else> |
||||
<div class="empty"> |
||||
<div> |
||||
<img src="@/assets/img/none.png" alt=""> |
||||
<p>暂无通知公告</p> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import util from "@/libs/util"; |
||||
import breadcrumb from '@/components/breadcrumb' |
||||
import Const from '@/const/activity' |
||||
export default { |
||||
data() { |
||||
return { |
||||
rules: Const.rules, |
||||
methods: Const.methods, |
||||
teamCalculationMethods: Const.teamCalculationMethods, |
||||
curType: '1', |
||||
typeList: [ |
||||
{ |
||||
id: '1', |
||||
name: '竞赛信息' |
||||
}, |
||||
{ |
||||
id: '2', |
||||
name: '竞赛进展' |
||||
}, |
||||
{ |
||||
id: '3', |
||||
name: '通知公告' |
||||
} |
||||
], |
||||
form: util.local.get('activity'), |
||||
progress: [], |
||||
notices: [], |
||||
}; |
||||
}, |
||||
components: { |
||||
breadcrumb |
||||
}, |
||||
mounted() { |
||||
this.handleAnnex() |
||||
if (this.form.id) { |
||||
this.getProgress() |
||||
this.getNotice() |
||||
} |
||||
}, |
||||
methods: { |
||||
// 处理附件 |
||||
handleAnnex() { |
||||
const list = this.form.competitionAnnexList |
||||
if (list) { |
||||
list.map(e => { |
||||
const { filePath } = e |
||||
e.canPreview = util.canPreview(filePath.substr(filePath.lastIndexOf('.') + 1)) // 判断是否能够预览 |
||||
}) |
||||
this.$forceUpdate() |
||||
} |
||||
}, |
||||
getProgress() { // 获取竞赛进展 |
||||
this.$get(this.api.getCompetitionProgress, { |
||||
competitionId: this.form.id |
||||
}).then(res => { |
||||
this.progress = res.competitionProgressList.reverse() |
||||
}).catch(err => {}); |
||||
}, |
||||
// 公告列表 |
||||
getNotice() { |
||||
this.$post(`${this.api.queryAnnouncementByCompetitionId}?pageNum=1&pageSize=1000&competitionId=${this.form.id}`).then(({ data }) => { |
||||
const records = data.records.filter(e => e.status) // 只显示已发布的(status 0草稿 1为已发布) |
||||
records.map(e => { |
||||
e.announcementText = e.announcementText.replace(/<img.*?(?:>|\/>)/gi, '') |
||||
}) |
||||
this.notices = records |
||||
}).catch(res => {}) |
||||
}, |
||||
// 预览附件 |
||||
previewFile(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) |
||||
}, |
||||
// tab切换 |
||||
typeChange() { |
||||
document.querySelector(`#part${this.curType}`).scrollIntoView() |
||||
}, |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.activity { |
||||
padding-bottom: 20px; |
||||
background-color: #F3F6FA; |
||||
.banner{ |
||||
width: 100%; |
||||
height: 350px; |
||||
color: #fff; |
||||
background-size: 100% 350px; |
||||
background-repeat: no-repeat; |
||||
box-sizing: border-box; |
||||
} |
||||
.center { |
||||
width: 1000px; |
||||
margin: 40px auto 0; |
||||
} |
||||
.activity-inner { |
||||
min-height: calc(100vh - 465px); |
||||
padding: 30px 40px 20px; |
||||
background-color: #fff; |
||||
box-sizing: border-box; |
||||
} |
||||
/deep/.el-tabs { |
||||
.el-tabs__item.is-active, .el-tabs__item:hover { |
||||
color: #007EFF; |
||||
} |
||||
.el-tabs__active-bar { |
||||
background-color: #007EFF; |
||||
} |
||||
} |
||||
.p-title { |
||||
border-left-color: #007EFF; |
||||
} |
||||
.l-title{ |
||||
display: flex; |
||||
align-items: center; |
||||
margin-bottom: 12px; |
||||
font-size: 18px; |
||||
color: #333; |
||||
img{ |
||||
margin-right: 5px; |
||||
} |
||||
} |
||||
.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: #007EFF; |
||||
} |
||||
&.signed { |
||||
background-color: #52C41A; |
||||
} |
||||
&.finish { |
||||
background-color: #ccc; |
||||
} |
||||
} |
||||
.title{ |
||||
width: 67%; |
||||
margin: 0 auto; |
||||
font-size: 28px; |
||||
text-align: center; |
||||
color: #0B1D30; |
||||
} |
||||
.info .meta{ |
||||
padding: 16px 0; |
||||
font-size: 12px; |
||||
color: #999; |
||||
text-align: center; |
||||
} |
||||
.texts { |
||||
margin-bottom: 30px; |
||||
font-size: 14px; |
||||
line-height: 1.6; |
||||
text-indent: 2em; |
||||
overflow: hidden; |
||||
/deep/img{ |
||||
max-width: 100%; |
||||
} |
||||
} |
||||
.files { |
||||
margin-bottom: 30px; |
||||
li { |
||||
display: flex; |
||||
align-items: center; |
||||
margin: 10px 0; |
||||
} |
||||
.file-name { |
||||
margin-right: 10px; |
||||
font-size: 12px; |
||||
} |
||||
} |
||||
.el-link.el-link--primary { |
||||
color: #007EFF !important; |
||||
&:after { |
||||
border-color: #007EFF; |
||||
} |
||||
} |
||||
} |
||||
.progress{ |
||||
position: relative; |
||||
width: 95%; |
||||
padding: 50px 0; |
||||
margin: 40px auto 80px; |
||||
text-align: left; |
||||
&:before{ |
||||
content: ''; |
||||
position: absolute; |
||||
top: 0; |
||||
left: 50%; |
||||
width: 2px; |
||||
height: 100%; |
||||
background-color: #E1E6F2; |
||||
} |
||||
&:after { |
||||
content: ''; |
||||
position: absolute; |
||||
top: -10px; |
||||
left: 430px; |
||||
border: 8px solid transparent; |
||||
border-bottom-color: #E1E6F2; |
||||
} |
||||
.rocket { |
||||
position: absolute; |
||||
bottom: -50px; |
||||
left: 425px; |
||||
} |
||||
li{ |
||||
position: relative; |
||||
width: 400px; |
||||
margin-bottom: 42px; |
||||
.dot{ |
||||
position: absolute; |
||||
top: 12px; |
||||
left: 431px; |
||||
width: 15px; |
||||
height: 15px; |
||||
background-color: #DCDCDC; |
||||
border-radius: 50%; |
||||
} |
||||
.name{ |
||||
display: inline-block; |
||||
padding: 0 19px; |
||||
margin-bottom: 16px; |
||||
line-height: 40px; |
||||
text-align: center; |
||||
font-size: 16px; |
||||
color: #fff; |
||||
border-radius: 20px; |
||||
background-color: #C4C4C4; |
||||
} |
||||
.desc{ |
||||
position: relative; |
||||
color: #333; |
||||
font-size: 14px; |
||||
} |
||||
&.ing, &.done { |
||||
.dot { |
||||
top: 8px; |
||||
background-color: #007EFF; |
||||
} |
||||
.name { |
||||
background-color: #007EFF; |
||||
} |
||||
} |
||||
&.ing { |
||||
.dot { |
||||
width: 27px; |
||||
height: 27px; |
||||
border: 6px solid #E2F1FB; |
||||
} |
||||
} |
||||
&:nth-child(odd) { |
||||
text-align: right; |
||||
&.ing { |
||||
.dot { |
||||
left: auto; |
||||
right: -58px; |
||||
} |
||||
} |
||||
.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; |
||||
} |
||||
} |
||||
} |
||||
.notice-list { |
||||
text-align: left; |
||||
li { |
||||
padding: 16px; |
||||
margin-bottom: 12px; |
||||
transition: all 0.3s; |
||||
cursor: pointer; |
||||
border-radius: 6px; |
||||
background-color: #fff; |
||||
border-bottom: 1px dashed #ebebeb; |
||||
&:last-child { |
||||
border-bottom: 0; |
||||
} |
||||
} |
||||
h6 { |
||||
font-size: 20px; |
||||
font-weight: 500; |
||||
color: #0B1D30; |
||||
&:hover { |
||||
color: #007EFF; |
||||
} |
||||
} |
||||
.meta { |
||||
margin: 10px 0; |
||||
font-size: 14px; |
||||
color: #666; |
||||
} |
||||
.des { |
||||
font-size: 14px; |
||||
color: #333; |
||||
line-height: 24px; |
||||
display: -webkit-box; |
||||
display:-moz-box; |
||||
-webkit-box-orient: vertical; |
||||
-moz-box-orient: vertical; |
||||
-webkit-line-clamp: 2; |
||||
-moz-line-clamp: 2; |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
} |
||||
} |
||||
.empty{ |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
padding: 50px 0; |
||||
text-align: center; |
||||
img{ |
||||
width: 471px; |
||||
} |
||||
p{ |
||||
margin-top: 40px; |
||||
font-size: 18px; |
||||
color: rgba(0, 0, 0, 0.25); |
||||
} |
||||
} |
||||
.rule-title { |
||||
margin-bottom: 10px; |
||||
font-size: 16px; |
||||
} |
||||
.rule { |
||||
padding: 15px; |
||||
margin-bottom: 15px; |
||||
border: 1px solid #dfdfdf; |
||||
p { |
||||
font-size: 14px; |
||||
line-height: 30px; |
||||
color: #6e6e6e; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,37 @@ |
||||
import BasicLayout from "@/layouts/home"; |
||||
|
||||
const meta = {}; |
||||
|
||||
const pre = "activity-"; |
||||
|
||||
export default { |
||||
path: "/activity", |
||||
name: "activity", |
||||
redirect: { |
||||
name: `${pre}list` |
||||
}, |
||||
meta, |
||||
component: BasicLayout, |
||||
children: [ |
||||
{ |
||||
name: `${pre}list`, |
||||
path: `list`, |
||||
component: () => import("@/pages/activity/list"), |
||||
}, |
||||
{ |
||||
name: `${pre}add`, |
||||
path: `add`, |
||||
component: () => import("@/pages/activity/add"), |
||||
}, |
||||
{ |
||||
name: `${pre}manage`, |
||||
path: `manage`, |
||||
component: () => import("@/pages/activity/manage"), |
||||
}, |
||||
{ |
||||
name: `${pre}noticeDetail`, |
||||
path: `noticeDetail`, |
||||
component: () => import("@/pages/activity/manage/noticeDetail"), |
||||
}, |
||||
] |
||||
}; |
@ -0,0 +1,21 @@ |
||||
/** |
||||
* 赛事相关 |
||||
* */ |
||||
export default { |
||||
namespaced: true, |
||||
state: { |
||||
page: 1, |
||||
cache: null |
||||
}, |
||||
mutations: { |
||||
setPage: (state, page) => { |
||||
state.page = page |
||||
}, |
||||
setCache: (state, cache) => { |
||||
state.cache = cache |
||||
} |
||||
}, |
||||
actions: { |
||||
|
||||
} |
||||
}; |
Loading…
Reference in new issue