|
|
|
@ -3,103 +3,163 @@ |
|
|
|
|
<div class="page"> |
|
|
|
|
<div class="page-content"> |
|
|
|
|
<div class="p-title">赛程与规则设置</div> |
|
|
|
|
<el-form :model="form" :rules="validRules" label-width="170px" label-suffix=":" size="small" :disabled="!editing && id"> |
|
|
|
|
<el-form :model="form" |
|
|
|
|
:rules="validRules" |
|
|
|
|
label-width="170px" |
|
|
|
|
label-suffix=":" |
|
|
|
|
size="small" |
|
|
|
|
:disabled="!editing && id"> |
|
|
|
|
<el-form-item label="竞赛类型"> |
|
|
|
|
{{ step1.completeCompetitionSetup.competitionType ? '团队赛(' + step1.completeCompetitionSetup.minTeamSize + '-' + step1.completeCompetitionSetup.maxTeamSize + '人/队)' : '个人赛' }} <span class="tips">(如需修改,请返回上一步。)</span> |
|
|
|
|
</el-form-item> |
|
|
|
|
<el-form-item prop="rule" label="赛制"> |
|
|
|
|
<el-radio v-for="(rule, i) in rules" :key="i" v-model="form.rule" :label="rule.id">{{ rule.name }}</el-radio> |
|
|
|
|
<el-form-item prop="rule" |
|
|
|
|
label="赛制"> |
|
|
|
|
<el-radio v-for="(rule, i) in rules" |
|
|
|
|
:key="i" |
|
|
|
|
v-model="form.rule" |
|
|
|
|
:label="rule.id">{{ rule.name }}</el-radio> |
|
|
|
|
<p class="tips">积分赛——包含多个竞赛阶段,每个阶段的成绩都包含在最终总成绩里,最后一轮结束后总成绩排名靠前的参赛者得到获奖资格。</p> |
|
|
|
|
<p class="tips">淘汰赛——包含多个竞赛阶段,每个阶段结束后之后只有部分参赛者能晋级下一阶段,晋级最后一轮且在最后一轮排名靠前的参赛者得到获奖资格。</p> |
|
|
|
|
<p class="tips">单项赛——仅包含一个竞赛阶段,单项的成绩排名即为最终排名,排名靠前的参赛者得到获奖资格。</p> |
|
|
|
|
<p class="tips">注:系统默认排名规则,优先按分数排名(分数高则排名靠前),分数相同则按用时排名(用时短则排名靠前)。</p> |
|
|
|
|
</el-form-item> |
|
|
|
|
<template v-if="form.rule !== 2"> |
|
|
|
|
<el-form-item prop="stageNum" label="阶段数量"> |
|
|
|
|
<el-form-item prop="stageNum" |
|
|
|
|
label="阶段数量"> |
|
|
|
|
<div class="input-center"> |
|
|
|
|
<el-select v-model="form.stageNum" @change="stageChange"> |
|
|
|
|
<el-option v-for="i in 10" :key="i" :label="i" :value="i"></el-option> |
|
|
|
|
<el-select v-model="form.stageNum" |
|
|
|
|
@change="stageChange"> |
|
|
|
|
<el-option v-for="i in 10" |
|
|
|
|
:key="i" |
|
|
|
|
:label="i" |
|
|
|
|
:value="i"></el-option> |
|
|
|
|
</el-select> |
|
|
|
|
</div> |
|
|
|
|
<div v-if="step1.completeCompetitionSetup.competitionType" class="tips"> |
|
|
|
|
<div v-if="step1.completeCompetitionSetup.competitionType" |
|
|
|
|
class="tips"> |
|
|
|
|
(团队赛是否限制队内每个成员只能参加一个阶段赛项? |
|
|
|
|
<el-radio v-model="form.teamLimit" :label="1">是</el-radio> |
|
|
|
|
<el-radio v-model="form.teamLimit" :label="0">否</el-radio> |
|
|
|
|
<el-radio v-model="form.teamLimit" |
|
|
|
|
:label="1">是</el-radio> |
|
|
|
|
<el-radio v-model="form.teamLimit" |
|
|
|
|
:label="0">否</el-radio> |
|
|
|
|
) |
|
|
|
|
</div> |
|
|
|
|
</el-form-item> |
|
|
|
|
<el-form-item v-if="!form.rule" prop="resultCalculationMethod" label="总成绩计算方式"> |
|
|
|
|
<el-radio v-model="form.resultCalculationMethod" :label="0">各阶段成绩加权求和</el-radio> |
|
|
|
|
<el-radio v-model="form.resultCalculationMethod" :label="1">各阶段成绩直接求和</el-radio> |
|
|
|
|
<el-radio v-model="form.resultCalculationMethod" :label="2">各阶段成绩取平均值</el-radio> |
|
|
|
|
<el-form-item v-if="!form.rule" |
|
|
|
|
prop="resultCalculationMethod" |
|
|
|
|
label="总成绩计算方式"> |
|
|
|
|
<el-radio v-model="form.resultCalculationMethod" |
|
|
|
|
:label="0">各阶段成绩加权求和</el-radio> |
|
|
|
|
<el-radio v-model="form.resultCalculationMethod" |
|
|
|
|
:label="1">各阶段成绩直接求和</el-radio> |
|
|
|
|
<el-radio v-model="form.resultCalculationMethod" |
|
|
|
|
:label="2">各阶段成绩取平均值</el-radio> |
|
|
|
|
<p class="tips">(若选择加权求和,则需要设置每个阶段成绩所占权重,且权重总和须为100%)</p> |
|
|
|
|
</el-form-item> |
|
|
|
|
<el-form-item prop="stageNum" label="阶段设置"> |
|
|
|
|
<div v-for="(item, i) in form.competitionStageList" :key="i" class="step-set"> |
|
|
|
|
<el-form-item prop="stageNum" |
|
|
|
|
label="阶段设置"> |
|
|
|
|
<div v-for="(item, i) in form.competitionStageList" |
|
|
|
|
:key="i" |
|
|
|
|
class="step-set"> |
|
|
|
|
<div class="line"> |
|
|
|
|
第{{ serials[i] }}阶段 <el-input v-model="item.stageName" clearable placeholder="请输入阶段名称,如“初赛”" style="width: 200px"></el-input> |
|
|
|
|
第{{ serials[i] }}阶段 <el-input v-model="item.stageName" |
|
|
|
|
clearable |
|
|
|
|
placeholder="请输入阶段名称,如“初赛”" |
|
|
|
|
style="width: 200px"></el-input> |
|
|
|
|
</div> |
|
|
|
|
<div class="line"> |
|
|
|
|
<span class="req">*</span> |
|
|
|
|
比赛方式: |
|
|
|
|
<el-radio v-for="(method, i) in methods" :key="i" v-model="item.method" :label="method.id">{{ method.name }}</el-radio> |
|
|
|
|
<el-radio v-for="(method, i) in methods" |
|
|
|
|
:key="i" |
|
|
|
|
v-model="item.method" |
|
|
|
|
:label="method.id">{{ method.name }}</el-radio> |
|
|
|
|
</div> |
|
|
|
|
<div v-if="step1.completeCompetitionSetup.competitionType" class="line"> |
|
|
|
|
<div v-if="step1.completeCompetitionSetup.competitionType" |
|
|
|
|
class="line"> |
|
|
|
|
<span class="req">*</span> |
|
|
|
|
团队参赛人数限制: |
|
|
|
|
<el-radio v-model="item.teamNumLimitOpt" :label="0">不限制</el-radio> |
|
|
|
|
<el-radio v-model="item.teamNumLimitOpt" :label="1">自定义</el-radio> |
|
|
|
|
<el-input v-model.number="item.teamNumLimit" type="number" style="width: 150px;" :disabled="item.teamNumLimitOpt === 0"></el-input> 人 |
|
|
|
|
<el-radio v-model="item.teamNumLimitOpt" |
|
|
|
|
:label="0">不限制</el-radio> |
|
|
|
|
<el-radio v-model="item.teamNumLimitOpt" |
|
|
|
|
:label="1">自定义</el-radio> |
|
|
|
|
<el-input v-model.number="item.teamNumLimit" |
|
|
|
|
type="number" |
|
|
|
|
style="width: 150px;" |
|
|
|
|
:disabled="item.teamNumLimitOpt === 0"></el-input> 人 |
|
|
|
|
<span class="tips">(可限制本阶段单个团队的出战人数)</span> |
|
|
|
|
</div> |
|
|
|
|
<div v-if="step1.completeCompetitionSetup.competitionType" class="line"> |
|
|
|
|
<div v-if="step1.completeCompetitionSetup.competitionType" |
|
|
|
|
class="line"> |
|
|
|
|
<span class="req">*</span> |
|
|
|
|
团队成绩计算方式: |
|
|
|
|
<el-radio v-for="(j, i) in teamCalculationMethods" :key="i" v-model="item.teamCalculationMethod" :label="j.id">{{ j.name }}</el-radio> |
|
|
|
|
<el-radio v-for="(j, i) in teamCalculationMethods" |
|
|
|
|
:key="i" |
|
|
|
|
v-model="item.teamCalculationMethod" |
|
|
|
|
:label="j.id">{{ j.name }}</el-radio> |
|
|
|
|
<span class="tips">(可设置本阶段的团队取分规则)</span> |
|
|
|
|
</div> |
|
|
|
|
<div v-if="form.rule === 1 && i !== form.competitionStageList.length - 1" class="line" style="display: flex;"> |
|
|
|
|
<div v-if="form.rule === 1 && i !== form.competitionStageList.length - 1" |
|
|
|
|
class="line" |
|
|
|
|
style="display: flex;"> |
|
|
|
|
<p> |
|
|
|
|
<span class="req">*</span>晋级规则: |
|
|
|
|
</p> |
|
|
|
|
<div> |
|
|
|
|
<div class="line"> |
|
|
|
|
本阶段成绩排名前 |
|
|
|
|
<el-input v-model.number="item.peopleLimit" type="number" style="width: 100px"></el-input> |
|
|
|
|
<el-input v-model.number="item.peopleLimit" |
|
|
|
|
type="number" |
|
|
|
|
style="width: 100px"></el-input> |
|
|
|
|
队,可晋级下一阶段比赛 |
|
|
|
|
</div> |
|
|
|
|
<div class="line"> |
|
|
|
|
本阶段成绩排名前 |
|
|
|
|
<el-input v-model.number="item.percentageLimit" type="number" style="width: 100px"></el-input> |
|
|
|
|
<el-input v-model.number="item.percentageLimit" |
|
|
|
|
type="number" |
|
|
|
|
style="width: 100px"></el-input> |
|
|
|
|
%,可晋级下一阶段比赛 |
|
|
|
|
</div> |
|
|
|
|
<div> |
|
|
|
|
本阶段成绩 |
|
|
|
|
<el-select v-model="item.operator" style="width: 80px;margin-right: 10px"> |
|
|
|
|
<el-option v-for="i in operators" :key="i" :label="i" :value="i"></el-option> |
|
|
|
|
<el-select v-model="item.operator" |
|
|
|
|
style="width: 80px;margin-right: 10px"> |
|
|
|
|
<el-option v-for="i in operators" |
|
|
|
|
:key="i" |
|
|
|
|
:label="i" |
|
|
|
|
:value="i"></el-option> |
|
|
|
|
</el-select> |
|
|
|
|
<el-input v-model="item.score" type="number" style="width: 100px"></el-input> |
|
|
|
|
<el-input v-model="item.score" |
|
|
|
|
type="number" |
|
|
|
|
style="width: 100px"></el-input> |
|
|
|
|
分,可晋级下一阶段比赛 |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<div v-if="!form.rule" class="line"> |
|
|
|
|
<div v-if="!form.rule" |
|
|
|
|
class="line"> |
|
|
|
|
<span class="req">*</span> |
|
|
|
|
占总成绩权重: |
|
|
|
|
<el-input v-model.number="item.pointWeight" type="number" :disabled="form.resultCalculationMethod != 0" style="width: 150px;"></el-input> % |
|
|
|
|
<el-input v-model.number="item.pointWeight" |
|
|
|
|
type="number" |
|
|
|
|
:disabled="form.resultCalculationMethod != 0" |
|
|
|
|
style="width: 150px;"></el-input> % |
|
|
|
|
</div> |
|
|
|
|
<div class="line"> |
|
|
|
|
<span class="req">*</span> |
|
|
|
|
成绩公布时间: |
|
|
|
|
(阶段)比赛结束后 |
|
|
|
|
<el-input v-model.number="item.resultAnnouncementTime" type="number" style="width: 120px"></el-input> |
|
|
|
|
<el-input v-model.number="item.resultAnnouncementTime" |
|
|
|
|
type="number" |
|
|
|
|
style="width: 120px"></el-input> |
|
|
|
|
小时,公布(阶段)比赛成绩。 |
|
|
|
|
</div> |
|
|
|
|
<div class="line"> |
|
|
|
|
<span class="req">*</span> |
|
|
|
|
<div v-if="item.resultAnnouncementTime != 0" |
|
|
|
|
class="line"> |
|
|
|
|
是否公布成绩详情: |
|
|
|
|
<el-radio v-model="item.resultsDetails" :label="0">是</el-radio> |
|
|
|
|
<el-radio v-model="item.resultsDetails" :label="1">否</el-radio> |
|
|
|
|
<el-radio v-model="item.resultsDetails" |
|
|
|
|
:label="0">是</el-radio> |
|
|
|
|
<el-radio v-model="item.resultsDetails" |
|
|
|
|
:label="1">否</el-radio> |
|
|
|
|
<p class="tips">若选择“是”,则公布成绩详情,竞赛结束后参赛者可查看自己的比赛成绩得分详情;</p> |
|
|
|
|
<p class="tips">若选择“否”,则不公布成绩详情,参赛者只能知晓自己的分数及排名,不能查看得分详情。</p> |
|
|
|
|
</div> |
|
|
|
@ -107,29 +167,43 @@ |
|
|
|
|
</el-form-item> |
|
|
|
|
</template> |
|
|
|
|
<template v-else> |
|
|
|
|
<el-form-item prop="stageNum" label="规则设置"> |
|
|
|
|
<el-form-item prop="stageNum" |
|
|
|
|
label="规则设置"> |
|
|
|
|
<div class="step-set"> |
|
|
|
|
<div class="line"> |
|
|
|
|
<span class="req">*</span> |
|
|
|
|
比赛方式: |
|
|
|
|
<el-radio v-for="(method, i) in methods" :key="i" v-model="form.competitionStageList[0].method" :label="method.id">{{ method.name }}</el-radio> |
|
|
|
|
<el-radio v-for="(method, i) in methods" |
|
|
|
|
:key="i" |
|
|
|
|
v-model="form.competitionStageList[0].method" |
|
|
|
|
:label="method.id">{{ method.name }}</el-radio> |
|
|
|
|
</div> |
|
|
|
|
<div v-if="step1.completeCompetitionSetup.competitionType" class="line"> |
|
|
|
|
<div v-if="step1.completeCompetitionSetup.competitionType" |
|
|
|
|
class="line"> |
|
|
|
|
<span class="req">*</span> |
|
|
|
|
团队成绩计算方式: |
|
|
|
|
<el-radio v-for="(j, i) in teamCalculationMethods" :key="i" v-model="form.competitionStageList[0].teamCalculationMethod" :label="j.id">{{ j.name }}</el-radio> |
|
|
|
|
<el-radio v-for="(j, i) in teamCalculationMethods" |
|
|
|
|
:key="i" |
|
|
|
|
v-model="form.competitionStageList[0].teamCalculationMethod" |
|
|
|
|
:label="j.id">{{ j.name }}</el-radio> |
|
|
|
|
<span class="tips">(可设置本阶段的团队取分规则)</span> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</el-form-item> |
|
|
|
|
<el-form-item prop="rule" label="成绩公布时间"> |
|
|
|
|
<el-form-item prop="rule" |
|
|
|
|
label="成绩公布时间"> |
|
|
|
|
(阶段)比赛结束后 |
|
|
|
|
<el-input v-model.number="form.competitionStageList[0].resultAnnouncementTime" type="number" style="width: 120px"></el-input> |
|
|
|
|
<el-input v-model.number="form.competitionStageList[0].resultAnnouncementTime" |
|
|
|
|
type="number" |
|
|
|
|
style="width: 120px"></el-input> |
|
|
|
|
小时,公布(阶段)比赛成绩。 |
|
|
|
|
</el-form-item> |
|
|
|
|
<el-form-item prop="resultsDetails" label="是否公布成绩详情"> |
|
|
|
|
<el-radio v-model="form.competitionStageList[0].resultsDetails" :label="0">是</el-radio> |
|
|
|
|
<el-radio v-model="form.competitionStageList[0].resultsDetails" :label="1">否</el-radio> |
|
|
|
|
<el-form-item prop="resultsDetails" |
|
|
|
|
label="是否公布成绩详情"> |
|
|
|
|
<el-radio v-model="form.competitionStageList[0].resultsDetails" |
|
|
|
|
:label="0">是</el-radio> |
|
|
|
|
<el-radio v-model="form.competitionStageList[0].resultsDetails" |
|
|
|
|
:label="1">否</el-radio> |
|
|
|
|
<p class="tips">若选择“是”,则公布成绩详情,竞赛结束后参赛者可查看自己的比赛成绩得分详情;</p> |
|
|
|
|
<p class="tips">若选择“否”,则不公布成绩详情,参赛者只能知晓自己的分数及排名,不能查看得分详情。</p> |
|
|
|
|
</el-form-item> |
|
|
|
@ -146,7 +220,7 @@ import quill from "@/components/quill"; |
|
|
|
|
import Const from '@/const/match' |
|
|
|
|
export default { |
|
|
|
|
props: ['setupId', 'editing'], |
|
|
|
|
data() { |
|
|
|
|
data () { |
|
|
|
|
return { |
|
|
|
|
id: this.$route.query.id, |
|
|
|
|
updateTime: 0, |
|
|
|
@ -172,7 +246,7 @@ export default { |
|
|
|
|
teamNumLimit: '', |
|
|
|
|
teamNumLimitOpt: 0, |
|
|
|
|
resultAnnouncementTime: '', |
|
|
|
|
resultsDetails: 0, |
|
|
|
|
resultsDetails: '', |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
method: 0, |
|
|
|
@ -188,7 +262,7 @@ export default { |
|
|
|
|
teamNumLimit: '', |
|
|
|
|
teamNumLimitOpt: 0, |
|
|
|
|
resultAnnouncementTime: '', |
|
|
|
|
resultsDetails: 0, |
|
|
|
|
resultsDetails: '', |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
method: 0, |
|
|
|
@ -204,7 +278,7 @@ export default { |
|
|
|
|
teamNumLimit: '', |
|
|
|
|
teamNumLimitOpt: 0, |
|
|
|
|
resultAnnouncementTime: '', |
|
|
|
|
resultsDetails: 0, |
|
|
|
|
resultsDetails: '', |
|
|
|
|
} |
|
|
|
|
] |
|
|
|
|
}, |
|
|
|
@ -235,19 +309,19 @@ export default { |
|
|
|
|
watch: { |
|
|
|
|
// 监听信息是否有更改,有的话页面离开的时候要询问是否要保存 |
|
|
|
|
form: { |
|
|
|
|
handler(){ |
|
|
|
|
handler () { |
|
|
|
|
this.updateTime++ |
|
|
|
|
}, |
|
|
|
|
deep:true |
|
|
|
|
deep: true |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
mounted() { |
|
|
|
|
mounted () { |
|
|
|
|
this.ruleForm = JSON.parse(JSON.stringify(this.form.competitionStageList[0])) |
|
|
|
|
this.id && this.getData() |
|
|
|
|
this.step1 || this.getStep1() // 如果没有第一步的数据,则直接接口获取 |
|
|
|
|
}, |
|
|
|
|
methods: { |
|
|
|
|
getData() { |
|
|
|
|
getData () { |
|
|
|
|
this.$get(this.api.getCompetitionRule, { |
|
|
|
|
competitionId: this.id |
|
|
|
|
}).then(res => { |
|
|
|
@ -273,18 +347,18 @@ export default { |
|
|
|
|
this.$nextTick(() => { |
|
|
|
|
this.updateTime = 0 |
|
|
|
|
}) |
|
|
|
|
}).catch(res => {}) |
|
|
|
|
}).catch(res => { }) |
|
|
|
|
}, |
|
|
|
|
// 获取第二部的数据 |
|
|
|
|
getStep1() { |
|
|
|
|
getStep1 () { |
|
|
|
|
this.$post(`${this.api.getCompetition}?competitionId=${this.id}`).then(({ competition }) => { |
|
|
|
|
this.step1 = competition |
|
|
|
|
const { minTeamSize, maxTeamSize, competitionType } = this.step1.completeCompetitionSetup |
|
|
|
|
competitionType && minTeamSize !== '' && maxTeamSize !== '' && minTeamSize == maxTeamSize && this.teamCalculationMethods.pop() // 团队上下限人数相等,则不显示求和 |
|
|
|
|
}).catch(err => {}) |
|
|
|
|
}).catch(err => { }) |
|
|
|
|
}, |
|
|
|
|
// 阶段数量选择回调 |
|
|
|
|
stageChange(val) { |
|
|
|
|
stageChange (val) { |
|
|
|
|
const stages = this.form.competitionStageList |
|
|
|
|
const { ruleId } = this.form |
|
|
|
|
if (stages.length < val) { |
|
|
|
@ -300,7 +374,7 @@ export default { |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
// 提交 |
|
|
|
|
save(status, next = 0) { |
|
|
|
|
save (status, next = 0) { |
|
|
|
|
let { form } = this |
|
|
|
|
const { rule } = form |
|
|
|
|
let invalid = 0 |
|
|
|
@ -312,10 +386,7 @@ export default { |
|
|
|
|
if (form.rule === 2) { // 单项赛只需要输入成绩公布时间 |
|
|
|
|
const e = stages[0] |
|
|
|
|
e.stageName = step1.name |
|
|
|
|
if (!e.resultsDetails) { |
|
|
|
|
if (e.resultAnnouncementTime === '') { |
|
|
|
|
return util.errorMsg('请填写成绩公布时间') |
|
|
|
|
} |
|
|
|
|
if (e.resultsDetails === 0 && e.resultAnnouncementTime !== '') { |
|
|
|
|
if (e.resultAnnouncementTime < 0) { |
|
|
|
|
return util.errorMsg('成绩公布时间不得小于0') |
|
|
|
|
} |
|
|
|
@ -368,12 +439,7 @@ export default { |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!e.resultsDetails) { |
|
|
|
|
if (e.resultAnnouncementTime === '') { |
|
|
|
|
invalid = 1 |
|
|
|
|
util.errorMsg('请填写成绩公布时间') |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
if (e.resultsDetails === 0 && e.resultAnnouncementTime !== '') { |
|
|
|
|
if (e.resultAnnouncementTime < 0) { |
|
|
|
|
invalid = 1 |
|
|
|
|
util.errorMsg('成绩公布时间不得小于0') |
|
|
|
@ -423,7 +489,8 @@ export default { |
|
|
|
|
<style scoped lang="scss"> |
|
|
|
|
/deep/ .d-inline-block { |
|
|
|
|
width: 216px; |
|
|
|
|
.el-select, .el-input { |
|
|
|
|
.el-select, |
|
|
|
|
.el-input { |
|
|
|
|
width: 100%; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -442,7 +509,7 @@ export default { |
|
|
|
|
.remove { |
|
|
|
|
width: 16px; |
|
|
|
|
height: 16px; |
|
|
|
|
background: url("../../../assets/img/close.png") 0 0/cover no-repeat; |
|
|
|
|
background: url('../../../assets/img/close.png') 0 0 / cover no-repeat; |
|
|
|
|
cursor: pointer; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|